./PaxHeaders.27918/drumstick-2.5.10000644000000000000000000000013214200302440013340 xustar0030 mtime=1644266784.865324206 30 atime=1644266784.873324212 30 ctime=1644266784.865324206 drumstick-2.5.1/0000755000175000001440000000000014200302440014041 5ustar00pedrousers00000000000000drumstick-2.5.1/PaxHeaders.27918/configure_dbg0000644000000000000000000000013214200302440016000 xustar0030 mtime=1644266784.865324206 30 atime=1644266784.873324212 30 ctime=1644266784.865324206 drumstick-2.5.1/configure_dbg0000755000175000001440000000035314200302440016565 0ustar00pedrousers00000000000000#!/bin/bash # a typical configuration for development usage... mkdir -p build cd build cmake .. -DCMAKE_CXX_FLAGS="-W -Wall" \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_INSTALL_PREFIX=/usr/local \ -DSTATIC_DRUMSTICK=YES \ -DUSE_DBUS=YES drumstick-2.5.1/PaxHeaders.27918/library0000644000000000000000000000013214200302440014647 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.873324212 30 ctime=1644266784.825324181 drumstick-2.5.1/library/0000755000175000001440000000000014200302440015505 5ustar00pedrousers00000000000000drumstick-2.5.1/library/PaxHeaders.27918/widgets0000644000000000000000000000013214200302440016315 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.873324212 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/0000755000175000001440000000000014200302440017153 5ustar00pedrousers00000000000000drumstick-2.5.1/library/widgets/PaxHeaders.27918/blkey.xcf0000644000000000000000000000013214200302440020202 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.873324212 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/blkey.xcf0000644000175000001440000154362514200302440021003 0ustar00pedrousers00000000000000gimp xcf fileCCgimp-image-grid(style solid) (fgcolor (color-rgba 0.000000 0.000000 0.000000 1.000000)) (bgcolor (color-rgba 1.000000 1.000000 1.000000 1.000000)) (xspacing 10.000000) (yspacing 10.000000) (spacing-unit inches) (xoffset 0.000000) (yoffset 0.000000) (offset-unit inches)  blkey.svg     =aeq}lj3n -WnK;Xw<EZ`:Y;zjo?-Cjb`]_X[XURORNKNIGHDAC>97.!cba^]\YWVUQPNMKIHFEC@><99!^ba^]\XWVUTPMLKIHFDB@><99 ^baa\[[WVUTRMLKIHEDB@><86^da`\[[ZVTSRQLKHGEDB@=;=6 ^c``_[[ZUTSRQOJHGEDB?=?=6^cc`_[ZYXTSRPNMHGECA?A?=6kcc`_]ZYXWSQPNMLJHFECA?<6kcca^]\YXVRQPNMKIHFECA><6keba^]\YWVUQPNLKIHFEB@><6kebaa][[WVUTOMLKIHFDB@><3kedaa\[[WVUSRMLKIGEDB@>;@ked``_[[ZUTSRQLJHGEDB@=;@fecc`_[[YXTSRQNMHGEDA?A?@fgcc`_]ZYXTSQPNMLJECACA?@fgcc`^]ZYXWRQPNMLIHFECA>@fgfba^]\YWVUQPNMKIHFEC@>@fgeba^]\XWVUTPMLKIHFDB@>@febaa\[[WVUSRMLKIHEDB@>@fheda`\[[ZVTSRQLKHGEDB@==ahec``_[[YUTSRQOJHGEDB?==ahdcc`_^ZYXTSRPNMHGECA?A=mggcc`^]ZYXWSQPNMLJHFECA=mggcca^]\YXVRQPNMKIHFEC@:migeba^]\YWVUQPNLKIHFEB@:mifebaa][[WVUTOMLKIHEDB@:mhfeda`\[[WVUSRMLKIGEDB@:mhhed``_[[ZUTSRQLJHGEDB@:mhhdcc`_[[YXTSRQNMHGEDA?F mkggcc`_]ZYXTSQPNMLJECECF hjggccb^]ZYXWRQPNMLIHFECF hjggfba^]\YWVUQPNLKIHFECC hjigeba^]\XWVUTPMLKIHFDBC hjhfebaa\[[WVUSRMLKIHEDBChkhheda`\[[ZVTSRQLKHGEDBC hkhhec``_[[YUTSRQOJHGEDBCtkhhgcc`_^ZYXTSRPNMLGECACtkjggcc`^]ZYXWRQPNMLJHFECojjggcca^]\YXVUQPNMKIHFEComjigeba^]\XWVUQPNLKIHFE@omjifebaa][[WVUTOMLKIHED@omkhfeda`\[[WVUSRMLKIGED@olkhhed``_[[ZUTSRQLJHGED@olkhhdcc`_[[YXTSRQNMHGED@jnkkggcc`_]ZYXTSQPNMLJDCJjnjjggcca^]ZYXWRQPNMLIHFGjmmjggfba^]\YWVUQPNLKIHFGjmmjifebaa]\[WVUTPMLKIHFGjomjhfebaa\[[WVUSRMLKIHEGjolkhheda`_[[ZVTSRQLKHGEGunlkhhec``_[[YUTSRQNJHGEGunnkkhgcc`_^ZYXTSRPNMLGEEunnkjggcc`^]ZYXWRQPNMLJHEuqmjjggcca^]\YXVUQPNMKIHEupmmjigeba^]\XWVUQPNLKIHEpmjifebaa][[WVUTOMLKIHEpomkhheda`\[[WVTSRMLKIGEpolkhhed``_[[ZUTSRQLJHGEpqnnkhhdcc`_[ZYXTSRQNMHGECjb`]_X[XURORNKNIGHDAC>97.!cba^]\YWVUQPNMKIHFEC@><99!^ba^]\XWVUTPMLKIHFDB@><99 ^baa\[[WVUTRMLKIHEDB@><86^da`\[[ZVTSRQLKHGEDB@=;=6 ^c``_[[ZUTSRQOJHGEDB?=?=6^cc`_[ZYXTSRPNMHGECA?A?=6kcc`_]ZYXWSQPNMLJHFECA?<6kcca^]\YXVRQPNMKIHFECA><6keba^]\YWVUQPNLKIHFEB@><6kebaa][[WVUTOMLKIHFDB@><3kedaa\[[WVUSRMLKIGEDB@>;@ked``_[[ZUTSRQLJHGEDB@=;@fecc`_[[YXTSRQNMHGEDA?A?@fgcc`_]ZYXTSQPNMLJECACA?@fgcc`^]ZYXWRQPNMLIHFECA>@fgfba^]\YWVUQPNMKIHFEC@>@fgeba^]\XWVUTPMLKIHFDB@>@febaa\[[WVUSRMLKIHEDB@>@fheda`\[[ZVTSRQLKHGEDB@==ahec``_[[YUTSRQOJHGEDB?==ahdcc`_^ZYXTSRPNMHGECA?A=mggcc`^]ZYXWSQPNMLJHFECA=mggcca^]\YXVRQPNMKIHFEC@:migeba^]\YWVUQPNLKIHFEB@:mifebaa][[WVUTOMLKIHEDB@:mhfeda`\[[WVUSRMLKIGEDB@:mhhed``_[[ZUTSRQLJHGEDB@:mhhdcc`_[[YXTSRQNMHGEDA?F mkggcc`_]ZYXTSQPNMLJECECF hjggccb^]ZYXWRQPNMLIHFECF hjggfba^]\YWVUQPNLKIHFECC hjigeba^]\XWVUTPMLKIHFDBC hjhfebaa\[[WVUSRMLKIHEDBChkhheda`\[[ZVTSRQLKHGEDBC hkhhec``_[[YUTSRQOJHGEDBCtkhhgcc`_^ZYXTSRPNMLGECACtkjggcc`^]ZYXWRQPNMLJHFECojjggcca^]\YXVUQPNMKIHFEComjigeba^]\XWVUQPNLKIHFE@omjifebaa][[WVUTOMLKIHED@omkhfeda`\[[WVUSRMLKIGED@olkhhed``_[[ZUTSRQLJHGED@olkhhdcc`_[[YXTSRQNMHGED@jnkkggcc`_]ZYXTSQPNMLJDCJjnjjggcca^]ZYXWRQPNMLIHFGjmmjggfba^]\YWVUQPNLKIHFGjmmjifebaa]\[WVUTPMLKIHFGjomjhfebaa\[[WVUSRMLKIHEGjolkhheda`_[[ZVTSRQLKHGEGunlkhhec``_[[YUTSRQNJHGEGunnkkhgcc`_^ZYXTSRPNMLGEEunnkjggcc`^]ZYXWRQPNMLJHEuqmjjggcca^]\YXVUQPNMKIHEupmmjigeba^]\XWVUQPNLKIHEpmjifebaa][[WVUTOMLKIHEpomkhheda`\[[WVTSRMLKIGEpolkhhed``_[[ZUTSRQLJHGEpqnnkhhdcc`_[ZYXTSRQNMHGECjb`]_X[XURORNKNIGHDAC>97.!cba^]\YWVUQPNMKIHFEC@><99!^ba^]\XWVUTPMLKIHFDB@><99 ^baa\[[WVUTRMLKIHEDB@><86^da`\[[ZVTSRQLKHGEDB@=;=6 ^c``_[[ZUTSRQOJHGEDB?=?=6^cc`_[ZYXTSRPNMHGECA?A?=6kcc`_]ZYXWSQPNMLJHFECA?<6kcca^]\YXVRQPNMKIHFECA><6keba^]\YWVUQPNLKIHFEB@><6kebaa][[WVUTOMLKIHFDB@><3kedaa\[[WVUSRMLKIGEDB@>;@ked``_[[ZUTSRQLJHGEDB@=;@fecc`_[[YXTSRQNMHGEDA?A?@fgcc`_]ZYXTSQPNMLJECACA?@fgcc`^]ZYXWRQPNMLIHFECA>@fgfba^]\YWVUQPNMKIHFEC@>@fgeba^]\XWVUTPMLKIHFDB@>@febaa\[[WVUSRMLKIHEDB@>@fheda`\[[ZVTSRQLKHGEDB@==ahec``_[[YUTSRQOJHGEDB?==ahdcc`_^ZYXTSRPNMHGECA?A=mggcc`^]ZYXWSQPNMLJHFECA=mggcca^]\YXVRQPNMKIHFEC@:migeba^]\YWVUQPNLKIHFEB@:mifebaa][[WVUTOMLKIHEDB@:mhfeda`\[[WVUSRMLKIGEDB@:mhhed``_[[ZUTSRQLJHGEDB@:mhhdcc`_[[YXTSRQNMHGEDA?F mkggcc`_]ZYXTSQPNMLJECECF hjggccb^]ZYXWRQPNMLIHFECF hjggfba^]\YWVUQPNLKIHFECC hjigeba^]\XWVUTPMLKIHFDBC hjhfebaa\[[WVUSRMLKIHEDBChkhheda`\[[ZVTSRQLKHGEDBC hkhhec``_[[YUTSRQOJHGEDBCtkhhgcc`_^ZYXTSRPNMLGECACtkjggcc`^]ZYXWRQPNMLJHFECojjggcca^]\YXVUQPNMKIHFEComjigeba^]\XWVUQPNLKIHFE@omjifebaa][[WVUTOMLKIHED@omkhfeda`\[[WVUSRMLKIGED@olkhhed``_[[ZUTSRQLJHGED@olkhhdcc`_[[YXTSRQNMHGED@jnkkggcc`_]ZYXTSQPNMLJDCJjnjjggcca^]ZYXWRQPNMLIHFGjmmjggfba^]\YWVUQPNLKIHFGjmmjifebaa]\[WVUTPMLKIHFGjomjhfebaa\[[WVUSRMLKIHEGjolkhheda`_[[ZVTSRQLKHGEGunlkhhec``_[[YUTSRQNJHGEGunnkkhgcc`_^ZYXTSRPNMLGEEunnkjggcc`^]ZYXWRQPNMLJHEuqmjjggcca^]\YXVUQPNMKIHEupmmjigeba^]\XWVUQPNLKIHEpmjifebaa][[WVUTOMLKIHEpomkhheda`\[[WVTSRMLKIGEpolkhhed``_[[ZUTSRQLJHGEpqnnkhhdcc`_[ZYXTSRQNMHGEC A@?>=;:98754311/.-+*)(% ca_][YXVTRPNLKIGECA@><: ca_][ZXVTRPOMKIGEDB@><: ca_^\ZXVTRQOMKIGFDB@><;ca`^\ZXVUSQOMKJHFDB@?=;db`^\ZXWUSQOMLJHFDBA?=;db`^\[YWUSQPNLJHFECA?=;db`^][YWUSRPNLJHGECA?=<dba_][YWVTRPNLKIGECA?><eca_][YXVTRPNMKIGECB@><eca_]\ZXVTRQOMKIGEDB@><eca_^\ZXVTSQOMKIHFDB@>=ecb`^\ZXWUSQOMLJHFDB@?=edb`^\ZYWUSQONLJHFDCA?=fdb`^][YWUSRPNLJHFECA?=fdb`_][YWUTRPNLJIGECA?>fdca_][YXVTRPNLKIGECA@>feca_][ZXVTRPOMKIGEDB@>geca_^\ZXVTSQOMKIGFDB@>geca`^\ZXVUSQOMKJHFDB@?gedb`^\ZYWUSQOMLJHFDBA?gfdb`^\[YWUSQPNLJHFECA?hfdb`_][YWUSRPNLJHGECA?hfdba_][YWVTRPNLKIGECA@hfeca_][YXVTRPNMKIGECB@hgeca_]\ZXVTRQOMKIGFDB@igeca`^\ZXVTSQOMKIHFDB@ igecb`^\ZXWUSQOMLJHFDB@ igfdb`^\ZYWUSQONLJHFDCA ihfdb`^][YWUSRPNLJHFECA jhfdb`_][YWUTRPNLJIGECA jhfdca_][YXVTRPNMKIGECA jhfeca_][ZXVTRPOMKIGEDB jigeca_^\ZXVTSQOMKIGFDBkigeca`^\ZXVUSQOMKJHFDBkigedb`^\ZYWUSQOMLJHFDBkigfdb`^\[YWUSQPNLJHFECkjhfdb`_][YWUTRPNLJHGECljhfdba_][YWVTRPNLKIGECljhfeca_][ZXVTRPNMKIGECljhgeca_]\ZXVTRQOMKIGFDlkigeca`^\ZXVTSQOMKIHFDmkigecb`^\ZXWUSQOMLJHFDmkigfdb`^\ZYWUSQONLJHFDmkihfdb`^][YWUSRPNLJHGEmljhfdba_][YWUTRPNLJIGEnljhfdca_][YXVTRPNMKIGEnljhgeca_][ZXVTRPOMKIGEnljigeca_^\ZXVTSQOMKIGFnmkigeca`^\ZXVUSQOMKJHFomkigedb`^\ZYWUSQONLJHFomkigfdb`^\[YWUSQPNLJHFomkjhfdb`_][YWUTRPNLJHGonljhfdba_][YWVTRPNLKIGpnljhfeca_][ZXVTRPNMKIGpnljhgeca_]\ZXVTRQOMKIGpnlkigeca`^\ZXVUSQOMKIHpnmkigecb`^\ZXWUSQOMLJHqomkigfdb`^\[YWUSQONLJH@@@@΀h qqqqqpppppooooonnnnnnmmmmmllkkkkkkjjjjjiiiiihhhhhgggggffffpqnnkkggcc`_]ZYXTSQPNMLJLpqqnjjggcca^]ZYXWRQPNMLILpqqmmjigfba^]\YWVUQPNLKILprpmmjifebaa]\[WVUTPMLKILvrpomjhfedaa\[[WVUSRMLKIIvrpolkhhed``_[[ZVTSRQLKHIvrrnlkhhec``_[[YUTSRQNJHIvqqnnkkggcc`_^ZYXTSRPNMLIvsqnnkjggcc`^]ZYXWRQPNMLIvsqqmjjggcca^]\YXVUQPNMKIqsqpmmjigeba^]\XWVUQPMLKIqrrpmmjifebaa][[WVUTOMLKIqurpomkhheda`\[[ZVTSRMLKIqurpnlkhhed``_[[ZUTSRQLJF{urqnnkhhdcc`_[ZYXTSRQNMF{tsqnnkkggcc`_]ZYXWSQPNMO{tsqqnjjggcca^]ZYXVRQPNMOvsqqmmjigfba^]\YWVUQPNLOvsrpmmjifebaa][[WVUTPMLMvrpomjhfedaa\[[WVUSRMLMvuurpolkhhed``_[[ZVTSRQLMvwurrnlkhhec``_[[YXTSRQNMvwuqqnnkkggcc`_^ZYXTSRPNMvwtsqnnkjggcc`^]ZYXWRQPNMvsqqmjjggcba^]\YXVUQPNMvxvsqpmmjigeba^]\XWVUQPMJvxvrrpmmjhfebaa][[WVUTOMJxuurpomkhheda`\[[ZVTSRMJ{wuurrnlkhhed``_[[ZUTSRQR{wwurqnnkhhdcc`_[ZYXTSRPP{ywtsqnnkkggcc`_]ZYXWSQPP{yvtsqqnjjggcca^]ZYXVRQPP{xvvsqpmmjigfba^]\YWVUQPP{xxvsrpmmjifebaa][[WVUTPP{zxurrpomjhfedaa\[[WVUSRPʀzwuurpolkhhed``_[[ZUTSRM̀ywwurrnlkhhec``_[[YXTSRMyywuqqnnkkggcc`_]ZYXTSRMހ{yvtsqnnkjggcc`^]ZYXWRQM߀{xvvsqqmjjggcba^]\YXVUQM؀zxxvsqpmmjigeba^]\XWVUTMۀzxxvrrpmmjhfebaa][[WVUTK{zzxuurpomkhheda`\[[ZVTSS{|ywwurrnlkhhec``_[[ZUTSS{ywwurqnnkhhdcc`_[ZYXTSS{ywtsqnnkjggcc`_]ZYXWSS{yvtsqqnjjggcca^]\YXVRS{}zxvvsqpmmjigfba^]\YWVUS|zxxvsrpmmjifebaa][[WVUS׀|zzxurrpomjhfedaa\[[WVUPڀ||zwuurpolkhhed``_[[ZUTP~{ywwurqnlkhhecc`_[[YXTP߀}{yywuqqnnkkggcc`_]ZYXTP}{{yvtsqnnkjggcc`^]ZYXWU|}}{xvvsqqmmjggfba^]\YWVU||zxxvsspmmjigeba^]\XWVU~|zzxvrrpomjhfebaa\[[WVU~||zwuurpomkhheda`\[[ZVUЃ~~|ywwurrnlkhhec``_[[ZUSك}{ywwurqnnkhhdcc`_[ZYXSՃ}{yywtsqnnkjggcc`_]ZYXZ}{{yvvsqqnjjggcca^]\YXZ}zxvvsqpmmjigeba^]\YWZ䀁|zxxvsrpmmjifebaa][[WZpqnnkkggcc`_]ZYXTSQPNMLJLpqqnjjggcca^]ZYXWRQPNMLILpqqmmjigfba^]\YWVUQPNLKILprpmmjifebaa]\[WVUTPMLKILvrpomjhfedaa\[[WVUSRMLKIIvrpolkhhed``_[[ZVTSRQLKHIvrrnlkhhec``_[[YUTSRQNJHIvqqnnkkggcc`_^ZYXTSRPNMLIvsqnnkjggcc`^]ZYXWRQPNMLIvsqqmjjggcca^]\YXVUQPNMKIqsqpmmjigeba^]\XWVUQPMLKIqrrpmmjifebaa][[WVUTOMLKIqurpomkhheda`\[[ZVTSRMLKIqurpnlkhhed``_[[ZUTSRQLJF{urqnnkhhdcc`_[ZYXTSRQNMF{tsqnnkkggcc`_]ZYXWSQPNMO{tsqqnjjggcca^]ZYXVRQPNMOvsqqmmjigfba^]\YWVUQPNLOvsrpmmjifebaa][[WVUTPMLMvrpomjhfedaa\[[WVUSRMLMvuurpolkhhed``_[[ZVTSRQLMvwurrnlkhhec``_[[YXTSRQNMvwuqqnnkkggcc`_^ZYXTSRPNMvwtsqnnkjggcc`^]ZYXWRQPNMvsqqmjjggcba^]\YXVUQPNMvxvsqpmmjigeba^]\XWVUQPMJvxvrrpmmjhfebaa][[WVUTOMJxuurpomkhheda`\[[ZVTSRMJ{wuurrnlkhhed``_[[ZUTSRQR{wwurqnnkhhdcc`_[ZYXTSRPP{ywtsqnnkkggcc`_]ZYXWSQPP{yvtsqqnjjggcca^]ZYXVRQPP{xvvsqpmmjigfba^]\YWVUQPP{xxvsrpmmjifebaa][[WVUTPP{zxurrpomjhfedaa\[[WVUSRPʀzwuurpolkhhed``_[[ZUTSRM̀ywwurrnlkhhec``_[[YXTSRMyywuqqnnkkggcc`_]ZYXTSRMހ{yvtsqnnkjggcc`^]ZYXWRQM߀{xvvsqqmjjggcba^]\YXVUQM؀zxxvsqpmmjigeba^]\XWVUTMۀzxxvrrpmmjhfebaa][[WVUTK{zzxuurpomkhheda`\[[ZVTSS{|ywwurrnlkhhec``_[[ZUTSS{ywwurqnnkhhdcc`_[ZYXTSS{ywtsqnnkjggcc`_]ZYXWSS{yvtsqqnjjggcca^]\YXVRS{}zxvvsqpmmjigfba^]\YWVUS|zxxvsrpmmjifebaa][[WVUS׀|zzxurrpomjhfedaa\[[WVUPڀ||zwuurpolkhhed``_[[ZUTP~{ywwurqnlkhhecc`_[[YXTP߀}{yywuqqnnkkggcc`_]ZYXTP}{{yvtsqnnkjggcc`^]ZYXWU|}}{xvvsqqmmjggfba^]\YWVU||zxxvsspmmjigeba^]\XWVU~|zzxvrrpomjhfebaa\[[WVU~||zwuurpomkhheda`\[[ZVUЃ~~|ywwurrnlkhhec``_[[ZUSك}{ywwurqnnkhhdcc`_[ZYXSՃ}{yywtsqnnkjggcc`_]ZYXZ}{{yvvsqqnjjggcca^]\YXZ}zxvvsqpmmjigeba^]\YWZ䀁|zxxvsrpmmjifebaa][[WZpqnnkkggcc`_]ZYXTSQPNMLJLpqqnjjggcca^]ZYXWRQPNMLILpqqmmjigfba^]\YWVUQPNLKILprpmmjifebaa]\[WVUTPMLKILvrpomjhfedaa\[[WVUSRMLKIIvrpolkhhed``_[[ZVTSRQLKHIvrrnlkhhec``_[[YUTSRQNJHIvqqnnkkggcc`_^ZYXTSRPNMLIvsqnnkjggcc`^]ZYXWRQPNMLIvsqqmjjggcca^]\YXVUQPNMKIqsqpmmjigeba^]\XWVUQPMLKIqrrpmmjifebaa][[WVUTOMLKIqurpomkhheda`\[[ZVTSRMLKIqurpnlkhhed``_[[ZUTSRQLJF{urqnnkhhdcc`_[ZYXTSRQNMF{tsqnnkkggcc`_]ZYXWSQPNMO{tsqqnjjggcca^]ZYXVRQPNMOvsqqmmjigfba^]\YWVUQPNLOvsrpmmjifebaa][[WVUTPMLMvrpomjhfedaa\[[WVUSRMLMvuurpolkhhed``_[[ZVTSRQLMvwurrnlkhhec``_[[YXTSRQNMvwuqqnnkkggcc`_^ZYXTSRPNMvwtsqnnkjggcc`^]ZYXWRQPNMvsqqmjjggcba^]\YXVUQPNMvxvsqpmmjigeba^]\XWVUQPMJvxvrrpmmjhfebaa][[WVUTOMJxuurpomkhheda`\[[ZVTSRMJ{wuurrnlkhhed``_[[ZUTSRQR{wwurqnnkhhdcc`_[ZYXTSRPP{ywtsqnnkkggcc`_]ZYXWSQPP{yvtsqqnjjggcca^]ZYXVRQPP{xvvsqpmmjigfba^]\YWVUQPP{xxvsrpmmjifebaa][[WVUTPP{zxurrpomjhfedaa\[[WVUSRPʀzwuurpolkhhed``_[[ZUTSRM̀ywwurrnlkhhec``_[[YXTSRMyywuqqnnkkggcc`_]ZYXTSRMހ{yvtsqnnkjggcc`^]ZYXWRQM߀{xvvsqqmjjggcba^]\YXVUQM؀zxxvsqpmmjigeba^]\XWVUTMۀzxxvrrpmmjhfebaa][[WVUTK{zzxuurpomkhheda`\[[ZVTSS{|ywwurrnlkhhec``_[[ZUTSS{ywwurqnnkhhdcc`_[ZYXTSS{ywtsqnnkjggcc`_]ZYXWSS{yvtsqqnjjggcca^]\YXVRS{}zxvvsqpmmjigfba^]\YWVUS|zxxvsrpmmjifebaa][[WVUS׀|zzxurrpomjhfedaa\[[WVUPڀ||zwuurpolkhhed``_[[ZUTP~{ywwurqnlkhhecc`_[[YXTP߀}{yywuqqnnkkggcc`_]ZYXTP}{{yvtsqnnkjggcc`^]ZYXWU|}}{xvvsqqmmjggfba^]\YWVU||zxxvsspmmjigeba^]\XWVU~|zzxvrrpomjhfebaa\[[WVU~||zwuurpomkhheda`\[[ZVUЃ~~|ywwurrnlkhhec``_[[ZUSك}{ywwurqnnkhhdcc`_[ZYXSՃ}{yywtsqnnkjggcc`_]ZYXZ}{{yvvsqqnjjggcca^]\YXZ}zxvvsqpmmjigeba^]\YWZ䀁|zxxvsrpmmjifebaa][[WZqomkihfdb`^][YWUSRPNLJHqomljhfdba_][YWUTRPNLJIqonljhfdca_][YXVTRPNMKIrpnljhgeca_][ZXVTRPOMKIrpnljigeca_^\ZXVTSQOMKIrpnmkigecb`^\ZXVUSQOMKJrpomkigedb`^\ZYWUSQONLJsqomkihfdb`^\[YWUSQPNLJsqomkjhfdb`_][YWUTRPNLJsqonljhfdba_][YWVTRPNLKsqpnljhfeca_][ZXVTRPOMKtrpnljhgeca_]\ZXVTRQOMKtrpnlkigeca`^\ZXVUSQOMKtrpomkigecb`^\ZXWUSQOMLtrqomkigfdb`^\[YWUSQONLusqomkihfdb`^][YWUSRPNLusqomljhfdba_][YWVTRPNLusqonljhfdca_][YXVTRPNMusrpnljhgeca_]\ZXVTRPOMutrpnljigeca_^\ZXVTSQOMvtrpnmkigecb`^\ZXVUSQOMvtrpomkigedb`^\ZYWUSQONvtsqomkihfdb`^\[YWUSQPNvusqomkjhfdb`_][YWUTRPNwusqonljhfdca_][YWVTRPNwusqpnljhfeca_][ZXVTRPOwutrpnljigeca_]\ZXVTRQOwvtrpnlkigeca`^\ZXVUSQOxvtrpomkigecb`^\ZXWUSQOxvtrqomkigfdb`^\[YWUSQP xvusqomkihfdb`^][YWUSRP xwusqomljhfdba_][YWVTRP ywusqpnljhfdca_][YXVTRP ywusrpnljhgeca_]\ZXVTRP ywvtrpnljigeca_^\ZXVTSQ yxvtrpnmkigecb`^\ZXWUSQ!zxvtrpomkigedb`^\ZYWUSQ!zxvtsqomkihfdb`^][YWUSQ!zxwusqomkjhfdb`_][YWUTR!zywusqonljhfdca_][YWVTR!{ywusqpnljhfeca_][ZXVTR!{ywutrpnljigeca_]\ZXVTR"{ywvtrpnlkigeca`^\ZXVUS"{zxvtrpomkigedb`^\ZXWUS"|zxvtrqomkigfdb`^\[YWUS"|zxvusqomkjhfdb`^][YWUS"|zxwusqomljhfdba_][YWVT"|{ywusqpnljhfdca_][YXVT" }{ywusrpnljhgeca_]\ZXVT" }{ywvtrpnljigeca_^\ZXVT# }{yxvtrpnmkigecb`^\ZXWU# }|zxvtrqomkigedb`^\ZYWU# ~|zxvtsqomkihfdb`^][YWU# ~|zxwusqomkjhfdb`_][YWU$!~|zywusqonljhfdca_][YXV$!~}{ywusqpnljhfeca_][ZXV$!}{ywutrpnljigeca_^\ZXV$!}{yxvtrpnlkigeca`^\ZXV$!}{zxvtrpomkigedb`^\ZXW%!~|zxvtrqomkigfdb`^\[YW%!~|zxvusqomkjhfdb`^][YW%"~|zxwusqomljhfdba_][YW%"~|{ywusqpnljhfeca_][YX%"~}{ywusrpnljhgeca_]\ZX%輻븷ﻼ񷸶캹뷸ﴵﴵ輻븷ﻼ񷸶캹뷸ﴵﴵ輻븷ﻼ񷸶캹뷸ﴵﴵԀ󻼻󺹺�򬭬󫪫󻼻󺹺�򬭬󫪫󻼻󺹺�򬭬󫪫ffeedddddccccccbbbbbaaaa濾a`澽`澽``潼`_𷶶_漻__滺_^^溹^]湸]湸]]渷]\촳\淶\\涵\[[浴[[洳[洳[Z泲ZZ豰Z沱ZY汰YYY氯Y~|zzxuurpomihfedaa\[[WZ~||zwuurpolkhhed``_[[ZW䇀~~{ywwurqnlkhhecc`_[[YW߇}{yywusqnnkkggcc`_]ZYWه}{{yvtsqnnkjggcc`^]ZYW僁}}{xvvsqqmmjggfba^]\YU߃|zxxvsrpmmjigeba^]\XU~|zzxvrrpomjhfebaa\[[UŃ~||zwuurpomkhheda`\[[\߃~~|ywwurrnlkhhec``_[[\ڃ}{ywwurqnnkhhdcc`_^Z\݃}{yywtsqnnkjggcc`^]Z\Ȋ}{{xvvsqqnjjggcca^]\Y}zxvvsqpmmjigeba^]\Y݇~|zxxvsrpmmjifebaa][Y凅~|zzxuurpomkhfedaa\[Yۇ~||zwuurpolkhhed``_[Wツ~~{ywwurqnlkhhdcc`_[W}{yywusqnnkkggcc`_]W˃}{{yvtsqnnjjggccb^]W䃅}}{xvvsqqmmjggfba^]]ϊ|zxxvsrpmmjigeba^]]ي~|zzxvrrpomjhfebaa\[ފ~||zwuurpomkhheda`\[ۊ~~|ywwurrnlkhhec``_[Ԅ}{ywwuqqnnkhhgcc`_a焂}{yywtsqnnkjggcc`^_ፈ}{{xvvsqqnjjggcca^_؍}zxvvsqpmmjigeba^_升~|zxxvsrpmmjifebaa_ۍ~|zzxuurpomkhfeda`_䍉~||ywuurpolkhhed``_Ս~{ywwurqnlkhhdcc`_≈}{yywusqnnkkggcc`]ى}{{yvtsqnnjjggcca]Չ}}{xvvsqqmmjggfba]؉|zxxvsrpmmjifebac䆉~|zzxvrrpomjhfebac܌~||zwuurpolkhhedac⌋~~|ywwurrnlkhhec`c錋}{yywuqqnnkkhgcc錊}{yywtsqnnkjggccٌ}}{xvvsqqmjjggcc`匋}zxvvsqpmmjigeb`ጋ~|zxxvrrpmmjifeb`ߓ~|zzxuurpomkhhed`双~||ywuurpolkhhed`㏌~{ywwurqnnkhhdcf䏌}{yywusqnnkkggcf⏍}{{yvtsqqnjjggcfߏ}}zxvvsqqmmjigfd反|zxxvsrpmmjifed⒍~|zzxvrrpomjhfed咎~||zwuurpolkhhed⒎~~|ywwurrnlkhhedߒ}{yywuqqnnkkggdے}{{ywtsqnnkjggdᒏ}}{xvvsqqmjjggdێ}zxvvsqpmmjiggԎ~|zxxvrrpmmjifg㔐~|zzxuurpomkhhg䔏~||ywuurpnlkhhg⑏~{ywwurqnnkhhgۑ}{yywtsqnnkkgg~|zzxuurpomihfedaa\[[WZ~||zwuurpolkhhed``_[[ZW䇀~~{ywwurqnlkhhecc`_[[YW߇}{yywusqnnkkggcc`_]ZYWه}{{yvtsqnnkjggcc`^]ZYW僁}}{xvvsqqmmjggfba^]\YU߃|zxxvsrpmmjigeba^]\XU~|zzxvrrpomjhfebaa\[[UŃ~||zwuurpomkhheda`\[[\߃~~|ywwurrnlkhhec``_[[\ڃ}{ywwurqnnkhhdcc`_^Z\݃}{yywtsqnnkjggcc`^]Z\Ȋ}{{xvvsqqnjjggcca^]\Y}zxvvsqpmmjigeba^]\Y݇~|zxxvsrpmmjifebaa][Y凅~|zzxuurpomkhfedaa\[Yۇ~||zwuurpolkhhed``_[Wツ~~{ywwurqnlkhhdcc`_[W}{yywusqnnkkggcc`_]W˃}{{yvtsqnnjjggccb^]W䃅}}{xvvsqqmmjggfba^]]ϊ|zxxvsrpmmjigeba^]]ي~|zzxvrrpomjhfebaa\[ފ~||zwuurpomkhheda`\[ۊ~~|ywwurrnlkhhec``_[Ԅ}{ywwuqqnnkhhgcc`_a焂}{yywtsqnnkjggcc`^_ፈ}{{xvvsqqnjjggcca^_؍}zxvvsqpmmjigeba^_升~|zxxvsrpmmjifebaa_ۍ~|zzxuurpomkhfeda`_䍉~||ywuurpolkhhed``_Ս~{ywwurqnlkhhdcc`_≈}{yywusqnnkkggcc`]ى}{{yvtsqnnjjggcca]Չ}}{xvvsqqmmjggfba]؉|zxxvsrpmmjifebac䆉~|zzxvrrpomjhfebac܌~||zwuurpolkhhedac⌋~~|ywwurrnlkhhec`c錋}{yywuqqnnkkhgcc錊}{yywtsqnnkjggccٌ}}{xvvsqqmjjggcc`匋}zxvvsqpmmjigeb`ጋ~|zxxvrrpmmjifeb`ߓ~|zzxuurpomkhhed`双~||ywuurpolkhhed`㏌~{ywwurqnnkhhdcf䏌}{yywusqnnkkggcf⏍}{{yvtsqqnjjggcfߏ}}zxvvsqqmmjigfd反|zxxvsrpmmjifed⒍~|zzxvrrpomjhfed咎~||zwuurpolkhhed⒎~~|ywwurrnlkhhedߒ}{yywuqqnnkkggdے}{{ywtsqnnkjggdᒏ}}{xvvsqqmjjggdێ}zxvvsqpmmjiggԎ~|zxxvrrpmmjifg㔐~|zzxuurpomkhhg䔏~||ywuurpnlkhhg⑏~{ywwurqnnkhhgۑ}{yywtsqnnkkgg~|zzxuurpomihfedaa\[[WZ~||zwuurpolkhhed``_[[ZW䇀~~{ywwurqnlkhhecc`_[[YW߇}{yywusqnnkkggcc`_]ZYWه}{{yvtsqnnkjggcc`^]ZYW僁}}{xvvsqqmmjggfba^]\YU߃|zxxvsrpmmjigeba^]\XU~|zzxvrrpomjhfebaa\[[UŃ~||zwuurpomkhheda`\[[\߃~~|ywwurrnlkhhec``_[[\ڃ}{ywwurqnnkhhdcc`_^Z\݃}{yywtsqnnkjggcc`^]Z\Ȋ}{{xvvsqqnjjggcca^]\Y}zxvvsqpmmjigeba^]\Y݇~|zxxvsrpmmjifebaa][Y凅~|zzxuurpomkhfedaa\[Yۇ~||zwuurpolkhhed``_[Wツ~~{ywwurqnlkhhdcc`_[W}{yywusqnnkkggcc`_]W˃}{{yvtsqnnjjggccb^]W䃅}}{xvvsqqmmjggfba^]]ϊ|zxxvsrpmmjigeba^]]ي~|zzxvrrpomjhfebaa\[ފ~||zwuurpomkhheda`\[ۊ~~|ywwurrnlkhhec``_[Ԅ}{ywwuqqnnkhhgcc`_a焂}{yywtsqnnkjggcc`^_ፈ}{{xvvsqqnjjggcca^_؍}zxvvsqpmmjigeba^_升~|zxxvsrpmmjifebaa_ۍ~|zzxuurpomkhfeda`_䍉~||ywuurpolkhhed``_Ս~{ywwurqnlkhhdcc`_≈}{yywusqnnkkggcc`]ى}{{yvtsqnnjjggcca]Չ}}{xvvsqqmmjggfba]؉|zxxvsrpmmjifebac䆉~|zzxvrrpomjhfebac܌~||zwuurpolkhhedac⌋~~|ywwurrnlkhhec`c錋}{yywuqqnnkkhgcc錊}{yywtsqnnkjggccٌ}}{xvvsqqmjjggcc`匋}zxvvsqpmmjigeb`ጋ~|zxxvrrpmmjifeb`ߓ~|zzxuurpomkhhed`双~||ywuurpolkhhed`㏌~{ywwurqnnkhhdcf䏌}{yywusqnnkkggcf⏍}{{yvtsqqnjjggcfߏ}}zxvvsqqmmjigfd反|zxxvsrpmmjifed⒍~|zzxvrrpomjhfed咎~||zwuurpolkhhed⒎~~|ywwurrnlkhhedߒ}{yywuqqnnkkggdے}{{ywtsqnnkjggdᒏ}}{xvvsqqmjjggdێ}zxvvsqpmmjiggԎ~|zxxvrrpmmjifg㔐~|zzxuurpomkhhg䔏~||ywuurpnlkhhg⑏~{ywwurqnnkhhgۑ}{yywtsqnnkkgg"}{ywvtrpnlkigeca_^\ZX%"}{yxvtrpnmkigecb`^\ZX&"}|zxvtrqomkigedb`^\ZY&"~|zxvtsqomkihfdb`^][Y&"~|zxwusqomkjhfdb`_][Y&#~|zywusqonljhfdca_][Y'#~}{ywusrpnljhfeca_][Z'#}{ywutrpnljigeca_^\Z'#}{yxvtrpnlkigeca`^\Z'#}{zxvtrpomkigedb`^\Z'#~|zxvtrqomkigfdb`^\['#~|zxvusqomkjhfdb`_]['#~|zywusqomljhfdba_][($~|{ywusqpnljhfeca_][($}{ywusrpnljhgeca_]\($}{ywvtrpnlkigeca_^\($}{yxvtrpnmkigecb`^\)%}|zxvtrqomkigfdb`^\)%~|zxvtsqomkihfdb`^])%~|zxwusqomljhfdb`_])%~|zywusqonljhfdca_])%~}{ywusrpnljhfeca_])%}{ywutrpnljigeca_^*%}{yxvtrpnlkigeca`^*%}{zxvtrpomkigedb`^*&~|zxvtsqomkigfdb`^*&~|zxvusqomkjhfdb`_+&~|zywusqomljhfdba_+&~|{ywusqpnljhfeca_+&}{ywusrpnljhgeca_+&}{ywvtrpnlkigeca`+&}{zxvtrpnmkigecb`+&}|zxvtrqomkigfdb`+'~|zxvtsqomkihfdb`,'~|zxwusqomljhfdba,'~|zywusqonljhfdca,'~}{ywusrpnljhgeca,(}{ywutrpnljigeca,(}{yxvtrpnmkigeca,(}{zxvtrpomkigedb,(~|zxvtsqomkigfdb,(~|zxvusqomkjhfdb,(~|zywusqonljhfdb-(~|{ywusqpnljhfec-(}{ywutrpnljhgec-(}{ywvtrpnlkigec-)}{zxvtrpnmkigec-)}|zxvtrqomkigfd-)~|zxvtsqomkihfd-)~|zxwusqomljhfd-)~|{ywusqonljhfd.)~}{ywusrpnljhge.*}{ywutrpnljige.*}{yxvtrpnmkige.*}{zxvtrpomkige.*~|zxvtsqomkihf.*~|zxvusqomkjhf.*~|zywusqonljhf.+~|{ywusqpnljhf/+}{ywutrpnljhg/+}{ywvtrpnlkig/+}{zxvtrpomkig/,}|zxvtrqomkig/,~|zxvusqomkih/󱰱𪫪򫪫𪫫ک򫪫楤⥤𬭬룤袡좡𞾽𞝞𝛜󱰱𪫪򫪫𪫫ک򫪫楤⥤𬭬룤袡좡𞾽𞝞𝛜󱰱𪫪򫪫𪫫ک򫪫楤⥤𬭬룤袡좡𞾽𞝞𝛜Ā󜝛񗘖񛚘󔒓皙󑒐򑒐󜝛񗘖񛚘󔒓皙󑒐򑒐󜝛񗘖񛚘󔒓皙󑒐򑒐X毮X毮XX殭XW歬W歬WV欫VVV櫪VU檩U檩UU橨UT樧T樧TT槦TSS榥SS楤S楤RR椣RR棢R棢RQ梡QQQ桠QP栟P栟PP柞PO枝O枝ON杜NNN望NM曚M曚MM暙ML晘L晘LL昗LKK琍}{{yvtsqqnjjgg⑐}}zxvvsqqmmjigᑐ|zxxvsrpmmjie◒~|zzxvrrpomjheח~||zwuurpolkhe򻼻嗑~~{ywwurrnlkheΓ}{yywuqqnnkke㑐}{{ywtsqnnkje}}{xvvsqqmjje򺹺̓}zxxvsqpmmjj▓~|zxxvrrpmmjh䖓~|zzxuurpomkh䖓~||ywuurrnlkh˖~{ywwurqnnkh喔}{yywtsqnnkhӖ}{{yvtsqqnjh䖔}}zxvvsqpmmhΛ|zxxvsrpmmhט~|zzxurrpomhԘ~||zwuurpolk㘕~~{ywwurrnlk䘖}{yywuqqnnk֕}{{ywtsqnnk啖}}{xvvsqqmkޚ|zxxvsqpmk㚗~|zxxvrrpmk՗~|zzxuurpok㗖~~|ywwurrnkݗ~{ywwurqnp嗘}{yywtsqnpږ}{{yvtsqqp᜙}}zxvvsqpn◕|zxxvsrpn疕~|zzxurrpnۙ~||zwuurpn☕~~{ywwurqn瘖}{yywuqqn䞙}{{yvtsqnۛ}}{xvvsqs㛚|zxxvssq䛚~|zxxvrrq㛜~|zzxuurq~~|ywwurq䙘}{ywwurq㝛}{yywtsq񬭬᝜}{{yvvsq᝛}}zxvvsq坛|zxxvsqޚ~|zzxurq㛘~||zwuuq~~{ywwuq埞}{yywusߟ}{{yvts䟞}}{xvvs㟝|zxxvs䟞~|zzxvs⟞~||zwus㡞~~|ywws𬭬ᡟ}{ywwsᡟ}{yywq⡟}{{yvvࡠ}zxvvᡟ~|zxxv䢟~|zzxv琍}{{yvtsqqnjjgg⑐}}zxvvsqqmmjigᑐ|zxxvsrpmmjie◒~|zzxvrrpomjheח~||zwuurpolkhe򻼻嗑~~{ywwurrnlkheΓ}{yywuqqnnkke㑐}{{ywtsqnnkje}}{xvvsqqmjje򺹺̓}zxxvsqpmmjj▓~|zxxvrrpmmjh䖓~|zzxuurpomkh䖓~||ywuurrnlkh˖~{ywwurqnnkh喔}{yywtsqnnkhӖ}{{yvtsqqnjh䖔}}zxvvsqpmmhΛ|zxxvsrpmmhט~|zzxurrpomhԘ~||zwuurpolk㘕~~{ywwurrnlk䘖}{yywuqqnnk֕}{{ywtsqnnk啖}}{xvvsqqmkޚ|zxxvsqpmk㚗~|zxxvrrpmk՗~|zzxuurpok㗖~~|ywwurrnkݗ~{ywwurqnp嗘}{yywtsqnpږ}{{yvtsqqp᜙}}zxvvsqpn◕|zxxvsrpn疕~|zzxurrpnۙ~||zwuurpn☕~~{ywwurqn瘖}{yywuqqn䞙}{{yvtsqnۛ}}{xvvsqs㛚|zxxvssq䛚~|zxxvrrq㛜~|zzxuurq~~|ywwurq䙘}{ywwurq㝛}{yywtsq񬭬᝜}{{yvvsq᝛}}zxvvsq坛|zxxvsqޚ~|zzxurq㛘~||zwuuq~~{ywwuq埞}{yywusߟ}{{yvts䟞}}{xvvs㟝|zxxvs䟞~|zzxvs⟞~||zwus㡞~~|ywws𬭬ᡟ}{ywwsᡟ}{yywq⡟}{{yvvࡠ}zxvvᡟ~|zxxv䢟~|zzxv琍}{{yvtsqqnjjgg⑐}}zxvvsqqmmjigᑐ|zxxvsrpmmjie◒~|zzxvrrpomjheח~||zwuurpolkhe򻼻嗑~~{ywwurrnlkheΓ}{yywuqqnnkke㑐}{{ywtsqnnkje}}{xvvsqqmjje򺹺̓}zxxvsqpmmjj▓~|zxxvrrpmmjh䖓~|zzxuurpomkh䖓~||ywuurrnlkh˖~{ywwurqnnkh喔}{yywtsqnnkhӖ}{{yvtsqqnjh䖔}}zxvvsqpmmhΛ|zxxvsrpmmhט~|zzxurrpomhԘ~||zwuurpolk㘕~~{ywwurrnlk䘖}{yywuqqnnk֕}{{ywtsqnnk啖}}{xvvsqqmkޚ|zxxvsqpmk㚗~|zxxvrrpmk՗~|zzxuurpok㗖~~|ywwurrnkݗ~{ywwurqnp嗘}{yywtsqnpږ}{{yvtsqqp᜙}}zxvvsqpn◕|zxxvsrpn疕~|zzxurrpnۙ~||zwuurpn☕~~{ywwurqn瘖}{yywuqqn䞙}{{yvtsqnۛ}}{xvvsqs㛚|zxxvssq䛚~|zxxvrrq㛜~|zzxuurq~~|ywwurq䙘}{ywwurq㝛}{yywtsq񬭬᝜}{{yvvsq᝛}}zxvvsq坛|zxxvsqޚ~|zzxurq㛘~||zwuuq~~{ywwuq埞}{yywusߟ}{{yvts䟞}}{xvvs㟝|zxxvs䟞~|zzxvs⟞~||zwus㡞~~|ywws𬭬ᡟ}{ywwsᡟ}{yywq⡟}{{yvvࡠ}zxvvᡟ~|zxxv䢟~|zzxv,~|zxwusqomljh/,~|{ywusqonljh/,~}{ywusrpnljh0,}{ywutrpnlji0,}{yxvtrpnmki0,}|zxvtrpomki0-~|zxvtsqomki0-~|zxvusqomkj0-~|zywusqonlj0-~|{ywusqpnlj0.}{ywutrpnlj1.}{ywvtrpnlk1.}{zxvtrpomk1.}|zxvtrqomk1.~|zxvusqomk1.~|zxwusqoml1.~|{ywusqpnl1.~}{ywusrpnl1/}{ywvtrpnl1/}{yxvtrpnm2/}|zxvtrpom2/~|zxvtsqom20~|zxvusqom20~|zywusqon20~}{ywusqpn20}{ywutrpn21}{ywvtrpn21}{zxvtrpo21}|zxvtrqo21~|zxvusqo21~|zxwusqo21~|{ywusqp32~}{ywusrp32}{ywvtrp32}{yxvtrp32}|zxvtrq32~|zxvtsq32~|zxwusq33~|zywusq33~}{ywusq43}{ywutr43}{ywvtr43}{zxvtr43~|zxvtr44~|zxvus44~|zxwus44~|{ywus44~}{ywus44}{ywvt44}{yxvt44}|zxvt45~|zxvt55~|zxwu55~|zywu55~}{ywu55}{ywu55}{yxv56}{zxv56~|zxv56~|zxv66~|zxw66~|{yw66}{yw67}{yw6𬭬휝𘖗𘖗𬭬험험󜝛񑒐񎏍ꑒ򚘙󒐑󍋌圝򑒐󒐑󍋌򌊋򑒐򑒐򌊋􋊋򑒐􊈉󒐑쌊򑒐󉊈󒐑ꍋ쌊򑒐󒐑슈卋䌊拊򑒐튈앓錊닊򑒐䉊󒐑쉇~𬭬휝𘖗𘖗𬭬험험󜝛񑒐񎏍ꑒ򚘙󒐑󍋌圝򑒐󒐑󍋌򌊋򑒐򑒐򌊋􋊋򑒐􊈉󒐑쌊򑒐󉊈󒐑ꍋ쌊򑒐󒐑슈卋䌊拊򑒐튈앓錊닊򑒐䉊󒐑쉇~𬭬휝𘖗𘖗𬭬험험󜝛񑒐񎏍ꑒ򚘙󒐑󍋌圝򑒐󒐑󍋌򌊋򑒐򑒐򌊋􋊋򑒐􊈉󒐑쌊򑒐󉊈󒐑ꍋ쌊򑒐󒐑슈卋䌊拊򑒐튈앓錊닊򑒐䉊󒐑쉇~򗖕򑒐󒐑􍋌򑒐󒐑񍋌򌊋󋊋󌊋򉊈􉇈珎񋊋獋獌틊슈狊~슋~銈狊~~|爉~|片~}~片~}~~򇈆~}|~󈆇~}|~熇~}~|}z燅~}~|}{|~}|{|~}|{z|熄~}~|}{|z|焅~}~|}{|z{x~}|{zyx~}|{zyz烄~}~|}{|z{yzz焂~}~|}{|z{yzx|~}~|}{|z{yzxyx~}|{zyzxyx~}|}{|z{yzxywx灂~}~|}{|z{yzxywxx炀~}~|}{|z{yzxywxvy~}|{zyxywxvy~}|{|z{yzxywxvwu灀~}~|}{|z{yzxywxvwuu瀁~}~|}{|z{yzxywxvwwvu~~}}||{{zzyyxxwwxvwuvq~}|{z{yzxywxvwuvts~}~|}{|z{yzxywxvwuvtus}~|}{|z{yzxywxvwuvvuus򗖕򑒐󒐑􍋌򑒐󒐑񍋌򌊋󋊋󌊋򉊈􉇈珎񋊋獋獌틊슈狊~슋~銈狊~~|爉~|片~}~片~}~~򇈆~}|~󈆇~}|~熇~}~|}z燅~}~|}{|~}|{|~}|{z|熄~}~|}{|z|焅~}~|}{|z{x~}|{zyx~}|{zyz烄~}~|}{|z{yzz焂~}~|}{|z{yzx|~}~|}{|z{yzxyx~}|{zyzxyx~}|}{|z{yzxywx灂~}~|}{|z{yzxywxx炀~}~|}{|z{yzxywxvy~}|{zyxywxvy~}|{|z{yzxywxvwu灀~}~|}{|z{yzxywxvwuu瀁~}~|}{|z{yzxywxvwwvu~~}}||{{zzyyxxwwxvwuvq~}|{z{yzxywxvwuvts~}~|}{|z{yzxywxvwuvtus}~|}{|z{yzxywxvwuvvuus򗖕򑒐󒐑􍋌򑒐󒐑񍋌򌊋󋊋󌊋򉊈􉇈珎񋊋獋獌틊슈狊~슋~銈狊~~|爉~|片~}~片~}~~򇈆~}|~󈆇~}|~熇~}~|}z燅~}~|}{|~}|{|~}|{z|熄~}~|}{|z|焅~}~|}{|z{x~}|{zyx~}|{zyz烄~}~|}{|z{yzz焂~}~|}{|z{yzx|~}~|}{|z{yzxyx~}|{zyzxyx~}|}{|z{yzxywx灂~}~|}{|z{yzxywxx炀~}~|}{|z{yzxywxvy~}|{zyxywxvy~}|{|z{yzxywxvwu灀~}~|}{|z{yzxywxvwuu瀁~}~|}{|z{yzxywxvwwvu~~}}||{{zzyyxxwwxvwuvq~}|{z{yzxywxvwuvts~}~|}{|z{yzxywxvwuvtus}~|}{|z{yzxywxvwuvvuus旖KK斕K斕JJ敔JJ攓J攓JI擒III撑IH摐HGG搏GG揎G揎GF掍FF􆅅F捌FE挋EEE拊ED抉D抉DD扈~D~C򂁁~~}C戇~~}C~}C懆~~}}|C~}|B~}|B憅~~}}||{B~}|{B慄~~}}||{{zB慄~~}}||{{zB~}|{zA愃~~}}||{{zzyA~}|{zy@~}}||{{zzyyx@惂~~}}||{{zzyyx@~}|{zyx@悁~~}}||{{zzyyxxw@~}|{zyxw?~}|{zyxw?恀~~}}||{{zzyyxxwwv?~}|{zyxwv?~~}}||{{zzyyxxwwvvu?~~}}||{{zzyyxxwwvvu?~}|{zyxwvu>~~}}||{{zzyyxxwwvvuut>~}|{zyxwvut>ߢ~||zwvࢡ~~{ywv墠}{yyv⟠}{{yt⟢}}{xt㤢|zxyᤡ~|zzy⡢~||zyᡢ~~|yyڦ}{yyۦ}{yyߦ}{{v梠}zvݣ~|zv࢟~|z{⧣~||{৥~{{৥}{{㣠}{{ᣢ}}{थ|{㩥~|{䩤~|⩦~~奢}}દ}}ᪧ}}媦}દ~}㪨~}䧨~}⫧}㫨{㫨{߫{禥ޭ𗘖߭㭫姦㨦}험⪫}媫}ޫ穨󜝛穨窧᫬⫬ޭ򑒐᪩񑒐䭬۱ᱮⱮ򑒐޲󒐑޲Ѳٲ򑒐ڲ󒐑㬫󍋌⳯􌊋ܳ򑒐ݳ򑒐ߢ~||zwvࢡ~~{ywv墠}{yyv⟠}{{yt⟢}}{xt㤢|zxyᤡ~|zzy⡢~||zyᡢ~~|yyڦ}{yyۦ}{yyߦ}{{v梠}zvݣ~|zv࢟~|z{⧣~||{৥~{{৥}{{㣠}{{ᣢ}}{थ|{㩥~|{䩤~|⩦~~奢}}દ}}ᪧ}}媦}દ~}㪨~}䧨~}⫧}㫨{㫨{߫{禥ޭ𗘖߭㭫姦㨦}험⪫}媫}ޫ穨󜝛穨窧᫬⫬ޭ򑒐᪩񑒐䭬۱ᱮⱮ򑒐޲󒐑޲Ѳٲ򑒐ڲ󒐑㬫󍋌⳯􌊋ܳ򑒐ݳ򑒐ߢ~||zwvࢡ~~{ywv墠}{yyv⟠}{{yt⟢}}{xt㤢|zxyᤡ~|zzy⡢~||zyᡢ~~|yyڦ}{yyۦ}{yyߦ}{{v梠}zvݣ~|zv࢟~|z{⧣~||{৥~{{৥}{{㣠}{{ᣢ}}{थ|{㩥~|{䩤~|⩦~~奢}}દ}}ᪧ}}媦}દ~}㪨~}䧨~}⫧}㫨{㫨{߫{禥ޭ𗘖߭㭫姦㨦}험⪫}媫}ޫ穨󜝛穨窧᫬⫬ޭ򑒐᪩񑒐䭬۱ᱮⱮ򑒐޲󒐑޲Ѳٲ򑒐ڲ󒐑㬫󍋌⳯􌊋ܳ򑒐ݳ򑒐7}{yx67}|zx67~|zx68~|zx78~|zy78~}{y78}{y79}{y79}{z79~|z79~|z79~|z8:~|{8:}{8:}{8:}{8:}|8:~|8;~|8;~|8;~}8;}8;}8;}8<~9<~9<~9<~9<9<9=9=9=:=:=:>:>:>:>:?:?;?;?;@;@;@;@;@;@<A<A<A<A<A<A<B<B=B=B=B=C=C=C=C=獋~󜝛닊~}򑒐߉~~}}󒐑䊈~}~ݍ~}~|錊~}|~}|{򑒐ۊ~}~|}{ވ~}~|}{|錊~}|{z닊~}|{z򑒐Ԋ~}~|}{|z{󒐑܉~}~|}{|z{y獋~}|{zy혙닊~}|{zyz򑒐Ӊ~}~|}{|z{yzx󒐑܉~}~|}{|z{yzxyӍ~}~|}{|z{yzxyw錊~}|{zyxyw򑒐~}|}{|z{yzxywx򑒐͊~}~|}{|z{yzxywxvш~}~|}{|z{yzxywxvw錊~}|{zyxywxvw닊~}|{z{yzxywxvwu򑒐Ԋ~}~|}{|z{yzxywxvwuv󒐑ω~}~|}{|z{yzxywxvwuvv錊~}|{zyxwxvwuvu닊~}|{zyzxywxvwuvtu򑒐҉~}~|}{|z{yzxywxvwuvtuu󒐑ω~}~|}{|z{yzxywxvwuvvuus獋~}~|}{|z{yzxywxxwwvvuuss錊~}|{zyzxywxvwuvtursq퉊~}|}{|z{yzxywxvwuvturssr͊~}~|}{|z{yzxywxvwuvvuussrrƍ~}~|}{|z{yzxywxvwwvvuussrrq錊~}|{zyxywxvwuvtursqrrq닊~}|{|z{yzxywxvwuvturssrrqqĊ~}~|}{|z{yzxywxvwuvtuussrrqqp~}~|}{|z{yzxywxvwwvvuussrrqqrp~}|{zyxwxvwuvtursqrrqrpq~}|{z{yzxywxvwuvturssrrqqppnÉ~}~|}{|z{yzxywxvwuvtuussrrqqppqn~}~|}{|z{yzxywxvwuvvuussrrqqppqno~}|{zyzxywxxwwvvuussrrqqrpqnom~}|{zyzxywxvwuvtursqrrqqppnnomÉ~}~|}{|z{yzxywxvwuvtuussrrqqppnnomn~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnl~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnnm~}|{zyxywxvwuvtursqrrqqppnnmmnlm~}|{|z{yzxywxvwuvturssrrqqppnnomnlmj~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmk~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkk~}|{zyxywxvwuvtursqrrqqppnnmnnmmkkj~}|{z{yzxywxvwuvturssrrqqppnnomnlmjkkj~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmkkjj~}~|}{|z{yzxywxvwuvvuussrrqqrpqnomnlmmkkjjk~}|{zyxwxwwvvuussrrqqrpqnomnnmmkkjjkh~}|{zyzxywxvwuvturssrrqqppnnomnlmjkkjjhh~}~|}{|z{yzxywxvwuvtuussrrqqppnnomnlmjkkjjhhi~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhig~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnnmmkkjjkhigh~}|{zyxywxvwuvtursqrrqqppnnmmnlmjkkjjhhggh~}|}{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighf~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfg獋~󜝛닊~}򑒐߉~~}}󒐑䊈~}~ݍ~}~|錊~}|~}|{򑒐ۊ~}~|}{ވ~}~|}{|錊~}|{z닊~}|{z򑒐Ԋ~}~|}{|z{󒐑܉~}~|}{|z{y獋~}|{zy혙닊~}|{zyz򑒐Ӊ~}~|}{|z{yzx󒐑܉~}~|}{|z{yzxyӍ~}~|}{|z{yzxyw錊~}|{zyxyw򑒐~}|}{|z{yzxywx򑒐͊~}~|}{|z{yzxywxvш~}~|}{|z{yzxywxvw錊~}|{zyxywxvw닊~}|{z{yzxywxvwu򑒐Ԋ~}~|}{|z{yzxywxvwuv󒐑ω~}~|}{|z{yzxywxvwuvv錊~}|{zyxwxvwuvu닊~}|{zyzxywxvwuvtu򑒐҉~}~|}{|z{yzxywxvwuvtuu󒐑ω~}~|}{|z{yzxywxvwuvvuus獋~}~|}{|z{yzxywxxwwvvuuss錊~}|{zyzxywxvwuvtursq퉊~}|}{|z{yzxywxvwuvturssr͊~}~|}{|z{yzxywxvwuvvuussrrƍ~}~|}{|z{yzxywxvwwvvuussrrq錊~}|{zyxywxvwuvtursqrrq닊~}|{|z{yzxywxvwuvturssrrqqĊ~}~|}{|z{yzxywxvwuvtuussrrqqp~}~|}{|z{yzxywxvwwvvuussrrqqrp~}|{zyxwxvwuvtursqrrqrpq~}|{z{yzxywxvwuvturssrrqqppnÉ~}~|}{|z{yzxywxvwuvtuussrrqqppqn~}~|}{|z{yzxywxvwuvvuussrrqqppqno~}|{zyzxywxxwwvvuussrrqqrpqnom~}|{zyzxywxvwuvtursqrrqqppnnomÉ~}~|}{|z{yzxywxvwuvtuussrrqqppnnomn~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnl~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnnm~}|{zyxywxvwuvtursqrrqqppnnmmnlm~}|{|z{yzxywxvwuvturssrrqqppnnomnlmj~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmk~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkk~}|{zyxywxvwuvtursqrrqqppnnmnnmmkkj~}|{z{yzxywxvwuvturssrrqqppnnomnlmjkkj~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmkkjj~}~|}{|z{yzxywxvwuvvuussrrqqrpqnomnlmmkkjjk~}|{zyxwxwwvvuussrrqqrpqnomnnmmkkjjkh~}|{zyzxywxvwuvturssrrqqppnnomnlmjkkjjhh~}~|}{|z{yzxywxvwuvtuussrrqqppnnomnlmjkkjjhhi~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhig~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnnmmkkjjkhigh~}|{zyxywxvwuvtursqrrqqppnnmmnlmjkkjjhhggh~}|}{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighf~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfg獋~󜝛닊~}򑒐߉~~}}󒐑䊈~}~ݍ~}~|錊~}|~}|{򑒐ۊ~}~|}{ވ~}~|}{|錊~}|{z닊~}|{z򑒐Ԋ~}~|}{|z{󒐑܉~}~|}{|z{y獋~}|{zy혙닊~}|{zyz򑒐Ӊ~}~|}{|z{yzx󒐑܉~}~|}{|z{yzxyӍ~}~|}{|z{yzxyw錊~}|{zyxyw򑒐~}|}{|z{yzxywx򑒐͊~}~|}{|z{yzxywxvш~}~|}{|z{yzxywxvw錊~}|{zyxywxvw닊~}|{z{yzxywxvwu򑒐Ԋ~}~|}{|z{yzxywxvwuv󒐑ω~}~|}{|z{yzxywxvwuvv錊~}|{zyxwxvwuvu닊~}|{zyzxywxvwuvtu򑒐҉~}~|}{|z{yzxywxvwuvtuu󒐑ω~}~|}{|z{yzxywxvwuvvuus獋~}~|}{|z{yzxywxxwwvvuuss錊~}|{zyzxywxvwuvtursq퉊~}|}{|z{yzxywxvwuvturssr͊~}~|}{|z{yzxywxvwuvvuussrrƍ~}~|}{|z{yzxywxvwwvvuussrrq錊~}|{zyxywxvwuvtursqrrq닊~}|{|z{yzxywxvwuvturssrrqqĊ~}~|}{|z{yzxywxvwuvtuussrrqqp~}~|}{|z{yzxywxvwwvvuussrrqqrp~}|{zyxwxvwuvtursqrrqrpq~}|{z{yzxywxvwuvturssrrqqppnÉ~}~|}{|z{yzxywxvwuvtuussrrqqppqn~}~|}{|z{yzxywxvwuvvuussrrqqppqno~}|{zyzxywxxwwvvuussrrqqrpqnom~}|{zyzxywxvwuvtursqrrqqppnnomÉ~}~|}{|z{yzxywxvwuvtuussrrqqppnnomn~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnl~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnnm~}|{zyxywxvwuvtursqrrqqppnnmmnlm~}|{|z{yzxywxvwuvturssrrqqppnnomnlmj~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmk~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkk~}|{zyxywxvwuvtursqrrqqppnnmnnmmkkj~}|{z{yzxywxvwuvturssrrqqppnnomnlmjkkj~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmkkjj~}~|}{|z{yzxywxvwuvvuussrrqqrpqnomnlmmkkjjk~}|{zyxwxwwvvuussrrqqrpqnomnnmmkkjjkh~}|{zyzxywxvwuvturssrrqqppnnomnlmjkkjjhh~}~|}{|z{yzxywxvwuvtuussrrqqppnnomnlmjkkjjhhi~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhig~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnnmmkkjjkhigh~}|{zyxywxvwuvtursqrrqqppnnmmnlmjkkjjhhggh~}|}{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighf~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfg~~~~~}~~}}~~}}~~}}|~~}}||~~}}||{~~}}||{~~}}||{{~~}}||{{z~~}}||{{zz~~}}||{{zz~~}}||{{zzy~~}}||{{zzyy~~}}||{{zzyyx~~}}||{{zzyyxx~~}}||{{zzyyxx~~}}||{{zzyyxxw~~}}||{{zzyyxxww~~}}||{{zzyyxxwwv~~}}||{{zzyyxxwwv~~}}||{{zzyyxxwwvv~~}}||{{zzyyxxwwvvu~~}}||{{zzyyxxwwvvuu~~}}||{{zzyyxxwwvvut~~}}||{{zzyyxxwwvvuut~~}}||{{zzyyxxwwvvuutt~~}}||{{zzyyxxwwvvuutts~}}||{{zzyyxxwwvvuuttss~~}}||{{zzyyxxwwvvuuttss~~}}||{{zzyyxxwwvvuuttssr~~}}||{{zzyyxxwwvvuuttssrr~~}}||{{zzyyxxwwvvuuttssrrq~~}}||{{zzyyxxwwvvuuttssrrq~~}}||{{zzyyxxwwvvuuttssrrqq~~}}||{{zzyyxxwwvvuuttssrrqqp~~}}||{{zzyyxxwwvvuuttssrrqqpp~~}}||{{zzyyxxwwvvuuttssrrqppo~~}}||{{zzyyxxwwvvuuttssrrqqppo~~}}||{{zzyyxxwwvvuuttssrrqqppoo~~}}||{{zzyyxxwwvvuuttssrrqqppoon~~}}||{{zyyxxwwvvuuttssrrqqppoonn~~}}||{{zzyyxxwwvvuuttssrrqqppoonn~~}}||{{zzyyxxwwvvuuttssrrqqppoonnm~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmm~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmml~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmml~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmll~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllk~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkk~~}}||{{zzyyxxwwvvuuttssrrqqppoonmmllkkj~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkj~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjj~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjji~~}}||{{zzyyxxwvvuuttssrrqqppoonnmmllkkjjii~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjii~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiih~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihh~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhg~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhg~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhgg~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggf}|{z{yzxywxxwwvvuuss}||{{zzyyzxywxvwuvturso~|}{|z{yzxywxvwuvturssq|}{|z{yzxywxvwuvvuussrq}{|z{yzxywxvwwvvuussrrq{zyxywxvwuvtursqrrq{|z{yzxywxvwuvturssrrqq|z{yzxywxvwuvtuussrrqqoz{yzxywxvwwvvuussrrqqrozyyxxywxvwuvtursqrrqqpo{yzxywxvwuvturssrrqqppoyzxywxvwuvtuussrrqqppqozxywxvwuvvuussrrqqrpqnpxwxxwwvvuussrrqqrpqnolxywxvwuvtursqrrqqppnnolywxvwuvtuussrrqqppnnomlwxvwuvvuussrrqqppqnomnlxvwwvvuussrrqqrpqnomnnxvwuvtursqrrqqppnnmmnlnvwuvturssrrqqppnnomnlmjwuvtuussrrqqppqnomnlmmkwvvuussrrqqrpqnomnlmmkkuvtursqrrqqppnnmmnlmkkvturssrrqqppnnomnlmjkktuussrrqqppqnomnlmmkkjkusrqrpqnomnlmmkkjjmussrrsqrpqnomnnmmkkjjkirssrrqqppnnomnlmjkkjjhisrqpnomnlmjkkjjhhisrrqqppqnomnlmmkkjjhhiirqrpqnomnnmmkkjjkhigkrqpnmnlmjkkjjhhggkrqqppnnomnlmjkkjjhhighfqpqnomnlmmkkjjhhighffqrpqnomnnmmkkjjkhighhgfqppnnmmnlmjkijjhhghhggcpnomnlmjkkjjhhighfgdcpqnomnlmmkkjjhhighfggecqnomnlmmkkjjkhighfggeecnomnnmmkkjjkhighhggeefcnomnlmjkkjjhhgghfgdeeccomnlmjkkjjhhighfggeeccemnlmmkkjjhhighfggeeccd`nmkjkhighhggeefcdb`nlmjkkjjhhgghfgdeeccbb`lmjkkjjhhighfggeeccdbc`mkjhighfggeeccdbc`bmkkjjkhighhggeefcdbccabjkijjhhgghfgdefcdbccaabkjhighfgdeeccdbc`aa]kjjhhighfggeeccdbc`aa`]jkhighfggeeccdbccaa``_jkhighhggeefcdbccaa``a_jhhgghfgdeeccbbc`aa``^_highfggeeccdbc`aa``a^_highfggeeccdbccaa``a^_Zighhggeefcdbccaa``a^__\ghfgdeeccbbc`aa``^^_\\ghfggeeccdbc`aa``^^_\]\hfggeeccdbc`aa``a^_\]]^hggeefcdbccaa``a^__]][^fgdeeccbbcaab`a^__]]^[^gecdbc`aa``^^_\]][[^geeccdbc`aa``a^_\]][[\X}|{z{yzxywxxwwvvuuss}||{{zzyyzxywxvwuvturso~|}{|z{yzxywxvwuvturssq|}{|z{yzxywxvwuvvuussrq}{|z{yzxywxvwwvvuussrrq{zyxywxvwuvtursqrrq{|z{yzxywxvwuvturssrrqq|z{yzxywxvwuvtuussrrqqoz{yzxywxvwwvvuussrrqqrozyyxxywxvwuvtursqrrqqpo{yzxywxvwuvturssrrqqppoyzxywxvwuvtuussrrqqppqozxywxvwuvvuussrrqqrpqnpxwxxwwvvuussrrqqrpqnolxywxvwuvtursqrrqqppnnolywxvwuvtuussrrqqppnnomlwxvwuvvuussrrqqppqnomnlxvwwvvuussrrqqrpqnomnnxvwuvtursqrrqqppnnmmnlnvwuvturssrrqqppnnomnlmjwuvtuussrrqqppqnomnlmmkwvvuussrrqqrpqnomnlmmkkuvtursqrrqqppnnmmnlmkkvturssrrqqppnnomnlmjkktuussrrqqppqnomnlmmkkjkusrqrpqnomnlmmkkjjmussrrsqrpqnomnnmmkkjjkirssrrqqppnnomnlmjkkjjhisrqpnomnlmjkkjjhhisrrqqppqnomnlmmkkjjhhiirqrpqnomnnmmkkjjkhigkrqpnmnlmjkkjjhhggkrqqppnnomnlmjkkjjhhighfqpqnomnlmmkkjjhhighffqrpqnomnnmmkkjjkhighhgfqppnnmmnlmjkijjhhghhggcpnomnlmjkkjjhhighfgdcpqnomnlmmkkjjhhighfggecqnomnlmmkkjjkhighfggeecnomnnmmkkjjkhighhggeefcnomnlmjkkjjhhgghfgdeeccomnlmjkkjjhhighfggeeccemnlmmkkjjhhighfggeeccd`nmkjkhighhggeefcdb`nlmjkkjjhhgghfgdeeccbb`lmjkkjjhhighfggeeccdbc`mkjhighfggeeccdbc`bmkkjjkhighhggeefcdbccabjkijjhhgghfgdefcdbccaabkjhighfgdeeccdbc`aa]kjjhhighfggeeccdbc`aa`]jkhighfggeeccdbccaa``_jkhighhggeefcdbccaa``a_jhhgghfgdeeccbbc`aa``^_highfggeeccdbc`aa``a^_highfggeeccdbccaa``a^_Zighhggeefcdbccaa``a^__\ghfgdeeccbbc`aa``^^_\\ghfggeeccdbc`aa``^^_\]\hfggeeccdbc`aa``a^_\]]^hggeefcdbccaa``a^__]][^fgdeeccbbcaab`a^__]]^[^gecdbc`aa``^^_\]][[^geeccdbc`aa``a^_\]][[\X}|{z{yzxywxxwwvvuuss}||{{zzyyzxywxvwuvturso~|}{|z{yzxywxvwuvturssq|}{|z{yzxywxvwuvvuussrq}{|z{yzxywxvwwvvuussrrq{zyxywxvwuvtursqrrq{|z{yzxywxvwuvturssrrqq|z{yzxywxvwuvtuussrrqqoz{yzxywxvwwvvuussrrqqrozyyxxywxvwuvtursqrrqqpo{yzxywxvwuvturssrrqqppoyzxywxvwuvtuussrrqqppqozxywxvwuvvuussrrqqrpqnpxwxxwwvvuussrrqqrpqnolxywxvwuvtursqrrqqppnnolywxvwuvtuussrrqqppnnomlwxvwuvvuussrrqqppqnomnlxvwwvvuussrrqqrpqnomnnxvwuvtursqrrqqppnnmmnlnvwuvturssrrqqppnnomnlmjwuvtuussrrqqppqnomnlmmkwvvuussrrqqrpqnomnlmmkkuvtursqrrqqppnnmmnlmkkvturssrrqqppnnomnlmjkktuussrrqqppqnomnlmmkkjkusrqrpqnomnlmmkkjjmussrrsqrpqnomnnmmkkjjkirssrrqqppnnomnlmjkkjjhisrqpnomnlmjkkjjhhisrrqqppqnomnlmmkkjjhhiirqrpqnomnnmmkkjjkhigkrqpnmnlmjkkjjhhggkrqqppnnomnlmjkkjjhhighfqpqnomnlmmkkjjhhighffqrpqnomnnmmkkjjkhighhgfqppnnmmnlmjkijjhhghhggcpnomnlmjkkjjhhighfgdcpqnomnlmmkkjjhhighfggecqnomnlmmkkjjkhighfggeecnomnnmmkkjjkhighhggeefcnomnlmjkkjjhhgghfgdeeccomnlmjkkjjhhighfggeeccemnlmmkkjjhhighfggeeccd`nmkjkhighhggeefcdb`nlmjkkjjhhgghfgdeeccbb`lmjkkjjhhighfggeeccdbc`mkjhighfggeeccdbc`bmkkjjkhighhggeefcdbccabjkijjhhgghfgdefcdbccaabkjhighfgdeeccdbc`aa]kjjhhighfggeeccdbc`aa`]jkhighfggeeccdbccaa``_jkhighhggeefcdbccaa``a_jhhgghfgdeeccbbc`aa``^_highfggeeccdbc`aa``a^_highfggeeccdbccaa``a^_Zighhggeefcdbccaa``a^__\ghfgdeeccbbc`aa``^^_\\ghfggeeccdbc`aa``^^_\]\hfggeeccdbc`aa``a^_\]]^hggeefcdbccaa``a^__]][^fgdeeccbbcaab`a^__]]^[^gecdbc`aa``^^_\]][[^geeccdbc`aa``a^_\]][[\X~}|{zzyyxxwwvvuutts>~}}||{{zzyyxxwwvvuutts>}|{zyxwvuts=}||{{zzyyxxwwvvuuttssr=|{zyxwvutsr=|{zyxwvutsr=|{{zzyyxxwwvvuuttssrrq={zyxwvutsrq<{zzyyxxwwvvuuttssrrqqp<{zzyyxxwwvvuuttssrrqqp<zyxwvutsrqp<zyyxxwwvvuuttssrrqqppo<yxwvutsrqpo;yxwwvvuuttssrrqqppoon;yxxwwvvuuttssrrqqppoon;xwvutsrqpon;xwwvvuuttssrrqqppoonnm;wvutsrqponm:wvutsrqponm:wvvuuttssrrqqppoonnmml:vutsrqponml9vuuttssrrqqppoonnmmllk9vuuttssrrqqppoonnmmlkk9utsrqponmlk9uttssrrqqppoonnmmllkkj9tsrqponmlkj8tssrrqqppoonnmmllkkjji8tssrrqqppoonnmmllkkjji8srqponmlkji8srrqqppoonnmmllkkjjiih8rqponmlkjih7rqponmlkjih7rqqppoonnmmllkkjjiihhg7qponmlkjihg7qppoonnmmllkkjjiihhggf7qppoonnmmllkkjjiihggff6ponmlkjihgf6poonnmmllkkjjiihhggffe6onmlkjihgfe6onnmmllkkjjiihhggffeed6onnmmllkkjjiihhggffeed6nmlkjihgfed5nmmllkkjjiihhggffeeddc5mlkjihgfedc5mlkjihgfedc5mllkkjjiihhggffeeddccb5lkjihgfedcb4lkkjjiihhggffeeddccbba4lkkjjiihhggffeddccbbaa4kjihgfedcba4kjjiihhggffeeddccbbaa`4jihgfedcba`3jiihhggffeeddccbbaa``_3jiihhggffeeddccbbaa``_3ihgfedcba`_3ihhggffeeddccbbaa``__^3hgfedcba`_^2hgfedcba`_^2hggffeeddccbbaa``__^^]2gfedcba`_^]1gffeeddccbbaa``__^^]]\1gffeeddccbaa``__^^]]\\1fedcba`_^]\1feeddccbbaa``__^^]]\\[1尯就񌊋ش򋊋ര򑒐⯮󒐑ݯ簭㱲򑒐񉊈䵲󒐑󉇈޵鍋౯싊ֶ׶ᶳ捋ⶳ猊ⶳ닊ڷ늈۷䷴錊~ȷ~ݵ牊~޵鉇~}帶獋~}˸~}|紲䉊~}~|Ṷ扇~}~|}¹~}~|}{ι~}|{㹷~}|{|亷ኈ~}~|}{|z亸䈆~}~|}{|z{Ѻ~}|{zyҺ~}|{z{yº~}~|}{|z{yzº~}~|}{|z{yzxԻ~}|{zyx׷~}|{zyzxyĸ~}~|}{|z{yzxyw¹~}~|}{|z{yzxywx¼~}~|}{|z{yzxywxvؼ~}|{zyzxywxvع~}|}{|z{yzxywxvw½~}~|}{|z{yzxywxvwu½~}~|}{|z{yzxywxvwwv۽~}|{zyxywxvwuvܽ~}|{|z{yzxywxvwuvt½~}~|}{|z{yzxywxvwuvtu¾~}~|}{|z{yzxywxvwwvvuu޾~}|{zyxwxvwuvtur߾~}|{z{yzxywxvwuvturs¾~}~|}{|z{yzxywxvwuvtuuss¾~}~|}{|z{yzxywxvwuvvuussr᾽~}|{|z{yzxywxxwwvvuussrr⾽~}|{zyzxywxvwuvtursqrr⾽~}~|}{|z{yzxywxvwuvturssrrqĻ~}~|}{|z{yzxywxvwuvvuussrrqq½~}~|}{|z{yzxywxvwwvvuussrrqqr俽~}|{zyxywxvwuvtursqrrqqpĽ~~}}||{{|z{yzxywxvwuvturssrrqqppļ~}~|}{|z{yzxywxvwuvtuussrrqqppq~}~|}{|z{yzxywxvwwvvuussrrqqrpqn~~}}||{{zzyyxxwwxvwuvtursqrrqqpqno}~}}||{{zz{yzxywxvwuvturssrrqqppnnoŽ}}~|}{|z{yzxywxvwuvtuussrrqqppqnom尯就񌊋ش򋊋ര򑒐⯮󒐑ݯ簭㱲򑒐񉊈䵲󒐑󉇈޵鍋౯싊ֶ׶ᶳ捋ⶳ猊ⶳ닊ڷ늈۷䷴錊~ȷ~ݵ牊~޵鉇~}帶獋~}˸~}|紲䉊~}~|Ṷ扇~}~|}¹~}~|}{ι~}|{㹷~}|{|亷ኈ~}~|}{|z亸䈆~}~|}{|z{Ѻ~}|{zyҺ~}|{z{yº~}~|}{|z{yzº~}~|}{|z{yzxԻ~}|{zyx׷~}|{zyzxyĸ~}~|}{|z{yzxyw¹~}~|}{|z{yzxywx¼~}~|}{|z{yzxywxvؼ~}|{zyzxywxvع~}|}{|z{yzxywxvw½~}~|}{|z{yzxywxvwu½~}~|}{|z{yzxywxvwwv۽~}|{zyxywxvwuvܽ~}|{|z{yzxywxvwuvt½~}~|}{|z{yzxywxvwuvtu¾~}~|}{|z{yzxywxvwwvvuu޾~}|{zyxwxvwuvtur߾~}|{z{yzxywxvwuvturs¾~}~|}{|z{yzxywxvwuvtuuss¾~}~|}{|z{yzxywxvwuvvuussr᾽~}|{|z{yzxywxxwwvvuussrr⾽~}|{zyzxywxvwuvtursqrr⾽~}~|}{|z{yzxywxvwuvturssrrqĻ~}~|}{|z{yzxywxvwuvvuussrrqq½~}~|}{|z{yzxywxvwwvvuussrrqqr俽~}|{zyxywxvwuvtursqrrqqpĽ~~}}||{{|z{yzxywxvwuvturssrrqqppļ~}~|}{|z{yzxywxvwuvtuussrrqqppq~}~|}{|z{yzxywxvwwvvuussrrqqrpqn~~}}||{{zzyyxxwwxvwuvtursqrrqqpqno}~}}||{{zz{yzxywxvwuvturssrrqqppnnoŽ}}~|}{|z{yzxywxvwuvtuussrrqqppqnom尯就񌊋ش򋊋ര򑒐⯮󒐑ݯ簭㱲򑒐񉊈䵲󒐑󉇈޵鍋౯싊ֶ׶ᶳ捋ⶳ猊ⶳ닊ڷ늈۷䷴錊~ȷ~ݵ牊~޵鉇~}帶獋~}˸~}|紲䉊~}~|Ṷ扇~}~|}¹~}~|}{ι~}|{㹷~}|{|亷ኈ~}~|}{|z亸䈆~}~|}{|z{Ѻ~}|{zyҺ~}|{z{yº~}~|}{|z{yzº~}~|}{|z{yzxԻ~}|{zyx׷~}|{zyzxyĸ~}~|}{|z{yzxyw¹~}~|}{|z{yzxywx¼~}~|}{|z{yzxywxvؼ~}|{zyzxywxvع~}|}{|z{yzxywxvw½~}~|}{|z{yzxywxvwu½~}~|}{|z{yzxywxvwwv۽~}|{zyxywxvwuvܽ~}|{|z{yzxywxvwuvt½~}~|}{|z{yzxywxvwuvtu¾~}~|}{|z{yzxywxvwwvvuu޾~}|{zyxwxvwuvtur߾~}|{z{yzxywxvwuvturs¾~}~|}{|z{yzxywxvwuvtuuss¾~}~|}{|z{yzxywxvwuvvuussr᾽~}|{|z{yzxywxxwwvvuussrr⾽~}|{zyzxywxvwuvtursqrr⾽~}~|}{|z{yzxywxvwuvturssrrqĻ~}~|}{|z{yzxywxvwuvvuussrrqq½~}~|}{|z{yzxywxvwwvvuussrrqqr俽~}|{zyxywxvwuvtursqrrqqpĽ~~}}||{{|z{yzxywxvwuvturssrrqqppļ~}~|}{|z{yzxywxvwuvtuussrrqqppq~}~|}{|z{yzxywxvwwvvuussrrqqrpqn~~}}||{{zzyyxxwwxvwuvtursqrrqqpqno}~}}||{{zz{yzxywxvwuvturssrrqqppnnoŽ}}~|}{|z{yzxywxvwuvtuussrrqqppqnomD=D=D=D=E=E=E=E=E>E>F>F>F>F>F>F>G>G?~G?~G?~H?~~H?~~~H?~~~H?}~~}I?}~~}}I@|~~}}|I@|~~}}||I@|~~}}||I@{~~}}||{J@{~~}}||{{J@z~~}}||{{zJ@z~~}}||{{zJ@z~~}}||{{zzJAy~~}}||{{zzyJAy~~}}||{{zzyyKAy~~}}||{{zzyyLAx~~}}||{{zzyyxLAx~~}}||{{zzyyxxLAw~~}}||{{zzyyxxwLAw~~}}||{{zzyyxxwwLAw~~}}||{{zzyyxxwwMBw~~}}||{{zzyyxxwwvMBw~~}}||{{zzyyxxwwvvMBv~~}}||{{zzyyxxwwvvuMBv~~}}||{{zzyyxxwwvvuMBv~~}}||{{zzyyxxwwvvuuMBu~~}}||{{zzyyxxwwvvuutNBu~~}}||{{zzyyxxwwvvuuttNAu~~}}||{{zzyyxxwwvvuuttNBt~~}}||{{zzyyxxwwvvuuttsNBt~~}}||{{zzyyxxwwvvuuttssNBs~~}}||{{zzyyxxwwvvuuttssrNBs~~}}|{{zzyyxxwwvvuuttssrrOBs~~}}||{{zzyyxxwwvvuuttssrrOBr~~}}||{{zzyyxxwwvvuuttssrrqOBr~~}}||{{zzyyxxwwvvuuttssrrqqOBq~~}}||{{zzyyxxwwvvuuttssrrqqpPCq~~}}||{{zzyyxxwwvvuuttssrrqqpPCq~~}}||{{zzyyxxwwvvuuttssrrqqppPCp~~}}||{{zzyyxxwwvvuuttssrrqqppoQCp~~}}||{{zzyyxxwwvvuuttssrrqqppooQCp~~}}||{{zzyyxxwwvvuuttssrrqqpoonQCp~~}}||{{zzyyxxwwvvuuttssrrqqppoonQCp~~}}||{{zzyyxxwwvvuuttssrrqqppoonn~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfgg~}|{zyxywxvwuvtursqrrqqppnnmmnlmjkjjkhighhgge~}|{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfgde~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggee~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfggeec~}|{zyxwxvwuvtussrrsqrpqnomnnmmkkjjkhighhggeefc~}|{z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeecc~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmjkkjjhhighfggeeccd~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdb~}|}{|z{yzxywxxwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbc~}|{zyzxywxvwuvtursqrrqqppnnmmnlmjkkjjhhgghfgdeeccbbc~} 7~|}{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfggeeccdbc`~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`a~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa~~}}||{{zzyyxxywxvwuvtursqrrqqppnnmmnlmjkijjhhghhggeefcdbccaa`~~}}||{{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfgdeeccdbc`aa`~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a~}}||{{zzyyxxwwxvwuvtursqrrqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^}}||{{zz{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmjkkjjhhighfggeeccdbc`aa``a^_~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbccaa``a^_\||{{zzyzxywxxwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]|{{zzyyzxywxvwuvtursqrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]}{|z{yzxywxvwuvtuussrrqqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]]{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][|z{yzxywxvwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[zzyyxxywxvwuvtursqrrqqppnnmmnlmjkijjhhgghfgdefcdbccaab`a^__]]^[\z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfgdeeccdbc`aa``^^_\]][[\{yzxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Zyzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[yxxywxvwuvtursqrrqqppnnmnnmmkkjjkhighhggeefcdbccaa``a^__]]^[\Z[[zxywxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[\Z[Xxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[Yywxvwuvvuussrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a^_\]][[\Z[[YYwwxwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZwxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[ZZ[XYZWxvwuvtuussrrqqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXwuvtursqrrqqppnnmmnlmjkkjjhhgghfgdeeccbbc`ab`a^__]]^[\Z[[YYZWXXVuvturssrrqqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVvuussrrqqrpqnomnnmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWtursqrrqqppnnmmnlmjkijkhighhggeefcdbccaa``a^__]]^[\Z[[YYZWXXVVWTurssrrqqppnnomnlmjkkjjhhighfgdeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTUssrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUsrrsqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSsrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[ZZ[XYYWWXUVVTUUSSrrqqppqnomnlmjkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXXVVTTURSSTqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_]]^[\Z[[YYZWXXVVWTUUSSTQRqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQRppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPpnnmmnlmjkijjhhgghggeefcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPnnomnlmjkkjjhhighfgdeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQomnlmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMmnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNmnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[ZZ[XYYWWXUVVTTURSSQRRPPQMNNnlmjkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNN~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfgg~}|{zyxywxvwuvtursqrrqqppnnmmnlmjkjjkhighhgge~}|{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfgde~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggee~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfggeec~}|{zyxwxvwuvtussrrsqrpqnomnnmmkkjjkhighhggeefc~}|{z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeecc~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmjkkjjhhighfggeeccd~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdb~}|}{|z{yzxywxxwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbc~}|{zyzxywxvwuvtursqrrqqppnnmmnlmjkkjjhhgghfgdeeccbbc~} 7~|}{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfggeeccdbc`~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`a~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa~~}}||{{zzyyxxywxvwuvtursqrrqqppnnmmnlmjkijjhhghhggeefcdbccaa`~~}}||{{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfgdeeccdbc`aa`~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a~}}||{{zzyyxxwwxvwuvtursqrrqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^}}||{{zz{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmjkkjjhhighfggeeccdbc`aa``a^_~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbccaa``a^_\||{{zzyzxywxxwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]|{{zzyyzxywxvwuvtursqrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]}{|z{yzxywxvwuvtuussrrqqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]]{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][|z{yzxywxvwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[zzyyxxywxvwuvtursqrrqqppnnmmnlmjkijjhhgghfgdefcdbccaab`a^__]]^[\z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfgdeeccdbc`aa``^^_\]][[\{yzxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Zyzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[yxxywxvwuvtursqrrqqppnnmnnmmkkjjkhighhggeefcdbccaa``a^__]]^[\Z[[zxywxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[\Z[Xxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[Yywxvwuvvuussrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a^_\]][[\Z[[YYwwxwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZwxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[ZZ[XYZWxvwuvtuussrrqqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXwuvtursqrrqqppnnmmnlmjkkjjhhgghfgdeeccbbc`ab`a^__]]^[\Z[[YYZWXXVuvturssrrqqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVvuussrrqqrpqnomnnmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWtursqrrqqppnnmmnlmjkijkhighhggeefcdbccaa``a^__]]^[\Z[[YYZWXXVVWTurssrrqqppnnomnlmjkkjjhhighfgdeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTUssrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUsrrsqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSsrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[ZZ[XYYWWXUVVTUUSSrrqqppqnomnlmjkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXXVVTTURSSTqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_]]^[\Z[[YYZWXXVVWTUUSSTQRqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQRppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPpnnmmnlmjkijjhhgghggeefcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPnnomnlmjkkjjhhighfgdeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQomnlmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMmnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNmnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[ZZ[XYYWWXUVVTTURSSQRRPPQMNNnlmjkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNN~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfgg~}|{zyxywxvwuvtursqrrqqppnnmmnlmjkjjkhighhgge~}|{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfgde~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggee~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfggeec~}|{zyxwxvwuvtussrrsqrpqnomnnmmkkjjkhighhggeefc~}|{z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeecc~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmjkkjjhhighfggeeccd~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdb~}|}{|z{yzxywxxwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbc~}|{zyzxywxvwuvtursqrrqqppnnmmnlmjkkjjhhgghfgdeeccbbc~} 7~|}{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfggeeccdbc`~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`a~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa~~}}||{{zzyyxxywxvwuvtursqrrqqppnnmmnlmjkijjhhghhggeefcdbccaa`~~}}||{{|z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfgdeeccdbc`aa`~}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``~}~|}{|z{yzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a~}}||{{zzyyxxwwxvwuvtursqrrqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^}}||{{zz{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^}~|}{|z{yzxywxvwuvtuussrrqqppqnomnlmjkkjjhhighfggeeccdbc`aa``a^_~|}{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbccaa``a^_\||{{zzyzxywxxwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]|{{zzyyzxywxvwuvtursqrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]}{|z{yzxywxvwuvtuussrrqqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]]{|z{yzxywxvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][|z{yzxywxvwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[zzyyxxywxvwuvtursqrrqqppnnmmnlmjkijjhhgghfgdefcdbccaab`a^__]]^[\z{yzxywxvwuvturssrrqqppnnomnlmjkkjjhhighfgdeeccdbc`aa``^^_\]][[\{yzxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Zyzxywxvwwvvuussrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[yxxywxvwuvtursqrrqqppnnmnnmmkkjjkhighhggeefcdbccaa``a^__]]^[\Z[[zxywxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[\Z[Xxywxvwuvtuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[Yywxvwuvvuussrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a^_\]][[\Z[[YYwwxwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZwxvwuvturssrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[ZZ[XYZWxvwuvtuussrrqqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWvwuvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXwwvvuussrrqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXwuvtursqrrqqppnnmmnlmjkkjjhhgghfgdeeccbbc`ab`a^__]]^[\Z[[YYZWXXVuvturssrrqqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVvvuussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVvuussrrqqrpqnomnnmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWtursqrrqqppnnmmnlmjkijkhighhggeefcdbccaa``a^__]]^[\Z[[YYZWXXVVWTurssrrqqppnnomnlmjkkjjhhighfgdeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTussrrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTUssrrqqrpqnomnlmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUsrrsqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSsrrqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[ZZ[XYYWWXUVVTUUSSrrqqppqnomnlmjkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSrqqppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXXVVTTURSSTqqrpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQqqppnnomnlmjkkjjhhgghfgdeeccbbc`aa``^^_]]^[\Z[[YYZWXXVVWTUUSSTQRqppnnomnlmjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQRppqnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRpqnomnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPpnnmmnlmjkijjhhgghggeefcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPnnomnlmjkkjjhhighfgdeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPnomnlmmkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQomnlmmkkjjkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMmnnmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNmnlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[ZZ[XYYWWXUVVTTURSSQRRPPQMNNnlmjkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNN~}|{zyxwvutsrqponmlkjihgf~}|{zyxwvutsrqponmlkjjiihhggffe~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffe~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffee~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeed~~}}||{{zzyyxxwwvvuutssrrqqppoonnmmllkkjjiihhggffeedd~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeedd~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddc~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddcc~~}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccb~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccb~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbb~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbba~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihggffeeddccbbaa`~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa`~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``_~~}}||{{zzyyxxwwvvuuttssrrqppoonnmmllkkjjiihhggffeeddccbbaa``__~~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__~}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^}}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^}}||{{zyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]}||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]||{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]|{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\{{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeddccbbaa``__^^]]\\[{zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[zzyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[zyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[Zzyyxxwwvvuuttssrrqqppoonmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZyyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZyxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYxxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYxxwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXxwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYXXwwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXwvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWvvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbba``__^^]]\\[[ZZYYXXWWVvuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVuuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVuttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUuttssrrqqppoonnmmllkkjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUttssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUtssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTssrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTsrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSsrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUTTSSrrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSrqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRqqppoonnmmllkkjjiihhggffeeddccbbaa``__^]]\\[[ZZYYXXWWVVUUTTSSRRQqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQpoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPpoonnmmllkkjjiihhgffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOnnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOOnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRQQPPOONNmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNecdbccaa``a^__]][[\ZZefcdbccaa``a^__]]^[\Z[Zeccdbc`aa``^^_\]][[\Z[Zcdbc`aa``a^_\]][[\Z[[Zcdbccaa``a^__]][[\Z[[YZdbccaa``a^__]][[\Z[[YY\bc`aa``^^_\]][[ZZ[XYYWbc`aa``a^_\]][[\Z[[YYWWc`aa``a^_\]][[\Z[[YYZWWcaa``a^__]][[\Z[[YYZWXW`aa``^__]]^[\Z[[YYZWXXYa`^_\]][[\Z[XYYWWXUYa``a^_\]][[\Z[[YYZWXUVY`a^__]][[\Z[[YYZWXXVVY`a^__]]^[\Z[[YYZWXXVVWS`^^_\]][[\Z[XYYWWXUVVTSa^_\]][[\Z[[YYWWXUVVTTU^__]][[\Z[[YYZWXXVVWTUU_][\Z[[YYZWXXVVWTUU_\]][[ZZ[XYYWWXUVVTTURU\]][[\Z[[YYWWXUVVTTURSU][\Z[[YYZWXXVVTTURSSW][[\Z[[YYZWXXVVWTUUSSTQ][\Z[[YYZWXXVVWTUUSSTQQ[\Z[XYYWWXUVVTTURSSQQ[\Z[[YYZWXUVVTTURSSQQRQ\Z[[YYZWXXVVWTUUSSTQRRMZ[[YYZWXXVVWTUUSSTQRRPMZ[XYYWWXUVVTTURSSQQROPM[YWXUVVTTURSSQQRRPPO[YYZWXXVVWTUUSSTQRRPPQOYZWXXVVWTUUSSTQRRPPQMOYWXUVVTTURSSQQROPQMNOYWWXUVVTTURSSQQROPPQMNOZWXXVVWTUUSSTQRRPPQMNNKWXXVVWTUUSSTQRRPPQMNNLKXVWTUUSSTQRRPPQMNNOLKXUVVTTURSSQQROPPQMNNLLKUVVTTURSSTQRRPPQMNNLLMKVWTUUSSTQRRPPQMNNLLMMVWTUUSSTQRRPPQMNNOLMMKMVTTURSSQQROPPQMNNLLMJKMTURSSQQRRPPQMNNLLMJKKMTUUSSTQRRPPQMNNLLMMKKLFUSTQRRPPQMNNLLMMKKLHHURSSQQROPPMMNNLLMKKLHIHRSSQQROPPQMNNLLMJKKLHIHSTQRRPPQMNNLLMJKKLHIIHSTQRRPPQMNNLLMMKKLHIIJHTQRRPPQMNNOLMMKKLHIIJGJQROPPQMNNLLMJKKLHIIGGJQRRPPQMNNLLMJKKLHIIGGHJRPQMNNLLMMKKLHIIGGHHCRPPQMNNOLMMKKLHIIJGHHECOPPQMNNLLMJKKHHIIGGHHECPQMNNLLMJKKLHIIGGHHEEPQMNNLLMMKKLHIIGGHHEEFEQMNNLLMMKKLHIIJGHHEEFFEMNLMJKKHHIJGHHEEFFDEMNNLLMJKKLHIIGGHHEEFCDENLMJKKLHIIGGHHEEFFDDGNLLMMKKLHIIJGHHEEFFDDEGOLMMKKLHIIJGHHEEFFDDEEBLMJKKLHIIGGHHEEFCDDEABecdbccaa``a^__]][[\ZZefcdbccaa``a^__]]^[\Z[Zeccdbc`aa``^^_\]][[\Z[Zcdbc`aa``a^_\]][[\Z[[Zcdbccaa``a^__]][[\Z[[YZdbccaa``a^__]][[\Z[[YY\bc`aa``^^_\]][[ZZ[XYYWbc`aa``a^_\]][[\Z[[YYWWc`aa``a^_\]][[\Z[[YYZWWcaa``a^__]][[\Z[[YYZWXW`aa``^__]]^[\Z[[YYZWXXYa`^_\]][[\Z[XYYWWXUYa``a^_\]][[\Z[[YYZWXUVY`a^__]][[\Z[[YYZWXXVVY`a^__]]^[\Z[[YYZWXXVVWS`^^_\]][[\Z[XYYWWXUVVTSa^_\]][[\Z[[YYWWXUVVTTU^__]][[\Z[[YYZWXXVVWTUU_][\Z[[YYZWXXVVWTUU_\]][[ZZ[XYYWWXUVVTTURU\]][[\Z[[YYWWXUVVTTURSU][\Z[[YYZWXXVVTTURSSW][[\Z[[YYZWXXVVWTUUSSTQ][\Z[[YYZWXXVVWTUUSSTQQ[\Z[XYYWWXUVVTTURSSQQ[\Z[[YYZWXUVVTTURSSQQRQ\Z[[YYZWXXVVWTUUSSTQRRMZ[[YYZWXXVVWTUUSSTQRRPMZ[XYYWWXUVVTTURSSQQROPM[YWXUVVTTURSSQQRRPPO[YYZWXXVVWTUUSSTQRRPPQOYZWXXVVWTUUSSTQRRPPQMOYWXUVVTTURSSQQROPQMNOYWWXUVVTTURSSQQROPPQMNOZWXXVVWTUUSSTQRRPPQMNNKWXXVVWTUUSSTQRRPPQMNNLKXVWTUUSSTQRRPPQMNNOLKXUVVTTURSSQQROPPQMNNLLKUVVTTURSSTQRRPPQMNNLLMKVWTUUSSTQRRPPQMNNLLMMVWTUUSSTQRRPPQMNNOLMMKMVTTURSSQQROPPQMNNLLMJKMTURSSQQRRPPQMNNLLMJKKMTUUSSTQRRPPQMNNLLMMKKLFUSTQRRPPQMNNLLMMKKLHHURSSQQROPPMMNNLLMKKLHIHRSSQQROPPQMNNLLMJKKLHIHSTQRRPPQMNNLLMJKKLHIIHSTQRRPPQMNNLLMMKKLHIIJHTQRRPPQMNNOLMMKKLHIIJGJQROPPQMNNLLMJKKLHIIGGJQRRPPQMNNLLMJKKLHIIGGHJRPQMNNLLMMKKLHIIGGHHCRPPQMNNOLMMKKLHIIJGHHECOPPQMNNLLMJKKHHIIGGHHECPQMNNLLMJKKLHIIGGHHEEPQMNNLLMMKKLHIIGGHHEEFEQMNNLLMMKKLHIIJGHHEEFFEMNLMJKKHHIJGHHEEFFDEMNNLLMJKKLHIIGGHHEEFCDENLMJKKLHIIGGHHEEFFDDGNLLMMKKLHIIJGHHEEFFDDEGOLMMKKLHIIJGHHEEFFDDEEBLMJKKLHIIGGHHEEFCDDEABecdbccaa``a^__]][[\ZZefcdbccaa``a^__]]^[\Z[Zeccdbc`aa``^^_\]][[\Z[Zcdbc`aa``a^_\]][[\Z[[Zcdbccaa``a^__]][[\Z[[YZdbccaa``a^__]][[\Z[[YY\bc`aa``^^_\]][[ZZ[XYYWbc`aa``a^_\]][[\Z[[YYWWc`aa``a^_\]][[\Z[[YYZWWcaa``a^__]][[\Z[[YYZWXW`aa``^__]]^[\Z[[YYZWXXYa`^_\]][[\Z[XYYWWXUYa``a^_\]][[\Z[[YYZWXUVY`a^__]][[\Z[[YYZWXXVVY`a^__]]^[\Z[[YYZWXXVVWS`^^_\]][[\Z[XYYWWXUVVTSa^_\]][[\Z[[YYWWXUVVTTU^__]][[\Z[[YYZWXXVVWTUU_][\Z[[YYZWXXVVWTUU_\]][[ZZ[XYYWWXUVVTTURU\]][[\Z[[YYWWXUVVTTURSU][\Z[[YYZWXXVVTTURSSW][[\Z[[YYZWXXVVWTUUSSTQ][\Z[[YYZWXXVVWTUUSSTQQ[\Z[XYYWWXUVVTTURSSQQ[\Z[[YYZWXUVVTTURSSQQRQ\Z[[YYZWXXVVWTUUSSTQRRMZ[[YYZWXXVVWTUUSSTQRRPMZ[XYYWWXUVVTTURSSQQROPM[YWXUVVTTURSSQQRRPPO[YYZWXXVVWTUUSSTQRRPPQOYZWXXVVWTUUSSTQRRPPQMOYWXUVVTTURSSQQROPQMNOYWWXUVVTTURSSQQROPPQMNOZWXXVVWTUUSSTQRRPPQMNNKWXXVVWTUUSSTQRRPPQMNNLKXVWTUUSSTQRRPPQMNNOLKXUVVTTURSSQQROPPQMNNLLKUVVTTURSSTQRRPPQMNNLLMKVWTUUSSTQRRPPQMNNLLMMVWTUUSSTQRRPPQMNNOLMMKMVTTURSSQQROPPQMNNLLMJKMTURSSQQRRPPQMNNLLMJKKMTUUSSTQRRPPQMNNLLMMKKLFUSTQRRPPQMNNLLMMKKLHHURSSQQROPPMMNNLLMKKLHIHRSSQQROPPQMNNLLMJKKLHIHSTQRRPPQMNNLLMJKKLHIIHSTQRRPPQMNNLLMMKKLHIIJHTQRRPPQMNNOLMMKKLHIIJGJQROPPQMNNLLMJKKLHIIGGJQRRPPQMNNLLMJKKLHIIGGHJRPQMNNLLMMKKLHIIGGHHCRPPQMNNOLMMKKLHIIJGHHECOPPQMNNLLMJKKHHIIGGHHECPQMNNLLMJKKLHIIGGHHEEPQMNNLLMMKKLHIIGGHHEEFEQMNNLLMMKKLHIIJGHHEEFFEMNLMJKKHHIJGHHEEFFDEMNNLLMJKKLHIIGGHHEEFCDENLMJKKLHIIGGHHEEFFDDGNLLMMKKLHIIJGHHEEFFDDEGOLMMKKLHIIJGHHEEFFDDEEBLMJKKLHIIGGHHEEFCDDEABedcba`_^]\[0eddccbbaa``__^^]]\\[[Z0eddccbbaa``__^^]]\\[[Z0dcba`_^]\[Z0dccbbaa``__^^]]\\[[ZZY0cba`_^]\[ZY/cba`_^]\[ZY/cbbaa``__^^]]\\[[ZZYYX/ba`_^]\[ZYX/baa``__^^]]\\[[ZZYYXXW/baa``_^^]]\\[[ZZYYXXWW.a`_^]\[ZYXW.a``__^^]]\\[[ZZYYXXWWV.`_^]\[ZYXWV.`__^^]]\\[[ZZYYXXWWVVU.`__^^]]\\[[ZZYYXXWWVVU._^]\[ZYXWVU-_^^]]\\[[ZZYYXXWWVVUUT-^]\[ZYXWVUT-^]\[ZYXWVUT-^]]\\[[ZZYYXXWWVVUUTTS-]\[ZYXWVUTS,]\\[[ZZYYXXWWVVUUTTSSR,]\[[ZZYYXXWWVVUUTTSSRR,\[ZYXWVUTSR,\[[ZZYYXXWWVVUUTTSSRRQ,[ZYXWVUTSRQ+[ZZYYXXWWVVUUTTSSRRQQP+[ZZYYXXWWVVUUTTSSRRQQP+ZYXWVUTSRQP*ZYYXXWWVVUUTTSSRRQQPPO*YXWVUTSRQPO*YXWVUTSRQPOON*YXXWWVVUUTTSSRRQQPPOON*XWVUTSRQPON)XWWVVUUTTSSRRQQPPOONNM)WVUTSRQPONM)WVUTSRQPONM)WVVUUTTSSRRQQPPOONNMML)VUTSRQPONML(VUUTTSSRRQQPPOONNMMLLK(VUUTTSSRRQQPPOONNMMLLK(UTSRQPONMLK(UTTSSRRQQPPOONNMMLLKKJ(TSRQPONMLKJ'TSRQPONMLKKJJI'TSSRRQQPPOONNMMLLKKJJI'SRQPONMLKJI'SRRQQPPOONNMMLLKKJJIIH'RQPONMLKJIH&RQPONMLKJIH&RQQPPOONNMMLLKKJJIIHHG&QPONMLKJIHG&QPPOONNMMLLKKJJIIHHGGF&QPPOONNMMLLKKJJIIHHGGF&PONMLKJIHGF%POONNMMLLKKJJIIHHGGFFE%ONMLKJIHGFE%ONMLKJIHHGGFFEED%ONNMMLLKKJJIIHHGGFFEED%NMLKJIHGFED$NMMLLKKJJIIHHGGFFEEDDC$MLKJIHGFEDC#MLKJIHGFEDC#ÿ~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnÿ|}||{{zzyyxywxxwwvvuussrrqqrpqnomnn翽||{zyzxywxvwuvtursqrrqqppnnomnl}|}{|z{yzxywxvwuvtuussrrqqppnnomnlm}}{|z{yzxywxvwuvvuussrrqqppqnomnlmm~{|z{yzxywxvwwvvuussrrqqrpqnomnnmmk|{zzyyxxywxvwuvtursqrrqqppnnmmnlmjk||z{yzxywxvwuvturssrrqqppnnomnlmjkk}z{yzxywxvwuvtuussrrqqppqnomnlmmkkj{{yzxywxvwwvvuussrrqqrpqnomnlmmkkjj{yyxxywxvwuvtursqrrqqppnnmmnmmkkjjk|yzxywxvwuvturssrrqqppnnomnlmjkkjjhzzxywxvwuvtuussrrqqppqnomnlmmkkjjhh{xywxvwuvvuussrrqqrpqnomnlmmkkjjkhixxwwxvwvvuussrrsqrpqnomnnmmkkjjkhig¿xywxvwuvturssrrqqppnnomnlmjkkjjhhggywxvwuvtuussrrqqppnnomnlmjkkjjhhighwxvwuvvuussrrqqppqnomnlmmkkjjhhighfwxwwvvuussrrqqrpqnomnnmmkkjjkhighhgwvwuvtursqrrqqppnnmmnlmjkkjjhhgghfguwuvturssrrqqppnnomnlmjkkjjhhighfggvuvvuussrrqqppqnomnlmmkkjjhhighfgge¿vvusrqrpqnomnnmmkkjjkhighfggeesvtursqrrqqppnnmmnlmjkijkhighhggeeftturssrrqqppnnomnlmjkkjjhhighfgdeectuussrrqqppqnomnlmmkkjjhhighfggeeccvussrrqqrpqnomnlmmkkjjkhighfggeeccdvrsrrsqrpqnomnnmmkkjjkhighhggeefcdbssrqpnomnlmjkkjjhhgghfgdeeccbbtsrrqqppqnomnlmjkkjjhhighfggeeccdbc¿trrqqppqnomnlmmkkjjhhighfggeeccdbc`srqqrpqnomnnmmkkjjkhighhggeefcdbccasrqqppnnomnlmjkkjjhhgghfgdeeccbbc`asqqppnnomnlmjkkjjhhighfggeeccdbc`aaqqppqnomnlmmkkjjhhighfggeeccdbc`aa`qrpqnomnnmmkkjjkhighhggeefcdbccaa``qppnnmmnlmjkijjhhgghggeefcdbccaa``a¿ppnnomnlmjkkjjhhighfgdeeccdbc`aa``^pqnomnlmmkkjjhhighfggeeccdbc`aa``a^pnomnlmmkkjjkhighfggeeccdbccaa``a^_momnnmmkkjjkhighhggeefcdbccaa``a^__momnlmjkkjjhhgghfgdeeccbbc`aa``^^_\nmnlmjkkjjhhighfggeeccdbc`aa``a^_\]lnlmmkkjjkhighfggeeccdbccaa``a^_\]]mnmmkkjjkhighhggeefcdbccaa``a^__]][¿mlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][jmjkkjjhhighfggeeccdbc`aa``^^_\]][[kmkkjjhhighfggeeccdbc`aa``a^_\]][[\kkjkhighhggeefcdbccaa``a^__]][[\Zkkjhghfgdeeccbccaab`a^__]]^[\Z[mkjjhhighfggeeccdbc`aa``^^_\]][[\Z[mjjhhighfggeeccdbc`aa``a^_\]][[\Z[[¿kjkhighfggeeccdbccaa``a^__]][[\Z[[Ykkhighhggeefcdbccaa``a^__]]^[\Z[[YYkhhgghfgdeeccbbc`aa``^^_\]][[\Z[XYYihighfggeeccdbc`aa``a^_\]][[\Z[[YYWiighfggeeccdbccaa``a^_\]][[\Z[[YYZWjghhggeefcdbccaa``a^__]][[\Z[[YYZWXhghfgdeeccbbc`aa``^^_\]][[ZZ[XYYWWXhhfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUifggeeccdbc`aa``a^_\]][[\Z[[YYZWXUViggeefcdbccaa``a^__]][[\Z[[YYZWXXVVfgdeeccbbc`aa`a^__]]^[\Z[[YYZWXXVVWfgeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTÿ~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnÿ|}||{{zzyyxywxxwwvvuussrrqqrpqnomnn翽||{zyzxywxvwuvtursqrrqqppnnomnl}|}{|z{yzxywxvwuvtuussrrqqppnnomnlm}}{|z{yzxywxvwuvvuussrrqqppqnomnlmm~{|z{yzxywxvwwvvuussrrqqrpqnomnnmmk|{zzyyxxywxvwuvtursqrrqqppnnmmnlmjk||z{yzxywxvwuvturssrrqqppnnomnlmjkk}z{yzxywxvwuvtuussrrqqppqnomnlmmkkj{{yzxywxvwwvvuussrrqqrpqnomnlmmkkjj{yyxxywxvwuvtursqrrqqppnnmmnmmkkjjk|yzxywxvwuvturssrrqqppnnomnlmjkkjjhzzxywxvwuvtuussrrqqppqnomnlmmkkjjhh{xywxvwuvvuussrrqqrpqnomnlmmkkjjkhixxwwxvwvvuussrrsqrpqnomnnmmkkjjkhig¿xywxvwuvturssrrqqppnnomnlmjkkjjhhggywxvwuvtuussrrqqppnnomnlmjkkjjhhighwxvwuvvuussrrqqppqnomnlmmkkjjhhighfwxwwvvuussrrqqrpqnomnnmmkkjjkhighhgwvwuvtursqrrqqppnnmmnlmjkkjjhhgghfguwuvturssrrqqppnnomnlmjkkjjhhighfggvuvvuussrrqqppqnomnlmmkkjjhhighfgge¿vvusrqrpqnomnnmmkkjjkhighfggeesvtursqrrqqppnnmmnlmjkijkhighhggeeftturssrrqqppnnomnlmjkkjjhhighfgdeectuussrrqqppqnomnlmmkkjjhhighfggeeccvussrrqqrpqnomnlmmkkjjkhighfggeeccdvrsrrsqrpqnomnnmmkkjjkhighhggeefcdbssrqpnomnlmjkkjjhhgghfgdeeccbbtsrrqqppqnomnlmjkkjjhhighfggeeccdbc¿trrqqppqnomnlmmkkjjhhighfggeeccdbc`srqqrpqnomnnmmkkjjkhighhggeefcdbccasrqqppnnomnlmjkkjjhhgghfgdeeccbbc`asqqppnnomnlmjkkjjhhighfggeeccdbc`aaqqppqnomnlmmkkjjhhighfggeeccdbc`aa`qrpqnomnnmmkkjjkhighhggeefcdbccaa``qppnnmmnlmjkijjhhgghggeefcdbccaa``a¿ppnnomnlmjkkjjhhighfgdeeccdbc`aa``^pqnomnlmmkkjjhhighfggeeccdbc`aa``a^pnomnlmmkkjjkhighfggeeccdbccaa``a^_momnnmmkkjjkhighhggeefcdbccaa``a^__momnlmjkkjjhhgghfgdeeccbbc`aa``^^_\nmnlmjkkjjhhighfggeeccdbc`aa``a^_\]lnlmmkkjjkhighfggeeccdbccaa``a^_\]]mnmmkkjjkhighhggeefcdbccaa``a^__]][¿mlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][jmjkkjjhhighfggeeccdbc`aa``^^_\]][[kmkkjjhhighfggeeccdbc`aa``a^_\]][[\kkjkhighhggeefcdbccaa``a^__]][[\Zkkjhghfgdeeccbccaab`a^__]]^[\Z[mkjjhhighfggeeccdbc`aa``^^_\]][[\Z[mjjhhighfggeeccdbc`aa``a^_\]][[\Z[[¿kjkhighfggeeccdbccaa``a^__]][[\Z[[Ykkhighhggeefcdbccaa``a^__]]^[\Z[[YYkhhgghfgdeeccbbc`aa``^^_\]][[\Z[XYYihighfggeeccdbc`aa``a^_\]][[\Z[[YYWiighfggeeccdbccaa``a^_\]][[\Z[[YYZWjghhggeefcdbccaa``a^__]][[\Z[[YYZWXhghfgdeeccbbc`aa``^^_\]][[ZZ[XYYWWXhhfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUifggeeccdbc`aa``a^_\]][[\Z[[YYZWXUViggeefcdbccaa``a^__]][[\Z[[YYZWXXVVfgdeeccbbc`aa`a^__]]^[\Z[[YYZWXXVVWfgeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTÿ~}~|}{|z{yzxywxvwuvvuussrrqqppqnomnÿ|}||{{zzyyxywxxwwvvuussrrqqrpqnomnn翽||{zyzxywxvwuvtursqrrqqppnnomnl}|}{|z{yzxywxvwuvtuussrrqqppnnomnlm}}{|z{yzxywxvwuvvuussrrqqppqnomnlmm~{|z{yzxywxvwwvvuussrrqqrpqnomnnmmk|{zzyyxxywxvwuvtursqrrqqppnnmmnlmjk||z{yzxywxvwuvturssrrqqppnnomnlmjkk}z{yzxywxvwuvtuussrrqqppqnomnlmmkkj{{yzxywxvwwvvuussrrqqrpqnomnlmmkkjj{yyxxywxvwuvtursqrrqqppnnmmnmmkkjjk|yzxywxvwuvturssrrqqppnnomnlmjkkjjhzzxywxvwuvtuussrrqqppqnomnlmmkkjjhh{xywxvwuvvuussrrqqrpqnomnlmmkkjjkhixxwwxvwvvuussrrsqrpqnomnnmmkkjjkhig¿xywxvwuvturssrrqqppnnomnlmjkkjjhhggywxvwuvtuussrrqqppnnomnlmjkkjjhhighwxvwuvvuussrrqqppqnomnlmmkkjjhhighfwxwwvvuussrrqqrpqnomnnmmkkjjkhighhgwvwuvtursqrrqqppnnmmnlmjkkjjhhgghfguwuvturssrrqqppnnomnlmjkkjjhhighfggvuvvuussrrqqppqnomnlmmkkjjhhighfgge¿vvusrqrpqnomnnmmkkjjkhighfggeesvtursqrrqqppnnmmnlmjkijkhighhggeeftturssrrqqppnnomnlmjkkjjhhighfgdeectuussrrqqppqnomnlmmkkjjhhighfggeeccvussrrqqrpqnomnlmmkkjjkhighfggeeccdvrsrrsqrpqnomnnmmkkjjkhighhggeefcdbssrqpnomnlmjkkjjhhgghfgdeeccbbtsrrqqppqnomnlmjkkjjhhighfggeeccdbc¿trrqqppqnomnlmmkkjjhhighfggeeccdbc`srqqrpqnomnnmmkkjjkhighhggeefcdbccasrqqppnnomnlmjkkjjhhgghfgdeeccbbc`asqqppnnomnlmjkkjjhhighfggeeccdbc`aaqqppqnomnlmmkkjjhhighfggeeccdbc`aa`qrpqnomnnmmkkjjkhighhggeefcdbccaa``qppnnmmnlmjkijjhhgghggeefcdbccaa``a¿ppnnomnlmjkkjjhhighfgdeeccdbc`aa``^pqnomnlmmkkjjhhighfggeeccdbc`aa``a^pnomnlmmkkjjkhighfggeeccdbccaa``a^_momnnmmkkjjkhighhggeefcdbccaa``a^__momnlmjkkjjhhgghfgdeeccbbc`aa``^^_\nmnlmjkkjjhhighfggeeccdbc`aa``a^_\]lnlmmkkjjkhighfggeeccdbccaa``a^_\]]mnmmkkjjkhighhggeefcdbccaa``a^__]][¿mlmjkkjjhhgghfgdeeccbbc`aa``^^_\]][jmjkkjjhhighfggeeccdbc`aa``^^_\]][[kmkkjjhhighfggeeccdbc`aa``a^_\]][[\kkjkhighhggeefcdbccaa``a^__]][[\Zkkjhghfgdeeccbccaab`a^__]]^[\Z[mkjjhhighfggeeccdbc`aa``^^_\]][[\Z[mjjhhighfggeeccdbc`aa``a^_\]][[\Z[[¿kjkhighfggeeccdbccaa``a^__]][[\Z[[Ykkhighhggeefcdbccaa``a^__]]^[\Z[[YYkhhgghfgdeeccbbc`aa``^^_\]][[\Z[XYYihighfggeeccdbc`aa``a^_\]][[\Z[[YYWiighfggeeccdbccaa``a^_\]][[\Z[[YYZWjghhggeefcdbccaa``a^__]][[\Z[[YYZWXhghfgdeeccbbc`aa``^^_\]][[ZZ[XYYWWXhhfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUifggeeccdbc`aa``a^_\]][[\Z[[YYZWXUViggeefcdbccaa``a^__]][[\Z[[YYZWXXVVfgdeeccbbc`aa`a^__]]^[\Z[[YYZWXXVVWfgeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTQCo~}}||{{zzyyxxwwvvuuttssrrqqppoonnmQDo~}}||{{zzyxxwwvvuuttssrrqqppoonnmmRDo}}||{{zzyyxxwwvvuuttssrrqqppoonnmmRDn}||{{zzyyxxwwvvuuttssrrqqppoonnmmlRDn||{{zzyyxxwwvvuuttssrrqqppoonnmmllSDm|{{zzyyxxwwvvuuttssrrqqppoonnmmllkSDm|{{zzyyxxwwvvuuttssrrqqppoonnmmllkSDm{{zzyyxxwwvvuuttssrrqqppoonnmmllkkSDl{zzyyxxwwvvuuttssrrqqppoonnmmllkkjTElzzyyxxwwvvuuttssrrqqppoonnmmllkkjjTElzzyyxxwwvvuuttssrrqqppoonnmllkkjjiTEkzyyxxwwvvuuttssrrqqppoonnmmllkkjjiTEkyyxxwwvvuuttssrrqqppoonnmmllkkjjiiTEjyxxwwvvuuttssrrqqppoonnmmllkkjjiihUEjyxxwwvuuttssrrqqppoonnmmllkkjjiihhUEjxxwwvvuuttssrrqqppoonnmmllkkjjiihhUEixwwvvuuttssrrqqppoonnmmllkkjjiihhgUEiwwvvuuttssrrqqppoonnmmllkkjjiihhggUEiwvvuuttssrrqqppoonnmmllkkjjiihhggfUEiwvvuuttssrrqqppoonnmmllkkjjiihhggfUEivvuuttssrrqqppoonnmmllkkjjiihhggffWEhvuuttssrrqqppoonnmmllkkjjiihhggffeWFhuuttssrrqqppoonnmmllkkjjiihhggffeeWFhuuttssrrqqppoonnmmllkkjiihhggffeedWFguttssrrqqppoonnmmllkkjjiihhggffeedWFgttssrrqqppoonnmmllkkjjiihhggffeeddWFftssrrqqppoonnmmllkkjjiihhggffeeddcXFftsrrqqppoonnmmllkkjjiihhggffeeddccXFfssrrqqppoonnmmllkkjjiihhggffeeddccXFesrrqqppoonnmmllkkjjiihhggffeeddccbXGerrqqppoonnmmllkkjjiihhggffeeddccbbXGdrqqppoonnmmllkkjjiihhggffeeddccbbaXGdrqqppoonnmmllkkjjiihhggffeeddccbbaZGdqqppoonnmmllkkjjiihhggffeeddccbbaaZGcqppoonnmmllkkjjiihhggffeeddccbbaa`ZGcppoonnmmllkkjjiihhggffeeddccbbaa``ZGcppoonnmmllkkjjiihhgffeeddccbbaa``_ZGbpoonnmmllkkjjiihhggffeeddccbbaa``_ZGboonnmmllkkjjiihhggffeeddccbbaa``__[Gbonnmmllkkjjiihhggffeeddccbbaa``__^[Gbnnmmllkkjjiihhggffeeddccbbaa``__^^[Gbnnmmllkkjjiihhggffeeddccbbaa``__^^[Hanmmllkkjjiihhggffeeddccbbaa``__^^][Hammllkkjjiihhggffeeddccbbaa``__^^]][H`mllkkjjiihhggffeeddccbbaa``__^^]]\\H`mllkkjjiihhggffeeddccbbaa``__^^]]\\H`llkkjjiihhggffeeddccbbaa``__^^]]\\\H_lkkjjiihhggffeeddccbbaa``__^^]]\\[\H_kkjjiihhggffeeddccbbaa``__^^]]\\[[]H_kkjjiihhggffeeddcbbaa``__^^]]\\[[Z]H^kjjiihhggffeeddccbbaa``__^^]]\\[[Z]H^jjiihhggffeeddccbbaa``__^^]]\\[[ZZ^H]jiihhggffeeddccbbaa``__^^]]\\[[ZZY^H]iihhggffeeddccbbaa``__^^]]\\[[ZZYY^I]iihhggffeeddccbbaa``__^^]]\\[[ZZYY^I\ihhggffeeddccbbaa``__^^]]\\[[ZZYYX^I\hhggffeeddccbbaa``__^^]]\\[[ZZYYXX^I[hggffeeddccbbaa``__^^]]\\[[ZZYYXXW_I[hggffeeddccbbaa``__^^]]\\[[ZZYYXXW_I[ggffeeddccbbaa``__^^]]\\[[ZZYYXXWW_IZgffeeddccbbaa``__^^]]\\[[ZZYYXXWWV_IZffeeddccbbaa``__^^]]\\[[ZZYYXXWWVV`JZffeeddccbbaa`__^^]]\\[[ZZYYXXWWVVU`JZfeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUlmmkkjjkhighfggeeccdbccaa``a^_\]][[\Z[[YYZWXXVVTTURSSTQRRPPQMNNLmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKijjhhgghfgdeecdbccaab`a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKjjhhighfgdeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMNNLLMJKKjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHhighhggeefcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIhgghfgdeeccbbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMNNOLMMKKLHIIighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIghfggeeccdbccaa``a^_\]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGhhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGhfgdeeccbbc`aa``^^_\]][[ZZ[XYYWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHgeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEdeeccbbc`ab`a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKHHIIGGHDEEeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDcdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMNNLLMKKLHIIJGHHEEFFDDdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEc`aa``^^_\]][[ZZ[XYYWWXUVVTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEB`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABaa``a^_\]][[\Z[[YYZWXXVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBCa``^^_]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKHHIIGGHHEEFCDDEABBC?`a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMNNLLMJKKHHIJGHHEEFFDDEEBBCC@@AA_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=_]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABBC?@@A=>]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>]][[ZZ[XYYWWXUVVTTURSSQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>?][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?[[\Z[[YYZWXXVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEABBC?@@A=>>?;<[Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<=Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@A=>>??<<==9XYYWWXUVVTTURSSQQROPPMMNNLLMJKKHHIIGGHDEEFDDEEBBCC@@AA>>??<<==99YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899YZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99:ZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??<<==99::WWXUVVTTURSSQQROPPMMNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::7WXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::7XXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<=899::77XVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>?;<<==99::778VVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::7788VVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899:;7889VTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884WTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::778894TUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::7788945TURSSQQROPPQMNNLLMJKKHHIIGGHHEEFCDDEABCC@@AA>>??<<==99::;7889455lmmkkjjkhighfggeeccdbccaa``a^_\]][[\Z[[YYZWXXVVTTURSSTQRRPPQMNNLmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKijjhhgghfgdeecdbccaab`a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKjjhhighfgdeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMNNLLMJKKjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHhighhggeefcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIhgghfgdeeccbbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMNNOLMMKKLHIIighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIghfggeeccdbccaa``a^_\]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGhhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGhfgdeeccbbc`aa``^^_\]][[ZZ[XYYWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHgeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEdeeccbbc`ab`a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKHHIIGGHDEEeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDcdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMNNLLMKKLHIIJGHHEEFFDDdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEc`aa``^^_\]][[ZZ[XYYWWXUVVTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEB`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABaa``a^_\]][[\Z[[YYZWXXVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBCa``^^_]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKHHIIGGHHEEFCDDEABBC?`a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMNNLLMJKKHHIJGHHEEFFDDEEBBCC@@AA_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=_]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABBC?@@A=>]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>]][[ZZ[XYYWWXUVVTTURSSQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>?][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?[[\Z[[YYZWXXVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEABBC?@@A=>>?;<[Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<=Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@A=>>??<<==9XYYWWXUVVTTURSSQQROPPMMNNLLMJKKHHIIGGHDEEFDDEEBBCC@@AA>>??<<==99YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899YZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99:ZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??<<==99::WWXUVVTTURSSQQROPPMMNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::7WXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::7XXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<=899::77XVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>?;<<==99::778VVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::7788VVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899:;7889VTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884WTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::778894TUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::7788945TURSSQQROPPQMNNLLMJKKHHIIGGHHEEFCDDEABCC@@AA>>??<<==99::;7889455lmmkkjjkhighfggeeccdbccaa``a^_\]][[\Z[[YYZWXXVVTTURSSTQRRPPQMNNLmmkkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLmjkkjjhhgghfgdeeccbbc`aa``^^_\]][[Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMjkkjjhhighfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMkkjjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJkjjkhighhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKijjhhgghfgdeecdbccaab`a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKjjhhighfgdeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMNNLLMJKKjhhighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLkhighfggeeccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHhighhggeefcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIhgghfgdeeccbbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMNNOLMMKKLHIIighfggeeccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIghfggeeccdbccaa``a^_\]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGhhggeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGhfgdeeccbbc`aa``^^_\]][[ZZ[XYYWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHfggeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHggeeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHgeefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEdeeccbbc`ab`a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEeeccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKHHIIGGHDEEeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFccdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDcdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMNNLLMKKLHIIJGHHEEFFDDdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEc`aa``^^_\]][[ZZ[XYYWWXUVVTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEB`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABaa``a^_\]][[\Z[[YYZWXXVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBCa``^^_]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKHHIIGGHHEEFCDDEABBC?`a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMNNLLMJKKHHIJGHHEEFFDDEEBBCC@@AA_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=_]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABBC?@@A=>]][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>]][[ZZ[XYYWWXUVVTTURSSQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>?][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?[[\Z[[YYZWXXVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEABBC?@@A=>>?;<[Z[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<=Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@A=>>??<<==9XYYWWXUVVTTURSSQQROPPMMNNLLMJKKHHIIGGHDEEFDDEEBBCC@@AA>>??<<==99YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899YZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99:ZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??<<==99::WWXUVVTTURSSQQROPPMMNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::7WXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::7XXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<=899::77XVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>?;<<==99::778VVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::7788VVTTURSSQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899:;7889VTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884WTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::778894TUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::7788945TURSSQQROPPQMNNLLMJKKHHIIGGHHEEFCDDEABCC@@AA>>??<<==99::;7889455mllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMllkkjjiihhggffeeddccbbaa``__^^]]\\[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLlkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKkjjiihhggffeedccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPONNMMLLKKJJIIhhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHggffeeddccbbaa``__^^]]\\[[ZZYYXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGgffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGfeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFfeeddccbba``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEdccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDdccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLKKJJIIHHGGFFEEDDccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDcbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCbbaa``__^^]]\\[[ZZYYXXWWVVUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAa``__^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA`__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@_^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@?_^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIHHGGFFEEDDCCBBAA@@??^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>]]\\[[ZZYYXXWWVVUUTTSSRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>=]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>=\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<\[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<;[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;ZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;:ZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEDDCCBBAA@@??>>==<<;;::YYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::YXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9XXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99XXWWVVUUTTSSRRQQPPOONMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::998XWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::998WWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988WVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887VVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::998877VVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::988776VUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988776UUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766UTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::998877665UTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBAA@@??>>==<<;;::9988776655LMJKKLHIIGGHHEEFCDDEABBMKLHIIJGHHEEFFDDEABBMKKLHIIJGHHEEFFDDEEBBCBJKKLHIIGGHHEEFCDDEABBCBKLHIIGGHHEEFCDDEABBC?DKLHIIGGHHEEFFDDEABBC?@DLHIIJGHHEEFFDDEEBBC?@@DHIGHDEFFDDEEBBCC@@ADHIIGGHHEEFCDDEABBC?@@A<IGHEFDEABBC?@@A=>IJGHHEEFFDDEEBBC?@@A=>>JGHHEEFFDDEEBBCC@@AA>>GHEFCDDEABBC?@@A=>>GHHEEFFDDEABBC?@@A=>>?>HEFDEABBC?@@A=>>?;@HEEFFDDEEBBCC@@AA>>??<@HEEFCDDEABBC?@@A=>>?;<@EFCDDEABBC?@@A=>>?;<<@EFFDDEABBC?@@A=>>?;<<=@FDEBC@A=>>??<<==:FCDDEBBCC@@AA>>??<<==9:CDDEABBC?@@A=>>?;<<=89:DEABBC?@@A=>>?;<<==99:DEEBBC?@@A=>>??<<==99::EBC@A>?<=9:3EABBC?@@A=>>?;<<=899::3ABBC?@@A=>>?;<<=899::73BC?@@A=>>?;<<==99::773BCC@@AA>>??<<==99::7783BC?@@A=>>?;<<=899::7785C?@@A=>>?;<<=899::77885?@@A=>>?;<<==99::778895@A>?<=9:78947@AA>>??<<==99::;7889457@A=>>?;<<=899::77884457A=>>?;<<==99::778894557=>>??<<==99::7788945567>?<=9:78945566/>?;<<=899::7788445561/>?;<<==99::77889455612/?;<<==99::778894556622/?<<==99::7788945566223/;<<=899::77884455622331<=899::778844556122331<==99::7788945561223341=9:7894556622334/1=99::;78894556622334/01899::77884455612233//019:789455612233//0039::778894556622334/0013:7894556622334/0011):7845612233//001+):77889455612233//0011,)7894556622334/0011,,+78894556622334/0011,,-+7884455612233//011,,--+845612233//0011,,--+894556622334/0011,,--.+94556622334/0011,,--..,4556622334/0011,,--..*,455612233//0011,,--.)*,5612233//0011,,--.)**,56622334/0011,,--..**+,6234/0011,,--..**++.LMJKKLHIIGGHHEEFCDDEABBMKLHIIJGHHEEFFDDEABBMKKLHIIJGHHEEFFDDEEBBCBJKKLHIIGGHHEEFCDDEABBCBKLHIIGGHHEEFCDDEABBC?DKLHIIGGHHEEFFDDEABBC?@DLHIIJGHHEEFFDDEEBBC?@@DHIGHDEFFDDEEBBCC@@ADHIIGGHHEEFCDDEABBC?@@A<IGHEFDEABBC?@@A=>IJGHHEEFFDDEEBBC?@@A=>>JGHHEEFFDDEEBBCC@@AA>>GHEFCDDEABBC?@@A=>>GHHEEFFDDEABBC?@@A=>>?>HEFDEABBC?@@A=>>?;@HEEFFDDEEBBCC@@AA>>??<@HEEFCDDEABBC?@@A=>>?;<@EFCDDEABBC?@@A=>>?;<<@EFFDDEABBC?@@A=>>?;<<=@FDEBC@A=>>??<<==:FCDDEBBCC@@AA>>??<<==9:CDDEABBC?@@A=>>?;<<=89:DEABBC?@@A=>>?;<<==99:DEEBBC?@@A=>>??<<==99::EBC@A>?<=9:3EABBC?@@A=>>?;<<=899::3ABBC?@@A=>>?;<<=899::73BC?@@A=>>?;<<==99::773BCC@@AA>>??<<==99::7783BC?@@A=>>?;<<=899::7785C?@@A=>>?;<<=899::77885?@@A=>>?;<<==99::778895@A>?<=9:78947@AA>>??<<==99::;7889457@A=>>?;<<=899::77884457A=>>?;<<==99::778894557=>>??<<==99::7788945567>?<=9:78945566/>?;<<=899::7788445561/>?;<<==99::77889455612/?;<<==99::778894556622/?<<==99::7788945566223/;<<=899::77884455622331<=899::778844556122331<==99::7788945561223341=9:7894556622334/1=99::;78894556622334/01899::77884455612233//019:789455612233//0039::778894556622334/0013:7894556622334/0011):7845612233//001+):77889455612233//0011,)7894556622334/0011,,+78894556622334/0011,,-+7884455612233//011,,--+845612233//0011,,--+894556622334/0011,,--.+94556622334/0011,,--..,4556622334/0011,,--..*,455612233//0011,,--.)*,5612233//0011,,--.)**,56622334/0011,,--..**+,6234/0011,,--..**++.LMJKKLHIIGGHHEEFCDDEABBMKLHIIJGHHEEFFDDEABBMKKLHIIJGHHEEFFDDEEBBCBJKKLHIIGGHHEEFCDDEABBCBKLHIIGGHHEEFCDDEABBC?DKLHIIGGHHEEFFDDEABBC?@DLHIIJGHHEEFFDDEEBBC?@@DHIGHDEFFDDEEBBCC@@ADHIIGGHHEEFCDDEABBC?@@A<IGHEFDEABBC?@@A=>IJGHHEEFFDDEEBBC?@@A=>>JGHHEEFFDDEEBBCC@@AA>>GHEFCDDEABBC?@@A=>>GHHEEFFDDEABBC?@@A=>>?>HEFDEABBC?@@A=>>?;@HEEFFDDEEBBCC@@AA>>??<@HEEFCDDEABBC?@@A=>>?;<@EFCDDEABBC?@@A=>>?;<<@EFFDDEABBC?@@A=>>?;<<=@FDEBC@A=>>??<<==:FCDDEBBCC@@AA>>??<<==9:CDDEABBC?@@A=>>?;<<=89:DEABBC?@@A=>>?;<<==99:DEEBBC?@@A=>>??<<==99::EBC@A>?<=9:3EABBC?@@A=>>?;<<=899::3ABBC?@@A=>>?;<<=899::73BC?@@A=>>?;<<==99::773BCC@@AA>>??<<==99::7783BC?@@A=>>?;<<=899::7785C?@@A=>>?;<<=899::77885?@@A=>>?;<<==99::778895@A>?<=9:78947@AA>>??<<==99::;7889457@A=>>?;<<=899::77884457A=>>?;<<==99::778894557=>>??<<==99::7788945567>?<=9:78945566/>?;<<=899::7788445561/>?;<<==99::77889455612/?;<<==99::778894556622/?<<==99::7788945566223/;<<=899::77884455622331<=899::778844556122331<==99::7788945561223341=9:7894556622334/1=99::;78894556622334/01899::77884455612233//019:789455612233//0039::778894556622334/0013:7894556622334/0011):7845612233//001+):77889455612233//0011,)7894556622334/0011,,+78894556622334/0011,,-+7884455612233//011,,--+845612233//0011,,--+894556622334/0011,,--.+94556622334/0011,,--..,4556622334/0011,,--..*,455612233//0011,,--.)*,5612233//0011,,--.)**,56622334/0011,,--..**+,6234/0011,,--..**++.MLLKKJJIIHHGGFFEEDDCCB#LKJIHGFEDCB#LKKJJIIHHGGFFEEDDCCBBA#LKKJJIIHHGGFFEEDDCCBBA#KJIHGFEDCBA"KJJIIHHGGFFEEDDCCBBAA@"JIHGFEDCBA@"JIHGFEEDDCCBBAA@@?"JIIHHGGFFEEDDCCBBAA@@?"IHGFEDCBA@?!IHHGGFFEEDDCCBBAA@@??>!HGFEDCBA@?>!HGFEDCBA@?>!HGGFFEEDDCCBBAA@@??>>=!GFEDCBA@?>= GFFEEDDCCBBAA@@??>>==< GFFEEDDCCBBAA@@??>>==< FEDCBA@?>=< FEEDDCCBBAA@@??>>==<<; EDCBA@?>=<;EDCBBAA@@??>>==<<;;:EDDCCBBAA@@??>>==<<;;:DCBA@?>=<;:DCCBBAA@@??>>==<<;;::9CBA@?>=<;:9CBA@?>=<;:9CBBAA@@??>>==<<;;::998BA@?>=<;:98BAA@@??>>==<<;;::99887BAA@@??>>==<<;;::99887A@?>=<;:987A@@??>>==<<;;::9988776@?>=<;:9876@??>>==<<;;::998877665@??>>==<<;;::998877665?>=<;:98765?>>==<<;;::99887766554>=<;:987654>=<;:987654>==<<;;::9988776655443=<;:9876543=<<;;::998877665544332=<<;;::998877665543322<;:98765432<;;::99887766554433221;:987654321;::9988776655443322110;::9988776655443322110:9876543210:99887766554433221100/9876543210/9876543210/9887766554433221100//.876543210/.87766554433221100//..-8776655443322110//..--76543210/.-766554433221100//..--,6543210/.-,6554433221100//..--,,+6554433221100//..--,,+543210/.-,+54433221100//..--,,++*43210/.-,+*feeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTdefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUdfcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUU¿dccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURScdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTabc`aa``^^_\]][[ZZ[XYYWWXUVVTTUSSTQac`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQb`aa``a^_\]][[\Z[[YYZWXXVVTTURSSTQRbaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRbaa``^^_\]^[\Z[[YYZWXXVVWTUUSSTQRRPca``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPc``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPa`a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQaa^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMa^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMb^_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQMN¿__][\Z[[YYZWXXVVWTUUSSTQRRPPQMNN__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNL_\]][[\Z[XYYWWXUVVTTURSSQQRPPQMNNOL\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLL]][[\Z[[YYZWXXVVTTUUSSTQRRPPQMNNLLM][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMM][[ZZ[YYZWXXVVWTUUSSTQRRPPQMNNOLMMK[[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJK[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKK\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLY[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHY[XYYWWXUVVTTURSSQQROPPMMNNLLMJKKHHZ[YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLHIZYYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIXYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJ¿XYWWXUVVTTURSSQQROPPMMNOLMMKKLHIIJGXWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGYWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHVXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHWXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEWUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHETVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEETVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFTWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFTTURSSQQROPPQMNNLLMJKKHHIIGGHHEEFCUTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDUUSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDVUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEVRSSQQROPPMMNNLLMJKLHIIJGHHEEFFDDEESSQROPPQMNNLLMJKKLHIIGGHHEEFCDDEA¿TSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABTTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBUQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBCQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?SRPPQMNNLLMMKKLHIIJGHHEEFFDDEABBC?@SPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@OPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@PPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@APQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=QMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>NMNNLLMJKKHHIIGGHEEFFDDEEBBCC@@AA>>NNLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>NNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?NLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??¿OLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<feeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTdefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUdfcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUU¿dccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURScdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTabc`aa``^^_\]][[ZZ[XYYWWXUVVTTUSSTQac`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQb`aa``a^_\]][[\Z[[YYZWXXVVTTURSSTQRbaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRbaa``^^_\]^[\Z[[YYZWXXVVWTUUSSTQRRPca``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPc``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPa`a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQaa^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMa^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMb^_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQMN¿__][\Z[[YYZWXXVVWTUUSSTQRRPPQMNN__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNL_\]][[\Z[XYYWWXUVVTTURSSQQRPPQMNNOL\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLL]][[\Z[[YYZWXXVVTTUUSSTQRRPPQMNNLLM][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMM][[ZZ[YYZWXXVVWTUUSSTQRRPPQMNNOLMMK[[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJK[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKK\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLY[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHY[XYYWWXUVVTTURSSQQROPPMMNNLLMJKKHHZ[YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLHIZYYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIXYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJ¿XYWWXUVVTTURSSQQROPPMMNOLMMKKLHIIJGXWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGYWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHVXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHWXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEWUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHETVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEETVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFTWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFTTURSSQQROPPQMNNLLMJKKHHIIGGHHEEFCUTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDUUSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDVUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEVRSSQQROPPMMNNLLMJKLHIIJGHHEEFFDDEESSQROPPQMNNLLMJKKLHIIGGHHEEFCDDEA¿TSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABTTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBUQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBCQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?SRPPQMNNLLMMKKLHIIJGHHEEFFDDEABBC?@SPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@OPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@PPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@APQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=QMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>NMNNLLMJKKHHIIGGHEEFFDDEEBBCC@@AA>>NNLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>NNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?NLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??¿OLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<feeccdbc`aa``a^_\]][[\Z[[YYZWXUVVTTdefcdbccaa``a^__]][[\Z[[YYZWXXVVWTUdfcdbccaa``a^__]]^[\Z[[YYZWXXVVWTUU¿dccdbc`aa``^^_\]][[\Z[XYYWWXUVVTTURccdbc`aa``a^_\]][[\Z[[YYWWXUVVTTURScdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSdbccaa``a^__]][[\Z[[YYZWXXVVWTUUSSTabc`aa``^^_\]][[ZZ[XYYWWXUVVTTUSSTQac`aa``a^_\]][[\Z[[YYWWXUVVTTURSSQQb`aa``a^_\]][[\Z[[YYZWXXVVTTURSSTQRbaa``a^__]][[\Z[[YYZWXXVVWTUUSSTQRRbaa``^^_\]^[\Z[[YYZWXXVVWTUUSSTQRRPca``^^_\]][[\Z[XYYWWXUVVTTURSSQQROPc``a^_\]][[\Z[[YYZWXUVVTTURSSQQRRPPa`a^__]][[\Z[[YYZWXXVVWTUUSSTQRRPPQaa^__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMa^^_\]][[\Z[XYYWWXUVVTTURSSQQROPPMMb^_\]][[\Z[[YYWWXUVVTTURSSQQRRPPQMN¿__][\Z[[YYZWXXVVWTUUSSTQRRPPQMNN__]]^[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNL_\]][[\Z[XYYWWXUVVTTURSSQQRPPQMNNOL\]][[\Z[[YYWWXUVVTTURSSQQROPPQMNNLL]][[\Z[[YYZWXXVVTTUUSSTQRRPPQMNNLLM][[\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMM][[ZZ[YYZWXXVVWTUUSSTQRRPPQMNNOLMMK[[\Z[XYYWWXUVVTTURSSQQROPPQMNNLLMJK[\Z[[YYZWXUVVTTURSSQQRRPPQMNNLLMJKK\Z[[YYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLY[[YYZWXXVVWTUUSSTQRRPPQMNNOLMMKKLHY[XYYWWXUVVTTURSSQQROPPMMNNLLMJKKHHZ[YYWWXUVVTTURSSQQRRPPQMNNLLMJKKLHIZYYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIXYZWXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJ¿XYWWXUVVTTURSSQQROPPMMNOLMMKKLHIIJGXWWXUVVTTURSSQQROPPQMNNLLMJKKLHIIGGYWXXVVWTUUSSTQRRPPQMNNLLMJKKLHIIGGHVXXVVWTUUSSTQRRPPQMNNLLMMKKLHIIJGHHWXVVWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEWUVVTTURSSQQROPPQMNNLLMJKKLHIIGGHHETVVTTURSSTQRRPPQMNNLLMJKKLHIIGGHHEETVWTUUSSTQRRPPQMNNLLMMKKLHIIGGHHEEFTWTUUSSTQRRPPQMNNOLMMKKLHIIJGHHEEFFTTURSSQQROPPQMNNLLMJKKHHIIGGHHEEFCUTURSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDUUSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDVUSSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEVRSSQQROPPMMNNLLMJKLHIIJGHHEEFFDDEESSQROPPQMNNLLMJKKLHIIGGHHEEFCDDEA¿TSTQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABTTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBUQRRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBCQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?SRPPQMNNLLMMKKLHIIJGHHEEFFDDEABBC?@SPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@OPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@PPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@APQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=QMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>NMNNLLMJKKHHIIGGHEEFFDDEEBBCC@@AA>>NNLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>NNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?NLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??¿OLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<aJZeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUaJYeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTaJYddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTaJYddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTaJXdccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSaJXccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSbKWcbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRbKWcbbaa``__^^]]\\[[ZZYYXXWWVVUUTSSRRbKWbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRbKVbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQcKVaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQcKVaa``__^^]\\[[ZZYYXXWWVVUUTTSSRRQQPcKUa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPdKU``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPdLT`__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOdLT__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOOdLT__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOOdLS_^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONeLS^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNfLS^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMfLS^]]\\[[ZZYYXXWWVVUUTTSSRRQPPOONNMMfLS]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMfLR]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLfLR\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLfLR\\[[ZYYXXWWVVUUTTSSRRQQPPOONNMMLLKgLQ\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKgLQ[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKgLP[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJgLPZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJgLPZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJhLOZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIiMOYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIiMNYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHiMNYXXWWVVUUTTSSRRQQPPOONMMLLKKJJIIHHiMNXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHiMMXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGiMMWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGiMLWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFjMLWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFjNLVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFjNLVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEjNLUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEkNLUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEkNKUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDlNKTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDlNJTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDClNJTSSRRQQPPOONNMMLLKJJIIHHGGFFEEDDCClNJSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCClNISRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBlNIRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBnNHRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAnOHRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAnOHQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAAnOGQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@nOGPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@nOGPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@oOFPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@?oOFOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??oOEONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>pPEONNMMLLKKJJIIHHGFFEEDDCCBBAA@@??>>pPENNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>pPENMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>=pPEMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==qPDMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<URSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455USSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::778894556SSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??<<==99::7788945566SSQQROPPMMNNLLMJKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::77889455662SQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612TQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<=899::778844556122QRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>?;<<==99::7788945566223RRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::77889455662233ROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884556622334RPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233/PPQMNNLLMMKKLHIIJGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//PQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0PQMNNLLMJKKHHIIGGHHEEFCDDEABBC?@@A>>??<<==99::;78894556622334/00QMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//00MNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//001NNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??<<==99::778894556622334/0011NNLLMJKKHHIIGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,NLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//001+,LLMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,LMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>?;<<==99::778894556622334/0011,,-MMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--MJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612334/0011,,--.JKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.KKLHIIJGHHEEFFDDEABBC?@@A=>>?;<<==99::778894556122334/0011,,--.)KLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..*KLHIIGGHHEEFCDDEABBC?@@A=>>?;<==99::;78894556622334/0011,,--..**LHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.)**HIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**+IIJGHHEEFFDDEEBBCC@@A=>>??<<==99::778894556622334/0011,,--..**++IIGGHDEEFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,IGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//001+,,--.)**++,GGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**++,%GHHEEFFDDEEBBC?@@A=>>??<<==99::778894556622334/0011,,--..**++,,&HHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&HHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//011,,--..**++,,&&'HEEFFDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&'EEFFDDEEBBC?@@A=>>?;<<==99::778894556622334/0011,,--.)**++,%&&''EFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''(EFCDDEABBC?@@A=>>?;<<=899:;78894556622334/0011,,--..**++,,&&''((FCDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&''((FDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**++,%&&''(("DDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""DDEABCC@@AA>>??<<==99::;78894556622334/0011,,--..**++,,&&''((""#DEABBC?@@A=>>?;<<=899::77884455612233//001+,,--.)**++,%&&''((""#EABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**++,%&&''((""##EBBC?@@A=>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$BBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$BBC?@@A=>>?;<<=899::77884455612233//001+,,-..**++,,&&''(()"##$$&BC?@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&''((""##$$&C?@@A=>>?;<<==99::778894556622334/0011,,--.)**++,,&&''((""##$$&C@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$&?@@A=>>?;<<=899::77884556622334/0011,,--..**++,,&&''((""##$$&&@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&''((""##$$&@A=>>?;<<==99::77889455612233//0011,,--.)**++,%&&''((""##$$& AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& A=>??<<==99::;78894556622334/0011,,--..**++,,&&''((""##$$&& !=>>?;<<=899::77884455612233//001+,,--.)**++,%&&''((""##$$& !!>>?;<<==99::77889455612233//0011,,--.)**++,%&&''((""##$$& !!>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"?;<<=899::77884455612233//001+,,--.)**++,&&''(()"##$$&& !!"";<<==99::77889455612233//0011,,--.)**++,%&&''((""##$$& !!"<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"URSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455USSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::778894556SSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??<<==99::7788945566SSQQROPPMMNNLLMJKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::77889455662SQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612TQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<=899::778844556122QRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>?;<<==99::7788945566223RRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::77889455662233ROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884556622334RPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233/PPQMNNLLMMKKLHIIJGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//PQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0PQMNNLLMJKKHHIIGGHHEEFCDDEABBC?@@A>>??<<==99::;78894556622334/00QMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//00MNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//001NNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??<<==99::778894556622334/0011NNLLMJKKHHIIGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,NLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//001+,LLMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,LMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>?;<<==99::778894556622334/0011,,-MMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--MJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612334/0011,,--.JKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.KKLHIIJGHHEEFFDDEABBC?@@A=>>?;<<==99::778894556122334/0011,,--.)KLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..*KLHIIGGHHEEFCDDEABBC?@@A=>>?;<==99::;78894556622334/0011,,--..**LHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.)**HIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**+IIJGHHEEFFDDEEBBCC@@A=>>??<<==99::778894556622334/0011,,--..**++IIGGHDEEFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,IGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//001+,,--.)**++,GGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**++,%GHHEEFFDDEEBBC?@@A=>>??<<==99::778894556622334/0011,,--..**++,,&HHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&HHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//011,,--..**++,,&&'HEEFFDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&'EEFFDDEEBBC?@@A=>>?;<<==99::778894556622334/0011,,--.)**++,%&&''EFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''(EFCDDEABBC?@@A=>>?;<<=899:;78894556622334/0011,,--..**++,,&&''((FCDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&''((FDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**++,%&&''(("DDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""DDEABCC@@AA>>??<<==99::;78894556622334/0011,,--..**++,,&&''((""#DEABBC?@@A=>>?;<<=899::77884455612233//001+,,--.)**++,%&&''((""#EABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**++,%&&''((""##EBBC?@@A=>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$BBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$BBC?@@A=>>?;<<=899::77884455612233//001+,,-..**++,,&&''(()"##$$&BC?@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&''((""##$$&C?@@A=>>?;<<==99::778894556622334/0011,,--.)**++,,&&''((""##$$&C@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$&?@@A=>>?;<<=899::77884556622334/0011,,--..**++,,&&''((""##$$&&@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&''((""##$$&@A=>>?;<<==99::77889455612233//0011,,--.)**++,%&&''((""##$$& AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& A=>??<<==99::;78894556622334/0011,,--..**++,,&&''((""##$$&& !=>>?;<<=899::77884455612233//001+,,--.)**++,%&&''((""##$$& !!>>?;<<==99::77889455612233//0011,,--.)**++,%&&''((""##$$& !!>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"?;<<=899::77884455612233//001+,,--.)**++,&&''(()"##$$&& !!"";<<==99::77889455612233//0011,,--.)**++,%&&''((""##$$& !!"<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"URSSQQRRPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455USSTQRRPPQMNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::778894556SSTQRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??<<==99::7788945566SSQQROPPMMNNLLMJKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::77889455662SQQROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612TQRRPPQMNNLLMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<=899::778844556122QRRPPQMNNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>?;<<==99::7788945566223RRPPQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::77889455662233ROPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884556622334RPPQMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233/PPQMNNLLMMKKLHIIJGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//PQMNNOLMMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0PQMNNLLMJKKHHIIGGHHEEFCDDEABBC?@@A>>??<<==99::;78894556622334/00QMNNLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//00MNNLLMMKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//001NNLLMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>??<<==99::778894556622334/0011NNLLMJKKHHIIGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,NLLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//001+,LLMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,LMMKKLHIIJGHHEEFFDDEEBBC?@@A=>>?;<<==99::778894556622334/0011,,-MMKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--MJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612334/0011,,--.JKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.KKLHIIJGHHEEFFDDEABBC?@@A=>>?;<<==99::778894556122334/0011,,--.)KLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..*KLHIIGGHHEEFCDDEABBC?@@A=>>?;<==99::;78894556622334/0011,,--..**LHIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.)**HIIGGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**+IIJGHHEEFFDDEEBBCC@@A=>>??<<==99::778894556622334/0011,,--..**++IIGGHDEEFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,IGGHHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//001+,,--.)**++,GGHHEEFFDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**++,%GHHEEFFDDEEBBC?@@A=>>??<<==99::778894556622334/0011,,--..**++,,&HHEEFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&HHEEFCDDEABBC?@@A=>>?;<<=899::77884455612233//011,,--..**++,,&&'HEEFFDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&'EEFFDDEEBBC?@@A=>>?;<<==99::778894556622334/0011,,--.)**++,%&&''EFFDDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''(EFCDDEABBC?@@A=>>?;<<=899:;78894556622334/0011,,--..**++,,&&''((FCDDEABBC?@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&''((FDDEABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**++,%&&''(("DDEEBBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""DDEABCC@@AA>>??<<==99::;78894556622334/0011,,--..**++,,&&''((""#DEABBC?@@A=>>?;<<=899::77884455612233//001+,,--.)**++,%&&''((""#EABBC?@@A=>>?;<<==99::77889455612233//0011,,--.)**++,%&&''((""##EBBC?@@A=>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$BBCC@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$BBC?@@A=>>?;<<=899::77884455612233//001+,,-..**++,,&&''(()"##$$&BC?@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&''((""##$$&C?@@A=>>?;<<==99::778894556622334/0011,,--.)**++,,&&''((""##$$&C@@AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$&?@@A=>>?;<<=899::77884556622334/0011,,--..**++,,&&''((""##$$&&@@A=>>?;<<=899::77884455612233//0011,,--.)**++,%&&''((""##$$&@A=>>?;<<==99::77889455612233//0011,,--.)**++,%&&''((""##$$& AA>>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& A=>??<<==99::;78894556622334/0011,,--..**++,,&&''((""##$$&& !=>>?;<<=899::77884455612233//001+,,--.)**++,%&&''((""##$$& !!>>?;<<==99::77889455612233//0011,,--.)**++,%&&''((""##$$& !!>??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"??<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"?;<<=899::77884455612233//001+,,--.)**++,&&''(()"##$$&& !!"";<<==99::77889455612233//0011,,--.)**++,%&&''((""##$$& !!"<<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"<==99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"TSRQPONMLKJIHGFEDCBA@?>=<;:98765TSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554SSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::998877665544SSRRQQPPOONNMMLLKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988776655443SRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988776655443RRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433RQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::998877665544332QQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988776655443322QQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988776554433221QPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221PPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::998877665544332211POONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988776655443322110POONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@?>>==<<;;::99887766554433221100OONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100ONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100/NNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//NNMMLLKKJJIIHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//.NMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//.MMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..MLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..-LLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--LLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988776655443221100//..--,LKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,KKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,KJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,+KJJIIHHGGFFEEDDCCBBAA@@??>>==<;;::99887766554433221100//..--,,++JJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++JIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++*IIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**IIHHGGFFEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**)IHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**)HHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))HGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))(GGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((GGFFEEDDCCBBAA@@??>>==<<;;::9988776655443322110//..--,,++**))(('GFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))(('FFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''FEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&FEEDDCCBBAA@@??>>==<<;;::9887766554433221100//..--,,++**))((''&&EEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&EDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%DDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%DDCCBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$DCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$CCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$CBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#BBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##BBAA@@??>>==<<;;::99887766554433221100//..-,,++**))((''&&%%$$##"BAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"AA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""A@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!A@@??>>==<<;;::9988776554433221100//..--,,++**))((''&&%%$$##""!!@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!! ??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!! ??>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!! ?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!! >>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!! >==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!! ==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!! ==<<;;::99887766554433221100//..--,,++**)((''&&%%$$##""!! =<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!! <<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!! <;;::99887766554433221100//..--,,++**))((''&&%%$$##""!! 612233//001+,,--.)**++.12233//0011,,--.)**++,#234/0011,,--..**++,,$2334/0011,,--..**++,,&$233//001+,,-..**++,,&&$3/01,-.)**++,%&&$34/0011,,--.)**++,,&&'$4/0011,,--..**++,,&&''&/0011,,--..**++,,&&''(&/0011,,--.)**++,%&&''(&01,-.)**++,%&&''((&011,,--..**++,,&&''(("&1,-.*+,&'("(1+,,--.)**++,%&&''((""(1,,--.)**++,%&&''((""#(,-.*+,&'("#(,--..**++,,&&''((""##$(,--.)**+,,&&''(()"##$$+-.)**++,%&&''((""##$$+-..**++,,&&''((""##$$&.*+,&'("#$&.**++,,&&''((""##$$&&)**++,%&&''((""##$$&*+,%&&''((""##$$&*++,,&&''((""##$$& +,&'("#$& +,%&&''((""##$$& +,%&&''((""##$$& !,&'("#$& !! ,&&''((""##$$& !!" %&&'(()"##$$&& !!"" &'("#$& !!" &''((""##$$& !!" '("#$& !!""'(()"##$$&& !!"""'((""##$$& !!""("#$& !!""(""##$$& !!"""#$& !"$"#$& !!"$"##$$& !!"$#$& !!"#$$&& !!"$& !"$& !!"$& !!"& !!"& !!"" !!" !" !!" !" !" !!"!"!""""       612233//001+,,--.)**++.12233//0011,,--.)**++,#234/0011,,--..**++,,$2334/0011,,--..**++,,&$233//001+,,-..**++,,&&$3/01,-.)**++,%&&$34/0011,,--.)**++,,&&'$4/0011,,--..**++,,&&''&/0011,,--..**++,,&&''(&/0011,,--.)**++,%&&''(&01,-.)**++,%&&''((&011,,--..**++,,&&''(("&1,-.*+,&'("(1+,,--.)**++,%&&''((""(1,,--.)**++,%&&''((""#(,-.*+,&'("#(,--..**++,,&&''((""##$(,--.)**+,,&&''(()"##$$+-.)**++,%&&''((""##$$+-..**++,,&&''((""##$$&.*+,&'("#$&.**++,,&&''((""##$$&&)**++,%&&''((""##$$&*+,%&&''((""##$$&*++,,&&''((""##$$& +,&'("#$& +,%&&''((""##$$& +,%&&''((""##$$& !,&'("#$& !! ,&&''((""##$$& !!" %&&'(()"##$$&& !!"" &'("#$& !!" &''((""##$$& !!" '("#$& !!""'(()"##$$&& !!"""'((""##$$& !!""("#$& !!""(""##$$& !!"""#$& !"$"#$& !!"$"##$$& !!"$#$& !!"#$$&& !!"$& !"$& !!"$& !!"& !!"& !!"" !!" !" !!" !" !" !!"!"!""""       612233//001+,,--.)**++.12233//0011,,--.)**++,#234/0011,,--..**++,,$2334/0011,,--..**++,,&$233//001+,,-..**++,,&&$3/01,-.)**++,%&&$34/0011,,--.)**++,,&&'$4/0011,,--..**++,,&&''&/0011,,--..**++,,&&''(&/0011,,--.)**++,%&&''(&01,-.)**++,%&&''((&011,,--..**++,,&&''(("&1,-.*+,&'("(1+,,--.)**++,%&&''((""(1,,--.)**++,%&&''((""#(,-.*+,&'("#(,--..**++,,&&''((""##$(,--.)**+,,&&''(()"##$$+-.)**++,%&&''((""##$$+-..**++,,&&''((""##$$&.*+,&'("#$&.**++,,&&''((""##$$&&)**++,%&&''((""##$$&*+,%&&''((""##$$&*++,,&&''((""##$$& +,&'("#$& +,%&&''((""##$$& +,%&&''((""##$$& !,&'("#$& !! ,&&''((""##$$& !!" %&&'(()"##$$&& !!"" &'("#$& !!" &''((""##$$& !!" '("#$& !!""'(()"##$$&& !!"""'((""##$$& !!""("#$& !!""(""##$$& !!"""#$& !"$"#$& !!"$"##$$& !!"$#$& !!"#$$&& !!"$& !"$& !!"$& !!"& !!"& !!"" !!" !" !!" !" !" !!"!"!""""       43210/.-,+*433221100//..--,,++**)3210/.-,+*)3221100//..--,,++**))(3221100//..-,,++**))((210/.-,+*)(21100//..--,,++**))(('10/.-,+*)('100//..--,,++**))((''&100//..--,,++**))((''&0/.-,+*)('&0//..--,,++**))((''&&%/.-,+*)('&%/.-,+*)('&%/..--,,++**))((''&&%%$.-,+*)('&%$.--,,++**))((''&&%%$$#.--,,++*))((''&&%%$$##-,+*)('&%$#-,,++**))((''&&%%$$##",+*)('&%$#",++**))((''&&%%$$##""!,++**))((''&&%%$$##""!+*)('&%$#"!+**))((''&&%%$$##""!! *)('&%$#"! *)('&%$#"! *))((''&&%%$$##""!! )('&%$#"! )((''&&%%$$##""!! )(('&&%%$$##""!! ('&%$#"! (''&&%%$$##""!! '&%$#"! '&&%%$$##""!! '&&%%$$##""!! &%$#"! &%%$$##""!! %$#"! %$#"! %$$##""!! $#"!  $##""!!  #"!  #"!  #""!!  "!  "!!  "!!  !  !                  KLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<KMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<LMKKLHIIJGHHEEFFDDEABBC?@@A=>>?;<<=LKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==HKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=9IKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=89¿ILHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99KHIIJGHHEEFFDDEEBBCC@@A=>>??<<==99:GHIIGGHDEEFCDEEBBCC@@AA>>??<<==99::GIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::HIGGHHEEFFDDEABBC?@@A=>>?;<<==99::7HJGHHEEFFDDEEBBC?@@A=>>??<<==99::77IGHHEEFFDDEEBBCC@@AA>>??<<==99::778IGHHEEFCDDEABBC?@@A=>>?;<<=899::778¿IHHEEFFDDEABBC?@@A=>>?;<<=899::7788JHEEFFDDEEBBC?@@A=>>?;<<==99::77889JEEFFDDEEBBCC@@AA>>??<<==99::778894JEEFCDDEABBC?@@A=>>?;<<=899::788945GEFCDDEABBC?@@A=>>?;<<=899::7788445GFFDDEABBC?@@A=>>?;<<==99::77889455GFDDEEBBCC@@AA>>??<<==99::778894556¿GCDDEABBC@@AA>>??<<==99::;788945566CDDEABBC?@@A=>>?;<<=899::7788445561DDEABBC?@@A=>>?;<<==99::77889455612DEEBBC?@@A=>>??<<==99::778894556622EEBBCC@@AA>>??<<==99::7788945566223EABBC?@@A=>>?;<<=899::7788445561223ABBC?@@A=>>?;<<=899::77889455612233BBC?@@A=>>?;<<==99::778894556622334¿BCC@@AA>>??<<==99::778894556622334/BC?@@A=>>?;<<=899::77884456622334/0C?@@A=>>?;<<=899::77884455612233//0?@@A=>>?;<<==99::77889455612233//00@@AA>>??<<==99::778894556622334/001@@A=>??<<==99::;78894556622334/0011@A=>>?;<<=899::77884455612233//001+¿A=>>?;<<==99::77889455612233//0011,<>>??<<==99::778894556622334/0011,,=>??<<==99::778894556622334/0011,,-=>?;<<=899::77884455612233//001+,,-=?;<<==99::77889455612233//0011,,--=?<<==99::778894556622334/0011,,--.=<<==99::778894556622334/0011,,--..9<<=899::77884455612234/0011,,--..*:<=899::77884455612233//0011,,--.)*:==99::778894556122334/0011,,--.)**;=99::778894556622334/0011,,--..**+;99::;78894556622334/0011,,--..**++699::77884455612233//0011,,--.)**++79::77889455612233//0011,,--.)**++,7::778894556622334/0011,,--..**++,,8:778894556622334/0011,,--..**++,,&8:77884455612233//001+,,--.)**++,%&877889455612233//0011,,--.)**++,%&&978894556622334/0011,,--..**++,,&&'98894556622334/0011,,--..**++,,&&''9884455612233//001,,--..**++,,&&''(:84455612233//0011,,--.)**++,%&&''(:94556622334/0011,,--.)**++,%&&''((<4556622334/0011,,--..**++,,&&''(("6556622334/0011,,--..**++,,&&''((""655612233//0011,,--.)**++,%&&''((""65612233//0011,,--.)**++,%&&''((""#66234/0011,,--..**++,,&&''((""##KLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<KMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<LMKKLHIIJGHHEEFFDDEABBC?@@A=>>?;<<=LKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==HKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=9IKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=89¿ILHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99KHIIJGHHEEFFDDEEBBCC@@A=>>??<<==99:GHIIGGHDEEFCDEEBBCC@@AA>>??<<==99::GIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::HIGGHHEEFFDDEABBC?@@A=>>?;<<==99::7HJGHHEEFFDDEEBBC?@@A=>>??<<==99::77IGHHEEFFDDEEBBCC@@AA>>??<<==99::778IGHHEEFCDDEABBC?@@A=>>?;<<=899::778¿IHHEEFFDDEABBC?@@A=>>?;<<=899::7788JHEEFFDDEEBBC?@@A=>>?;<<==99::77889JEEFFDDEEBBCC@@AA>>??<<==99::778894JEEFCDDEABBC?@@A=>>?;<<=899::788945GEFCDDEABBC?@@A=>>?;<<=899::7788445GFFDDEABBC?@@A=>>?;<<==99::77889455GFDDEEBBCC@@AA>>??<<==99::778894556¿GCDDEABBC@@AA>>??<<==99::;788945566CDDEABBC?@@A=>>?;<<=899::7788445561DDEABBC?@@A=>>?;<<==99::77889455612DEEBBC?@@A=>>??<<==99::778894556622EEBBCC@@AA>>??<<==99::7788945566223EABBC?@@A=>>?;<<=899::7788445561223ABBC?@@A=>>?;<<=899::77889455612233BBC?@@A=>>?;<<==99::778894556622334¿BCC@@AA>>??<<==99::778894556622334/BC?@@A=>>?;<<=899::77884456622334/0C?@@A=>>?;<<=899::77884455612233//0?@@A=>>?;<<==99::77889455612233//00@@AA>>??<<==99::778894556622334/001@@A=>??<<==99::;78894556622334/0011@A=>>?;<<=899::77884455612233//001+¿A=>>?;<<==99::77889455612233//0011,<>>??<<==99::778894556622334/0011,,=>??<<==99::778894556622334/0011,,-=>?;<<=899::77884455612233//001+,,-=?;<<==99::77889455612233//0011,,--=?<<==99::778894556622334/0011,,--.=<<==99::778894556622334/0011,,--..9<<=899::77884455612234/0011,,--..*:<=899::77884455612233//0011,,--.)*:==99::778894556122334/0011,,--.)**;=99::778894556622334/0011,,--..**+;99::;78894556622334/0011,,--..**++699::77884455612233//0011,,--.)**++79::77889455612233//0011,,--.)**++,7::778894556622334/0011,,--..**++,,8:778894556622334/0011,,--..**++,,&8:77884455612233//001+,,--.)**++,%&877889455612233//0011,,--.)**++,%&&978894556622334/0011,,--..**++,,&&'98894556622334/0011,,--..**++,,&&''9884455612233//001,,--..**++,,&&''(:84455612233//0011,,--.)**++,%&&''(:94556622334/0011,,--.)**++,%&&''((<4556622334/0011,,--..**++,,&&''(("6556622334/0011,,--..**++,,&&''((""655612233//0011,,--.)**++,%&&''((""65612233//0011,,--.)**++,%&&''((""#66234/0011,,--..**++,,&&''((""##KLMJKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<KMJKKLHIIGGHHEEFFDDEABBC?@@A=>>?;<<LMKKLHIIJGHHEEFFDDEABBC?@@A=>>?;<<=LKKLHIIJGHHEEFFDDEEBBCC@@AA>>??<<==HKKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=9IKLHIIGGHHEEFCDDEABBC?@@A=>>?;<<=89¿ILHIIGGHHEEFFDDEABBC?@@A=>>?;<<==99KHIIJGHHEEFFDDEEBBCC@@A=>>??<<==99:GHIIGGHDEEFCDEEBBCC@@AA>>??<<==99::GIIGGHHEEFCDDEABBC?@@A=>>?;<<=899::HIGGHHEEFFDDEABBC?@@A=>>?;<<==99::7HJGHHEEFFDDEEBBC?@@A=>>??<<==99::77IGHHEEFFDDEEBBCC@@AA>>??<<==99::778IGHHEEFCDDEABBC?@@A=>>?;<<=899::778¿IHHEEFFDDEABBC?@@A=>>?;<<=899::7788JHEEFFDDEEBBC?@@A=>>?;<<==99::77889JEEFFDDEEBBCC@@AA>>??<<==99::778894JEEFCDDEABBC?@@A=>>?;<<=899::788945GEFCDDEABBC?@@A=>>?;<<=899::7788445GFFDDEABBC?@@A=>>?;<<==99::77889455GFDDEEBBCC@@AA>>??<<==99::778894556¿GCDDEABBC@@AA>>??<<==99::;788945566CDDEABBC?@@A=>>?;<<=899::7788445561DDEABBC?@@A=>>?;<<==99::77889455612DEEBBC?@@A=>>??<<==99::778894556622EEBBCC@@AA>>??<<==99::7788945566223EABBC?@@A=>>?;<<=899::7788445561223ABBC?@@A=>>?;<<=899::77889455612233BBC?@@A=>>?;<<==99::778894556622334¿BCC@@AA>>??<<==99::778894556622334/BC?@@A=>>?;<<=899::77884456622334/0C?@@A=>>?;<<=899::77884455612233//0?@@A=>>?;<<==99::77889455612233//00@@AA>>??<<==99::778894556622334/001@@A=>??<<==99::;78894556622334/0011@A=>>?;<<=899::77884455612233//001+¿A=>>?;<<==99::77889455612233//0011,<>>??<<==99::778894556622334/0011,,=>??<<==99::778894556622334/0011,,-=>?;<<=899::77884455612233//001+,,-=?;<<==99::77889455612233//0011,,--=?<<==99::778894556622334/0011,,--.=<<==99::778894556622334/0011,,--..9<<=899::77884455612234/0011,,--..*:<=899::77884455612233//0011,,--.)*:==99::778894556122334/0011,,--.)**;=99::778894556622334/0011,,--..**+;99::;78894556622334/0011,,--..**++699::77884455612233//0011,,--.)**++79::77889455612233//0011,,--.)**++,7::778894556622334/0011,,--..**++,,8:778894556622334/0011,,--..**++,,&8:77884455612233//001+,,--.)**++,%&877889455612233//0011,,--.)**++,%&&978894556622334/0011,,--..**++,,&&'98894556622334/0011,,--..**++,,&&''9884455612233//001,,--..**++,,&&''(:84455612233//0011,,--.)**++,%&&''(:94556622334/0011,,--.)**++,%&&''((<4556622334/0011,,--..**++,,&&''(("6556622334/0011,,--..**++,,&&''((""655612233//0011,,--.)**++,%&&''((""65612233//0011,,--.)**++,%&&''((""#66234/0011,,--..**++,,&&''((""##qPDMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<qPDLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<qPCLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;qQCKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;qQCKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;:qQBKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;:qQBJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::rQAJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9rQAJIIHHGGFFEEDCCBBAA@@??>>==<<;;::99rQAIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99sQ@IHHGGFFEEDDCCBBAA@@??>>==<<;;::998sR@HHGGFFEEDDCCBBAA@@??>>==<<;;::9988sQ?HGGFFEEDDCCBBAA@@??>>==<<;;::99887sQ?HGGFFEEDDCCBBAA@@??>>==<<;;::99887sQ?GGFFEEDDCCBBAA@@??>>==<<;;::998877tQ>GFFEEDDCCBBAA@@??>>==<<;;::9988776uQ>FFEEDDCCBBAA@@??>>==<<;;::99887766uQ>FFEEDDCCBBAA@@??>>==<<;;::99877665uQ=FEEDDCCBBAA@@??>>==<<;;::998877665uR=EEDDCCBBAA@@??>>==<<;;::9988776655uR=EDDCCBBAA@@??>>==<<;;::99887766554uR=EDDCCBBA@@??>>==<<;;::998877665544vR=DDCCBBAA@@??>>==<<;;::998877665544wR>==<<;;::9988776655443wR>==<<;;::99887766554433wR;CBBAA@@??>>==<<;;::998877665544332wR;CBBAA@@??>>==<<;;::998877665544332wR;BBAA@@??>>==<<;;::9988776655443322wS:BAA@@??>>==<<;;::99887766554433221xS:AA@@??>>==<<;;::998877665544332211xS:AA@@??>>==<<;;::998877665443322110yS9A@@??>>==<<;;::9988776655443322110yS9@@??>>==<<;;::99887766554433221100yS8@??>>==<<;;::99887766554433221100/yS8@??>==<<;;::99887766554433221100//zS8??>>==<<;;::99887766554433221100//zS7?>>==<<;;::99887766554433221100//.zS7>>==<<;;::99887766554433221100//..zS6>==<<;;::99887766554433221100//..-{S6>==<<;;::99887766554433221100//..-{T6==<<;;::99887766554433221100//..--{T6=<<;;::99887766554433221100//..--,{T6<<;;::99887766554433221100//..--,,|T6<<;;::9988776655443321100//..--,,+|T5<;;::99887766554433221100//..--,,+|T5;;::99887766554433221100//..--,,++|T4;::99887766554433221100//..--,,++*}T4::99887766554433221100//..--,,++**}U4::99887766554433221100//..--,,++**}U3:99887766554433221100//..--,,++**)}U399887766554433221100//..--,,++**))~U29887766554433221100//..--,,++**))(~U29887766554433221100//..--,,++**))(~U2887766554433221100//..--,,++**))((U187766554433221100//..--,,++**))(('U17766554433221100//..--,,++**))((''V17766554433221100/..--,,++**))((''&V0766554433221100//..--,,++**))((''&V066554433221100//..--,,++**))((''&&V/6554433221100//..--,,++**))((''&&%V/554433221100//..--,,++**))((''&&%%V/554433221100//..--,,++**))((''&&%%V/54433221100//..--,,++**))((''&&%%$āV/4433221100//..--,,++**))((''&&%%$$<=899::77884455612234/0011,,--..**++,,&&''(()"##$$&& !!""=899::77884455612233//0011,,--.)**++,%&&''((""##$$& !!"=99::778894556122334/0011,,--.)**++,%&&''((""##$$& !!"99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"9::;78894556622334/0011,,--..**++,,&&''((""##$$&& !!""9::77884455612233//0011,,--.)**++,%&&''((""##$$& !!"::77889455612233//0011,,--.)**++,%&&''((""##$$& !!":778894556622334/0011,,--..**++,,&&''((""##$$& !!"778894556622334/0011,,--..**++,,&&''((""##$$& !!"77884455612233//001+,,--.)**++,%&&''()"##$$&& !!""7889455612233//0011,,--.)**++,%&&''((""##$$& !!"8894556622334/0011,,--..**++,,&&''((""##$$& !!"894556622334/0011,,--..**++,,&&''((""##$$& !!"84455612233//001,,--..**++,,&&''(()"##$$&& !!""4455612233//0011,,--.)**++,%&&''((""##$$& !!"4556622334/0011,,--.)**++,%&&''((""##$$& !!"556622334/0011,,--..**++,,&&''((""##$$& !!"56622334/0011,,--..**++,,&&''((""##$$&& !!""5612233//0011,,--.)**++,%&&''((""##$$& !!"612233//0011,,--.)**++,%&&''((""##$$& !!"622334/0011,,--..**++,,&&''((""##$$& !!"22334/0011,,--..**++,,&&''((""##$$&& !!"2233//001+,,--.)**++,%&&''((""##$&& !!"" 233//0011,,--.)**++,%&&''((""##$$& !!" 334/0011,,--..**++,,&&''((""##$$& !!" 34/0011,,--..**++,,&&''((""##$$& !!" 3//001+,,--.**++,,&&''(()"##$$&& !!"" //0011,,--.)**++,%&&''((""##$$& !!"  /0011,,--.)**++,,&&''((""##$$& !!" 0011,,--..**++,,&&''((""##$$& !!" 011,,--..**++,,&&''((""##$$&& !!"" 011,,--.)**++,%&&''((""##$$& !!" 11,,--.)**++,%&&''((""##$$& !!" 1,,--..**++,,&&''((""##$$& !!" ,,--..**++,,&&''((""##$$&& !!"" ,,--.)**++,%&&''((""##$$& !!"" ,--.)**++,%&&''((""##$$& !!" --..**++,,&&''((""##$$& !!" -..**++,,&&''((""##$$& !!" -.)**++,&&''(()"##$$&& !!"" .)**++,%&&''((""##$$& !!"  .**++,,&&''((""##$$& !!" **++,,&&''((""##$$& !!" *++,,&&''(()"##$$&& !!"" *++,%&&''((""##$$& !!" ++,%&&''((""##$$& !!" +,,&&''((""##$$& !!" ,&'("#$& !" ,%&&''((""##$$& !!" %&&''((""##$$& !!" &'("#$& !!" &''((""##$$& !!" &''()"##$$&& !!"" '("#$& !!"  '((""##$$& !!" ("#$& !!" ()"##$$&& !!"" (""##$$& !!"   "#$& !!"  "##$$& !!"  #$& !"  #$& !!"  #$$& !!" $& !!" <=899::77884455612234/0011,,--..**++,,&&''(()"##$$&& !!""=899::77884455612233//0011,,--.)**++,%&&''((""##$$& !!"=99::778894556122334/0011,,--.)**++,%&&''((""##$$& !!"99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"9::;78894556622334/0011,,--..**++,,&&''((""##$$&& !!""9::77884455612233//0011,,--.)**++,%&&''((""##$$& !!"::77889455612233//0011,,--.)**++,%&&''((""##$$& !!":778894556622334/0011,,--..**++,,&&''((""##$$& !!"778894556622334/0011,,--..**++,,&&''((""##$$& !!"77884455612233//001+,,--.)**++,%&&''()"##$$&& !!""7889455612233//0011,,--.)**++,%&&''((""##$$& !!"8894556622334/0011,,--..**++,,&&''((""##$$& !!"894556622334/0011,,--..**++,,&&''((""##$$& !!"84455612233//001,,--..**++,,&&''(()"##$$&& !!""4455612233//0011,,--.)**++,%&&''((""##$$& !!"4556622334/0011,,--.)**++,%&&''((""##$$& !!"556622334/0011,,--..**++,,&&''((""##$$& !!"56622334/0011,,--..**++,,&&''((""##$$&& !!""5612233//0011,,--.)**++,%&&''((""##$$& !!"612233//0011,,--.)**++,%&&''((""##$$& !!"622334/0011,,--..**++,,&&''((""##$$& !!"22334/0011,,--..**++,,&&''((""##$$&& !!"2233//001+,,--.)**++,%&&''((""##$&& !!"" 233//0011,,--.)**++,%&&''((""##$$& !!" 334/0011,,--..**++,,&&''((""##$$& !!" 34/0011,,--..**++,,&&''((""##$$& !!" 3//001+,,--.**++,,&&''(()"##$$&& !!"" //0011,,--.)**++,%&&''((""##$$& !!"  /0011,,--.)**++,,&&''((""##$$& !!" 0011,,--..**++,,&&''((""##$$& !!" 011,,--..**++,,&&''((""##$$&& !!"" 011,,--.)**++,%&&''((""##$$& !!" 11,,--.)**++,%&&''((""##$$& !!" 1,,--..**++,,&&''((""##$$& !!" ,,--..**++,,&&''((""##$$&& !!"" ,,--.)**++,%&&''((""##$$& !!"" ,--.)**++,%&&''((""##$$& !!" --..**++,,&&''((""##$$& !!" -..**++,,&&''((""##$$& !!" -.)**++,&&''(()"##$$&& !!"" .)**++,%&&''((""##$$& !!"  .**++,,&&''((""##$$& !!" **++,,&&''((""##$$& !!" *++,,&&''(()"##$$&& !!"" *++,%&&''((""##$$& !!" ++,%&&''((""##$$& !!" +,,&&''((""##$$& !!" ,&'("#$& !" ,%&&''((""##$$& !!" %&&''((""##$$& !!" &'("#$& !!" &''((""##$$& !!" &''()"##$$&& !!"" '("#$& !!"  '((""##$$& !!" ("#$& !!" ()"##$$&& !!"" (""##$$& !!"   "#$& !!"  "##$$& !!"  #$& !"  #$& !!"  #$$& !!" $& !!" <=899::77884455612234/0011,,--..**++,,&&''(()"##$$&& !!""=899::77884455612233//0011,,--.)**++,%&&''((""##$$& !!"=99::778894556122334/0011,,--.)**++,%&&''((""##$$& !!"99::778894556622334/0011,,--..**++,,&&''((""##$$& !!"9::;78894556622334/0011,,--..**++,,&&''((""##$$&& !!""9::77884455612233//0011,,--.)**++,%&&''((""##$$& !!"::77889455612233//0011,,--.)**++,%&&''((""##$$& !!":778894556622334/0011,,--..**++,,&&''((""##$$& !!"778894556622334/0011,,--..**++,,&&''((""##$$& !!"77884455612233//001+,,--.)**++,%&&''()"##$$&& !!""7889455612233//0011,,--.)**++,%&&''((""##$$& !!"8894556622334/0011,,--..**++,,&&''((""##$$& !!"894556622334/0011,,--..**++,,&&''((""##$$& !!"84455612233//001,,--..**++,,&&''(()"##$$&& !!""4455612233//0011,,--.)**++,%&&''((""##$$& !!"4556622334/0011,,--.)**++,%&&''((""##$$& !!"556622334/0011,,--..**++,,&&''((""##$$& !!"56622334/0011,,--..**++,,&&''((""##$$&& !!""5612233//0011,,--.)**++,%&&''((""##$$& !!"612233//0011,,--.)**++,%&&''((""##$$& !!"622334/0011,,--..**++,,&&''((""##$$& !!"22334/0011,,--..**++,,&&''((""##$$&& !!"2233//001+,,--.)**++,%&&''((""##$&& !!"" 233//0011,,--.)**++,%&&''((""##$$& !!" 334/0011,,--..**++,,&&''((""##$$& !!" 34/0011,,--..**++,,&&''((""##$$& !!" 3//001+,,--.**++,,&&''(()"##$$&& !!"" //0011,,--.)**++,%&&''((""##$$& !!"  /0011,,--.)**++,,&&''((""##$$& !!" 0011,,--..**++,,&&''((""##$$& !!" 011,,--..**++,,&&''((""##$$&& !!"" 011,,--.)**++,%&&''((""##$$& !!" 11,,--.)**++,%&&''((""##$$& !!" 1,,--..**++,,&&''((""##$$& !!" ,,--..**++,,&&''((""##$$&& !!"" ,,--.)**++,%&&''((""##$$& !!"" ,--.)**++,%&&''((""##$$& !!" --..**++,,&&''((""##$$& !!" -..**++,,&&''((""##$$& !!" -.)**++,&&''(()"##$$&& !!"" .)**++,%&&''((""##$$& !!"  .**++,,&&''((""##$$& !!" **++,,&&''((""##$$& !!" *++,,&&''(()"##$$&& !!"" *++,%&&''((""##$$& !!" ++,%&&''((""##$$& !!" +,,&&''((""##$$& !!" ,&'("#$& !" ,%&&''((""##$$& !!" %&&''((""##$$& !!" &'("#$& !!" &''((""##$$& !!" &''()"##$$&& !!"" '("#$& !!"  '((""##$$& !!" ("#$& !!" ()"##$$&& !!"" (""##$$& !!"   "#$& !!"  "##$$& !!"  #$& !"  #$& !!"  #$$& !!" $& !!" <;;::9988776655443321100//..--,,++**))((''&&%%$$##""!! ;;::99887766554433221100//..--,,++**))((''&&%%$$##""!! ;::99887766554433221100//..--,,++**))((''&&%%$$##""!! ::99887766554433221100//..--,,++**))((''&&%%$$##""!! :99887766554433221100//..--,,++**))((''&&%%$$##""!! :99887766554433221100//..--,,++**))((''&&%%$$##""!! 99887766554433221100//..--,,++**))((''&&%%$$##""!! 9887766554433221100//..--,,++**))((''&&%%$$##""!! 887766554433221100//..--,,++**))((''&&%%$$##""!! 887766554433221100//..--,,++**))((''&%%$$##""!! 87766554433221100//..--,,++**))((''&&%%$$##""!! 7766554433221100//..--,,++**))((''&&%%$$##""!! 766554433221100//..--,,++**))((''&&%%$$##""!! 766554433221100/..--,,++**))((''&&%%$$##""!! 66554433221100//..--,,++**))((''&&%%$$##""!! 6554433221100//..--,,++**))((''&&%%$$##""!! 554433221100//..--,,++**))((''&&%%$$##""!! 54433221100//..--,,++**))((''&&%%$$##""!! 54433221100//..--,,++**))((''&&%%$$##""!! 4433221100//..--,,++**))((''&&%%$$##""!! 433221100//..--,,++**))((''&&%%$$##""!! 33221100//..--,,++**))((''&&%%$$##""!! 33221100//..--,,++**))((''&&%%$$#""!! 3221100//..--,,++**))((''&&%%$$##""!! 221100//..--,,++**))((''&&%%$$##""!! 21100//..--,,++**))((''&&%%$$##""!! 21100//..--,++**))((''&&%%$$##""!! 1100//..--,,++**))((''&&%%$$##""!! 100//..--,,++**))((''&&%%$$##""!! 00//..--,,++**))((''&&%%$$##""!! 0//..--,,++**))((''&&%%$$##""!! 0//..--,,++**))((''&&%%$$##""!! //..--,,++**))((''&&%%$$##""!! /..--,,++**))((''&&%%$$##""!! ..--,,++**))((''&&%%$$##""!! ..--,,++**))((''&&%%$$##""!! .--,,++**))((''&&%%$$##""!! --,,++**))((''&&%%$$##""!! -,,++**))((''&&%%$$##""!!  -,,++**)((''&&%%$$##""!!  ,,++**))((''&&%%$$##""!!  ,++**))((''&&%%$$##""!!  ++**))((''&&%%$$##""!!  +**))((''&&%%$$##""!!  +**))((''&&%%$$##""!!  **))((''&&%%$$##""!!  *))((''&&%%$$##""!!  ))((''&&%%$$##""!!  ))((''&&%%$$##""!!  )((''&&%%$$##""!!  ((''&&%%$$##""!!  (''&&%%$$##""!!  (''&%%$$##""!!  ''&&%%$$##""!!  '&&%%$$##""!!  &&%%$$##""!!  &%%$$##""!!  &%%$$##""!!  %%$$##""!!  %$$##""!!  $$##""!!  $$##""!!  $##""!!  ##""!!                $ $  $ + + +                                 $ $  $ + + +                                 $ $  $ + + +                                                                                                                       7622334/0011,,--..**++,,&&''((""##$712233//001+,,--.)**++,%&&''((""##$223/01,-.)**++,%&&''((""##$$32334/0011,,--..**++,,&&''((""##$$&334/0011,,--..**++,,&&''((""##$$&33/01+,,--.)*++,,&&''(()"##$$&&43//0011,,--.)**++,%&&''((""##$$&44/0011,,--..**++,,&&''((""##$$&5/0011,,--..**++,,&&''((""##$$& /0011,,--..**++,,&&''((""##$$&& /0011,,--.)**++,%&&''((""##$$& 1011,,--.)**++,%&&''((""##$$& !11,-.*+,&'("#$& !!21,,--..**++,,&&''((""##$$&& !!"21,,--.)**++,%&&''((""##$$& !""2,,--.)**++,%&&''((""##$$& !!"-,--..**++,,&&''((""##$$& !!"--.*+,&'("#$& !!"--.)**++,%&''(()"##$$&& !!""--.)**++,%&&''((""##$$& !!"-..**++,,&&''((""##$$& !!"..**++,,&&''((""##$$& !!".**++,,&&''(()"##$$&& !!""'**++,%&&''((""##$$& !!"(*++,%&&''((""##$$& !!"(++,,&&''((""##$$& !!")+,,&&''((""##$$&& !!"")+,%&&''((""##$$& !!"),%&&''((""##$$& !!"+,&&''((""##$$& !!"+&&''((""##$$& !!"#&&''(("##$$&& !!""$&''((""##$$& !!"$''((""##$$& !!"&'((""##$$& !!"&(()"##$$&& !!""&((""##$$& !!"'(""##$$& !!"'""##$$& !!""##$$&& !!"""##$$& !!"##$$& !!" #$$& !!"  $$&& !!"  $$& !!"" !$& !!" !& !!" +$''+ %%%%7622334/0011,,--..**++,,&&''((""##$712233//001+,,--.)**++,%&&''((""##$223/01,-.)**++,%&&''((""##$$32334/0011,,--..**++,,&&''((""##$$&334/0011,,--..**++,,&&''((""##$$&33/01+,,--.)*++,,&&''(()"##$$&&43//0011,,--.)**++,%&&''((""##$$&44/0011,,--..**++,,&&''((""##$$&5/0011,,--..**++,,&&''((""##$$& /0011,,--..**++,,&&''((""##$$&& /0011,,--.)**++,%&&''((""##$$& 1011,,--.)**++,%&&''((""##$$& !11,-.*+,&'("#$& !!21,,--..**++,,&&''((""##$$&& !!"21,,--.)**++,%&&''((""##$$& !""2,,--.)**++,%&&''((""##$$& !!"-,--..**++,,&&''((""##$$& !!"--.*+,&'("#$& !!"--.)**++,%&''(()"##$$&& !!""--.)**++,%&&''((""##$$& !!"-..**++,,&&''((""##$$& !!"..**++,,&&''((""##$$& !!".**++,,&&''(()"##$$&& !!""'**++,%&&''((""##$$& !!"(*++,%&&''((""##$$& !!"(++,,&&''((""##$$& !!")+,,&&''((""##$$&& !!"")+,%&&''((""##$$& !!"),%&&''((""##$$& !!"+,&&''((""##$$& !!"+&&''((""##$$& !!"#&&''(("##$$&& !!""$&''((""##$$& !!"$''((""##$$& !!"&'((""##$$& !!"&(()"##$$&& !!""&((""##$$& !!"'(""##$$& !!"'""##$$& !!""##$$&& !!"""##$$& !!"##$$& !!" #$$& !!"  $$&& !!"  $$& !!"" !$& !!" !& !!" +$''+ %%%%7622334/0011,,--..**++,,&&''((""##$712233//001+,,--.)**++,%&&''((""##$223/01,-.)**++,%&&''((""##$$32334/0011,,--..**++,,&&''((""##$$&334/0011,,--..**++,,&&''((""##$$&33/01+,,--.)*++,,&&''(()"##$$&&43//0011,,--.)**++,%&&''((""##$$&44/0011,,--..**++,,&&''((""##$$&5/0011,,--..**++,,&&''((""##$$& /0011,,--..**++,,&&''((""##$$&& /0011,,--.)**++,%&&''((""##$$& 1011,,--.)**++,%&&''((""##$$& !11,-.*+,&'("#$& !!21,,--..**++,,&&''((""##$$&& !!"21,,--.)**++,%&&''((""##$$& !""2,,--.)**++,%&&''((""##$$& !!"-,--..**++,,&&''((""##$$& !!"--.*+,&'("#$& !!"--.)**++,%&''(()"##$$&& !!""--.)**++,%&&''((""##$$& !!"-..**++,,&&''((""##$$& !!"..**++,,&&''((""##$$& !!".**++,,&&''(()"##$$&& !!""'**++,%&&''((""##$$& !!"(*++,%&&''((""##$$& !!"(++,,&&''((""##$$& !!")+,,&&''((""##$$&& !!"")+,%&&''((""##$$& !!"),%&&''((""##$$& !!"+,&&''((""##$$& !!"+&&''((""##$$& !!"#&&''(("##$$&& !!""$&''((""##$$& !!"$''((""##$$& !!"&'((""##$$& !!"&(()"##$$&& !!""&((""##$$& !!"'(""##$$& !!"'""##$$& !!""##$$&& !!"""##$$& !!"##$$& !!" #$$& !!"  $$&& !!"  $$& !!"" !$& !!" !& !!" +$''+ %%%%V.433221100//..--,,++**))((''&&%%$$#V.433221100//..--,,++**))((''&&%%$$#‚V.33221100//..--,,++**))((''&&%%$$##‚V-3221100//..--,,++**))((''&&%%$$##"ƒV-221100//..--,,++**))((''&&%%$$##""ƒV-221100//..--,,+**))((''&&%%$$##""!ƒV,21100//..--,,++**))((''&&%%$$##""!ƒV,1100//..--,,++**))((''&&%%$$##""!!„W+100//..--,,++**))((''&&%%$$##""!! „W+00//..--,,++**))((''&&%%$$##""!! „W+00//..--,,++**))((''&&%%$$##""!! „W*0//..--,,++**))((''&&%%$$##""!! …W*//..--,,++**))((''&&%%$$##""!! …W)/..--,,++**))((''&&%%$$##""!! …W)/..--,,++**))((''&&%%$$##""!! †W)..--,,++**))((''&&%%$$##""!! ‡W(.--,,++**))((''&&%%$$##""!! ‡W(--,,++**))((''&&%%$$##""!! ‡W(--,,++**))(''&&%%$$##""!! ‡W(-,,++**))((''&&%%$$##""!! ‡X(,,++**))((''&&%%$$##""!! ˆX',++**))((''&&%%$$##""!! ˆX'++**))((''&&%%$$##""!! ˆX'++**))((''&&%%$$##""!! ‰X&+**))((''&&%%$$##""!! ‰X&**))((''&&%%$$##""!! ‰X%*))((''&&%%$$##""!! ŠX%*))((''&&%%$$##""!! ŠX%))((''&&%%$$##""!! ŠY$)((''&&%%$$##""!! ŠY$((''&&%%$$##""!! ŠY$((''&&%$$##""!! ‹Y#(''&&%%$$##""!! ŒY#''&&%%$$##""!! ŒY"'&&%%$$##""!! ŒY"&&%%$$##""!! ŒY"&&%%$$##""!! ŒZ!&%%$$##""!! ŒZ!%%$$##""!! Z!%$$##""!! ŽZ!%$$##""!! ŽZ!$$##""!! ŽZ $##""!! ŽZ ##""!! ŽZ ##"!! Ž[#""!! [""!! [       [%[%[%[%D7߇֤j)0wؑWeݱۺ ~UCݠ$&& !!" $& !!"" & !!"  !!"  !"  !!""  !!"   !"  !!" !" !" !" " "              ! " " # % % ' &  ( ) ) )  * + - , - / //01tӮϻĨ٩ϻĨ٩ϻĨ٩ϻ$&& !!" $& !!"" & !!"  !!"  !"  !!""  !!"   !"  !!" !" !" !" " "              ! " " # % % ' &  ( ) ) )  * + - , - / //01tӮϻĨ٩ϻĨ٩ϻĨ٩ϻ$&& !!" $& !!"" & !!"  !!"  !"  !!""  !!"   !"  !!" !" !" !" " "              ! " " # % % ' &  ( ) ) )  * + - , - / //01tӮϻĨ٩ϻĨ٩ϻĨ٩ϻ#""!!  #"!!  ""!!  "!!  !!  !  !                                                                                                                       !Żzwwvuutssrqmeddꥧ񝜚颡颡읜蟞螝睜盚皘癘昖ꥧ񝜚颡颡읜蟞螝睜盚皘癘昖ꥧ񝜚颡颡읜蟞螝睜盚皘癘昖cbbaa`__^TSSRRQQPOON@餣  론4顠_蠟 蟞(蝜R眛{盚 皙F瘗n旖 ߀򻺺껺滺𰯯⻺찯󩧦޻谯逸ڻ䰯멧ֻయ穧һܰ꾿㩧ذߩ԰𺹷۩̸а󸶴ة߀򻺺껺滺𰯯⻺찯󩧦޻谯逸ڻ䰯멧ֻయ穧һܰ꾿㩧ذߩ԰𺹷۩̸а󸶴ة߀򻺺껺滺𰯯⻺찯󩧦޻谯逸ڻ䰯멧ֻయ穧һܰ꾿㩧ذߩ԰𺹷۩̸а󸶴ة ާDjێ.4~V!mٶA \ؤj +MדU=ւ.?sոjc)ԧTSӖE҇=6wjѶ%(hЩSZϙ~;Lʭh>#{ɕ1Pm#}_7ǪQd rDHƑ}K 7ĉo٩ϻĨ٩ϻĨ٩٩٩~~}~}~}|{|~}|{zy~}{zyx~}|{|{zyx~}|{zyxyxw~}{zyxwvwv~}|{|{zyxvutu~}|{zyxyxwvusr|~}{zyxwvwvusrq~}|{|{zyxvutusrqp~}|{zyxyxwvusrrqpn~}{zyxwvwvusrqpqon~}|{|{zyxvutusrqpnonm~}|{zyxyxwvusrrqpnmlmk~}{zyxwvwvusrqpqonmjkj~}|{|{zyxvutusrqpnonmkjki~}|{zyxyxwvusrrqpnmlmkjhih~}{zyxwvwvusrqpqonmjkjhgfg~}|{|{zyxvutusrqpnonmkjkihfde~}|{zyxyxwvusrrqpnmlmkjhihgecd~}{zyxwvwvusrqpqonmjkjhgfgecdc~}|{|{zyxvutusrqpnonmkjkihfdecbca~}|{zyxyxwvusrrqpnmlmkjhihgecdc`a`~}{zyxwvwvusrqpqonmjkjhgfgecdca`a_~}|{|{zyxvutusrqpnonmkjkihfdecbca`^_]~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][~}{zyxwvwvusrqpqonmjkjhgfgecdca`a_]^[Z~}|{|{zyxvutrsrqpnonmkjkihfdecbca`^_][\[Y~}|{zyxyxwvusrrqpnmlmkjhihgecdc`a`^\][Z[YW~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWX~}|{|{zyxvutusrqpnonmkjkihfdecbca`^_][\[YZXUV~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWU~}{zyxwvwvusrqpqonmjkjhgfgecdca`a_]^[Z[YWXVTUS~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQ~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQO~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQ~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMN~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNL~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJ~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKL~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHI~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIG٩ϻĨ٩ϻĨ٩٩٩~~}~}~}|{|~}|{zy~}{zyx~}|{|{zyx~}|{zyxyxw~}{zyxwvwv~}|{|{zyxvutu~}|{zyxyxwvusr|~}{zyxwvwvusrq~}|{|{zyxvutusrqp~}|{zyxyxwvusrrqpn~}{zyxwvwvusrqpqon~}|{|{zyxvutusrqpnonm~}|{zyxyxwvusrrqpnmlmk~}{zyxwvwvusrqpqonmjkj~}|{|{zyxvutusrqpnonmkjki~}|{zyxyxwvusrrqpnmlmkjhih~}{zyxwvwvusrqpqonmjkjhgfg~}|{|{zyxvutusrqpnonmkjkihfde~}|{zyxyxwvusrrqpnmlmkjhihgecd~}{zyxwvwvusrqpqonmjkjhgfgecdc~}|{|{zyxvutusrqpnonmkjkihfdecbca~}|{zyxyxwvusrrqpnmlmkjhihgecdc`a`~}{zyxwvwvusrqpqonmjkjhgfgecdca`a_~}|{|{zyxvutusrqpnonmkjkihfdecbca`^_]~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][~}{zyxwvwvusrqpqonmjkjhgfgecdca`a_]^[Z~}|{|{zyxvutrsrqpnonmkjkihfdecbca`^_][\[Y~}|{zyxyxwvusrrqpnmlmkjhihgecdc`a`^\][Z[YW~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWX~}|{|{zyxvutusrqpnonmkjkihfdecbca`^_][\[YZXUV~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWU~}{zyxwvwvusrqpqonmjkjhgfgecdca`a_]^[Z[YWXVTUS~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQ~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQO~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQ~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMN~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNL~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJ~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKL~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHI~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIG٩ϻĨ٩ϻĨ٩٩٩~~}~}~}|{|~}|{zy~}{zyx~}|{|{zyx~}|{zyxyxw~}{zyxwvwv~}|{|{zyxvutu~}|{zyxyxwvusr|~}{zyxwvwvusrq~}|{|{zyxvutusrqp~}|{zyxyxwvusrrqpn~}{zyxwvwvusrqpqon~}|{|{zyxvutusrqpnonm~}|{zyxyxwvusrrqpnmlmk~}{zyxwvwvusrqpqonmjkj~}|{|{zyxvutusrqpnonmkjki~}|{zyxyxwvusrrqpnmlmkjhih~}{zyxwvwvusrqpqonmjkjhgfg~}|{|{zyxvutusrqpnonmkjkihfde~}|{zyxyxwvusrrqpnmlmkjhihgecd~}{zyxwvwvusrqpqonmjkjhgfgecdc~}|{|{zyxvutusrqpnonmkjkihfdecbca~}|{zyxyxwvusrrqpnmlmkjhihgecdc`a`~}{zyxwvwvusrqpqonmjkjhgfgecdca`a_~}|{|{zyxvutusrqpnonmkjkihfdecbca`^_]~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][~}{zyxwvwvusrqpqonmjkjhgfgecdca`a_]^[Z~}|{|{zyxvutrsrqpnonmkjkihfdecbca`^_][\[Y~}|{zyxyxwvusrrqpnmlmkjhihgecdc`a`^\][Z[YW~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWX~}|{|{zyxvutusrqpnonmkjkihfdecbca`^_][\[YZXUV~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWU~}{zyxwvwvusrqpqonmjkjhgfgecdca`a_]^[Z[YWXVTUS~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQ~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQO~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQ~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMN~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNL~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJ~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKL~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHI~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIG~~}|~}|{~}|{z~}||{zy~}|{zyxw~}|{zyxwv~}||{zyxwvu~}|{zyxwwvut~}|{zyxwvutsr~}||{zyxwvutsrq~}|{zyxwwvutsrqp~}|{zyxwvutsrrqpo~}||{zyxwvutsrqponm~}|{zyxwwvutsrqponml~}|{zyxwvutsrrqponmlk~}||{zyxwvutsrqponmllkj~}|{zyxwwvutsrqponmlkjih~}|{zyxwvutsrrqponmlkjihg~}||{zyxwvutsrqponmllkjihgf~}|{zyxwwvutsrqponmlkjihggfe~}|{zyxwvutsrrqponmlkjihgfedc~}||{zyxwvutsrqponmllkjihgfedcb~}|{zyxwwvutsrqponmlkjihggfedcba~}|{zyxwvutsrrqponmlkjihgfedcbba`~}||{zyxwvutsrqponmllkjihgfedcba`_^~}|{zyxwwvutsrqponmlkjihggfedcba`_^]~}|{zyxwvutsrrqponmlkjihgfedcbba`_^]\~}||{zyxwvutsrqponmllkjihgfedcba`_^]\\[~}|{zyxwwvutsrqponmlkjihggfedcba`_^]\[ZY~}|{zyxwvutsrrqponmlkjihgfedcbba`_^]\[ZYX~}||{zyxwvutsrqponmllkjihgfedcba`_^]\\[ZYXW~}|{zyxwwvutsrqponmlkjihggfedcba`_^]\[ZYXWWV~}|{zyxwvutsrrqponmlkjihgfedcbba`_^]\[ZYXWVUT~}||{zyxwvutsrqponmllkjihgfedcba`_^]\\[ZYXWVUTS~}|{zyxwwvutsrqponmlkjihggfedcba`_^]\[ZYXWWVUTSR~}|{zyxwvutsrrqponmlkjihgfedcbba`_^]\[ZYXWVUTSRRQ~}||{zyxwvutsrqponmllkjihgfedcba`_^]\\[ZYXWVUTSRQPO~}|{zyxwwvutsrqponmlkjihggfedcba`_^]\[ZYXWWVUTSRQPON~}|{zyxwvutsrrqponmlkjihgfedcbba`_^]\[ZYXWVUTSRRQPONM~}||{zyxwvutsrqponmllkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLL~}|{zyxwwvutsrqponmlkjihggfedcba`_^]\[ZYXWWVUTSRQPONMLKJ~}|{zyxwvutsrrqponmlkjihgfedcbba`_^]\[ZYXWVUTSRRQPONMLKJI~}||{zyxwvutsrqponmllkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLLKJIH斕敔~}瑐~}}哒~|{}吏~}|{|{y掍~}|{zyxyf䎍~}{zyxwvu䍌~}|{|{zyxvuuጋ~}|{zyxyxwvus㊉~}{zyxwvwvusrq㊉~}|{|{zyxvutusrqq㉈~}|{zyxyxwvusrrqpmↅ~}{zyxwvwvusrqpqonq⅄~}|{|{zyxvutusrqpnonmi⅄~}|{zyxyxwvusrrqpnmlmkl߂~}{zyxwvwvusrqpqonljkjh]၀~}|{|{zyxvutusrqpnonmkjkihd~}|{zyxyxwvusrrqpnmlmkjhihgcށ~}{zyxwvwvusrqpqonljkjhgfgedf}|{|{zyxvutusrqpnonmkjkihfdecbh|{zyxyxwvusrrqpnmlmkjhihgecdc`c{zyxwvwvusrqpqonmjkjhgfgecdca`a {zyxvutusrqpnonmkjkihfdecbca`^_` xyxwvusrrqpnmlmkjhihgecdc`a`^\]] wvwvusrqpqonljkjhgfgecdca`a_]][Y vutusrqpnonmkjkihfdecbca`^_][\[Y` vusrrqpnmlmkjhihgecdc`a`^\][Z[YWY usrqpqonmjkjhgfgecdca`a_]][Z[YWXU srqpnonmkjkihfdecbca`^_][\[YZXUVTM rqpnmlmkjhihgecdc`a`^\][Z[YWXVWUSS pqonmjkjhgfgecdca`a_]][Z[YWXVTUSQR nonmkjkihfdecbca`^_][\[YZXUVTRSQRRf mlmkjhihgecdc`a`^\][Z[YWXVWUSTQOPML mjkjhgfgecdca`a_]][Z[YWXVTUSQRPQNOM kjkihfdecbca`^_][\[YZXUVTRSQRPMNLMK jhihgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHM hgfgecdca`a_]][Z[YWXVTUSQRPQNOLJKHII hfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHI gecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFIecdca`a_]][Z[YWXVTUSQRPQNOLJKHIGHEFDDcbca`^_][\[YZXUVTRSQRPMNLMKLIJHHECDABc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@a`a_]^[Z[YWXVTUSQRPQNOLJKHIGHEFDEBC@AB`^_][\[YZXUVTRSQRPMNLMKLIJHHECDABC@A>>^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@=>?=3]^[Z[YWXVTUSQRPQNOLJKHIGHEFDEBC@A>?;<8=[\[YZXUVTRSQRPMNLMKLIJHHECDABC@A>?<=9:6Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@=>?<=9:76[YWXVTUSQRPQNOLJKHIGHEFDEBC@A>?;<89:7843ZXUVTRSQRPMNLMKLIJHHECDABC@A>?<=9:788451XVWUSTQOPMNLMKHIGHEFDEBB?@=>?<=9:7895623VTUSQRPQNOLJKHIGHEFDEBC@A>?;<89:7845623/.TRSQRPMNLMKLIJHHECDABC@A>?<=9:78845123/03STQOPMNLMKHIGHEFDEBB?@=>?<=9:78956233/01.QRPQNOLJKHIGHEFDEBC@A>?;<89:7845623/01,--$RPMNLMKLIJHHECDABC@A>?<=9:78845123/01,-.*(PMNLMKHIGHEFDEBB?@=>?<=9:78956233/01,-.*+)NOLJKHIGHEFDEBC@A>?;<89:7845623/01,--)*+,&@LMKLIJHHECDABC@A>?<=9:78845123/01,-.*+,&''$MKHIGHEFDEBB?@=>?<=9:78956233/01,-.*+,&'("KHIGHEFDEBC@A>?;<89:7845623/01,--)*+,&'("#&IJHHECDABC@A>?<=9:78845123/01,-.*+,&''("#$GHEFDEBB?@=>?<=9:78956233/01,-.*+,&'("#$&HEFDEBC@A>?;<89:7845623/01,--)*+,&'("#$& !$斕敔~}瑐~}}哒~|{}吏~}|{|{y掍~}|{zyxyf䎍~}{zyxwvu䍌~}|{|{zyxvuuጋ~}|{zyxyxwvus㊉~}{zyxwvwvusrq㊉~}|{|{zyxvutusrqq㉈~}|{zyxyxwvusrrqpmↅ~}{zyxwvwvusrqpqonq⅄~}|{|{zyxvutusrqpnonmi⅄~}|{zyxyxwvusrrqpnmlmkl߂~}{zyxwvwvusrqpqonljkjh]၀~}|{|{zyxvutusrqpnonmkjkihd~}|{zyxyxwvusrrqpnmlmkjhihgcށ~}{zyxwvwvusrqpqonljkjhgfgedf}|{|{zyxvutusrqpnonmkjkihfdecbh|{zyxyxwvusrrqpnmlmkjhihgecdc`c{zyxwvwvusrqpqonmjkjhgfgecdca`a {zyxvutusrqpnonmkjkihfdecbca`^_` xyxwvusrrqpnmlmkjhihgecdc`a`^\]] wvwvusrqpqonljkjhgfgecdca`a_]][Y vutusrqpnonmkjkihfdecbca`^_][\[Y` vusrrqpnmlmkjhihgecdc`a`^\][Z[YWY usrqpqonmjkjhgfgecdca`a_]][Z[YWXU srqpnonmkjkihfdecbca`^_][\[YZXUVTM rqpnmlmkjhihgecdc`a`^\][Z[YWXVWUSS pqonmjkjhgfgecdca`a_]][Z[YWXVTUSQR nonmkjkihfdecbca`^_][\[YZXUVTRSQRRf mlmkjhihgecdc`a`^\][Z[YWXVWUSTQOPML mjkjhgfgecdca`a_]][Z[YWXVTUSQRPQNOM kjkihfdecbca`^_][\[YZXUVTRSQRPMNLMK jhihgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHM hgfgecdca`a_]][Z[YWXVTUSQRPQNOLJKHII hfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHI gecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFIecdca`a_]][Z[YWXVTUSQRPQNOLJKHIGHEFDDcbca`^_][\[YZXUVTRSQRPMNLMKLIJHHECDABc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@a`a_]^[Z[YWXVTUSQRPQNOLJKHIGHEFDEBC@AB`^_][\[YZXUVTRSQRPMNLMKLIJHHECDABC@A>>^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@=>?=3]^[Z[YWXVTUSQRPQNOLJKHIGHEFDEBC@A>?;<8=[\[YZXUVTRSQRPMNLMKLIJHHECDABC@A>?<=9:6Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@=>?<=9:76[YWXVTUSQRPQNOLJKHIGHEFDEBC@A>?;<89:7843ZXUVTRSQRPMNLMKLIJHHECDABC@A>?<=9:788451XVWUSTQOPMNLMKHIGHEFDEBB?@=>?<=9:7895623VTUSQRPQNOLJKHIGHEFDEBC@A>?;<89:7845623/.TRSQRPMNLMKLIJHHECDABC@A>?<=9:78845123/03STQOPMNLMKHIGHEFDEBB?@=>?<=9:78956233/01.QRPQNOLJKHIGHEFDEBC@A>?;<89:7845623/01,--$RPMNLMKLIJHHECDABC@A>?<=9:78845123/01,-.*(PMNLMKHIGHEFDEBB?@=>?<=9:78956233/01,-.*+)NOLJKHIGHEFDEBC@A>?;<89:7845623/01,--)*+,&@LMKLIJHHECDABC@A>?<=9:78845123/01,-.*+,&''$MKHIGHEFDEBB?@=>?<=9:78956233/01,-.*+,&'("KHIGHEFDEBC@A>?;<89:7845623/01,--)*+,&'("#&IJHHECDABC@A>?<=9:78845123/01,-.*+,&''("#$GHEFDEBB?@=>?<=9:78956233/01,-.*+,&'("#$&HEFDEBC@A>?;<89:7845623/01,--)*+,&'("#$& !$斕敔~}瑐~}}哒~|{}吏~}|{|{y掍~}|{zyxyf䎍~}{zyxwvu䍌~}|{|{zyxvuuጋ~}|{zyxyxwvus㊉~}{zyxwvwvusrq㊉~}|{|{zyxvutusrqq㉈~}|{zyxyxwvusrrqpmↅ~}{zyxwvwvusrqpqonq⅄~}|{|{zyxvutusrqpnonmi⅄~}|{zyxyxwvusrrqpnmlmkl߂~}{zyxwvwvusrqpqonljkjh]၀~}|{|{zyxvutusrqpnonmkjkihd~}|{zyxyxwvusrrqpnmlmkjhihgcށ~}{zyxwvwvusrqpqonljkjhgfgedf}|{|{zyxvutusrqpnonmkjkihfdecbh|{zyxyxwvusrrqpnmlmkjhihgecdc`c{zyxwvwvusrqpqonmjkjhgfgecdca`a {zyxvutusrqpnonmkjkihfdecbca`^_` xyxwvusrrqpnmlmkjhihgecdc`a`^\]] wvwvusrqpqonljkjhgfgecdca`a_]][Y vutusrqpnonmkjkihfdecbca`^_][\[Y` vusrrqpnmlmkjhihgecdc`a`^\][Z[YWY usrqpqonmjkjhgfgecdca`a_]][Z[YWXU srqpnonmkjkihfdecbca`^_][\[YZXUVTM rqpnmlmkjhihgecdc`a`^\][Z[YWXVWUSS pqonmjkjhgfgecdca`a_]][Z[YWXVTUSQR nonmkjkihfdecbca`^_][\[YZXUVTRSQRRf mlmkjhihgecdc`a`^\][Z[YWXVWUSTQOPML mjkjhgfgecdca`a_]][Z[YWXVTUSQRPQNOM kjkihfdecbca`^_][\[YZXUVTRSQRPMNLMK jhihgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHM hgfgecdca`a_]][Z[YWXVTUSQRPQNOLJKHII hfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHI gecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFIecdca`a_]][Z[YWXVTUSQRPQNOLJKHIGHEFDDcbca`^_][\[YZXUVTRSQRPMNLMKLIJHHECDABc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@a`a_]^[Z[YWXVTUSQRPQNOLJKHIGHEFDEBC@AB`^_][\[YZXUVTRSQRPMNLMKLIJHHECDABC@A>>^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@=>?=3]^[Z[YWXVTUSQRPQNOLJKHIGHEFDEBC@A>?;<8=[\[YZXUVTRSQRPMNLMKLIJHHECDABC@A>?<=9:6Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@=>?<=9:76[YWXVTUSQRPQNOLJKHIGHEFDEBC@A>?;<89:7843ZXUVTRSQRPMNLMKLIJHHECDABC@A>?<=9:788451XVWUSTQOPMNLMKHIGHEFDEBB?@=>?<=9:7895623VTUSQRPQNOLJKHIGHEFDEBC@A>?;<89:7845623/.TRSQRPMNLMKLIJHHECDABC@A>?<=9:78845123/03STQOPMNLMKHIGHEFDEBB?@=>?<=9:78956233/01.QRPQNOLJKHIGHEFDEBC@A>?;<89:7845623/01,--$RPMNLMKLIJHHECDABC@A>?<=9:78845123/01,-.*(PMNLMKHIGHEFDEBB?@=>?<=9:78956233/01,-.*+)NOLJKHIGHEFDEBC@A>?;<89:7845623/01,--)*+,&@LMKLIJHHECDABC@A>?<=9:78845123/01,-.*+,&''$MKHIGHEFDEBB?@=>?<=9:78956233/01,-.*+,&'("KHIGHEFDEBC@A>?;<89:7845623/01,--)*+,&'("#&IJHHECDABC@A>?<=9:78845123/01,-.*+,&''("#$GHEFDEBB?@=>?<=9:78956233/01,-.*+,&'("#$&HEFDEBC@A>?;<89:7845623/01,--)*+,&'("#$& !$斕:敔`哒~| 咑~}}|/ 呐~}|{zT䐏~}|{zyt䎍~}||{zyxw% 䍌~}|{zyxwwvH~}|{zyxwvutj㋊~}||{zyxwvutsr㉈~}|{zyxwwvutsrq= ㈇~}|{zyxwvutsrrqp`⇆~}||{zyxwvutsrqponm ↅ~}|{zyxwwvutsrqponml3 ℃~}|{zyxwvutsrrqponmlkS ރ~}||{zyxwvutsrqponmmlkji  ႁ~}|{zyxwwvutsrqponmlkjihg) ၀~}|{zyxwvutsrrqponmlkjihgfH  ~}||{zyxwvutsrqponmmlkjihgfea ~}|{zyxwwvutsrqponmlkjihggfedc  }|{zyxwvutsrrqponmlkjihgfedcbb> |{zyxwvutsrqponmllkjihgfedcba`Y zyxwwvutsrqponmlkjihggfedcba`_^ yxwvutsrrqponmlkjihgfedcbba`_^]4 xwvutsrqponmmlkjihgfedcba`_^]]\P  wvutsrqponmlkjihggfedcba`_^]\[ZY utsrrqponmlkjihgfedcbba`_^]\[ZYX+ tsrqponmllkjihgfedcba`_^]]\[ZYXWE srqponmlkjihggfedcba`_^]\[ZYXWWVU  rqponmlkjihgfedcbba`_^]\[ZYXWVUTS" ponmllkjihgfedcba`_^]]\[ZYXWVUTSR;onmlkjihggfedcba`_^]\[ZYXWWVUTSRQN nmlkjihgfedcbba`_^]\[ZYXWVUTSRRQPOlkjihgfedcba`_^]]\[ZYXWVUTSRQPONM2kjihggfedcba`_^]\[ZYXWWVUTSRQPONMLGjihgfedcbba`_^]\[ZYXWVUTSRRQPONMLKJ ihgfedcba`_^]]\[ZYXWVUTSRQPONMMLKJI*gfedcba`_^]\[ZYXWWVUTSRQPONMLKJIHG?fedcbba`_^]\[ZYXWVUTSRRQPONMLKJIHGFE edcba`_^]]\[ZYXWVUTSRQPONMMLKJIHGFED"dcba`_^]\[ZYXWWVUTSRQPONMLKJIHGGFEDC6ba`_^]\[ZYXWVUTSRRQPONMLKJIHGFEDCBBAa`_^]\\[ZYXWVUTSRQPONMMLKJIHGFEDCBA@? `_^]\[ZYXWWVUTSRQPONMLKJIHGGFEDCBA@?>-_^]\[ZYXWVUTSRRQPONMLKJIHGFEDCBBA@?>=;]\\[ZYXWVUTSRQPONMMLKJIHGFEDCBA@?>==<; \[ZYXWWVUTSRQPONMLKJIHGGFEDCBA@?>=<;:9&[ZYXWVUTSRRQPONMLKJIHGFEDCBBA@?>=<;:984ZYXWVUTSRQPONMMLKJIHGFEDCBA@?>==<;:9876XWWVUTSRQPONMLKJIHGGFEDCBA@?>=<;:987765 WVUTSRRQPONMLKJIHGFEDCBBA@?>=<;:9876543-VUTSRQPONMMLKJIHGFEDCBA@?>==<;:987654321 UTSRQPONMLKJIHGGFEDCBA@?>=<;:98776543210 SRRQPONMLKJIHGFEDCBBA@?>=<;:98765432210/'RQPONMMLKJIHGFEDCBA@?>==<;:9876543210/.--QPONMLKJIHGGFEDCBA@?>=<;:98776543210/.-,+PONMLKJIHGFEDCBBA@?>=<;:98765432210/.-,+* NMMLKJIHGFEDCBA@?>==<;:9876543210/.--,+*)(MLKJIHGGFEDCBA@?>=<;:98776543210/.-,+*)(''LKJIHGFEDCBBA@?>=<;:98765432210/.-,+*)('&% KJIHGFEDCBA@?>==<;:9876543210/.--,+*)('&%$"IHGGFEDCBA@?>=<;:98776543210/.-,+*)(''&%$#" HGFEDCBBA@?>=<;:98765432210/.-,+*)('&%$#""! GFEDCBA@?>==<;:9876543210/.--,+*)('&%$#"!  ̰өdz~DZ~}ϩ~}ȯ~}|{|Ȩ~}|{zyɬ~}{zyx ʥ~}}{}{{zx̰өdz~DZ~}ϩ~}ȯ~}|{|Ȩ~}|{zyɬ~}{zyx ʥ~}}{}{{zx̰өdz~DZ~}ϩ~}ȯ~}|{|Ȩ~}|{zyɬ~}{zyx ʥ~}}{}{{zx4y2+8`hR~'~}|~}|{2~}|{zJ~}||{zy "byzyxxwvuutsrrqpoonmmlkjjihggfeddccbba`__^]\\[ZYYXW~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHH~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEF~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIGHEFD}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHHECDA|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIGHEFDEBC@{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHHECDABC@Axyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@=>wvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIGHEFDEBC@A>?;uutrsprpnklnlijkhecdebca__`^[[YZZXTUVRTQRNOQMMJLGHJJFAB>@@AC>>:;~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHH~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEF~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIGHEFD}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHHECDA|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIGHEFDEBC@{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHHECDABC@Axyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@=>wvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIGHEFDEBC@A>?;uutrsprpnklnlijkhecdebca__`^[[YZZXTUVRTQRNOQMMJLGHJJFAB>@@AC>>:;~}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHH~}|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEF~}{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIGHEFD}|{|{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHHECDA|{zyxyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB{zyxwvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIGHEFDEBC@{zyxvutrsrqpnmnmkjkihfdecbca`^_][\[YZXUVTRSQRPMNLMKLIJHHECDABC@Axyxwvusrrqpnmlmkjhghgecdc`a`^\][Z[YWXVWUSTQOPMNLMKHIGHEFDEBB?@=>wvwvusrqpqonmjkjhgfgecbca`a_]^[Z[YWXVTUSQRPQNOMJKHIGHEFDEBC@A>?;uutrsprpnklnlijkhecdebca__`^[[YZZXTUVRTQRNOQMMJLGHJJFAB>@@AC>>:;P~}|{zyxwwvutsrqponmlkjihggfedcba`_^]\[ZYXWWVUTSRQPONMLKJIHGG~}|{zyxwvutsrrqponmlkjihgfedcbba`_^]\[ZYXWVUTSRRQPONMLKJIHGFE~}||{zyxwvutsrqponmllkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLLKJIHGFED~}|{zyxwwvutsrqponmlkjihggfedcba`_^]\[ZYXWWVUTSRQPONMLKJIHGGFEDC}|{zyxwvutsrrqponmlkjihgfedcbba`_^]\[ZYXWVUTSRRQPONMLKJIHGFEDCBB|{zyxwvutsrqponmllkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLLKJIHGFEDCBA@zyxwwvutsrqponmlkjihggfedcba`_^]\[ZYXWWVUTSRQPONMLKJIHGGFEDCBA@?yxwvutsrrqponmlkjihgfedcbba`_^]\[ZYXWVUTSRRQPONMLKJIHGFEDCBBA@?>xwvutsrqponmllkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLLKJIHGFEDCBA@?>==WWVUTTSRQQPONNMLLKJIIHGFFEDCCBAA@@?>>=<;;:988766544332100/.--,+ECDABC@A>?<=9:78845123/01,-.*+,&''("#$ !"$DEBB?@=>?<=9:78956233/01,-.*+,&'("#$& !"EBC@A>?;<89:7845623/01,--)*+,&'("#$& !"#BC@A>?<=9:78845123/01,-.*+,&''("#$ !"?@=>?<=9:78956233/01,-.*+,&'("#$& !A>?;<89:7845623/01,--)*+,&'("#$& !">?<=9:78845123/01,-.*+,&''("#$ !"?<=9:78956233/01,-.*+,&'("#$& !<89:7845623/01,--)*+,&'("#$& !";=89934/00235-.0()+##$&'' !!#$AECDABC@A>?<=9:78845123/01,-.*+,&''("#$ !"$DEBB?@=>?<=9:78956233/01,-.*+,&'("#$& !"EBC@A>?;<89:7845623/01,--)*+,&'("#$& !"#BC@A>?<=9:78845123/01,-.*+,&''("#$ !"?@=>?<=9:78956233/01,-.*+,&'("#$& !A>?;<89:7845623/01,--)*+,&'("#$& !">?<=9:78845123/01,-.*+,&''("#$ !"?<=9:78956233/01,-.*+,&'("#$& !<89:7845623/01,--)*+,&'("#$& !";=89934/00235-.0()+##$&'' !!#$AECDABC@A>?<=9:78845123/01,-.*+,&''("#$ !"$DEBB?@=>?<=9:78956233/01,-.*+,&'("#$& !"EBC@A>?;<89:7845623/01,--)*+,&'("#$& !"#BC@A>?<=9:78845123/01,-.*+,&''("#$ !"?@=>?<=9:78956233/01,-.*+,&'("#$& !A>?;<89:7845623/01,--)*+,&'("#$& !">?<=9:78845123/01,-.*+,&''("#$ !"?<=9:78956233/01,-.*+,&'("#$& !<89:7845623/01,--)*+,&'("#$& !";=89934/00235-.0()+##$&'' !!#$AFEDCBA@?>=<;:98776543210/.-,+*)(''&%$#"! DCBBA@?>=<;:98765432210/.-,+*)('&%$#""! CBA@?>==<;:9876543210/.--,+*)('&%$#"! BA@?>=<;:98776543210/.-,+*)(''&%$#"! A@?>=<;:98765432210/.-,+*)('&%$#""! ?>==<;:9876543210/.--,+*)('&%$#"!  >=<;:98776543210/.-,+*)(''&%$#"! =<;:98765432210/.-,+*)('&%$#""!  <;:9876543210/.--,+*)('&%$#"! +*)(('&%%$#""! AZh-Z -drumstick-2.5.1/library/widgets/PaxHeaders.27918/sonivoxsettingsdialog.h0000644000000000000000000000013214200302440023211 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/sonivoxsettingsdialog.h0000644000175000001440000000400314200302440023767 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SonivoxSettingsDialog_H #define SonivoxSettingsDialog_H #include #include #include /** * @file sonivoxsettingsdialog.h * Definition of the Sonivox Synth configuration dialog */ namespace drumstick { namespace rt { class MIDIOutput; } namespace widgets { namespace Ui { class SonivoxSettingsDialog; } class SonivoxSettingsDialog : public QDialog { Q_OBJECT public: explicit SonivoxSettingsDialog(QWidget *parent = nullptr); ~SonivoxSettingsDialog(); void readSettings(); void writeSettings(); void chkDriverProperties(QSettings *settings); static const QString QSTR_PREFERENCES; static const QString QSTR_BUFFERTIME; static const QString QSTR_REVERBTYPE; static const QString QSTR_REVERBAMT; static const QString QSTR_CHORUSTYPE; static const QString QSTR_CHORUSAMT; public slots: void accept() override; void showEvent(QShowEvent *event) override; void restoreDefaults(); private: Ui::SonivoxSettingsDialog *ui; drumstick::rt::MIDIOutput *m_driver; }; }} // namespace drumstick::widgets #endif // SonivoxSettingsDialog_H drumstick-2.5.1/library/widgets/PaxHeaders.27918/checked.svg0000644000000000000000000000013214200302440020501 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.877324214 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/checked.svg0000644000175000001440000000111714200302440021262 0ustar00pedrousers00000000000000 drumstick-2.5.1/library/widgets/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440021132 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/CMakeLists.txt0000644000175000001440000001523314200302440021717 0ustar00pedrousers00000000000000# Drumstick Widgets C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) find_package(Qt${QT_VERSION_MAJOR}Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR}Network REQUIRED) find_package(Qt${QT_VERSION_MAJOR}LinguistTools REQUIRED) set(drumstick-widgets_HEADERS ../include/drumstick/pianokeybd.h ../include/drumstick/pianopalette.h ../include/drumstick/settingsfactory.h ../include/drumstick/configurationdialogs.h ) set(drumstick-widgets_OBJ_SRCS ../include/drumstick/pianokeybd.h ../include/drumstick/pianopalette.h ../include/drumstick/rtmidiinput.h ../include/drumstick/rtmidioutput.h pianoscene.h fluidsettingsdialog.h networksettingsdialog.h macsynthsettingsdialog.h sonivoxsettingsdialog.h ) if(BUILD_FRAMEWORKS) set_source_files_properties(${drumstick-widgets_HEADERS} PROPERTIES MACOSX_PACKAGE_LOCATION Headers/drumstick ) endif() set(drumstick-widgets_SRCS configurationdialogs.cpp fluidsettingsdialog.cpp fluidsettingsdialog.h keylabel.cpp keylabel.h macsynthsettingsdialog.cpp macsynthsettingsdialog.h networksettingsdialog.cpp networksettingsdialog.h pianokey.cpp pianokey.h pianokeybd.cpp pianopalette.cpp pianoscene.cpp pianoscene.h settingsfactory.cpp sonivoxsettingsdialog.cpp sonivoxsettingsdialog.h ) set(drumstick-widgets_FORMS fluidsettingsdialog.ui macsynthsettingsdialog.ui networksettingsdialog.ui sonivoxsettingsdialog.ui ) if (WIN32) set(TARGET_DESCRIPTION ${Drumstick_DESCRIPTION}) set(TARGET_NAME drumstick-widgets) set(TARGET_ORIGINAL_FILENAME libdrumstick-widgets.dll) configure_file(${Drumstick_SOURCE_DIR}/versioninfo.rc.in versioninfo.rc @ONLY) list(APPEND drumstick-widgets_SRCS versioninfo.rc) endif() if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_ui(drumstick-widgets_UI_SRCS ${drumstick-widgets_FORMS}) qt5_wrap_cpp(drumstick-widgets_MOC_SRCS ${drumstick-widgets_OBJ_SRCS}) qt5_add_resources(drumstick-widgets_RESOURCES pianokeybd.qrc) else() qt_wrap_ui(drumstick-widgets_UI_SRCS ${drumstick-widgets_FORMS}) qt_wrap_cpp(drumstick-widgets_MOC_SRCS ${drumstick-widgets_OBJ_SRCS}) qt_add_resources(drumstick-widgets_RESOURCES pianokeybd.qrc) endif() add_library(drumstick-widgets ${drumstick-widgets_UI_SRCS} ${drumstick-widgets_MOC_SRCS} ${drumstick-widgets_SRCS} ${drumstick-widgets_RESOURCES} ${drumstick-widgets_HEADERS} ) add_library(Drumstick::Widgets ALIAS drumstick-widgets) target_include_directories(drumstick-widgets PUBLIC $ $ ) target_link_libraries(drumstick-widgets PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network Drumstick::RT ) set(TS_FILES translations/drumstick-widgets_cs.ts translations/drumstick-widgets_de.ts translations/drumstick-widgets_en.ts translations/drumstick-widgets_es.ts translations/drumstick-widgets_fr.ts translations/drumstick-widgets_gl.ts translations/drumstick-widgets_it.ts translations/drumstick-widgets_nl.ts translations/drumstick-widgets_ru.ts translations/drumstick-widgets_sr.ts translations/drumstick-widgets_sv.ts translations/drumstick-widgets_tr.ts translations/drumstick-widgets_zh_CN.ts ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_add_translation(QM_FILES ${TS_FILES}) else() qt_add_translation(QM_FILES ${TS_FILES}) endif() add_custom_command(TARGET drumstick-widgets POST_BUILD COMMAND Qt${QT_VERSION_MAJOR}::lupdate ${CMAKE_CURRENT_SOURCE_DIR} -I ${PROJECT_SOURCE_DIR}/library/include -I ${CMAKE_CURRENT_SOURCE_DIR} -I ${CMAKE_CURRENT_BINARY_DIR} -ts ${TS_FILES} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Updating translations" ) add_custom_target(drumstick-widgets-translations ALL DEPENDS ${QM_FILES}) if (UNIX) install( FILES ${QM_FILES} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/drumstick ) endif () if(STATIC_DRUMSTICK) set_target_properties(drumstick-widgets PROPERTIES STATIC_LIB "libdrumstick-widgets") else() # STATIC_DRUMSTICK set_target_properties(drumstick-widgets PROPERTIES VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} SOVERSION ${PROJECT_VERSION_MAJOR} EXPORT_NAME Widgets # macOS: MACOSX_RPATH TRUE ) if (BUILD_FRAMEWORKS) set_target_properties(drumstick-widgets PROPERTIES FRAMEWORK ${BUILD_FRAMEWORKS} FRAMEWORK_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} MACOSX_FRAMEWORK_IDENTIFIER "net.sourceforge.drumstick-widgets" MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_SOURCE_DIR}/cmake_admin/CustomFrameworkInfo.plist.in" ) endif() endif() # STATIC_DRUMSTICK install(TARGETS drumstick-widgets EXPORT drumstick-widgets-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install(FILES ${drumstick-widgets_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/drumstick) install(EXPORT drumstick-widgets-targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/drumstick NAMESPACE Drumstick:: ) export(EXPORT drumstick-widgets-targets NAMESPACE Drumstick:: FILE ${CMAKE_BINARY_DIR}/drumstick-widgets-targets.cmake ) include(CMakePackageConfigHelpers) write_basic_package_version_file(${CMAKE_BINARY_DIR}/drumstick-widgets-config-version.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) configure_file( drumstick-widgets-config.cmake ${CMAKE_BINARY_DIR}/drumstick-widgets-config.cmake @ONLY ) install(FILES ${CMAKE_BINARY_DIR}/drumstick-widgets-config-version.cmake ${CMAKE_BINARY_DIR}/drumstick-widgets-config.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/drumstick ) drumstick-2.5.1/library/widgets/PaxHeaders.27918/configurationdialogs.cpp0000644000000000000000000000013214200302440023310 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/configurationdialogs.cpp0000644000175000001440000001104214200302440024067 0ustar00pedrousers00000000000000/* Drumstick MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "fluidsettingsdialog.h" #include "networksettingsdialog.h" #include #if defined(Q_OS_LINUX) #include "sonivoxsettingsdialog.h" #endif #if defined(Q_OS_MACOS) #include "macsynthsettingsdialog.h" #endif /** * @file configurationdialogs.cpp * Implementation of the configuration dialogs */ /** * @addtogroup Widgets Drumstick Widgets * @{ */ namespace drumstick { namespace widgets { /** * @brief inputDriverIsConfigurable * @param driver the driver name * @return true if the input driver has a configuration dialog */ bool inputDriverIsConfigurable(const QString driver) { return (driver == "Network"); } /** * @brief outputDriverIsConfigurable * @param driver the driver name * @return true if the output driver has a configuration dialog */ bool outputDriverIsConfigurable(const QString driver) { return (driver == "Network") #if defined(Q_OS_LINUX) || (driver == "SonivoxEAS") #endif #if defined(Q_OS_MACOS) || (driver == "DLS Synth") #endif || (driver == "FluidSynth"); } /** * @brief Input Driver configuration dialog * Some RT input drivers can be configured. This function provides a * dialog box to show and edit the configurable parameters, and * save the settings. Curremtly, only the Network driver is configurable. * @param driver name of the driver * @param parent optional parent widget * @return true if configuration has changed */ bool configureInputDriver(const QString driver, QWidget* parent) { if (driver == "Network") { NetworkSettingsDialog dlg(true, parent); return (dlg.exec() == QDialog::Accepted); } return false; } /** * @brief Output Driver configuration dialog * Some RT output drivers can be configured. This function provides a * dialog box to show and edit the configurable parameters, and * save the settings. Curremtly the Network, FluidSynth, SonivoxEAS, * and macOS DLS Synth drivers are configurable. * @param driver name of the driver * @param parent optional parent widget * @return true if configuration has changed */ bool configureOutputDriver(const QString driver, QWidget* parent) { bool result = false; if (driver == "Network") { NetworkSettingsDialog dlg(false, parent); result = (dlg.exec() == QDialog::Accepted); } else if (driver == "FluidSynth") { FluidSettingsDialog dlg(parent); result = (dlg.exec() == QDialog::Accepted); #if defined(Q_OS_LINUX) } else if (driver == "SonivoxEAS") { SonivoxSettingsDialog dlg(parent); result = (dlg.exec() == QDialog::Accepted); #endif #if defined(Q_OS_MACOS) } else if (driver == "DLS Synth") { MacSynthSettingsDialog dlg(parent); return (dlg.exec() == QDialog::Accepted); #endif } return result; } /** * @brief Changes the sound font configuration * Some RT output drivers accept soundfonts. This function allows to * change the soundfont file for a driver and store the setting. The * FluidSynth and macOS DLS Synth drivers are currently supported. * @param driver name of the driver * @param fileName name of the soundfont file * @param parent optional parent widget * @return true if configuration has changed */ void changeSoundFont(const QString driver, const QString fileName, QWidget* parent) { if (driver == "FluidSynth") { FluidSettingsDialog dlg(parent); dlg.changeSoundFont(fileName); #if defined(Q_OS_MACOS) } else if (driver == "DLS Synth") { MacSynthSettingsDialog dlg(parent); dlg.changeSoundFont(fileName); #endif } } /** * @brief libraryVersion returns the runtime library version as a QString * @return version string */ QString libraryVersion() { return QStringLiteral(QT_STRINGIFY(VERSION)); } } // namespace widgets } // namespace drumstick /** @} */ drumstick-2.5.1/library/widgets/PaxHeaders.27918/pianokeybd.qrc0000644000000000000000000000013214200302440021226 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/pianokeybd.qrc0000644000175000001440000000035114200302440022006 0ustar00pedrousers00000000000000 blkey.png whkey.png checked.png error.png drumstick-2.5.1/library/widgets/PaxHeaders.27918/checked.png0000644000000000000000000000013214200302440020466 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/checked.png0000644000175000001440000000264214200302440021253 0ustar00pedrousers00000000000000PNG  IHDR$xgAMA a cHRMz&u0`:pQ<bKGDC pHYs]OtIME .r8qIDATHŗmLWyP'3Ρ"MZ 2%]kE'$c.qbaTh?Ta~,t0 /ڂՀ\dh%OϽܜs۹~*ŠW4FFzKrJ A߂$)a ge2OZ)CCGjqdW qR̓ˍOrP*+ϻhm:zwQpx^rE4CGE πFKcq037pC/J@>3sŀKi+&5^R i496$b4!;6.,iyҸd2e߭?ǙclRںLsqF/* ~/gGCMFZmGHO`ÇY7(SD\nK ƈ@Ad8wN qXffy/%x3~>bF& TU(TgJHҍHȿ8N;_bd7၁Bbő'z75UNL\P^LO. @m))ůw:(Z?R)%$"prv@\\HȺukDރz~C dbhSӶmǏ?;~X{1AGJ"Grs1H+l99N2žss% @* *|V}XIiXbonuxB®]Kgm&;S\4+Q w*bp^ deEGsxK覦O=7jn0옙:PkA׎_Ue^Ӄ߼_7yfިɑVs ݤ$傯6(rNS\U5m0 x<ljo笴 aaׯ WO,q91q_[S幛_iaBt_NC&W7[϶oG%䴴niffs 8 ɓQOs4+%}b8T+\n5H%tEXtdate:create2021-05-18T17:19:14+02:00$%tEXtdate:modify2018-04-07T09:46:27+02:00/̱IENDB`drumstick-2.5.1/library/widgets/PaxHeaders.27918/drumstick-widgets-config.cmake0000644000000000000000000000013214200302440024310 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/drumstick-widgets-config.cmake0000644000175000001440000000014614200302440025072 0ustar00pedrousers00000000000000#include(CMakeFindDependencyMacro) include(${CMAKE_CURRENT_LIST_DIR}/drumstick-widgets-targets.cmake) drumstick-2.5.1/library/widgets/PaxHeaders.27918/error.svg0000644000000000000000000000013214200302440020244 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/error.svg0000644000175000001440000000122514200302440021025 0ustar00pedrousers00000000000000 drumstick-2.5.1/library/widgets/PaxHeaders.27918/macsynthsettingsdialog.h0000644000000000000000000000013214200302440023332 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.877324214 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/macsynthsettingsdialog.h0000644000175000001440000000335314200302440024117 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef MacSynthSettingsDialog_H #define MacSynthSettingsDialog_H #include #include #include /** * @file macsynthsettingsdialog.h * Declaration of the Mac Synth configuration dialog */ namespace drumstick { namespace rt { class MIDIOutput; } namespace widgets { namespace Ui { class MacSynthSettingsDialog; } class MacSynthSettingsDialog : public QDialog { Q_OBJECT public: explicit MacSynthSettingsDialog(QWidget *parent = nullptr); ~MacSynthSettingsDialog(); void readSettings(); void writeSettings(); void changeSoundFont(const QString& fileName); public slots: void accept() override; void showEvent(QShowEvent *event) override; void restoreDefaults(); void showFileDialog(); private: Ui::MacSynthSettingsDialog *ui; drumstick::rt::MIDIOutput *m_driver; void checkDriver(QSettings* settings); }; }} // namespace drumstick::widgets #endif // MacSynthSettingsDialog_H drumstick-2.5.1/library/widgets/PaxHeaders.27918/widgets.pro0000644000000000000000000000013214200302440020562 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.877324214 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/widgets.pro0000644000175000001440000000467714200302440021361 0ustar00pedrousers00000000000000TEMPLATE = lib TARGET = drumstick-widgets DESTDIR = ../../build/lib DEPENDPATH += . ../include INCLUDEPATH += . ../include include (../../global.pri) CONFIG += c++11 qt create_pc create_prl no_install_prl lrelease static { CONFIG += staticlib } LRELEASE_DIR=. DEFINES += drumstick_widgets_EXPORTS QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_HIDESYMS QMAKE_PKGCONFIG_PREFIX = $$INSTALLBASE QT += widgets network LIBS += -L$$OUT_PWD/../../build/lib -ldrumstick-rt FORMS += \ fluidsettingsdialog.ui \ networksettingsdialog.ui HEADERS += \ ../include/drumstick/pianokeybd.h \ ../include/drumstick/pianopalette.h \ ../include/drumstick/rtmidiinput.h \ ../include/drumstick/rtmidioutput.h \ ../include/drumstick/configurationdialogs.h \ ../include/drumstick/settingsfactory.h \ pianoscene.h \ pianokey.h \ keylabel.h \ fluidsettingsdialog.h \ networksettingsdialog.h SOURCES += \ configurationdialogs.cpp \ pianokey.cpp \ pianokeybd.cpp \ pianoscene.cpp \ pianopalette.cpp \ keylabel.cpp \ fluidsettingsdialog.cpp \ networksettingsdialog.cpp \ settingsfactory.cpp RESOURCES += pianokeybd.qrc TRANSLATIONS += \ translations/drumstick-widgets_en.ts \ translations/drumstick-widgets_cs.ts \ translations/drumstick-widgets_de.ts \ translations/drumstick-widgets_es.ts \ translations/drumstick-widgets_fr.ts \ translations/drumstick-widgets_gl.ts \ translations/drumstick-widgets_it.ts \ translations/drumstick-widgets_nl.ts \ translations/drumstick-widgets_ru.ts \ translations/drumstick-widgets_sr.ts \ translations/drumstick-widgets_sv.ts \ translations/drumstick-widgets_tr.ts \ translations/drumstick-widgets_zh_CN.ts macx { FORMS += macsynthsettingsdialog.ui HEADERS += macsynthsettingsdialog.h SOURCES += macsynthsettingsdialog.cpp } linux { FORMS += sonivoxsettingsdialog.ui HEADERS += sonivoxsettingsdialog.h SOURCES += sonivoxsettingsdialog.cpp } macx:!static { TARGET = drumstick-widgets CONFIG += lib_bundle FRAMEWORK_HEADERS.version = Versions FRAMEWORK_HEADERS.files = $$HEADERS FRAMEWORK_HEADERS.path = Headers/drumstick QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS #QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/ QMAKE_SONAME_PREFIX = @rpath QMAKE_TARGET_BUNDLE_PREFIX = net.sourceforge QMAKE_BUNDLE = drumstick-widgets QMAKE_INFO_PLIST = ../Info.plist.lib } drumstick-2.5.1/library/widgets/PaxHeaders.27918/fluidsettingsdialog.ui0000644000000000000000000000013214200302440022775 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/fluidsettingsdialog.ui0000644000175000001440000001610714200302440023563 0ustar00pedrousers00000000000000 drumstick::widgets::FluidSettingsDialog 0 0 319 431 FluidSynth Driver Settings Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults QFrame::StyledPanel QFrame::Raised Audio Driver: Gain: gain Reverb Sound Font: soundFont 2 64 FluidSynth Version: 64 8192 Period Size: periodSize Initialization Status: Sample Rate: sampleRate Chorus ... # of Periods: periods Polyphony: polyphony Buffer Time: ms 3 300 30 audioDriver periodSize periods sampleRate chorus reverb gain polyphony soundFont btnFile buttonBox accepted() drumstick::widgets::FluidSettingsDialog accept() 248 254 157 274 buttonBox rejected() drumstick::widgets::FluidSettingsDialog reject() 316 260 286 274 drumstick-2.5.1/library/widgets/PaxHeaders.27918/keylabel.cpp0000644000000000000000000000013214200302440020666 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/keylabel.cpp0000644000175000001440000000513214200302440021450 0ustar00pedrousers00000000000000/* Virtual Piano Widget for Qt5 Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include "keylabel.h" #include "pianokey.h" #include /** * @file keylabel.cpp * Implementation of the KeyLabel class */ namespace drumstick { namespace widgets { KeyLabel::KeyLabel(QGraphicsItem *parent) : QGraphicsTextItem(parent) { setAcceptedMouseButtons(Qt::NoButton); } void KeyLabel::adjust() { qreal ax, ay; QRectF kr, br; PianoKey* key = static_cast(parentItem()); kr = key->boundingRect(); br = boundingRect(); ax = kr.x(); ay = kr.height() - 5; if (key->isBlack()) { ay -= 70; } if (rotation() == 0) { ax += (kr.width() - br.width()) / 2; ay -= br.height(); } else { ax += (kr.width() - br.height()) / 2; } setPos(ax, ay); m_savedColor = defaultTextColor(); } void KeyLabel::setOrientation(LabelOrientation ori) { if (m_orientation != ori) { m_orientation = ori; switch(m_orientation) { case VerticalOrientation: setRotation(270); break; case HorizontalOrientation: setRotation(0); break; case AutomaticOrientation: default: calculateRotation(); break; } } } void KeyLabel::restoreColor() { if (m_savedColor.isValid()) { setDefaultTextColor(m_savedColor); } } void drumstick::widgets::KeyLabel::calculateRotation() { PianoKey* key = static_cast(parentItem()); QRectF kr, br; kr = key->boundingRect(); br = boundingRect(); if (br.width() > kr.width()) { setRotation(270); } else { setRotation(0); } } void KeyLabel::setPlainText(const QString &text) { QGraphicsTextItem::setPlainText(text); adjustSize(); if (m_orientation == AutomaticOrientation) { calculateRotation(); } } } // namespace widgets } // namespace drumstick drumstick-2.5.1/library/widgets/PaxHeaders.27918/networksettingsdialog.cpp0000644000000000000000000000013214200302440023530 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.877324214 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/networksettingsdialog.cpp0000644000175000001440000001415714200302440024321 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "networksettingsdialog.h" #include "ui_networksettingsdialog.h" #include #include /** * @file networksettingsdialog.cpp * Implementation of the Network configuration dialog */ namespace drumstick { namespace widgets { const QString NetworkSettingsDialog::QSTR_ADDRESS_IPV4 = QStringLiteral("225.0.0.37"); const QString NetworkSettingsDialog::QSTR_ADDRESS_IPV6 = QStringLiteral("ff12::37"); NetworkSettingsDialog::NetworkSettingsDialog(const bool forInput, QWidget *parent) : QDialog(parent), ui(new Ui::NetworkSettingsDialog), m_input(forInput) { ui->setupUi(this); connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::pressed, this, &NetworkSettingsDialog::restoreDefaults); connect(ui->checkIPv6, &QCheckBox::toggled, this, &NetworkSettingsDialog::toggledIPv6); drumstick::rt::BackendManager man; if (m_input) { m_driver = man.inputBackendByName("Network"); } else { m_driver = man.outputBackendByName("Network"); } } NetworkSettingsDialog::~NetworkSettingsDialog() { if (m_driver != nullptr) { if (m_input) { static_cast(m_driver)->close(); } else { static_cast(m_driver)->close(); } } delete ui; } void NetworkSettingsDialog::accept() { writeSettings(); if (m_driver != nullptr) { QString title; QVariant varStatus = m_driver->property("status"); if (varStatus.isValid()) { title = varStatus.toBool() ? tr("Network Initialized") : tr("Network Initialization Failed"); QVariant varDiag = m_driver->property("diagnostics"); if (varDiag.isValid()) { QString text = varDiag.toStringList().join(QChar::LineFeed).trimmed(); if (varStatus.toBool()) { if (!text.isEmpty()) { QMessageBox::information(this, title, text); } } else { QMessageBox::critical(this, title, text); return; } } } } QDialog::accept(); } void NetworkSettingsDialog::showEvent(QShowEvent *event) { readSettings(); event->accept(); } void NetworkSettingsDialog::readSettings() { SettingsFactory settings; settings->beginGroup("Network"); QString ifaceName = settings->value("interface", QString()).toString(); bool ipv6 = settings->value("ipv6", false).toBool(); QString address = settings->value("address", ipv6 ? QSTR_ADDRESS_IPV6 : QSTR_ADDRESS_IPV4).toString(); settings->endGroup(); ui->txtAddress->setText(address); ui->checkIPv6->setChecked(ipv6); ui->comboInterface->addItem(tr("Any"), ""); foreach( const QNetworkInterface& iface, QNetworkInterface::allInterfaces() ) { if ( iface.isValid() && iface.flags().testFlag(QNetworkInterface::CanMulticast) && iface.flags().testFlag(QNetworkInterface::IsUp) && iface.flags().testFlag(QNetworkInterface::IsRunning) && !iface.flags().testFlag(QNetworkInterface::IsLoopBack) ) { QString name = iface.name(); QString text = iface.humanReadableName(); ui->comboInterface->addItem(text, name); if (name == ifaceName) { ui->comboInterface->setCurrentText(text); } } } chkInitialization(settings.getQSettings()); } void NetworkSettingsDialog::writeSettings() { SettingsFactory settings; QString networkAddr = ui->txtAddress->text(); QString networkIface = ui->comboInterface->currentData().toString(); bool ipv6 = ui->checkIPv6->isChecked(); settings->beginGroup("Network"); settings->setValue("address", networkAddr); settings->setValue("interface", networkIface); settings->setValue("ipv6", ipv6); settings->endGroup(); settings->sync(); chkInitialization(settings.getQSettings()); } void NetworkSettingsDialog::chkInitialization(QSettings *settings) { if (m_driver != nullptr) { drumstick::rt::MIDIConnection conn("21928", 21928); if (m_input) { auto d = static_cast(m_driver); d->close(); d->initialize(settings); d->open(conn); } else { auto d = static_cast(m_driver); d->close(); d->initialize(settings); d->open(conn); } QVariant varStatus = m_driver->property("status"); if (varStatus.isValid()) { ui->lblStatusText->clear(); ui->lblStatusText->setText(varStatus.toBool() ? tr("Ready") : tr("Failed") ); ui->lblStatusIcon->setPixmap(varStatus.toBool() ? QPixmap(":/checked.png") : QPixmap(":/error.png") ); } } } void NetworkSettingsDialog::restoreDefaults() { ui->checkIPv6->setChecked(false); ui->txtAddress->setText(QSTR_ADDRESS_IPV4); ui->comboInterface->setCurrentText(tr("Any")); } void NetworkSettingsDialog::toggledIPv6(bool checked) { ui->txtAddress->setText(checked ? QSTR_ADDRESS_IPV6 : QSTR_ADDRESS_IPV4); } } // namespace widgets } // namespace drumstick drumstick-2.5.1/library/widgets/PaxHeaders.27918/pianopalette.cpp0000644000000000000000000000013214200302440021563 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.877324214 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/pianopalette.cpp0000644000175000001440000003721414200302440022353 0ustar00pedrousers00000000000000/* MIDI Virtual Piano Keyboard Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include #include /** * @file pianopalette.cpp * Implementation of the Piano Palette */ namespace drumstick { namespace widgets { /** * @brief PianoPalette::QSTR_PALETTEPREFIX is the string prefix for all * the settings stored as persisting settings */ const QString PianoPalette::QSTR_PALETTEPREFIX = QStringLiteral("Palette_"); /** * @brief PianoPalette::PianoPalette Constructor * @param id The Palette Policy identifier */ PianoPalette::PianoPalette(int id) : m_paletteId(id) { initialize(); resetColors(); retranslateStrings(); } /** * @brief PianoPalette::initialize reserves and initializes space to store colors * according to the palette policy identifier */ void PianoPalette::initialize() { int maxcolors = 0; switch(m_paletteId) { case PAL_SINGLE: maxcolors = 1; break; case PAL_DOUBLE: maxcolors = 2; break; case PAL_CHANNELS: maxcolors = 16; break; case PAL_SCALE: maxcolors = 12; break; case PAL_KEYS: maxcolors = 2; break; case PAL_FONT: maxcolors = 4; break; case PAL_HISCALE: maxcolors = 12; break; default: return; } m_colors.reserve(maxcolors); m_names.reserve(maxcolors); for(int i=0; ipalette().highlight().color()); } /** * @brief PianoPalette::resetPaletteDouble resets the colors to the standard values * for the PAL_DOUBLE palette policy */ void PianoPalette::resetPaletteDouble() { setColor(0, tr("N"), qApp->palette().highlight().color()); setColor(1, tr("#"), QColor("lawngreen")); } /** * @brief PianoPalette::resetPaletteChannels resets the colors to the standard values * for the PAL_CHANNELS palette policy */ void PianoPalette::resetPaletteChannels() { setColor(0, tr("1"), QColor("red")); setColor(1, tr("2"), QColor("lime")); setColor(2, tr("3"), QColor("blue")); setColor(3, tr("4"), QColor("gold")); setColor(4, tr("5"), QColor("maroon")); setColor(5, tr("6"), QColor("green")); setColor(6, tr("7"), QColor("navy")); setColor(7, tr("8"), QColor("darkorange")); setColor(8, tr("9"), QColor("purple")); setColor(9, tr("10"), qApp->palette().highlight().color()); setColor(10, tr("11"), QColor("teal")); setColor(11, tr("12"), QColor("chocolate")); setColor(12, tr("13"), QColor("fuchsia")); setColor(13, tr("14"), QColor("olivedrab")); setColor(14, tr("15"), QColor("aqua")); setColor(15, tr("16"), QColor("greenyellow")); } /** * @brief PianoPalette::resetPaletteScale resets the colors to the standard values * for the PAL_SCALE palette policy */ void PianoPalette::resetPaletteScale() { /* R G B C 100% - - 0 C# 100% 50% - 1 D 100% 100% - 2 D# 50% 100% - 3 E - 100% - 4 F - 100% 50% 5 F# - 100% 100% 6 G - 50% 100% 7 G# - - 100% 8 A 50% - 100% 9 A# 100% - 100% 10 B 100% - 50% 11 */ setColor(0, tr("C"), QColor::fromRgb(255,0,0)); setColor(1, tr("C#"), QColor::fromRgb(255,127,0)); setColor(2, tr("D"), QColor::fromRgb(255,255,0)); setColor(3, tr("D#"), QColor::fromRgb(127,255,0)); setColor(4, tr("E"), QColor::fromRgb(0,255,0)); setColor(5, tr("F"), QColor::fromRgb(0,255,127)); setColor(6, tr("F#"), QColor::fromRgb(0,255,255)); setColor(7, tr("G"), QColor::fromRgb(0,127,255)); setColor(8, tr("G#"), QColor::fromRgb(0,0,255)); setColor(9, tr("A"), QColor::fromRgb(127,0,255)); setColor(10, tr("A#"), QColor::fromRgb(255,0,255)); setColor(11, tr("B"), QColor::fromRgb(255,0,127)); } /** * @brief PianoPalette::resetPaletteKeys resets the colors to the standard values * for the PAL_KEYS palette policy */ void PianoPalette::resetPaletteKeys() { setColor(0, tr("N"), QColor("white")); setColor(1, tr("#"), QColor("black")); } /** * @brief PianoPalette::resetPaletteFont resets the colors to the standard values * for the PAL_FONT palette policy */ void PianoPalette::resetPaletteFont() { setColor(0, tr("N"), QColor("black")); setColor(1, tr("#"), QColor("white")); setColor(2, tr("N*"), QColor("white")); setColor(3, tr("#*"), QColor("white")); } /** * @brief PianoPalette::retranslateStrings retranslates the names and description * texts according to the palette policy */ void PianoPalette::retranslateStrings() { switch(m_paletteId) { case PAL_SINGLE: setPaletteName(tr("Single color highlight")); setPaletteText(tr("A single color to highlight all note events")); retranslatePaletteSingle(); break; case PAL_DOUBLE: setPaletteName(tr("Two colors highlight")); setPaletteText(tr("One color to highlight natural notes and a different one for accidentals")); retranslatePaletteDouble(); break; case PAL_CHANNELS: setPaletteName(tr("MIDI Channels highlight")); setPaletteText(tr("A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection")); retranslatePaletteChannels(); break; case PAL_SCALE: setPaletteName(tr("Chromatic scale background")); setPaletteText(tr("One color for each note in the chromatic scale")); retranslatePaletteScale(); break; case PAL_KEYS: setPaletteName(tr("Keys background")); setPaletteText(tr("One color for natural notes and another for accidentals")); retranslatePaletteKeys(); break; case PAL_FONT: setPaletteName(tr("Font foreground")); setPaletteText(tr("Colors for note names")); retranslatePaletteFont(); break; case PAL_HISCALE: setPaletteName(tr("Chromatic scale highlight")); setPaletteText(tr("One color for each note in the chromatic scale")); retranslatePaletteScale(); break; default: return; } } /** * @brief PianoPalette::retranslatePaletteSingle retranslates the color names * for the PAL_SINGLE palette policy */ void PianoPalette::retranslatePaletteSingle() { setColorName(0, QString()); } /** * @brief PianoPalette::retranslatePaletteDouble retranslates the color names * for the PAL_DOUBLE palette policy */ void PianoPalette::retranslatePaletteDouble() { setColorName(0, tr("N")); setColorName(1, tr("#")); } /** * @brief PianoPalette::retranslatePaletteChannels retranslates the color names * for the PAL_CHANNELS palette policy */ void PianoPalette::retranslatePaletteChannels() { setColorName(0, tr("1")); setColorName(1, tr("2")); setColorName(2, tr("3")); setColorName(3, tr("4")); setColorName(4, tr("5")); setColorName(5, tr("6")); setColorName(6, tr("7")); setColorName(7, tr("8")); setColorName(8, tr("9")); setColorName(9, tr("10")); setColorName(10, tr("11")); setColorName(11, tr("12")); setColorName(12, tr("13")); setColorName(13, tr("14")); setColorName(14, tr("15")); setColorName(15, tr("16")); } /** * @brief PianoPalette::retranslatePaletteScale retranslates the color names * for the PAL_SCALE palette policy */ void PianoPalette::retranslatePaletteScale() { setColorName(0, tr("C")); setColorName(1, tr("C#")); setColorName(2, tr("D")); setColorName(3, tr("D#")); setColorName(4, tr("E")); setColorName(5, tr("F")); setColorName(6, tr("F#")); setColorName(7, tr("G")); setColorName(8, tr("G#")); setColorName(9, tr("A")); setColorName(10, tr("A#")); setColorName(11, tr("B")); } /** * @brief PianoPalette::retranslatePaletteKeys retranslates the color names * for the PAL_KEYS palette policy */ void PianoPalette::retranslatePaletteKeys() { setColorName(0, tr("N")); setColorName(1, tr("#")); } /** * @brief PianoPalette::retranslatePaletteFont retranslates the color names * for the PAL_FONT palette policy */ void PianoPalette::retranslatePaletteFont() { setColorName(0, tr("N")); setColorName(1, tr("#")); setColorName(2, tr("N*")); setColorName(3, tr("#*")); } /** * @brief PianoPalette::isHighLight palette function * @return true if the palette is used for keys highlighting */ bool PianoPalette::isHighLight() const { return (m_paletteId == PAL_SINGLE) || (m_paletteId == PAL_DOUBLE) || (m_paletteId == PAL_CHANNELS) || (m_paletteId == PAL_HISCALE); } /** * @brief PianoPalette::isBackground palette function * @return true if the palette is used for painting the keys background */ bool PianoPalette::isBackground() const { return (m_paletteId == PAL_SCALE) || (m_paletteId == PAL_KEYS); } /** * @brief PianoPalette::isForeground palette function * @return true if the palette is used to paint text over the keys */ bool PianoPalette::isForeground() const { return (m_paletteId == PAL_FONT); } /** * @brief PianoPalette::paletteId palette policy * @return the palette policy identifier */ int PianoPalette::paletteId() const { return m_paletteId; } /** * @brief PianoPalette::setColor changes a palette color * @param n the color number * @param s the color name * @param c the color value */ void PianoPalette::setColor(const int n, const QString& s, const QColor& c) { if (n < m_colors.size()) { m_colors[n] = c; m_names[n] = s; } } /** * @brief PianoPalette::setColor changes a palette color * @param n the color number * @param c the color value */ void PianoPalette::setColor(const int n, const QColor& c) { if (n < m_colors.size()) m_colors[n] = c; } /** * @brief PianoPalette::setColorName changes a palette color name * @param n the color number * @param s the color name */ void PianoPalette::setColorName(const int n, const QString& s) { if (n < m_names.size()) m_names[n] = s; } /** * @brief PianoPalette::getColor gets a palette color * @param i the color number * @return the color value */ QColor PianoPalette::getColor(const int i) const { if (i < m_colors.size()) return m_colors[i]; return {}; } /** * @brief PianoPalette::getColorName gets a palette color name * @param i the color number * @return the color name */ QString PianoPalette::getColorName(const int i) const { if (i < m_names.size()) return m_names[i]; return QString(); } /** * @brief PianoPalette::getNumColors palette policy colors size * @return the number of colors represented by the palette */ int PianoPalette::getNumColors() const { return m_colors.size(); } /** * @brief PianoPalette::paletteName palette policy name * @return the name of the palette */ QString PianoPalette::paletteName() const { return m_paletteName; } /** * @brief PianoPalette::setPaletteName changes the palette name * @param name new name of the palette */ void PianoPalette::setPaletteName(const QString& name) { if (m_paletteName != name) { m_paletteName = name; } } /** * @brief PianoPalette::paletteText gets the palette description * @return new description of the palette */ QString PianoPalette::paletteText() const { return m_paletteText; } /** * @brief PianoPalette::setPaletteText changes the palette description * @param help new palette description string */ void PianoPalette::setPaletteText(const QString& help) { m_paletteText = help; } /** * @brief PianoPalette::saveColors stores the set of colors as persistent settings */ void PianoPalette::saveColors() const { SettingsFactory settings; settings->beginWriteArray(QSTR_PALETTEPREFIX + QString::number(m_paletteId)); for(int i=0; isetArrayIndex(i); settings->setValue("color", m_colors[i]); } settings->endArray(); settings->sync(); } /** * @brief PianoPalette::loadColors loads the set of colors from persistent settings */ void PianoPalette::loadColors() { SettingsFactory settings; int size = settings->beginReadArray(QSTR_PALETTEPREFIX + QString::number(m_paletteId)); if (size > m_colors.size()) size = m_colors.size(); for(int i=0; isetArrayIndex(i); QColor c = settings->value("color", QColor()).value(); setColor(i, c); } settings->endArray(); } /** * @brief PianoPalette::operator == compares two palettes * @param other another palette object * @return true if both palettes are equal */ bool PianoPalette::operator==(const PianoPalette& other) const { return (m_paletteId == other.m_paletteId) && (m_colors == other.m_colors); } /** * @brief PianoPalette::operator != compares two palettes * @param other another palette object * @return true if both palettes are different */ bool PianoPalette::operator!=(const PianoPalette &other) const { return !(*this == other); } /** * @brief Serialize a PianoPalette instance into a QDataStream * @param stream a QDataStream * @param palette instance * @return the QDataStream */ QDataStream &operator<<(QDataStream &stream, const PianoPalette &palette) { stream << palette.m_paletteId; stream << palette.m_colors; stream << palette.m_names; stream << palette.m_paletteName; stream << palette.m_paletteText; return stream; } /** * @brief Deserialize a PianoPalette instance from a QDataStream * @param stream a QDataStream * @param palette instance * @return the QDataStream */ QDataStream &operator>>(QDataStream &stream, PianoPalette &palette) { stream >> palette.m_paletteId; stream >> palette.m_colors; stream >> palette.m_names; stream >> palette.m_paletteName; stream >> palette.m_paletteText; return stream; } } // namespace widgets } // namespace drumstick drumstick-2.5.1/library/widgets/PaxHeaders.27918/networksettingsdialog.ui0000644000000000000000000000013214200302440023363 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/networksettingsdialog.ui0000644000175000001440000000665514200302440024160 0ustar00pedrousers00000000000000 drumstick::widgets::NetworkSettingsDialog 0 0 325 210 Network Driver Settings 0 0 :/checked.png Init. Status: 0 0 Use IPv6 Network Interface: comboInterface Address Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults buttonBox accepted() drumstick::widgets::NetworkSettingsDialog accept() 236 126 157 87 buttonBox rejected() drumstick::widgets::NetworkSettingsDialog reject() 292 126 286 87 drumstick-2.5.1/library/widgets/PaxHeaders.27918/blkey.svg0000644000000000000000000000013214200302440020221 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.877324214 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/blkey.svg0000644000175000001440000001523514200302440021010 0ustar00pedrousers00000000000000 image/svg+xml drumstick-2.5.1/library/widgets/PaxHeaders.27918/fluidsettingsdialog.h0000644000000000000000000000013214200302440022607 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/fluidsettingsdialog.h0000644000175000001440000000562414200302440023377 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef FLUIDSETTINGSDIALOG_H #define FLUIDSETTINGSDIALOG_H #include #include #include /** * @file fluidsettingsdialog.h * Declaration of the Fluidsynth configuration dialog */ namespace drumstick { namespace rt { class MIDIOutput; } namespace widgets { namespace Ui { class FluidSettingsDialog; } class FluidSettingsDialog : public QDialog { Q_OBJECT public: explicit FluidSettingsDialog(QWidget *parent = nullptr); ~FluidSettingsDialog(); void readSettings(); void writeSettings(); void changeSoundFont(const QString& fileName); void chkDriverProperties(QSettings* settings); public slots: void accept() override; void showEvent(QShowEvent *event) override; void restoreDefaults(); void showFileDialog(); void audioDriverChanged(const QString &text); void bufferTimeChanged(int value); void bufferSizeChanged(); public: static const QString QSTR_PREFERENCES; static const QString QSTR_INSTRUMENTSDEFINITION; static const QString QSTR_DATADIR; static const QString QSTR_DATADIR2; static const QString QSTR_SOUNDFONT; static const QString QSTR_AUDIODRIVER; static const QString QSTR_PERIODSIZE; static const QString QSTR_PERIODS; static const QString QSTR_SAMPLERATE; static const QString QSTR_CHORUS; static const QString QSTR_REVERB; static const QString QSTR_GAIN; static const QString QSTR_POLYPHONY; static const QString QSTR_BUFFERTIME; static const int DEFAULT_BUFFERTIME = 30; static const int DEFAULT_PERIODSIZE = 64; static const int DEFAULT_PERIODS = 16; static constexpr double DEFAULT_SAMPLERATE = 44100.0; static const int DEFAULT_CHORUS = 0; static const int DEFAULT_REVERB = 0; static constexpr double DEFAULT_GAIN = 0.5; static const int DEFAULT_POLYPHONY = 256; static const QString QSTR_PULSEAUDIO; private: QString defaultAudioDriver() const; bool checkRanges() const; void initBuffer(); Ui::FluidSettingsDialog *ui; drumstick::rt::MIDIOutput *m_driver; }; }} // namespace drumstick::widgets #endif // FLUIDSETTINGSDIALOG_H drumstick-2.5.1/library/widgets/PaxHeaders.27918/settingsfactory.cpp0000644000000000000000000000013214200302440022326 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/settingsfactory.cpp0000644000175000001440000000420314200302440023106 0ustar00pedrousers00000000000000/* Drumstick Widgets Copyright (C) 2018-2022 Pedro Lopez-Cabanillas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include /** * @file settingsfactory.cpp * Implementation of the Settings Factory class */ namespace drumstick { namespace widgets { /** * @brief SettingsFactory::s_fileName is a global string providing the file name * of the persisting settings using the INI file format */ QString SettingsFactory::s_fileName; /** * @brief SettingsFactory::setFileName sets the global file name for the * persisting settings and sets the INI format as well * @param name the new file name */ void SettingsFactory::setFileName(const QString name) { SettingsFactory::s_fileName = name; QSettings::setDefaultFormat(QSettings::IniFormat); } /** * @brief SettingsFactory::getQSettings creates and/or returns a QSettings object pointer * @return the internal QSettings object pointer */ QSettings* SettingsFactory::getQSettings() { if (m_settings.isNull()) { if (s_fileName.isEmpty() || QSettings::defaultFormat() == QSettings::NativeFormat) { m_settings.reset(new QSettings()); } else { m_settings.reset(new QSettings(s_fileName, QSettings::IniFormat)); } } return m_settings.data(); } /** * @brief SettingsFactory::operator -> is equivalent to calling getQSettings() * @return the internal QSettings object pointer */ QSettings* SettingsFactory::operator->() { return getQSettings(); } } // namespace widgets } // namespace drumstick drumstick-2.5.1/library/widgets/PaxHeaders.27918/whkey.png0000644000000000000000000000013214200302440020227 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/whkey.png0000644000175000001440000001041514200302440021011 0ustar00pedrousers00000000000000PNG  IHDR97ZWsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<RtEXtCopyrightCC Attribution-ShareAlike http://creativecommons.org/licenses/by-sa/4.0/Tb,IDATxuwA6B#T[b,E $DSI&ƐH@c4KLcLTM!l%&PPJ Zi?ә;wt·+ife3}y=sl$yYl}2[aI'y '{ 'y|'I˷ +X7$8G7]'1&$KXst66Ǔe7*{j mEx7瘢~A$8fܒwsdش]i_OyZgtp@%y"I~.|eՃfNrg?= M$e{$ej3 ԗ>7CΰSbm/I$Wn\3I^a|kIUXd#e b$fئV'{,8AݳOdXѾ# ?}6ɻnz8Ϭ'Iޟayw^[2lyԣ5ܿ'ZwyAodgG>,X3_8O&b%ÑNΠ_ 82dw7AHnBuJ4k33pZvoH ǚi؂_L#3A4gObDpOdџwed "pM2/W|w2aOn\yAߝZg73YxNpPy׼f\2w`}O/X$o&&xPAϾ8|0u5WOtHekk73\ޓS ? G;4NEkG\"K#hKA[C3v$x3Eɷ\Y3v5Sx6ɓ`%9#hZld=ވ+2NB0"h*"h*fvr *"h*"h*'t *"h*"h*2Z MASET4UMASET4UMA3Vsg MASET4UMASET4UMA3f{f MASET4UMASET4UMASET4UMASET4UMASET4UMeMASET4UMASET4UMAbq.)#h*"h*"hjl"h*"h*"h*"h*"h*]' *"h*"h*l"2"h*"h*fNASFT4UMASET4UMASET4UMASET4UMASET4UMA3f{N4UMASET4UMASET4U-4UMASET4UMASET4UMA`{[T4UMASET4UMASET4-&)#h*"h*"h.)#h*"h*"h13-h*"h*"h5[(h*"h*"h۳fl^zJT4UMASET4UMASET4cpPT4UMASET4UMASET4UX͝4UMASET4UMASET4U͘-4UMASET4UMASET4U-4UMASET4UMASET4UMASET4UMASET4UMASET4-&"2"h*"h&A3Vsg MASET4UMASET4UMA3f{f MASET4UMASET4UMASET4UMASET4UMASET4UMeMASET4UMASET4UMAbq.)#h*"h*"h;-h*"h*"h*"h*"h*] *"h*"h*y^&h*"h*"hDЌwMMASET4UMASET4UMASET4UMASET4UMASET4cBASET4UMASET4UMASET4ck[T4UMASET4UMASET4 g MASET4UMASET4UMAb2"h*"h*"hj"'"h*"h*="h*"h*]"h*"h*i=[(hfetMASET4UMASET4UMAbqZ8-h*"h*"h;[(h*"h*"h13[(h*"h*"h*fvM *"h*"h*l"h*"h*"h1.)#h*"h*"h;-h*"h*"h13[(h*"h*"h5[(h*"h*"h*fll"h*"h*"hDЌoASET4UMASET4UMASEЌBASET4UMASET4UMASEЌٞBASET4Ul,QЌfXCS*+djN o$l&y*əʢ$9%w9 M4Nn<,z{ DIĆ;m%yd3CI.=\ |c%'38.$[C3&.$m&7wxP}E{7ܓ䚓,weA[Csڭwe/o&J;xWӠ`e'A<^vgܘ#;~8я l3+sSmv>h'yю rM4-$yla;z٬ $y\a;pO%y Y}˓|&Ѣ]V=In=q]/uIfvἠȰ7.8 {-V]sqzgoIH%5ޘ$foXcrRp*7f8;y7. $Wʤ2FIGIwe*p[::8+ܜ]UIϜS˂$$Xubυ/K$9S*ʰ&]uIv%C0$[I~+Cpf This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #ifndef KEYLABEL_H #define KEYLABEL_H #include #include /** * @file keylabel.h * Declaration of the KeyLabel class */ namespace drumstick { namespace widgets { class KeyLabel : public QGraphicsTextItem { public: explicit KeyLabel(QGraphicsItem *parent = nullptr); virtual ~KeyLabel() = default; void setPlainText(const QString& text); void adjust(); void setOrientation(LabelOrientation ori); void restoreColor(); private: LabelOrientation m_orientation = HorizontalOrientation; void calculateRotation(); QColor m_savedColor; }; }} // namespace drumstick::widgets #endif // KEYLABEL_H drumstick-2.5.1/library/widgets/PaxHeaders.27918/pianokey.h0000644000000000000000000000013214200302440020362 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.877324214 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/pianokey.h0000644000175000001440000000461614200302440021152 0ustar00pedrousers00000000000000/* Virtual Piano Widget for Qt5 Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #ifndef PIANOKEY_H_ #define PIANOKEY_H_ #include #include /** * @file pianokey.h * Declaration of the PianoKey class */ namespace drumstick { namespace widgets { class PianoPalette; class PianoKey : public QGraphicsRectItem { public: explicit PianoKey(QGraphicsItem * parent = nullptr ): QGraphicsRectItem(parent), m_pressed(false), m_note(0), m_black(false), m_usePixmap(true) { } PianoKey(const QRectF &rect, const bool black, const int note); void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override; int getNote() const { return m_note; } void setBrush(const QBrush& b) { m_brush = b; } void setPressedBrush(const QBrush& b) { m_selectedBrush = b; } void resetBrush(); bool isPressed() const { return m_pressed; } void setPressed(bool p); int getDegree() const { return m_note % 12; } int getType() const { return (m_black ? 1 : 0); } bool isBlack() const { return m_black; } const QPixmap& getPixmap() const; void setPixmap(const QPixmap& p); QRectF pixmapRect() const; bool getUsePixmap() const; void setUsePixmap(bool usePixmap); void paintPixmap(QPixmap &pixmap, const QColor& color) const; static const PianoPalette keyPalette; private: bool m_pressed; QBrush m_selectedBrush; QBrush m_brush; int m_note; bool m_black; QPixmap m_pixmap; bool m_usePixmap; }; }} // namespace drumstick::widgets #endif /*PIANOKEY_H_*/ drumstick-2.5.1/library/widgets/PaxHeaders.27918/sonivoxsettingsdialog.ui0000644000000000000000000000013214200302440023377 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/sonivoxsettingsdialog.ui0000644000175000001440000001352214200302440024163 0ustar00pedrousers00000000000000 drumstick::widgets::SonivoxSettingsDialog 0 0 319 290 Sonivox EAS Synth :/icon.png:/icon.png Chorus Qt::AlignCenter 32765 Reverb Qt::AlignCenter 32765 0 0 Buffer Time: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter ms 10 200 30 0 0 Init. Status: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 0 0 Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults spnTime dial_Reverb dial_Chorus combo_Reverb combo_Chorus buttonBox accepted() drumstick::widgets::SonivoxSettingsDialog accept() 145 260 148 288 buttonBox rejected() drumstick::widgets::SonivoxSettingsDialog reject() 239 260 251 289 drumstick-2.5.1/library/widgets/PaxHeaders.27918/blkey.png0000644000000000000000000000013214200302440020206 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/blkey.png0000644000175000001440000005301014200302440020766 0ustar00pedrousers00000000000000PNG  IHDR97ZWbKGD pHYs.#.#x?vtIME  0M IDATxߓ,QϩV+V])d!d͂%"#?'" o/<͏" @ @.C 3]U~PٜsTS՝qTWUde3s26l6l6l`7_[?u]߶m4Mvv֯Vm[Vvfq]u~kl6f黮k޽3~}:x}w]皦r^u۝{E绾?裏s>3 svعG;>]uzڶjo]4]۶Ψ/_Vsykιιsߩ٘c蜻cGGO]o=| χz/=_>{8Mrc~;r9g6gV~m[Taϋc79ǧ^z\ع% W50_:iDm5b^s9yCdpcSĞks]P^y^'rtt+x`Q{+9_z<UB9=4MCS +,F ]XyLcŚTE<ĸ먐UcUCz%}WX2$sF/O;;!>BiHykgCOV<SI)t$HWٯ.m7:ZjRxR>u`Ht$ 1JiwI5$T( Icrq/)ZAK S#F::supn%G7M1H6lbKBGR=V7bA V`8u5 +ݛSa^'g21=i;l3s+H5JX_svnƭ*A24XmXX?G*hQj q-2̘hT7QNE+tp7~WRwC24#7!s'M~< wy`=#ItsG ͏ylJ}#ho fЧ)yC+qXǁIQz^j2RҰԘ %kf./H ke.㑋.)[II Cr #u$œQNq搠nVޗ3!i]Gbs 's) qcpf! iQWO:yy܂JT1HczDzq~ؒ@GR)_qv$IeBGn2tTS7R1BK,cs){n Hz](uH͇!t (w* s,FU7if:D)}"ˁAF HGz\"#M0t4"bA 8)2&Q]VL[nB\jss(MK@GqNc. 5UUKstj@H MNAG;J+wT QPX}n*=ve+Bst1W\SBGTvN曱W.rM"RơE1Q긹ySbv8ʺ$7&Ɂř'}v"/p Ts3G\z* cyiɜB]% БT7)UI\# oܸ1[dL%q.hntYmP%CVKYZBK~ S3Xt3KԬXe0JD9$ɐCGcNXH|쇆 Z.ls)K;քͥe7۬1f|#CSb6;0R+l,qC0 JFA߼ysWf!F5ExP=LD7Szcudca?]ym,4B)3$,+XЍ m,^(W7y\#utsLoeQ&F:e!Zx,tʗOoRQJo/}K s(FrgK,Kͅ(i}4( n*uKs#Ϫ”28M5AG46tD-e {yH7RK֏ݬ+(J};99\K\: NJ<$K\n,q}CA> Sw0RK:5F}Kb9>:J=NCGRs0ҰbO!41cW9xH9y!H<%. 0*T~:#Į^P7)# Ka6XGLX?լX\,a9~s6Y *l!!wN[p8͙΁Do\;\++.7~x*+ san1#m,4B)(&gx=5f6RCJ KQvs*9. Xi:b^Oej.s}{ K\֗BHfTAElH0!A2/p1fMs0Rֻ~:m,qĵ#WWYJ)Cy,qm(dz{uqbmmc [ق+(H)Ks%!tn&+TtjJl?iKoBfӓ20R=::\Ynvi89u}IC1R+}csɅ"1-/:fԣ`u,1xK!TcS :f}m )rTy8:Ch)(CP1Fv# 99q]Wr)}M`uckAGյ1e14r8bt9:tTz,qObВ+1 =# :*Eqr44`CtX/:)o*XD5<4|HQI+K@m kqɘq.0R R* Xb.!TKt3<^M0G+S+%;K\w,xfu{obTf*}oc\:Hnv37a54ƆRrCZzn* AsjuS% IWS)4t CGZׄY׬iz(Fjc {kbվVNH%^(tSݠ>*)HCI w%?Nr>6Zu19%;8'a 6)j4>r%ChL S b4fQĚtsn;П.r_6xzXLͽ:$FӀ6xU#n.v0#n ,BБĵVSX999! k.H5jc+% Ij$CV\*Xy:)Ĥu#7/-/=vׄbYjh #ŖFjcE^|V(3[aXvݧĥ#.+Q7K0X&׆8݌W`6XCSϫ H\O /.prD[qe0R앩JJ |QnhDlk(Jc1RX6hZXCu3ҧKcoct3|^ $c0R7C聍%v#iqE>b6X!Tt;>&[u3X44dXc'DϫAvJd3m,rTqEUƓhFZ F;WC2tN ]#]XS@GZt3%ϸ: KcC*Z=:F7sPpcxMБUu3~^]_Ny=XX#YZ<%c0RJB2e!4tEyXkFvMXБ[gAGc%ҷDC`8x::8T94F%T#kK,Sts)X_U. $C0R% Б%gv-ߠ۶`?n!X\p_  ThK)  IЇK IC44=f)t8^MP8-TRwSE\_F.HqPv]2t`ʘM6( yF,e,!ttsV/IlFJcSz:ru+ACK0R?#Iu!AG)-͔qRŎg^^Cb R :r|G+v-pϏ7ڠ%0TB7SE}KӻR_/&(<>>vPNI0R +8wckt́Y]Fm:%Chta_%)UPT E::8?X >kyj:KwG #Eks%v`iĥa}#9OA_) ot4X~ :^^zBVCK54':'t%'VrPw(Fg}KQɱĚ:ր$04kh1i@ m,O5C.4F26x(7[4!s_6IUj%76t$* "!C0Zu, :*9trl_Zim,qݱc1Yu_h%0R(7 :7x.ݬ.(ܥS ,%^tȠ1@G%t3cF&5q #M_0ҡ٠a7:$ )x@#l,r#θEm7f)gh %4X-Rĥu9QN? D)!%p2XbCXݜJC16xzX?'( VÔTs0R5C!%ƙܱĹœ1AcKa+:Fp͹3GEP euCh)(j7(H!!^֢,61)U5\*tm[4ţ,G+bSJᾌ%΅9z9ej{2i4<:P) 0<]SX#ōfCBG8T;֍ZZ#tySF2ܯ+K%& e,q$EAG1nVnF=%7EnV}iOe6r0RNv@ocuCG!M BNsiJC-%K<=tqϫb9$^9?&U8t1̹ꡣnJ[H饠Zc*RckBGnVH-\i<#U!tU7QrusxTyea.G!t>(>JfdpLz0R4XP#*u3tݓD7)(d6Rʎ :;v$%5fFJykZzQNfenV;-J&HQXeRݬn[u^;gi=L6- ֧gٶze.*]J9 m,|Bsu3Ԋq[85ϡe,qm(VlQ%9HSXⱰĚus-(e*a,eC0Re9JCGRXX+kAGR<:59)DJ+ 1<:J[Tih`>VTanFjcuIKᡡ\SCG1ݜq**`?df#%#cnG(u6(U }Ha?0FK,; tTK78,H" 9X[ҺYeJʐbب5CGKO( oMdx5 HK8-KzhБsk\9KuG;ITU ?#]:ӽqǧV{9xļuLC[eCGnV9T0RXihؙ6t(cn5dq@vxF oQnEn. Io:_ #\ ^:nYw-qy, ] L)(m#.T)9?a`V(#2tfuc݈F3!Hᘂ%%+ŗ)aŷ(J$K\ChnsI gm,u3<|~/墇`t`q;f)x ݜ2fUpRʹ)`:^Ew&|WNazKI]ZC֗d7TSHap޷AGwMa$T[FD?#]jХ% ŌY>FzF2#cB4xn "U⣫*ꄣ8oKisIX_#t]/z 9) C_XPӒsиbd9 !#Kѹ*BN.4dQj%!%$t:|&*(o] #mƠ#W,q Hr Sn L-:ziuo@B~ XXAG : Ma4ewaG5d`׶ $c)|AG˂4{&q\xFJ -ػKAORyt$5r5o+B/t$8Tf)c@_2L41mcut`1AIHr^You]0t$" +a1YCGvs܏DHa6X✴\Iݬ6v+XbT:ZFFFJċ)<5po.tlHRdQRe%!npRaУXl,958Bx+kXK==ߠ!-HMyhͪjM QhcSCK\)¨ rf%iL?sO͵')ݬ2Hs$%:e$,G*1#C/U7kK\֗fuYAu4Wb9nK\y,T7sƙ*PPCJZg,u̜Z  (F}TK02D`:e90RJFb野J uAapTz,F yh œ}K\:Y>Gf<i,%^dѪ1kGT^Y:'q:n6h8tDU b%9MFHK\@7k ۶%{q&R)Ӫm,T3rU,GHݕHqdcCPۮ4F Ǻ )XBBG *AG}9fX$6XG\/*} lx)q}KCh{gMP;jEw #Zn^;V;t֗湍``XFbZ`A`ͥA7RƬf[ H9cC>%jIN`"MaNH,PyntAw]Gf6Ja!ZsuAG9Az8 .^/0Xu*|tZ{4~cUCͥ'%u3^$2#ծ%С#t}>5{b6h9Бvȟ`;.=#Mʥv=4(uKb.y,1:tfc&Y0#Eں!CG1 DgggB+NJ-.csq4upAa#$7T o&6 tI Uyh $?<74h'KSj28#u-9,b9b:0{ >-2}eXbl@sBGszhb2x<4ctĵP;[ 5DjБ?x vX]*MA속%^tͪTN2.X:.U7|3Xp 1FAGa\vx=&HKcKK#T+ļu #::5xLGХ%5[4 I˥0RwMaQ\7tT)mGy_ #w0m2#y'''r@+Cw62P :O݌RH`ԵbœںР#|ŠWե̆#eVDNZx,5ig}VGj^ {)oHq;]K,,^z%5A%y_W#_yK7 19uAGu{xMs(!H\BK%u]z~cI =A!b9yhJ9uB(r)~LHUNe1Rѐa?76xA UWRDJ !Xu.yhl%0%B5OEi;KaAG#nb3bYxSr$#%=b^TXС#ARH a:s%@i;jEX4VK%%.F i,šœCK3F7tdƜvFyg#%3t4X߂fFfg90d`\k塣!Z8+~eБlyhS<4sm,dyh)FJ%m<4:wtLzHЦ;C{.ہr #A ͘Q!;E6Kl\MCCoMxK0hecm1FSl 2f[Hm,T#@J n,EXb3 4áAPj͘'!W2f}M` 6r$bmU5h:n֠0UXbg!w[u}뻮뻮s=v8p~pᚻvq<\߶Nx=\8\Åmɽywhsv]s9\۶}ߟi5Mӷm뚦۶uN{?KK_}U z9!eݿy/o{748lX >=uAnx{ kn(st3u]w$vűo7/Wg1hewJnA~K *s?o_Få2\ΠлQC/(>3Rx-yW ݩ{7;$qZ>{ Y 1#:d;ΑcCĸr}=ι?@1kO.+sI5UBJCŊHu0U}TzKsq;H;hT?%t>1ᵐ#Sb0u{/o{П|,Cze&[wϑF?z$^J+;d%%p#\x㍟޿˲{)1.(2;.zBTZ"1fcr,'n[sIBH̥;b¾o-1b_&1tH sL['<40R@[[ɍ$FAeKKۏ L*9%E}OHw)]}$HKF{~W~!פ)c&RqI/k߽{tIbP^<5z  d4-H O{7ǗwN8nhFι들ގn?衇3y0͆c ,'':?6Zȭ3K>.<1Jyv]urRjιnWٻ_{u{~;21#]V7͛m~5!KbPӧǓih @⨼o)N͖$nt]ׯV:F㸺g)^yԿ#17Xblv}ݬGeR,S˰sR^xSIbPv=99s][U5蘆i=p% /pĸ>? ]:z4(6|6qUbqv JʎdCv] d.CKb5M%&1??Jb@gu{'Ҳc-и̜`OA`|ws=^7KbY =tTC{_|׿>bY ᳀:{0h}["}7HCKOK޾Lzi'M/gĸj%5RUC)Wx'j [Pk ā!$/npn y y}Kk5%&=4Xz8^~{sJ}Z%?;;{su`УwkQGD!޽{_<(APpv}9G檆QS&1Gbc$}F)ٱa H~ˠrݻ?By-bĀξs7'Hx3>+@n|b$AM5-j提$Iv{)}Fu݅~sLb$F)oֿ+ϝsתVw^z/1n83?#G4p{w'L3FCQq {P-8uﻶm;J`=MGkM\Ќ ǟg5~~ꩧt=PMbK wν94}5fv@\'Mb(1\eX0{[`O01Dbrw~3ꛏ?, ƽm~2\$޿U i-Lb(1s>T5,r z 7~2},BJ CCw=cGO?{I߭s4swMWՓW_}S{ĥJ 9e$FxnnW`q7nxslG_i01Vb@n}4w7'!cc^$JPGk'3KNY>Kh?z ~!Qk4]KS ѱc=vHmJ{&1J *;u{ȎbY@ mLb&,%1swQCoawm Xc,4f1Xn3ܖg7s'v}$,&1(^r㤄A[ .Egò#%F7ͻsdGYnvkLbL(1(\PD*1ݬ~لo~k_ڙ$}'1Z~_(ŀ}HY ʨw^z}9w{_ۘJ P? X{%ubPz2[ι׀ݘG@P$FA{Ÿ"1׸㏯/mS;lЯSz'7nmKdK J 0Š/ww7sowkB/x?ʲ&1&Иmۛ`!L1ƃȍy]˒F{ߟ\wL8_Q:zWLc%FZ%6SC] Pc {r_۵%8wa;Y$T#xi@pABMsלsOz޹xI 5%F8ƒ߸qxU8)'H}۶"{v]sݒ,v,F'_=dw-!E1ѵm{4Ѐ)r8intͦ ߹s?'&꡽O}Wս!]gY SI۳km(*k[V?}0QSb>Zpۢҷ@F-aYY hi۷oN,Gu/s²&1jKݻ!ݎ힅AI K c{!tu۶}%72bĠS"1(ϕ1;ΰ9AHlm-1Ġ2R7qΝKx饗^ù\ݟǣ h$IQwwc,9~w~移}{ lA,1V$'>/Z<40,Asx9  Db`:gַ`vιZ׏m]mCXum[4ͅ}d`yQσ| |xz=|۶ X=>h779Y;xU"}ff| d*?'h4}vvb0T@oqPngϧiQ../3 Z\\]*_t8AOܙrGjP^"pv 9*ˠi==@B!:?rc1 )Z].ON dhow4Lf?;Eq{t1uKel]2,/ᡌ?#!*.LKKQwtaaeET7p<bP5܈"wuWjH2,Gyxm9 7GfRݜWV^T7Q}4AyxחoVLmidh${ZxOeE_^k)H)3Ʉ [-Ƈ/ww9lu?MPG%tEXtdate:create2021-05-18T17:19:23+02:00ը%tEXtdate:modify2018-04-07T09:46:27+02:00/̱IENDB`drumstick-2.5.1/library/widgets/PaxHeaders.27918/pianokey.cpp0000644000000000000000000000013214200302440020715 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/pianokey.cpp0000644000175000001440000000653214200302440021504 0ustar00pedrousers00000000000000/* Virtual Piano Widget for Qt5 Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include #include #include "pianokey.h" /** * @file pianokey.cpp * Implementation of the PianoKey class */ namespace drumstick { namespace widgets { const PianoPalette PianoKey::keyPalette(PAL_KEYS); PianoKey::PianoKey(const QRectF &rect, const bool black, const int note) : QGraphicsRectItem(rect), m_pressed(false), m_note(note), m_black(black), m_usePixmap(true) { m_brush = keyPalette.getColor(black ? 1 : 0); setAcceptedMouseButtons(Qt::NoButton); } void PianoKey::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { static const QPen blackPen(Qt::black, 1); painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); if (m_pressed) { if (m_selectedBrush.style() != Qt::NoBrush) { painter->setBrush(m_selectedBrush); } else { painter->setBrush(QApplication::palette().highlight()); } } else { painter->setBrush(m_brush); } painter->setPen(blackPen); painter->drawRoundedRect(rect(), 20, 15, Qt::RelativeSize); if (m_usePixmap) { QPixmap p = getPixmap(); painter->drawPixmap(rect(), p, p.rect()); } } void PianoKey::setPressed(bool p) { if (p != m_pressed) { m_pressed = p; update(); } } const QPixmap& PianoKey::getPixmap() const { static QPixmap blpixmap(QStringLiteral(":/vpiano/blkey.png")); static QPixmap whpixmap(QStringLiteral(":/vpiano/whkey.png")); static QColor bgColor; if (!m_black && (bgColor != m_brush.color())) { bgColor = m_brush.color(); paintPixmap(whpixmap, QColor::fromRgba(bgColor.rgba()^0xffffff)); } if (m_pixmap.isNull()) { return m_black ? blpixmap : whpixmap; } else { return m_pixmap; } } QRectF PianoKey::pixmapRect() const { return getPixmap().rect(); } void PianoKey::resetBrush() { m_brush = keyPalette.getColor(m_black ? 1 : 0); } void PianoKey::setPixmap(const QPixmap &p) { m_pixmap = p; } bool PianoKey::getUsePixmap() const { return m_usePixmap; } void PianoKey::setUsePixmap(bool usePixmap) { m_usePixmap = usePixmap; } void PianoKey::paintPixmap(QPixmap &pixmap, const QColor& color) const { if (!pixmap.isNull()) { QPainter painter(&pixmap); painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing); painter.setCompositionMode(QPainter::CompositionMode_SourceIn); painter.fillRect(pixmap.rect(), color); } } } // namespace widgets } // namespace drumstick drumstick-2.5.1/library/widgets/PaxHeaders.27918/pianoscene.cpp0000644000000000000000000000013214200302440021222 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.877324214 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/pianoscene.cpp0000644000175000001440000011605514200302440022013 0ustar00pedrousers00000000000000/* Virtual Piano Widget for Qt5 Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include #include #include #include #include #include #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) #include #else #include #endif #include #include "pianoscene.h" /** * @file pianoscene.cpp * Implementation of the Piano Scene */ /** * @class QGraphicsScene * The QGraphicsScene class provides a surface for managing a large number of 2D graphical items. * @see https://doc.qt.io/qt-5/qgraphicsscene.html */ namespace drumstick { namespace widgets { class PianoScene::PianoScenePrivate { public: PianoScenePrivate ( const int baseOctave, const int numKeys, const int startKey ): m_baseOctave( baseOctave ), m_numKeys( numKeys ), m_startKey( startKey ), m_minNote( 0 ), m_maxNote( 127 ), m_transpose( 0 ), m_showLabels( ShowNever ), m_alterations( ShowSharps ), m_octave( OctaveC4 ), m_orientation( HorizontalOrientation ), m_rawkbd( false ), m_keyboardEnabled( true ), m_mouseEnabled( true ), m_touchEnabled( true ), m_mousePressed( false ), m_velocity( 100 ), m_channel( 0 ), m_velocityTint( true ), m_handler( nullptr ), m_keybdMap( nullptr ), m_showColorScale( false ), m_hilightPalette(PianoPalette(PAL_SINGLE)), m_backgroundPalette(PianoPalette(PAL_KEYS)), m_foregroundPalette(PianoPalette(PAL_FONT)), m_useKeyPix( true ) { } void saveData(QByteArray& buffer) { QDataStream ds(&buffer, QIODevice::WriteOnly); ds << m_minNote; ds << m_maxNote; ds << m_transpose; ds << m_showLabels; ds << m_alterations; ds << m_octave; ds << m_orientation; ds << m_rawkbd; ds << m_keyboardEnabled; ds << m_mouseEnabled; ds << m_touchEnabled; ds << m_mousePressed; ds << m_velocity; ds << m_channel; ds << m_velocityTint; ds << m_noteNames; ds << m_names_s; ds << m_names_f; ds << m_showColorScale; ds << m_hilightPalette; ds << m_backgroundPalette; ds << m_foregroundPalette; ds << m_useKeyPix; ds << m_keyPix[0]; ds << m_keyPix[1]; } void loadData(QByteArray& buffer) { quint32 u; QDataStream ds(&buffer, QIODevice::ReadOnly); ds >> m_minNote; ds >> m_maxNote; ds >> m_transpose; ds >> u; m_showLabels = LabelVisibility(u); ds >> u; m_alterations = LabelAlteration(u); ds >> u; m_octave = LabelCentralOctave(u); ds >> u; m_orientation = LabelOrientation(u); ds >> m_rawkbd; ds >> m_keyboardEnabled; ds >> m_mouseEnabled; ds >> m_touchEnabled; ds >> m_mousePressed; ds >> m_velocity; ds >> m_channel; ds >> m_velocityTint; ds >> m_noteNames; ds >> m_names_s; ds >> m_names_f; ds >> m_showColorScale; ds >> m_hilightPalette; ds >> m_backgroundPalette; ds >> m_foregroundPalette; ds >> m_useKeyPix; ds >> m_keyPix[0]; ds >> m_keyPix[1]; } int m_baseOctave; int m_numKeys; int m_startKey; int m_minNote; int m_maxNote; int m_transpose; LabelVisibility m_showLabels; LabelAlteration m_alterations; LabelCentralOctave m_octave; LabelOrientation m_orientation; bool m_rawkbd; bool m_keyboardEnabled; bool m_mouseEnabled; bool m_touchEnabled; bool m_mousePressed; int m_velocity; int m_channel; bool m_velocityTint; PianoHandler *m_handler; KeyboardMap *m_keybdMap; QHash m_keys; QMap m_labels; QStringList m_noteNames; QStringList m_names_s; QStringList m_names_f; bool m_showColorScale; PianoPalette m_hilightPalette; PianoPalette m_backgroundPalette; PianoPalette m_foregroundPalette; bool m_useKeyPix; QPixmap m_keyPix[2]; }; const int KEYWIDTH = 180; const int KEYHEIGHT = 720; static qreal sceneWidth(int keys) { return KEYWIDTH * qCeil( keys * 7.0 / 12.0 ); } /** * Constructor. * @param baseOctave octave base number * @param numKeys number of keys * @param startKey starting key * @param keyPressedColor highlight keys color * @param parent owner object */ PianoScene::PianoScene ( const int baseOctave, const int numKeys, const int startKey, const QColor& keyPressedColor, QObject * parent ) : QGraphicsScene( QRectF(0, 0, sceneWidth(numKeys), KEYHEIGHT), parent ), d(new PianoScenePrivate(baseOctave, numKeys, startKey)) { if (keyPressedColor.isValid()) { setKeyPressedColor(keyPressedColor); } QBrush hilightBrush(getKeyPressedColor()); PianoKeybd* view = dynamic_cast(parent); if (view != nullptr) { setFont(view->font()); } int upperLimit = d->m_numKeys + d->m_startKey; int adj = d->m_startKey % 12; if (adj >= 5) adj++; for(int i = d->m_startKey; i < upperLimit; ++i) { float x = 0; PianoKey* key = nullptr; KeyLabel* lbl = nullptr; int ocs = i / 12 * 7; int j = i % 12; if (j >= 5) j++; if ((j % 2) == 0) { x = (ocs + qFloor((j-adj) / 2.0)) * KEYWIDTH; key = new PianoKey( QRectF(x, 0, KEYWIDTH, KEYHEIGHT), false, i ); lbl = new KeyLabel(key); lbl->setDefaultTextColor(d->m_foregroundPalette.getColor(0)); } else { x = (ocs + qFloor((j-adj) / 2.0)) * KEYWIDTH + KEYWIDTH * 0.6 + 1; key = new PianoKey( QRectF( x, 0, KEYWIDTH * 0.8 - 1, KEYHEIGHT * 0.6 ), true, i ); key->setZValue( 1 ); lbl = new KeyLabel(key); lbl->setDefaultTextColor(d->m_foregroundPalette.getColor(1)); } addItem( key ); lbl->setFont(font()); key->setAcceptTouchEvents(true); key->setPressedBrush(hilightBrush); d->m_keys.insert(i, key); d->m_labels.insert(i, lbl); } hideOrShowKeys(); retranslate(); } /** * Destructor. */ PianoScene::~PianoScene() { } /** * Returns the calculated size of the scene. * @return the calculated size of the scene */ QSize PianoScene::sizeHint() const { return {static_cast(sceneWidth(d->m_numKeys)), KEYHEIGHT}; } /** * Assigns the computer keyboard note map. * @param map the computer keyboard note map. */ void PianoScene::setKeyboardMap(KeyboardMap *map) { d->m_keybdMap = map; } /** * Returns the computer keyboard note map. * @return the computer keyboard note map */ KeyboardMap *PianoScene::getKeyboardMap() const { return d->m_keybdMap; } /** * Gets the PianoHandler pointer to the note receiver. * * If this method returns null, then there is not a PianoHandler class assigned, * and then the signals noteOn() and noteOff() are emitted instead. * @return pointer to the PianoHandler class, if there is one assigned */ PianoHandler *PianoScene::getPianoHandler() const { return d->m_handler; } /** * Assigns a PianoHandler pointer for processing note events. * * When this member is used to assign a PianoHandler instance, then * the methods in that instance are called instead of emitting the * signals noteOn() and noteOff(). * @param handler pointer to a PianoHandler instance */ void PianoScene::setPianoHandler(PianoHandler *handler) { d->m_handler = handler; } /** * Returns the palette used for highlighting the played keys * @return The PianoPalette used to highlight the played keys */ PianoPalette PianoScene::getHighlightPalette() { return d->m_hilightPalette; } /** * Displays the note label over a highligted key * @param key the activated key */ void PianoScene::displayKeyOn(PianoKey* key) { key->setPressed(true); int n = key->getNote() + d->m_baseOctave*12 + d->m_transpose; QString s = QString("#%1 (%2)").arg(n).arg(noteName(key)); emit signalName(s); KeyLabel* lbl = dynamic_cast(key->childItems().constFirst()); if (lbl != nullptr) { lbl->setDefaultTextColor(d->m_foregroundPalette.getColor(key->isBlack() ? 3 : 2)); if (d->m_showLabels == ShowActivated) { lbl->setVisible(true); } } } /** * Displays highlighted the activated key with the supplied color and note velocity * @param key the activated key * @param color the highlight color * @param vel the MIDI note velocity */ void PianoScene::showKeyOn( PianoKey* key, QColor color, int vel ) { //qDebug() << Q_FUNC_INFO << key->getNote() << vel << color << d->m_velocityTint; if (d->m_velocityTint && (vel >= 0) && (vel < 128) && color.isValid() ) { QBrush hilightBrush(color.lighter(200 - vel)); key->setPressedBrush(hilightBrush); } else if (color.isValid()) { key->setPressedBrush(color); } displayKeyOn(key); } /** * Displays highlighted the activated key with the supplied note velocity * @param key the activated key * @param vel the MIDI note velocity */ void PianoScene::showKeyOn( PianoKey* key, int vel ) { setHighlightColorFromPolicy(key, vel); displayKeyOn(key); } /** * Displays as deactivated a key * @param key the deactivated key * @param vel the MIDI note velocity */ void PianoScene::showKeyOff( PianoKey* key, int vel) { Q_UNUSED(vel) key->setPressed(false); emit signalName(QString()); KeyLabel* lbl = dynamic_cast(key->childItems().constFirst()); if (lbl != nullptr) { lbl->restoreColor(); if (d->m_showLabels == ShowActivated) { lbl->setVisible(false); } } } /** * Displays highlighted the corresponding key for a given MIDI note, with a color and MIDI velocity * @param note The MIDI note number * @param color The highlight color * @param vel The MIDI note velocity */ void PianoScene::showNoteOn( const int note, QColor color, int vel ) { //qDebug() << Q_FUNC_INFO << note << vel << color; int n = note - d->m_baseOctave*12 - d->m_transpose; if ((note >= d->m_minNote) && (note <= d->m_maxNote) && d->m_keys.contains(n) && color.isValid()) showKeyOn(d->m_keys.value(n), color, vel); } /** * Displays highlighted the corresponding key for a given MIDI note, with MIDI velocity * @param note The MIDI note number * @param vel The MIDI note velocity */ void PianoScene::showNoteOn( const int note, int vel ) { //qDebug() << Q_FUNC_INFO << note << vel; int n = note - d->m_baseOctave*12 - d->m_transpose; if ((note >= d->m_minNote) && (note <= d->m_maxNote) && d->m_keys.contains(n)) { showKeyOn(d->m_keys.value(n), vel); } } /** * Displays deactivated the corresponding key for a given MIDI note, with MIDI velocity * @param note The MIDI note number * @param vel The MIDI note velocity */ void PianoScene::showNoteOff( const int note, int vel ) { int n = note - d->m_baseOctave*12 - d->m_transpose; if ((note >= d->m_minNote) && (note <= d->m_maxNote) && d->m_keys.contains(n)) { showKeyOff(d->m_keys.value(n), vel); } } /** * Returns the base octave number. * @see setBaseOctave() * @return the base octave number */ int PianoScene::baseOctave() const { return d->m_baseOctave; } /** * Performs a Note On MIDI event for the given MIDI note number and velocity. * If a PianoHandler instance is assigned, its PianoHandler::noteOn() method is called, * otherwise the noteOn() signal is triggered. * @param note The MIDI note number * @param vel The MIDI velocity */ void PianoScene::triggerNoteOn( const int note, const int vel ) { int n = d->m_baseOctave*12 + note + d->m_transpose; if ((n >= d->m_minNote) && (n <= d->m_maxNote)) { if (d->m_handler != nullptr) { d->m_handler->noteOn(n, vel); } else { emit noteOn(n, vel); } } } /** * Performs a Note Off MIDI event for the given MIDI note number and velocity. * If a PianoHandler instance is assigned, its PianoHandler::noteOff() method is called, * otherwise the noteOff() signal is triggered. * @param note The MIDI note number * @param vel The MIDI velocity */ void PianoScene::triggerNoteOff( const int note, const int vel ) { int n = d->m_baseOctave*12 + note + d->m_transpose; if ((n >= d->m_minNote) && (n <= d->m_maxNote)) { if (d->m_handler != nullptr) { d->m_handler->noteOff(n, vel); } else { emit noteOff(n, vel); } } } /** * Assigns to the given key the highlight color from the active highlight palette * and the given MIDI velocity. * @param key The given piano key * @param vel The MIDI note velocity */ void PianoScene::setHighlightColorFromPolicy(PianoKey* key, int vel) { QColor c; //qDebug() << Q_FUNC_INFO << key->getNote() << vel << d->m_velocityTint; switch (d->m_hilightPalette.paletteId()) { case PAL_SINGLE: c = d->m_hilightPalette.getColor(0); break; case PAL_DOUBLE: c = d->m_hilightPalette.getColor(key->getType()); break; case PAL_CHANNELS: c = d->m_hilightPalette.getColor(d->m_channel); break; case PAL_HISCALE: c = d->m_hilightPalette.getColor(key->getDegree()); break; default: return; } if (c.isValid()) { if (d->m_velocityTint && (vel >= 0) && (vel < 128)) { QBrush h(c.lighter(200 - vel)); key->setPressedBrush(h); } else { key->setPressedBrush(c); } } } /** * Produces a MIDI Note On event and highlights the given key * @param key The given key */ void PianoScene::keyOn( PianoKey* key ) { triggerNoteOn(key->getNote(), d->m_velocity); showKeyOn(key, d->m_velocity); } /** * Produces a MIDI Note Off event and deactivates the given key * @param key The given key */ void PianoScene::keyOff( PianoKey* key ) { triggerNoteOff(key->getNote(), 0); showKeyOff(key, 0); } /** * Produces a MIDI Note On event and highlights the given key with the given pressure * @param key The given key * @param pressure The applied pressure */ void PianoScene::keyOn( PianoKey* key, qreal pressure ) { int vel = d->m_velocity * pressure; triggerNoteOn(key->getNote(), vel); showKeyOn(key, vel); } /** * Produces a MIDI Note Off event and deactivates the given key with the given pressure. * @param key The given key * @param pressure The applied pressure */ void PianoScene::keyOff( PianoKey* key, qreal pressure ) { int vel = d->m_velocity * pressure; triggerNoteOff(key->getNote(), vel); showKeyOff(key, vel); } /** * Produces a MIDI Note On event and highlights the corresponding key for the given MIDI note number. * @param note The given MIDI note number */ void PianoScene::keyOn(const int note) { if (d->m_keys.contains(note)) keyOn(d->m_keys.value(note)); else triggerNoteOn(note, d->m_velocity); } /** * Produces a MIDI Note Off event and deactivates the corresponding key for the given MIDI note number. * @param note The given MIDI note number */ void PianoScene::keyOff(const int note) { if (d->m_keys.contains(note)) keyOff(d->m_keys.value(note)); else triggerNoteOff(note, d->m_velocity); } /** * Returns whether the low level computer keyboard mode is enabled. * @return true if the low level computer keyboard mode is enabled */ bool PianoScene::getRawKeyboardMode() const { return d->m_rawkbd; } /** * Returns the piano key for the given scene point coordenates. * @param p The given scene point coordenates * @return */ PianoKey* PianoScene::getKeyForPos( const QPointF& p ) const { PianoKey* key = nullptr; QList ptitems = this->items(p, Qt::IntersectsItemShape, Qt::DescendingOrder); foreach(QGraphicsItem *itm, ptitems) { key = dynamic_cast(itm); if (key != nullptr) break; } return key; } /** * This event handler, for event mouseEvent, is reimplemented to receive mouse move events for the scene. * @param mouseEvent The mouse move event object pointer */ void PianoScene::mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent ) { if (d->m_mouseEnabled) { if (d->m_mousePressed) { PianoKey* key = getKeyForPos(mouseEvent->scenePos()); PianoKey* lastkey = getKeyForPos(mouseEvent->lastScenePos()); if ((lastkey != nullptr) && (lastkey != key) && lastkey->isPressed()) { keyOff(lastkey); } if ((key != nullptr) && !key->isPressed()) { keyOn(key); } mouseEvent->accept(); return; } } } /** * This event handler, for event mouseEvent, is reimplemented to receive mouse press events for the scene. * @param mouseEvent The mouse press event object pointer */ void PianoScene::mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent ) { if (d->m_mouseEnabled) { PianoKey* key = getKeyForPos(mouseEvent->scenePos()); if (key != nullptr && !key->isPressed()) { keyOn(key); d->m_mousePressed = true; mouseEvent->accept(); return; } } } /** * This event handler, for event mouseEvent, is reimplemented to receive mouse release events for the scene. * @param mouseEvent The mouse release event object pointer */ void PianoScene::mouseReleaseEvent ( QGraphicsSceneMouseEvent * mouseEvent ) { if (d->m_mouseEnabled) { d->m_mousePressed = false; PianoKey* key = getKeyForPos(mouseEvent->scenePos()); if (key != nullptr && key->isPressed()) { keyOff(key); mouseEvent->accept(); return; } } } /** * Returns the note number for the given computer keyboard key code. * @param key The given computer keyboard key code * @return The note number */ int PianoScene::getNoteFromKey( const int key ) const { if (d->m_keybdMap != nullptr) { KeyboardMap::ConstIterator it = d->m_keybdMap->constFind(key); if ((it != d->m_keybdMap->constEnd()) && (it.key() == key)) { int note = it.value(); return note; } } return -1; } /** * Returns the piano key object corresponding to the given computer keyboard key. * @param key The given computer keyboard key * @return The Piano Key object pointer */ PianoKey* PianoScene::getPianoKey( const int key ) const { int note = getNoteFromKey(key); if (d->m_keys.contains(note)) return d->m_keys.value(note); return nullptr; } /** * This event handler, for event keyEvent, is reimplemented to receive keypress events. * @param keyEvent The computer keyboard pressed event */ void PianoScene::keyPressEvent ( QKeyEvent * keyEvent ) { if ( d->m_keyboardEnabled) { if ( !d->m_rawkbd && !keyEvent->isAutoRepeat() ) { // ignore auto-repeats int note = getNoteFromKey(keyEvent->key()); if (note > -1) keyOn(note); } keyEvent->accept(); return; } keyEvent->ignore(); } /** * This event handler, for event keyEvent, is reimplemented to receive key release events. * @param keyEvent The computer keyboard released event */ void PianoScene::keyReleaseEvent ( QKeyEvent * keyEvent ) { if (d->m_keyboardEnabled) { if ( !d->m_rawkbd && !keyEvent->isAutoRepeat() ) { // ignore auto-repeats int note = getNoteFromKey(keyEvent->key()); if (note > -1) keyOff(note); } keyEvent->accept(); return; } keyEvent->ignore(); } /** * Processes touch screen events * @param event The given event * @return true if the event was processed */ bool PianoScene::event(QEvent *event) { switch(event->type()) { case QEvent::TouchBegin: case QEvent::TouchEnd: case QEvent::TouchUpdate: { QTouchEvent *touchEvent = static_cast(event); #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) const auto touchScreen = QTouchDevice::DeviceType::TouchScreen; #else const auto touchScreen = QInputDevice::DeviceType::TouchScreen; #endif if (d->m_touchEnabled && touchEvent->device()->type() == touchScreen) { QList touchPoints = touchEvent->touchPoints(); bool hasPressure = #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) touchEvent->device()->capabilities().testFlag(QTouchDevice::Pressure); #else touchEvent->device()->capabilities().testFlag(QInputDevice::Capability::Pressure); #endif foreach(const QTouchEvent::TouchPoint& touchPoint, touchPoints) { switch (touchPoint.state()) { //case Qt::TouchPointPrimary: case Qt::TouchPointStationary: continue; case Qt::TouchPointReleased: { PianoKey* key = getKeyForPos(touchPoint.scenePos()); if (key != nullptr && key->isPressed()) { if (hasPressure) { keyOff(key, touchPoint.pressure()); } else { keyOff(key); } } break; } case Qt::TouchPointPressed: { PianoKey* key = getKeyForPos(touchPoint.scenePos()); if (key != nullptr && !key->isPressed()) { if (hasPressure) { keyOn(key, touchPoint.pressure()); } else { keyOn(key); } key->ensureVisible(); } break; } case Qt::TouchPointMoved: { PianoKey* key = getKeyForPos(touchPoint.scenePos()); PianoKey* lastkey = getKeyForPos(touchPoint.lastScenePos()); if ((lastkey != nullptr) && (lastkey != key) && lastkey->isPressed()) { if (hasPressure) { keyOff(lastkey, touchPoint.pressure()); } else { keyOff(lastkey); } } if ((key != nullptr) && !key->isPressed()) { if (hasPressure) { keyOn(key, touchPoint.pressure()); } else { keyOn(key); } } break; } default: //qDebug() << "TouchPoint state: " << touchPoint.state(); break; } } //qDebug() << "accepted event: " << event; event->accept(); return true; } break; } default: break; } //qDebug() << "unprocessed event: " << event; return QGraphicsScene::event(event); } /** * Deactivates all keys. */ void PianoScene::allKeysOff() { foreach(PianoKey* key, d->m_keys) { key->setPressed(false); } } /** * Assigns a single color for key highlight. This is an alternative to creating a * highlight palette with a single color and assigning it. * @see setHighlightPalette() * @param color Color for key highlight */ void PianoScene::setKeyPressedColor(const QColor& color) { if (color.isValid()) { d->m_hilightPalette = PianoPalette(PAL_SINGLE); d->m_hilightPalette.setColor(0, color); QBrush hilightBrush(color); for (PianoKey* key : qAsConst(d->m_keys)) { key->setPressedBrush(hilightBrush); } } } /** * Assigns the default highlight palette colors and assigns it to the scene. */ void PianoScene::resetKeyPressedColor() { d->m_hilightPalette.resetColors(); QBrush hilightBrush(getKeyPressedColor()); for (PianoKey* key : qAsConst(d->m_keys)) { key->setPressedBrush(hilightBrush); } } /** * Returns the minimum MIDI note number that will be displayed. * @return the minimum MIDI note number */ int PianoScene::getMinNote() const { return d->m_minNote; } /** * Hides or shows keys */ void PianoScene::hideOrShowKeys() { for (PianoKey* key : qAsConst(d->m_keys)) { int n = d->m_baseOctave*12 + key->getNote() + d->m_transpose; bool b = !(n > d->m_maxNote) && !(n < d->m_minNote); key->setVisible(b); } } /** * Assigns the minimum MIDI note number that will be displayed. * @param note the minimum MIDI note number */ void PianoScene::setMinNote(const int note) { if (d->m_minNote != note) { d->m_minNote = note; hideOrShowKeys(); } } /** * Returns the maximum MIDI note number that will be displayed. * @return the maximum MIDI note number */ int PianoScene::getMaxNote() const { return d->m_maxNote; } /** * Assigns the maximum MIDI note number that will be displayed. * @param note the maximum MIDI note number */ void PianoScene::setMaxNote(const int note) { if (d->m_maxNote != note) { d->m_maxNote = note; hideOrShowKeys(); } } /** * Returns the transpose amount in semitones. * @return the transpose amount in semitones */ int PianoScene::getTranspose() const { return d->m_transpose; } /** * Assigns the octave base number * @param base the octave base number */ void PianoScene::setBaseOctave(const int base) { if (d->m_baseOctave != base) { d->m_baseOctave = base; hideOrShowKeys(); refreshLabels(); } } /** * Returns the number of keys that will be displayed. * @return the number of keys */ int PianoScene::numKeys() const { return d->m_numKeys; } /** * Returns the first key number that will be displayed. * @return the first key number */ int PianoScene::startKey() const { return d->m_startKey; } /** * Returns whether the given note number is a octave startup note * @param note The given note number * @return true if the given note number is a octave startup note */ bool PianoScene::isOctaveStart(const int note) { return (note + d->m_transpose + 12) % 12 == 0; } /** * Returns the note name string that will be displayed over a given piano key. * @param key The given piano key * @return the note name string */ QString PianoScene::noteName( PianoKey* key ) { Q_ASSERT(key != nullptr); int note = key->getNote(); int num = (note + d->m_transpose + 12) % 12; int adj = ((note + d->m_transpose < 0) ? 2 : 1) - d->m_octave + 1; int oct = d->m_baseOctave + ((note + d->m_transpose) / 12) - adj; if (d->m_noteNames.isEmpty()) { QString name; if (!d->m_names_f.isEmpty() && !d->m_names_s.isEmpty()) { switch(d->m_alterations) { case ShowFlats: name = d->m_names_f.value(num); break; case ShowSharps: name = d->m_names_s.value(num); break; case ShowNothing: if (key->isBlack()) { return QString(); } name = d->m_names_s.value(num); break; default: break; } } if (d->m_octave==OctaveNothing) { return name; } else { return QString("%1%2").arg(name).arg(oct); } } else { if (d->m_noteNames.length() == 128) { int n = d->m_baseOctave*12 + note + d->m_transpose; //qDebug() << Q_FUNC_INFO << n << note; if (n >= 0 && n < d->m_noteNames.length()) { return d->m_noteNames.value(n); } } else if (d->m_noteNames.length() >= 12) { if (d->m_octave==OctaveNothing) { return d->m_noteNames.value(num); } else { return QString("%1%2").arg(d->m_noteNames.value(num)).arg(oct); } } return QString(); } } /** * Refresh the visibility and other attributes of the labels shown over the piano keys. */ void PianoScene::refreshLabels() { for (KeyLabel* lbl : qAsConst(d->m_labels)) { PianoKey* key = dynamic_cast(lbl->parentItem()); if (key != nullptr) { lbl->setVisible(false); lbl->setFont(font()); lbl->setDefaultTextColor(d->m_foregroundPalette.getColor(key->isBlack() ? 1 : 0)); lbl->setOrientation(d->m_orientation); lbl->setPlainText(noteName(key)); lbl->adjust(); lbl->setVisible((d->m_showLabels == ShowAlways) || (d->m_showLabels == ShowMinimum && isOctaveStart(key->getNote()))); } } } /** * Refresh the background colors of all the piano keys */ void PianoScene::refreshKeys() { for (PianoKey* key : qAsConst(d->m_keys)) { if (d->m_showColorScale && (d->m_backgroundPalette.paletteId() == PAL_SCALE)) { int degree = key->getNote() % 12; key->setBrush(d->m_backgroundPalette.getColor(degree)); } else { key->setBrush(d->m_backgroundPalette.getColor(key->isBlack() ? 1 : 0)); } key->setPressed(false); } } /** * Assigns the label visibility policy to the piano keys * @see LabelVisibility * @param show the new label visibility policy */ void PianoScene::setShowLabels(const LabelVisibility show) { //qDebug() << Q_FUNC_INFO << show; if (d->m_showLabels != show) { d->m_showLabels = show; refreshLabels(); } } /** * Returns the alterations name policy. * @see LabelAlteration, setAlterations() * @return the alterations name policy */ LabelAlteration PianoScene::alterations() const { return d->m_alterations; } /** * Assigns the alterations name policy * @see LabelAlteration, alterations() * @param use the new alterations name policy */ void PianoScene::setAlterations(const LabelAlteration use) { if (d->m_alterations != use) { d->m_alterations = use; refreshLabels(); } } /** * Returns the central octave name policy. * @return the central octave name policy */ LabelCentralOctave PianoScene::getOctave() const { return d->m_octave; } /** * Assigns the label orientation policy. * @param orientation the label orientation policy */ void PianoScene::setOrientation(const LabelOrientation orientation) { if (d->m_orientation != orientation) { d->m_orientation = orientation; refreshLabels(); } } bool PianoScene::isKeyboardEnabled() const { return d->m_keyboardEnabled; } void PianoScene::setOctave(const LabelCentralOctave octave) { if (d->m_octave != octave) { d->m_octave = octave; refreshLabels(); } } LabelOrientation PianoScene::getOrientation() const { return d->m_orientation; } /** * Assigns the transpose amount in semitones. * @param transpose the transpose amount in semitones */ void PianoScene::setTranspose(const int transpose) { if (d->m_transpose != transpose && transpose > -12 && transpose < 12) { d->m_transpose = transpose; hideOrShowKeys(); refreshLabels(); } } /** * Returns the label visibility policy (display note names over the piano keys). * @see LabelVisibility, setShowLabels() * @return the label visibility policy */ LabelVisibility PianoScene::showLabels() const { return d->m_showLabels; } /** * Assigns the low level computer keyboard mode. * @param b the low level computer keyboard mode */ void PianoScene::setRawKeyboardMode(bool b) { if (d->m_rawkbd != b) { d->m_rawkbd = b; } } /** * Returns the custom note names list. * @return the custom note names list */ QStringList PianoScene::customNoteNames() const { return d->m_noteNames; } /** * Returns the standard note names list. * @return the standard note names list */ QStringList PianoScene::standardNoteNames() const { return d->m_names_s; } /** * Returns the MIDI note velocity parameter that is assigned to the MIDI OUT notes. * @return the MIDI note velocity */ int PianoScene::getVelocity() { return d->m_velocity; } /** * Assigns the MIDI note velocity parameter that is assigned to the MIDI OUT notes. * @param velocity the MIDI note velocity */ void PianoScene::setVelocity(const int velocity) { d->m_velocity = velocity; } /** * Returns the MIDI channel that is assigned to the output events, or used to filter * the input events (unless MIDI OMNI mode is enabled). * @return the MIDI channel */ int PianoScene::getChannel() const { return d->m_channel; } /** * Assigns the MIDI channel that is included into the output events, or used to filter * the input events (unless MIDI OMNI mode is enabled). * @param channel the MIDI channel */ void PianoScene::setChannel(const int channel) { d->m_channel = channel; } /** * Assigns the list of custom note names, and enables this mode. * @param names the list of custom note names */ void PianoScene::useCustomNoteNames(const QStringList& names) { //qDebug() << Q_FUNC_INFO << names; d->m_noteNames = names; refreshLabels(); } /** * Assigns the standard note names, clearing the list of custom note names. */ void PianoScene::useStandardNoteNames() { //qDebug() << Q_FUNC_INFO; d->m_noteNames.clear(); refreshLabels(); } /** * Enables or disables the computer keyboard note generation. * @param enable the computer keyboard note generation */ void PianoScene::setKeyboardEnabled(const bool enable) { if (enable != d->m_keyboardEnabled) { d->m_keyboardEnabled = enable; } } /** * Returns whether the computer keyboard note generation is enabled * @return true if the computer keyboard note generation is enabled */ bool PianoScene::isMouseEnabled() const { return d->m_mouseEnabled; } /** * Enables or disables the mouse note generation. * @param enable the mouse note generation */ void PianoScene::setMouseEnabled(const bool enable) { if (enable != d->m_mouseEnabled) { d->m_mouseEnabled = enable; } } /** * Returns whether the touch screen note generation is enabled. * @return true if the touch screen note generation is enabled */ bool PianoScene::isTouchEnabled() const { return d->m_touchEnabled; } /** * Enables or disables the touch screen note generation. * @param enable the touch screen note generation */ void PianoScene::setTouchEnabled(const bool enable) { if (enable != d->m_touchEnabled) { d->m_touchEnabled = enable; } } /** * Returns whether the velocity parameter of note events is used to influence the highlight key colors. * @return whether the velocity parameter of note events is used to influence the highlight key colors */ bool PianoScene::velocityTint() const { return d->m_velocityTint; } /** * Enables or disables the velocity parameter of note events to influence the highlight key colors. * @param enable the velocity parameter of note events to influence the highlight key colors */ void PianoScene::setVelocityTint(const bool enable) { //qDebug() << Q_FUNC_INFO << enable; d->m_velocityTint = enable; } /** * Retranslates the standard note names */ void PianoScene::retranslate() { d->m_names_s = QStringList{ tr("C"), tr("C♯"), tr("D"), tr("D♯"), tr("E"), tr("F"), tr("F♯"), tr("G"), tr("G♯"), tr("A"), tr("A♯"), tr("B")}; d->m_names_f = QStringList{ tr("C"), tr("D♭"), tr("D"), tr("E♭"), tr("E"), tr("F"), tr("G♭"), tr("G"), tr("A♭"), tr("A"), tr("B♭"), tr("B")}; refreshLabels(); } /** * Enables or disables the color scale key background mode. * @param show the color scale key background mode */ void PianoScene::setShowColorScale(const bool show) { if (d->m_showColorScale != show) { d->m_showColorScale = show; refreshKeys(); invalidate(); } } /** * Returns the single highlight palette color. * @return the single highlight palette color */ QColor PianoScene::getKeyPressedColor() const { return d->m_hilightPalette.getColor(0); } /** * Assigns the active highlight palette. * @param p the active highlight palette */ void PianoScene::setHighlightPalette( const PianoPalette& p ) { if (d->m_hilightPalette != p) { d->m_hilightPalette = p; refreshKeys(); invalidate(); } } /** * Returns the background palette. * @return the background palette */ PianoPalette PianoScene::getBackgroundPalette() { return d->m_backgroundPalette; } /** * Assigns the active background palette. * @param p the active background palette */ void PianoScene::setBackgroundPalette(const PianoPalette& p ) { if (d->m_backgroundPalette != p) { d->m_backgroundPalette = p; refreshKeys(); invalidate(); } } /** * Returns the active foreground palette. * @return the active foreground palette */ PianoPalette PianoScene::getForegroundPalette() { return d->m_foregroundPalette; } /** * Assigns the active foreground palette. * @param p the foreground palette */ void PianoScene::setForegroundPalette(const PianoPalette &p) { if (d->m_foregroundPalette != p) { d->m_foregroundPalette = p; refreshLabels(); invalidate(); } } /** * Returns whether the color scale mode is enabled. * @return true if the color scale mode is enabled */ bool PianoScene::showColorScale() const { return d->m_showColorScale; } void PianoScene::setKeyPicture(const bool natural, const QPixmap &pix) { d->m_keyPix[int(natural)] = pix; for (PianoKey* key : qAsConst(d->m_keys)) { if (key->isBlack() == !natural) { key->setPixmap(pix); } } } QPixmap PianoScene::getKeyPicture(const bool natural) { return d->m_keyPix[int(natural)]; } void PianoScene::setUseKeyPictures(const bool enable) { d->m_useKeyPix = enable; for (PianoKey* key : qAsConst(d->m_keys)) { key->setUsePixmap(enable); } } bool PianoScene::getUseKeyPictures() const { return d->m_useKeyPix; } void PianoScene::saveData(QByteArray &ba) { d->saveData(ba); } void PianoScene::loadData(QByteArray &ba) { d->loadData(ba); } } // namespace widgets } // namespace drumstick drumstick-2.5.1/library/widgets/PaxHeaders.27918/sonivoxsettingsdialog.cpp0000644000000000000000000000013214200302440023544 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/sonivoxsettingsdialog.cpp0000644000175000001440000001473014200302440024332 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "sonivoxsettingsdialog.h" #include "ui_sonivoxsettingsdialog.h" #include #include /** * @file sonivoxsettingsdialog.cpp * Implementation of the Sonivox Synth configuration dialog */ namespace drumstick { namespace widgets { const QString SonivoxSettingsDialog::QSTR_PREFERENCES = QStringLiteral("SonivoxEAS"); const QString SonivoxSettingsDialog::QSTR_BUFFERTIME = QStringLiteral("BufferTime"); const QString SonivoxSettingsDialog::QSTR_REVERBTYPE = QStringLiteral("ReverbType"); const QString SonivoxSettingsDialog::QSTR_REVERBAMT = QStringLiteral("ReverbAmt"); const QString SonivoxSettingsDialog::QSTR_CHORUSTYPE = QStringLiteral("ChorusType"); const QString SonivoxSettingsDialog::QSTR_CHORUSAMT = QStringLiteral("ChorusAmt"); SonivoxSettingsDialog::SonivoxSettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::SonivoxSettingsDialog) { ui->setupUi(this); ui->combo_Reverb->addItem(QStringLiteral("Large Hall"), 0); ui->combo_Reverb->addItem(QStringLiteral("Hall"), 1); ui->combo_Reverb->addItem(QStringLiteral("Chamber"), 2); ui->combo_Reverb->addItem(QStringLiteral("Room"), 3); ui->combo_Reverb->addItem(QStringLiteral("None"), -1); ui->combo_Reverb->setCurrentIndex(4); ui->combo_Chorus->addItem(QStringLiteral("Preset 1"), 0); ui->combo_Chorus->addItem(QStringLiteral("Preset 2"), 1); ui->combo_Chorus->addItem(QStringLiteral("Preset 3"), 2); ui->combo_Chorus->addItem(QStringLiteral("Preset 4"), 3); ui->combo_Chorus->addItem(QStringLiteral("None"), -1); ui->combo_Chorus->setCurrentIndex(4); connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::pressed, this, &SonivoxSettingsDialog::restoreDefaults); drumstick::rt::BackendManager man; m_driver = man.outputBackendByName("SonivoxEAS"); //qDebug() << Q_FUNC_INFO; } SonivoxSettingsDialog::~SonivoxSettingsDialog() { //qDebug() << Q_FUNC_INFO; if (m_driver != nullptr) { m_driver->close(); } delete ui; } void SonivoxSettingsDialog::accept() { //qDebug() << Q_FUNC_INFO; writeSettings(); if (m_driver != nullptr) { QString title; QVariant varStatus = m_driver->property("status"); if (varStatus.isValid()) { title = varStatus.toBool() ? tr("Sonivox Initialized") : tr("Sonivox Initialization Failed"); QVariant varDiag = m_driver->property("diagnostics"); if (varDiag.isValid()) { QString text = varDiag.toStringList().join(QChar::LineFeed).trimmed(); if (varStatus.toBool()) { if (!text.isEmpty()) { QMessageBox::information(this, title, text); } } else { QMessageBox::critical(this, title, text); return; } } } } QDialog::accept(); } void SonivoxSettingsDialog::showEvent(QShowEvent *event) { //qDebug() << Q_FUNC_INFO; readSettings(); event->accept(); } void SonivoxSettingsDialog::readSettings() { //qDebug() << Q_FUNC_INFO; SettingsFactory settings; settings->beginGroup(QSTR_PREFERENCES); int bufferTime = settings->value(QSTR_BUFFERTIME, 30).toInt(); int reverbType = settings->value(QSTR_REVERBTYPE, 1).toInt(); int reverbAmt = settings->value(QSTR_REVERBAMT, 25800).toInt(); int chorusType = settings->value(QSTR_CHORUSTYPE, -1).toInt(); int chorusAmt = settings->value(QSTR_CHORUSAMT, 0).toInt(); settings->endGroup(); if (qEnvironmentVariableIsSet("PULSE_LATENCY_MSEC")) { bufferTime = qEnvironmentVariable("PULSE_LATENCY_MSEC").toInt(); } ui->spnTime->setValue(bufferTime); ui->dial_Reverb->setValue(reverbAmt); ui->dial_Chorus->setValue(chorusAmt); int reverbIndex = ui->combo_Reverb->findData(reverbType); int chorusIndex = ui->combo_Chorus->findData(chorusType); ui->combo_Reverb->setCurrentIndex(reverbIndex); ui->combo_Chorus->setCurrentIndex(chorusIndex); chkDriverProperties(settings.getQSettings()); } void SonivoxSettingsDialog::writeSettings() { //qDebug() << Q_FUNC_INFO; SettingsFactory settings; settings->beginGroup(QSTR_PREFERENCES); settings->setValue(QSTR_BUFFERTIME, ui->spnTime->value()); settings->setValue(QSTR_REVERBTYPE, ui->combo_Reverb->currentData()); settings->setValue(QSTR_CHORUSTYPE, ui->combo_Chorus->currentData()); settings->setValue(QSTR_REVERBAMT, ui->dial_Reverb->value()); settings->setValue(QSTR_CHORUSAMT, ui->dial_Chorus->value()); settings->endGroup(); settings->sync(); qputenv("PULSE_LATENCY_MSEC", QByteArray::number( ui->spnTime->value() )); chkDriverProperties(settings.getQSettings()); } void SonivoxSettingsDialog::chkDriverProperties(QSettings *settings) { //qDebug() << Q_FUNC_INFO; if (m_driver != nullptr) { //drumstick::rt::MIDIConnection conn; m_driver->close(); m_driver->initialize(settings); //m_driver->open(conn); } QVariant varStatus = m_driver->property("status"); if (varStatus.isValid()) { ui->lblStatusText->clear(); ui->lblStatusText->setText(varStatus.toBool() ? tr("Ready") : tr("Failed") ); ui->lblStatusIcon->setPixmap(varStatus.toBool() ? QPixmap(":/checked.png") : QPixmap(":/error.png") ); } } void SonivoxSettingsDialog::restoreDefaults() { ui->spnTime->setValue(30); ui->combo_Reverb->setCurrentIndex(1); ui->dial_Reverb->setValue(25800); ui->combo_Chorus->setCurrentIndex(4); ui->dial_Chorus->setValue(0); } } // namespace widgets } // namespace drumstick drumstick-2.5.1/library/widgets/PaxHeaders.27918/networksettingsdialog.h0000644000000000000000000000013214200302440023175 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/networksettingsdialog.h0000644000175000001440000000354114200302440023761 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef NETWORKSETTINGSDIALOG_H #define NETWORKSETTINGSDIALOG_H #include #include #include /** * @file networksettingsdialog.h * Declaration of the Network configuration dialog */ namespace drumstick { namespace widgets { namespace Ui { class NetworkSettingsDialog; } class NetworkSettingsDialog : public QDialog { Q_OBJECT public: explicit NetworkSettingsDialog(const bool forInput, QWidget *parent = nullptr); ~NetworkSettingsDialog(); void readSettings(); void writeSettings(); void chkInitialization(QSettings* settings); static const QString QSTR_ADDRESS_IPV4; static const QString QSTR_ADDRESS_IPV6; public slots: void accept() override; void showEvent(QShowEvent *event) override; void restoreDefaults(); void toggledIPv6(bool checked); private: Ui::NetworkSettingsDialog *ui; QObject *m_driver; bool m_input; }; }} // namespace drumstick::widgets #endif // NETWORKSETTINGSDIALOG_H drumstick-2.5.1/library/widgets/PaxHeaders.27918/fluidsettingsdialog.cpp0000644000000000000000000000013214200302440023142 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.877324214 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/fluidsettingsdialog.cpp0000644000175000001440000003546014200302440023733 0ustar00pedrousers00000000000000/* Drumstick MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "fluidsettingsdialog.h" #include "ui_fluidsettingsdialog.h" #include #include /** * @file fluidsettingsdialog.cpp * Implementation of the Fluidsynth configuration dialog */ namespace drumstick { namespace widgets { const QString FluidSettingsDialog::QSTR_PREFERENCES = QStringLiteral("FluidSynth"); const QString FluidSettingsDialog::QSTR_INSTRUMENTSDEFINITION = QStringLiteral("InstrumentsDefinition"); const QString FluidSettingsDialog::QSTR_DATADIR = QStringLiteral("soundfonts"); const QString FluidSettingsDialog::QSTR_DATADIR2 = QStringLiteral("sounds/sf2"); const QString FluidSettingsDialog::QSTR_SOUNDFONT = QStringLiteral("default.sf2"); const QString FluidSettingsDialog::QSTR_AUDIODRIVER = QStringLiteral("AudioDriver"); const QString FluidSettingsDialog::QSTR_PERIODSIZE = QStringLiteral("PeriodSize"); const QString FluidSettingsDialog::QSTR_PERIODS = QStringLiteral("Periods"); const QString FluidSettingsDialog::QSTR_SAMPLERATE = QStringLiteral("SampleRate"); const QString FluidSettingsDialog::QSTR_CHORUS = QStringLiteral("Chorus"); const QString FluidSettingsDialog::QSTR_REVERB = QStringLiteral("Reverb"); const QString FluidSettingsDialog::QSTR_GAIN = QStringLiteral("Gain"); const QString FluidSettingsDialog::QSTR_POLYPHONY = QStringLiteral("Polyphony"); const QString FluidSettingsDialog::QSTR_BUFFERTIME = QStringLiteral("BufferTime"); const QString FluidSettingsDialog::QSTR_PULSEAUDIO = QStringLiteral("pulseaudio"); FluidSettingsDialog::FluidSettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::FluidSettingsDialog) { ui->setupUi(this); connect(ui->audioDriver, &QComboBox::currentTextChanged, this, &FluidSettingsDialog::audioDriverChanged); connect(ui->bufferTime, QOverload::of(&QSpinBox::valueChanged), this, &FluidSettingsDialog::bufferTimeChanged); connect(ui->periodSize, QOverload::of(&QSpinBox::valueChanged), this, &FluidSettingsDialog::bufferSizeChanged); connect(ui->periods, QOverload::of(&QSpinBox::valueChanged), this, &FluidSettingsDialog::bufferSizeChanged); connect(ui->btnFile, &QToolButton::clicked, this, &FluidSettingsDialog::showFileDialog); connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, this, &FluidSettingsDialog::restoreDefaults); auto sampleRateValidator = new QDoubleValidator(8000.0, 96000.0, 1, this); sampleRateValidator->setNotation(QDoubleValidator::StandardNotation); sampleRateValidator->setLocale(QLocale::c()); ui->sampleRate->setValidator(sampleRateValidator); auto gainValidator = new QDoubleValidator(0.1, 10.0, 2, this); gainValidator->setNotation(QDoubleValidator::StandardNotation); gainValidator->setLocale(QLocale::c()); ui->gain->setValidator(gainValidator); auto polyphonyValidator = new QIntValidator(1, 65535, this); ui->polyphony->setValidator(polyphonyValidator); drumstick::rt::BackendManager man; m_driver = man.outputBackendByName("FluidSynth"); if (m_driver != nullptr) { QVariant v = m_driver->property("audiodrivers"); if (v.isValid()) { ui->audioDriver->blockSignals(true); ui->audioDriver->clear(); ui->audioDriver->addItems(v.toStringList()); ui->audioDriver->blockSignals(false); } } ui->bufferTime->blockSignals(true); ui->periodSize->blockSignals(true); ui->periods->blockSignals(true); //qDebug() << Q_FUNC_INFO; } FluidSettingsDialog::~FluidSettingsDialog() { //qDebug() << Q_FUNC_INFO; if (m_driver != nullptr) { m_driver->close(); } delete ui; } bool FluidSettingsDialog::checkRanges() const { //qDebug() << Q_FUNC_INFO; if (ui->gain->hasAcceptableInput()) { ui->gain->deselect(); } else { ui->gain->selectAll(); } if (ui->polyphony->hasAcceptableInput()) { ui->polyphony->deselect(); } else { ui->polyphony->selectAll(); } if (ui->sampleRate->hasAcceptableInput()) { ui->sampleRate->deselect(); } else { ui->sampleRate->selectAll(); } return ui->bufferTime->hasAcceptableInput() && ui->periodSize->hasAcceptableInput() && ui->periods->hasAcceptableInput() && ui->gain->hasAcceptableInput() && ui->polyphony->hasAcceptableInput() && ui->sampleRate->hasAcceptableInput(); } void FluidSettingsDialog::accept() { //qDebug() << Q_FUNC_INFO; if (checkRanges()) { writeSettings(); if (m_driver != nullptr) { QString title; QVariant varStatus = m_driver->property("status"); if (varStatus.isValid()) { title = varStatus.toBool() ? tr("FluidSynth Initialized") : tr("FluidSynth Initialization Failed"); QVariant varDiag = m_driver->property("diagnostics"); if (varDiag.isValid()) { QString text = varDiag.toStringList().join(QChar::LineFeed).trimmed(); if (varStatus.toBool()) { if (!text.isEmpty()) { QMessageBox::information(this, title, text); } } else { QMessageBox::critical(this, title, text); return; } } } } QDialog::accept(); } } void FluidSettingsDialog::showEvent(QShowEvent *event) { readSettings(); event->accept(); } QString FluidSettingsDialog::defaultAudioDriver() const { const QString QSTR_DEFAULT_AUDIODRIVER = #if defined(Q_OS_WIN) QLatin1String("wasapi"); #elif defined(Q_OS_OSX) QLatin1String("coreaudio"); #elif defined(Q_OS_LINUX) QSTR_PULSEAUDIO; #else QLatin1String("oss"); #endif return QSTR_DEFAULT_AUDIODRIVER; } void FluidSettingsDialog::chkDriverProperties(QSettings *settings) { //qDebug() << Q_FUNC_INFO; if (m_driver != nullptr) { drumstick::rt::MIDIConnection conn; m_driver->close(); m_driver->initialize(settings); m_driver->open(conn); QVariant drivers = m_driver->property("audiodrivers"); if (drivers.isValid()) { auto text = ui->audioDriver->currentText(); ui->audioDriver->blockSignals(true); ui->audioDriver->clear(); ui->audioDriver->addItems(drivers.toStringList()); ui->audioDriver->setCurrentText(text); ui->audioDriver->blockSignals(false); } QVariant varVersion = m_driver->property("libversion"); if (varVersion.isValid()) { ui->lblVersion->clear(); ui->lblVersion->setText(varVersion.toString()); } QVariant varStatus = m_driver->property("status"); if (varStatus.isValid()) { ui->lblStatus->clear(); ui->lblStatus->setText(varStatus.toBool() ? tr("Ready") : tr("Failed") ); ui->lblStatusIcon->setPixmap(varStatus.toBool() ? QPixmap(":/checked.png") : QPixmap(":/error.png") ); } } } void drumstick::widgets::FluidSettingsDialog::initBuffer() { if (ui->audioDriver->currentText() == QSTR_PULSEAUDIO) { //qDebug() << Q_FUNC_INFO << QSTR_PULSEAUDIO; int bufferTime = ui->bufferTime->value(); int minBufTime = ui->bufferTime->minimum(); if (qEnvironmentVariableIsSet("PULSE_LATENCY_MSEC")) { bufferTime = qEnvironmentVariable("PULSE_LATENCY_MSEC").toInt(); } if (bufferTime < minBufTime) { bufferTime = minBufTime; } ui->bufferTime->setValue( bufferTime ); bufferTimeChanged( bufferTime ); } else { //qDebug() << Q_FUNC_INFO; bufferSizeChanged(); } } void FluidSettingsDialog::readSettings() { //qDebug() << Q_FUNC_INFO; SettingsFactory settings; QString fs_defSoundFont = QSTR_SOUNDFONT; QDir dir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR, QStandardPaths::LocateDirectory)); if (!dir.exists()) { dir = QDir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR2, QStandardPaths::LocateDirectory)); } QFileInfo sf2(dir, QSTR_SOUNDFONT); if (sf2.exists()) { fs_defSoundFont = sf2.absoluteFilePath(); } settings->beginGroup(QSTR_PREFERENCES); ui->audioDriver->setCurrentText( settings->value(QSTR_AUDIODRIVER, defaultAudioDriver()).toString() ); ui->bufferTime->setValue( settings->value(QSTR_BUFFERTIME, DEFAULT_BUFFERTIME).toInt() ); ui->periodSize->setValue( settings->value(QSTR_PERIODSIZE, DEFAULT_PERIODSIZE).toInt() ); ui->periods->setValue( settings->value(QSTR_PERIODS, DEFAULT_PERIODS).toInt() ); ui->sampleRate->setText( settings->value(QSTR_SAMPLERATE, DEFAULT_SAMPLERATE).toString() ); ui->chorus->setChecked( settings->value(QSTR_CHORUS, DEFAULT_CHORUS).toInt() != 0 ); ui->reverb->setChecked( settings->value(QSTR_REVERB, DEFAULT_REVERB).toInt() != 0 ); ui->gain->setText( settings->value(QSTR_GAIN, DEFAULT_GAIN).toString() ); ui->polyphony->setText( settings->value(QSTR_POLYPHONY, DEFAULT_POLYPHONY).toString() ); ui->soundFont->setText( settings->value(QSTR_INSTRUMENTSDEFINITION, fs_defSoundFont).toString() ); settings->endGroup(); audioDriverChanged( ui->audioDriver->currentText() ); chkDriverProperties(settings.getQSettings()); } void FluidSettingsDialog::writeSettings() { //qDebug() << Q_FUNC_INFO; SettingsFactory settings; QString audioDriver; QString soundFont(QSTR_SOUNDFONT); int bufferTime(DEFAULT_BUFFERTIME); int periodSize(DEFAULT_PERIODSIZE); int periods(DEFAULT_PERIODS); double sampleRate(DEFAULT_SAMPLERATE); int chorus(DEFAULT_CHORUS); int reverb(DEFAULT_REVERB); double gain(DEFAULT_GAIN); int polyphony(DEFAULT_POLYPHONY); audioDriver = ui->audioDriver->currentText(); if (audioDriver.isEmpty()) { audioDriver = defaultAudioDriver(); } soundFont = ui->soundFont->text(); bufferTime = ui->bufferTime->value(); periodSize = ui->periodSize->value(); periods = ui->periods->value(); sampleRate = ui->sampleRate->text().toDouble(); chorus = (ui->chorus->isChecked() ? 1 : 0); reverb = (ui->reverb->isChecked() ? 1 : 0); gain = ui->gain->text().toDouble(); polyphony = ui->polyphony->text().toInt(); settings->beginGroup(QSTR_PREFERENCES); settings->setValue(QSTR_INSTRUMENTSDEFINITION, soundFont); settings->setValue(QSTR_AUDIODRIVER, audioDriver); settings->setValue(QSTR_BUFFERTIME, bufferTime); settings->setValue(QSTR_PERIODSIZE, periodSize); settings->setValue(QSTR_PERIODS, periods); settings->setValue(QSTR_SAMPLERATE, sampleRate); settings->setValue(QSTR_CHORUS, chorus); settings->setValue(QSTR_REVERB, reverb); settings->setValue(QSTR_GAIN, gain); settings->setValue(QSTR_POLYPHONY, polyphony); settings->endGroup(); settings->sync(); if ( audioDriver == QSTR_PULSEAUDIO ) { qputenv("PULSE_LATENCY_MSEC", QByteArray::number( bufferTime ) ); } chkDriverProperties(settings.getQSettings()); } void FluidSettingsDialog::restoreDefaults() { //qDebug() << Q_FUNC_INFO; ui->audioDriver->setCurrentText( defaultAudioDriver() ); ui->bufferTime->setValue( DEFAULT_BUFFERTIME ); ui->periodSize->setValue( DEFAULT_PERIODSIZE ); ui->periods->setValue( DEFAULT_PERIODS ); ui->sampleRate->setText( QString::number( DEFAULT_SAMPLERATE )); ui->chorus->setChecked( DEFAULT_CHORUS != 0 ); ui->reverb->setChecked( DEFAULT_REVERB != 0 ); ui->gain->setText( QString::number( DEFAULT_GAIN ) ); ui->polyphony->setText( QString::number( DEFAULT_POLYPHONY )); ui->soundFont->setText( QSTR_SOUNDFONT ); initBuffer(); } void FluidSettingsDialog::showFileDialog() { QDir dir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR, QStandardPaths::LocateDirectory)); if (!dir.exists()) { dir = QDir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR2, QStandardPaths::LocateDirectory)); } QString fileName = QFileDialog::getOpenFileName(this, tr("Select SoundFont"), dir.absolutePath(), tr("SoundFont Files (*.sf2 *.sf3 *.dls)")); if (!fileName.isEmpty()) { ui->soundFont->setText(fileName); } } void FluidSettingsDialog::audioDriverChanged(const QString &text) { //qDebug() << Q_FUNC_INFO << text; if (text == QSTR_PULSEAUDIO) { ui->bufferTime->setDisabled(false); ui->bufferTime->blockSignals(false); ui->periodSize->setDisabled(true); ui->periodSize->blockSignals(true); ui->periods->setDisabled(true); ui->periods->blockSignals(true); } else { ui->bufferTime->setDisabled(true); ui->bufferTime->blockSignals(true); ui->periodSize->setDisabled(false); ui->periodSize->blockSignals(false); ui->periods->setDisabled(false); ui->periods->blockSignals(false); } initBuffer(); } void FluidSettingsDialog::bufferTimeChanged(int value) { double rate = ui->sampleRate->text().toDouble(); int size = qRound( value * rate / 1000.0 ); ui->periodSize->setValue( size ); ui->periods->setValue( ui->periods->minimum() ); //qDebug() << Q_FUNC_INFO << "time:" << value << "rate:" << rate << "size:" << size; } void FluidSettingsDialog::bufferSizeChanged() { QString audioDriver = ui->audioDriver->currentText(); double rate = ui->sampleRate->text().toDouble(); int size = ui->periodSize->value(); if (audioDriver != QSTR_PULSEAUDIO) { size *= ui->periods->value(); } int ms = qRound( 1000.0 * size / rate ); ui->bufferTime->setValue(ms); //qDebug() << Q_FUNC_INFO << "time:" << ms << "rate:" << rate << "size:" << size; } void FluidSettingsDialog::changeSoundFont(const QString& fileName) { readSettings(); ui->soundFont->setText(fileName); writeSettings(); } } // namespace widgets } // namespace drumstick drumstick-2.5.1/library/widgets/PaxHeaders.27918/macsynthsettingsdialog.cpp0000644000000000000000000000013214200302440023665 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.881324217 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/macsynthsettingsdialog.cpp0000644000175000001440000001222514200302440024450 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "macsynthsettingsdialog.h" #include "ui_macsynthsettingsdialog.h" #include #include /** * @file macsynthsettingsdialog.cpp * Implementation of the Mac Synth configuration dialog */ namespace drumstick { namespace widgets { MacSynthSettingsDialog::MacSynthSettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::MacSynthSettingsDialog) { ui->setupUi(this); connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::pressed, this, &MacSynthSettingsDialog::restoreDefaults); connect(ui->btn_soundfont, &QToolButton::pressed, this, &MacSynthSettingsDialog::showFileDialog); SettingsFactory settings; drumstick::rt::BackendManager man; m_driver = man.outputBackendByName("DLS Synth"); if (m_driver != nullptr) { checkDriver(settings.getQSettings()); } } MacSynthSettingsDialog::~MacSynthSettingsDialog() { if (m_driver != nullptr) { m_driver->close(); } delete ui; } void MacSynthSettingsDialog::accept() { writeSettings(); if (m_driver != nullptr) { QString title; QVariant varStatus = m_driver->property("status"); if (varStatus.isValid()) { title = varStatus.toBool() ? tr("DLS Synth Initialized") : tr("DLS Synth Initialization Failed"); QVariant varDiag = m_driver->property("diagnostics"); if (varDiag.isValid()) { QString text = varDiag.toStringList().join(QChar::LineFeed).trimmed(); if (varStatus.toBool()) { if (!text.isEmpty()) { QMessageBox::information(this, title, text); } } else { QMessageBox::critical(this, title, text); return; } } } } QDialog::accept(); } void MacSynthSettingsDialog::showEvent(QShowEvent *event) { readSettings(); event->accept(); } void MacSynthSettingsDialog::readSettings() { SettingsFactory settings; settings->beginGroup("DLS Synth"); bool reverb = settings->value("reverb_dls", true).toBool(); bool def = settings->value("default_dls", true).toBool(); QString soundfont = settings->value("soundfont_dls").toString(); settings->endGroup(); ui->reverb_dls->setChecked(reverb); ui->default_dls->setChecked(def); ui->soundfont_dls->setText(soundfont); } void drumstick::widgets::MacSynthSettingsDialog::checkDriver(QSettings* settings) { if (m_driver != nullptr) { m_driver->close(); m_driver->initialize(settings); drumstick::rt::MIDIConnection conn; m_driver->open(conn); QVariant varStatus = m_driver->property("status"); if (varStatus.isValid()) { ui->lblStatusText->clear(); ui->lblStatusText->setText(varStatus.toBool() ? tr("Ready") : tr("Failed") ); ui->lblStatusIcon->setPixmap(varStatus.toBool() ? QPixmap(":/checked.png") : QPixmap(":/error.png") ); } } } void MacSynthSettingsDialog::writeSettings() { SettingsFactory settings; QString soundfont = ui->soundfont_dls->text(); bool reverb = ui->reverb_dls->isChecked(); bool def = ui->default_dls->isChecked(); settings->beginGroup("DLS Synth"); settings->setValue("soundfont_dls", soundfont); settings->setValue("reverb_dls", reverb); settings->setValue("default_dls", def); settings->endGroup(); settings->sync(); checkDriver(settings.getQSettings()); } void MacSynthSettingsDialog::restoreDefaults() { ui->reverb_dls->setChecked(false); ui->default_dls->setChecked(true); ui->soundfont_dls->clear(); } void MacSynthSettingsDialog::changeSoundFont(const QString& fileName) { readSettings(); ui->soundfont_dls->setText(fileName); writeSettings(); } void MacSynthSettingsDialog::showFileDialog() { QDir dir = (QDir::homePath() + "/Library/Audio/Sounds/Banks/"); QString fileName = QFileDialog::getOpenFileName(this, tr("Select SoundFont"), dir.absolutePath(), tr("SoundFont Files (*.sf2 *.dls)")); if (!fileName.isEmpty()) { ui->soundfont_dls->setText(fileName); } } } // namespace widgets } // namespace drumstick drumstick-2.5.1/library/widgets/PaxHeaders.27918/pianoscene.h0000644000000000000000000000013214200302440020667 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.881324217 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/pianoscene.h0000644000175000001440000001573714200302440021465 0ustar00pedrousers00000000000000/* Virtual Piano Widget for Qt5 Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #ifndef PIANOSCENE_H_ #define PIANOSCENE_H_ #include #include #include #include #include #include "pianokey.h" #include "keylabel.h" /** * @file pianoscene.h * PianoScene class declaration */ namespace drumstick { namespace widgets { /** * @addtogroup Widgets * @{ * * @class PianoScene * The PianoScene class is a QGraphicsScene composed by a number of graphics items: * the piano keys. */ class DRUMSTICK_EXPORT PianoScene : public QGraphicsScene { Q_OBJECT public: PianoScene ( const int baseOctave, const int numKeys, const int startKey, const QColor& keyPressedColor = QColor(), QObject * parent = nullptr ); ~PianoScene(); QSize sizeHint() const; void setKeyboardMap( KeyboardMap *map ); KeyboardMap *getKeyboardMap() const; PianoHandler *getPianoHandler() const; void setPianoHandler(PianoHandler *handler); PianoPalette getHighlightPalette(); void setHighlightPalette( const PianoPalette& p ); PianoPalette getBackgroundPalette(); void setBackgroundPalette( const PianoPalette& p ); PianoPalette getForegroundPalette(); void setForegroundPalette( const PianoPalette& p ); bool showColorScale() const; void setShowColorScale(const bool show); QColor getKeyPressedColor() const; void setKeyPressedColor(const QColor& color); void resetKeyPressedColor(); int getMinNote() const; void setMinNote(const int note); int getMaxNote() const; void setMaxNote(const int note); int getTranspose() const; void setTranspose(const int transpose); LabelVisibility showLabels() const; void setShowLabels(const LabelVisibility show); LabelAlteration alterations() const; void setAlterations(const LabelAlteration use); LabelCentralOctave getOctave() const; void setOctave(const LabelCentralOctave octave); LabelOrientation getOrientation() const; void setOrientation(const LabelOrientation orientation); bool isKeyboardEnabled() const; void setKeyboardEnabled( const bool enable ); bool isMouseEnabled() const; void setMouseEnabled( const bool enable ); bool isTouchEnabled() const; void setTouchEnabled( const bool enable ); bool velocityTint() const; void setVelocityTint( const bool enable ); bool isOctaveStart( const int note ); void showNoteOn( const int note, QColor color, int vel = -1 ); void showNoteOn( const int note, int vel = -1 ); void showNoteOff( const int note, int vel = -1 ); int baseOctave() const; void setBaseOctave( const int base ); int numKeys() const; int startKey() const; void allKeysOff(); void keyOn( const int note ); void keyOff( const int note ); bool getRawKeyboardMode() const; void setRawKeyboardMode(const bool b); void useCustomNoteNames(const QStringList& names); void useStandardNoteNames(); QStringList customNoteNames() const; QStringList standardNoteNames() const; int getVelocity(); void setVelocity(const int velocity); int getChannel() const; void setChannel(const int channel); void retranslate(); void refreshLabels(); void hideOrShowKeys(); void refreshKeys(); void setKeyPicture(const bool natural, const QPixmap& pix); QPixmap getKeyPicture(const bool natural); void setUseKeyPictures(const bool enable); bool getUseKeyPictures() const; void saveData(QByteArray& ba); void loadData(QByteArray& ba); signals: /** * This signal is emitted for each Note On MIDI event created using * the computer keyboard, mouse or touch screen. It is not emitted if * a PianoHandler has been assigned using setPianoHandler(). * @param n the MIDI note number * @param v the MIDI velocity */ void noteOn(int n, int v); /** * This signal is emitted for each Note Off MIDI event created using * the computer keyboard, mouse or touch screen. It is not emitted if * a PianoHandler has been assigned using setPianoHandler(). * @param n the MIDI note number * @param v the MIDI velocity */ void noteOff(int n, int v); /** * signalName is emitted for each note created, and contains a string * with the MIDI note number and the note name for each note on event. * @param name the MIDI note number and name */ void signalName(const QString& name); protected: void showKeyOn( PianoKey *key, QColor color, int vel ); void showKeyOn( PianoKey *key, int vel ); void showKeyOff( PianoKey *key, int vel ); void displayKeyOn(PianoKey *key); void keyOn( PianoKey *key ); void keyOff( PianoKey *key ); void keyOn( PianoKey *key, qreal pressure ); void keyOff( PianoKey *key, qreal pressure ); PianoKey *getKeyForPos( const QPointF &p ) const; PianoKey *getPianoKey( const int key ) const; QString noteName( PianoKey *key ); void mouseMoveEvent ( QGraphicsSceneMouseEvent *mouseEvent ) override; void mousePressEvent ( QGraphicsSceneMouseEvent *mouseEvent ) override; void mouseReleaseEvent ( QGraphicsSceneMouseEvent *mouseEvent ) override; void keyPressEvent ( QKeyEvent *keyEvent ) override; void keyReleaseEvent ( QKeyEvent *keyEvent ) override; bool event(QEvent *event) override; void triggerNoteOn( const int note, const int vel ); void triggerNoteOff( const int note, const int vel ); int getNoteFromKey( const int key ) const; void setHighlightColorFromPolicy(PianoKey *key, const int vel); private: class PianoScenePrivate; QScopedPointer d; }; /** @} */ }} // namespace drumstick::widgets #endif /*PIANOSCENE_H_*/ drumstick-2.5.1/library/widgets/PaxHeaders.27918/translations0000644000000000000000000000013214200302440021036 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/0000755000175000001440000000000014200302440021674 5ustar00pedrousers00000000000000drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_zh_CN.ts0000644000000000000000000000013214200302440026215 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_zh_CN.ts0000644000175000001440000005605714200302440027013 0ustar00pedrousers00000000000000 PianoPalette N # 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 C C C# D D D# E E F F F# G G G# A A A# B B N* #* Single color highlight A single color to highlight all note events Two colors highlight One color to highlight natural notes and a different one for accidentals MIDI Channels highlight A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Chromatic scale background One color for each note in the chromatic scale Keys background One color for natural notes and another for accidentals Font foreground Colors for note names Chromatic scale highlight drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Sample Rate: Period Size: # of Periods: Audio Driver: Polyphony: FluidSynth Version: Sound Font: Initialization Status: Buffer Time: ms Gain: ... ... Chorus Reverb FluidSynth Initialized FluidSynth Initialization Failed Ready Failed Select SoundFont SoundFont Files (*.sf2 *.sf3 *.dls) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings SoundFont: ... ... Use Internal Reverb Init. Status: Default Apple DLS Sound Set DLS Synth Initialized DLS Synth Initialization Failed Ready Failed Select SoundFont SoundFont Files (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Init. Status: Use IPv6 Network Interface: Address Network Initialized Network Initialization Failed Any Ready Failed drumstick::widgets::PianoScene C C C♯ C♯ D D D♯ D♯ E E F F F♯ F♯ G G G♯ G♯ A A A♯ A♯ B B D♭ D♭ E♭ E♭ G♭ G♭ A♭ A♭ B♭ B♭ drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Chorus Reverb Buffer Time: ms Init. Status: Sonivox Initialized Sonivox Initialization Failed Ready Failed drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_sv.ts0000644000000000000000000000013214200302440025644 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_sv.ts0000644000175000001440000005754214200302440026442 0ustar00pedrousers00000000000000 PianoPalette N N # # 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 C C C# Ciss D D D# Diss E E F F F# Fiss G G G# Giss A A A# Aiss B H N* N* #* #* Single color highlight Enfärgsmarkering A single color to highlight all note events En färg för att markera alla tonhändelser Two colors highlight Tvåfärgsmarkering One color to highlight natural notes and a different one for accidentals En färg för att markera stamtoner och en annan för grentoner MIDI Channels highlight MIDI-kanalmarkering A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Olika färger för att markera varje MIDI-kanal. Aktivera omniläget i MIDI-IN-anslutningen. Chromatic scale background Bakgrund för kromatisk skala One color for each note in the chromatic scale En färg för varje ton i den kromatiska skalan Keys background Tangentbakgrund One color for natural notes and another for accidentals En färg för stamtoner och en annan för grentoner. Font foreground Typsnittsförgrund Colors for note names Färger för tonnamn Chromatic scale highlight Markering för kromatisk skala drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Drivrutinsinställningar för FluidSynth Sample Rate: Samplingsfrekvens: Period Size: Periodstorlek: # of Periods: Antal perioder: Audio Driver: Ljuddrivrutin: Polyphony: Polyfoni: FluidSynth Version: FluidSynth-version: Sound Font: Ljudfont: Initialization Status: Initialiseringsstatus: Buffer Time: Buffringstid: ms ms Gain: Volym: ... ... Chorus Korus Reverb Eko FluidSynth Initialized FluidSynth initialiserad FluidSynth Initialization Failed FluidSynth-initialiseringen misslyckades Ready Redo Failed Misslyckades Select SoundFont Välj ljudfont SoundFont Files (*.sf2 *.sf3 *.dls) SoundFont Files (*.sf2) SoundFont-filer (*.sf2) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings Syntdrivrutinsinställningar för macOS SoundFont: Ljudfont: ... ... Use Internal Reverb Använd internt eko Init. Status: Initialiseringsstatus: Default Apple DLS Sound Set Förvald Apple DLS ljuduppsättning DLS Synth Initialized DLS-synt initialiserad DLS Synth Initialization Failed DLS-syntinitialiseringen misslyckades Ready Redo Failed Misslyckades Select SoundFont Välj ljudfont SoundFont Files (*.sf2 *.dls) SoundFont-filer (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Drivrutinsinställningar för nätverk Init. Status: Initialiseringsstatus: Use IPv6 Network Interface: Nätverksgränssnitt: Address Adress Network Initialized Nätverk initialiserat Network Initialization Failed Nätverksinitialiseringen misslyckades Any Någon Ready Redo Failed Misslyckades drumstick::widgets::PianoScene C C C♯ Ciss D D D♯ Diss E E F F F♯ Fiss G G G♯ Giss A A A♯ Aiss B H D♭ Dess E♭ Ess G♭ Gess A♭ Ass B♭ B drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Sonivox EAS Synt Chorus Korus Reverb Eko Buffer Time: Buffringstid: ms ms Init. Status: Initialiseringsstatus: Sonivox Initialized Sonivox initialiserad Sonivox Initialization Failed Sonivoxinitialisering misslyckades Ready Redo Failed Misslyckades drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_en.ts0000644000000000000000000000013214200302440025616 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_en.ts0000644000175000001440000006053014200302440026403 0ustar00pedrousers00000000000000 PianoPalette N # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 C C# D D# E F F# G G# A A# B N* #* Single color highlight A single color to highlight all note events Two colors highlight One color to highlight natural notes and a different one for accidentals MIDI Channels highlight A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Chromatic scale background One color for each note in the chromatic scale Keys background One color for natural notes and another for accidentals Font foreground Colors for note names Chromatic scale highlight drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Sample Rate: Period Size: # of Periods: Audio Driver: Polyphony: FluidSynth Version: Sound Font: Initialization Status: Buffer Time: ms Gain: ... Chorus Reverb FluidSynth Initialized FluidSynth Initialization Failed Ready Failed Select SoundFont SoundFont Files (*.sf2 *.sf3 *.dls) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings SoundFont: ... Use Internal Reverb Init. Status: Default Apple DLS Sound Set DLS Synth Initialized DLS Synth Initialization Failed Ready Failed Select SoundFont SoundFont Files (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Init. Status: Use IPv6 Network Interface: Address Network Initialized Network Initialization Failed Any Ready Failed drumstick::widgets::PianoScene C C♯ D D♯ E F F♯ G G♯ A A♯ B D♭ E♭ G♭ A♭ B♭ drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Chorus Reverb Buffer Time: ms Init. Status: Sonivox Initialized Sonivox Initialization Failed Ready Failed drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_it.ts0000644000000000000000000000013214200302440025630 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_it.ts0000644000175000001440000005765614200302440026434 0ustar00pedrousers00000000000000 PianoPalette N # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 C do C# do# D re D# re# E me F fa F# fa# G sol G# sol# A la A# la# B si N* #* Single color highlight A single color to highlight all note events Two colors highlight One color to highlight natural notes and a different one for accidentals MIDI Channels highlight A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Chromatic scale background One color for each note in the chromatic scale Keys background One color for natural notes and another for accidentals Font foreground Colors for note names Chromatic scale highlight drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Sample Rate: Period Size: # of Periods: Audio Driver: Polyphony: FluidSynth Version: Sound Font: Initialization Status: Buffer Time: ms Gain: ... Chorus Reverb FluidSynth Initialized FluidSynth Initialization Failed Ready Failed Select SoundFont SoundFont Files (*.sf2 *.sf3 *.dls) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings SoundFont: ... Use Internal Reverb Init. Status: Default Apple DLS Sound Set DLS Synth Initialized DLS Synth Initialization Failed Ready Failed Select SoundFont SoundFont Files (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Init. Status: Use IPv6 Network Interface: Address Network Initialized Network Initialization Failed Any Ready Failed drumstick::widgets::PianoScene C do C♯ do♯ D re D♯ re♯ E mi F fa F♯ fa♯ G sol G♯ sol♯ A la A♯ la♯ B si D♭ re♭ E♭ mim♭ G♭ sol♭ A♭ la♭ B♭ si♭ drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Chorus Reverb Buffer Time: ms Init. Status: Sonivox Initialized Sonivox Initialization Failed Ready Failed drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_ru.ts0000644000000000000000000000013214200302440025642 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_ru.ts0000644000175000001440000006117414200302440026434 0ustar00pedrousers00000000000000 PianoPalette N N # # 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 C До C# До # D Ре D# Ре # E Ми F Фа F# Фа # G Соль G# Соль # A Ля A# Ля # B Си N* N* #* #* Single color highlight Подсветка одним цветом A single color to highlight all note events Один цвет для подсветки всех событий нот Two colors highlight Подсветка двумя цветами One color to highlight natural notes and a different one for accidentals Один цвет подсвечивает натуральные ноты, второй акцентированные MIDI Channels highlight Подсветка каналов MIDI A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Разные цвета подсветки каждого канала MIDI. Включить режим Omni в соединении MIDI IN Chromatic scale background Хроматический фон One color for each note in the chromatic scale Один цвет для каждой ноты по хроматической шкале Keys background Фон клавиш One color for natural notes and another for accidentals Один цвет для натуральных нот и один для акцентированных Font foreground Цвет шрифта Colors for note names Цвета для названий нот Chromatic scale highlight Подсветка хроматической шкалой drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Настройки драйвера FluidSynth Sample Rate: Скорость сэмплов: Period Size: Размер периода: # of Periods: Число периодов: Audio Driver: Аудиодрайвер: Polyphony: Полифония: FluidSynth Version: Sound Font: Sound Font: Initialization Status: Buffer Time: Время буфера: ms мс Gain: Усиление: ... ... Chorus Хорус Reverb Реверберация FluidSynth Initialized FluidSynth Initialization Failed Ready Failed Select SoundFont Выбрать SoundFont SoundFont Files (*.sf2 *.sf3 *.dls) SoundFont Files (*.sf2) Файлы SoundFont (*.sf2) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings Настройки драйвера macOS Synth SoundFont: SoundFont: ... ... Use Internal Reverb Использовать встроенную реверберацию Init. Status: Default Apple DLS Sound Set Набор звуков Apple DLS по умолчанию DLS Synth Initialized DLS Synth Initialization Failed Ready Failed Select SoundFont Выбор SoundFont SoundFont Files (*.sf2 *.dls) Файлы SoundFont (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Настройки драйвера сети Init. Status: Use IPv6 Использовать IPv6 Network Interface: Сетевой интерфейс: Address Адрес Network Initialized Network Initialization Failed Any Любой Ready Failed drumstick::widgets::PianoScene C До C♯ До♯ D Ре D♯ Ре♯ E Ми F Фа F♯ Фа♯ G Соль G♯ Соль♯ A Ля A♯ Ля♯ B Си D♭ Ре♭ E♭ Ми♭ G♭ Соль♭ A♭ Ля♭ B♭ Си♭ drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Sonivox EAS Synth Chorus Хорус Reverb Реверберация Buffer Time: Время буфера: ms мс Init. Status: Sonivox Initialized Sonivox Initialization Failed Ready Failed drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_tr.ts0000644000000000000000000000013214200302440025641 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_tr.ts0000644000175000001440000005576314200302440026442 0ustar00pedrousers00000000000000 PianoPalette N # 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 C C# D D# E F F# G G# A A# B N* #* Single color highlight A single color to highlight all note events Two colors highlight One color to highlight natural notes and a different one for accidentals MIDI Channels highlight A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Chromatic scale background One color for each note in the chromatic scale Keys background One color for natural notes and another for accidentals Font foreground Colors for note names Chromatic scale highlight drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Sample Rate: Period Size: # of Periods: Audio Driver: Polyphony: FluidSynth Version: Sound Font: Initialization Status: Buffer Time: ms Gain: ... Chorus Reverb FluidSynth Initialized FluidSynth Initialization Failed Ready Failed Select SoundFont SoundFont Files (*.sf2 *.sf3 *.dls) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings SoundFont: ... Use Internal Reverb Init. Status: Default Apple DLS Sound Set DLS Synth Initialized DLS Synth Initialization Failed Ready Failed Select SoundFont SoundFont Files (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Init. Status: Use IPv6 Network Interface: Address Network Initialized Network Initialization Failed Any Ready Failed drumstick::widgets::PianoScene C C♯ D D♯ E F F♯ G G♯ A A♯ B D♭ E♭ G♭ A♭ B♭ drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Chorus Reverb Buffer Time: ms Init. Status: Sonivox Initialized Sonivox Initialization Failed Ready Failed drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_gl.ts0000644000000000000000000000013214200302440025616 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_gl.ts0000644000175000001440000005777214200302440026421 0ustar00pedrousers00000000000000 PianoPalette N N # # 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 C Do C# Do# D Re D# Re# E Mi F Fa F# Fa# G Sol G# Sol# A La A# La# B Si N* N* #* #* Single color highlight Salientar unha soa cor A single color to highlight all note events Unha única cor para resaltar todas as accións das notas Two colors highlight Salientar dúas cores One color to highlight natural notes and a different one for accidentals Unha cor para resaltar as notas naturais e outro diferente para as alteracións MIDI Channels highlight Salientar canles MIDI A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Unha cor diferente para resaltar cada canle MIDI. Activa o modo Omni na conexión MIDI IN Chromatic scale background Escala cromática de fondo One color for each note in the chromatic scale Unha cor para cada nota da escala cromática Keys background Fondo das teclas One color for natural notes and another for accidentals Unha cor para as notas naturais e outro diferente para as alteracións Font foreground Cor do texto Colors for note names Cores para nomes de notas Chromatic scale highlight Salientar escala cromática drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Axustes do controlador FluidSynth Sample Rate: Frecuencia de mostraxe: Period Size: Tamaña dos período: # of Periods: Núm. de períodos: Audio Driver: Controlador de son: Polyphony: Polifonía: FluidSynth Version: Versión de FluidSynth: Sound Font: Son fonte: Initialization Status: Estado de inicialización: Buffer Time: Tempo de buffer: ms ms Gain: Ganancia: ... ... Chorus Coros Reverb Reverberación FluidSynth Initialized FluidSynth Inicializado FluidSynth Initialization Failed Inicialización fallida de FluidSynth Ready Listo Failed Fallou Select SoundFont Seleccione SoundFont SoundFont Files (*.sf2 *.sf3 *.dls) SoundFont Files (*.sf2) Ficheiros SoundFont (*.sf2) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings Axustes do controlador de sintetizador de macOS SoundFont: SoundFont: ... ... Use Internal Reverb Usar a reverberación interna Init. Status: Estado de inicialización: Default Apple DLS Sound Set Sonidos DLS predeterminados de Apple DLS Synth Initialized DLS Synth Iniciado DLS Synth Initialization Failed Fallou a inicialización do DLS Synth Ready Listo Failed Fallou Select SoundFont Seleccione SoundFont SoundFont Files (*.sf2 *.dls) Ficheiros SoundFont (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Axustes do controlador de rede Init. Status: Estado de inicialización: Use IPv6 Usar IPv6 Network Interface: Interface de rede: Address Enderezo Network Initialized Rede inicializada Network Initialization Failed Fallou a inicialización da rede Any Calquera Ready Listo Failed Fallou drumstick::widgets::PianoScene C Do C♯ Do♯ D Re D♯ Re♯ E Mi F Fa F♯ Fa♯ G Sol G♯ Sol♯ A La A♯ La♯ B Si D♭ Re♭ E♭ Mi♭ G♭ Sol♭ A♭ La♭ B♭ Si♭ drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Sintetizador Sonivox EAS Chorus Coros Reverb Reverberación Buffer Time: Tempo de buffer: ms ms Init. Status: Estado de inicialización: Sonivox Initialized Sonivox inicializado Sonivox Initialization Failed Fallou a inicialización de Sonivox Ready Listo Failed Fallou drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_es.ts0000644000000000000000000000013214200302440025623 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_es.ts0000644000175000001440000006014314200302440026410 0ustar00pedrousers00000000000000 PianoPalette N N # # 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 C do C# do# D re D# re# E mi F fa F# fa# G sol G# sol# A la A# la# B si N* N* #* #* Single color highlight Color único de resaltado A single color to highlight all note events Un único color para resaltar todos los eventos de notas Two colors highlight Dos colores de resaltado One color to highlight natural notes and a different one for accidentals Un color para resaltar las notas naturales y otro diferente para las alteraciones MIDI Channels highlight Resaltado por Canales MIDI A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Un color diferente para resaltar cada canal MIDI. Habilitar modo Omni en la conexión MIDI IN Chromatic scale background Escala cromática (fondode teclas) One color for each note in the chromatic scale Un color para cada nota de la escala cromática Keys background Fondo de teclas One color for natural notes and another for accidentals Un color para las notas naturales y otro para las accidentales Font foreground Primer plano de fuente Colors for note names Colores para los nombres de notas Chromatic scale highlight Escala cromática (resaltado) drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Opciones del controlador de FluidSynth Sample Rate: Frecuencia de muestreo: Period Size: Tamaño del periodo: # of Periods: Número de periodos: Audio Driver: Controlador de audio: Polyphony: Polifonía: FluidSynth Version: Versión de Fluidsynth: Sound Font: SoundFont: Initialization Status: Estado de inicialización: Buffer Time: Tiempo de buffer: ms ms Gain: Ganancia: ... ... Chorus Coral Reverb Reverberación FluidSynth Initialized FluidSynth inicializado FluidSynth Initialization Failed Inicialización fallida de FluidSynth Ready Listo Failed Fallido Select SoundFont Seleccionar SoundFont SoundFont Files (*.sf2 *.sf3 *.dls) Archivos SoundFont (*.sf2 *.sf3 *.dls) SoundFont Files (*.sf2) Archivos SoundFont (*.sf2) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings Opciones del controlador del sintetizador de macOS SoundFont: SoundFont: ... ... Use Internal Reverb Utilizar reverberación interna Init. Status: Estado de inicialización: Default Apple DLS Sound Set Conjunto de sonidos DLS de Apple por omisión DLS Synth Initialized Sintetizador DLS inicializado DLS Synth Initialization Failed Inicialización fallida del sintetizador DLS Ready Listo Failed Fallido Select SoundFont Seleccionar SoundFont SoundFont Files (*.sf2 *.dls) Archivos SoundFont (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Opciones del controlador de red Init. Status: Estado de inicialización: Use IPv6 Usar IPv6 Network Interface: Interfaz de red: Address Dirección Network Initialized Red inicializada Network Initialization Failed Inicialización fallida de la red Any Cualquiera Ready Listo Failed Fallido drumstick::widgets::PianoScene C do C♯ do♯ D re D♯ re♯ E mi F fa F♯ fa♯ G sol G♯ sol♯ A la A♯ la♯ B si D♭ re♭ E♭ mi♭ G♭ sol♭ A♭ la♭ B♭ si♭ drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Sintetizador Sonivox EAS Chorus Coral Reverb Reverberación Buffer Time: Tiempo de buffer: ms ms Init. Status: Estado de inicialización: Sonivox Initialized Sonivox inicializado Sonivox Initialization Failed Inicialización fallida de Sonivox Ready Listo Failed Fallido drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_nl.ts0000644000000000000000000000013214200302440025625 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_nl.ts0000644000175000001440000005574214200302440026423 0ustar00pedrousers00000000000000 PianoPalette N # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 C C# D D# E F F# G G# A A# B N* #* Single color highlight A single color to highlight all note events Two colors highlight One color to highlight natural notes and a different one for accidentals MIDI Channels highlight A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Chromatic scale background One color for each note in the chromatic scale Keys background One color for natural notes and another for accidentals Font foreground Colors for note names Chromatic scale highlight drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Sample Rate: Period Size: # of Periods: Audio Driver: Polyphony: FluidSynth Version: Sound Font: Initialization Status: Buffer Time: ms Gain: ... ... Chorus Reverb FluidSynth Initialized FluidSynth Initialization Failed Ready Failed Select SoundFont SoundFont Files (*.sf2 *.sf3 *.dls) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings SoundFont: ... ... Use Internal Reverb Init. Status: Default Apple DLS Sound Set DLS Synth Initialized DLS Synth Initialization Failed Ready Failed Select SoundFont SoundFont Files (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Init. Status: Use IPv6 Network Interface: Address Network Initialized Network Initialization Failed Any Ready Failed drumstick::widgets::PianoScene C C♯ D D♯ E F F♯ G G♯ A A♯ B D♭ E♭ G♭ A♭ B♭ drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Chorus Reverb Buffer Time: ms Init. Status: Sonivox Initialized Sonivox Initialization Failed Ready Failed drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_de.ts0000644000000000000000000000013214200302440025604 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_de.ts0000644000175000001440000005725114200302440026377 0ustar00pedrousers00000000000000 PianoPalette N # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 C C C# C♯ D D D# D♯ E E F F F# F♯ G G G# G♯ A A A# A♯ B H N* #* Single color highlight Eine Farbe für alles A single color to highlight all note events Eine einzige Farbe für alle Noten-Events Two colors highlight One color to highlight natural notes and a different one for accidentals Eine Farbe für Stammtöne, eine andere für Halbtöne MIDI Channels highlight Farbe nach MIDI-Kanal A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Eine andere Farbe für jeden MIDI-Kanal. Hierzu den Omni-Modus in der MIDI IN Verbindung aktivieren Chromatic scale background Chromatische Farbskala One color for each note in the chromatic scale Verschiedene Farben nach Noten in der Skala Keys background Tasten-Hintergrund One color for natural notes and another for accidentals Eine Farbe für Stammtöne, eine andere für Halbtöne Font foreground Schriftfarbe Colors for note names Farben für Notennamen Chromatic scale highlight Chromatische Farbskala (hervorgehoben) drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings FluidSynth Treiber-Einstellungen Sample Rate: Period Size: # of Periods: Audio Driver: Audio-Treiber: Polyphony: Polyphonie: FluidSynth Version: Sound Font: Initialization Status: Buffer Time: Puffer-Zeit: ms Gain: ... Chorus Reverb Hall FluidSynth Initialized FluidSynth Initialization Failed Ready Failed Select SoundFont SoundFont auswählen SoundFont Files (*.sf2 *.sf3 *.dls) SoundFont Files (*.sf2) SoundFont-Dateien (*.sf2) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings macOS Treiber-Einstellungen SoundFont: ... Use Internal Reverb Internen Hall benutzen Init. Status: Default Apple DLS Sound Set DLS Synth Initialized DLS Synth Initialization Failed Ready Failed Select SoundFont SoundFont auswählen SoundFont Files (*.sf2 *.dls) SoundFont-Dateien (*.sf2) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Netzwerk Treiber-Einstellungen Init. Status: Use IPv6 IPv6 benutzen Network Interface: Netzwerk-Schnittstelle: Address Adresse Network Initialized Network Initialization Failed Any Alle Ready Failed drumstick::widgets::PianoScene C C C♯ C♯ D D D♯ D♯ E E F F F♯ F♯ G G G♯ G♯ A A A♯ A♯ B H D♭ D♭ E♭ E♭ G♭ G♭ A♭ A♭ B♭ B drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Chorus Reverb Hall Buffer Time: Puffer-Zeit: ms Init. Status: Sonivox Initialized Sonivox Initialization Failed Ready Failed drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_fr.ts0000644000000000000000000000013214200302440025623 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_fr.ts0000644000175000001440000005776114200302440026424 0ustar00pedrousers00000000000000 PianoPalette N N # # 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 C Do C# Do# D Re D# Re# E Mi F Fa F# Fa# G Sol G# Sol# A La A# La# B Si N* N* #* #* Single color highlight Couleur unique A single color to highlight all note events Une seule couleur pour tous les évênements de notes Two colors highlight Deux couleurs One color to highlight natural notes and a different one for accidentals Une couleur pour les notes naturelles, une autre pour les notes altérées MIDI Channels highlight Canaux MIDI A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Couleur différente selon le canal MIDI. Activer le mode Omni pour la connexion MIDI IN Chromatic scale background Echelle chromatique One color for each note in the chromatic scale Une couleur pour chaque note dans l'échelle chromatique Keys background Couleur des touches One color for natural notes and another for accidentals Une couleur pour les notes naturelles, une autre pour les notes altérées Font foreground Couleur du texte Colors for note names Couleurs des noms des notes Chromatic scale highlight Echelle chromatique drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Paramètres du pilote FluidSynth Sample Rate: Fréquence d'échantillonnage: Period Size: Taille d'une période: # of Periods: Nb Périodes: Audio Driver: Pilote Audio: Polyphony: Polyphonie: FluidSynth Version: Sound Font: Soundfont : Initialization Status: Buffer Time: Durée tampon: ms ms Gain: Gain: ... ... Chorus Chorus Reverb Réverbération FluidSynth Initialized FluidSynth Initialization Failed Ready Failed Select SoundFont Choisir un SoundFont SoundFont Files (*.sf2 *.sf3 *.dls) SoundFont Files (*.sf2) Fichiers SoundFont (*.sf2) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings Paramètres du pilote de synthé macOS SoundFont: Soundfont : ... ... Use Internal Reverb Utiliser la réverberation interne Init. Status: Default Apple DLS Sound Set Apple DLS Sound Set standard DLS Synth Initialized DLS Synth Initialization Failed Ready Failed Select SoundFont Choisir un SoundFont SoundFont Files (*.sf2 *.dls) Fichiers SoundFont (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Paramètres du pilote réseau Init. Status: Use IPv6 Utiliser l'IPv6 Network Interface: Interface réseau: Address Adresse Network Initialized Network Initialization Failed Any Toutes Ready Failed drumstick::widgets::PianoScene C Do C♯ Do♯ D Re D♯ Re♯ E Mi F Fa F♯ Fa♯ G Sol G♯ Sol♯ A La A♯ La♯ B Si D♭ Re♭ E♭ Mi♭ G♭ Sol♭ A♭ La♭ B♭ Si♭ drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Sonivox EAS Synth Chorus Chorus Reverb Réverbération Buffer Time: Durée tampon: ms ms Init. Status: Sonivox Initialized Sonivox Initialization Failed Ready Failed drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_cs.ts0000644000000000000000000000013214200302440025621 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_cs.ts0000644000175000001440000005773314200302440026421 0ustar00pedrousers00000000000000 PianoPalette N Č # # 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 C C C# Cis D D D# Dis E E F F F# Fis G G G# Gis A A A# Ais B H N* Č* #* #* Single color highlight Zvýraznění jednou barvou A single color to highlight all note events Jedna barva pro zvýraznění všech událostí not Two colors highlight Zvýraznění dvěma barvami One color to highlight natural notes and a different one for accidentals Jedna barva pro zvýraznění odrážek a jiná pro posuvky MIDI Channels highlight Zvýraznění kanálů MIDI A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Různá barva pro zvýraznění každého MIDI kanálu. Povolte režim Omni v připojení MIDI IN Chromatic scale background Pozadí chromatické stupnice One color for each note in the chromatic scale Jedna barva pro každou notu v chromatické stupnici Keys background Pozadí předznamenání One color for natural notes and another for accidentals Jedna barva pro noty odrážek a jiná pro posuvky Font foreground Popředí písma Colors for note names Barvy pro názvy not Chromatic scale highlight Zvýraznění chromatické stupnice drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Nastavení ovladače FluidSynth Sample Rate: Vzorkovací kmitočet: Period Size: Velikost období: # of Periods: # období: Audio Driver: Ovladač zvuku: Polyphony: Vícehlas: FluidSynth Version: Verze FluidSynth: Sound Font: Zvuková banka: Initialization Status: Stav inicializace: Buffer Time: Čas vyrovnávací paměti: ms ms Gain: Zesílení: ... ... Chorus Sbor Reverb Dozvuk FluidSynth Initialized FluidSynth inicializován FluidSynth Initialization Failed FluidSynth se nepodařilo inicializovat Ready Připraven Failed Selhalo Select SoundFont Vybrat zvukovou banku SoundFont Files (*.sf2 *.sf3 *.dls) SoundFont Files (*.sf2) Soubory zvukových bank (*.sf2) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings Nastavení ovladače syntetizátoru macOS SoundFont: Zvuková banka: ... ... Use Internal Reverb Použít vnitřní dozvuk Init. Status: Stav inicializace: Default Apple DLS Sound Set Výchozí zvuková sada Apple DLS DLS Synth Initialized DLS Synth inicializován DLS Synth Initialization Failed DLS Synth se nepodařilo inicializovat Ready Připraven Failed Selhalo Select SoundFont Vybrat zvukovou banku SoundFont Files (*.sf2 *.dls) Soubory zvukových bank (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Nastavení síťového ovladače Init. Status: Stav inicializace: Use IPv6 Použít IPv6 Network Interface: Síťové rozhraní: Address Adresa Network Initialized Síť inicializována Network Initialization Failed Síť se nepodařilo inicializovat Any Vše Ready Připraven Failed Selhalo drumstick::widgets::PianoScene C C C♯ C♯ D D D♯ D♯ E E F F F♯ F♯ G G G♯ G♯ A A A♯ A♯ B H D♭ D♭ E♭ E♭ G♭ G♭ A♭ A♭ B♭ B drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Sonivox EAS Synth Chorus Sbor Reverb Dozvuk Buffer Time: Čas vyrovnávací paměti: ms ms Init. Status: Stav inicializace: Sonivox Initialized Sonivox inicializován Sonivox Initialization Failed Sonivox se nepodařilo inicializovat Ready Připraven Failed Selhalo drumstick-2.5.1/library/widgets/translations/PaxHeaders.27918/drumstick-widgets_sr.ts0000644000000000000000000000013214200302440025640 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/translations/drumstick-widgets_sr.ts0000644000175000001440000005763014200302440026434 0ustar00pedrousers00000000000000 PianoPalette N N # # 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 C C C# C# D D D# D# E E F F F# F# G G G# G# A A A# A# B B N* #* Single color highlight A single color to highlight all note events Једнобојно означавање догађаја свих нота Two colors highlight One color to highlight natural notes and a different one for accidentals Прва боја означава тонове, а друга полутонове MIDI Channels highlight A different color to highlight each MIDI channel. Enable Omni mode in the MIDI IN connection Chromatic scale background One color for each note in the chromatic scale Једна боја за сваку ноту хроматске скале Keys background One color for natural notes and another for accidentals Font foreground Colors for note names Chromatic scale highlight drumstick::widgets::FluidSettingsDialog FluidSynth Driver Settings Флуид-синт — поставке Sample Rate: Учестаност узорковања: Period Size: Величина периода: # of Periods: # периода: Audio Driver: Зв. посредник: Polyphony: Полифонија: FluidSynth Version: Sound Font: Звукотека: Initialization Status: Buffer Time: ms мс Gain: Јачина: ... ... Chorus Хорус Reverb Јека FluidSynth Initialized FluidSynth Initialization Failed Ready Failed Select SoundFont Избор звукотеке SoundFont Files (*.sf2 *.sf3 *.dls) SoundFont Files (*.sf2) Звукотеке (*.sf2) drumstick::widgets::MacSynthSettingsDialog macOS Synth Driver Settings SoundFont: Звукотека: ... ... Use Internal Reverb Init. Status: Default Apple DLS Sound Set DLS Synth Initialized DLS Synth Initialization Failed Ready Failed Select SoundFont Избор звукотеке SoundFont Files (*.sf2 *.dls) Звукотеке (*.sf2 *.dls) drumstick::widgets::NetworkSettingsDialog Network Driver Settings Поставке мрежног посредника Init. Status: Use IPv6 Network Interface: Мрежни прикључак: Address Адреса Network Initialized Network Initialization Failed Any Било који Ready Failed drumstick::widgets::PianoScene C C C♯ C♯ D D D♯ D♯ E E F F F♯ F♯ G G G♯ G♯ A A A♯ A♯ B B D♭ D♭ E♭ E♭ G♭ G♭ A♭ A♭ B♭ B drumstick::widgets::SonivoxSettingsDialog Sonivox EAS Synth Chorus Хорус Reverb Јека Buffer Time: ms мс Init. Status: Sonivox Initialized Sonivox Initialization Failed Ready Failed drumstick-2.5.1/library/widgets/PaxHeaders.27918/macsynthsettingsdialog.ui0000644000000000000000000000013214200302440023520 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.881324217 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/macsynthsettingsdialog.ui0000644000175000001440000001160014200302440024277 0ustar00pedrousers00000000000000 drumstick::widgets::MacSynthSettingsDialog 0 0 319 182 macOS Synth Driver Settings Qt::Vertical 20 256 true 0 0 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults SoundFont: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter soundfont_dls Default Apple DLS Sound Set ... Use Internal Reverb Init. Status: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter soundfont_dls btn_soundfont default_dls reverb_dls default_dls toggled(bool) soundfont_dls setDisabled(bool) 136 58 260 31 default_dls toggled(bool) btn_soundfont setDisabled(bool) 294 58 294 30 default_dls toggled(bool) lblSoundFont setDisabled(bool) 96 58 66 31 buttonBox accepted() drumstick::widgets::MacSynthSettingsDialog accept() 170 158 192 184 buttonBox rejected() drumstick::widgets::MacSynthSettingsDialog reject() 259 155 281 179 drumstick-2.5.1/library/widgets/PaxHeaders.27918/whkey.svg0000644000000000000000000000013214200302440020242 xustar0030 mtime=1644266784.833324185 30 atime=1644266784.881324217 30 ctime=1644266784.833324185 drumstick-2.5.1/library/widgets/whkey.svg0000644000175000001440000001070414200302440021025 0ustar00pedrousers00000000000000 image/svg+xml drumstick-2.5.1/library/widgets/PaxHeaders.27918/pianokeybd.cpp0000644000000000000000000000013214200302440021223 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.881324217 30 ctime=1644266784.825324181 drumstick-2.5.1/library/widgets/pianokeybd.cpp0000644000175000001440000005473014200302440022015 0ustar00pedrousers00000000000000/* Virtual Piano Widget for Qt5 Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include "pianoscene.h" /** * @file pianokeybd.cpp * Implementation of the PianoKeybd class */ /** * @class QGraphicsView * The QGraphicsView class provides a widget for displaying the contents of a QGraphicsScene. * @see https://doc.qt.io/qt-5/qgraphicsview.html */ namespace drumstick { namespace widgets { /** * Global Default Alphanumeric Keyboard Map */ KeyboardMap g_DefaultKeyMap { {Qt::Key_Z, 12}, {Qt::Key_S, 13}, {Qt::Key_X, 14}, {Qt::Key_D, 15}, {Qt::Key_C, 16}, {Qt::Key_V, 17}, {Qt::Key_G, 18}, {Qt::Key_B, 19}, {Qt::Key_H, 20}, {Qt::Key_N, 21}, {Qt::Key_J, 22}, {Qt::Key_M, 23}, {Qt::Key_Q, 24}, {Qt::Key_2, 25}, {Qt::Key_W, 26}, {Qt::Key_3, 27}, {Qt::Key_E, 28}, {Qt::Key_R, 29}, {Qt::Key_5, 30}, {Qt::Key_T, 31}, {Qt::Key_6, 32}, {Qt::Key_Y, 33}, {Qt::Key_7, 34}, {Qt::Key_U, 35}, {Qt::Key_I, 36}, {Qt::Key_9, 37}, {Qt::Key_O, 38}, {Qt::Key_0, 39}, {Qt::Key_P, 40} }; /** * Global Default Raw Keyboard Map */ KeyboardMap g_DefaultRawKeyMap { #if defined(Q_OS_LINUX) {94, 11}, {52, 12}, {39, 13}, {53, 14}, {40, 15}, {54, 16}, {55, 17}, {42, 18}, {56, 19}, {43, 20}, {57, 21}, {44, 22}, {58, 23}, {59, 24}, {46, 25}, {60, 26}, {47, 27}, {61, 28}, {24, 29}, {11, 30}, {25, 31}, {12, 32}, {26, 33}, {13, 34}, {27, 35}, {28, 36}, {15, 37}, {29, 38}, {16, 39}, {30, 40}, {31, 41}, {18, 42}, {32, 43}, {19, 44}, {33, 45}, {20, 46}, {34, 47}, {35, 48} #endif #if defined(Q_OS_WIN) {86, 11}, {44, 12}, {31, 13}, {45, 14}, {32, 15}, {46, 16}, {47, 17}, {34, 18}, {48, 19}, {35, 20}, {49, 21}, {36, 22}, {50, 23}, {51, 24}, {38, 25}, {52, 26}, {39, 27}, {53, 28}, {16, 29}, {3, 30}, {17, 31}, {4, 32}, {18, 33}, {5, 34}, {19, 35}, {20, 36}, {7, 37}, {21, 38}, {8, 39}, {22, 40}, {23, 41}, {10, 42}, {24, 43}, {11, 44}, {25, 45}, {12, 46}, {26, 47}, {27, 48} #endif #if defined(Q_OS_MAC) {50, 11}, {6, 12}, {1, 13}, {7, 14}, {2, 15}, {8, 16}, {9, 17}, {5, 18}, {11, 19}, {4, 20}, {45, 21}, {38, 22}, {46, 23}, {43, 24}, {37, 25}, {47, 26}, {41, 27}, {44, 28}, {12, 29}, {19, 30}, {13, 31}, {20, 32}, {14, 33}, {21, 34}, {15, 35}, {17, 36}, {22, 37}, {16, 38}, {26, 39}, {32, 40}, {34, 41}, {25, 42}, {31, 43}, {29, 44}, {35, 45}, {27, 46}, {33, 47}, {30, 48} #endif }; class PianoKeybd::PianoKeybdPrivate { public: PianoKeybdPrivate(): m_rotation(0), m_scene(nullptr), m_rawMap(nullptr) { } ~PianoKeybdPrivate() = default; int m_rotation; PianoScene *m_scene; KeyboardMap *m_rawMap; }; /** * @brief Constructor * * This is the usual constructor when using QtDesigner and without providing * custom settings, using the default octave, number of keys and starting key. * @param parent Widget's parent */ PianoKeybd::PianoKeybd(QWidget *parent) : QGraphicsView(parent), d(new PianoKeybdPrivate()) { initialize(); initScene(DEFAULTBASEOCTAVE, DEFAULTNUMBEROFKEYS, DEFAULTSTARTINGKEY); } /** * @brief Constructor providing not only a parent widget, but also * custom values for octave, number of keys and starting key. * @param baseOctave The base octave number * @param numKeys The number of displayed keys * @param startKey The startup key * @param parent The widget's parent */ PianoKeybd::PianoKeybd(const int baseOctave, const int numKeys, const int startKey, QWidget *parent) : QGraphicsView(parent), d(new PianoKeybdPrivate) { initialize(); initScene(baseOctave, numKeys, startKey); } /** * @brief Destructor */ PianoKeybd::~PianoKeybd() { d->m_scene->setRawKeyboardMode(false); setKeyboardMap(nullptr); } /** * Gets the PianoHandler pointer to the note receiver. * * If this method returns null, then there is not a PianoHandler class assigned, * and then the signals noteOn() and noteOff() are emitted instead. * @return pointer to the PianoHandler class, if there is one assigned */ PianoHandler *PianoKeybd::getPianoHandler() const { return d->m_scene->getPianoHandler(); } /** * Assigns a PianoHandler pointer for processing note events. * * When this member is used to assign a PianoHandler instance, then * the methods in that instance are called instead of emitting the * signals noteOn() and noteOff(). * @param handler pointer to the PianoHandler instance */ void PianoKeybd::setPianoHandler(PianoHandler *handler) { d->m_scene->setPianoHandler(handler); } /** * Returns the palette used for highlighting the played keys * @return The PianoPalette used to highlight the played keys */ PianoPalette PianoKeybd::getHighlightPalette() const { return d->m_scene->getHighlightPalette(); } /** * Assigns the palette used for highlighting the played keys. When the palette * has a single color, the method setKeyPressedColor() may be used instead. * @see setKeyPressedColor() * @param p PianoPalette const reference */ void PianoKeybd::setHighlightPalette(const PianoPalette& p) { d->m_scene->setHighlightPalette(p); } /** * Returns the palette used to paint the keys' background. * @return The PianoPalette used to paint the keys' background */ PianoPalette PianoKeybd::getBackgroundPalette() const { return d->m_scene->getBackgroundPalette(); } /** * Assigns the palette used to paint the keys' background. * @param p PianoPalette const reference */ void PianoKeybd::setBackgroundPalette(const PianoPalette& p) { d->m_scene->setBackgroundPalette(p); } /** * Returns the palette used to paint texts over the keys like the note names * or custom labels. * @return The PianoPalette used to paint the keys' foreground */ PianoPalette PianoKeybd::getForegroundPalette() const { return d->m_scene->getForegroundPalette(); } /** * Assigns the palette used to paint texts over the keys like the note names * or custom labels. * @param p PianoPalette const reference */ void PianoKeybd::setForegroundPalette(const PianoPalette &p) { d->m_scene->setForegroundPalette(p); } /** * Returns true if the color scale background palette is assigned and active. * @return whether the color scale display is enabled or not */ bool PianoKeybd::showColorScale() const { return d->m_scene->showColorScale(); } /** * Enables or disables the color scale background palette. * @param show the color scale activation state */ void PianoKeybd::setShowColorScale(const bool show) { d->m_scene->setShowColorScale(show); } /** * Assigns a list of custom text labels to be displayer over the keys. * * This can be used for instance, to display the names of the percussion sounds for * General MIDI channel 10. The number of elements should be 128, when * naming the whole set of MIDI notes, or at least 12 when naming the note names, * in which case an octave designation may be attached to the supplied name. * @param names list of key labels */ void PianoKeybd::useCustomNoteNames(const QStringList &names) { d->m_scene->useCustomNoteNames(names); } /** * Disables the custom note names usage as labels over the keys, and restores * the standard note names instead. */ void PianoKeybd::useStandardNoteNames() { d->m_scene->useStandardNoteNames(); } /** * Returns the list of custom note names. * @return the list of custom key names */ QStringList PianoKeybd::customNoteNames() const { return d->m_scene->customNoteNames(); } /** * Returns the list of standard note names. * @return the list of standard key names */ QStringList PianoKeybd::standardNoteNames() const { return d->m_scene->standardNoteNames(); } /** * Updates the standard names of notes according to the * currently active program language translation. * The custom note names are not affected. */ void PianoKeybd::retranslate() { d->m_scene->retranslate(); } /** * Creates and initializes a new PianoScene instance and assigns it to this widget. * @param base octave base number * @param num number of displayed keys * @param strt starting note number * @param c single default highlight color */ void PianoKeybd::initScene(int base, int num, int strt, const QColor& c) { d->m_scene = new PianoScene(base, num, strt, c, this); d->m_scene->setKeyboardMap(&g_DefaultKeyMap); connect(d->m_scene, &PianoScene::noteOn, this, &PianoKeybd::noteOn); connect(d->m_scene, &PianoScene::noteOff, this, &PianoKeybd::noteOff); connect(d->m_scene, &PianoScene::signalName, this, &PianoKeybd::signalName); setScene(d->m_scene); } /** * This method is called from the available constructors * to initialize some widget attributes, settings, and optimizations. */ void PianoKeybd::initialize() { setAttribute(Qt::WA_AcceptTouchEvents); setAttribute(Qt::WA_InputMethodEnabled, false); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setViewportUpdateMode(MinimalViewportUpdate); setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing|QPainter::SmoothPixmapTransform); #if (QT_VERSION < QT_VERSION_CHECK(5,15,0)) setOptimizationFlag(DontClipPainter, true); #endif setOptimizationFlag(DontSavePainterState, true); setOptimizationFlag(DontAdjustForAntialiasing, true); resetRawKeyboardMap(); } /** * This method overrides QGraphicsView::resizeEvent() * to keep the aspect ratio of the keys scene when the view is resized. * @param event */ void PianoKeybd::resizeEvent(QResizeEvent *event) { QGraphicsView::resizeEvent(event); fitInView(d->m_scene->sceneRect(), Qt::KeepAspectRatio); } /** * This method changes the number of displayed keys * and the starting key number, keeping the other settings the same. * @param numKeys The new number of keys * @param startKey The number of the starting key */ void PianoKeybd::setNumKeys(const int numKeys, const int startKey) { //qDebug() << Q_FUNC_INFO << numKeys << startKey; if ( numKeys != d->m_scene->numKeys() || startKey != d->m_scene->startKey() ) { QByteArray dataBuffer; int baseOctave = d->m_scene->baseOctave(); QColor color = d->m_scene->getKeyPressedColor(); PianoHandler* handler = d->m_scene->getPianoHandler(); KeyboardMap* keyMap = d->m_scene->getKeyboardMap(); d->m_scene->saveData(dataBuffer); delete d->m_scene; initScene(baseOctave, numKeys, startKey, color); d->m_scene->loadData(dataBuffer); d->m_scene->setPianoHandler(handler); d->m_scene->setKeyboardMap(keyMap); d->m_scene->hideOrShowKeys(); d->m_scene->refreshKeys(); d->m_scene->refreshLabels(); fitInView(d->m_scene->sceneRect(), Qt::KeepAspectRatio); } } /** * Rotates the keyboard view an angle clockwise. * @param r rotating angle in degrees to rotate. */ void PianoKeybd::setRotation(int r) { if (r != d->m_rotation) { d->m_rotation = r; resetTransform(); rotate(d->m_rotation); fitInView(d->m_scene->sceneRect(), Qt::KeepAspectRatio); } } /** * Overrides QGraphicsView::sizeHint() providing a size value based on the piano scene. * @return The sizeHint property of the piano view */ QSize PianoKeybd::sizeHint() const { return mapFromScene(sceneRect()).boundingRect().size(); } // RAWKBD_SUPPORT bool PianoKeybd::handleKeyPressed(int keycode) { if (d->m_scene->isKeyboardEnabled() && d->m_rawMap != nullptr && d->m_rawMap->contains(keycode)) { d->m_scene->keyOn(d->m_rawMap->value(keycode)); return true; } return false; } bool PianoKeybd::handleKeyReleased(int keycode) { if (d->m_scene->isKeyboardEnabled() && d->m_rawMap != nullptr && d->m_rawMap->contains(keycode)) { d->m_scene->keyOff(d->m_rawMap->value(keycode)); return true; } return false; } /** * @brief Assigns a custom picture to the white or black keys * that will be used as a texture to paint the keys. * @param natural true for white keys, false for black keys * @param pix this transparent QPixmap will be used to paint the keys */ void PianoKeybd::setKeyPicture(const bool natural, const QPixmap &pix) { d->m_scene->setKeyPicture(natural, pix); } /** * @brief Returns the custom picture used to paint the corresponding keys. * @param natural true for white keys, false for black keys * @return a transparent QPixmap used to paint the keys */ QPixmap PianoKeybd::getKeyPicture(const bool natural) { return d->m_scene->getKeyPicture(natural); } /** * @brief Enables or disables a picture to paint the keys. * @param enable or disable */ void PianoKeybd::setUseKeyPictures(const bool enable) { d->m_scene->setUseKeyPictures(enable); } /** * @brief Returns whether pictures are used to paint the keys. * @return true if the pictures are enabled to paint the keys */ bool PianoKeybd::getUseKeyPictures() const { return d->m_scene->getUseKeyPictures(); } /** * Returns the base octave number. * @see setBaseOctave() * @return the base octave number */ int PianoKeybd::baseOctave() const { return d->m_scene->baseOctave(); } /** * Assigns the base octave number. * @param baseOctave the base octave number */ void PianoKeybd::setBaseOctave(const int baseOctave) { d->m_scene->setBaseOctave(baseOctave); } /** * Returns the total number of keys * @see setNumKeys() * @return the number of keys displayed */ int PianoKeybd::numKeys() const { return d->m_scene->numKeys(); } /** * Returns the starting key note: C=0, A=9 and so on. * @return the starting key note. */ int PianoKeybd::startKey() const { return d->m_scene->startKey(); } /** * Returns the rotation angle in degrees, clockwise, of the piano view. * @return the rotation angle in degrees. */ int PianoKeybd::getRotation() const { return d->m_rotation; } /** * Returns the key highlight color. * @return the key highlight color */ QColor PianoKeybd::getKeyPressedColor() const { return d->m_scene->getKeyPressedColor(); } /** * Assigns a single color for key highlight. This is an alternative to creating a * highlight palette with a single color and assigning it. * @see setHighlightPalette() * @param c color for key highlight */ void PianoKeybd::setKeyPressedColor(const QColor& c) { d->m_scene->setKeyPressedColor(c); } /** * Assigns the default highlight palette colors and assigns it to the scene. */ void PianoKeybd::resetKeyPressedColor() { d->m_scene->resetKeyPressedColor(); } /** * Returns the label visibility policy. * @see setShowLabels() * @return the label visibility policy */ LabelVisibility PianoKeybd::showLabels() const { return d->m_scene->showLabels(); } /** * Assigns the label visibility policy. * @see LabelVisibility * @param show the label visibility policy */ void PianoKeybd::setShowLabels(const LabelVisibility show) { d->m_scene->setShowLabels(show); } /** * Returns the label alterations policy. * @see setLabelAlterations() * @return the label alterations policy */ LabelAlteration PianoKeybd::labelAlterations() const { return d->m_scene->alterations(); } /** * Assigns the label alterations policy. * @see LabelAlteration * @param use the label alterations policy */ void PianoKeybd::setLabelAlterations(const LabelAlteration use) { d->m_scene->setAlterations(use); } /** * Returns the labels orientation policy. * @see setLabelOrientation() * @return the labels orientation policy */ LabelOrientation PianoKeybd::labelOrientation() const { return d->m_scene->getOrientation(); } /** * Assigns the labels orientation policy. * @see LabelOrientation * @param orientation the labels orientation policy */ void PianoKeybd::setLabelOrientation(const LabelOrientation orientation) { d->m_scene->setOrientation(orientation); } /** * Returns the octave label policy. * @see setLabelOctave() * @return the octave label policy */ LabelCentralOctave PianoKeybd::labelOctave() const { return d->m_scene->getOctave(); } /** * Assigns the octave label policy * @see LabelCentralOctave * @param octave the octave label policy */ void PianoKeybd::setLabelOctave(const LabelCentralOctave octave) { d->m_scene->setOctave(octave); } /** * Returns the transpose amount in semitones. * @see setTranspose() * @return the transpose amount in semitones */ int PianoKeybd::getTranspose() const { return d->m_scene->getTranspose(); } /** * Assigns the transpose amount in semitones. * @see getTranspose() * @param t the transpose amount in semitones */ void PianoKeybd::setTranspose(int t) { d->m_scene->setTranspose(t); } /** * Returns the MIDI Channel (0-15). * @return the MIDI Channel (0-15) */ int PianoKeybd::getChannel() const { return d->m_scene->getChannel(); } /** * Assigns the MIDI Channel (0-15). * @param c the MIDI Channel (0-15) */ void PianoKeybd::setChannel(const int c) { d->m_scene->setChannel(c); } /** * Returns the MIDI note velocity * @see setVelocity() * @return the MIDI note velocity */ int PianoKeybd::getVelocity() const { return d->m_scene->getVelocity(); } /** * Assigns the MIDI note velocity. * @see getVelocity() * @param v the MIDI note velocity */ void PianoKeybd::setVelocity(const int v) { d->m_scene->setVelocity(v); } /** * Returns whether the computer keyboard is enabled. * @return true if the computer keyboard is enabled. */ bool PianoKeybd::isKeyboardEnabled() const { return d->m_scene->isKeyboardEnabled(); } /** * Enables or disables the computer keyboard note input. * @param enable the computer keyboard note input. */ void PianoKeybd::setKeyboardEnabled(const bool enable) { d->m_scene->setKeyboardEnabled(enable); } /** * Returns whether the mouse note input is enabled. * @return true if the mouse note input is enabled */ bool PianoKeybd::isMouseEnabled() const { return d->m_scene->isMouseEnabled(); } /** * Enables or disables the mouse note input. * @param enable the mouse note input */ void PianoKeybd::setMouseEnabled(const bool enable) { d->m_scene->setMouseEnabled(enable); } /** * Returns whether the touch screen note input is enabled. * @return true if the touch screen note input is enabled */ bool PianoKeybd::isTouchEnabled() const { return d->m_scene->isTouchEnabled(); } /** * Enables or disables the touch screen note input. * @param enable the touch screen note input. */ void PianoKeybd::setTouchEnabled(const bool enable) { d->m_scene->setTouchEnabled(enable); } /** * Returns whether the note MIDI velocity influences the highlight color tint. * @return true if the note MIDI velocity influences the highlight color tint */ bool PianoKeybd::velocityTint() const { return d->m_scene->velocityTint(); } /** * Enables or disables the note MIDI velocity influencing the highlight color tint. * @param enable the note MIDI velocity influencing the highlight color tint */ void PianoKeybd::setVelocityTint(const bool enable) { //qDebug() << Q_FUNC_INFO << enable; d->m_scene->setVelocityTint(enable); } /** * Forces all active notes to silence. */ void PianoKeybd::allKeysOff() { d->m_scene->allKeysOff(); } /** * Assigns the computer keyboard note map. * @param m the computer keyboard note map. */ void PianoKeybd::setKeyboardMap(KeyboardMap* m) { d->m_scene->setKeyboardMap(m); } /** * Returns the computer keyboard note map. * @return the computer keyboard note map */ KeyboardMap* PianoKeybd::getKeyboardMap() { return d->m_scene->getKeyboardMap(); } /** * Resets the computer keyboard note map to the default one. */ void PianoKeybd::resetRawKeyboardMap() { d->m_rawMap = &g_DefaultRawKeyMap; } /** * Returns the low level computer keyboard note map. * @return the low level computer keyboard note map */ bool PianoKeybd::getRawKeyboardMode() const { return d->m_scene->getRawKeyboardMode(); } /** * Enables or disables the low level computer keyboard mode. * @param b the low level computer keyboard mode */ void PianoKeybd::setRawKeyboardMode(const bool b) { d->m_scene->setRawKeyboardMode(b); } /** * Resets the low level computer keyboard note map to the default one. */ void PianoKeybd::resetKeyboardMap() { d->m_scene->setKeyboardMap(&g_DefaultKeyMap); } /** * Assigns the low level computer keyboard note map. * @param m the low level computer keyboard note map */ void PianoKeybd::setRawKeyboardMap(KeyboardMap *m) { d->m_rawMap = m; } /** * Returns the low level computer keyboard note map. * @return the low level computer keyboard note map */ KeyboardMap *PianoKeybd::getRawKeyboardMap() { return d->m_rawMap; } /** * Highlights one note key with the specified color and velocity * @param note The MIDI note number * @param color The highlight color * @param vel The MIDI note velocity */ void PianoKeybd::showNoteOn(const int note, QColor color, int vel) { d->m_scene->showNoteOn(note, color, vel); } /** * Highlights one note key with the specified velocity * @param note The MIDI note number * @param vel The MIDI note velocity */ void PianoKeybd::showNoteOn(const int note, int vel) { d->m_scene->showNoteOn(note, vel); } /** * Shows inactive one note key with the specified velocity * @param note The MIDI note number * @param vel The MIDI note velocity */ void PianoKeybd::showNoteOff(const int note, int vel) { d->m_scene->showNoteOff(note, vel); } /** * Assigns a typographic font for drawing the note labels over the piano keys. * @param font typographic font for drawing the note labels */ void PianoKeybd::setFont(const QFont &font) { QWidget::setFont(font); d->m_scene->setFont(font); d->m_scene->refreshLabels(); } } // namespace widgets } // namespace drumstick drumstick-2.5.1/library/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440017464 xustar0030 mtime=1644266784.821324179 30 atime=1644266784.965324271 30 ctime=1644266784.821324179 drumstick-2.5.1/library/CMakeLists.txt0000644000175000001440000000307014200302440020245 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . if(BUILD_ALSA AND ALSA_FOUND) add_subdirectory(alsa) endif() if (BUILD_FILE) add_subdirectory(file) endif() if (BUILD_RT) add_subdirectory(rt) add_subdirectory(rt-backends) if (BUILD_WIDGETS) add_subdirectory(widgets) add_subdirectory(vpiano-plugin) endif() endif() configure_file( drumstick-config.cmake ${CMAKE_BINARY_DIR}/drumstick-config.cmake @ONLY ) include(CMakePackageConfigHelpers) write_basic_package_version_file( ${CMAKE_BINARY_DIR}/drumstick-config-version.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) install(FILES include/drumstick.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install( FILES ${CMAKE_BINARY_DIR}/drumstick-config.cmake ${CMAKE_BINARY_DIR}/drumstick-config-version.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/drumstick ) drumstick-2.5.1/library/PaxHeaders.27918/drumstick-config.cmake0000644000000000000000000000013214200302440021176 xustar0030 mtime=1644266784.789324158 30 atime=1644266784.965324271 30 ctime=1644266784.789324158 drumstick-2.5.1/library/drumstick-config.cmake0000644000175000001440000000047014200302440021760 0ustar00pedrousers00000000000000if (CMAKE_VERSION VERSION_LESS 3.1.0) message(FATAL_ERROR "Drumstick requires at least CMake version 3.1.0") endif() foreach(component ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS}) string(TOLOWER ${component} locomp) include(${CMAKE_CURRENT_LIST_DIR}/drumstick-${locomp}-config.cmake) endforeach() drumstick-2.5.1/library/PaxHeaders.27918/include0000644000000000000000000000013214200302440016272 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/0000755000175000001440000000000014200302440017130 5ustar00pedrousers00000000000000drumstick-2.5.1/library/include/PaxHeaders.27918/drumstick.h0000644000000000000000000000013214200302440020525 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick.h0000644000175000001440000000322214200302440021305 0ustar00pedrousers00000000000000/* Drumstick MIDI C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMSTICK_H #define DRUMSTICK_H #include /** * @file drumstick.h * The main header that a program can include to use all drumstick features. */ #if defined(Q_OS_LINUX) // ALSA library interface #include #include #include #include #include #include #include #include #endif // File formats #include #include #include // RealTime interfaces #include #include #include // Widgets #include #include #include #include #endif /*DRUMSTICK_H*/ drumstick-2.5.1/library/include/PaxHeaders.27918/drumstick0000644000000000000000000000013214200302440020277 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/0000755000175000001440000000000014200302440021135 5ustar00pedrousers00000000000000drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/alsaport.h0000644000000000000000000000013214200302440022352 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/alsaport.h0000644000175000001440000001423614200302440023141 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMSTICK_ALSAPORT_H #define DRUMSTICK_ALSAPORT_H #include "subscription.h" #include namespace drumstick { namespace ALSA { /** * @file alsaport.h * Classes managing ALSA Sequencer ports. */ class MidiClient; /** * @addtogroup ALSAPort ALSA Sequencer Ports * @{ * * @class PortInfo * Port information container */ class DRUMSTICK_EXPORT PortInfo { friend class MidiPort; friend class ClientInfo; friend class MidiClient; public: PortInfo(); PortInfo(const PortInfo& other); explicit PortInfo(snd_seq_port_info_t* other); PortInfo(MidiClient* seq, const int client, const int port); PortInfo(MidiClient* seq, const int port); virtual ~PortInfo(); PortInfo* clone(); PortInfo& operator=(const PortInfo& other); int getSizeOfInfo() const; int getClient(); int getPort(); QString getClientName() const; const snd_seq_addr_t* getAddr(); QString getName(); unsigned int getCapability(); unsigned int getType(); int getMidiChannels(); int getMidiVoices(); int getSynthVoices(); int getReadUse(); int getWriteUse(); int getPortSpecified(); void setClient(int client); void setPort(int port); void setAddr(const snd_seq_addr_t* addr); void setName( QString const& name ); void setCapability(unsigned int capability); void setType(unsigned int type); void setMidiChannels(int channels); void setMidiVoices(int voices); void setSynthVoices(int voices); void setPortSpecified(int val); SubscribersList getReadSubscribers() const; SubscribersList getWriteSubscribers() const; bool getTimestamping(); bool getTimestampReal(); int getTimestampQueue(); void setTimestamping(bool value); void setTimestampReal(bool value); void setTimestampQueue(int queueId); protected: void readSubscribers(MidiClient* seq); void freeSubscribers(); void setClientName(QString name); private: snd_seq_port_info_t* m_Info; QString m_ClientName; SubscribersList m_ReadSubscribers; SubscribersList m_WriteSubscribers; }; /** * List of port information objects */ typedef QList PortInfoList; /** * Port management. * * This class represents an ALSA sequencer port. */ class DRUMSTICK_EXPORT MidiPort : public QObject { Q_OBJECT friend class MidiClient; public: explicit MidiPort( QObject* parent = nullptr ); virtual ~MidiPort(); void attach( MidiClient* seq ); void detach(); void subscribe( Subscription* subs ); void unsubscribe( Subscription* subs ); void unsubscribeAll(); void unsubscribeTo( QString const& name ); void unsubscribeTo( PortInfo* port ); void unsubscribeTo( const snd_seq_addr_t* addr ); void unsubscribeFrom( QString const& name ); void unsubscribeFrom( PortInfo* port ); void unsubscribeFrom( const snd_seq_addr_t* addr ); void subscribeTo( PortInfo* port); void subscribeTo( int client, int port ); void subscribeTo( QString const& name ); void subscribeFrom( PortInfo* port ); void subscribeFrom( int client, int port ); void subscribeFrom( QString const& name ); void subscribeFromAnnounce(); void updateSubscribers(); SubscriptionsList getSubscriptions() const; PortInfoList getReadSubscribers(); PortInfoList getWriteSubscribers(); void updateConnectionsTo(const PortInfoList& desired); void updateConnectionsFrom(const PortInfoList& desired); static bool containsAddress(const snd_seq_addr_t* addr, const PortInfoList& lst); void applyPortInfo(); QString getPortName(); void setPortName( QString const& newName); int getPortId(); unsigned int getCapability(); void setCapability( unsigned int newValue); unsigned int getPortType(); void setPortType( unsigned int newValue); int getMidiChannels(); void setMidiChannels(int newValue); int getMidiVoices(); void setMidiVoices(int newValue); int getSynthVoices(); void setSynthVoices(int newValue); bool getTimestamping(); bool getTimestampReal(); int getTimestampQueue(); void setTimestamping(bool value); void setTimestampReal(bool value); void setTimestampQueue(int queueId); signals: /** * Signal emitted when an internal subscription is done. * @param port MIDI port object pointer * @param subs Subscription object pointer */ void subscribed(drumstick::ALSA::MidiPort* port, drumstick::ALSA::Subscription* subs); /** * Signal emitted when the MidiClient has changed * @param port MIDI port object pinter * @param seq MidiClient object pointer */ void midiClientChanged(drumstick::ALSA::MidiPort* port, drumstick::ALSA::MidiClient* seq); /** * Signal emitted when the port is attached to a MidiClient * @param port MIDI port object pointer */ void attached(drumstick::ALSA::MidiPort* port); /** * Signal emitted when the port is detached from a MidiClient * @param port MIDI port object pointer */ void detached(drumstick::ALSA::MidiPort* port); protected: PortInfo* getPortInfo(); void freeSubscriptions(); void setMidiClient( MidiClient* seq ); private: MidiClient* m_MidiClient; PortInfo m_Info; bool m_Attached; SubscriptionsList m_Subscriptions; }; /** * List of Ports instances. */ typedef QList MidiPortList; /** @} */ }} /* namespace drumstick::ALSA */ #endif //DRUMSTICK_ALSAPORT_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/macros.h0000644000000000000000000000013214200302440022011 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/macros.h0000644000175000001440000000531214200302440022573 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMSTICK_MACROS_H #define DRUMSTICK_MACROS_H #include /** * @file macros.h * Drumstick visibility macros */ #if !defined(DRUMSTICK_EXPORT) # if defined(DRUMSTICK_STATIC) # define DRUMSTICK_EXPORT # else # if defined(drumstick_alsa_EXPORTS) || defined(drumstick_file_EXPORTS) || defined(drumstick_rt_EXPORTS) || defined(drumstick_widgets_EXPORTS) # define DRUMSTICK_EXPORT Q_DECL_EXPORT # else # if defined(Q_OS_WIN) # define DRUMSTICK_EXPORT Q_DECL_IMPORT # else # define DRUMSTICK_EXPORT Q_DECL_EXPORT # endif # endif # endif #endif #if defined(_MSC_VER) #define DISABLE_WARNING_PUSH __pragma(warning( push )) #define DISABLE_WARNING_POP __pragma(warning( pop )) #define DISABLE_WARNING(warningNumber) __pragma(warning( disable : warningNumber )) #define DISABLE_WARNING_UNREFERENCED_FORMAL_PARAMETER DISABLE_WARNING(4100) #define DISABLE_WARNING_UNREFERENCED_FUNCTION DISABLE_WARNING(4505) #define DISABLE_WARNING_DEPRECATED_DECLARATIONS DISABLE_WARNING(4996) #elif defined(__GNUC__) || defined(__clang__) #define DO_PRAGMA(X) _Pragma(#X) #define DISABLE_WARNING_PUSH DO_PRAGMA(GCC diagnostic push) #define DISABLE_WARNING_POP DO_PRAGMA(GCC diagnostic pop) #define DISABLE_WARNING(warningName) DO_PRAGMA(GCC diagnostic ignored #warningName) #define DISABLE_WARNING_UNREFERENCED_FORMAL_PARAMETER DISABLE_WARNING(-Wunused-parameter) #define DISABLE_WARNING_UNREFERENCED_FUNCTION DISABLE_WARNING(-Wunused-function) #define DISABLE_WARNING_DEPRECATED_DECLARATIONS DISABLE_WARNING(-Wdeprecated-declarations) #else #define DISABLE_WARNING_PUSH #define DISABLE_WARNING_POP #define DISABLE_WARNING_UNREFERENCED_FORMAL_PARAMETER #define DISABLE_WARNING_UNREFERENCED_FUNCTION #define DISABLE_WARNING_DEPRECATED_DECLARATIONS #endif #endif /* DRUMSTICK_MACROS_H */ drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/settingsfactory.h0000644000000000000000000000013214200302440023755 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/settingsfactory.h0000644000175000001440000000334014200302440024536 0ustar00pedrousers00000000000000/* Drumstick Widgets Copyright (C) 2018-2022 Pedro Lopez-Cabanillas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SETTINGS_H #define SETTINGS_H #include #include #include "macros.h" /** * @file settingsfactory.h * SettingsFactory class declaration */ /** * @class QSettings * @brief The QSettings class provides persistent platform-independent application settings. * @see https://doc.qt.io/qt-5/qsettings.html */ namespace drumstick { namespace widgets { /** * @addtogroup Widgets * @{ * * @class SettingsFactory * @brief The SettingsFactory class holds a global QSettings object. * This class creates and returns a QSettings object globally configured * instance using native or file storage. */ class DRUMSTICK_EXPORT SettingsFactory { public: QSettings* getQSettings(); QSettings* operator->(); static void setFileName(const QString name); private: QScopedPointer m_settings{nullptr}; static QString s_fileName; }; /** @} */ }} // namespace drumstick::widgets #endif // SETTINGS_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/qsmf.h0000644000000000000000000000013214200302440021473 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/qsmf.h0000644000175000001440000002742714200302440022270 0ustar00pedrousers00000000000000/* Standard MIDI File component Copyright (C) 2006-2022, Pedro Lopez-Cabanillas Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMSTICK_QSMF_H #define DRUMSTICK_QSMF_H #include "macros.h" #include #include class QTextCodec; class QDataStream; /** * @file qsmf.h * Standard MIDI Files Input/Output */ namespace drumstick { /** * @ingroup File * @brief Drumstick File library */ namespace File { /** * @addtogroup SMF Standard MIDI Files Management (I/O) * @{ */ const quint32 MThd = 0x4d546864; /**< SMF Header prefix */ const quint32 MTrk = 0x4d54726b; /**< SMF Track prefix */ /* Standard MIDI Files meta event definitions */ const quint8 meta_event = 0xff; /**< SMF Meta Event prefix */ const quint8 sequence_number = 0x00; /**< SMF Sequence number */ const quint8 text_event = 0x01; /**< SMF Text event */ const quint8 copyright_notice = 0x02; /**< SMF Copyright notice */ const quint8 sequence_name = 0x03; /**< SMF Sequence name */ const quint8 instrument_name = 0x04; /**< SMF Instrument name */ const quint8 lyric = 0x05; /**< SMF Lyric */ const quint8 marker = 0x06; /**< SMF Marker */ const quint8 cue_point = 0x07; /**< SMF Cue point */ const quint8 forced_channel = 0x20; /**< SMF Forced MIDI channel */ const quint8 forced_port = 0x21; /**< SMF Forced MIDI port */ const quint8 end_of_track = 0x2f; /**< SMF End of track */ const quint8 set_tempo = 0x51; /**< SMF Tempo change */ const quint8 smpte_offset = 0x54; /**< SMF SMPTE offset */ const quint8 time_signature = 0x58; /**< SMF Time signature */ const quint8 key_signature = 0x59; /**< SMF Key signature */ const quint8 sequencer_specific = 0x7f; /**< SMF Sequencer specific */ /* MIDI status commands most significant bit is 1 */ const quint8 note_off = 0x80; /**< MIDI event Note Off */ const quint8 note_on = 0x90; /**< MIDI event Note On */ const quint8 poly_aftertouch = 0xa0; /**< MIDI event Polyphonic pressure */ const quint8 control_change = 0xb0; /**< MIDI event Control change */ const quint8 program_chng = 0xc0; /**< MIDI event Program change */ const quint8 channel_aftertouch = 0xd0; /**< MIDI event Channel after-touch */ const quint8 pitch_wheel = 0xe0; /**< MIDI event Bender */ const quint8 system_exclusive = 0xf0; /**< MIDI event System Exclusive begin */ const quint8 end_of_sysex = 0xf7; /**< MIDI event System Exclusive end */ const quint8 midi_command_mask = 0xf0; /**< Mask to extract the command from the status byte */ const quint8 midi_channel_mask = 0x0f; /**< Mask to extract the channel from the status byte */ const quint8 major_mode = 0; /**< Major mode scale */ const quint8 minor_mode = 1; /**< Minor mode scale */ /** * Standard MIDI Files input/output * * This class is used to parse and encode Standard MIDI Files (SMF) */ class DRUMSTICK_EXPORT QSmf : public QObject { Q_OBJECT public: explicit QSmf(QObject * parent = nullptr); virtual ~QSmf(); void readFromStream(QDataStream *stream); void readFromFile(const QString& fileName); void writeToStream(QDataStream *stream); void writeToFile(const QString& fileName); void writeMetaEvent(long deltaTime, int type, const QByteArray& data); void writeMetaEvent(long deltaTime, int type, const QString& data); void writeMetaEvent(long deltaTime, int type, int data); void writeMetaEvent(long deltaTime, int type); void writeMidiEvent(long deltaTime, int type, int chan, int b1); void writeMidiEvent(long deltaTime, int type, int chan, int b1, int b2); void writeMidiEvent(long deltaTime, int type, int chan, const QByteArray& data); void writeMidiEvent(long deltaTime, int type, long len, char* data); void writeTempo(long deltaTime, long tempo); void writeBpmTempo(long deltaTime, int tempo); void writeTimeSignature(long deltaTime, int num, int den, int cc, int bb); void writeKeySignature(long deltaTime, int tone, int mode); void writeSequenceNumber(long deltaTime, int seqnum); long getCurrentTime(); long getCurrentTempo(); long getRealTime(); long getFilePos(); int getDivision(); void setDivision(int division); int getTracks(); void setTracks(int tracks); int getFileFormat(); void setFileFormat(int fileFormat); Q_DECL_DEPRECATED QTextCodec* getTextCodec(); Q_DECL_DEPRECATED void setTextCodec(QTextCodec *codec); signals: /** * Emitted for a SMF read or write error * @param errorStr Error string */ void signalSMFError(const QString& errorStr); /** * Emitted after reading a SMF header * @param format SMF format (0/1) * @param ntrks Number pof tracks * @param division Division (resolution in ticks per quarter note) */ void signalSMFHeader(int format, int ntrks, int division); /** * Emitted after reading a Note On message * @param chan MIDI Channel * @param pitch MIDI Note * @param vol Velocity */ void signalSMFNoteOn(int chan, int pitch, int vol); /** * Emitted after reading a Note Off message * @param chan MIDI Channel * @param pitch MIDI Note * @param vol Velocity */ void signalSMFNoteOff(int chan, int pitch, int vol); /** * Emitted after reading a Polyphonic Aftertouch message * @param chan MIDI Channel * @param pitch MIDI Note * @param press Pressure amount */ void signalSMFKeyPress(int chan, int pitch, int press); /** * Emitted after reading a Control Change message * @param chan MIDI Channel * @param ctl MIDI Controller * @param value Control value */ void signalSMFCtlChange(int chan, int ctl, int value); /** * Emitted after reading a Bender message * @param chan MIDI Channel * @param value Bender value */ void signalSMFPitchBend(int chan, int value); /** * Emitted after reading a Program change message * @param chan MIDI Channel * @param patch Program number */ void signalSMFProgram(int chan, int patch); /** * Emitted after reading a Channel Aftertouch message * @param chan MIDI Channel * @param press Pressure amount */ void signalSMFChanPress(int chan, int press); /** * Emitted after reading a System Exclusive message * @param data Sysex bytes */ void signalSMFSysex(const QByteArray& data); /** * Emitted after reading a Sequencer specific message * @param data Message data */ void signalSMFSeqSpecific(const QByteArray& data); /** * Emitted after reading an unregistered SMF Meta message * @param typ Message type * @param data Message data * @since 0.2.0 */ void signalSMFMetaUnregistered(int typ, const QByteArray& data); /** * Emitted after reading any SMF Meta message * @param typ Message type * @param data Message data */ void signalSMFMetaMisc(int typ, const QByteArray& data); /** * Emitted after reading a Sequence number message * @param seq Sequence number */ void signalSMFSequenceNum(int seq); /** * Emitted after reading a Forced channel message * @param channel MIDI Channel */ void signalSMFforcedChannel(int channel); /** * Emitted after reading a Forced port message * @param port Port number */ void signalSMFforcedPort(int port); /** * Emitted after reading a SMF text message * @param typ Text type * @param data Text data * @deprecated because the class QTextCodec was removed from QtCore since Qt6. * use signalSMFText2() instead. */ Q_DECL_DEPRECATED void signalSMFText(int typ, const QString& data); /** * Emitted after reading a SMF text message * @param typ Text type * @param data Text data */ void signalSMFText2(int typ, const QByteArray& data); /** * Emitted after reading a SMPT offset message * @param b0 Hours * @param b1 Minutes * @param b2 Seconds * @param b3 Frames * @param b4 Fractional frames */ void signalSMFSmpte(int b0, int b1, int b2, int b3, int b4); /** * Emitted after reading a SMF Time signature message * @param b0 Numerator * @param b1 Denominator (exponent in a power of two) * @param b2 Number of MIDI clocks per metronome click * @param b3 Number of notated 32nd notes per 24 MIDI clocks */ void signalSMFTimeSig(int b0, int b1, int b2, int b3); /** * Emitted after reading a SMF Key Signature smessage * @param b0 Number of alterations (negative=flats, positive=sharps) * @param b1 Scale Mode (0=major, 1=minor) */ void signalSMFKeySig(int b0, int b1); /** * Emitted after reading a Tempo Change message * @param tempo Microseconds per quarter note */ void signalSMFTempo(int tempo); /** * Emitted after reading a End-Of-Track message */ void signalSMFendOfTrack(); /** * Emitted after reading a track prefix */ void signalSMFTrackStart(); /** * Emitted after a track has finished */ void signalSMFTrackEnd(); /** * Emitted to request the user to prepare the tempo track. * * The signal handler should not call the writeTempo() or writeBpmTempo() * methods directly, but instead it should fill the Conductor track with * tempo and other SMF meta events like key and time signatures to be written * later, at the signalSMFWriteTrack() handler. * * The Conductor track is the first track in a format 1 SMF. */ void signalSMFWriteTempoTrack(); /** * Emitted to request the user to write a track. * @param track Track number */ void signalSMFWriteTrack(int track); private: /** * Tempo change within a SMF or sequence */ struct QSmfRecTempo { quint64 tempo; quint64 time; }; class QSmfPrivate; QScopedPointer d; void SMFRead(); void SMFWrite(); quint8 getByte(); void putByte(quint8 value); void readHeader(); void readTrack(); quint16 to16bit(quint8 c1, quint8 c2); quint32 to32bit(quint8 c1, quint8 c2, quint8 c3, quint8 c4); quint16 read16bit(); quint32 read32bit(); void write16bit(quint16 data); void write32bit(quint32 data); void writeVarLen(quint64 value); double ticksToSecs(quint64 ticks, quint16 division, quint64 tempo); long readVarLen(); void readExpected(const QString& s); void addTempo(quint64 tempo, quint64 time); quint64 findTempo(); void SMFError(const QString& s); void channelMessage(quint8 status, quint8 c1, quint8 c2); void msgInit(); void msgAdd(quint8 b); void metaEvent(quint8 b); void sysEx(); void badByte(quint8 b, int p); quint8 lowerByte(quint16 x); quint8 upperByte(quint16 x); bool endOfSmf(); void writeHeaderChunk(int format, int ntracks, int division); void writeTrackChunk(int track); }; QString DRUMSTICK_EXPORT drumstickLibraryVersion(); /** @} */ }} /* namespace drumstick::File */ #endif /* DRUMSTICK_QSMF_H */ drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/backendmanager.h0000644000000000000000000000013214200302440023447 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/backendmanager.h0000644000175000001440000001003714200302440024231 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef BACKENDMANAGER_H #define BACKENDMANAGER_H #include #include #include "macros.h" #include "rtmidiinput.h" #include "rtmidioutput.h" /** * @file backendmanager.h * BackendManager class declaration */ namespace drumstick { /** * @ingroup RT * @brief Drumstick Real-Time library */ namespace rt { /** * @addtogroup RT Realtime MIDI (I/O) * @{ */ /** * @brief The BackendManager class manages lists of dynamic and static * backends for applications based on drumstick-rt */ class DRUMSTICK_EXPORT BackendManager { public: /** * @brief BackendManager constructor */ explicit BackendManager(); /** * @brief ~BackendManager destructor */ virtual ~BackendManager(); /** * @brief refresh the list of backends * @param settings Program settings */ void refresh(QSettings* settings = nullptr); /** * @brief refresh the list of backends * @param map Program settings relevant section */ void refresh(const QVariantMap& map); /** * @brief availableInputs * @return list of available MIDI inputs */ QList availableInputs(); /** * @brief availableOutputs * @return list of available MIDI outputs */ QList availableOutputs(); /** * @brief defaultPaths * @return list of paths for backends search */ QStringList defaultPaths(); /** * @brief inputBackendByName * @param name The name of some input backend * @return Input backend instance if available */ MIDIInput* inputBackendByName(const QString name); /** * @brief outputBackendByName * @param name The name of some output backend * @return Output backend instance if available */ MIDIOutput* outputBackendByName(const QString name); /** * @brief findInput returns the backend corresponding * to the provided name, or a suitable input instead. * @param name The name of some input backend * @return Input backend instance if available */ MIDIInput* findInput(QString name); /** * @brief findOutput returns the backend corresponding * to the provided name, or a suitable output instead. * @param name The name of some output backend * @return Output backend instance if available */ MIDIOutput* findOutput(QString name); static const QString QSTR_DRUMSTICK; static const QString QSTR_DRUMSTICK_VERSION; static const QString QSTR_DRUMSTICKRT; static const QString QSTR_DRUMSTICKRT_GROUP; static const QString QSTR_DRUMSTICKRT_PUBLICNAMEIN; static const QString QSTR_DRUMSTICKRT_PUBLICNAMEOUT; static const QString QSTR_DRUMSTICKRT_EXCLUDED; static const QString QSTR_DRUMSTICKRT_PATH; private: class BackendManagerPrivate; QScopedPointer d; }; QString DRUMSTICK_EXPORT drumstickLibraryVersion(); /** @} */ }} // namespace drumstick::rt #endif // BACKENDMANAGER_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/alsaqueue.h0000644000000000000000000000013214200302440022512 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/alsaqueue.h0000644000175000001440000001374414200302440023304 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMSTICK_ALSAQUEUE_H #define DRUMSTICK_ALSAQUEUE_H #include extern "C" { #include } #include "macros.h" namespace drumstick { namespace ALSA { /** * @file alsaqueue.h * Classes managing ALSA Sequencer queues */ class MidiClient; class TimerId; /** * @addtogroup ALSAQueue ALSA Sequencer Queues * @{ * * @class QueueInfo * Queue information container. * * This class is used to hold some properties about an ALSA queue object. */ class DRUMSTICK_EXPORT QueueInfo { friend class MidiQueue; public: QueueInfo(); QueueInfo(const QueueInfo& other); explicit QueueInfo(snd_seq_queue_info_t* other); virtual ~QueueInfo(); QueueInfo* clone(); QueueInfo& operator=(const QueueInfo& other); int getInfoSize() const; int getId(); QString getName(); int getOwner(); bool isLocked(); unsigned int getFlags(); void setName(QString value); void setOwner(int value); void setLocked(bool locked); void setFlags(unsigned int value); private: snd_seq_queue_info_t* m_Info; }; /** * Queue status container. * * This class is used to retrieve some status information from an ALSA queue. */ class DRUMSTICK_EXPORT QueueStatus { friend class MidiQueue; public: QueueStatus(); QueueStatus(const QueueStatus& other); explicit QueueStatus(snd_seq_queue_status_t* other); virtual ~QueueStatus(); QueueStatus* clone(); QueueStatus& operator=(const QueueStatus& other); int getInfoSize() const; int getId(); int getEvents(); const snd_seq_real_time_t* getRealtime(); unsigned int getStatusBits(); bool isRunning(); double getClockTime(); snd_seq_tick_time_t getTickTime(); private: snd_seq_queue_status_t* m_Info; }; /** * Queue tempo container. * * This class is used to hold some tempo properties of an ALSA queue object. * The queue's resolution defines the meaning of the musical time, in ticks. It * is expressed in PPQ (parts per quarter), or ticks in a quarter note (crotchet). * The nominal tempo is usually expressed in BPM (beats per minute), or Maelzel * metronome units. It can be also given in microseconds per beat. The tempo skew * factor is given as two integer numbers: skew value and skew base, being the * factor the quotient of both quantities = value / base. Currently (ALSA <= 1.0.20) * you can only use the base constant 0x10000 (decimal 65536). */ class DRUMSTICK_EXPORT QueueTempo { friend class MidiQueue; public: QueueTempo(); QueueTempo(const QueueTempo& other); explicit QueueTempo(snd_seq_queue_tempo_t* other); virtual ~QueueTempo(); QueueTempo* clone(); QueueTempo& operator=(const QueueTempo& other); int getInfoSize() const; int getId(); int getPPQ(); unsigned int getSkewValue(); unsigned int getSkewBase(); unsigned int getTempo(); void setPPQ(int value); void setSkewValue(unsigned int value); void setTempo(unsigned int value); float getNominalBPM(); float getRealBPM(); void setTempoFactor(float value); void setNominalBPM(float value); protected: void setSkewBase(unsigned int value); private: snd_seq_queue_tempo_t* m_Info; }; /** * Queue timer container. * * This class is used to hold some properties about the Timer used with an ALSA * queue object. */ class DRUMSTICK_EXPORT QueueTimer { friend class MidiQueue; public: QueueTimer(); QueueTimer(const QueueTimer& other); explicit QueueTimer(snd_seq_queue_timer_t* other); virtual ~QueueTimer(); QueueTimer* clone(); QueueTimer& operator=(const QueueTimer& other); int getInfoSize() const; int getQueueId(); snd_seq_queue_timer_type_t getType(); const snd_timer_id_t* getId(); unsigned int getResolution(); void setType(snd_seq_queue_timer_type_t value); void setId(snd_timer_id_t* value); void setId(const TimerId& id); void setResolution(unsigned int value); private: snd_seq_queue_timer_t* m_Info; }; /** * Queue management. * * This class represents an ALSA sequencer queue object. */ class DRUMSTICK_EXPORT MidiQueue : public QObject { Q_OBJECT public: explicit MidiQueue(MidiClient* seq, QObject* parent = nullptr); MidiQueue(MidiClient* seq, const QueueInfo& info, QObject* parent = nullptr); MidiQueue(MidiClient* seq, const QString name, QObject* parent = nullptr); MidiQueue(MidiClient* seq, const int queue_id, QObject* parent = nullptr); virtual ~MidiQueue(); int getId() const { return m_Id; } void start(); void stop(); void continueRunning(); void clear(); void setTickPosition(snd_seq_tick_time_t pos); void setRealTimePosition(snd_seq_real_time_t* pos); QueueInfo& getInfo(); QueueStatus& getStatus(); QueueTempo& getTempo(); QueueTimer& getTimer(); int getUsage(); void setInfo(const QueueInfo& value); void setTempo(const QueueTempo& value); void setTimer(const QueueTimer& value); void setUsage(int used); private: bool m_allocated; int m_Id; MidiClient* m_MidiClient; QueueInfo m_Info; QueueTempo m_Tempo; QueueTimer m_Timer; QueueStatus m_Status; }; /** @} */ }} /* namespace drumstick::ALSA */ #endif //DRUMSTICK_ALSAQUEUE_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/pianopalette.h0000644000000000000000000000013214200302440023212 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/pianopalette.h0000644000175000001440000000727114200302440024002 0ustar00pedrousers00000000000000/* MIDI Virtual Piano Keyboard Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #ifndef PIANOPALETTE_H #define PIANOPALETTE_H #include #include #include #include #include "macros.h" /** * @file pianopalette.h * Piano Palette declarations */ namespace drumstick { namespace widgets { /** * @addtogroup Widgets * @{ * * @enum PalettePolicy * @brief The PalettePolicy enumeration. * * This enum describes the different kind of color palettes supported, which * can be used for highlight, background or foreground colors. */ enum PalettePolicy { PAL_SINGLE = 0, ///< Single highlihgting color for all keys PAL_DOUBLE = 1, ///< Two highlihgting colors (naturals/alterations) PAL_CHANNELS = 2, ///< Different highlihgting colors for each channel PAL_SCALE = 3, ///< Background colors for each chromatic scale note PAL_KEYS = 4, ///< Two background colors (naturals/alterations) PAL_FONT = 5, ///< Foreground font colors for names PAL_HISCALE = 6 ///< Highlighting colors for each chromatic scale note }; /** * @brief The PianoPalette class * * PianoPalette represents a set of colors used to paint the PianoKeybd widgets */ class DRUMSTICK_EXPORT PianoPalette { Q_GADGET Q_DECLARE_TR_FUNCTIONS(PianoPalette) Q_ENUM(PalettePolicy) public: explicit PianoPalette(const int id); virtual ~PianoPalette() = default; void resetColors(); void retranslateStrings(); int paletteId() const; int getNumColors() const; bool isHighLight() const; bool isBackground() const; bool isForeground() const; QString paletteName() const; void setPaletteName(const QString& name); QString paletteText() const; void setPaletteText(const QString& text); QColor getColor(const int i) const; void setColor(const int n, const QString& s, const QColor& c); void setColor(const int n, const QColor& c); QString getColorName(const int i) const; void setColorName(const int n, const QString& s); void saveColors() const; void loadColors(); bool operator==(const PianoPalette& other) const; bool operator!=(const PianoPalette& other) const; static const QString QSTR_PALETTEPREFIX; friend QDataStream &operator<<(QDataStream& stream, const PianoPalette& palette); friend QDataStream &operator>>(QDataStream& stream, PianoPalette& palette); protected: void initialize(); void resetPaletteSingle(); void resetPaletteDouble(); void resetPaletteChannels(); void resetPaletteScale(); void resetPaletteKeys(); void resetPaletteFont(); void retranslatePaletteSingle(); void retranslatePaletteDouble(); void retranslatePaletteChannels(); void retranslatePaletteScale(); void retranslatePaletteKeys(); void retranslatePaletteFont(); int m_paletteId; QList m_colors; QList m_names; QString m_paletteName; QString m_paletteText; }; /** @} */ }} // namespace drumstick::widgets #endif // PIANOPALETTE_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/alsaevent.h0000644000000000000000000000013214200302440022507 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/alsaevent.h0000644000175000001440000006063614200302440023303 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMSTICK_ALSAEVENT_H #define DRUMSTICK_ALSAEVENT_H extern "C" { #include } #include #include #include "macros.h" namespace drumstick { namespace ALSA { /** * @file alsaevent.h * Classes managing ALSA Sequencer events. * * @addtogroup ALSAEvent ALSA Sequencer Events * @{ */ /** * 8-bit unsigned number to be used as a MIDI message parameter */ typedef quint8 MidiByte; /** * Constant SequencerEventType is the QEvent::type() of any SequencerEvent * object to be used to check the argument in QObject::customEvent(). */ const QEvent::Type SequencerEventType = QEvent::Type(QEvent::User + 4154); // :-) /** * Base class for the event's hierarchy * * All event classes share this base class. It provides several common * properties and methods. */ class DRUMSTICK_EXPORT SequencerEvent : public QEvent { public: SequencerEvent(); SequencerEvent(const SequencerEvent& other); explicit SequencerEvent(const snd_seq_event_t* event); SequencerEvent& operator=(const SequencerEvent& other); void setSequencerType(const snd_seq_event_type_t eventType); /** * Gets the sequencer event type. * @return The sequencer event type. * @see setSequencerType() */ snd_seq_event_type_t getSequencerType() const { return m_event.type; } void setDestination(const unsigned char client, const unsigned char port); void setSource(const unsigned char port); /** * Gets the source client id. * @return The source client id. * @see setSource() */ unsigned char getSourceClient() const { return m_event.source.client; } /** * Gets the source port id. * @return The source port id. * @see setSource() */ unsigned char getSourcePort() const { return m_event.source.port; } /** * Gets the tick time of the event. * @return The tick time. * @see scheduleTick() */ snd_seq_tick_time_t getTick() const { return m_event.time.tick; } /** * Gets the seconds of the event's real time. * @return The seconds of the time. * @see scheduleReal(), getRealTimeNanos() */ unsigned int getRealTimeSecs() const { return m_event.time.time.tv_sec; } /** * Gets the nanoseconds of the event's real time. * @return The nanoseconds of the time. * @see scheduleReal(), getRealTimeSecs() */ unsigned int getRealTimeNanos() const { return m_event.time.time.tv_nsec; } void setSubscribers(); void setBroadcast(); void setDirect(); void scheduleTick(const int queue, const int tick, const bool relative); void scheduleReal(const int queue, const ulong secs, const ulong nanos, const bool relative); void setPriority(const bool high); /** * Gets the tag of the event * @return The event's tag * @see setTag() */ unsigned char getTag() const { return m_event.tag; } void setTag(const unsigned char aTag); unsigned int getRaw32(const unsigned int n) const; void setRaw32(const unsigned int n, const unsigned int value); unsigned char getRaw8(const unsigned int n) const; void setRaw8(const unsigned int n, const unsigned char value); /** * Gets the handle of the event * @return The event's handle */ snd_seq_event_t* getHandle() { return &m_event; } int getEncodedLength(); static bool isSubscription(const SequencerEvent* event); static bool isPort(const SequencerEvent* event); static bool isClient(const SequencerEvent* event); static bool isConnectionChange(const SequencerEvent* event); static bool isChannel(const SequencerEvent* event); virtual SequencerEvent* clone() const; protected: Q_DECL_DEPRECATED void free(); /** * ALSA sequencer event record. * @see https://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__event.html */ snd_seq_event_t m_event; }; /** * Base class for the events having a Channel property */ class DRUMSTICK_EXPORT ChannelEvent : public SequencerEvent { public: /** Default constructor */ ChannelEvent() : SequencerEvent() {} /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit ChannelEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} /** * Sets the channel of the event * @param c A channel, between 0 and 15. * @see getChannel() */ void setChannel(const MidiByte c) { m_event.data.note.channel = (c & 0xf); } /** * Gets the event's channel * @return The event's channel * @see setChannel() */ int getChannel() const { return m_event.data.note.channel; } virtual ChannelEvent* clone() const override; }; /** * Base class for the events having Key and Velocity properties. */ class DRUMSTICK_EXPORT KeyEvent : public ChannelEvent { public: /** Default constructor */ KeyEvent() : ChannelEvent() {} /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit KeyEvent(const snd_seq_event_t* event) : ChannelEvent(event) {} /** * Gets the MIDI note of this event. * @return The event's MIDI note. * @see setKey() */ int getKey() const { return m_event.data.note.note; } /** * Sets the MIDI note of this event. * @param b A MIDI note, between 0 and 127. * @see getKey() */ void setKey(const MidiByte b) { m_event.data.note.note = b; } /** * Gets the note velocity of this event. * @return The event's note velocity. * @see setVelocity() */ int getVelocity() const { return m_event.data.note.velocity; } /** * Sets the note velocity of this event. * @param b A velocity value, between 0 and 127. * @see getVelocity() */ void setVelocity(const MidiByte b) { m_event.data.note.velocity = b; } virtual KeyEvent* clone() const override; }; /** * Class representing a note event with duration * * Note events are converted into two MIDI events, a note-on and a note-off * over the wire. */ class DRUMSTICK_EXPORT NoteEvent : public KeyEvent { public: /** Default constructor */ NoteEvent() : KeyEvent() { m_event.type = SND_SEQ_EVENT_NOTE; } /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit NoteEvent(const snd_seq_event_t* event) : KeyEvent(event) {} /** * Constructor * @param ch MIDI Channel * @param key a MIDI note number * @param vel a MIDI velocity value * @param dur duration of the note in ticks */ NoteEvent(const int ch, const int key, const int vel, const int dur); /** * Gets the note's duration * @return The duration of the event * @see setDuration() */ ulong getDuration() const { return m_event.data.note.duration; } /** * Sets the note's duration * @param d The duration of the event * @see getDuration() */ void setDuration(const ulong d) { m_event.data.note.duration = d; } virtual NoteEvent* clone() const override; }; /** * Event representing a note-on MIDI event */ class DRUMSTICK_EXPORT NoteOnEvent : public KeyEvent { public: /** Default constructor */ NoteOnEvent() : KeyEvent() { m_event.type = SND_SEQ_EVENT_NOTEON; } /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit NoteOnEvent(const snd_seq_event_t* event) : KeyEvent(event) {} /** * Constructor * @param ch MIDI Channel * @param key a MIDI note number * @param vel a MIDI velocity value */ NoteOnEvent(const int ch, const int key, const int vel); virtual NoteOnEvent* clone() const override; }; /** * Event representing a note-off MIDI event */ class DRUMSTICK_EXPORT NoteOffEvent : public KeyEvent { public: /** Default constructor */ NoteOffEvent() : KeyEvent() { m_event.type = SND_SEQ_EVENT_NOTEOFF; } /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit NoteOffEvent(const snd_seq_event_t* event) : KeyEvent(event) {} /** * Constructor * @param ch MIDI Channel * @param key a MIDI note number * @param vel a MIDI velocity value */ NoteOffEvent(const int ch, const int key, const int vel); virtual NoteOffEvent* clone() const override; }; /** * Event representing a MIDI key pressure, or polyphonic after-touch event */ class DRUMSTICK_EXPORT KeyPressEvent : public KeyEvent { public: /** Default constructor */ KeyPressEvent() : KeyEvent() { m_event.type = SND_SEQ_EVENT_KEYPRESS; } /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit KeyPressEvent(const snd_seq_event_t* event) : KeyEvent(event) {} /** * Constructor * @param ch MIDI Channel * @param key a MIDI note number * @param vel a MIDI velocity value */ KeyPressEvent(const int ch, const int key, const int vel); virtual KeyPressEvent* clone() const override; }; /** * Event representing a MIDI control change event */ class DRUMSTICK_EXPORT ControllerEvent : public ChannelEvent { public: /** Default constructor */ ControllerEvent() : ChannelEvent() {} /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit ControllerEvent(const snd_seq_event_t* event) : ChannelEvent(event) {} /** * Constructor * @param ch MIDI Channel * @param cc a MIDI controller * @param val a value */ ControllerEvent(const int ch, const int cc, const int val); /** * Gets the controller event's parameter. * @return The controller event's parameter. * @see setParam() */ uint getParam() const { return m_event.data.control.param; } /** * Sets the controller event's parameter. * @param p The controller event's parameter. * @see getParam() */ void setParam( const uint p ) { m_event.data.control.param = p; } /** * Gets the controller event's value. * @return The controller event's value. * @see setValue() */ int getValue() const { return m_event.data.control.value; } /** * Sets the controller event's value. * @param v The controller event's value. * @see getValue() */ void setValue( const int v ) { m_event.data.control.value = v; } virtual ControllerEvent* clone() const override; }; /** * Event representing a MIDI program change event */ class DRUMSTICK_EXPORT ProgramChangeEvent : public ChannelEvent { public: /** Default constructor */ ProgramChangeEvent() : ChannelEvent() { m_event.type = SND_SEQ_EVENT_PGMCHANGE; } /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit ProgramChangeEvent(const snd_seq_event_t* event) : ChannelEvent(event) {} /** * Constructor * @param ch MIDI Channel * @param val a value */ ProgramChangeEvent(const int ch, const int val); /** * Gets the MIDI program number * @return the MIDI program number */ int getValue() const { return m_event.data.control.value; } /** * Sets the MIDI program number * @param v the MIDI program number */ void setValue( const int v ) { m_event.data.control.value = v; } virtual ProgramChangeEvent* clone() const override; }; /** * Event representing a MIDI bender, or pitch wheel event */ class DRUMSTICK_EXPORT PitchBendEvent : public ChannelEvent { public: /** Default constructor */ PitchBendEvent() : ChannelEvent() { m_event.type = SND_SEQ_EVENT_PITCHBEND; } /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit PitchBendEvent(const snd_seq_event_t* event) : ChannelEvent(event) {} /** * Constructor * @param ch MIDI Channel * @param val a value */ PitchBendEvent(const int ch, const int val); /** * Gets the MIDI pitch bend value, zero centered from -8192 to 8191 * @return the MIDI pitch bend value */ int getValue() const { return m_event.data.control.value; } /** * Sets the MIDI pitch bend value, zero centered from -8192 to 8191 * @param v the MIDI pitch bend value */ void setValue( const int v ) { m_event.data.control.value = v; } virtual PitchBendEvent* clone() const override; }; /** * Event representing a MIDI channel pressure or after-touch event */ class DRUMSTICK_EXPORT ChanPressEvent : public ChannelEvent { public: /** Default constructor */ ChanPressEvent() : ChannelEvent() { m_event.type = SND_SEQ_EVENT_CHANPRESS; } /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit ChanPressEvent( const snd_seq_event_t* event ) : ChannelEvent(event) {} /** * Constructor * @param ch MIDI Channel * @param val a value */ ChanPressEvent( const int ch, const int val ); /** * Gets the channel aftertouch value * @return the channel aftertouch value */ int getValue() const { return m_event.data.control.value; } /** * Sets the channel aftertouch value * @param v the channel aftertouch value */ void setValue( const int v ) { m_event.data.control.value = v; } virtual ChanPressEvent* clone() const override; }; /** * Base class for variable length events */ class DRUMSTICK_EXPORT VariableEvent : public SequencerEvent { public: VariableEvent(); explicit VariableEvent(const snd_seq_event_t* event); explicit VariableEvent(const QByteArray& data); VariableEvent(const VariableEvent& other); VariableEvent(const unsigned int datalen, char* dataptr); VariableEvent& operator=(const VariableEvent& other); /** * Gets the data length * @return the data length */ unsigned int getLength() const { return m_event.data.ext.len; } /** * Gets the data pointer * @return the data pointer */ const char* getData() const { return static_cast(m_event.data.ext.ptr); } virtual VariableEvent* clone() const override; protected: QByteArray m_data; }; /** * Event representing a MIDI system exclusive event */ class DRUMSTICK_EXPORT SysExEvent : public VariableEvent { public: SysExEvent(); explicit SysExEvent(const snd_seq_event_t* event); explicit SysExEvent(const QByteArray& data); SysExEvent(const SysExEvent& other); SysExEvent(const unsigned int datalen, char* dataptr); virtual SysExEvent* clone() const override; }; /** * Event representing a SMF text event * * This event type is not intended to be transmitted over the wire to an * external device, but it is useful for sequencer programs or MIDI applications */ class DRUMSTICK_EXPORT TextEvent : public VariableEvent { public: TextEvent(); explicit TextEvent(const snd_seq_event_t* event); explicit TextEvent(const QString& text, const int textType = 1); TextEvent(const TextEvent& other); TextEvent(const unsigned int datalen, char* dataptr); QString getText() const; int getTextType() const; virtual TextEvent* clone() const override; protected: int m_textType; }; /** * Generic event */ class DRUMSTICK_EXPORT SystemEvent : public SequencerEvent { public: /** Default constructor */ SystemEvent() : SequencerEvent() {} /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit SystemEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} explicit SystemEvent(const snd_seq_event_type_t type); virtual SystemEvent* clone() const override; }; /** * ALSA Event representing a queue control command * * This event is used to schedule changes to the ALSA queues */ class DRUMSTICK_EXPORT QueueControlEvent : public SequencerEvent { public: /** Default constructor */ QueueControlEvent() : SequencerEvent() {} /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit QueueControlEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} QueueControlEvent(const snd_seq_event_type_t type, const int queue, const int value); /** * Gets the queue number * @return the queue number */ int getQueue() const { return m_event.data.queue.queue; } /** * Sets the queue number * @param q the queue number */ void setQueue(const uchar q) { m_event.data.queue.queue = q; } /** * Gets the event's value * @return the event's value */ int getValue() const { return m_event.data.queue.param.value; } /** * Sets the event's value * @param val the event's value */ void setValue(const int val) { m_event.data.queue.param.value = val; } /** * Gets the queue position * @return the queue position */ uint getPosition() const { return m_event.data.queue.param.position; } /** * Sets the queue position * @param pos the queue position */ void setPosition(const uint pos) { m_event.data.queue.param.position = pos; } /** * Gets the musical time in ticks * @return the musical time in ticks */ snd_seq_tick_time_t getTickTime() const { return m_event.data.queue.param.time.tick; } /** * Sets the musical time in ticks * @param t the musical time in ticks */ void setTickTime(const snd_seq_tick_time_t t) { m_event.data.queue.param.time.tick = t; } /** * Gets the skew base * @return the skew base */ uint getSkewBase() const { return m_event.data.queue.param.skew.base; } /** * Sets the skew base, should be 65536 * @param base the skew base, should be 65536 */ void setSkewBase(const uint base) { m_event.data.queue.param.skew.base = base; } /** * Gets the skew value * @return the skew value */ uint getSkewValue() const { return m_event.data.queue.param.skew.value; } /** * Sets the skew value * @param val the skew value */ void setSkewValue(const uint val) {m_event.data.queue.param.skew.value = val; } virtual QueueControlEvent* clone() const override; }; /** * Generic event having a value property */ class DRUMSTICK_EXPORT ValueEvent : public SequencerEvent { public: /** Default constructor */ ValueEvent() : SequencerEvent() {} /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit ValueEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} ValueEvent(const snd_seq_event_type_t type, const int val); /** * Gets the event's value * @return the event's value */ int getValue() const { return m_event.data.control.value; } /** * Sets the event's value * @param v the event's value */ void setValue( const int v ) { m_event.data.control.value = v; } virtual ValueEvent* clone() const override; }; /** * ALSA Event representing a tempo change for an ALSA queue */ class DRUMSTICK_EXPORT TempoEvent : public QueueControlEvent { public: /** Default constructor */ TempoEvent() : QueueControlEvent() {} /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit TempoEvent(const snd_seq_event_t* event) : QueueControlEvent(event) {} TempoEvent(const int queue, const int tempo); virtual TempoEvent* clone() const override; }; /** * ALSA Event representing a subscription between two ALSA clients and ports */ class DRUMSTICK_EXPORT SubscriptionEvent : public SequencerEvent { public: /** Default constructor */ SubscriptionEvent() : SequencerEvent() {} /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit SubscriptionEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} /** * Returns true if the event was a subscribed port * @return whether the event was a subscribed port */ bool subscribed() const { return (m_event.type == SND_SEQ_EVENT_PORT_SUBSCRIBED); } /** * Returns true if the event was an unsubscribed port * @return whether the event was an unsubscribed port */ bool unsubscribed() const { return (m_event.type == SND_SEQ_EVENT_PORT_UNSUBSCRIBED); } /** * Gets the sender client number * @return the sender client number */ int getSenderClient() const { return m_event.data.connect.sender.client; } /** * Gets the sender port number * @return the sender port number */ int getSenderPort() const { return m_event.data.connect.sender.port; } /** * Gets the destination client number * @return the destination client number */ int getDestClient() const { return m_event.data.connect.dest.client; } /** * Gets the destination port number * @return the destination port number */ int getDestPort() const { return m_event.data.connect.dest.port; } virtual SubscriptionEvent* clone() const override; }; /** * ALSA Event representing a change on some ALSA sequencer client on the system */ class DRUMSTICK_EXPORT ClientEvent : public SequencerEvent { public: /** Default constructor */ ClientEvent() : SequencerEvent() {} /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit ClientEvent(const snd_seq_event_t* event) : SequencerEvent(event) {} /** * Gets the client number * @return the client number */ int getClient() const { return m_event.data.addr.client; } virtual ClientEvent* clone() const override; }; /** * ALSA Event representing a change on some ALSA sequencer port on the system */ class DRUMSTICK_EXPORT PortEvent : public ClientEvent { public: /** Default constructor */ PortEvent() : ClientEvent() {} /** * Constructor from an ALSA event record * @param event an ALSA event record */ explicit PortEvent(const snd_seq_event_t* event) : ClientEvent(event) {} /** * Gets the port number * @return the port number */ int getPort() const { return m_event.data.addr.port; } virtual PortEvent* clone() const override; }; /** * Auxiliary class to remove events from an ALSA queue * @see MidiClient::removeEvents() */ class DRUMSTICK_EXPORT RemoveEvents { public: friend class MidiClient; public: RemoveEvents(); RemoveEvents(const RemoveEvents& other); explicit RemoveEvents(snd_seq_remove_events_t* other); virtual ~RemoveEvents(); RemoveEvents* clone(); RemoveEvents& operator=(const RemoveEvents& other); int getSizeOfInfo() const; int getChannel(); unsigned int getCondition(); const snd_seq_addr_t* getDest(); int getEventType(); int getQueue(); int getTag(); const snd_seq_timestamp_t* getTime(); void setChannel(int chan); void setCondition(unsigned int cond); void setDest(const snd_seq_addr_t* dest); void setEventType(int type); void setQueue(int queue); void setTag(int tag); void setTime(const snd_seq_timestamp_t* time); private: snd_seq_remove_events_t* m_Info; }; /** * Auxiliary class to translate between raw MIDI streams and ALSA events */ class DRUMSTICK_EXPORT MidiCodec : public QObject { Q_OBJECT public: explicit MidiCodec(int bufsize, QObject* parent = nullptr); ~MidiCodec(); void init(); long decode(unsigned char *buf, long count, const snd_seq_event_t *ev); long encode(const unsigned char *buf, long count, snd_seq_event_t *ev); long encode(int c, snd_seq_event_t *ev); void enableRunningStatus(bool enable); void resetEncoder(); void resetDecoder(); void resizeBuffer(int bufsize); private: snd_midi_event_t* m_Info; }; /** @} */ }} /* namespace drumstick::ALSA */ #endif //DRUMSTICK_ALSAEVENT_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/rmid.h0000644000000000000000000000013214200302440021460 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/rmid.h0000644000175000001440000001226114200302440022243 0ustar00pedrousers00000000000000/* Standard RIFF MIDI Component Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef RMIDI_H #define RMIDI_H #include #include #include #include #include "macros.h" /** * @file rmid.h * RIFF MIDI Files Input */ namespace drumstick { namespace File { /** * @addtogroup RMID RIFF MIDI File Parser (Input) * @{ */ /** * RIFF MIDI file format (input only) * * This class is used to parse RIFF MIDI Files * @since 2.4.0 */ class DRUMSTICK_EXPORT Rmidi : public QObject { Q_OBJECT public: explicit Rmidi(QObject * parent = nullptr); virtual ~Rmidi(); void readFromFile(QString fileName); void readFromStream(QDataStream* ds); signals: /** * @brief signalRMidInfo is emitted for each RIFF INFO element * @param infoType Type of data (chunk ID) as defined in the spec (Source: www.midi.org rp29spec.pdf). * * * IARL Archival Location. Indicates where the subject of the file is archived. * * IART Artist. Lists the artist (author) of the original subject of the file. For example: Les Getalong. * * ICMS Commissioned. Lists the name of the person or organization that commissioned the subject of the file. For example: Acme Consolidated GameWorks. * * ICMT Comments. Provides general comments about the file or the subject of the file. If the comment is several sentences long, end each sentence with a period. Do not include newline characters. * * ICOP Copyright. Records the copyright information for the file. For example: Copyright Acme Consolidated GameWorks 1991. If there are multiple copyrights, separate them by a semicolon followed by a space. * * ICRD Creation date. Specifies the date the subject of the file was created. List dates in year-month-day format, padding one-digit months and days with a zero on the left. For example: 1553-05-03 for May 3, 1553. The year should always be given using four digits. * * IENG Engineer. Stores the name of the engineer who worked on the file. If there are multiple engineers, separate the names by a semicolon and a blank. For example: Smith, John; Adams, Joe. * * IGNR Genre. Describes the original work, such as jazz, classical, rock, techno, rave, neo british pop grunge metal, etc. * * IKEY Keywords. Provides a list of keywords that refer to the file or subject of the file. Separate multiple keywords with a semicolon and a blank. For example: FX; visitation; space alien. * * IMED Medium. Describes the original subject of the file, such as record, CD and so forth. * * INAM Name. Stores the title of the subject of the file, such as Seattle From Above. * * IPRD Product. Specifies the name of the title the file was originally intended for, such as Galactic Ambassadors V. * * ISBJ Subject. Describes the contents of the file, such as Music of the Gnu Whirled Order. * * ISFT Software. Identifies the name of the software package used to create the file, such as Crash Compactor, Acme Consolidated Sonic Booms. * * ISRC Source. Identifies the name of the person or organization who supplied the original subject of the file. For example: Acme Hysterical Media Archives. * * ISRF Source Form. Identifies the original form of the material that was digitized, such as record, sampling CD, TV sound track and so forth. This is not necessarily the same as IMED. * * ITCH Technician. Identifies the technician who sampled the subject file. For example: Smith, John. * * @param info Text data */ void signalRiffInfo(const QString& infoType, const QByteArray& info); /** * @brief signalRiffData is emitted for each RMID data element * * The handler of this event should use the method QSmf::readFromStream() to * parse the contents of the SMF data element. * * @param dataType may only be "RMID" for RIFF RMID files * @param data binary payload, in RMID files is a Standard MIDI File structure */ void signalRiffData(const QString& dataType, const QByteArray& data); private: void read(); void processINFO(int size); void processList(int size); void processRMID(int size); void processData(const QString& dataType, int size); void skip(quint32 cktype, int size); quint32 readExpectedChunk(quint32 cktype); quint32 readChunk(quint32& cktype); quint32 readChunkID(); QByteArray readByteArray(int size); QString toString(quint32 ckid); private: QDataStream *m_stream; QString m_fileName; }; /** @} */ }} // namespace drumstick::File #endif // RMIDI_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/rtmidioutput.h0000644000000000000000000000013214200302440023276 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/rtmidioutput.h0000644000175000001440000002075414200302440024067 0ustar00pedrousers00000000000000/* Drumstick MIDI realtime input-output Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef MIDIOUTPUT_H #define MIDIOUTPUT_H #include #include #include #include #include #include "macros.h" /** * @file rtmidioutput.h * Realtime MIDI output interface */ namespace drumstick { namespace rt { /** * @addtogroup RT * @{ */ const quint8 MIDI_STD_CHANNELS = 16; ///< Standard number of MIDI channels const quint8 MIDI_GM_STD_DRUM_CHANNEL = (10-1); ///< Number of the GM percussion channel const quint8 MIDI_CONTROL_MSB_BANK_SELECT = 0x00; ///< MIDI Controller number for MSB Bank number const quint8 MIDI_CONTROL_MSB_MAIN_VOLUME = 0x07; ///< MIDI Controller number for MSB volume const quint8 MIDI_CONTROL_LSB_BANK_SELECT = 0x20; ///< MIDI Controller number for LSB Bank number const quint8 MIDI_CONTROL_REVERB_SEND = 0x5b; ///< MIDI Controller number for Reverb send const quint8 MIDI_CONTROL_ALL_SOUNDS_OFF = 0x78; ///< MIDI Controller number for All sounds off const quint8 MIDI_CONTROL_ALL_NOTES_OFF = 0x7b; ///< MIDI Controller number for All notes off const quint8 MIDI_CONTROL_RESET_CONTROLLERS = 0x79; ///< MIDI Controller number for Reset all controllers const quint8 MIDI_STATUS_NOTEOFF = 0x80; ///< MIDI status byte for NOTE OFF messages const quint8 MIDI_STATUS_NOTEON = 0x90; ///< MIDI status byte for NOTE ON messages const quint8 MIDI_STATUS_KEYPRESURE = 0xa0; ///< MIDI status byte for KEY pressure messages const quint8 MIDI_STATUS_CONTROLCHANGE = 0xb0; ///< MIDI status byte for CONTROL change messages const quint8 MIDI_STATUS_PROGRAMCHANGE = 0xc0; ///< MIDI status byte for PROGRAM change messages const quint8 MIDI_STATUS_CHANNELPRESSURE = 0xd0; ///< MIDI status byte for CHANNEL PRESSURE messages const quint8 MIDI_STATUS_PITCHBEND = 0xe0; ///< MIDI status byte for PITCH bend messages const quint8 MIDI_STATUS_SYSEX = 0xf0; ///< MIDI status byte for System Exclusive START messages const quint8 MIDI_STATUS_ENDSYSEX = 0xf7; ///< MIDI status byte for System Exclusive END messages const quint8 MIDI_STATUS_REALTIME = 0xf8; ///< Minimum value for MIDI Realtime messages status const quint8 MIDI_STATUS_MASK = 0xf0; ///< Mask to extract the MIDI status byte from a MIDI message const quint8 MIDI_CHANNEL_MASK = 0x0f; ///< Mask to extract the MIDI channel byte from a MIDI message const quint8 MIDI_COMMON_QTRFRAME = 0xF1; ///< MIDI Quarter frame status message const quint8 MIDI_COMMON_SONGPP = 0xF2; ///< MIDI Song Position status message const quint8 MIDI_COMMON_SONGSELECT = 0xF3; ///< MIDI Song Select status message const quint8 MIDI_COMMON_TUNEREQ = 0xF6; ///< MIDI Tune Request status message const quint8 MIDI_REALTIME_CLOCK = 0xF8; ///< MIDI Clock status message const quint8 MIDI_REALTIME_START = 0xFA; ///< MIDI Start status message const quint8 MIDI_REALTIME_CONTINUE = 0xFB; ///< MIDI Continue status message const quint8 MIDI_REALTIME_STOP = 0xFC; ///< MIDI Stop status message const quint8 MIDI_REALTIME_SENSING = 0xFE; ///< MIDI Active Sensing status message const quint8 MIDI_REALTIME_RESET = 0xFF; ///< MIDI Reset status message /** * @brief MIDI_LSB is a function to extract the least significative byte of a MIDI value * @param x a MIDI integer value * @return the least significative byte of the input value */ inline int MIDI_LSB(int x) { return (x % 0x80); } /** * @brief MIDI_MSB is a function to extract the most significative byte of a MIDI value * @param x MIDI integer value * @return the most significative byte of the input value */ inline int MIDI_MSB(int x) { return (x / 0x80); } /** * @brief MIDIConnection represents a connection identifier * * MIDIConnection is an alias for QPair where the * first component is a QString representing the symbolic name of the MIDI Port * and the second component is a QVariant that represents the native identification * of the MIDI port, which may be a string, a number, or any other data type * accepted as a QVariant. */ typedef QPair MIDIConnection; /** * @brief MIDI OUT interface */ class DRUMSTICK_EXPORT MIDIOutput : public QObject { Q_OBJECT public: /** * @brief MIDIOutput constructor * @param parent */ explicit MIDIOutput(QObject *parent = nullptr) : QObject(parent) {} /** * @brief ~MIDIOutput destructor */ virtual ~MIDIOutput() = default; /** * @brief initialize * @param settings */ virtual void initialize(QSettings* settings) = 0; /** * @brief backendName * @return plugin name */ virtual QString backendName() = 0; /** * @brief publicName * @return MIDI port name */ virtual QString publicName() = 0; /** * @brief setPublicName * @param name MIDI port name */ virtual void setPublicName(QString name) = 0; /** * @brief connections * @param advanced whether the advanced connections are included or not * @return list of available MIDI ports */ virtual QList connections(bool advanced = false) = 0; /** * @brief setExcludedConnections * @param conns */ virtual void setExcludedConnections(QStringList conns) = 0; /** * @brief open the MIDI port by name * @param conn the MIDI connection to be opened */ virtual void open(const MIDIConnection& conn) = 0; /** * @brief close the MIDI port */ virtual void close() = 0; /** * @brief currentConnection * @return name of the current connection if it is opened */ virtual MIDIConnection currentConnection() = 0; public Q_SLOTS: /** * @brief sendNoteOff 0x8 * @param chan * @param note * @param vel */ virtual void sendNoteOff(int chan, int note, int vel) = 0; /** * @brief sendNoteOn 0x9 * @param chan * @param note * @param vel */ virtual void sendNoteOn(int chan, int note, int vel) = 0; /** * @brief sendKeyPressure 0xA * @param chan * @param note * @param value */ virtual void sendKeyPressure(int chan, int note, int value) = 0; /** * @brief sendController 0xB * @param chan * @param control * @param value */ virtual void sendController(int chan, int control, int value) = 0; /** * @brief sendProgram 0xC * @param chan * @param program */ virtual void sendProgram(int chan, int program) = 0; /** * @brief sendChannelPressure 0xD * @param chan * @param value */ virtual void sendChannelPressure(int chan, int value) = 0; /** * @brief sendPitchBend 0xE * @param chan * @param value */ virtual void sendPitchBend(int chan, int value) = 0; /** * @brief sendSysex * @param data 0xF0 ... 0xF7 */ virtual void sendSysex(const QByteArray& data) = 0; /** * @brief sendSystemMsg * @param status 0xF */ virtual void sendSystemMsg(const int status) = 0; }; /** @} */ }} // namespace drumstick::rt Q_DECLARE_INTERFACE(drumstick::rt::MIDIOutput, "net.sourceforge.drumstick.rt.MIDIOutput/2.0") Q_DECLARE_METATYPE(drumstick::rt::MIDIConnection) #endif /* MIDIOUTPUT_H */ drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/pianokeybd.h0000644000000000000000000000013214200302440022652 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/pianokeybd.h0000644000175000001440000002634014200302440023440 0ustar00pedrousers00000000000000/* Virtual Piano Widget for Qt5 Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #ifndef PIANOKEYBD_H #define PIANOKEYBD_H #include #include #include #include "macros.h" #include "pianopalette.h" /** * @file pianokeybd.h * Piano Keyboard Widget */ namespace drumstick { namespace widgets { /** * @addtogroup Widgets * @{ * * @class RawKbdHandler * @brief The RawKbdHandler class callbacks * * RawKbdHandler provides callbacks for low level computer keyboard events */ class RawKbdHandler { public: virtual ~RawKbdHandler() = default; /** * @brief handleKeyPressed handles low level computer keyboard press events * @param keycode The low level key code pressed * @return whether the event has been processed or not */ virtual bool handleKeyPressed(int keycode) = 0; /** * @brief handleKeyReleased handles low level computer keyboard reelase events * @param keycode The low level key code released * @return whether the event has been processed or not */ virtual bool handleKeyReleased(int keycode) = 0; }; /** * @brief The PianoHandler class callbacks * * This class provides handler methods for note events. This class must be * inherited and implemented by a program using also PianoKeybd to receive the * note events generated from a computer keyboard, mouse or touch events. It is * provided using the method @ref PianoKeybd::setPianoHandler() and can be retrieved * using @ref PianoKeybd::getPianoHandler(). This mechanism is an option alternative * to proces signals @ref PianoKeybd::noteOn() and @ref PianoKeybd::noteOff() . */ class PianoHandler { public: virtual ~PianoHandler() = default; /** * @brief noteOn handles MIDI note on events * @param note MIDI note number * @param vel MIDI velocity */ virtual void noteOn( const int note, const int vel ) = 0; /** * @brief noteOff handles MIDI note off events * @param note MIDI note number * @param vel MIDI velocity */ virtual void noteOff( const int note, const int vel ) = 0; }; /** * @brief KeyboardMap * * KeyboardMap represents a mapping definition to translate from * computer keyboard keys and MIDI notes, either for alphanumeric * or low level (raw) events. */ typedef QHash KeyboardMap; extern DRUMSTICK_EXPORT KeyboardMap g_DefaultKeyMap; ///< Global Key Map Variable extern DRUMSTICK_EXPORT KeyboardMap g_DefaultRawKeyMap; ///< Global Raw Key Map Variable const int DEFAULTSTARTINGKEY = 9; ///< Default starting key (A) const int DEFAULTBASEOCTAVE = 1; ///< Default base octave const int DEFAULTNUMBEROFKEYS = 88; ///< Default number of piano keys /** * @brief Labels Visibility */ enum LabelVisibility { ShowNever, ///< Don't show note names ShowMinimum, ///< Show only note C names ShowActivated, ///< Show names when notes are activated ShowAlways ///< Show always note names }; /** * @brief Labels for Alterations */ enum LabelAlteration { ShowSharps, ///< Show sharps on black keys ShowFlats, ///< Show flats on black keys ShowNothing ///< Do not show names on black keys }; /** * @brief Labels Orientation */ enum LabelOrientation { HorizontalOrientation, ///< Show horizontal names VerticalOrientation, ///< Show vertical names AutomaticOrientation ///< Show horizonal or vertical names depending on the size }; /** * @brief Labels Naming */ enum LabelNaming { StandardNames, ///< Show standard names CustomNamesWithSharps, ///< Show custom names with sharps CustomNamesWithFlats ///< Show custom names with flats }; /** * @brief Labels Central Octave */ enum LabelCentralOctave { OctaveNothing = -1, ///< Don't show octave numbers OctaveC3, ///< Central C, MIDI note #60 is C3 OctaveC4, ///< Central C, MIDI note #60 is C4 OctaveC5 ///< Central C, MIDI note #60 is C5 }; /** * @brief The PianoKeybd class * * This class is a widget providing the look and behavior of a musical piano keyboard. * It is implemented as a QGraphicsView displaying the contents of a QGraphicsScene (PianoScene). */ class DRUMSTICK_EXPORT PianoKeybd : public QGraphicsView, public RawKbdHandler { Q_OBJECT Q_PROPERTY( int baseOctave READ baseOctave WRITE setBaseOctave ) Q_PROPERTY( int numKeys READ numKeys WRITE setNumKeys ) Q_PROPERTY( int rotation READ getRotation WRITE setRotation ) Q_PROPERTY( QColor keyPressedColor READ getKeyPressedColor WRITE setKeyPressedColor ) Q_PROPERTY( LabelVisibility showLabels READ showLabels WRITE setShowLabels ) Q_PROPERTY( LabelAlteration alterations READ labelAlterations WRITE setLabelAlterations ) Q_PROPERTY( LabelOrientation labelOrientation READ labelOrientation WRITE setLabelOrientation ) Q_PROPERTY( LabelCentralOctave labelOctave READ labelOctave WRITE setLabelOctave ) Q_PROPERTY( int transpose READ getTranspose WRITE setTranspose ) #ifndef Q_MOC_RUN Q_CLASSINFO("Author", "Pedro Lopez-Cabanillas ") Q_CLASSINFO("URL", "https://sourceforge.net/projects/drumstick") Q_CLASSINFO("Version", QT_STRINGIFY(VERSION)) #endif public: explicit PianoKeybd(QWidget *parent = nullptr); PianoKeybd(const int baseOctave, const int numKeys, const int startKey, QWidget *parent = nullptr); virtual ~PianoKeybd(); Q_ENUM(LabelVisibility); Q_ENUM(LabelAlteration); Q_ENUM(LabelOrientation); Q_ENUM(LabelNaming); Q_ENUM(LabelCentralOctave); void setFont(const QFont &font); PianoHandler* getPianoHandler() const; void setPianoHandler(PianoHandler* handler); PianoPalette getHighlightPalette() const; void setHighlightPalette(const PianoPalette& p ); PianoPalette getBackgroundPalette() const; void setBackgroundPalette(const PianoPalette& p ); PianoPalette getForegroundPalette() const; void setForegroundPalette(const PianoPalette& p ); bool showColorScale() const; void setShowColorScale(const bool show); void useCustomNoteNames(const QStringList& names); void useStandardNoteNames(); QStringList customNoteNames() const; QStringList standardNoteNames() const; void retranslate(); int baseOctave() const; void setBaseOctave(const int baseOctave); int numKeys() const; int startKey() const; void setNumKeys(const int numKeys, const int startKey = DEFAULTSTARTINGKEY); int getRotation() const; void setRotation(int r); QColor getKeyPressedColor() const; void setKeyPressedColor(const QColor& c); void resetKeyPressedColor(); LabelVisibility showLabels() const; void setShowLabels(const LabelVisibility show); LabelAlteration labelAlterations() const; void setLabelAlterations(const LabelAlteration use); LabelOrientation labelOrientation() const; void setLabelOrientation(const LabelOrientation orientation); LabelCentralOctave labelOctave() const; void setLabelOctave(const LabelCentralOctave octave); int getTranspose() const; void setTranspose(int t); int getChannel() const; void setChannel(const int c); int getVelocity() const; void setVelocity(const int v); bool isKeyboardEnabled() const; void setKeyboardEnabled( const bool enable ); bool isMouseEnabled() const; void setMouseEnabled( const bool enable ); bool isTouchEnabled() const; void setTouchEnabled( const bool enable ); bool velocityTint() const ; void setVelocityTint( const bool enable ); void allKeysOff(); QSize sizeHint() const override; void setKeyboardMap(KeyboardMap* m); KeyboardMap* getKeyboardMap(); void resetKeyboardMap(); void setRawKeyboardMap(KeyboardMap* m); KeyboardMap* getRawKeyboardMap(); void resetRawKeyboardMap(); bool getRawKeyboardMode() const; void setRawKeyboardMode(const bool b); void showNoteOn( const int note, QColor color, int vel = -1 ); void showNoteOn( const int note, int vel = -1 ); void showNoteOff( const int note, int vel = -1 ); // RawKbdHandler methods bool handleKeyPressed(int keycode) override; bool handleKeyReleased(int keycode) override; void setKeyPicture(const bool natural, const QPixmap& pix); QPixmap getKeyPicture(const bool natural); void setUseKeyPictures(const bool enable); bool getUseKeyPictures() const; signals: /** * This signal is emitted for each Note On MIDI event created using * the computer keyboard, mouse or touch screen. It is not emitted if * a PianoHandler has been assigned using setPianoHandler(). * @param midiNote the MIDI note number * @param vel the MIDI velocity */ void noteOn( int midiNote, int vel ); /** * This signal is emitted for each Note Off MIDI event created using * the computer keyboard, mouse or touch screen. It is not emitted if * a PianoHandler has been assigned using setPianoHandler(). * @param midiNote the MIDI note number * @param vel the MIDI velocity */ void noteOff( int midiNote, int vel ); /** * signalName is emitted for each note created, and contains a string * with the MIDI note number and the note name for each note on event. * @param name the MIDI note number and name */ void signalName( const QString& name ); protected: void initialize(); void initDefaultMap(); void initScene(int base, int num, int ini, const QColor& c = QColor()); void resizeEvent(QResizeEvent *event) override; private: class PianoKeybdPrivate; QScopedPointer d; }; /** @} */ }} // namespace drumstick::widgets #endif // PIANOKEYBD_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/qwrk.h0000644000000000000000000000013214200302440021511 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/qwrk.h0000644000175000001440000005224514200302440022302 0ustar00pedrousers00000000000000/* WRK File component Copyright (C) 2010-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMSTICK_QWRK_H #define DRUMSTICK_QWRK_H #include "macros.h" #include #include class QTextCodec; class QDataStream; /** * @file qwrk.h * Cakewalk WRK Files Input */ namespace drumstick { namespace File { /** * @addtogroup WRK Cakewalk WRK File Parser (Input) * @{ * * @enum WrkChunkType * Record types within a WRK file */ enum WrkChunkType { TRACK_CHUNK = 1, ///< Track prefix STREAM_CHUNK = 2, ///< Events stream VARS_CHUNK = 3, ///< Global variables TEMPO_CHUNK = 4, ///< Tempo map METER_CHUNK = 5, ///< Meter map SYSEX_CHUNK = 6, ///< System exclusive bank MEMRGN_CHUNK = 7, ///< Memory region COMMENTS_CHUNK = 8, ///< Comments TRKOFFS_CHUNK = 9, ///< Track offset TIMEBASE_CHUNK = 10, ///< Timebase. If present is the first chunk in the file. TIMEFMT_CHUNK = 11, ///< SMPTE time format TRKREPS_CHUNK = 12, ///< Track repetitions TRKPATCH_CHUNK = 14, ///< Track patch NTEMPO_CHUNK = 15, ///< New Tempo map THRU_CHUNK = 16, ///< Extended thru parameters LYRICS_CHUNK = 18, ///< Events stream with lyrics TRKVOL_CHUNK = 19, ///< Track volume SYSEX2_CHUNK = 20, ///< System exclusive bank MARKERS_CHUNK = 21, ///< Markers STRTAB_CHUNK = 22, ///< Table of text event types METERKEY_CHUNK = 23, ///< Meter/Key map TRKNAME_CHUNK = 24, ///< Track name VARIABLE_CHUNK = 26, ///< Variable record chunk NTRKOFS_CHUNK = 27, ///< Track offset TRKBANK_CHUNK = 30, ///< Track bank NTRACK_CHUNK = 36, ///< Track prefix NSYSEX_CHUNK = 44, ///< System exclusive bank NSTREAM_CHUNK = 45, ///< Events stream SGMNT_CHUNK = 49, ///< Segment prefix SOFTVER_CHUNK = 74, ///< Software version which saved the file END_CHUNK = 255 ///< Last chunk, end of file }; /** * Cakewalk WRK file format (input only) * * This class is used to parse Cakewalk WRK Files. * Signals with QString parameters are deprecated because the class QTextCodec was removed from QtCore since Qt6. * * @since 0.3.0 */ class DRUMSTICK_EXPORT QWrk : public QObject { Q_OBJECT Q_ENUM(WrkChunkType) public: explicit QWrk(QObject * parent = nullptr); virtual ~QWrk(); void readFromStream(QDataStream *stream); void readFromFile(const QString& fileName); Q_DECL_DEPRECATED QTextCodec* getTextCodec(); Q_DECL_DEPRECATED void setTextCodec(QTextCodec *codec); long getFilePos(); int getNow() const; int getFrom() const; int getThru() const; int getKeySig() const; int getClock() const; int getAutoSave() const; int getPlayDelay() const; bool getZeroCtrls() const; bool getSendSPP() const; bool getSendCont() const; bool getPatchSearch() const; bool getAutoStop() const; unsigned int getStopTime() const; bool getAutoRewind() const; int getRewindTime() const; bool getMetroPlay() const; bool getMetroRecord() const; bool getMetroAccent() const; int getCountIn() const; bool getThruOn() const; bool getAutoRestart() const; int getCurTempoOfs() const; int getTempoOfs1() const; int getTempoOfs2() const; int getTempoOfs3() const; bool getPunchEnabled() const; int getPunchInTime() const; int getPunchOutTime() const; int getEndAllTime() const; QByteArray getLastChunkRawData() const; double getRealTime(long ticks) const; /** * Cakewalk WRK file format header string id */ static const QByteArray HEADER; ///< Cakewalk WRK File header id Q_SIGNALS: /** * Emitted for a WRK file read error * * @param errorStr Error string */ void signalWRKError(const QString& errorStr); /** * Emitted after reading an unknown chunk * * @param type chunk type * @param data chunk data (not decoded) */ void signalWRKUnknownChunk(int type, const QByteArray& data); /** * Emitted after reading a WRK header * * @param verh WRK file format version major * @param verl WRK file format version minor */ void signalWRKHeader(int verh, int verl); /** * Emitted after reading the last chunk of a WRK file */ void signalWRKEnd(); /** * Emitted after reading the last event of a event stream * @param time musical time */ void signalWRKStreamEnd(long time); /** * Emitted after reading a Note message * * @param track track number * @param time musical time * @param chan MIDI Channel * @param pitch MIDI Note * @param vol Velocity * @param dur Duration */ void signalWRKNote(int track, long time, int chan, int pitch, int vol, int dur); /** * Emitted after reading a Polyphonic Aftertouch message * * @param track track number * @param time musical time * @param chan MIDI Channel * @param pitch MIDI Note * @param press Pressure amount */ void signalWRKKeyPress(int track, long time, int chan, int pitch, int press); /** * Emitted after reading a Control Change message * * @param track track number * @param time musical time * @param chan MIDI Channel * @param ctl MIDI Controller * @param value Control value */ void signalWRKCtlChange(int track, long time, int chan, int ctl, int value); /** * Emitted after reading a Bender message * * @param track track number * @param time musical time * @param chan MIDI Channel * @param value Bender value */ void signalWRKPitchBend(int track, long time, int chan, int value); /** * Emitted after reading a Program change message * * @param track track number * @param time musical time * @param chan MIDI Channel * @param patch Program number */ void signalWRKProgram(int track, long time, int chan, int patch); /** * Emitted after reading a Channel Aftertouch message * * @param track track number * @param time musical time * @param chan MIDI Channel * @param press Pressure amount */ void signalWRKChanPress(int track, long time, int chan, int press); /** * Emitted after reading a System Exclusive event * * @param track track number * @param time musical time * @param bank Sysex Bank number */ void signalWRKSysexEvent(int track, long time, int bank); /** * Emitted after reading a System Exclusive Bank * * @param bank Sysex Bank number * @param name Sysex Bank name * @param autosend Send automatically after loading the song * @param port MIDI output port * @param data Sysex bytes */ void signalWRKSysex(int bank, const QString& name, bool autosend, int port, const QByteArray& data); /** * Emitted after reading a text message * * @param track track number * @param time musical time * @param type Text type * @param data Text data * @deprecated because the class QTextCodec was removed from QtCore since Qt6. * use signalWRKText2() instead */ Q_DECL_DEPRECATED void signalWRKText(int track, long time, int type, const QString& data); /** * Emitted after reading a WRK Time signature * * @param bar Measure number * @param num Numerator * @param den Denominator (exponent in a power of two) */ void signalWRKTimeSig(int bar, int num, int den); /** * Emitted after reading a WRK Key Signature * * @param bar Measure number * @param alt Number of alterations (negative=flats, positive=sharps) */ void signalWRKKeySig(int bar, int alt); /** * Emitted after reading a Tempo Change message. * * Tempo units are given in beats * 100 per minute, so to obtain BPM * it is necessary to divide by 100 the tempo. * * @param time musical time * @param tempo beats per minute multiplied by 100 */ void signalWRKTempo(long time, int tempo); /** * Emitted after reading a track prefix chunk * * @param name1 track 1st name * @param name2 track 2nd name * @param trackno track number * @param channel track forced channel (-1=no forced) * @param pitch track pitch transpose in semitones (-127..127) * @param velocity track velocity increment (-127..127) * @param port track forced port * @param selected true if track is selected * @param muted true if track is muted * @param loop true if loop is enabled * @deprecated because the class QTextCodec was removed from QtCore since Qt6. * use signalWRKTrack2() instead */ Q_DECL_DEPRECATED void signalWRKTrack(const QString& name1, const QString& name2, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop ); /** * Emitted after reading the timebase chunk * * @param timebase ticks per quarter note */ void signalWRKTimeBase(int timebase); /** * Emitted after reading the global variables chunk. * * This record contains miscellaneous Cakewalk global variables that can * be retrieved using individual getters. * * @see getNow(), getFrom(), getThru() */ void signalWRKGlobalVars(); /** * Emitted after reading an Extended Thru parameters chunk. * * It was introduced in Cakewalk version 4.0. These parameters are * intended to override the global vars Thruon value, so this record should * come after the VARS_CHUNK record. It is optional. * * @param mode (auto, off, on) * @param port MIDI port * @param channel MIDI channel * @param keyPlus Note transpose * @param velPlus Velocity transpose * @param localPort MIDI local port */ void signalWRKThru(int mode, int port, int channel, int keyPlus, int velPlus, int localPort); /** * Emitted after reading a track offset chunk * * @param track track number * @param offset time offset */ void signalWRKTrackOffset(int track, int offset); /** * Emitted after reading a track offset chunk * * @param track track number * @param reps number of repetitions */ void signalWRKTrackReps(int track, int reps); /** * Emitted after reading a track patch chunk * * @param track track number * @param patch */ void signalWRKTrackPatch(int track, int patch); /** * Emitted after reading a track bank chunk * * @param track track number * @param bank */ void signalWRKTrackBank(int track, int bank); /** * Emitted after reading a SMPTE time format chunk * * @param frames frames/sec (24, 25, 29=30-drop, 30) * @param offset frames of offset */ void signalWRKTimeFormat(int frames, int offset); /** * Emitted after reading a comments chunk * * @param data file text comments * @deprecated because the class QTextCodec was removed from QtCore since Qt6. * use signalWRKComments2() instead */ Q_DECL_DEPRECATED void signalWRKComments(const QString& data); /** * Emitted after reading a variable chunk. * This record may contain data in text or binary format. * * @param name record identifier * @param data record variable data */ void signalWRKVariableRecord(const QString& name, const QByteArray& data); /** * Emitted after reading a track volume chunk. * * @param track track number * @param vol initial volume */ void signalWRKTrackVol(int track, int vol); /** * Emitted after reading a new track prefix * * @param name track name * @param trackno track number * @param channel forced MIDI channel * @param pitch Note transposition * @param velocity Velocity increment * @param port MIDI port number * @param selected track is selected * @param muted track is muted * @param loop track loop enabled * @deprecated because the class QTextCodec was removed from QtCore since Qt6. * use signalWRKNewTrack2() instead */ Q_DECL_DEPRECATED void signalWRKNewTrack( const QString& name, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop ); /** * Emitted after reading a software version chunk. * * @param version software version string */ void signalWRKSoftVer(const QString& version); /** * Emitted after reading a track name chunk. * * @param track track number * @param name track name * @deprecated because the class QTextCodec was removed from QtCore since Qt6. * use signalWRKTrackName2() instead */ Q_DECL_DEPRECATED void signalWRKTrackName(int track, const QString& name); /** * Emitted after reading a string event types chunk. * * @param strs list of declared string event types * @deprecated because the class QTextCodec was removed from QtCore since Qt6. * use signalWRKStringTable2() instead */ Q_DECL_DEPRECATED void signalWRKStringTable(const QStringList& strs); /** * Emitted after reading a segment prefix chunk. * * @param track track number * @param time segment time offset * @param name segment name * @deprecated because the class QTextCodec was removed from QtCore since Qt6. * use signalWRKSegment2() instead */ Q_DECL_DEPRECATED void signalWRKSegment(int track, long time, const QString& name); /** * Emitted after reading a chord diagram chunk. * * @param track track number * @param time event time in ticks * @param name chord name * @param data chord data definition (not decoded) */ void signalWRKChord(int track, long time, const QString& name, const QByteArray& data); /** * Emitted after reading an expression indication (notation) chunk. * * @param track track number * @param time event time in ticks * @param code expression event code * @param text expression text * @deprecated because the class QTextCodec was removed from QtCore since Qt6. * use signalWRKExpression2() instead */ Q_DECL_DEPRECATED void signalWRKExpression(int track, long time, int code, const QString& text); /** * Emitted after reading a hairpin symbol (notation) chunk. * * @param track track number * @param time event time in ticks * @param code hairpin code * @param dur duration */ void signalWRKHairpin(int track, long time, int code, int dur); /** * Emitted after reading a text message * This signal is emitted when getTextCodec() is nullptr * * @param track track number * @param time musical time * @param type Text type * @param data Text data */ void signalWRKText2(int track, long time, int type, const QByteArray& data); /** * Emitted after reading a track prefix chunk * This signal is emitted when getTextCodec() is nullptr * * @param name1 track 1st name * @param name2 track 2nd name * @param trackno track number * @param channel track forced channel (-1=no forced) * @param pitch track pitch transpose in semitones (-127..127) * @param velocity track velocity increment (-127..127) * @param port track forced port * @param selected true if track is selected * @param muted true if track is muted * @param loop true if loop is enabled */ void signalWRKTrack2(const QByteArray& name1, const QByteArray& name2, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop ); /** * Emitted after reading a comments chunk * This signal is emitted when getTextCodec() is nullptr * * @param data file text comments */ void signalWRKComments2(const QByteArray& data); /** * Emitted after reading a new track prefix * This signal is emitted when getTextCodec() is nullptr * * @param name track name * @param trackno track number * @param channel forced MIDI channel * @param pitch Note transposition * @param velocity Velocity increment * @param port MIDI port number * @param selected track is selected * @param muted track is muted * @param loop track loop enabled */ void signalWRKNewTrack2(const QByteArray& name, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop ); /** * Emitted after reading a track name chunk. * This signal is emitted when getTextCodec() is nullptr * * @param track track number * @param name track name */ void signalWRKTrackName2(int track, const QByteArray& name); /** * Emitted after reading a string event types chunk. * This signal is emitted when getTextCodec() is nullptr * * @param strs list of declared string event types */ void signalWRKStringTable2(const QList& strs); /** * Emitted after reading a segment prefix chunk. * This signal is emitted when getTextCodec() is nullptr * * @param track track number * @param time segment time offset * @param name segment name */ void signalWRKSegment2(int track, long time, const QByteArray& name); /** * Emitted after reading an expression indication (notation) chunk. * This signal is emitted when getTextCodec() is nullptr * * @param track track number * @param time event time in ticks * @param code expression event code * @param text expression text */ void signalWRKExpression2(int track, long time, int code, const QByteArray& text); /** * Emitted after reading a text marker * This is deprecated because the class QTextCodec was removed from QtCore since Qt6 * Use signalWRKMarker2() instead * * @param time event time in ticks or smpte * @param type tipe of time: 0=ticks or 1=smpte * @param data marker text * @deprecated because the class QTextCodec was removed from QtCore since Qt6. * use signalWRKMarker2() instead */ Q_DECL_DEPRECATED void signalWRKMarker(long time, int type, const QString& data); /** * Emitted after reading a text marker * This signal is emitted when getTextCodec() is nullptr * * @param time event time in ticks or smpte * @param type tipe of time: 0=ticks or 1=smpte * @param data marker text */ void signalWRKMarker2(long time, int type, const QByteArray& data); private: quint8 readByte(); quint16 to16bit(quint8 c1, quint8 c2); quint32 to32bit(quint8 c1, quint8 c2, quint8 c3, quint8 c4); quint16 read16bit(); quint32 read24bit(); quint32 read32bit(); QString readString(int len); QString readVarString(); void readRawData(int size); void readGap(int size); bool atEnd(); void seek(qint64 pos); int readChunk(); void processTrackChunk(); void processVarsChunk(); void processTimebaseChunk(); void processNoteArray(int track, int events); void processStreamChunk(); void processMeterChunk(); void processTempoChunk(int factor = 1); void processSysexChunk(); void processSysex2Chunk(); void processNewSysexChunk(); void processThruChunk(); void processTrackOffset(); void processTrackReps(); void processTrackPatch(); void processTrackBank(); void processTimeFormat(); void processComments(); void processVariableRecord(int max); void processNewTrack(); void processSoftVer(); void processTrackName(); void processStringTable(); void processLyricsStream(); void processTrackVol(); void processNewTrackOffset(); void processMeterKeyChunk(); void processSegmentChunk(); void processNewStream(); void processUnknown(int id); void processEndChunk(); void wrkRead(); QByteArray readByteArray(int len); QByteArray readVarByteArray(); void processMarkers(); struct RecTempo { long time; double tempo; double seconds; }; class QWrkPrivate; QScopedPointer d; }; /** @} */ }} // namespace drumstick::File #endif // DRUMSTICK_QWRK_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/subscription.h0000644000000000000000000000013214200302440023251 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/subscription.h0000644000175000001440000000657514200302440024047 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMSTICK_SUBSCRIPTION_H #define DRUMSTICK_SUBSCRIPTION_H extern "C" { #include } #include #include "macros.h" namespace drumstick { namespace ALSA { /** * @file subscription.h * Classes managing ALSA sequencer subscriptions */ class MidiClient; /** * @addtogroup ALSASubs ALSA Sequencer Subscriptions * @{ * * @class Subscriber * Subscriber container class. * * This class is used to enumerate the subscribers of a given (root) port. */ class DRUMSTICK_EXPORT Subscriber { friend class PortInfo; public: Subscriber(); Subscriber(const Subscriber& other); explicit Subscriber(snd_seq_query_subscribe_t* other); virtual ~Subscriber(); Subscriber* clone(); int getSizeOfInfo() const; int getClient(); int getPort(); const snd_seq_addr_t* getRoot(); snd_seq_query_subs_type_t getType(); int getIndex(); int getNumSubs(); const snd_seq_addr_t* getAddr(); int getQueue(); bool getExclusive(); bool getTimeUpdate(); bool getTimeReal(); void setClient(int client); void setPort(int port); void setRoot(snd_seq_addr_t* addr); void setType(snd_seq_query_subs_type_t type); void setIndex(int index); Subscriber& operator=(const Subscriber& other); private: snd_seq_query_subscribe_t* m_Info; }; /** * Subscription management. * * This class represents a connection between two ports. */ class DRUMSTICK_EXPORT Subscription { public: Subscription(); Subscription(const Subscription& other); explicit Subscription(snd_seq_port_subscribe_t* other); explicit Subscription(MidiClient* seq); virtual ~Subscription(); Subscription* clone(); int getSizeOfInfo() const; void setSender(unsigned char client, unsigned char port); void setDest(unsigned char client, unsigned char port); void subscribe(MidiClient* seq); void unsubscribe(MidiClient* seq); const snd_seq_addr_t* getSender(); const snd_seq_addr_t* getDest(); int getQueue(); bool getExclusive(); bool getTimeUpdate(); bool getTimeReal(); void setSender(const snd_seq_addr_t* addr); void setDest(const snd_seq_addr_t* addr); void setQueue(int queue); void setExclusive(bool val); void setTimeUpdate(bool val); void setTimeReal(bool val); Subscription& operator=(const Subscription& other); private: snd_seq_port_subscribe_t* m_Info; }; /** * List of subscriptions */ typedef QList SubscriptionsList; /** * List of subscribers */ typedef QList SubscribersList; /** @} */ }} /* namespace drumstick::ALSA */ #endif //DRUMSTICK_SUBSCRIPTION_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/playthread.h0000644000000000000000000000013214200302440022662 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/playthread.h0000644000175000001440000000726014200302440023450 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMSTICK_PLAYTHREAD_H #define DRUMSTICK_PLAYTHREAD_H #include "alsaevent.h" #include #include namespace drumstick { namespace ALSA { /** * @file playthread.h * Sequencer output thread */ class MidiClient; class MidiQueue; /** * @addtogroup PlayThread ALSA Sequencer Output * @{ * * @class SequencerOutputThread * Sequence player auxiliary class * * This class is used to implement an asynchronous sequence player using * ALSA sequencer scheduling * * Examples: guiplayer.cpp and playsmf.cpp */ class DRUMSTICK_EXPORT SequencerOutputThread : public QThread { Q_OBJECT public: SequencerOutputThread(MidiClient *seq, int portId); virtual void run() override; /** * Gets the initial position in ticks of the sequence. The * default value zero means starting from the beginning. * @return Initial position (ticks) */ virtual unsigned int getInitialPosition() { return 0; } /** * Gets the echo event resolution in ticks. This is the time * between echo events interleaved with the MIDI sequence. The default * value zero means that no echo events are sent at all. * @return Echo resolution (ticks) */ virtual unsigned int getEchoResolution() { return 0; } /** * Check if there is one more event in the sequence. * This is a pure virtual method that must be overridden in the derived * class. * @return True if the sequence has another event. */ virtual bool hasNext() = 0; /** * Gets the next event in the sequence. * This is a pure virtual function that must be overridden in the derived * class. * @return Pointer to the next SequencerEvent to be played. */ virtual SequencerEvent* nextEvent() = 0; /** * Stops playing the current sequence. */ virtual void stop(); signals: /** * Signal emitted when the sequence play-back has finished. */ void playbackFinished(); /** * Signal emitted when the play-back has stopped. */ void playbackStopped(); public slots: void start( QThread::Priority priority = InheritPriority ); protected: virtual void sendEchoEvent(int tick); virtual void sendSongEvent(SequencerEvent* ev); virtual void drainOutput(); virtual void syncOutput(); virtual bool stopRequested(); MidiClient *m_MidiClient; /**< MidiClient instance pointer */ MidiQueue *m_Queue; /**< MidiQueue instance pointer */ int m_PortId; /**< MidiPort numeric identifier */ bool m_Stopped; /**< Stopped status */ int m_QueueId; /**< MidiQueue numeric identifier */ int m_npfds; /**< Number of pollfd pointers */ pollfd* m_pfds; /**< Array of pollfd pointers */ QReadWriteLock m_mutex; /**< Mutex object used for synchronization */ }; /** @} */ }} /* namespace drumstick::ALSA */ #endif /*DRUMSTICK_PLAYTHREAD_H*/ drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/sequencererror.h0000644000000000000000000000013214200302440023571 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/sequencererror.h0000644000175000001440000000461714200302440024362 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SEQUENCERERROR_H #define SEQUENCERERROR_H #include #include #include "macros.h" /** * @file sequencererror.h * SequencerError Exception class */ /** * @namespace std * C++ Standard Library namespace * * @class std::exception * Provides consistent interface to handle errors. * @see https://en.cppreference.com/w/cpp/error/exception */ namespace drumstick { namespace ALSA { /** * @addtogroup ALSAError ALSA Sequencer Exception * @{ * * @class SequencerError * Exception class for ALSA Sequencer errors. * This class is used to report errors from the ALSA sequencer. * * The class SequencerError represents an exception object reported when the * ALSA library returns an error code. It is only used for severe errors. */ class DRUMSTICK_EXPORT SequencerError : std::exception { public: /** * Constructor * @param s Error location * @param rc Numeric error code */ SequencerError(QString const& s, int rc); /** * Retrieve a human readable error message * @return human readable error message */ virtual const char* what() const noexcept override; /** * Gets the human readable error message from the error code * @return Error message */ QString qstrError() const; /** * Gets the numeric error code * @return Error code */ int code() const; /** * Gets the location of the error code as provided in the constructor * @return Error location */ const QString& location() const; private: QString m_location; int m_errCode; }; /** @} */ }} // namespace drumstick::ALSA #endif // SEQUENCERERROR_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/alsaclient.h0000644000000000000000000000013214200302440022644 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/alsaclient.h0000644000175000001440000002341614200302440023433 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMSTICK_ALSACLIENT_H #define DRUMSTICK_ALSACLIENT_H #include #include #include #include #include #include "macros.h" #include "alsaport.h" /** * @file alsaclient.h * Classes managing ALSA Sequencer clients */ /** * @brief Drumstick common */ namespace drumstick { /** * @ingroup ALSAGroup * @brief Drumstick ALSA library wrapper */ namespace ALSA { class MidiQueue; class MidiClient; class SequencerEvent; class RemoveEvents; /** * @addtogroup ALSAClient ALSA Sequencer Clients * @{ * * @class ClientInfo * Client information * * This class is used to retrieve, hold and set some data from * sequencer clients, like the name or id. */ class DRUMSTICK_EXPORT ClientInfo { friend class MidiClient; public: ClientInfo(); ClientInfo(const ClientInfo &other); explicit ClientInfo(snd_seq_client_info_t *other); ClientInfo(MidiClient* seq, int id); virtual ~ClientInfo(); ClientInfo* clone(); ClientInfo& operator=(const ClientInfo &other); int getSizeOfInfo() const; int getClientId(); snd_seq_client_type_t getClientType(); QString getName(); bool getBroadcastFilter(); bool getErrorBounce(); int getNumPorts(); int getEventLost(); void setClient(int client); void setName(QString name); void setBroadcastFilter(bool val); void setErrorBounce(bool val); PortInfoList getPorts() const; #if SND_LIB_VERSION > 0x010010 void addFilter(int eventType); bool isFiltered(int eventType); void clearFilter(); void removeFilter(int eventType); #endif protected: void readPorts(MidiClient* seq); void freePorts(); Q_DECL_DEPRECATED const unsigned char* getEventFilter(); Q_DECL_DEPRECATED void setEventFilter(unsigned char* filter); private: snd_seq_client_info_t* m_Info; PortInfoList m_Ports; }; /** * List of sequencer client information */ typedef QList ClientInfoList; /** * System information * * This class is used to retrieve and hold some data about the * whole sequencer subsystem. */ class DRUMSTICK_EXPORT SystemInfo { friend class MidiClient; public: SystemInfo(); SystemInfo(const SystemInfo& other); explicit SystemInfo(snd_seq_system_info_t* other); explicit SystemInfo(MidiClient* seq); virtual ~SystemInfo(); SystemInfo* clone(); SystemInfo& operator=(const SystemInfo& other); int getSizeOfInfo() const; int getMaxClients(); int getMaxPorts(); int getMaxQueues(); int getMaxChannels(); int getCurrentQueues(); int getCurrentClients(); private: snd_seq_system_info_t* m_Info; }; /** * Sequencer Pool information * * This class is used to get and set the size of the input and output pool * buffers for a sequencer client. */ class DRUMSTICK_EXPORT PoolInfo { friend class MidiClient; public: PoolInfo(); PoolInfo(const PoolInfo& other); explicit PoolInfo(snd_seq_client_pool_t* other); explicit PoolInfo(MidiClient* seq); virtual ~PoolInfo(); PoolInfo* clone(); PoolInfo& operator=(const PoolInfo& other); int getSizeOfInfo() const; int getClientId(); int getInputFree(); int getInputPool(); int getOutputFree(); int getOutputPool(); int getOutputRoom(); void setInputPool(int size); void setOutputPool(int size); void setOutputRoom(int size); private: snd_seq_client_pool_t* m_Info; }; /** * Sequencer events handler * * This abstract class is used to define an interface that other class can * implement to receive sequencer events. It is one of the three methods of * delivering events offered by this library. * * @see ALSAClient */ class DRUMSTICK_EXPORT SequencerEventHandler { public: /** Destructor */ virtual ~SequencerEventHandler() = default; /** * Callback function to be implemented by the derived class. * It will be invoked by the client to deliver received events to the * registered listener. * * @param ev A pointer to the received SequencerEvent * @see MidiClient::setHandler(), MidiClient::startSequencerInput(), * MidiClient::stopSequencerInput(), MidiClient::doEvents() */ virtual void handleSequencerEvent(SequencerEvent* ev) = 0; }; /** * Client management. * * This class represents an ALSA sequencer client */ class DRUMSTICK_EXPORT MidiClient : public QObject { Q_OBJECT public: explicit MidiClient( QObject* parent = nullptr ); virtual ~MidiClient(); void open( const QString deviceName = "default", const int openMode = SND_SEQ_OPEN_DUPLEX, const bool blockMode = false ); void open( snd_config_t* conf, const QString deviceName = "default", const int openMode = SND_SEQ_OPEN_DUPLEX, const bool blockMode = false ); void close(); void startSequencerInput(); void stopSequencerInput(); MidiPort* createPort(); MidiQueue* createQueue(); MidiQueue* createQueue(QString const& name); MidiQueue* getQueue(); MidiQueue* useQueue(int queue_id); MidiQueue* useQueue(const QString& name); MidiQueue* useQueue(MidiQueue* queue); void portAttach(MidiPort* port); void portDetach(MidiPort* port); void detachAllPorts(); void addEventFilter(int evtype); void output(SequencerEvent* ev, bool async = false, int timeout = -1); void outputDirect(SequencerEvent* ev, bool async = false, int timeout = -1); void outputBuffer(SequencerEvent* ev); void drainOutput(bool async = false, int timeout = -1); void synchronizeOutput(); int getClientId(); snd_seq_type_t getSequencerType(); snd_seq_t* getHandle(); bool isOpened(); size_t getOutputBufferSize(); void setOutputBufferSize(size_t newSize); size_t getInputBufferSize(); void setInputBufferSize(size_t newSize); QString getDeviceName(); int getOpenMode(); bool getBlockMode(); void setBlockMode(bool newValue); QString getClientName(); QString getClientName(const int clientId); void setClientName(QString const& newName); bool getBroadcastFilter(); void setBroadcastFilter(bool newValue); bool getErrorBounce(); void setErrorBounce(bool newValue); ClientInfo& getThisClientInfo(); void setThisClientInfo(const ClientInfo& val); MidiPortList getMidiPorts() const; ClientInfoList getAvailableClients(); PortInfoList getAvailableInputs(); PortInfoList getAvailableOutputs(); SystemInfo& getSystemInfo(); QList getAvailableQueues(); PoolInfo& getPoolInfo(); void setPoolInfo(const PoolInfo& info); void setPoolInput(int size); void setPoolOutput(int size); void setPoolOutputRoom(int size); void resetPoolInput(); void resetPoolOutput(); void dropInput(); void dropInputBuffer(); void dropOutput(); void dropOutputBuffer(); void removeEvents(const RemoveEvents* spec); SequencerEvent* extractOutput(); int outputPending(); int inputPending(bool fetch); int getQueueId(const QString& name); void addListener(QObject* listener); void removeListener(QObject* listener); void setEventsEnabled(const bool bEnabled); bool getEventsEnabled() const; void setHandler(SequencerEventHandler* handler); bool parseAddress( const QString& straddr, snd_seq_addr& result ); void setRealTimeInput(bool enabled); bool realTimeInputEnabled(); signals: /** Signal emitted when an event is received * @param ev pointer to the received event */ void eventReceived(drumstick::ALSA::SequencerEvent* ev); protected: void doEvents(); void applyClientInfo(); void readClients(); void freeClients(); void updateAvailablePorts(); PortInfoList filterPorts(unsigned int filter); /* low level public functions */ const char * _getDeviceName(); int getPollDescriptorsCount(short events); int pollDescriptors(struct pollfd *pfds, unsigned int space, short events); unsigned short pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds); /* mid level functions */ void _setClientName( const char *name ); int createSimplePort( const char *name, unsigned int caps, unsigned int type ); void deleteSimplePort( int port ); void connectFrom(int myport, int client, int port); void connectTo(int myport, int client, int port); void disconnectFrom(int myport, int client, int port); void disconnectTo(int myport, int client, int port); private: class SequencerInputThread; class MidiClientPrivate; QScopedPointer d; }; #if SND_LIB_VERSION > 0x010004 DRUMSTICK_EXPORT QString getRuntimeALSALibraryVersion(); DRUMSTICK_EXPORT int getRuntimeALSALibraryNumber(); #endif DRUMSTICK_EXPORT QString getRuntimeALSADriverVersion(); DRUMSTICK_EXPORT int getRuntimeALSADriverNumber(); DRUMSTICK_EXPORT QString getCompiledALSALibraryVersion(); DRUMSTICK_EXPORT QString getDrumstickLibraryVersion(); /** @} */ }} /* namespace drumstick::ALSA */ #endif // DRUMSTICK_ALSACLIENT_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/rtmidiinput.h0000644000000000000000000000013214200302440023075 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/rtmidiinput.h0000644000175000001440000001232214200302440023656 0ustar00pedrousers00000000000000/* Drumstick MIDI realtime input-output Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef MIDIINPUT_H #define MIDIINPUT_H #include #include #include #include #include #include "macros.h" #include "rtmidioutput.h" /** * @file rtmidiinput.h * Realtime MIDI input interface */ namespace drumstick { namespace rt { /** * @addtogroup RT * @{ * * @class MIDIInput * @brief MIDI IN interface */ class DRUMSTICK_EXPORT MIDIInput : public QObject { Q_OBJECT public: /** * @brief MIDIInput constructor * @param parent */ explicit MIDIInput(QObject *parent = nullptr) : QObject(parent) {} /** * @brief ~MIDIInput destructor */ virtual ~MIDIInput() = default; /** * @brief initialize * @param settings */ virtual void initialize(QSettings* settings) = 0; /** * @brief backendName * @return plugin name */ virtual QString backendName() = 0; /** * @brief publicName * @return MIDI port name */ virtual QString publicName() = 0; /** * @brief setPublicName * @param name MIDI port name */ virtual void setPublicName(QString name) = 0; /** * @brief connections * @param advanced whether the advanced connections are included or not * @return list of available MIDI ports */ virtual QList connections(bool advanced = false) = 0; /** * @brief setExcludedConnections * @param conns */ virtual void setExcludedConnections(QStringList conns) = 0; /** * @brief open the MIDI port by name * @param conn Connection to open */ virtual void open(const MIDIConnection& conn) = 0; /** * @brief close the MIDI port */ virtual void close() = 0; /** * @brief currentConnection * @return name of the current connection if it is opened */ virtual MIDIConnection currentConnection() = 0; /** * @brief setMIDIThruDevice * @param device */ virtual void setMIDIThruDevice(MIDIOutput* device) = 0; /** * @brief enableMIDIThru * @param enable */ virtual void enableMIDIThru(bool enable) = 0; /** * @brief isEnabledMIDIThru * @return MIDI Thru is enabled */ virtual bool isEnabledMIDIThru() = 0; Q_SIGNALS: /** * @brief midiNoteOff 0x8 * @param chan * @param note * @param vel */ void midiNoteOff(const int chan, const int note, const int vel); /** * @brief midiNoteOn 0x9 * @param chan * @param note * @param vel */ void midiNoteOn(const int chan, const int note, const int vel); /** * @brief midiKeyPressure 0xA * @param chan * @param note * @param value */ void midiKeyPressure(const int chan, const int note, const int value); /** * @brief midiController 0xB * @param chan * @param control * @param value */ void midiController(const int chan, const int control, const int value); /** * @brief midiProgram 0xC * @param chan * @param program */ void midiProgram(const int chan, const int program); /** * @brief midiChannelPressure 0xD * @param chan * @param value */ void midiChannelPressure(const int chan, const int value); /** * @brief midiPitchBend 0xE * @param chan * @param value */ void midiPitchBend(const int chan, const int value); /** * @brief midiSysex * @param data 0xF0 ... 0xF7 */ void midiSysex(const QByteArray &data); /** * @brief midiSystemCommon * @param status 0xF (1..6) */ void midiSystemCommon(const int status); /** * @brief midiSystemRealtime * @param status 0xF (8..F) */ void midiSystemRealtime(const int status); }; /** @} */ }} // namespace drumstick::rt Q_DECLARE_INTERFACE(drumstick::rt::MIDIInput, "net.sourceforge.drumstick.rt.MIDIInput/2.0") #endif // MIDIINPUT_H drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/alsatimer.h0000644000000000000000000000013214200302440022506 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/alsatimer.h0000644000175000001440000002214114200302440023267 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMSTICK_ALSATIMER_H #define DRUMSTICK_ALSATIMER_H extern "C" { #include } #include #include #include #include #include #include "macros.h" namespace drumstick { namespace ALSA { /** * @file alsatimer.h * Classes managing ALSA Timers */ class TimerQuery; class TimerId; class TimerGlobalInfo; /** * @addtogroup ALSATimer ALSA Timers * @{ * * @class TimerInfo * ALSA Timer information container. * * This class is used to hold properties about ALSA Timers. */ class DRUMSTICK_EXPORT TimerInfo { friend class Timer; public: TimerInfo(); TimerInfo(const TimerInfo& other); explicit TimerInfo(const snd_timer_info_t* other); virtual ~TimerInfo(); TimerInfo* clone(); TimerInfo& operator=(const TimerInfo& other); int getSizeOfInfo() const; bool isSlave(); int getCard(); QString getId(); QString getName(); long getResolution(); long getFrequency(); protected: Q_DECL_DEPRECATED long getTicks(); private: snd_timer_info_t *m_Info; }; /** * ALSA Timer identifier container. * * This class provides an unique identifier for a Timer. */ class DRUMSTICK_EXPORT TimerId { friend class TimerQuery; friend class TimerGlobalInfo; friend class QueueTimer; public: TimerId(); TimerId(const TimerId& other); explicit TimerId(const snd_timer_id_t *other); TimerId(int cls, int scls, int card, int dev, int sdev); virtual ~TimerId(); TimerId* clone(); TimerId& operator=(const TimerId& other); int getSizeOfInfo() const; void setClass(int devclass); int getClass(); void setSlaveClass(int devsclass); int getSlaveClass(); void setCard(int card); int getCard(); void setDevice(int device); int getDevice(); void setSubdevice(int subdevice); int getSubdevice(); private: snd_timer_id_t *m_Info; }; /** * List of timer identifiers */ typedef QList TimerIdList; /** * Global timer information container. * * This class provides global timer parameters. */ class DRUMSTICK_EXPORT TimerGlobalInfo { friend class TimerQuery; public: TimerGlobalInfo(); TimerGlobalInfo(const TimerGlobalInfo& other); explicit TimerGlobalInfo(const snd_timer_ginfo_t* other); virtual ~TimerGlobalInfo(); TimerGlobalInfo* clone(); TimerGlobalInfo& operator=(const TimerGlobalInfo& other); int getSizeOfInfo() const; void setTimerId(const TimerId& tid); TimerId& getTimerId(); unsigned int getFlags(); int getCard(); QString getId(); QString getName(); unsigned long getResolution(); unsigned long getMinResolution(); unsigned long getMaxResolution(); unsigned int getClients(); private: snd_timer_ginfo_t* m_Info; TimerId m_Id; }; /** * ALSA Timer inquiry helper. * * This class provides a mechanism to enumerate the available system timers. */ class DRUMSTICK_EXPORT TimerQuery { public: TimerQuery(const QString& deviceName, int openMode); TimerQuery(const QString& deviceName, int openMode, snd_config_t* conf); virtual ~TimerQuery(); /** * Gets the list of available timers * @return List of TimerId objects */ TimerIdList getTimers() const { return m_timers; } TimerGlobalInfo& getGlobalInfo(); void setGlobalParams(snd_timer_gparams_t* params); void getGlobalParams(snd_timer_gparams_t* params); void getGlobalStatus(snd_timer_gstatus_t* status); protected: void readTimers(); void freeTimers(); private: snd_timer_query_t *m_Info; TimerIdList m_timers; TimerGlobalInfo m_GlobalInfo; }; /** * ALSA Timer parameters container. * * This class provides several parameters about a Timer. */ class DRUMSTICK_EXPORT TimerParams { friend class Timer; public: TimerParams(); TimerParams(const TimerParams& other); explicit TimerParams(const snd_timer_params_t* other); virtual ~TimerParams(); TimerParams* clone(); TimerParams& operator=(const TimerParams& other); int getSizeOfInfo() const; void setAutoStart(bool auto_start); bool getAutoStart(); void setExclusive(bool exclusive); bool getExclusive(); void setEarlyEvent(bool early_event); bool getEarlyEvent(); void setTicks(long ticks); long getTicks(); void setQueueSize(long queue_size); long getQueueSize(); void setFilter(unsigned int filter); unsigned int getFilter(); private: snd_timer_params_t* m_Info; }; /** * ALSA Timer status container. * * This class provides some status information about a Timer. */ class DRUMSTICK_EXPORT TimerStatus { friend class Timer; public: TimerStatus(); TimerStatus(const TimerStatus& other); explicit TimerStatus(const snd_timer_status_t* other); virtual ~TimerStatus(); TimerStatus* clone(); TimerStatus& operator=(const TimerStatus& other); int getSizeOfInfo() const; snd_htimestamp_t getTimestamp(); long getResolution(); long getLost(); long getOverrun(); long getQueue(); private: snd_timer_status_t* m_Info; }; /** * ALSA Timer events handler. * * This abstract class is used to define an interface that other class can * implement to receive timer events. */ class DRUMSTICK_EXPORT TimerEventHandler { public: /** Destructor */ virtual ~TimerEventHandler() = default; /** * Timer event handler. This method is called when the timer expires. * @param ticks The time in ticks. * @param msecs The time in milliseconds. */ virtual void handleTimerEvent(int ticks, int msecs) = 0; }; /** * ALSA Timer management. * * This class represents an ALSA timer object. */ class DRUMSTICK_EXPORT Timer : public QObject { Q_OBJECT private: /** * This class manages timer events input from ALSA */ class TimerInputThread : public QThread { public: /** Constructor */ TimerInputThread(Timer* t, int timeout) : QThread(), m_timer(t), m_Wait(timeout), m_Stopped(false) {} /** Destructor */ virtual ~TimerInputThread() = default; void run() override; bool stopped(); void stop(); private: Timer* m_timer; int m_Wait; bool m_Stopped; QReadWriteLock m_mutex; }; public: Timer(int cls, int scls, int card, int dev, int sdev, int openMode, QObject* parent = nullptr); Timer(const QString& deviceName, int openMode, QObject* parent = nullptr); Timer(const QString& deviceName, int openMode, snd_config_t* config, QObject* parent = nullptr); Timer(TimerId& id, int openMode, QObject* parent = nullptr); virtual ~Timer(); static TimerId bestGlobalTimerId(); static Timer* bestGlobalTimer(int openMode, QObject* parent = nullptr); /** * Gets the ALSA timer object. * @return ALSA timer object pointer. */ snd_timer_t* getHandle() { return m_Info; } TimerInfo& getTimerInfo(); TimerStatus& getTimerStatus(); void setTimerParams(const TimerParams& params); void start(); void stop(); void continueRunning(); void addAsyncTimerHandler(snd_async_callback_t callback, void *private_data); int getPollDescriptorsCount(); void pollDescriptors(struct pollfd *pfds, unsigned int space); void pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds, unsigned short *revents); ssize_t read(void *buffer, size_t size); snd_timer_t* getTimerHandle(); /** * Sets an event handler providing a method to be called when a timer expires. * @param h A TimerEventHandler instance. */ void setHandler(TimerEventHandler* h) { m_handler = h; } void startEvents(); void stopEvents(); protected: void doEvents(); signals: /** * This signal is emitted when the timer has expired, if there is not an * event hander installed. * * @param ticks The time in ticks. * @param msecs The time in milliseconds. */ void timerExpired(int ticks, int msecs); private: snd_timer_t *m_Info; snd_async_handler_t *m_asyncHandler; TimerEventHandler* m_handler; QPointer m_thread; TimerInfo m_TimerInfo; TimerStatus m_TimerStatus; QString m_deviceName; snd_htimestamp_t m_last_time; }; /** @} */ }} /* namespace drumstick::ALSA */ #endif /* DRUMSTICK_ALSATIMER_H */ drumstick-2.5.1/library/include/drumstick/PaxHeaders.27918/configurationdialogs.h0000644000000000000000000000013214200302440024737 xustar0030 mtime=1644266784.825324181 30 atime=1644266784.965324271 30 ctime=1644266784.825324181 drumstick-2.5.1/library/include/drumstick/configurationdialogs.h0000644000175000001440000000322214200302440025517 0ustar00pedrousers00000000000000/* Drumstick MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef CONFIGURATIONDIALOGS_H #define CONFIGURATIONDIALOGS_H #include #include #include "macros.h" /** * @file configurationdialogs.h * Functions providing configuration dialogs */ namespace drumstick { /** * @ingroup Widgets * @brief Drumstick Widgets library * MIDI related widgets and functions. */ namespace widgets { bool DRUMSTICK_EXPORT inputDriverIsConfigurable(const QString driver); bool DRUMSTICK_EXPORT outputDriverIsConfigurable(const QString driver); bool DRUMSTICK_EXPORT configureInputDriver(const QString driver, QWidget* parent = nullptr); bool DRUMSTICK_EXPORT configureOutputDriver(const QString driver, QWidget* parent = nullptr); void DRUMSTICK_EXPORT changeSoundFont(const QString driver, const QString fileName, QWidget* parent = nullptr); QString DRUMSTICK_EXPORT libraryVersion(); }} // namespace drumstick::widgets #endif // CONFIGURATIONDIALOGS_H drumstick-2.5.1/library/PaxHeaders.27918/library.pro0000644000000000000000000000013214200302440017112 xustar0030 mtime=1644266784.789324158 30 atime=1644266784.965324271 30 ctime=1644266784.789324158 drumstick-2.5.1/library/library.pro0000644000175000001440000000041514200302440017673 0ustar00pedrousers00000000000000TEMPLATE = subdirs SUBDIRS += \ file \ rt \ rt-backends \ vpiano-plugin \ widgets rt-backends.depends += rt vpiano-plugin.depends += widgets linux { SUBDIRS += alsa rt-backends.depends += alsa } macx { OTHER_FILES += Info.plist.lib } drumstick-2.5.1/library/PaxHeaders.27918/rt-backends0000644000000000000000000000013214200302440017044 xustar0030 mtime=1644266784.821324179 30 atime=1644266784.965324271 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/0000755000175000001440000000000014200302440017702 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/mac-in0000644000000000000000000000013214200302440020210 xustar0030 mtime=1644266784.793324161 30 atime=1644266784.965324271 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/mac-in/0000755000175000001440000000000014200302440021046 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/mac-in/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023025 xustar0030 mtime=1644266784.793324161 30 atime=1644266784.965324271 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/mac-in/CMakeLists.txt0000644000175000001440000000521014200302440023604 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-mac-in_QTOBJ_SRCS macmidiinput.h ) set(drumstick-rt-mac-in_SRCS ../common/maccommon.h ../common/maccommon.cpp ../common/maccommon.mm macmidiinput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-mac-in_MOC_SRCS ${drumstick-rt-mac-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-mac-in_MOC_SRCS ${drumstick-rt-mac-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-mac-in STATIC ${drumstick-rt-mac-in_MOC_SRCS} ${drumstick-rt-mac-in_SRCS}) target_compile_definitions(drumstick-rt-mac-in PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-mac-in PROPERTIES STATIC_LIB "libdrumstick-rt-mac-in") else() add_library(drumstick-rt-mac-in MODULE ${drumstick-rt-mac-in_MOC_SRCS} ${drumstick-rt-mac-in_SRCS}) target_compile_definitions(drumstick-rt-mac-in PRIVATE QT_PLUGIN) endif() target_include_directories(drumstick-rt-mac-in PRIVATE ${Drumstick_SOURCE_DIR}/library/include ../common ) target_link_libraries(drumstick-rt-mac-in PUBLIC Drumstick::RT Qt${QT_VERSION_MAJOR}::Core "-framework CoreMIDI -framework CoreFoundation -framework CoreServices -framework Foundation" ) if (QT_VERSION VERSION_LESS 6.0.0) target_link_libraries( drumstick-rt-mac-in PUBLIC Qt${QT_VERSION_MAJOR}::Concurrent ) endif() set_target_properties(drumstick-rt-mac-in PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-mac-in EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/mac-in/PaxHeaders.27918/macmidiinput.h0000644000000000000000000000013214200302440023121 xustar0030 mtime=1644266784.793324161 30 atime=1644266784.965324271 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/mac-in/macmidiinput.h0000644000175000001440000000411714200302440023705 0ustar00pedrousers00000000000000/* Drumstick RT Backend Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef MACMIDIOBJECT_H #define MACMIDIOBJECT_H #include namespace drumstick { namespace rt { class MIDIOutput; class MacMIDIInputPrivate; class MacMIDIInput : public MIDIInput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput/2.0") Q_INTERFACES(drumstick::rt::MIDIInput) Q_PROPERTY(QStringList diagnostics READ getDiagnostics) Q_PROPERTY(bool status READ getStatus); public: explicit MacMIDIInput(QObject *parent = nullptr); ~MacMIDIInput(); // MIDIInput interface public: virtual void initialize(QSettings* settings); virtual QString backendName(); virtual QString publicName(); virtual void setPublicName(QString name); virtual QList connections(bool advanced); virtual void setExcludedConnections(QStringList conns); virtual void open(const MIDIConnection& name); virtual void close(); virtual MIDIConnection currentConnection(); virtual void setMIDIThruDevice(MIDIOutput *device); virtual void enableMIDIThru(bool enable); virtual bool isEnabledMIDIThru(); private: MacMIDIInputPrivate* const d; QStringList getDiagnostics(); bool getStatus(); }; }} #endif // MACMIDIOBJECT_H drumstick-2.5.1/library/rt-backends/mac-in/PaxHeaders.27918/mac-in.pro0000644000000000000000000000013214200302440022153 xustar0030 mtime=1644266784.793324161 30 atime=1644266784.965324271 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/mac-in/mac-in.pro0000644000175000001440000000104114200302440022730 0ustar00pedrousers00000000000000TEMPLATE = lib CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } TARGET = drumstick-rt-mac-in DESTDIR = ../../../build/lib/drumstick2 DEPENDPATH += . ../../include ../common INCLUDEPATH += . ../../include ../common include (../../../global.pri) QT -= gui QT += concurrent HEADERS += macmidiinput.h \ ../common/maccommon.h SOURCES += macmidiinput.cpp \ ../common/maccommon.cpp !static:LIBS += -F$$OUT_PWD/../../../build/lib -framework drumstick-rt LIBS += -framework CoreMIDI -framework CoreFoundation drumstick-2.5.1/library/rt-backends/mac-in/PaxHeaders.27918/macmidiinput.cpp0000644000000000000000000000013214200302440023454 xustar0030 mtime=1644266784.793324161 30 atime=1644266784.965324271 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/mac-in/macmidiinput.cpp0000644000175000001440000002771014200302440024244 0ustar00pedrousers00000000000000/* Drumstick RT Backend Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "macmidiinput.h" #include "maccommon.h" #include #include #include #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) #include #endif #include #include namespace drumstick { namespace rt { static CFStringRef DEFAULT_PUBLIC_NAME CFSTR("MIDI In"); static void MacMIDIReadProc( const MIDIPacketList *pktlist, void *refCon, void *connRefCon ); class MacMIDIInputPrivate { public: MacMIDIInput *m_inp; MIDIOutput *m_out; MIDIClientRef m_client; MIDIPortRef m_port; MIDIEndpointRef m_endpoint; MIDIEndpointRef m_source; bool m_thruEnabled; bool m_clientFilter; QString m_publicName; MIDIConnection m_currentInput; QStringList m_excludedNames; QList m_inputDevices; bool m_status; QStringList m_diagnostics; explicit MacMIDIInputPrivate(MacMIDIInput *inp) : m_inp(inp), m_out(nullptr), m_client(0), m_port(0), m_endpoint(0), m_source(0), m_thruEnabled(false), m_clientFilter(true), m_publicName(QString::fromCFString(DEFAULT_PUBLIC_NAME)) { internalCreate( DEFAULT_PUBLIC_NAME ); } void registerStatus(const QString& context, const OSStatus status) { if (status != noErr) { m_diagnostics << QString("%1 error: %2").arg(context, status); m_diagnostics << getErrorTextFromOSStatus(status); } } void internalCreate(CFStringRef name) { OSStatus result = noErr; result = MIDIClientCreate( name , nullptr, nullptr, &m_client ); if (result != noErr) { registerStatus("MIDIClientCreate()", result); return; } result = MIDIDestinationCreate ( m_client, name, MacMIDIReadProc, (void*) this, &m_endpoint ); if (result != noErr) { registerStatus("MIDIDestinationCreate()", result); return; } result = MIDIInputPortCreate( m_client, name, MacMIDIReadProc, (void *) this, &m_port ); if (result != noErr) { registerStatus("MIDIInputPortCreate()", result); return; } reloadDeviceList(true); } virtual ~MacMIDIInputPrivate() { internalDispose(); } void internalDispose() { OSStatus result = noErr; if (m_port != 0) { result = MIDIPortDispose(m_port); if (result != noErr) { registerStatus("MIDIPortDispose()", result); m_port = 0; } } if (m_endpoint != 0) { result = MIDIEndpointDispose(m_endpoint); if (result != noErr) { registerStatus("MIDIEndpointDispose()", result); m_endpoint = 0; } } if (m_client != 0) { result = MIDIClientDispose(m_client); if (result != noErr) { registerStatus("MIDIClientDispose()", result); m_client = 0; } } } void reloadDeviceList(bool advanced) { int num = MIDIGetNumberOfSources(); m_clientFilter = !advanced; m_inputDevices.clear(); m_inputDevices << MIDIConnection(); for (int i = 0; i < num; ++i) { bool excluded = false; MIDIEndpointRef dest = MIDIGetSource( i ); if (dest != 0) { QString name = getEndpointName(dest); if ( m_clientFilter && name.contains(QStringLiteral("IAC"), Qt::CaseSensitive) ) continue; if ( name.contains(m_publicName)) continue; for (const QString& n : m_excludedNames) { if (name.contains(n)) { excluded = true; break; } } if (!excluded) { m_inputDevices << MIDIConnection(name, i); } } } if (!m_currentInput.first.isEmpty() && m_source != 0 && !m_inputDevices.contains(m_currentInput)) { m_currentInput = MIDIConnection(); m_source = 0; } } void setPublicName(QString name) { if (m_publicName != name) { internalDispose(); internalCreate(name.toCFString()); m_publicName = name; } } void open(const MIDIConnection& conn) { OSStatus result = noErr; m_diagnostics.clear(); m_status = false; m_source = MIDIGetSource( conn.second.toInt() ); result = MIDIPortConnectSource( m_port, m_source, nullptr ); if (result != noErr) { registerStatus("MIDIPortConnectSource()", result); return; } m_currentInput = conn; m_status = (result == noErr); return; } void close() { OSStatus result = noErr; m_status = false; m_diagnostics.clear(); if (m_source != 0) { result = MIDIPortDisconnectSource(m_port, m_source); if (result != noErr) { registerStatus("MIDIPortDisconnectSource()", result); } m_source = 0; m_currentInput = MIDIConnection(); m_status = (result == noErr); } } void emitSignals(QByteArray& packet) { int value = 0, j = 0; while(j < packet.length()) { int status = packet[j] & 0xf0; int channel = packet[j] & 0x0f; QByteArray data; switch (status) { case MIDI_STATUS_NOTEOFF: if(m_out != nullptr && m_thruEnabled) m_out->sendNoteOff(channel, packet[j+1], packet[j+2]); emit m_inp->midiNoteOff(channel, packet[j+1], packet[j+2]); j+=3; break; case MIDI_STATUS_NOTEON: if(m_out != nullptr && m_thruEnabled) m_out->sendNoteOn(channel, packet[j+1], packet[j+2]); emit m_inp->midiNoteOn(channel, packet[j+1], packet[j+2]); j+=3; break; case MIDI_STATUS_KEYPRESURE: if(m_out != nullptr && m_thruEnabled) m_out->sendKeyPressure(channel, packet[j+1], packet[j+2]); emit m_inp->midiKeyPressure(channel, packet[j+1], packet[j+2]); j+=3; break; case MIDI_STATUS_CONTROLCHANGE: if(m_out != nullptr && m_thruEnabled) m_out->sendController(channel, packet[j+1], packet[j+2]); emit m_inp->midiController(channel, packet[j+1], packet[j+2]); j+=3; break; case MIDI_STATUS_PROGRAMCHANGE: if(m_out != nullptr && m_thruEnabled) m_out->sendProgram(channel, packet[j+1]); emit m_inp->midiProgram(channel, packet[j+1]); j+=2; break; case MIDI_STATUS_CHANNELPRESSURE: if(m_out != nullptr && m_thruEnabled) m_out->sendChannelPressure(channel, packet[j+1]); emit m_inp->midiChannelPressure(channel, packet[j+1]); j+=2; break; case MIDI_STATUS_PITCHBEND: value = (packet[j+1] + packet[j+2] * 0x80) - 8192; if(m_out != nullptr && m_thruEnabled) m_out->sendPitchBend(channel, value); emit m_inp->midiPitchBend(channel, value); j+=3; break; case MIDI_STATUS_SYSEX: if(m_out != nullptr && m_thruEnabled) m_out->sendSysex(packet); emit m_inp->midiSysex(packet); j+=packet.length(); break; default: registerStatus("invalid status", status); } } } }; static void MacMIDIReadProc( const MIDIPacketList *pktlist, void *refCon, void *connRefCon ) { Q_UNUSED(connRefCon) MacMIDIInputPrivate *obj = nullptr; if (refCon != nullptr) obj = static_cast(refCon); const MIDIPacket *packet = static_cast(pktlist->packet); for (unsigned int i = 0; i < pktlist->numPackets; ++i) { if (obj != nullptr && packet != nullptr) { QByteArray data((const char *)packet->data, packet->length); #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) QtConcurrent::run(obj, &MacMIDIInputPrivate::emitSignals, data); #else obj->emitSignals(data); #endif } packet = MIDIPacketNext(packet); } } MacMIDIInput::MacMIDIInput(QObject *parent) : MIDIInput(parent), d(new MacMIDIInputPrivate(this)) { } MacMIDIInput::~MacMIDIInput() { delete d; } void MacMIDIInput::initialize(QSettings *settings) { Q_UNUSED(settings) } QString MacMIDIInput::backendName() { return QLatin1String("CoreMIDI"); } QString MacMIDIInput::publicName() { return d->m_publicName; } void MacMIDIInput::setPublicName(QString name) { d->setPublicName(name); } QList MacMIDIInput::connections(bool advanced) { d->reloadDeviceList(advanced); return d->m_inputDevices; } void MacMIDIInput::setExcludedConnections(QStringList conns) { d->m_excludedNames = conns; } void MacMIDIInput::open(const MIDIConnection& conn) { d->open(conn); } void MacMIDIInput::close() { d->close(); } MIDIConnection MacMIDIInput::currentConnection() { return d->m_currentInput; } void MacMIDIInput::setMIDIThruDevice(MIDIOutput *device) { d->m_out = device; } void MacMIDIInput::enableMIDIThru(bool enable) { d->m_thruEnabled = enable; } bool MacMIDIInput::isEnabledMIDIThru() { return d->m_thruEnabled && d->m_out != 0; } QStringList MacMIDIInput::getDiagnostics() { return d->m_diagnostics; } bool MacMIDIInput::getStatus() { return d->m_status; } }} // namespace drumstick::rt drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440021661 xustar0030 mtime=1644266784.817324175 30 atime=1644266784.965324271 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/CMakeLists.txt0000644000175000001440000000277714200302440022457 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(DRUMSTICK_PLUGINS_DIR "drumstick2") if(FALSE) add_subdirectory(dummy-in) add_subdirectory(dummy-out) endif() if(BUILD_ALSA AND ALSA_FOUND) add_subdirectory(alsa-in) add_subdirectory(alsa-out) endif() if (PULSE_FOUND) add_subdirectory(eassynth) endif() if(Qt${QT_VERSION_MAJOR}Network_FOUND) add_subdirectory(net-in) add_subdirectory(net-out) endif() if(UNIX AND NOT APPLE) add_subdirectory(oss-in) add_subdirectory(oss-out) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") add_subdirectory(mac-in) add_subdirectory(mac-out) add_subdirectory(macsynth) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") add_subdirectory(win-in) add_subdirectory(win-out) endif() if(FLUIDSYNTH_FOUND) add_subdirectory(fluidsynth) endif() drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/net-out0000644000000000000000000000013214200302440020437 xustar0030 mtime=1644266784.821324179 30 atime=1644266784.965324271 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/net-out/0000755000175000001440000000000014200302440021275 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/net-out/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023254 xustar0030 mtime=1644266784.817324175 30 atime=1644266784.965324271 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/net-out/CMakeLists.txt0000644000175000001440000000461114200302440024037 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . find_package(Qt${QT_VERSION_MAJOR}Network REQUIRED) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-net-out_QTOBJ_SRCS netmidioutput.h ) set(drumstick-rt-net-out_SRCS netmidioutput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-net-out_MOC_SRCS ${drumstick-rt-net-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-net-out_MOC_SRCS ${drumstick-rt-net-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-net-out STATIC ${drumstick-rt-net-out_MOC_SRCS} ${drumstick-rt-net-out_SRCS}) target_compile_definitions(drumstick-rt-net-out PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-net-out PROPERTIES STATIC_LIB "libdrumstick-rt-net-out") else() add_library(drumstick-rt-net-out MODULE ${drumstick-rt-net-out_MOC_SRCS} ${drumstick-rt-net-out_SRCS}) target_compile_definitions(drumstick-rt-net-out PRIVATE QT_PLUGIN) endif() target_include_directories(drumstick-rt-net-out PRIVATE ${Drumstick_SOURCE_DIR}/library/include ) target_link_libraries(drumstick-rt-net-out PRIVATE Qt${QT_VERSION_MAJOR}::Network Drumstick::RT ) set_target_properties(drumstick-rt-net-out PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-net-out EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/net-out/PaxHeaders.27918/netmidioutput.cpp0000644000000000000000000000013214200302440024132 xustar0030 mtime=1644266784.821324179 30 atime=1644266784.965324271 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/net-out/netmidioutput.cpp0000644000175000001440000001734614200302440024726 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "netmidioutput.h" #include #include #include namespace drumstick { namespace rt { const QString NetMIDIOutput::DEFAULT_PUBLIC_NAME = QStringLiteral("MIDI Out"); const QString NetMIDIOutput::STR_ADDRESS_IPV4 = QStringLiteral("225.0.0.37"); const QString NetMIDIOutput::STR_ADDRESS_IPV6 = QStringLiteral("ff12::37"); const int NetMIDIOutput::MULTICAST_PORT = 21928; const int NetMIDIOutput::LAST_PORT = 21948; class NetMIDIOutput::NetMIDIOutputPrivate { public: QUdpSocket *m_socket; QString m_publicName; QHostAddress m_groupAddress; MIDIConnection m_currentOutput; QList m_outputDevices; QStringList m_excludedNames; QNetworkInterface m_iface; quint16 m_port; bool m_ipv6; bool m_status; QStringList m_diagnostics; NetMIDIOutputPrivate() : m_socket(nullptr), m_publicName(DEFAULT_PUBLIC_NAME), m_groupAddress(QHostAddress(STR_ADDRESS_IPV4)), m_port(0), m_ipv6(false) { for(int i=MULTICAST_PORT; ibeginGroup("Network"); QString ifaceName = settings->value("interface", QString()).toString(); m_ipv6 = settings->value("ipv6", false).toBool(); QString address = settings->value("address", m_ipv6 ? STR_ADDRESS_IPV6 : STR_ADDRESS_IPV4).toString(); settings->endGroup(); if (!ifaceName.isEmpty()) { m_iface = QNetworkInterface::interfaceFromName(ifaceName); } if (address.isEmpty()) { m_groupAddress.setAddress(m_ipv6 ? STR_ADDRESS_IPV6 : STR_ADDRESS_IPV4); } else { m_groupAddress.setAddress(address); } m_status = m_groupAddress.isMulticast(); if (!m_status) { m_diagnostics << QString("Invalid multicast address: %1").arg(address); } } } void open(const MIDIConnection& portName) { //qDebug() << Q_FUNC_INFO << portName; int p = portName.second.toInt(); if (p >= MULTICAST_PORT && p < LAST_PORT && m_status) { m_socket = new QUdpSocket(); bool res = m_socket->bind(m_ipv6 ? QHostAddress::AnyIPv6 : QHostAddress::AnyIPv4, m_socket->localPort()); if (res) { m_socket->setSocketOption(QAbstractSocket::MulticastTtlOption, 1); #ifdef Q_OS_UNIX m_socket->setSocketOption(QAbstractSocket::MulticastLoopbackOption, 0); #endif m_port = static_cast(p); if (m_iface.isValid()) { m_socket->setMulticastInterface(m_iface); } m_currentOutput = portName; m_status = m_socket->isValid(); } else { m_status = false; m_diagnostics << QString("Socket error: %1 = %2").arg(m_socket->error()).arg(m_socket->errorString()); } } } void close() { delete m_socket; m_socket = nullptr; m_currentOutput = MIDIConnection(); m_status = false; m_diagnostics.clear(); } void sendMessage(int m0) { QByteArray m; m.resize(1); m[0] = static_cast(m0); sendMessage(m); } void sendMessage(int m0, int m1) { QByteArray m; m.resize(2); m[0] = static_cast(m0); m[1] = static_cast(m1); sendMessage(m); } void sendMessage(int m0, int m1, int m2) { QByteArray m; m.resize(3); m[0] = static_cast(m0); m[1] = static_cast(m1); m[2] = static_cast(m2); sendMessage(m); } void sendMessage(const QByteArray& message ) { //qDebug() << Q_FUNC_INFO << message.toHex() << m_groupAddress << m_port; if (m_socket == nullptr) { m_diagnostics << "udp socket is null"; return; } else if (!m_socket->isValid() || m_socket->state() != QAbstractSocket::BoundState) { m_diagnostics << QString("udp socket has invalid state: %1 Error: %2 %3").arg(m_socket->state()).arg(m_socket->error()).arg(m_socket->errorString()); return; } auto res = m_socket->writeDatagram(message, m_groupAddress, m_port); //qDebug() << Q_FUNC_INFO << "writeDatagram:" << res; if (res < 0) { m_diagnostics << QString("Error: %1 %2").arg(m_socket->error()).arg(m_socket->errorString()); } } }; NetMIDIOutput::NetMIDIOutput(QObject *parent) : MIDIOutput(parent), d(new NetMIDIOutputPrivate) { } NetMIDIOutput::~NetMIDIOutput() { delete d; } void NetMIDIOutput::initialize(QSettings *settings) { d->initialize(settings); } QString NetMIDIOutput::backendName() { return QStringLiteral("Network"); } QString NetMIDIOutput::publicName() { return d->m_publicName; } void NetMIDIOutput::setPublicName(QString name) { d->m_publicName = name; } QList NetMIDIOutput::connections(bool advanced) { Q_UNUSED(advanced) return d->m_outputDevices; } void NetMIDIOutput::setExcludedConnections(QStringList conns) { Q_UNUSED(conns) } void NetMIDIOutput::open(const MIDIConnection& name) { d->open(name); } void NetMIDIOutput::close() { d->close(); } MIDIConnection NetMIDIOutput::currentConnection() { return d->m_currentOutput; } void NetMIDIOutput::sendNoteOff(int chan, int note, int vel) { d->sendMessage(MIDI_STATUS_NOTEOFF + chan, note, vel); } void NetMIDIOutput::sendNoteOn(int chan, int note, int vel) { d->sendMessage(MIDI_STATUS_NOTEON + chan, note, vel); } void NetMIDIOutput::sendKeyPressure(int chan, int note, int value) { d->sendMessage(MIDI_STATUS_KEYPRESURE + chan, note, value); } void NetMIDIOutput::sendController(int chan, int control, int value) { d->sendMessage(MIDI_STATUS_CONTROLCHANGE + chan, control, value); } void NetMIDIOutput::sendProgram(int chan, int program) { d->sendMessage(MIDI_STATUS_PROGRAMCHANGE + chan, program); } void NetMIDIOutput::sendChannelPressure(int chan, int value) { d->sendMessage(MIDI_STATUS_CHANNELPRESSURE + chan, value); } void NetMIDIOutput::sendPitchBend(int chan, int v) { // -8192 <= v <= 8191; 0 <= value <= 16384 int value = 8192 + v; d->sendMessage(MIDI_STATUS_PITCHBEND + chan, MIDI_LSB(value), MIDI_MSB(value)); } void NetMIDIOutput::sendSysex(const QByteArray &data) { d->sendMessage(data); } void NetMIDIOutput::sendSystemMsg(const int status) { d->sendMessage(status); } QStringList NetMIDIOutput::getDiagnostics() { return d->m_diagnostics; } bool NetMIDIOutput::getStatus() { return d->m_status; } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/net-out/PaxHeaders.27918/netmidioutput.h0000644000000000000000000000013214200302440023577 xustar0030 mtime=1644266784.821324179 30 atime=1644266784.965324271 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/net-out/netmidioutput.h0000644000175000001440000000567014200302440024370 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef NETMIDIOUTPUT_H #define NETMIDIOUTPUT_H #include #include #include namespace drumstick { namespace rt { class NetMIDIOutput : public MIDIOutput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput/2.0") Q_INTERFACES(drumstick::rt::MIDIOutput) Q_PROPERTY(QStringList diagnostics READ getDiagnostics) Q_PROPERTY(bool status READ getStatus) public: explicit NetMIDIOutput(QObject *parent = nullptr); virtual ~NetMIDIOutput(); static const QString DEFAULT_PUBLIC_NAME; static const QString STR_ADDRESS_IPV4; static const QString STR_ADDRESS_IPV6; static const int MULTICAST_PORT; static const int LAST_PORT; // MIDIOutput interface public: virtual void initialize(QSettings* settings) override; virtual QString backendName() override; virtual QString publicName() override; virtual void setPublicName(QString name) override; virtual QList connections(bool advanced) override; virtual void setExcludedConnections(QStringList conns) override; virtual void open(const MIDIConnection& name) override; virtual void close() override; virtual MIDIConnection currentConnection() override; public slots: virtual void sendNoteOff(int chan, int note, int vel) override; virtual void sendNoteOn(int chan, int note, int vel) override; virtual void sendKeyPressure(int chan, int note, int value) override; virtual void sendController(int chan, int control, int value) override; virtual void sendProgram(int chan, int program) override; virtual void sendChannelPressure(int chan, int value) override; virtual void sendPitchBend(int chan, int value) override; virtual void sendSysex(const QByteArray &data) override; virtual void sendSystemMsg(const int status) override; private: class NetMIDIOutputPrivate; NetMIDIOutputPrivate * const d; private: QStringList getDiagnostics(); bool getStatus(); }; }} #endif // NETMIDIOUTPUT_H drumstick-2.5.1/library/rt-backends/net-out/PaxHeaders.27918/net-out.pro0000644000000000000000000000013214200302440022631 xustar0030 mtime=1644266784.821324179 30 atime=1644266784.965324271 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/net-out/net-out.pro0000644000175000001440000000102714200302440023412 0ustar00pedrousers00000000000000TEMPLATE = lib CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } TARGET = drumstick-rt-net-out DESTDIR = ../../../build/lib/drumstick2 DEPENDPATH += . ../../include INCLUDEPATH += . ../../include include (../../../global.pri) DEPENDPATH += ../../include INCLUDEPATH += ../../include QT -= gui HEADERS += netmidioutput.h SOURCES += netmidioutput.cpp QT += network macx:!static:LIBS += -F$$OUT_PWD/../../../build/lib -framework drumstick-rt else:LIBS += -L$$OUT_PWD/../../../build/lib -l$$drumstickLib(drumstick-rt) drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/oss-out0000644000000000000000000000013214200302440020455 xustar0030 mtime=1644266784.821324179 30 atime=1644266784.965324271 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-out/0000755000175000001440000000000014200302440021313 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/oss-out/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023272 xustar0030 mtime=1644266784.821324179 30 atime=1644266784.965324271 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-out/CMakeLists.txt0000644000175000001440000000447014200302440024060 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-oss-out_QTOBJ_SRCS ossoutput.h ) set(drumstick-rt-oss-out_SRCS ossoutput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-oss-out_MOC_SRCS ${drumstick-rt-oss-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-oss-out_MOC_SRCS ${drumstick-rt-oss-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-oss-out STATIC ${drumstick-rt-oss-out_MOC_SRCS} ${drumstick-rt-oss-out_SRCS}) target_compile_definitions(drumstick-rt-oss-out PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-oss-out PROPERTIES STATIC_LIB "libdrumstick-rt-oss-out") else() add_library(drumstick-rt-oss-out MODULE ${drumstick-rt-oss-out_MOC_SRCS} ${drumstick-rt-oss-out_SRCS}) target_compile_definitions(drumstick-rt-oss-out PRIVATE QT_PLUGIN) endif() target_include_directories(drumstick-rt-oss-out PRIVATE ${Drumstick_SOURCE_DIR}/library/include ) target_link_libraries(drumstick-rt-oss-out PRIVATE Qt${QT_VERSION_MAJOR}::Core ) set_target_properties(drumstick-rt-oss-out PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-oss-out EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/oss-out/PaxHeaders.27918/ossoutput.h0000644000000000000000000000013214200302440022770 xustar0030 mtime=1644266784.821324179 30 atime=1644266784.965324271 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-out/ossoutput.h0000644000175000001440000000501714200302440023554 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ossOUTPUT_H #define ossOUTPUT_H #include #include namespace drumstick { namespace rt { class OSSOutput : public MIDIOutput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput/2.0") Q_INTERFACES(drumstick::rt::MIDIOutput) public: explicit OSSOutput(QObject *parent = nullptr); virtual ~OSSOutput(); static const QString DEFAULT_PUBLIC_NAME; // MIDIOutput interface public: virtual void initialize(QSettings* settings) override; virtual QString backendName() override; virtual QString publicName() override; virtual void setPublicName(QString name) override; virtual QList connections(bool advanced) override; virtual void setExcludedConnections(QStringList conns) override; virtual void open(const MIDIConnection& name) override; virtual void close() override; virtual MIDIConnection currentConnection() override; public slots: virtual void sendNoteOff(int chan, int note, int vel) override; virtual void sendNoteOn(int chan, int note, int vel) override; virtual void sendKeyPressure(int chan, int note, int value) override; virtual void sendController(int chan, int control, int value) override; virtual void sendProgram(int chan, int program) override; virtual void sendChannelPressure(int chan, int value) override; virtual void sendPitchBend(int chan, int value) override; virtual void sendSysex(const QByteArray &data) override; virtual void sendSystemMsg(const int status) override; private: class OSSOutputPrivate; OSSOutputPrivate *d; }; }} #endif // ossOUTPUT_H drumstick-2.5.1/library/rt-backends/oss-out/PaxHeaders.27918/oss-out.pro0000644000000000000000000000013214200302440022665 xustar0030 mtime=1644266784.821324179 30 atime=1644266784.965324271 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-out/oss-out.pro0000644000175000001440000000054314200302440023450 0ustar00pedrousers00000000000000TEMPLATE = lib TARGET = drumstick-rt-oss-out DESTDIR = ../../../build/lib/drumstick2 include (../../../global.pri) CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } DEPENDPATH += ../../include INCLUDEPATH += ../../include QT -= gui HEADERS += ossoutput.h SOURCES += ossoutput.cpp LIBS += -L$$OUT_PWD/../../../build/lib -ldrumstick-rt drumstick-2.5.1/library/rt-backends/oss-out/PaxHeaders.27918/ossoutput.cpp0000644000000000000000000000013214200302440023323 xustar0030 mtime=1644266784.821324179 30 atime=1644266784.965324271 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-out/ossoutput.cpp0000644000175000001440000001211314200302440024102 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "ossoutput.h" namespace drumstick { namespace rt { const QString OSSOutput::DEFAULT_PUBLIC_NAME = QStringLiteral("MIDI Out"); class OSSOutput::OSSOutputPrivate { public: bool m_advanced; QIODevice *m_device; QString m_publicName; MIDIConnection m_currentOutput; QList m_outputDevices; QStringList m_excludedNames; OSSOutputPrivate() : m_advanced(false), m_device(nullptr), m_publicName(DEFAULT_PUBLIC_NAME) { reloadDeviceList(); } ~OSSOutputPrivate() { close(); } void reloadDeviceList(bool advanced = false) { QDir dir("/dev"); QStringList filters; m_advanced = advanced; filters << "dmmidi*" << "admmidi*"; if (advanced) { filters << "midi*" << "amidi*"; } dir.setNameFilters(filters); dir.setFilter(QDir::System); dir.setSorting(QDir::Name); m_outputDevices.clear(); QFileInfoList listInfo = dir.entryInfoList(); foreach(const QFileInfo &info, listInfo) { m_outputDevices << MIDIConnection(info.baseName(), info.absoluteFilePath()); } } void open(const MIDIConnection& portName) { //qDebug() << Q_FUNC_INFO << portName; m_device = new QFile(portName.second.toString()); m_device->open(QIODevice::WriteOnly | QIODevice::Unbuffered); m_currentOutput = portName; } void close() { if (m_device != nullptr) { m_device->close(); delete m_device; m_device = nullptr; } m_currentOutput = MIDIConnection(); } void sendMessage(int m0) { QByteArray m; m.resize(1); m[0] = m0; sendMessage(m); } void sendMessage(int m0, int m1) { QByteArray m; m.resize(2); m[0] = m0; m[1] = m1; sendMessage(m); } void sendMessage(int m0, int m1, int m2) { QByteArray m; m.resize(3); m[0] = m0; m[1] = m1; m[2] = m2; sendMessage(m); } void sendMessage(const QByteArray& message ) { if (m_device == nullptr) { //qDebug() << "device is null"; return; } m_device->write(message); //m_device->flush(); } }; OSSOutput::OSSOutput(QObject *parent) : MIDIOutput(parent), d(new OSSOutputPrivate) {} OSSOutput::~OSSOutput() { delete d; } void OSSOutput::initialize(QSettings *settings) { Q_UNUSED(settings) } QString OSSOutput::backendName() { return QStringLiteral("OSS"); } QString OSSOutput::publicName() { return d->m_publicName; } void OSSOutput::setPublicName(QString name) { d->m_publicName = name; } QList OSSOutput::connections(bool advanced) { d->reloadDeviceList(advanced); return d->m_outputDevices; } void OSSOutput::setExcludedConnections(QStringList conns) { Q_UNUSED(conns) } void OSSOutput::open(const MIDIConnection& name) { d->open(name); } void OSSOutput::close() { d->close(); } MIDIConnection OSSOutput::currentConnection() { return d->m_currentOutput; } void OSSOutput::sendNoteOff(int chan, int note, int vel) { d->sendMessage(MIDI_STATUS_NOTEOFF + chan, note, vel);} void OSSOutput::sendNoteOn(int chan, int note, int vel) { d->sendMessage(MIDI_STATUS_NOTEON + chan, note, vel); } void OSSOutput::sendKeyPressure(int chan, int note, int value) { d->sendMessage(MIDI_STATUS_KEYPRESURE + chan, note, value); } void OSSOutput::sendController(int chan, int control, int value) { d->sendMessage(MIDI_STATUS_CONTROLCHANGE + chan, control, value); } void OSSOutput::sendProgram(int chan, int program) { d->sendMessage(MIDI_STATUS_PROGRAMCHANGE + chan, program); } void OSSOutput::sendChannelPressure(int chan, int value) { d->sendMessage(MIDI_STATUS_CHANNELPRESSURE + chan, value); } void OSSOutput::sendPitchBend(int chan, int v) { // -8192 <= v <= 8191; 0 <= value <= 16384 int value = 8192 + v; d->sendMessage(MIDI_STATUS_PITCHBEND + chan, MIDI_LSB(value), MIDI_MSB(value)); } void OSSOutput::sendSysex(const QByteArray &data) { d->sendMessage(data); } void OSSOutput::sendSystemMsg(const int status) { d->sendMessage(status); } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/alsa-out0000644000000000000000000000013214200302440020571 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/alsa-out/0000755000175000001440000000000014200302440021427 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/alsa-out/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023406 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/alsa-out/CMakeLists.txt0000644000175000001440000000440714200302440024174 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-alsa-out_QTOBJ_SRCS alsamidioutput.h ) set(drumstick-rt-alsa-out_SRCS alsamidioutput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-alsa-out_MOC_SRCS ${drumstick-rt-alsa-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-alsa-out_MOC_SRCS ${drumstick-rt-alsa-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-alsa-out STATIC ${drumstick-rt-alsa-out_MOC_SRCS} ${drumstick-rt-alsa-out_SRCS}) target_compile_definitions(drumstick-rt-alsa-out PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-alsa-out PROPERTIES STATIC_LIB "libdrumstick-rt-alsa-out") else() add_library(drumstick-rt-alsa-out MODULE ${drumstick-rt-alsa-out_MOC_SRCS} ${drumstick-rt-alsa-out_SRCS} ) target_compile_definitions(drumstick-rt-alsa-out PRIVATE QT_PLUGIN) endif() target_link_libraries(drumstick-rt-alsa-out PRIVATE Qt${QT_VERSION_MAJOR}::Core Drumstick::ALSA ) set_target_properties(drumstick-rt-alsa-out PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-alsa-out EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/alsa-out/PaxHeaders.27918/alsa-out.pro0000644000000000000000000000013214200302440023115 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/alsa-out/alsa-out.pro0000644000175000001440000000064014200302440023676 0ustar00pedrousers00000000000000TEMPLATE = lib CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } TARGET = drumstick-rt-alsa-out DESTDIR = ../../../build/lib/drumstick2 DEPENDPATH += . ../../include INCLUDEPATH += . ../../include include (../../../global.pri) QT -= gui HEADERS += alsamidioutput.h SOURCES += alsamidioutput.cpp LIBS += -L../../../build/lib \ -ldrumstick-rt \ -ldrumstick-alsa \ -lasound drumstick-2.5.1/library/rt-backends/alsa-out/PaxHeaders.27918/alsamidioutput.cpp0000644000000000000000000000013214200302440024416 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/alsa-out/alsamidioutput.cpp0000644000175000001440000002360314200302440025203 0ustar00pedrousers00000000000000/* Drumstick RT Backend using the ALSA Sequencer Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "alsamidioutput.h" #include #include #include #include #include #include #include #include namespace drumstick { namespace rt { using namespace ALSA; const QString ALSAMIDIOutput::DEFAULT_PUBLIC_NAME = QStringLiteral("MIDI Out"); class ALSAMIDIOutput::ALSAMIDIOutputPrivate { public: ALSAMIDIOutput *m_out; MidiClient *m_client; MidiPort *m_port; int m_portId; bool m_clientFilter; int m_runtimeAlsaNum; QString m_publicName; MIDIConnection m_currentOutput; QList m_outputDevices; QStringList m_excludedNames; QMutex m_outMutex; bool m_initialized; bool m_status; QStringList m_diagnostics; explicit ALSAMIDIOutputPrivate(ALSAMIDIOutput *q): m_out(q), m_client(nullptr), m_port(nullptr), m_portId(0), m_clientFilter(true), m_runtimeAlsaNum(0), m_publicName(DEFAULT_PUBLIC_NAME), m_initialized(false), m_status(false) { m_runtimeAlsaNum = getRuntimeALSALibraryNumber(); m_diagnostics.clear(); } ~ALSAMIDIOutputPrivate() { if (m_initialized) { clearSubscription(); uninitialize(); } } void initialize() { //qDebug() << Q_FUNC_INFO << m_initialized; if (!m_initialized) { m_client = new MidiClient(m_out); m_client->open(); m_client->setClientName(m_publicName); m_port = m_client->createPort(); m_port->setPortName("out"); m_port->setCapability( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ ); m_port->setPortType( SND_SEQ_PORT_TYPE_APPLICATION | SND_SEQ_PORT_TYPE_MIDI_GENERIC ); m_portId = m_port->getPortId(); m_initialized = true; m_status = true; m_diagnostics.clear(); } } void uninitialize() { //qDebug() << Q_FUNC_INFO << m_initialized; if (m_initialized) { if (m_port != nullptr) { m_port->detach(); delete m_port; m_port = nullptr; } if (m_client != nullptr) { m_client->close(); delete m_client; m_client = nullptr; } m_initialized = false; m_status = false; m_diagnostics.clear(); } } bool clientIsAdvanced(int clientId) { // asking for runtime version instead of SND_LIB_VERSION if (m_runtimeAlsaNum < 0x01000B) // ALSA <= 1.0.10 return (clientId < 64); else // ALSA >= 1.0.11 return (clientId < 16); } void reloadDeviceList(bool advanced) { QStringList clientNames; QMap namesMap; if (!m_initialized) { initialize(); } auto outputs = m_client->getAvailableOutputs(); m_clientFilter = !advanced; m_outputDevices.clear(); for (const PortInfo& p : qAsConst(outputs)) { QString name = p.getClientName(); clientNames << name; if (namesMap.contains(name)) { namesMap[name]++; } else { namesMap.insert(name, 1); } } for (PortInfo& p : outputs) { bool excluded = false; QString name = p.getClientName(); if (m_clientFilter && clientIsAdvanced(p.getClient())) continue; if ( m_clientFilter && name.startsWith(QStringLiteral("Virtual Raw MIDI")) ) continue; if ( name.startsWith(m_publicName) ) continue; for (const QString& n : qAsConst(m_excludedNames)) { if ( name.startsWith(n) ) { excluded = true; break; } } if (!excluded) { int k = clientNames.count(name) + 1; QString addr = QString("%1:%2").arg(p.getClient()).arg(p.getPort()); if (k > 2) { m_outputDevices << MIDIConnection(QString("%1 (%2)").arg(name).arg(k - namesMap[name]--), addr); } else { m_outputDevices << MIDIConnection(name, addr); } } } if (!m_currentOutput.first.isEmpty() && !m_outputDevices.contains(m_currentOutput)) { m_currentOutput = MIDIConnection(); } } bool setSubscription(const MIDIConnection &newOutputDevice) { if (!m_initialized) { initialize(); } if (m_outputDevices.contains(newOutputDevice)) { m_currentOutput = newOutputDevice; m_port->unsubscribeAll(); m_port->subscribeTo(newOutputDevice.second.toString()); return true; } return false; } void clearSubscription() { if (!m_currentOutput.first.isEmpty() && m_initialized) { m_port->unsubscribeAll(); m_currentOutput = MIDIConnection(); } } void sendEvent(SequencerEvent *ev) { if (!m_initialized) { initialize(); } QMutexLocker locker(&m_outMutex); ev->setSource(m_portId); ev->setSubscribers(); ev->setDirect(); m_client->outputDirect(ev); } void setPublicName(QString newName) { if (newName != m_publicName) { m_publicName = newName; if (m_initialized) { m_client->setClientName(newName); } } } }; ALSAMIDIOutput::ALSAMIDIOutput(QObject *parent) : MIDIOutput(parent), d(new ALSAMIDIOutputPrivate(this)) { } ALSAMIDIOutput::~ALSAMIDIOutput() { delete d; } void ALSAMIDIOutput::initialize(QSettings* settings) { Q_UNUSED(settings) d->initialize(); } /* SLOTS */ void ALSAMIDIOutput::sendNoteOn(int chan, int note, int vel) { NoteOnEvent ev(chan, note, vel); d->sendEvent(&ev); } void ALSAMIDIOutput::sendNoteOff(int chan, int note, int vel) { NoteOffEvent ev(chan, note, vel); d->sendEvent(&ev); } void ALSAMIDIOutput::sendController(int chan, int control, int value) { ControllerEvent ev(chan, control, value); d->sendEvent(&ev); } void ALSAMIDIOutput::sendKeyPressure(int chan, int note, int value) { KeyPressEvent ev(chan, note, value); d->sendEvent(&ev); } void ALSAMIDIOutput::sendProgram(int chan, int program) { ProgramChangeEvent ev(chan, program); d->sendEvent(&ev); } void ALSAMIDIOutput::sendChannelPressure(int chan, int value) { ChanPressEvent ev(chan, value); d->sendEvent(&ev); } void ALSAMIDIOutput::sendPitchBend(int chan, int value) { PitchBendEvent ev(chan, value); d->sendEvent(&ev); } void ALSAMIDIOutput::sendSysex(const QByteArray& data) { SysExEvent ev(data); d->sendEvent(&ev); } void ALSAMIDIOutput::sendSystemMsg(const int status) { SystemEvent ev(status); d->sendEvent(&ev); } QStringList ALSAMIDIOutput::getDiagnostics() { return d->m_diagnostics; } bool ALSAMIDIOutput::getStatus() { return d->m_status; } QString ALSAMIDIOutput::backendName() { return "ALSA"; } QString ALSAMIDIOutput::publicName() { return d->m_publicName; } void ALSAMIDIOutput::setPublicName(QString name) { d->setPublicName(name); } QList ALSAMIDIOutput::connections(bool advanced) { d->reloadDeviceList(advanced); return d->m_outputDevices; } void ALSAMIDIOutput::setExcludedConnections(QStringList conns) { d->m_excludedNames = conns; } MIDIConnection ALSAMIDIOutput::currentConnection() { return d->m_currentOutput; } void ALSAMIDIOutput::open(const MIDIConnection& name) { bool b = d->setSubscription(name); if (!b) { d->m_diagnostics << "failed subscription to " + name.first; } } void ALSAMIDIOutput::close() { d->clearSubscription(); d->uninitialize(); } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/alsa-out/PaxHeaders.27918/alsamidioutput.h0000644000000000000000000000013214200302440024063 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/alsa-out/alsamidioutput.h0000644000175000001440000000532714200302440024653 0ustar00pedrousers00000000000000/* Drumstick RT Backend using the ALSA Sequencer Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ALSAMIDIOUTPUT_H #define ALSAMIDIOUTPUT_H #include #include namespace drumstick { namespace rt { class ALSAMIDIOutput : public MIDIOutput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput/2.0") Q_INTERFACES(drumstick::rt::MIDIOutput) Q_PROPERTY(QStringList diagnostics READ getDiagnostics) Q_PROPERTY(bool status READ getStatus) public: explicit ALSAMIDIOutput(QObject *parent = nullptr); virtual ~ALSAMIDIOutput(); virtual void initialize(QSettings* settings) override; virtual QString backendName() override; virtual QString publicName() override; virtual void setPublicName(QString name) override; virtual QList connections(bool advanced) override; virtual void setExcludedConnections(QStringList conns) override; virtual void open(const MIDIConnection& name) override; virtual void close() override; virtual MIDIConnection currentConnection() override; static const QString DEFAULT_PUBLIC_NAME; public slots: virtual void sendNoteOn(int chan, int note, int vel) override; virtual void sendNoteOff(int chan, int note, int vel) override; virtual void sendController(int chan, int control, int value) override; virtual void sendKeyPressure(int chan, int note, int value) override; virtual void sendProgram(int chan, int program) override; virtual void sendChannelPressure(int chan, int value) override; virtual void sendPitchBend(int chan, int value) override; virtual void sendSysex(const QByteArray& data) override; virtual void sendSystemMsg(const int status) override; private: class ALSAMIDIOutputPrivate; ALSAMIDIOutputPrivate *d; private: QStringList getDiagnostics(); bool getStatus(); }; }} #endif /* ALSAMIDIOUTPUT_H */ drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/eassynth0000644000000000000000000000013214200302440020702 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/0000755000175000001440000000000014200302440021540 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/eassynth/PaxHeaders.27918/eassynth.pro0000644000000000000000000000013214200302440023337 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/eassynth.pro0000644000175000001440000000011414200302440024114 0ustar00pedrousers00000000000000TEMPLATE = subdirs SUBDIRS += \ sonivox \ src src.depends = sonivox drumstick-2.5.1/library/rt-backends/eassynth/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023517 xustar0030 mtime=1644266784.793324161 30 atime=1644266784.965324271 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/eassynth/CMakeLists.txt0000644000175000001440000000020014200302440024270 0ustar00pedrousers00000000000000set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DQT_NO_DEBUG_OUTPUT") add_subdirectory(sonivox) add_subdirectory(src) drumstick-2.5.1/library/rt-backends/eassynth/PaxHeaders.27918/sonivox0000644000000000000000000000013214200302440022407 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/0000755000175000001440000000000014200302440023245 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/eassynth/sonivox/PaxHeaders.27918/lib_src0000644000000000000000000000013214200302440024024 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/0000755000175000001440000000000014200302440024662 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_xmfdata.h0000644000000000000000000000013214200302440026526 xustar0030 mtime=1644266784.809324171 30 atime=1644266784.965324271 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_xmfdata.h0000644000175000001440000000313614200302440027312 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_xmfdata.h * * Contents and purpose: * Contains declarations for the XMF file parser. * * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_XMFDATA_H #define _EAS_XMFDATA_H #include "eas_data.h" /*---------------------------------------------------------------------------- * * S_XMF_DATA * * This structure contains the instance data required to parse an XMF file. * *---------------------------------------------------------------------------- */ typedef struct { EAS_FILE_HANDLE fileHandle; EAS_I32 fileOffset; EAS_VOID_PTR pSMFData; EAS_I32 midiOffset; EAS_I32 dlsOffset; S_DLS *pDLS; } S_XMF_DATA; #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_xmf.c0000644000000000000000000000013214200302440025667 xustar0030 mtime=1644266784.809324171 30 atime=1644266784.965324271 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_xmf.c0000644000175000001440000006733714200302440026470 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_xmf.c * 5 * Contents and purpose: * XMF File Parser * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 501 $ * $Date: 2006-12-11 17:53:36 -0800 (Mon, 11 Dec 2006) $ *---------------------------------------------------------------------------- */ #include #include "eas_data.h" #include "eas_miditypes.h" #include "eas_parser.h" #include "eas_report.h" #include "eas_host.h" #include "eas_midi.h" #include "eas_xmf.h" #include "eas_xmfdata.h" #include "eas_config.h" #include "eas_vm_protos.h" #include "eas_mdls.h" #include "eas_smf.h" /* XMF header file type */ #define XMF_IDENTIFIER 0x584d465f #define XMF_VERSION_1_00 0x312e3030 #define XMF_VERSION_1_01 0x312e3031 #define XMF_VERSION_2_00 0x322e3030 #define XMF_FILE_TYPE 0x00000002 #define XMF_SPEC_LEVEL 0x00000001 #define XMF_RIFF_CHUNK 0x52494646 #define XMF_RIFF_DLS 0x444c5320 #define XMF_SMF_CHUNK 0x4d546864 /* local prototypes */ static EAS_RESULT XMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset); static EAS_RESULT XMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT XMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime); static EAS_RESULT XMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode); static EAS_RESULT XMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState); static EAS_RESULT XMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT XMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT XMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT XMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT XMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); static EAS_RESULT XMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); static EAS_RESULT XMF_FindFileContents (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData); static EAS_RESULT XMF_ReadNode (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData, EAS_I32 nodeOffset, EAS_I32 *pLength, EAS_I32 depth); static EAS_RESULT XMF_ReadVLQ (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 *value); /*---------------------------------------------------------------------------- * * XMF_Parser * * This structure contains the functional interface for the XMF parser *---------------------------------------------------------------------------- */ const S_FILE_PARSER_INTERFACE EAS_XMF_Parser = { XMF_CheckFileType, XMF_Prepare, XMF_Time, XMF_Event, XMF_State, XMF_Close, XMF_Reset, XMF_Pause, XMF_Resume, NULL, XMF_SetData, XMF_GetData, NULL }; /*---------------------------------------------------------------------------- * XMF_CheckFileType() *---------------------------------------------------------------------------- * Purpose: * Check the file type to see if we can parse it * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset) { S_XMF_DATA *pXMFData; EAS_RESULT result; EAS_U32 temp; /* assume we don't recognize it initially */ *ppHandle = NULL; /* read the file identifier */ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS) return result; if (temp != XMF_IDENTIFIER) return EAS_SUCCESS; /* read the version */ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS) return result; if (temp == XMF_VERSION_2_00) { /* read the file type */ result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE); if (result != EAS_SUCCESS) return result; if (temp != XMF_FILE_TYPE) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file type was 0x%08x, expected 0x%08x\n", temp, XMF_FILE_TYPE); */ } return EAS_SUCCESS; } /* read the spec level */ result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE); if (result != EAS_SUCCESS) return result; if (temp != XMF_SPEC_LEVEL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file spec was 0x%08x, expected 0x%08x\n", temp, XMF_SPEC_LEVEL); */ } return EAS_SUCCESS; } } else if (temp != XMF_VERSION_1_00 && temp != XMF_VERSION_1_01) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file version was 0x%08x\n", temp); */ } return EAS_SUCCESS; } /* check for static memory allocation */ if (pEASData->staticMemoryModel) pXMFData = EAS_CMEnumData(EAS_CM_XMF_DATA); else pXMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_XMF_DATA)); if (!pXMFData) return EAS_ERROR_MALLOC_FAILED; /* zero the memory to insure complete initialization */ EAS_HWMemSet((void *)pXMFData,0, sizeof(S_XMF_DATA)); pXMFData->fileHandle = fileHandle; pXMFData->fileOffset = offset; *ppHandle = pXMFData; /* locate the SMF and DLS contents */ if ((result = XMF_FindFileContents(pEASData->hwInstData, pXMFData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No SMF data found in XMF file\n"); */ } return result; } /* let the SMF parser take over */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pXMFData->midiOffset)) != EAS_SUCCESS) return result; return SMF_CheckFileType(pEASData, fileHandle, &pXMFData->pSMFData, pXMFData->midiOffset); } /*---------------------------------------------------------------------------- * XMF_Prepare() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. Allocates instance data (or uses static allocation for * static memory model). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_XMF_DATA* pXMFData; EAS_RESULT result; /* parse DLS collection */ pXMFData = (S_XMF_DATA*) pInstData; if (pXMFData->dlsOffset != 0) { if ((result = DLSParser(pEASData->hwInstData, pXMFData->fileHandle, pXMFData->dlsOffset, &pXMFData->pDLS)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error converting XMF DLS data\n"); */ } return result; } } /* Prepare the SMF parser */ if ((result = SMF_Prepare(pEASData, pXMFData->pSMFData)) != EAS_SUCCESS) return result; /* if no DLS file, skip this step */ if (pXMFData->pDLS == NULL) return EAS_SUCCESS; /* tell the synth to use the DLS collection */ result = VMSetDLSLib(((S_SMF_DATA*) pXMFData->pSMFData)->pSynth, pXMFData->pDLS); if (result == EAS_SUCCESS) { DLSAddRef(pXMFData->pDLS); VMInitializeAllChannels(pEASData->pVoiceMgr, ((S_SMF_DATA*) pXMFData->pSMFData)->pSynth); } return result; } /*---------------------------------------------------------------------------- * XMF_Time() *---------------------------------------------------------------------------- * Purpose: * Returns the time of the next event in msecs * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pTime - pointer to variable to hold time of next event (in msecs) * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime) { return SMF_Time(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, pTime); } /*---------------------------------------------------------------------------- * XMF_Event() *---------------------------------------------------------------------------- * Purpose: * Parse the next event in the file * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode) { return SMF_Event(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, parserMode); } /*---------------------------------------------------------------------------- * XMF_State() *---------------------------------------------------------------------------- * Purpose: * Returns the current state of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pState - pointer to variable to store state * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState) { return SMF_State(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, pState); } /*---------------------------------------------------------------------------- * XMF_Close() *---------------------------------------------------------------------------- * Purpose: * Close the file and clean up * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_XMF_DATA* pXMFData; EAS_RESULT result; pXMFData = (S_XMF_DATA *)pInstData; /* close the SMF stream, it will close the file handle */ if ((result = SMF_Close(pEASData, pXMFData->pSMFData)) != EAS_SUCCESS) return result; if (pXMFData->pDLS) DLSCleanup(pEASData->hwInstData, pXMFData->pDLS); /* if using dynamic memory, free it */ if (!pEASData->staticMemoryModel) { /* free the instance data */ EAS_HWFree(pEASData->hwInstData, pXMFData); } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * XMF_Reset() *---------------------------------------------------------------------------- * Purpose: * Reset the sequencer. Used for locating backwards in the file. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { return SMF_Reset(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData); } /*---------------------------------------------------------------------------- * XMF_Pause() *---------------------------------------------------------------------------- * Purpose: * Pauses the sequencer. Mutes all voices and sets state to pause. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { return SMF_Pause(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData); } /*---------------------------------------------------------------------------- * XMF_Resume() *---------------------------------------------------------------------------- * Purpose: * Resume playing after a pause, sets state back to playing. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { return SMF_Resume(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData); } /*---------------------------------------------------------------------------- * XMF_SetData() *---------------------------------------------------------------------------- * Purpose: * Sets the playback rate of the underlying SMF file * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * rate - rate (28-bit fraction) * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value) { return SMF_SetData(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, param, value); } /*---------------------------------------------------------------------------- * XMF_GetData() *---------------------------------------------------------------------------- * Purpose: * Gets the file type * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * rate - rate (28-bit fraction) * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue) { EAS_RESULT result; /* call SMF parser to get value */ if ((result = SMF_GetData(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, param, pValue)) != EAS_SUCCESS) return result; /* special case for file type */ if (param == PARSER_DATA_FILE_TYPE) { if (*pValue == EAS_FILE_SMF0) *pValue = EAS_FILE_XMF0; else if (*pValue == EAS_FILE_SMF1) *pValue = EAS_FILE_XMF1; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * XMF_FindFileContents() *---------------------------------------------------------------------------- * Purpose: * Finds SMF data and DLS data in XMF file, and remembers offset for each. * If more than one is found, uses the first one found of each. * Makes assumptions about the format of a mobile XMF file * * Inputs: * pEASData - pointer to overall EAS data structure * pXMFData - pointer to XMF parser instance data * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_FindFileContents (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData) { EAS_RESULT result; EAS_I32 value; EAS_I32 length; EAS_I32 node_depth = 0 ; /* initialize offsets */ pXMFData->dlsOffset = pXMFData->midiOffset = 0; /* read file length, ignore it for now */ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS) return result; /* read MetaDataTypesTable length and skip over it */ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS) return result; if ((result = EAS_HWFileSeekOfs(hwInstData, pXMFData->fileHandle, value)) != EAS_SUCCESS) return result; /* get TreeStart offset and jump to it */ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS) return result; if ((result = XMF_ReadNode(hwInstData, pXMFData, value, &length, node_depth)) != EAS_SUCCESS) return result; /* check for SMF data */ if (pXMFData->midiOffset == 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No SMF data found in XMF file\n"); */ } return EAS_ERROR_FILE_FORMAT; } /* check for SFM in wrong order */ if ((pXMFData->dlsOffset > 0) && (pXMFData->midiOffset < pXMFData->dlsOffset)) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS data must precede SMF data in Mobile XMF file\n"); */ } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * XMF_ReadNode() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_ReadNode (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData, EAS_I32 nodeOffset, EAS_I32 *pLength, EAS_I32 depth) { EAS_RESULT result; EAS_I32 refType; EAS_I32 numItems; EAS_I32 offset; EAS_I32 length; EAS_I32 headerLength; EAS_U32 chunkType; /* check the depth of current node*/ if ( depth > 100 ) return EAS_ERROR_FILE_FORMAT; /* seek to start of node */ if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, nodeOffset)) != EAS_SUCCESS) return result; /* get node length */ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, pLength)) != EAS_SUCCESS) return result; /* get number of contained items */ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &numItems)) != EAS_SUCCESS) return result; /* get node header length */ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &headerLength)) != EAS_SUCCESS) return result; /* get metadata length */ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &length)) != EAS_SUCCESS) return result; /* get the current location */ if ((result = EAS_HWFilePos(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS) return result; if (offset - nodeOffset > headerLength) return EAS_FAILURE; /* skip to node contents */ if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, nodeOffset + headerLength)) != EAS_SUCCESS) return result; /* get reference type */ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &refType)) != EAS_SUCCESS) return result; /* get the current location */ if ((result = EAS_HWFilePos(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS) return result; /* process file node */ if (numItems == 0) { /* if in-file resource, find out where it is and jump to it */ if (refType == 2) { if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS) return result; offset += pXMFData->fileOffset; if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, offset)) != EAS_SUCCESS) return result; } /* or else it must be an inline resource */ else if (refType != 1) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected reference type %d\n", refType); */ } return EAS_ERROR_FILE_FORMAT; } /* get the chunk type */ if ((result = EAS_HWGetDWord(hwInstData, pXMFData->fileHandle, &chunkType, EAS_TRUE)) != EAS_SUCCESS) return result; /* found a RIFF chunk, check for DLS type */ if (chunkType == XMF_RIFF_CHUNK) { /* skip length */ if ((result = EAS_HWFileSeekOfs(hwInstData, pXMFData->fileHandle, sizeof(EAS_I32))) != EAS_SUCCESS) return result; /* get RIFF file type */ if ((result = EAS_HWGetDWord(hwInstData, pXMFData->fileHandle, &chunkType, EAS_TRUE)) != EAS_SUCCESS) return result; if (chunkType == XMF_RIFF_DLS) pXMFData->dlsOffset = offset; } /* found an SMF chunk */ else if (chunkType == XMF_SMF_CHUNK) pXMFData->midiOffset = offset; } /* folder node, process the items in the list */ else { for ( ; numItems > 0; numItems--) { /* process this item */ if (offset <= nodeOffset) { ALOGE("b/36725407: parser did not advance"); return EAS_ERROR_FILE_FORMAT; } if ((result = XMF_ReadNode(hwInstData, pXMFData, offset, &length, depth+1)) != EAS_SUCCESS) return result; /* seek to start of next item */ offset += length; if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, offset)) != EAS_SUCCESS) return result; } } return EAS_SUCCESS; } #if 0 /*---------------------------------------------------------------------------- * XMF_FindFileContents() *---------------------------------------------------------------------------- * Purpose: * Finds SMF data and DLS data in XMF file, and remembers offset for each. * If more than one is found, uses the first one found of each. * Makes assumptions about the format of a mobile XMF file * * Inputs: * pEASData - pointer to overall EAS data structure * pXMFData - pointer to XMF parser instance data * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_FindFileContents(S_EAS_DATA *pEASData, S_XMF_DATA *pXMFData, EAS_FILE_HANDLE fileHandle) { EAS_RESULT result; EAS_I32 offset; EAS_I32 value; EAS_I32 numItems; EAS_I32 length; EAS_CHAR id[4]; EAS_I32 location; /* init dls offset, so that we know we haven't found a dls chunk yet */ pXMFData->dlsOffset = 0; /* read file length, ignore it for now */ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS) return result; /* read MetaDataTypesTable length and skip over it */ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS) return result; if ((result = EAS_HWFileSeekOfs(pEASData, fileHandle, value)) != EAS_SUCCESS) return result; /* get TreeStart offset and jump to it */ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &offset)) != EAS_SUCCESS) return result; if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS) return result; /* read node length, ignore it for now */ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS) return result; /* read number of contained items */ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &numItems)) != EAS_SUCCESS) return result; /*read node header length */ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS) return result; /*go to the node offset */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + value)) != EAS_SUCCESS) return result; /* read Reference Type */ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS) return result; /* make sure it is an in-line resource, for now */ if (value != 1) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file tree\n"); */ } return EAS_FAILURE; } /* parse through the list of items */ while (numItems > 0) { /*get current offset */ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &offset)) != EAS_SUCCESS) return result; /*read node length */ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &length)) != EAS_SUCCESS) return result; /* read number of items */ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS) return result; /* make sure not a folder */ if (value != 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file node\n"); */ } return EAS_FAILURE; } /* read offset to resource and jump to it */ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS) return result; if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + value)) != EAS_SUCCESS) return result; /* read Reference Type */ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS) return result; /* make sure it is an in-line resource */ if (value != 1) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file node\n"); */ } return EAS_FAILURE; } /* get current offset as a possible location for SMF file or DLS file */ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &location)) != EAS_SUCCESS) return result; /* read four bytes */ if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, id, sizeof(id), &value)) != EAS_SUCCESS) return result; /* check if DLS */ if (pXMFData->dlsOffset == 0 && id[0] == 'R' && id[1] == 'I' && id[2] == 'F' && id[3] == 'F') { //remember offset pXMFData->dlsOffset = location; } /* else check if SMF */ else if (id[0] == 'M' && id[1] == 'T' && id[2] == 'h' && id[3] == 'd') { //remember offset pXMFData->midiOffset = location; //we are done return EAS_SUCCESS; } //one less item numItems--; //if more data, go to the next item if (numItems >0) { if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + length)) != EAS_SUCCESS) return result; } } return EAS_FAILURE; } #endif /*---------------------------------------------------------------------------- * XMF_ReadVLQ() *---------------------------------------------------------------------------- * Purpose: * Reads a VLQ encoded value from the file referenced by fileHandle * * Inputs: * pEASData - pointer to overall EAS data structure * fileHandle - pointer to file handle * * Outputs: * value - pointer to the value decoded from the VLQ data * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT XMF_ReadVLQ (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 *value) { EAS_RESULT result; EAS_U8 c; *value = 0; if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS) return result; while (c > 0x7F) { /*lint -e{703} shift for performance */ *value = (*value << 7) | (c & 0x7F); if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS) return result; } /*lint -e{703} shift for performance */ *value = (*value << 7) | c; return EAS_SUCCESS; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_wt_IPC_frame.h0000644000000000000000000000013214200302440027401 xustar0030 mtime=1644266784.809324171 30 atime=1644266784.965324271 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_wt_IPC_frame.h0000644000175000001440000000556114200302440030171 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_wt_IPC_frame.h * * Contents and purpose: * This module contains data definitions for the interprocessor * communications framework for a split-architecture synthesizer. * * This sample version writes IPC data to a file that can be used * as a test vector for the DSP simulator. For a real-time system * the file I/O is replaced with an IPC protocol in the hardware. * * Synchronization with the DSP is accomplished at the API level, * i.e. the host code should call EAS_Render when it is ready to * buffer another block of data for transmission to the DSP. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 818 $ * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_WT_IPC_FRAME_H #define _EAS_WT_IPC_FRAME_H /*---------------------------------------------------------------------------- * S_WT_FRAME * * This structure contains the common parameters that are updated *for each frame of audio. *---------------------------------------------------------------------------- */ typedef struct s_wt_frame_tag { EAS_I32 gainTarget; EAS_I32 phaseIncrement; #if defined(_FILTER_ENABLED) EAS_I32 k; EAS_I32 b1; EAS_I32 b2; #endif } S_WT_FRAME; /*---------------------------------------------------------------------------- * S_WT_CONFIG * * This structure contains state data for the wavetable engine *---------------------------------------------------------------------------- */ typedef struct s_wt_config_tag { EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */ EAS_U32 loopStart; /* points to first sample at start of loop */ EAS_U32 phaseAccum; /* current sample, integer portion of phase */ #if (NUM_OUTPUT_CHANNELS == 2) EAS_I16 gainLeft; /* left channel gain */ EAS_I16 gainRight; /* right channel gain */ #endif EAS_I16 gain; /* current voice gain */ } S_WT_CONFIG; #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_public.c0000644000000000000000000000013214200302440026353 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_public.c0000644000175000001440000025632414200302440027150 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_public.c * * Contents and purpose: * Contains EAS library public interface * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 842 $ * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $ *---------------------------------------------------------------------------- */ #define LOG_TAG "Sonivox" //#include "log/log.h" #include "eas_synthcfg.h" #include "eas.h" #include "eas_config.h" #include "eas_host.h" #include "eas_report.h" #include "eas_data.h" #include "eas_parser.h" #include "eas_pcm.h" #include "eas_midi.h" #include "eas_mixer.h" #include "eas_build.h" #include "eas_vm_protos.h" #include "eas_math.h" #ifdef JET_INTERFACE #include "jet_data.h" #endif #ifdef DLS_SYNTHESIZER #include "eas_mdls.h" #endif /* number of events to parse before calling EAS_HWYield function */ #define YIELD_EVENT_COUNT 10 /*---------------------------------------------------------------------------- * easLibConfig * * This structure is available through the EAS public interface to allow * the user to check the configuration of the library. *---------------------------------------------------------------------------- */ static const S_EAS_LIB_CONFIG easLibConfig = { LIB_VERSION, #ifdef _CHECKED_BUILD EAS_TRUE, #else EAS_FALSE, #endif MAX_SYNTH_VOICES, NUM_OUTPUT_CHANNELS, _OUTPUT_SAMPLE_RATE, BUFFER_SIZE_IN_MONO_SAMPLES, #ifdef _FILTER_ENABLED EAS_TRUE, #else EAS_FALSE, #endif _BUILD_TIME_, _BUILD_VERSION_ }; /* local prototypes */ static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, S_EAS_STREAM *pStream, EAS_U32 endTime, EAS_INT parseMode); /*---------------------------------------------------------------------------- * EAS_SetStreamParameter *---------------------------------------------------------------------------- * Sets the specified parameter in the stream. Allows access to * customizable settings within the individual file parsers. *---------------------------------------------------------------------------- * pEASData - pointer to EAS persistent data object * pStream - stream handle * param - enumerated parameter (see eas_parser.h) * value - new value *---------------------------------------------------------------------------- */ EAS_RESULT EAS_SetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 value) { S_FILE_PARSER_INTERFACE *pParserModule; pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule; if (pParserModule->pfSetData) return (*pParserModule->pfSetData)(pEASData, pStream->handle, param, value); return EAS_ERROR_FEATURE_NOT_AVAILABLE; } /*---------------------------------------------------------------------------- * EAS_GetStreamParameter *---------------------------------------------------------------------------- * Sets the specified parameter in the stream. Allows access to * customizable settings within the individual file parsers. *---------------------------------------------------------------------------- * pEASData - pointer to EAS persistent data object * pStream - stream handle * param - enumerated parameter (see eas_parser.h) * pValue - pointer to variable to receive current setting *---------------------------------------------------------------------------- */ EAS_RESULT EAS_GetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 *pValue) { S_FILE_PARSER_INTERFACE *pParserModule; pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule; if (pParserModule->pfGetData) return (*pParserModule->pfGetData)(pEASData, pStream->handle, param, pValue); return EAS_ERROR_FEATURE_NOT_AVAILABLE; } /*---------------------------------------------------------------------------- * EAS_StreamReady() *---------------------------------------------------------------------------- * This routine sets common parameters like transpose, volume, etc. * First, it attempts to use the parser EAS_SetStreamParameter interface. If that * fails, it attempts to get the synth handle from the parser and * set the parameter directly on the synth. This eliminates duplicate * code in the parser. *---------------------------------------------------------------------------- */ EAS_BOOL EAS_StreamReady (S_EAS_DATA *pEASData, EAS_HANDLE pStream) { S_FILE_PARSER_INTERFACE *pParserModule; EAS_STATE state; pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule; if (pParserModule->pfState(pEASData, pStream->handle, &state) != EAS_SUCCESS) return EAS_FALSE; return (state < EAS_STATE_OPEN); } /*---------------------------------------------------------------------------- * EAS_IntSetStrmParam() *---------------------------------------------------------------------------- * This routine sets common parameters like transpose, volume, etc. * First, it attempts to use the parser EAS_SetStreamParameter interface. If that * fails, it attempts to get the synth handle from the parser and * set the parameter directly on the synth. This eliminates duplicate * code in the parser. *---------------------------------------------------------------------------- */ EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value) { S_SYNTH *pSynth; /* try to set the parameter using stream interface */ if (EAS_SetStreamParameter(pEASData, pStream, param, value) == EAS_SUCCESS) return EAS_SUCCESS; /* get a pointer to the synth object and set it directly */ /*lint -e{740} we are cheating by passing a pointer through this interface */ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS) return EAS_ERROR_INVALID_PARAMETER; if (pSynth == NULL) return EAS_ERROR_INVALID_PARAMETER; switch (param) { #ifdef DLS_SYNTHESIZER case PARSER_DATA_DLS_COLLECTION: { EAS_RESULT result = VMSetDLSLib(pSynth, (EAS_DLSLIB_HANDLE) value); if (result == EAS_SUCCESS) { DLSAddRef((S_DLS*) value); VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth); } return result; } #endif case PARSER_DATA_EAS_LIBRARY: return VMSetEASLib(pSynth, (EAS_SNDLIB_HANDLE) value); case PARSER_DATA_POLYPHONY: return VMSetPolyphony(pEASData->pVoiceMgr, pSynth, value); case PARSER_DATA_PRIORITY: return VMSetPriority(pEASData->pVoiceMgr, pSynth, value); case PARSER_DATA_TRANSPOSITION: VMSetTranposition(pSynth, value); break; case PARSER_DATA_VOLUME: VMSetVolume(pSynth, (EAS_U16) value); break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ } return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_IntGetStrmParam() *---------------------------------------------------------------------------- * This routine gets common parameters like transpose, volume, etc. * First, it attempts to use the parser EAS_GetStreamParameter interface. If that * fails, it attempts to get the synth handle from the parser and * get the parameter directly on the synth. *---------------------------------------------------------------------------- */ EAS_RESULT EAS_IntGetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 *pValue) { S_SYNTH *pSynth; /* try to set the parameter */ if (EAS_GetStreamParameter(pEASData, pStream, param, pValue) == EAS_SUCCESS) return EAS_SUCCESS; /* get a pointer to the synth object and retrieve data directly */ /*lint -e{740} we are cheating by passing a pointer through this interface */ if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS) return EAS_ERROR_INVALID_PARAMETER; if (pSynth == NULL) return EAS_ERROR_INVALID_PARAMETER; switch (param) { case PARSER_DATA_POLYPHONY: return VMGetPolyphony(pEASData->pVoiceMgr, pSynth, pValue); case PARSER_DATA_PRIORITY: return VMGetPriority(pEASData->pVoiceMgr, pSynth, pValue); case PARSER_DATA_TRANSPOSITION: VMGetTranposition(pSynth, pValue); break; case PARSER_DATA_NOTE_COUNT: *pValue = VMGetNoteCount(pSynth); break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ } return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_AllocateStream() *---------------------------------------------------------------------------- * Purpose: * Allocates a stream handle * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static EAS_INT EAS_AllocateStream (EAS_DATA_HANDLE pEASData) { EAS_INT streamNum; /* check for static allocation, only one stream allowed */ if (pEASData->staticMemoryModel) { if (pEASData->streams[0].handle != NULL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Attempt to open multiple streams in static model\n"); */ } return -1; } return 0; } /* dynamic model */ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++) if (pEASData->streams[streamNum].handle == NULL) break; if (streamNum == MAX_NUMBER_STREAMS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Exceeded maximum number of open streams\n"); */ } return -1; } return streamNum; } /*---------------------------------------------------------------------------- * EAS_InitStream() *---------------------------------------------------------------------------- * Purpose: * Initialize a stream * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static void EAS_InitStream (S_EAS_STREAM *pStream, EAS_VOID_PTR pParserModule, EAS_VOID_PTR streamHandle) { pStream->pParserModule = pParserModule; pStream->handle = streamHandle; pStream->time = 0; pStream->frameLength = AUDIO_FRAME_LENGTH; pStream->repeatCount = 0; pStream->volume = DEFAULT_STREAM_VOLUME; pStream->streamFlags = 0; } /*---------------------------------------------------------------------------- * EAS_Config() *---------------------------------------------------------------------------- * Purpose: * Returns a pointer to a structure containing the configuration options * in this library build. * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void) { return &easLibConfig; } /*---------------------------------------------------------------------------- * EAS_Init() *---------------------------------------------------------------------------- * Purpose: * Initialize the synthesizer library * * Inputs: * ppEASData - pointer to data handle variable for this instance * * Outputs: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData) { EAS_HW_DATA_HANDLE pHWInstData; EAS_RESULT result; S_EAS_DATA *pEASData; EAS_INT module; EAS_BOOL staticMemoryModel; /* get the memory model */ staticMemoryModel = EAS_CMStaticMemoryModel(); /* initialize the host wrapper interface */ *ppEASData = NULL; if ((result = EAS_HWInit(&pHWInstData)) != EAS_SUCCESS) return result; /* check Configuration Module for S_EAS_DATA allocation */ if (staticMemoryModel) pEASData = EAS_CMEnumData(EAS_CM_EAS_DATA); else pEASData = EAS_HWMalloc(pHWInstData, sizeof(S_EAS_DATA)); if (!pEASData) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate EAS library memory\n"); */ } return EAS_ERROR_MALLOC_FAILED; } /* initialize some data */ EAS_HWMemSet(pEASData, 0, sizeof(S_EAS_DATA)); pEASData->staticMemoryModel = (EAS_BOOL8) staticMemoryModel; pEASData->hwInstData = pHWInstData; pEASData->renderTime = 0; /* set header search flag */ #ifdef FILE_HEADER_SEARCH pEASData->searchHeaderFlag = EAS_TRUE; #endif /* initalize parameters */ EAS_SetVolume(pEASData, NULL, DEFAULT_VOLUME); #ifdef _METRICS_ENABLED /* initalize the metrics module */ pEASData->pMetricsModule = EAS_CMEnumOptModules(EAS_MODULE_METRICS); if (pEASData->pMetricsModule != NULL) { if ((result = (*pEASData->pMetricsModule->pfInit)(pEASData, &pEASData->pMetricsData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld initializing metrics module\n", result); */ } return result; } } #endif /* initailize the voice manager & synthesizer */ if ((result = VMInitialize(pEASData)) != EAS_SUCCESS) return result; /* initialize mix engine */ if ((result = EAS_MixEngineInit(pEASData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld starting up mix engine\n", result); */ } return result; } /* initialize effects modules */ for (module = 0; module < NUM_EFFECTS_MODULES; module++) { pEASData->effectsModules[module].effect = EAS_CMEnumFXModules(module); if (pEASData->effectsModules[module].effect != NULL) { if ((result = (*pEASData->effectsModules[module].effect->pfInit)(pEASData, &pEASData->effectsModules[module].effectData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Initialization of effects module %d returned %d\n", module, result); */ } return result; } } } /* initialize PCM engine */ if ((result = EAS_PEInit(pEASData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_PEInit failed with error code %ld\n", result); */ } return result; } /* return instance data pointer to host */ *ppEASData = pEASData; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_Shutdown() *---------------------------------------------------------------------------- * Purpose: * Shuts down the library. Deallocates any memory associated with the * synthesizer (dynamic memory model only) * * Inputs: * pEASData - handle to data for this instance * * Outputs: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData) { /* check for NULL handle */ if (!pEASData) return EAS_ERROR_HANDLE_INTEGRITY; /* establish pointers */ EAS_HW_DATA_HANDLE hwInstData = pEASData->hwInstData; /* if there are streams open, close them */ EAS_RESULT reportResult = EAS_SUCCESS; EAS_RESULT result; EAS_INT i; for (i = 0; i < MAX_NUMBER_STREAMS; i++) { if (pEASData->streams[i].pParserModule && pEASData->streams[i].handle) { if ((result = (*((S_FILE_PARSER_INTERFACE*)(pEASData->streams[i].pParserModule))->pfClose)(pEASData, pEASData->streams[i].handle)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down parser module\n", result); */ } reportResult = result; } } } /* shutdown PCM engine */ if ((result = EAS_PEShutdown(pEASData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down PCM engine\n", result); */ } if (reportResult == EAS_SUCCESS) reportResult = result; } /* shutdown mix engine */ if ((result = EAS_MixEngineShutdown(pEASData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down mix engine\n", result); */ } if (reportResult == EAS_SUCCESS) reportResult = result; } /* shutdown effects modules */ for (i = 0; i < NUM_EFFECTS_MODULES; i++) { if (pEASData->effectsModules[i].effect) { if ((result = (*pEASData->effectsModules[i].effect->pfShutdown)(pEASData, pEASData->effectsModules[i].effectData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Shutdown of effects module %d returned %d\n", i, result); */ } if (reportResult == EAS_SUCCESS) reportResult = result; } } } /* shutdown the voice manager & synthesizer */ VMShutdown(pEASData); #ifdef _METRICS_ENABLED /* shutdown the metrics module */ if (pEASData->pMetricsModule != NULL) { if ((result = (*pEASData->pMetricsModule->pfShutdown)(pEASData, pEASData->pMetricsData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down metrics module\n", result); */ } if (reportResult == EAS_SUCCESS) reportResult = result; } } #endif /* release allocated memory */ if (!pEASData->staticMemoryModel) EAS_HWFree(hwInstData, pEASData); /* shutdown host wrappers */ if (hwInstData) { if ((result = EAS_HWShutdown(hwInstData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down host wrappers\n", result); */ } if (reportResult == EAS_SUCCESS) reportResult = result; } } return reportResult; } #ifdef JET_INTERFACE /*---------------------------------------------------------------------------- * EAS_OpenJETStream() *---------------------------------------------------------------------------- * Private interface for JET to open an SMF stream with an offset *---------------------------------------------------------------------------- */ EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream) { EAS_RESULT result; EAS_VOID_PTR streamHandle; S_FILE_PARSER_INTERFACE *pParserModule; EAS_INT streamNum; /* allocate a stream */ if ((streamNum = EAS_AllocateStream(pEASData)) < 0) return EAS_ERROR_MAX_STREAMS_OPEN; /* check Configuration Module for SMF parser */ *ppStream = NULL; streamHandle = NULL; pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(0); if (pParserModule == NULL) return EAS_ERROR_UNRECOGNIZED_FORMAT; /* see if SMF parser recognizes the file */ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, offset)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ } return result; } /* parser recognized the file, return the handle */ if (streamHandle) { EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle); *ppStream = &pEASData->streams[streamNum]; return EAS_SUCCESS; } return EAS_ERROR_UNRECOGNIZED_FORMAT; } #endif /*---------------------------------------------------------------------------- * EAS_OpenFile() *---------------------------------------------------------------------------- * Purpose: * Opens a file for audio playback. * * Inputs: * pEASData - pointer to overall EAS data structure * pHandle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream) { EAS_RESULT result; EAS_FILE_HANDLE fileHandle; EAS_VOID_PTR streamHandle; S_FILE_PARSER_INTERFACE *pParserModule; EAS_INT streamNum; EAS_INT moduleNum; /* open the file */ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS) return result; /* allocate a stream */ if ((streamNum = EAS_AllocateStream(pEASData)) < 0) { /* Closing the opened file as stream allocation failed */ EAS_HWCloseFile(pEASData->hwInstData, fileHandle); return EAS_ERROR_MAX_STREAMS_OPEN; } /* check Configuration Module for file parsers */ pParserModule = NULL; *ppStream = NULL; streamHandle = NULL; for (moduleNum = 0; ; moduleNum++) { pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(moduleNum); if (pParserModule == NULL) break; /* see if this parser recognizes it */ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS) { /* Closing the opened file as file type check failed */ EAS_HWCloseFile(pEASData->hwInstData, fileHandle); { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ } return result; } /* parser recognized the file, return the handle */ if (streamHandle) { /* save the parser pointer and file handle */ EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle); *ppStream = &pEASData->streams[streamNum]; return EAS_SUCCESS; } /* rewind the file for the next parser */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, 0L)) != EAS_SUCCESS) { /* Closing the opened file as file seek failed */ EAS_HWCloseFile(pEASData->hwInstData, fileHandle); return result; } } /* no parser was able to recognize the file, close it and return an error */ EAS_HWCloseFile(pEASData->hwInstData, fileHandle); { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } #ifdef MMAPI_SUPPORT /*---------------------------------------------------------------------------- * EAS_MMAPIToneControl() *---------------------------------------------------------------------------- * Purpose: * Opens a ToneControl file for audio playback. * * Inputs: * pEASData - pointer to overall EAS data structure * pHandle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream) { EAS_RESULT result; EAS_FILE_HANDLE fileHandle; EAS_VOID_PTR streamHandle; S_FILE_PARSER_INTERFACE *pParserModule; EAS_INT streamNum; /* check if the tone control parser is available */ *ppStream = NULL; streamHandle = NULL; pParserModule = EAS_CMEnumOptModules(EAS_MODULE_MMAPI_TONE_CONTROL); if (pParserModule == NULL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_MMAPIToneControl: ToneControl parser not available\n"); */ } return EAS_ERROR_FEATURE_NOT_AVAILABLE; } /* open the file */ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS) return result; /* allocate a stream */ if ((streamNum = EAS_AllocateStream(pEASData)) < 0) return EAS_ERROR_MAX_STREAMS_OPEN; /* see if ToneControl parser recognizes it */ if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ } return result; } /* parser accepted the file, return the handle */ if (streamHandle) { /* save the parser pointer and file handle */ EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle); *ppStream = &pEASData->streams[streamNum]; return EAS_SUCCESS; } /* parser did not recognize the file, close it and return an error */ EAS_HWCloseFile(pEASData->hwInstData, fileHandle); { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /*---------------------------------------------------------------------------- * EAS_GetWaveFmtChunk *---------------------------------------------------------------------------- * Helper function to retrieve WAVE file fmt chunk for MMAPI *---------------------------------------------------------------------------- * pEASData - pointer to EAS persistent data object * pStream - stream handle * pFmtChunk - pointer to variable to receive current setting *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_VOID_PTR *ppFmtChunk) { EAS_RESULT result; EAS_I32 value; if ((result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FORMAT, &value)) != EAS_SUCCESS) return result; *ppFmtChunk = (EAS_VOID_PTR) value; return EAS_SUCCESS; } #endif /*---------------------------------------------------------------------------- * EAS_GetFileType *---------------------------------------------------------------------------- * Returns the file type (see eas_types.h for enumerations) *---------------------------------------------------------------------------- * pEASData - pointer to EAS persistent data object * pStream - stream handle * pFileType - pointer to variable to receive file type *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetFileType (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 *pFileType) { if (!EAS_StreamReady (pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; return EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FILE_TYPE, pFileType); } /*---------------------------------------------------------------------------- * EAS_Prepare() *---------------------------------------------------------------------------- * Purpose: * Prepares the synthesizer to play the file or stream. Parses the first * frame of data from the file and arms the synthesizer. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - file or stream handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream) { S_FILE_PARSER_INTERFACE *pParserModule; EAS_STATE state; EAS_RESULT result; pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule; if (pParserModule == NULL) return EAS_ERROR_FEATURE_NOT_AVAILABLE; /* check for valid state */ result = pParserModule->pfState(pEASData, pStream->handle, &state); if (result == EAS_SUCCESS) { /* prepare the stream */ if (state == EAS_STATE_OPEN) { pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule; result = (*pParserModule->pfPrepare)(pEASData, pStream->handle); /* set volume */ if (result == EAS_SUCCESS) result = EAS_SetVolume(pEASData, pStream, pStream->volume); } else result = EAS_ERROR_NOT_VALID_IN_THIS_STATE; } return result; } /*---------------------------------------------------------------------------- * EAS_Render() *---------------------------------------------------------------------------- * Purpose: * Parse the Midi data and render PCM audio data. * * Inputs: * pEASData - buffer for internal EAS data * pOut - output buffer pointer * nNumRequested - requested num samples to generate * pnNumGenerated - actual number of samples generated * * Outputs: * EAS_SUCCESS if PCM data was successfully rendered * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated) { S_FILE_PARSER_INTERFACE *pParserModule; EAS_RESULT result; EAS_I32 voicesRendered; EAS_STATE parserState; EAS_INT streamNum; /* assume no samples generated and reset workload */ *pNumGenerated = 0; VMInitWorkload(pEASData->pVoiceMgr); /* no support for other buffer sizes yet */ if (numRequested != BUFFER_SIZE_IN_MONO_SAMPLES) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "This library supports only %ld samples in buffer, host requested %ld samples\n", (EAS_I32) BUFFER_SIZE_IN_MONO_SAMPLES, numRequested); */ } return EAS_BUFFER_SIZE_MISMATCH; } #ifdef _METRICS_ENABLED /* start performance counter */ if (pEASData->pMetricsData) (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME); #endif /* prep the frame buffer, do mix engine prep only if TRUE */ #ifdef _SPLIT_ARCHITECTURE if (VMStartFrame(pEASData)) EAS_MixEnginePrep(pEASData, numRequested); #else /* prep the mix engine */ EAS_MixEnginePrep(pEASData, numRequested); #endif /* save the output buffer pointer */ pEASData->pOutputAudioBuffer = pOut; #ifdef _METRICS_ENABLED /* start performance counter */ if (pEASData->pMetricsData) (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME); #endif /* if we haven't finished parsing from last time, do it now */ /* need to parse another frame of events before we render again */ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++) { /* clear the locate flag */ pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_LOCATE; if (pEASData->streams[streamNum].pParserModule) { /* establish pointer to parser module */ pParserModule = pEASData->streams[streamNum].pParserModule; /* handle pause */ if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PAUSE) { if (pParserModule->pfPause) result = pParserModule->pfPause(pEASData, pEASData->streams[streamNum].handle); pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PAUSE; } /* get current state */ if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS) return result; /* handle resume */ if (parserState == EAS_STATE_PAUSED) { if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_RESUME) { if (pParserModule->pfResume) result = pParserModule->pfResume(pEASData, pEASData->streams[streamNum].handle); pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_RESUME; } } /* if necessary, parse stream */ if ((pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PARSED) == 0) if ((result = EAS_ParseEvents(pEASData, &pEASData->streams[streamNum], pEASData->streams[streamNum].time + pEASData->streams[streamNum].frameLength, eParserModePlay)) != EAS_SUCCESS) return result; /* check for an early abort */ if ((pEASData->streams[streamNum].streamFlags) == 0) { #ifdef _METRICS_ENABLED /* stop performance counter */ if (pEASData->pMetricsData) (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME); #endif return EAS_SUCCESS; } /* check for repeat */ if (pEASData->streams[streamNum].repeatCount) { /* check for stopped state */ if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS) return result; if (parserState == EAS_STATE_STOPPED) { /* decrement repeat count, unless it is negative */ if (pEASData->streams[streamNum].repeatCount > 0) pEASData->streams[streamNum].repeatCount--; /* reset the parser */ if ((result = (*pParserModule->pfReset)(pEASData, pEASData->streams[streamNum].handle)) != EAS_SUCCESS) return result; pEASData->streams[streamNum].time = 0; } } } } #ifdef _METRICS_ENABLED /* stop performance counter */ if (pEASData->pMetricsData) (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME); #endif #ifdef _METRICS_ENABLED /* start the render timer */ if (pEASData->pMetricsData) (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME); #endif /* render audio */ if ((result = VMRender(pEASData->pVoiceMgr, BUFFER_SIZE_IN_MONO_SAMPLES, pEASData->pMixBuffer, &voicesRendered)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "pfRender function returned error %ld\n", result); */ } return result; } #ifdef _METRICS_ENABLED /* stop the render timer */ if (pEASData->pMetricsData) { (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_FRAME_COUNT, 1); (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME); (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_TOTAL_VOICE_COUNT, (EAS_U32) voicesRendered); (void)(*pEASData->pMetricsModule->pfRecordMaxValue)(pEASData->pMetricsData, EAS_PM_MAX_VOICES, (EAS_U32) voicesRendered); } #endif //2 Do we really need frameParsed? /* need to parse another frame of events before we render again */ for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++) if (pEASData->streams[streamNum].pParserModule != NULL) pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PARSED; #ifdef _METRICS_ENABLED /* start performance counter */ if (pEASData->pMetricsData) (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME); #endif /* render PCM audio */ if ((result = EAS_PERender(pEASData, numRequested)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_PERender returned error %ld\n", result); */ } return result; } #ifdef _METRICS_ENABLED /* stop the stream timer */ if (pEASData->pMetricsData) (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME); #endif #ifdef _METRICS_ENABLED /* start the post timer */ if (pEASData->pMetricsData) (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME); #endif /* for split architecture, send DSP vectors. Do post only if return is TRUE */ #ifdef _SPLIT_ARCHITECTURE if (VMEndFrame(pEASData)) { /* now do post-processing */ EAS_MixEnginePost(pEASData, numRequested); *pNumGenerated = numRequested; } #else /* now do post-processing */ EAS_MixEnginePost(pEASData, numRequested); *pNumGenerated = numRequested; #endif #ifdef _METRICS_ENABLED /* stop the post timer */ if (pEASData->pMetricsData) (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME); #endif /* advance render time */ pEASData->renderTime += AUDIO_FRAME_LENGTH; #if 0 /* dump workload for debug */ if (pEASData->pVoiceMgr->workload) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Workload = %d\n", pEASData->pVoiceMgr->workload); */ } #endif #ifdef _METRICS_ENABLED /* stop performance counter */ if (pEASData->pMetricsData) { PERF_TIMER temp; temp = (*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME); /* if max render time, record the number of voices and time */ if ((*pEASData->pMetricsModule->pfRecordMaxValue) (pEASData->pMetricsData, EAS_PM_MAX_CYCLES, (EAS_U32) temp)) { (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_VOICES, (EAS_U32) voicesRendered); (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_TIME, (EAS_I32) (pEASData->renderTime >> 8)); } } #endif #ifdef JET_INTERFACE /* let JET to do its thing */ if (pEASData->jetHandle != NULL) { result = JET_Process(pEASData); if (result != EAS_SUCCESS) return result; } #endif return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_SetRepeat() *---------------------------------------------------------------------------- * Purpose: * Set the selected stream to repeat. * * Inputs: * pEASData - handle to data for this instance * handle - handle to stream * repeatCount - repeat count * * Outputs: * * Side Effects: * * Notes: * 0 = no repeat * 1 = repeat once, i.e. play through twice * -1 = repeat forever *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 repeatCount) { pStream->repeatCount = repeatCount; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_GetRepeat() *---------------------------------------------------------------------------- * Purpose: * Gets the current repeat count for the selected stream. * * Inputs: * pEASData - handle to data for this instance * handle - handle to stream * pRrepeatCount - pointer to variable to hold repeat count * * Outputs: * * Side Effects: * * Notes: * 0 = no repeat * 1 = repeat once, i.e. play through twice * -1 = repeat forever *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pRepeatCount) { *pRepeatCount = pStream->repeatCount; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_SetPlaybackRate() *---------------------------------------------------------------------------- * Purpose: * Sets the playback rate. * * Inputs: * pEASData - handle to data for this instance * handle - handle to stream * rate - rate (28-bit fractional amount) * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U32 rate) { /* check range */ if ((rate < (1 << 27)) || (rate > (1 << 29))) return EAS_ERROR_INVALID_PARAMETER; /* calculate new frame length * * NOTE: The maximum frame length we can accomodate based on a * maximum rate of 2.0 (2^28) is 2047 (2^13-1). To accomodate a * longer frame length or a higher maximum rate, the fixed point * divide below will need to be adjusted */ pStream->frameLength = (AUDIO_FRAME_LENGTH * (rate >> 8)) >> 20; /* notify stream of new playback rate */ EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_PLAYBACK_RATE, (EAS_I32) rate); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_SetTransposition) *---------------------------------------------------------------------------- * Purpose: * Sets the key tranposition for the synthesizer. Transposes all * melodic instruments by the specified amount. Range is limited * to +/-12 semitones. * * Inputs: * pEASData - handle to data for this instance * handle - handle to stream * transposition - +/-12 semitones * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 transposition) { /* check range */ if ((transposition < -12) || (transposition > 12)) return EAS_ERROR_INVALID_PARAMETER; if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_TRANSPOSITION, transposition); } /*---------------------------------------------------------------------------- * EAS_ParseEvents() *---------------------------------------------------------------------------- * Purpose: * Parse events in the current streams until the desired time is reached. * * Inputs: * pEASData - buffer for internal EAS data * endTime - stop parsing if this time is reached * parseMode - play, locate, or metadata * * Outputs: * EAS_SUCCESS if PCM data was successfully rendered * *---------------------------------------------------------------------------- */ static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_U32 endTime, EAS_INT parseMode) { S_FILE_PARSER_INTERFACE *pParserModule; EAS_RESULT result; EAS_I32 parserState; EAS_BOOL done; EAS_INT yieldCount = YIELD_EVENT_COUNT; EAS_U32 time = 0; // This constant is the maximum number of events that can be processed in a single time slice. // A typical ringtone will contain a few events per time slice. // Extremely dense ringtones might go up to 50 events. // If we see this many events then the file is probably stuck in an infinite loop // and should be aborted. static const EAS_INT MAX_EVENT_COUNT = 100000; EAS_INT eventCount = 0; /* does this parser have a time function? */ pParserModule = pStream->pParserModule; if (pParserModule->pfTime == NULL) { /* check state */ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS) return result; /* if play state, advance time */ if ((parserState >= EAS_STATE_READY) && (parserState <= EAS_STATE_PAUSING)) pStream->time += pStream->frameLength; done = EAS_TRUE; } /* assume we're not done, in case we abort out */ else { pStream->streamFlags &= ~STREAM_FLAGS_PARSED; done = EAS_FALSE; } while (!done) { /* check for stopped state */ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS) return result; if (parserState > EAS_STATE_PLAY) { /* save current time if we're not in play mode */ if (parseMode != eParserModePlay) pStream->time = time << 8; done = EAS_TRUE; break; } /* get the next event time */ if (pParserModule->pfTime) { if ((result = (*pParserModule->pfTime)(pEASData, pStream->handle, &time)) != EAS_SUCCESS) return result; /* if next event is within this frame, parse it */ if (time < (endTime >> 8)) { /* parse the next event */ if (pParserModule->pfEvent) { if ((result = (*pParserModule->pfEvent)(pEASData, pStream->handle, parseMode)) != EAS_SUCCESS) { //ALOGE("%s() pfEvent returned %ld", __func__, result); return result; } } // An infinite loop within a ringtone file can cause this function // to loop forever. Try to detect that and return an error. // Only check when playing. Otherwise a very large file could be rejected // when scanning the entire file in a single call to this function. // OTA files will only do infinite loops when in eParserModePlay. if (++eventCount >= MAX_EVENT_COUNT && parseMode == eParserModePlay) { //ALOGE("%s() aborting, %d events. Infinite loop in song file?!", // __func__, eventCount); //android_errorWriteLog(0x534e4554, "68664359"); return EAS_ERROR_FILE_POS; } } /* no more events in this frame, advance time */ else { pStream->time = endTime; done = EAS_TRUE; } } /* check for max workload exceeded */ if (VMCheckWorkload(pEASData->pVoiceMgr)) { /* stop even though we may not have parsed * all the events in this frame. The parser will try to * catch up on the next frame. */ break; } /* give host a chance for an early abort */ if (--yieldCount == 0) { if (EAS_HWYield(pEASData->hwInstData)) break; yieldCount = YIELD_EVENT_COUNT; } } /* if no early abort, parsing is complete for this frame */ if (done) pStream->streamFlags |= STREAM_FLAGS_PARSED; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_ParseMetaData() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * pEASData - pointer to overall EAS data structure * handle - file or stream handle * playLength - pointer to variable to store the play length (in msecs) * * Outputs: * * * Side Effects: * - resets the parser to the start of the file *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *playLength) { S_FILE_PARSER_INTERFACE *pParserModule; EAS_RESULT result; EAS_STATE state; pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule; if (pParserModule == NULL) return EAS_ERROR_FEATURE_NOT_AVAILABLE; /* check parser state */ if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS) return result; if (state >= EAS_STATE_OPEN) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* if parser has metadata function, use that */ if (pParserModule->pfGetMetaData != NULL) return pParserModule->pfGetMetaData(pEASData, pStream->handle, playLength); /* reset the parser to the beginning */ if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS) return result; /* parse the file to end */ pStream->time = 0; VMInitWorkload(pEASData->pVoiceMgr); if ((result = EAS_ParseEvents(pEASData, pStream, 0x7fffffff, eParserModeMetaData)) != EAS_SUCCESS) return result; /* get the parser time */ if ((result = EAS_GetLocation(pEASData, pStream, playLength)) != EAS_SUCCESS) return result; /* reset the parser to the beginning */ pStream->time = 0; return (*pParserModule->pfReset)(pEASData, pStream->handle); } /*---------------------------------------------------------------------------- * EAS_RegisterMetaDataCallback() *---------------------------------------------------------------------------- * Purpose: * Registers a metadata callback function for parsed metadata. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - file or stream handle * cbFunc - pointer to host callback function * metaDataBuffer - pointer to metadata buffer * metaDataBufSize - maximum size of the metadata buffer * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback ( EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_METADATA_CBFUNC cbFunc, char *metaDataBuffer, EAS_I32 metaDataBufSize, EAS_VOID_PTR pUserData) { S_METADATA_CB metadata; if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* register callback function */ metadata.callback = cbFunc; metadata.buffer = metaDataBuffer; metadata.bufferSize = metaDataBufSize; metadata.pUserData = pUserData; return EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_METADATA_CB, (EAS_I32) &metadata); } /*---------------------------------------------------------------------------- * EAS_GetNoteCount () *---------------------------------------------------------------------------- * Returns the total number of notes played in this stream *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount) { if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_NOTE_COUNT, pNoteCount); } /*---------------------------------------------------------------------------- * EAS_CloseFile() *---------------------------------------------------------------------------- * Purpose: * Closes an audio file or stream. Playback should have either paused or * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - file or stream handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream) { S_FILE_PARSER_INTERFACE *pParserModule; EAS_RESULT result; /* call the close function */ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule; if (pParserModule == NULL) return EAS_ERROR_FEATURE_NOT_AVAILABLE; result = (*pParserModule->pfClose)(pEASData, pStream->handle); /* clear the handle and parser interface pointer */ pStream->handle = NULL; pStream->pParserModule = NULL; return result; } /*---------------------------------------------------------------------------- * EAS_OpenMIDIStream() *---------------------------------------------------------------------------- * Purpose: * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer * * Inputs: * pEASData - pointer to overall EAS data structure * pHandle - pointer to variable to hold file or stream handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *ppStream, EAS_HANDLE streamHandle) { EAS_RESULT result; S_INTERACTIVE_MIDI *pMIDIStream; EAS_INT streamNum; /* initialize some pointers */ *ppStream = NULL; /* allocate a stream */ if ((streamNum = EAS_AllocateStream(pEASData)) < 0) return EAS_ERROR_MAX_STREAMS_OPEN; /* check Configuration Module for S_EAS_DATA allocation */ if (pEASData->staticMemoryModel) pMIDIStream = EAS_CMEnumData(EAS_CM_MIDI_STREAM_DATA); else pMIDIStream = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_INTERACTIVE_MIDI)); /* allocate dynamic memory */ if (!pMIDIStream) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate MIDI stream data\n"); */ } return EAS_ERROR_MALLOC_FAILED; } /* zero the memory to insure complete initialization */ EAS_HWMemSet(pMIDIStream, 0, sizeof(S_INTERACTIVE_MIDI)); EAS_InitStream(&pEASData->streams[streamNum], NULL, pMIDIStream); /* instantiate a new synthesizer */ if (streamHandle == NULL) { result = VMInitMIDI(pEASData, &pMIDIStream->pSynth); } /* use an existing synthesizer */ else { EAS_I32 value; result = EAS_GetStreamParameter(pEASData, streamHandle, PARSER_DATA_SYNTH_HANDLE, &value); pMIDIStream->pSynth = (S_SYNTH*) value; VMIncRefCount(pMIDIStream->pSynth); } if (result != EAS_SUCCESS) { EAS_CloseMIDIStream(pEASData, &pEASData->streams[streamNum]); return result; } /* initialize the MIDI stream data */ EAS_InitMIDIStream(&pMIDIStream->stream); *ppStream = (EAS_HANDLE) &pEASData->streams[streamNum]; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_WriteMIDIStream() *---------------------------------------------------------------------------- * Purpose: * Send data to the MIDI stream device * * Inputs: * pEASData - pointer to overall EAS data structure * handle - stream handle * pBuffer - pointer to buffer * count - number of bytes to write * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 *pBuffer, EAS_I32 count) { S_INTERACTIVE_MIDI *pMIDIStream; EAS_RESULT result; pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle; if (count <= 0) return EAS_ERROR_PARAMETER_RANGE; /* send the entire buffer */ while (count--) { if ((result = EAS_ParseMIDIStream(pEASData, pMIDIStream->pSynth, &pMIDIStream->stream, *pBuffer++, eParserModePlay)) != EAS_SUCCESS) return result; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_CloseMIDIStream() *---------------------------------------------------------------------------- * Purpose: * Closes a raw MIDI stream * * Inputs: * pEASData - pointer to overall EAS data structure * handle - stream handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream) { S_INTERACTIVE_MIDI *pMIDIStream; pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle; /* close synth */ if (pMIDIStream->pSynth != NULL) { VMMIDIShutdown(pEASData, pMIDIStream->pSynth); pMIDIStream->pSynth = NULL; } /* release allocated memory */ if (!pEASData->staticMemoryModel) EAS_HWFree(((S_EAS_DATA*) pEASData)->hwInstData, pMIDIStream); pStream->handle = NULL; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_State() *---------------------------------------------------------------------------- * Purpose: * Returns the state of an audio file or stream. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - file or stream handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_STATE *pState) { S_FILE_PARSER_INTERFACE *pParserModule; EAS_RESULT result; /* call the parser to return state */ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule; if (pParserModule == NULL) return EAS_ERROR_FEATURE_NOT_AVAILABLE; if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, pState)) != EAS_SUCCESS) return result; /* if repeat count is set for this parser, mask the stopped state from the application */ if (pStream->repeatCount && (*pState == EAS_STATE_STOPPED)) *pState = EAS_STATE_PLAY; /* if we're not paused or pausing, we don't need to hide state from host */ if (*pState != EAS_STATE_PAUSED && *pState != EAS_STATE_PAUSING) return EAS_SUCCESS; /* if stream is about to be paused, report it as paused */ if (pStream->streamFlags & STREAM_FLAGS_PAUSE) { if (pStream->streamFlags & STREAM_FLAGS_LOCATE) *pState = EAS_STATE_PAUSED; else *pState = EAS_STATE_PAUSING; } /* if stream is about to resume, report it as playing */ if (pStream->streamFlags & STREAM_FLAGS_RESUME) *pState = EAS_STATE_PLAY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_SetPolyphony() *---------------------------------------------------------------------------- * Purpose: * Set the polyphony of the stream. A value of 0 allows the stream * to use all voices (set by EAS_SetSynthPolyphony). * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - handle returned by EAS_OpenFile * polyphonyCount - the desired polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 polyphonyCount) { if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, polyphonyCount); } /*---------------------------------------------------------------------------- * EAS_GetPolyphony() *---------------------------------------------------------------------------- * Purpose: * Returns the current polyphony setting of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - handle returned by EAS_OpenFile * pPolyphonyCount - pointer to variable to receive polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPolyphonyCount) { if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, pPolyphonyCount); } /*---------------------------------------------------------------------------- * EAS_SetSynthPolyphony() *---------------------------------------------------------------------------- * Purpose: * Set the polyphony of the synth . Value must be >= 1 and <= the * maximum number of voices. This function will pin the polyphony * at those limits * * Inputs: * pEASData - pointer to overall EAS data structure * synthNum - synthesizer number (0 = onboard, 1 = DSP) * polyphonyCount - the desired polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount) { return VMSetSynthPolyphony(pEASData->pVoiceMgr, synthNum, polyphonyCount); } /*---------------------------------------------------------------------------- * EAS_GetSynthPolyphony() *---------------------------------------------------------------------------- * Purpose: * Returns the current polyphony setting of the synth * * Inputs: * pEASData - pointer to overall EAS data structure * synthNum - synthesizer number (0 = onboard, 1 = DSP) * pPolyphonyCount - pointer to variable to receive polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount) { return VMGetSynthPolyphony(pEASData->pVoiceMgr, synthNum, pPolyphonyCount); } /*---------------------------------------------------------------------------- * EAS_SetPriority() *---------------------------------------------------------------------------- * Purpose: * Set the priority of the stream. Determines which stream's voices * are stolen when there are insufficient voices for all notes. * Value must be in the range of 1-15, lower values are higher * priority. * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - handle returned by EAS_OpenFile * polyphonyCount - the desired polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 priority) { if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, priority); } /*---------------------------------------------------------------------------- * EAS_GetPriority() *---------------------------------------------------------------------------- * Purpose: * Returns the current priority setting of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - handle returned by EAS_OpenFile * pPriority - pointer to variable to receive priority * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPriority) { if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, pPriority); } /*---------------------------------------------------------------------------- * EAS_SetVolume() *---------------------------------------------------------------------------- * Purpose: * Set the master gain for the mix engine in 1dB increments * * Inputs: * pEASData - pointer to overall EAS data structure * volume - the desired master gain (100 is max) * handle - file or stream handle * * Outputs: * * * Side Effects: * overrides any previously set master volume from sysex * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 volume) { EAS_I16 gain; /* check range */ if ((volume < 0) || (volume > EAS_MAX_VOLUME)) return EAS_ERROR_PARAMETER_RANGE; /* stream volume */ if (pStream != NULL) { EAS_I32 gainOffset; EAS_RESULT result; if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* get gain offset */ pStream->volume = (EAS_U8) volume; result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_GAIN_OFFSET, &gainOffset); if (result == EAS_SUCCESS) volume += gainOffset; /* set stream volume */ gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM); /* convert to linear scalar */ return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_VOLUME, gain); } /* master volume */ pEASData->masterVolume = (EAS_U8) volume; #if (NUM_OUTPUT_CHANNELS == 1) /* leave 3dB headroom for mono output */ volume -= 3; #endif gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM); pEASData->masterGain = gain; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_GetVolume() *---------------------------------------------------------------------------- * Purpose: * Returns the master volume for the synthesizer. The default volume setting is * 50. The volume range is 0 to 100; * * Inputs: * pEASData - pointer to overall EAS data structure * volume - the desired master volume * handle - file or stream handle * * Outputs: * * * Side Effects: * overrides any previously set master volume from sysex * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream) { if (pStream == NULL) return pEASData->masterVolume; if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; return pStream->volume; } /*---------------------------------------------------------------------------- * EAS_SetMaxLoad() *---------------------------------------------------------------------------- * Purpose: * Sets the maximum workload the parsers will do in a single call to * EAS_Render. The units are currently arbitrary, but should correlate * well to the actual CPU cycles consumed. The primary effect is to * reduce the occasional peaks in CPU cycles consumed when parsing * dense parts of a MIDI score. * * Inputs: * pEASData - handle to data for this instance * maxLoad - the desired maximum workload * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad) { VMSetWorkload(pEASData->pVoiceMgr, maxLoad); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_SetMaxPCMStreams() *---------------------------------------------------------------------------- * Sets the maximum number of PCM streams allowed in parsers that * use PCM streaming. * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - handle returned by EAS_OpenFile * maxNumStreams - maximum number of PCM streams *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams) { if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_MAX_PCM_STREAMS, maxNumStreams); } /*---------------------------------------------------------------------------- * EAS_Locate() *---------------------------------------------------------------------------- * Purpose: * Locate into the file associated with the handle. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - file handle * milliseconds - playback offset from start of file in milliseconds * * Outputs: * * * Side Effects: * the actual offset will be quantized to the closest update period, typically * a resolution of 5.9ms. Notes that are started prior to this time will not * sound. Any notes currently playing will be shut off. * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 milliseconds, EAS_BOOL offset) { S_FILE_PARSER_INTERFACE *pParserModule; EAS_RESULT result; EAS_U32 requestedTime; EAS_STATE state; /* get pointer to parser function table */ pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule; if (pParserModule == NULL) return EAS_ERROR_FEATURE_NOT_AVAILABLE; if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS) return result; if (state >= EAS_STATE_OPEN) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* handle offset and limit to start of file */ /*lint -e{704} use shift for performance*/ if (offset) milliseconds += (EAS_I32) pStream->time >> 8; if (milliseconds < 0) milliseconds = 0; /* check to see if the request is different from the current time */ requestedTime = (EAS_U32) milliseconds; if (requestedTime == (pStream->time >> 8)) return EAS_SUCCESS; /* set the locate flag */ pStream->streamFlags |= STREAM_FLAGS_LOCATE; /* use the parser locate function, if available */ if (pParserModule->pfLocate != NULL) { EAS_BOOL parserLocate = EAS_FALSE; result = pParserModule->pfLocate(pEASData, pStream->handle, (EAS_I32) requestedTime, &parserLocate); if (!parserLocate) { if (result == EAS_SUCCESS) pStream->time = requestedTime << 8; return result; } } /* if we were paused and not going to resume, set pause request flag */ if (((state == EAS_STATE_PAUSING) || (state == EAS_STATE_PAUSED)) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0)) pStream->streamFlags |= STREAM_FLAGS_PAUSE; /* reset the synth and parser */ if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS) return result; pStream->time = 0; /* locating forward, clear parsed flag and parse data until we get to the requested location */ if ((result = EAS_ParseEvents(pEASData, pStream, requestedTime << 8, eParserModeLocate)) != EAS_SUCCESS) return result; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_GetLocation() *---------------------------------------------------------------------------- * Purpose: * Returns the current playback offset * * Inputs: * pEASData - pointer to overall EAS data structure * handle - file handle * * Outputs: * The offset in milliseconds from the start of the current sequence, quantized * to the nearest update period. Actual resolution is typically 5.9 ms. * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pTime) { if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; *pTime = pStream->time >> 8; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_GetRenderTime() *---------------------------------------------------------------------------- * Purpose: * Returns the current playback offset * * Inputs: * pEASData - pointer to overall EAS data structure * * Outputs: * Gets the render time clock in msecs. * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime) { *pTime = pEASData->renderTime >> 8; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_Pause() *---------------------------------------------------------------------------- * Purpose: * Pauses the playback of the data associated with this handle. The audio * is gracefully ramped down to prevent clicks and pops. It may take several * buffers of audio before the audio is muted. * * Inputs: * psEASData - pointer to overall EAS data structure * handle - file or stream handle * * Outputs: * * * Side Effects: * * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream) { S_FILE_PARSER_INTERFACE *pParserModule; EAS_STATE state; EAS_RESULT result; pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule; if (pParserModule == NULL) return EAS_ERROR_FEATURE_NOT_AVAILABLE; /* check for valid state */ result = pParserModule->pfState(pEASData, pStream->handle, &state); if (result == EAS_SUCCESS) { if ((state != EAS_STATE_PLAY) && (state != EAS_STATE_READY) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* make sure parser implements pause */ if (pParserModule->pfPause == NULL) result = EAS_ERROR_NOT_IMPLEMENTED; /* clear resume flag */ pStream->streamFlags &= ~STREAM_FLAGS_RESUME; /* set pause flag */ pStream->streamFlags |= STREAM_FLAGS_PAUSE; #if 0 /* pause the stream */ if (pParserModule->pfPause) result = pParserModule->pfPause(pEASData, pStream->handle); else result = EAS_ERROR_NOT_IMPLEMENTED; #endif } return result; } /*---------------------------------------------------------------------------- * EAS_Resume() *---------------------------------------------------------------------------- * Purpose: * Resumes the playback of the data associated with this handle. The audio * is gracefully ramped up to prevent clicks and pops. * * Inputs: * psEASData - pointer to overall EAS data structure * handle - file or stream handle * * Outputs: * * * Side Effects: * * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream) { S_FILE_PARSER_INTERFACE *pParserModule; EAS_STATE state; EAS_RESULT result; pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule; if (pParserModule == NULL) return EAS_ERROR_FEATURE_NOT_AVAILABLE; /* check for valid state */ result = pParserModule->pfState(pEASData, pStream->handle, &state); if (result == EAS_SUCCESS) { if ((state != EAS_STATE_PAUSED) && (state != EAS_STATE_PAUSING) && ((pStream->streamFlags & STREAM_FLAGS_PAUSE) == 0)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* make sure parser implements this function */ if (pParserModule->pfResume == NULL) result = EAS_ERROR_NOT_IMPLEMENTED; /* clear pause flag */ pStream->streamFlags &= ~STREAM_FLAGS_PAUSE; /* set resume flag */ pStream->streamFlags |= STREAM_FLAGS_RESUME; #if 0 /* resume the stream */ if (pParserModule->pfResume) result = pParserModule->pfResume(pEASData, pStream->handle); else result = EAS_ERROR_NOT_IMPLEMENTED; #endif } return result; } /*---------------------------------------------------------------------------- * EAS_GetParameter() *---------------------------------------------------------------------------- * Purpose: * Set the parameter of a module. See E_MODULES for a list of modules * and the header files of the modules for a list of parameters. * * Inputs: * psEASData - pointer to overall EAS data structure * handle - file or stream handle * module - enumerated module number * param - enumerated parameter number * pValue - pointer to variable to receive parameter value * * Outputs: * * * Side Effects: * * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue) { if (module >= NUM_EFFECTS_MODULES) return EAS_ERROR_INVALID_MODULE; if (pEASData->effectsModules[module].effectData == NULL) return EAS_ERROR_INVALID_MODULE; return (*pEASData->effectsModules[module].effect->pFGetParam) (pEASData->effectsModules[module].effectData, param, pValue); } /*---------------------------------------------------------------------------- * EAS_SetParameter() *---------------------------------------------------------------------------- * Purpose: * Set the parameter of a module. See E_MODULES for a list of modules * and the header files of the modules for a list of parameters. * * Inputs: * psEASData - pointer to overall EAS data structure * handle - file or stream handle * module - enumerated module number * param - enumerated parameter number * value - new parameter value * * Outputs: * * * Side Effects: * * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value) { if (module >= NUM_EFFECTS_MODULES) return EAS_ERROR_INVALID_MODULE; if (pEASData->effectsModules[module].effectData == NULL) return EAS_ERROR_INVALID_MODULE; return (*pEASData->effectsModules[module].effect->pFSetParam) (pEASData->effectsModules[module].effectData, param, value); } #ifdef _METRICS_ENABLED /*---------------------------------------------------------------------------- * EAS_MetricsReport() *---------------------------------------------------------------------------- * Purpose: * Displays the current metrics through the metrics interface. * * Inputs: * p - instance data handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData) { if (!pEASData->pMetricsModule) return EAS_ERROR_INVALID_MODULE; return (*pEASData->pMetricsModule->pfReport)(pEASData->pMetricsData); } /*---------------------------------------------------------------------------- * EAS_MetricsReset() *---------------------------------------------------------------------------- * Purpose: * Resets the metrics. * * Inputs: * p - instance data handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData) { if (!pEASData->pMetricsModule) return EAS_ERROR_INVALID_MODULE; return (*pEASData->pMetricsModule->pfReset)(pEASData->pMetricsData); } #endif /*---------------------------------------------------------------------------- * EAS_SetSoundLibrary() *---------------------------------------------------------------------------- * Purpose: * Sets the location of the sound library. * * Inputs: * pEASData - instance data handle * pSoundLib - pointer to sound library * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_SNDLIB_HANDLE pSndLib) { if (pStream) { if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_EAS_LIBRARY, (EAS_I32) pSndLib); } return VMSetGlobalEASLib(pEASData->pVoiceMgr, pSndLib); } /*---------------------------------------------------------------------------- * EAS_SetHeaderSearchFlag() *---------------------------------------------------------------------------- * By default, when EAS_OpenFile is called, the parsers check the * first few bytes of the file looking for a specific header. Some * mobile devices may add a header to the start of a file, which * will prevent the parser from recognizing the file. If the * searchFlag is set to EAS_TRUE, the parser will search the entire * file looking for the header. This may enable EAS to recognize * some files that it would ordinarily reject. The negative is that * it make take slightly longer to process the EAS_OpenFile request. * * Inputs: * pEASData - instance data handle * searchFlag - search flag (EAS_TRUE or EAS_FALSE) *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag) { pEASData->searchHeaderFlag = (EAS_BOOL8) searchFlag; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_SetPlayMode() *---------------------------------------------------------------------------- * Some file formats support special play modes, such as iMode partial * play mode. This call can be used to change the play mode. The * default play mode (usually straight playback) is always zero. * * Inputs: * pEASData - instance data handle * handle - file or stream handle * playMode - play mode (see file parser for specifics) *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode) { return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PLAY_MODE, playMode); } #ifdef DLS_SYNTHESIZER /*---------------------------------------------------------------------------- * EAS_LoadDLSCollection() *---------------------------------------------------------------------------- * Purpose: * Sets the location of the sound library. * * Inputs: * pEASData - instance data handle * pSoundLib - pointer to sound library * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_FILE_LOCATOR locator) { EAS_FILE_HANDLE fileHandle; EAS_RESULT result; EAS_DLSLIB_HANDLE pDLS; if (pStream != NULL) { if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; } /* open the file */ if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS) return result; /* parse the file */ result = DLSParser(pEASData->hwInstData, fileHandle, 0, &pDLS); EAS_HWCloseFile(pEASData->hwInstData, fileHandle); if (result == EAS_SUCCESS) { /* if a stream pStream is specified, point it to the DLS collection */ if (pStream) result = EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_DLS_COLLECTION, (EAS_I32) pDLS); /* global DLS load */ else result = VMSetGlobalDLSLib(pEASData, pDLS); } return result; } #endif #ifdef EXTERNAL_AUDIO /*---------------------------------------------------------------------------- * EAS_RegExtAudioCallback() *---------------------------------------------------------------------------- * Purpose: * Registers callback functions for audio events. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - file or stream handle * cbProgChgFunc - pointer to host callback function for program change * cbEventFunc - pointer to host callback functio for note events * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc) { S_SYNTH *pSynth; if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS) return EAS_ERROR_INVALID_PARAMETER; if (pSynth == NULL) return EAS_ERROR_INVALID_PARAMETER; VMRegExtAudioCallback(pSynth, pInstData, cbProgChgFunc, cbEventFunc); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_GetMIDIControllers() *---------------------------------------------------------------------------- * Purpose: * Returns the current state of MIDI controllers on the requested channel. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - file or stream handle * pControl - pointer to structure to receive data * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl) { S_SYNTH *pSynth; if (!EAS_StreamReady(pEASData, pStream)) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS) return EAS_ERROR_INVALID_PARAMETER; if (pSynth == NULL) return EAS_ERROR_INVALID_PARAMETER; VMGetMIDIControllers(pSynth, channel, pControl); return EAS_SUCCESS; } #endif #ifdef _SPLIT_ARCHITECTURE /*---------------------------------------------------------------------------- * EAS_SetFrameBuffer() *---------------------------------------------------------------------------- * Purpose: * Sets the frame buffer pointer passed to the IPC communications functions * * Inputs: * pEASData - instance data handle * locator - file locator * * Outputs: * * * Side Effects: * May overlay instruments in the GM sound set * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer) { if (pEASData->pVoiceMgr) pEASData->pVoiceMgr->pFrameBuffer = pFrameBuffer; return EAS_SUCCESS; } #endif /*---------------------------------------------------------------------------- * EAS_SearchFile *---------------------------------------------------------------------------- * Search file for specific sequence starting at current file * position. Returns offset to start of sequence. * * Inputs: * pEASData - pointer to EAS persistent data object * fileHandle - file handle * searchString - pointer to search sequence * len - length of search sequence * pOffset - pointer to variable to store offset to sequence * * Returns EAS_EOF if end-of-file is reached *---------------------------------------------------------------------------- */ EAS_RESULT EAS_SearchFile (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset) { EAS_RESULT result; EAS_INT index; EAS_U8 c; *pOffset = -1; index = 0; for (;;) { result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &c); if (result != EAS_SUCCESS) return result; if (c == searchString[index]) { index++; if (index == 4) { result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, pOffset); if (result != EAS_SUCCESS) return result; *pOffset -= len; break; } } else index = 0; } return EAS_SUCCESS; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_chorusdata.c0000644000000000000000000000013214200302440027232 xustar0030 mtime=1644266784.809324171 30 atime=1644266784.965324271 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_chorusdata.c0000644000175000001440000000215114200302440030012 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_chorusdata.c * * Contents and purpose: * Contains the static data allocation for the Chorus effect * * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 550 $ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $ *---------------------------------------------------------------------------- */ #include "eas_chorusdata.h" S_CHORUS_OBJECT eas_ChorusData; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_otadata.h0000644000000000000000000000013214200302440026517 xustar0030 mtime=1644266784.805324168 30 atime=1644266784.965324271 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_otadata.h0000644000175000001440000000620114200302440027277 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_otadata.h * * Contents and purpose: * OTA File Parser * * This file contains data declarations for the OTA parser. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef EAS_OTADATA_H #define EAS_OTADATA_H #include "eas_data.h" /* definition for state flags */ #define OTA_FLAGS_UNICODE 0x01 /* unicode text */ /*---------------------------------------------------------------------------- * * S_OTA_DATA * * This structure contains the state data for the OTA parser *---------------------------------------------------------------------------- */ typedef struct { EAS_I32 fileOffset; /* offset to location in file */ EAS_U8 patternLen; /* length of current pattern */ EAS_U8 dataByte; /* previous char from file */ EAS_U8 bitCount; /* bit count in char */ } S_OTA_LOC; typedef struct { EAS_FILE_HANDLE fileHandle; /* file handle */ S_SYNTH *pSynth; /* synth handle */ EAS_I32 fileOffset; /* offset to start of data */ EAS_I32 time; /* current time in 256ths of a msec */ EAS_U32 tick; /* length of 32nd note in 256th of a msec */ EAS_U32 restTicks; /* ticks to rest after current note */ S_OTA_LOC patterns[4]; /* pattern locations */ S_OTA_LOC current; /* current location */ S_OTA_LOC restore; /* previous location */ S_METADATA_CB metadata; /* metadata callback */ EAS_U8 flags; /* bit flags */ EAS_U8 numPatterns; /* number of patterns left in song */ EAS_U8 currentPattern; /* current pattern for loop */ EAS_U8 note; /* MIDI note number */ EAS_U8 octave; /* octave modifier */ EAS_U8 style; /* from STYLE */ EAS_U8 velocity; /* current volume */ EAS_U8 state; /* current state EAS_STATE_XXXX */ EAS_U8 loopCount; /* loop count for pattern */ } S_OTA_DATA; #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_wavefiledata.c0000644000000000000000000000013214200302440027531 xustar0030 mtime=1644266784.809324171 30 atime=1644266784.965324271 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_wavefiledata.c0000644000175000001440000000211714200302440030313 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_wavefiledata.c * * Contents and purpose: * Static data block for wave file parser. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 547 $ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $ *---------------------------------------------------------------------------- */ #include "eas_wavefile.h" S_WAVE_STATE eas_WaveData; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_math.h0000644000000000000000000000013214200302440026033 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_math.h0000644000175000001440000004033214200302440026616 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_math.h * * Contents and purpose: * Contains common math routines for the various audio engines. * * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 584 $ * $Date: 2007-03-08 09:49:24 -0800 (Thu, 08 Mar 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_MATH_H #define _EAS_MATH_H #include /** coefs for pan, generates sin, cos */ #define COEFF_PAN_G2 -27146 /* -0.82842712474619 = 2 - 4/sqrt(2) */ #define COEFF_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */ /* coefficients for approximating 2^x = gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3 where x is a int.frac number representing number of octaves. Actually, we approximate only the 2^(frac) using the power series and implement the 2^(int) as a shift, so that 2^x == 2^(int.frac) == 2^(int) * 2^(fract) == (gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3) << (int) The gn2toX.. were generated using a best fit for a 3rd order polynomial, instead of taking the coefficients from a truncated Taylor (or Maclaurin?) series. */ #define GN2_TO_X0 32768 /* 1 */ #define GN2_TO_X1 22833 /* 0.696807861328125 */ #define GN2_TO_X2 7344 /* 0.22412109375 */ #define GN2_TO_X3 2588 /* 0.0789794921875 */ /*---------------------------------------------------------------------------- * Fixed Point Math *---------------------------------------------------------------------------- * These macros are used for fixed point multiplies. If the processor * supports fixed point multiplies, replace these macros with inline * assembly code to improve performance. *---------------------------------------------------------------------------- */ /* Fixed point multiply 0.15 x 0.15 = 0.15 returned as 32-bits */ #define FMUL_15x15(a,b) \ /*lint -e(704) */ \ (((int32_t)(a) * (int32_t)(b)) >> 15) /* Fixed point multiply 0.7 x 0.7 = 0.15 returned as 32-bits */ #define FMUL_7x7(a,b) \ /*lint -e(704) */ \ (((int32_t)(a) * (int32_t)(b) ) << 1) /* Fixed point multiply 0.8 x 0.8 = 0.15 returned as 32-bits */ #define FMUL_8x8(a,b) \ /*lint -e(704) */ \ (((int32_t)(a) * (int32_t)(b) ) >> 1) /* Fixed point multiply 0.8 x 1.15 = 0.15 returned as 32-bits */ #define FMUL_8x15(a,b) \ /*lint -e(704) */ \ (((int32_t)((a) << 7) * (int32_t)(b)) >> 15) /* macros for fractional phase accumulator */ /* Note: changed the _U32 to _I32 on 03/14/02. This should not affect the phase calculations, and should allow us to reuse these macros for other audio sample related math. */ #define HARDWARE_BIT_WIDTH 32 #define NUM_PHASE_INT_BITS 1 #define NUM_PHASE_FRAC_BITS 15 #define PHASE_FRAC_MASK (uint32_t) ((0x1L << NUM_PHASE_FRAC_BITS) -1) #define GET_PHASE_INT_PART(x) (uint32_t)((uint32_t)(x) >> NUM_PHASE_FRAC_BITS) #define GET_PHASE_FRAC_PART(x) (uint32_t)((uint32_t)(x) & PHASE_FRAC_MASK) #define DEFAULT_PHASE_FRAC 0 #define DEFAULT_PHASE_INT 0 /* Linear interpolation calculates: output = (1-frac) * sample[n] + (frac) * sample[n+1] where conceptually 0 <= frac < 1 For a fixed point implementation, frac is actually an integer value with an implied binary point one position to the left. The value of one (unity) is given by PHASE_ONE one half and one quarter are useful for 4-point linear interp. */ #define PHASE_ONE (int32_t) (0x1L << NUM_PHASE_FRAC_BITS) /* Multiply the signed audio sample by the unsigned fraction. - a is the signed audio sample - b is the unsigned fraction (cast to signed int as long as coef uses (n-1) or less bits, where n == hardware bit width) */ #define MULT_AUDIO_COEF(audio,coef) /*lint -e704 */ \ (int32_t)( \ ( \ ((int32_t)(audio)) * ((int32_t)(coef)) \ ) \ >> NUM_PHASE_FRAC_BITS \ ) \ /* lint +704 */ /* wet / dry calculation macros */ #define NUM_WET_DRY_FRAC_BITS 7 // 15 #define NUM_WET_DRY_INT_BITS 9 // 1 /* define a 1.0 */ #define WET_DRY_ONE (int32_t) ((0x1L << NUM_WET_DRY_FRAC_BITS)) #define WET_DRY_MINUS_ONE (int32_t) (~WET_DRY_ONE) #define WET_DRY_FULL_SCALE (int32_t) (WET_DRY_ONE - 1) #define MULT_AUDIO_WET_DRY_COEF(audio,coef) /*lint -e(702) */ \ (int32_t)( \ ( \ ((int32_t)(audio)) * ((int32_t)(coef)) \ ) \ >> NUM_WET_DRY_FRAC_BITS \ ) /* Envelope 1 (EG1) calculation macros */ #define NUM_EG1_INT_BITS 1 #define NUM_EG1_FRAC_BITS 15 /* the max positive gain used in the synth for EG1 */ /* SYNTH_FULL_SCALE_EG1_GAIN must match the value in the dls2eas converter, otherwise, the values we read from the .eas file are bogus. */ #define SYNTH_FULL_SCALE_EG1_GAIN (int32_t) ((0x1L << NUM_EG1_FRAC_BITS) -1) /* define a 1.0 */ #define EG1_ONE (int32_t) ((0x1L << NUM_EG1_FRAC_BITS)) #define EG1_MINUS_ONE (int32_t) (~SYNTH_FULL_SCALE_EG1_GAIN) #define EG1_HALF (int32_t) (EG1_ONE/2) #define EG1_MINUS_HALF (int32_t) (EG1_MINUS_ONE/2) /* We implement the EG1 using a linear gain value, which means that the attack segment is handled by incrementing (adding) the linear gain. However, EG1 treats the Decay, Sustain, and Release differently than the Attack portion. For Decay, Sustain, and Release, the gain is linear on dB scale, which is equivalent to exponential damping on a linear scale. Because we use a linear gain for EG1, we implement the Decay and Release as multiplication (instead of incrementing as we did for the attack segment). Therefore, we need the following macro to implement the multiplication (i.e., exponential damping) during the Decay and Release segments of the EG1 */ #define MULT_EG1_EG1(gain,damping) /*lint -e(704) */ \ (int32_t)( \ ( \ ((int32_t)(gain)) * ((int32_t)(damping)) \ ) \ >> NUM_EG1_FRAC_BITS \ ) // Use the following macro specifically for the filter, when multiplying // the b1 coefficient. The 0 <= |b1| < 2, which therefore might overflow // in certain conditions because we store b1 as a 1.15 value. // Instead, we could store b1 as b1p (b1' == b1 "prime") where // b1p == b1/2, thus ensuring no potential overflow for b1p because // 0 <= |b1p| < 1 // However, during the filter calculation, we must account for the fact // that we are using b1p instead of b1, and thereby multiply by // an extra factor of 2. Rather than multiply by an extra factor of 2, // we can instead shift the result right by one less, hence the // modified shift right value of (NUM_EG1_FRAC_BITS -1) #define MULT_EG1_EG1_X2(gain,damping) /*lint -e(702) */ \ (int32_t)( \ ( \ ((int32_t)(gain)) * ((int32_t)(damping)) \ ) \ >> (NUM_EG1_FRAC_BITS -1) \ ) #define SATURATE_EG1(x) /*lint -e{734} saturation operation */ \ ((int32_t)(x) > SYNTH_FULL_SCALE_EG1_GAIN) ? (SYNTH_FULL_SCALE_EG1_GAIN) : \ ((int32_t)(x) < EG1_MINUS_ONE) ? (EG1_MINUS_ONE) : (x); /* use "digital cents" == "dents" instead of cents */ /* we coudl re-use the phase frac macros, but if we do, we must change the phase macros to cast to _I32 instead of _U32, because using a _U32 cast causes problems when shifting the exponent for the 2^x calculation, because right shift a negative values MUST be sign extended, or else the 2^x calculation is wrong */ /* use "digital cents" == "dents" instead of cents */ #define NUM_DENTS_FRAC_BITS 12 #define NUM_DENTS_INT_BITS (HARDWARE_BIT_WIDTH - NUM_DENTS_FRAC_BITS) #define DENTS_FRAC_MASK (int32_t) ((0x1L << NUM_DENTS_FRAC_BITS) -1) #define GET_DENTS_INT_PART(x) /*lint -e(704) */ \ (int32_t)((int32_t)(x) >> NUM_DENTS_FRAC_BITS) #define GET_DENTS_FRAC_PART(x) (int32_t)((int32_t)(x) & DENTS_FRAC_MASK) #define DENTS_ONE (int32_t) (0x1L << NUM_DENTS_FRAC_BITS) /* use CENTS_TO_DENTS to convert a value in cents to dents */ #define CENTS_TO_DENTS (int32_t) (DENTS_ONE * (0x1L << NUM_EG1_FRAC_BITS) / 1200L) \ /* For gain, the LFO generates a value that modulates in terms of dB. However, we use a linear gain value, so we must convert the LFO value in dB to a linear gain. Normally, we would use linear gain = 10^x, where x = LFO value in dB / 20. Instead, we implement 10^x using our 2^x approximation. because 10^x = 2^(log2(10^x)) = 2^(x * log2(10)) so we need to multiply by log2(10) which is just a constant. Ah, but just wait -- our 2^x actually doesn't exactly implement 2^x, but it actually assumes that the input is in cents, and within the 2^x approximation converts its input from cents to octaves by dividing its input by 1200. So, in order to convert the LFO gain value in dB to something that our existing 2^x approximation can use, multiply the LFO gain by log2(10) * 1200 / 20 The divide by 20 helps convert dB to linear gain, and we might as well incorporate that operation into this conversion. Of course, we need to keep some fractional bits, so multiply the constant by NUM_EG1_FRAC_BITS */ /* use LFO_GAIN_TO_CENTS to convert the LFO gain value to cents */ #if 0 #define DOUBLE_LOG2_10 (double) (3.32192809488736) /* log2(10) */ #define DOUBLE_LFO_GAIN_TO_CENTS (double) \ ( \ (DOUBLE_LOG2_10) * \ 1200.0 / \ 20.0 \ ) #define LFO_GAIN_TO_CENTS (int32_t) \ ( \ DOUBLE_LFO_GAIN_TO_CENTS * \ (0x1L << NUM_EG1_FRAC_BITS) \ ) #endif #define LFO_GAIN_TO_CENTS (int32_t) (1671981156L >> (23 - NUM_EG1_FRAC_BITS)) #define MULT_DENTS_COEF(dents,coef) /*lint -e704 */ \ (int32_t)( \ ( \ ((int32_t)(dents)) * ((int32_t)(coef)) \ ) \ >> NUM_DENTS_FRAC_BITS \ ) \ /* lint +e704 */ /* we use 16-bits in the PC per audio sample */ #define BITS_PER_AUDIO_SAMPLE 16 /* we define 1 as 1.0 - 1 LSbit */ #define DISTORTION_ONE (int32_t)((0x1L << (BITS_PER_AUDIO_SAMPLE-1)) -1) #define DISTORTION_MINUS_ONE (int32_t)(~DISTORTION_ONE) /* drive coef is given as int.frac */ #define NUM_DRIVE_COEF_INT_BITS 1 #define NUM_DRIVE_COEF_FRAC_BITS 4 #define MULT_AUDIO_DRIVE(audio,drive) /*lint -e(702) */ \ (int32_t) ( \ ( \ ((int32_t)(audio)) * ((int32_t)(drive)) \ ) \ >> NUM_DRIVE_COEF_FRAC_BITS \ ) #define MULT_AUDIO_AUDIO(audio1,audio2) /*lint -e(702) */ \ (int32_t) ( \ ( \ ((int32_t)(audio1)) * ((int32_t)(audio2)) \ ) \ >> (BITS_PER_AUDIO_SAMPLE-1) \ ) #define SATURATE(x) \ ((((int32_t)(x)) > DISTORTION_ONE) ? (DISTORTION_ONE) : \ (((int32_t)(x)) < DISTORTION_MINUS_ONE) ? (DISTORTION_MINUS_ONE) : ((int32_t)(x))); /*---------------------------------------------------------------------------- * EAS_Calculate2toX() *---------------------------------------------------------------------------- * Purpose: * Calculate 2^x * * Inputs: * nCents - measured in cents * * Outputs: * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS) * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_I32 EAS_Calculate2toX (EAS_I32 nCents); /*---------------------------------------------------------------------------- * EAS_LogToLinear16() *---------------------------------------------------------------------------- * Purpose: * Transform log value to linear gain multiplier using piece-wise linear * approximation * * Inputs: * nGain - log scale value in 20.10 format. Even though gain is normally * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate * the need for saturation checking when combining gain values. * * Outputs: * Returns a 16-bit linear value approximately equal to 2^(nGain/1024) * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain); /*---------------------------------------------------------------------------- * EAS_VolumeToGain() *---------------------------------------------------------------------------- * Purpose: * Transform volume control in 1dB increments to gain multiplier * * Inputs: * volume - 100 = 0dB, 99 = -1dB, 0 = -inf * * Outputs: * Returns a 16-bit linear value *---------------------------------------------------------------------------- */ EAS_I16 EAS_VolumeToGain (EAS_INT volume); /*---------------------------------------------------------------------------- * EAS_fsqrt() *---------------------------------------------------------------------------- * Purpose: * Calculates the square root of a 32-bit fixed point value * * Inputs: * n = value of interest * * Outputs: * returns the square root of n * *---------------------------------------------------------------------------- */ EAS_U16 EAS_fsqrt (EAS_U32 n); /*---------------------------------------------------------------------------- * EAS_flog2() *---------------------------------------------------------------------------- * Purpose: * Calculates the log2 of a 32-bit fixed point value * * Inputs: * n = value of interest * * Outputs: * returns the log2 of n * *---------------------------------------------------------------------------- */ EAS_I32 EAS_flog2 (EAS_U32 n); #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_chorusdata.h0000644000000000000000000000013214200302440027237 xustar0030 mtime=1644266784.801324165 30 atime=1644266784.965324271 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_chorusdata.h0000644000175000001440000001137214200302440030024 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_chorusdata.h * * Contents and purpose: * Contains the prototypes for the Chorus effect. * * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 309 $ * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_CHORUS_H #define _EAS_CHORUS_H #include "eas_types.h" #include "eas_audioconst.h" //defines for chorus #define EAS_CHORUS_BYPASS_DEFAULT 1 #define EAS_CHORUS_PRESET_DEFAULT 0 #define EAS_CHORUS_RATE_DEFAULT 30 #define EAS_CHORUS_DEPTH_DEFAULT 39 #define EAS_CHORUS_LEVEL_DEFAULT 32767 #define EAS_CHORUS_LEVEL_MIN 0 #define EAS_CHORUS_LEVEL_MAX 32767 #define EAS_CHORUS_RATE_MIN 10 #define EAS_CHORUS_RATE_MAX 50 #define EAS_CHORUS_DEPTH_MIN 15 #define EAS_CHORUS_DEPTH_MAX 60 #define CHORUS_SIZE_MS 20 #define CHORUS_L_SIZE ((CHORUS_SIZE_MS*_OUTPUT_SAMPLE_RATE)/1000) #define CHORUS_R_SIZE CHORUS_L_SIZE #define CHORUS_SHAPE_SIZE 128 #define CHORUS_DELAY_MS 10 #define CHORUS_MAX_TYPE 4 // any Chorus numbers larger than this are invalid typedef struct { EAS_I16 m_nRate; EAS_I16 m_nDepth; EAS_I16 m_nLevel; } S_CHORUS_PRESET; typedef struct { S_CHORUS_PRESET m_sPreset[CHORUS_MAX_TYPE]; //array of presets } S_CHORUS_PRESET_BANK; /* parameters for each Chorus */ typedef struct { EAS_I32 lfoLPhase; EAS_I32 lfoRPhase; EAS_I16 chorusIndexL; EAS_I16 chorusIndexR; EAS_U16 chorusTapPosition; EAS_I16 m_nRate; EAS_I16 m_nDepth; EAS_I16 m_nLevel; //delay lines used by the chorus, longer would sound better EAS_PCM chorusDelayL[CHORUS_L_SIZE]; EAS_PCM chorusDelayR[CHORUS_R_SIZE]; EAS_BOOL bypass; EAS_I8 preset; EAS_I16 m_nCurrentChorus; // preset number for current Chorus EAS_I16 m_nNextChorus; // preset number for next Chorus S_CHORUS_PRESET pPreset; S_CHORUS_PRESET_BANK m_sPreset; } S_CHORUS_OBJECT; /*---------------------------------------------------------------------------- * WeightedTap() *---------------------------------------------------------------------------- * Purpose: Does fractional array look-up using linear interpolation * * first convert indexDesired to actual desired index by taking into account indexReference * then do linear interpolation between two actual samples using fractional part * * Inputs: * array: pointer to array of signed 16 bit values, typically either PCM data or control data * indexReference: the circular buffer relative offset * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction) * indexLimit: the total size of the array, used to compute buffer wrap * * Outputs: * Value from the input array, linearly interpolated between two actual data values * *---------------------------------------------------------------------------- */ static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit); /*---------------------------------------------------------------------------- * ChorusReadInPresets() *---------------------------------------------------------------------------- * Purpose: sets global Chorus preset bank to defaults * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData); /*---------------------------------------------------------------------------- * ChorusUpdate *---------------------------------------------------------------------------- * Purpose: * Update the Chorus preset parameters as required * * Inputs: * * Outputs: * * * Side Effects: * - chorus paramters will be changed * - m_nCurrentChorus := m_nNextChorus *---------------------------------------------------------------------------- */ static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT* pChorusData); #endif /* #ifndef _EAS_CHORUSDATA_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_tonecontrol.c0000644000000000000000000000013214200302440027443 xustar0030 mtime=1644266784.805324168 30 atime=1644266784.965324271 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_tonecontrol.c0000644000175000001440000007026614200302440030237 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_tonecontrol.c * * Contents and purpose: * MMAPI ToneControl parser * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 795 $ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $ *---------------------------------------------------------------------------- */ #include "eas_data.h" #include "eas_miditypes.h" #include "eas_parser.h" #include "eas_report.h" #include "eas_host.h" #include "eas_midi.h" #include "eas_config.h" #include "eas_vm_protos.h" #include "eas_tcdata.h" /* default channel and program for TC playback */ #define TC_CHANNEL 0 #define TC_PROGRAM 80 #define TC_VELOCITY 127 #define TC_FIELD_SILENCE -1 #define TC_FIELD_VERSION -2 #define TC_FIELD_TEMPO -3 #define TC_FIELD_RESOLUTION -4 #define TC_FIELD_BLOCK_START -5 #define TC_FIELD_BLOCK_END -6 #define TC_FIELD_PLAY_BLOCK -7 #define TC_FIELD_SET_VOLUME -8 #define TC_FIELD_REPEAT -9 #define TC_FIELD_INVALID -10 /* convert 0-100 volume to 0-127 velocity using fixed point */ #define TC_VOLUME_CONV 21307064 #define TC_VOLUME_SHIFT 24 /* local prototypes */ static EAS_RESULT TC_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset); static EAS_RESULT TC_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT TC_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime); static EAS_RESULT TC_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode); static EAS_RESULT TC_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState); static EAS_RESULT TC_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT TC_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT TC_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT TC_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT TC_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); static EAS_RESULT TC_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); static EAS_RESULT TC_ParseHeader (S_EAS_DATA *pEASData, S_TC_DATA* pData); static EAS_RESULT TC_StartNote (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode, EAS_I8 note); static EAS_RESULT TC_GetRepeat (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode); static EAS_RESULT TC_PlayBlock (S_EAS_DATA *pEASData, S_TC_DATA* pData); static EAS_RESULT TC_BlockEnd (S_EAS_DATA *pEASData, S_TC_DATA* pData); static EAS_RESULT TC_GetVolume (S_EAS_DATA *pEASData, S_TC_DATA* pData); static EAS_RESULT TC_GetTempo (S_EAS_DATA *pEASData, S_TC_DATA* pData); static EAS_RESULT TC_GetResolution (S_EAS_DATA *pEASData, S_TC_DATA* pData); static EAS_RESULT TC_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_TC_DATA *pData, EAS_I8 *pValue); static void TC_PutBackChar (S_TC_DATA *pData, EAS_I8 value); /* calculate a new tick time based on resolution & tempo */ EAS_INLINE void TC_CalcTimeBase (S_TC_DATA *pData) { /* ticks in 256ths of a millisecond */ pData->tick = ((60 * 1000) << 8) / (pData->tempo * pData->resolution); } /*---------------------------------------------------------------------------- * * EAS_TC_Parser * * This structure contains the functional interface for the iMelody parser *---------------------------------------------------------------------------- */ const S_FILE_PARSER_INTERFACE EAS_TC_Parser = { TC_CheckFileType, TC_Prepare, TC_Time, TC_Event, TC_State, TC_Close, TC_Reset, TC_Pause, TC_Resume, NULL, TC_SetData, TC_GetData, NULL }; /*---------------------------------------------------------------------------- * TC_CheckFileType() *---------------------------------------------------------------------------- * Purpose: * Check the file type to see if we can parse it * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT TC_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset) { S_TC_DATA data; S_TC_DATA *pData; /* init data */ EAS_HWMemSet(&data, 0, sizeof(S_TC_DATA)); data.fileHandle = fileHandle; data.fileOffset = offset; *ppHandle= NULL; /* see if we can parse the header */ if (TC_ParseHeader(pEASData, &data) == EAS_SUCCESS) { /* check for static memory allocation */ if (pEASData->staticMemoryModel) pData = EAS_CMEnumOptData(EAS_MODULE_MMAPI_TONE_CONTROL); else pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_TC_DATA)); if (!pData) return EAS_ERROR_MALLOC_FAILED; /* copy data to persistent storage */ EAS_HWMemCpy(pData, &data, sizeof(S_TC_DATA)); /* return a pointer to the instance data */ pData->state = EAS_STATE_OPEN; *ppHandle = pData; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_Prepare() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. Allocates instance data (or uses static allocation for * static memory model). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT TC_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_TC_DATA* pData; EAS_RESULT result; /* check for valid state */ pData = (S_TC_DATA*) pInstData; if (pData->state != EAS_STATE_OPEN) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* instantiate a synthesizer */ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ } return result; } /* set to ready state */ pData->state = EAS_STATE_READY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_Time() *---------------------------------------------------------------------------- * Purpose: * Returns the time of the next event in msecs * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pTime - pointer to variable to hold time of next event (in msecs) * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ static EAS_RESULT TC_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime) { S_TC_DATA *pData; pData = (S_TC_DATA*) pInstData; /* return time in milliseconds */ /*lint -e{704} use shift instead of division */ *pTime = pData->time >> 8; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_Event() *---------------------------------------------------------------------------- * Purpose: * Parse the next event in the file * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT TC_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode) { S_TC_DATA* pData; EAS_RESULT result; EAS_I8 temp; pData = (S_TC_DATA*) pInstData; if (pData->state >= EAS_STATE_OPEN) return EAS_SUCCESS; /* initialize MIDI channel when the track starts playing */ if (pData->time == 0) { /* set program to square lead */ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, TC_PROGRAM); /* set channel volume to max */ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, 7, 127); } /* check for end of note */ if (pData->note >= 0) { /* stop the note */ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) pData->note, 0); /* check for repeat note */ if (pData->repeatCount) { pData->repeatCount--; pData->time += pData->length; if ((pData->note >= 0) && (parserMode == eParserModePlay)) VMStartNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) pData->note, pData->volume); return EAS_SUCCESS; } pData->note = TC_FIELD_SILENCE; } /* parse stream until we get a note or rest */ for (;;) { /* get next byte from stream */ if ((result = TC_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS) { if (result == EAS_EOF) { pData->state = EAS_STATE_STOPPING; return EAS_SUCCESS; } break; } /* check for musical events */ if (temp >= TC_FIELD_SILENCE) { result = TC_StartNote(pEASData, pData, parserMode, temp); break; } /* must be a control field */ switch (temp) { case TC_FIELD_TEMPO: result = TC_GetTempo(pEASData, pData); break; case TC_FIELD_RESOLUTION: result = TC_GetResolution(pEASData, pData); break; case TC_FIELD_SET_VOLUME: result = TC_GetVolume(pEASData, pData); break; case TC_FIELD_REPEAT: result = TC_GetRepeat(pEASData, pData, parserMode); break; case TC_FIELD_PLAY_BLOCK: result = TC_PlayBlock(pEASData, pData); break; case TC_FIELD_BLOCK_START: result = TC_GetNextChar(pEASData->hwInstData, pData, &temp); break; case TC_FIELD_BLOCK_END: result = TC_BlockEnd(pEASData, pData); break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected byte 0x%02x in ToneControl stream\n", temp); */ } result = EAS_ERROR_FILE_FORMAT; } /* check for error */ if (result != EAS_SUCCESS) break; } /* check for error */ if (result != EAS_SUCCESS) { if (result == EAS_EOF) result = EAS_ERROR_FILE_FORMAT; pData->state = EAS_STATE_ERROR; } else pData->state = EAS_STATE_PLAY; return result; } /*---------------------------------------------------------------------------- * TC_State() *---------------------------------------------------------------------------- * Purpose: * Returns the current state of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pState - pointer to variable to store state * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ static EAS_RESULT TC_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState) { S_TC_DATA* pData; /* establish pointer to instance data */ pData = (S_TC_DATA*) pInstData; /* if stopping, check to see if synth voices are active */ if (pData->state == EAS_STATE_STOPPING) { if (VMActiveVoices(pData->pSynth) == 0) pData->state = EAS_STATE_STOPPED; } if (pData->state == EAS_STATE_PAUSING) { if (VMActiveVoices(pData->pSynth) == 0) pData->state = EAS_STATE_PAUSED; } /* return current state */ *pState = pData->state; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_Close() *---------------------------------------------------------------------------- * Purpose: * Close the file and clean up * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT TC_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_TC_DATA* pData; EAS_RESULT result; pData = (S_TC_DATA*) pInstData; /* close the file */ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS) return result; /* free the synth */ if (pData->pSynth != NULL) VMMIDIShutdown(pEASData, pData->pSynth); /* if using dynamic memory, free it */ if (!pEASData->staticMemoryModel) EAS_HWFree(pEASData->hwInstData, pData); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_Reset() *---------------------------------------------------------------------------- * Purpose: * Reset the sequencer. Used for locating backwards in the file. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT TC_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_TC_DATA* pData; EAS_RESULT result; pData = (S_TC_DATA*) pInstData; /* reset the synth */ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE); /* reset time to zero */ pData->time = 0; /* reset file position and re-parse header */ pData->state = EAS_STATE_ERROR; if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS) return result; if ((result = TC_ParseHeader (pEASData, pData)) != EAS_SUCCESS) return result; pData->state = EAS_STATE_READY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_Pause() *---------------------------------------------------------------------------- * Purpose: * Pauses the sequencer. Mutes all voices and sets state to pause. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT TC_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_TC_DATA *pData; /* can't pause a stopped stream */ pData = (S_TC_DATA*) pInstData; if (pData->state == EAS_STATE_STOPPED) return EAS_ERROR_ALREADY_STOPPED; /* mute the synthesizer */ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth); pData->state = EAS_STATE_PAUSING; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_Resume() *---------------------------------------------------------------------------- * Purpose: * Resume playing after a pause, sets state back to playing. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ static EAS_RESULT TC_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_TC_DATA *pData; /* can't resume a stopped stream */ pData = (S_TC_DATA*) pInstData; if (pData->state == EAS_STATE_STOPPED) return EAS_ERROR_ALREADY_STOPPED; /* nothing to do but resume playback */ pData->state = EAS_STATE_PLAY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_SetData() *---------------------------------------------------------------------------- * Purpose: * Return file type * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData, pInstData, value) reserved for future use */ static EAS_RESULT TC_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value) { /* we don't parse any metadata, but we need to return success here */ if (param == PARSER_DATA_METADATA_CB) return EAS_SUCCESS; return EAS_ERROR_INVALID_PARAMETER; } /*---------------------------------------------------------------------------- * TC_GetData() *---------------------------------------------------------------------------- * Purpose: * Return file type * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -e{715} common with other parsers */ static EAS_RESULT TC_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue) { S_TC_DATA *pData; pData = (S_TC_DATA *) pInstData; switch (param) { /* return file type as TC */ case PARSER_DATA_FILE_TYPE: *pValue = EAS_FILE_MMAPI_TONE_CONTROL; break; case PARSER_DATA_SYNTH_HANDLE: *pValue = (EAS_I32) pData->pSynth; break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_ParseHeader() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. Allocates instance data (or uses static allocation for * static memory model). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT TC_ParseHeader (S_EAS_DATA *pEASData, S_TC_DATA* pData) { EAS_RESULT result; EAS_I8 temp; /* initialize some defaults */ pData->time = 0; pData->tempo = 120; pData->resolution = 64; pData->volume = 127; pData->repeatCount = 0; pData->note = TC_FIELD_SILENCE; pData->byteAvail = EAS_FALSE; /* set default timebase */ TC_CalcTimeBase(pData); /* seek to start of data */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS) return result; /* get version */ if ((result = TC_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS) return result; /* check for version number */ if (temp == TC_FIELD_VERSION) { TC_GetNextChar(pEASData->hwInstData, pData, &temp); // { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "ToneControl sequence version %d\n", temp); */ } } else return EAS_ERROR_FILE_FORMAT; /* parse the header data until we find the first note or block */ for (;;) { /* get next byte from stream */ if ((result = TC_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS) return result; /* check for tempo */ if (temp == TC_FIELD_TEMPO) { if ((result = TC_GetTempo(pEASData, pData)) != EAS_SUCCESS) return result; } /* or resolution */ else if (temp == TC_FIELD_TEMPO) { if ((result = TC_GetResolution(pEASData, pData)) != EAS_SUCCESS) return result; } /* must be music data */ else if (temp > TC_FIELD_INVALID) { TC_PutBackChar(pData, temp); return EAS_SUCCESS; } /* unknown codes */ else { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected byte 0x%02x in ToneControl stream\n", temp); */ } return EAS_ERROR_FILE_FORMAT; } } } /*---------------------------------------------------------------------------- * TC_StartNote() *---------------------------------------------------------------------------- * Process a note or silence event *---------------------------------------------------------------------------- */ static EAS_RESULT TC_StartNote (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode, EAS_I8 note) { EAS_I8 duration; /* get the duration */ if (TC_GetNextChar(pEASData->hwInstData, pData, &duration) != EAS_SUCCESS) return EAS_ERROR_FILE_FORMAT; /* calculate time of next event */ pData->length = (EAS_I32) duration * pData->tick; pData->time += pData->length; /* start the note */ if ((note >= 0) && (parserMode == eParserModePlay)) { VMStartNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) note, pData->volume); pData->note = note; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_GetRepeat() *---------------------------------------------------------------------------- * Process a repeat code *---------------------------------------------------------------------------- */ static EAS_RESULT TC_GetRepeat (S_EAS_DATA *pEASData, S_TC_DATA* pData, EAS_INT parserMode) { EAS_I8 count; /* get the repeat count */ if (TC_GetNextChar(pEASData->hwInstData, pData, &count) != EAS_SUCCESS) return EAS_ERROR_FILE_FORMAT; /* validiate it */ if (count < 2) return EAS_ERROR_FILE_FORMAT; /* calculate time of next event */ pData->time += pData->length; pData->repeatCount = count - 2; /* start the note */ if ((pData->note >= 0) && (parserMode == eParserModePlay)) VMStartNote(pEASData->pVoiceMgr, pData->pSynth, TC_CHANNEL, (EAS_U8) pData->note, pData->volume); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_PlayBlock() *---------------------------------------------------------------------------- * Play a block of notes *---------------------------------------------------------------------------- */ static EAS_RESULT TC_PlayBlock (S_EAS_DATA *pEASData, S_TC_DATA* pData) { EAS_RESULT result; EAS_I8 blockNum; EAS_I8 temp; EAS_I8 temp2; /* get the block number */ if (TC_GetNextChar(pEASData->hwInstData, pData, &blockNum) != EAS_SUCCESS) return EAS_ERROR_FILE_FORMAT; /* validiate it */ if (blockNum < 0) return EAS_ERROR_FILE_FORMAT; /* save the current position */ if ((result = EAS_HWFilePos(pEASData->hwInstData, pData->fileHandle, &pData->restorePos)) != EAS_SUCCESS) return result; /* return to start of file */ pData->byteAvail = EAS_FALSE; if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS) return result; /* find the block */ for (;;) { if (TC_GetNextChar(pEASData->hwInstData, pData, &temp) != EAS_SUCCESS) return EAS_ERROR_FILE_FORMAT; if (TC_GetNextChar(pEASData->hwInstData, pData, &temp2) != EAS_SUCCESS) return EAS_ERROR_FILE_FORMAT; if ((temp == TC_FIELD_BLOCK_START) && (temp2 == blockNum)) return EAS_SUCCESS; } } /*---------------------------------------------------------------------------- * TC_BlockEnd() *---------------------------------------------------------------------------- * Handle end of block *---------------------------------------------------------------------------- */ static EAS_RESULT TC_BlockEnd (S_EAS_DATA *pEASData, S_TC_DATA* pData) { EAS_I8 blockNum; /* get the block number */ if (TC_GetNextChar(pEASData->hwInstData, pData, &blockNum) != EAS_SUCCESS) return EAS_ERROR_FILE_FORMAT; /* validiate it */ if (blockNum < 0) return EAS_ERROR_FILE_FORMAT; /* if we were playing this block, restore to previous position */ pData->byteAvail = EAS_FALSE; return EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->restorePos); } /*---------------------------------------------------------------------------- * TC_GetVolume() *---------------------------------------------------------------------------- * Get the volume field and process it *---------------------------------------------------------------------------- */ static EAS_RESULT TC_GetVolume (S_EAS_DATA *pEASData, S_TC_DATA* pData) { EAS_I8 volume; /* get volume */ if (TC_GetNextChar(pEASData->hwInstData, pData, &volume) != EAS_SUCCESS) return EAS_ERROR_FILE_FORMAT; if ((volume < 0) || (volume > 100)) return EAS_ERROR_FILE_FORMAT; /* save volume */ pData->volume = (EAS_U8) ((EAS_I32) (volume * TC_VOLUME_CONV + 1) >> TC_VOLUME_SHIFT); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_GetTempo() *---------------------------------------------------------------------------- * Get the tempo field and process it *---------------------------------------------------------------------------- */ static EAS_RESULT TC_GetTempo (S_EAS_DATA *pEASData, S_TC_DATA* pData) { EAS_I8 tempo; /* get tempo */ if (TC_GetNextChar(pEASData->hwInstData, pData, &tempo) != EAS_SUCCESS) return EAS_ERROR_FILE_FORMAT; if (tempo < 5) return EAS_ERROR_FILE_FORMAT; /* save tempo */ pData->tempo = tempo; /* calculate new timebase */ TC_CalcTimeBase(pData); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_GetResolution() *---------------------------------------------------------------------------- * Get the resolution field and process it *---------------------------------------------------------------------------- */ static EAS_RESULT TC_GetResolution (S_EAS_DATA *pEASData, S_TC_DATA* pData) { EAS_I8 resolution; /* get resolution */ if (TC_GetNextChar(pEASData->hwInstData, pData, &resolution) != EAS_SUCCESS) return EAS_ERROR_FILE_FORMAT; if (resolution < 0) return EAS_ERROR_FILE_FORMAT; /* save tempo */ pData->resolution = resolution; /* calculate new timebase */ TC_CalcTimeBase(pData); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * TC_GetNextChar() *---------------------------------------------------------------------------- * Fetch the next character from the stream *---------------------------------------------------------------------------- */ static EAS_RESULT TC_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_TC_DATA *pData, EAS_I8 *pValue) { /* get character from "put back" buffer */ if (pData->byteAvail) { pData->byteAvail = EAS_FALSE; *pValue = pData->dataByte; return EAS_SUCCESS; } /* get character from file */ return EAS_HWGetByte(hwInstData, pData->fileHandle, pValue); } /*---------------------------------------------------------------------------- * TC_PutBackChar() *---------------------------------------------------------------------------- * Put back the character *---------------------------------------------------------------------------- */ static void TC_PutBackChar (S_TC_DATA *pData, EAS_I8 value) { pData->dataByte = value; pData->byteAvail = EAS_TRUE; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_effects.h0000644000000000000000000000013214200302440026521 xustar0030 mtime=1644266784.801324165 30 atime=1644266784.965324271 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_effects.h0000644000175000001440000000426014200302440027304 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_effects.h * * Contents and purpose: * Defines a generic effects interface. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_EFFECTS_H #define _EAS_EFFECTS_H #include "eas_types.h" typedef struct { EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData); void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_PCM *in, EAS_PCM *out, EAS_I32 numSamples); EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData); EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); } S_EFFECTS_INTERFACE; typedef struct { EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData); void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_I32 *in, EAS_I32 *out, EAS_I32 numSamples); EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData); EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); } S_EFFECTS32_INTERFACE; /* mixer instance data */ typedef struct { S_EFFECTS_INTERFACE *effect; EAS_VOID_PTR effectData; } S_EFFECTS_MODULE; #endif /* end _EAS_EFFECTS_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_smf.h0000644000000000000000000000013214200302440025667 xustar0030 mtime=1644266784.805324168 30 atime=1644266784.965324271 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_smf.h0000644000175000001440000000416614200302440026457 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_smf.h * * Contents and purpose: * SMF Type 0 and 1 File Parser * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_SMF_H #define _EAS_SMF_H /* prototypes for private interface to SMF parser */ EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset); EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime); EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode); EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState); EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData); #endif /* end _EAS_SMF_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_xmfdata.c0000644000000000000000000000013214200302440026521 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_xmfdata.c0000644000175000001440000000257514200302440027313 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_xmfdata.c * * Contents and purpose: * XMF File Parser * * This file contains data definitions for the XMF parser. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 547 $ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $ *---------------------------------------------------------------------------- */ #include "eas_miditypes.h" #include "eas_xmf.h" #include "eas_xmfdata.h" /*---------------------------------------------------------------------------- * * eas_XMFData * * Static memory allocation for XMF parser *---------------------------------------------------------------------------- */ S_XMF_DATA eas_XMFData; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_ima_tables.c0000644000000000000000000000013214200302440027175 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.965324271 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_ima_tables.c0000644000175000001440000000357214200302440027765 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_ima_tables.c * * Contents and purpose: * Contains the constant tables for IMA encode/decode * * Copyright (c) 2005 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 760 $ * $Date: 2007-07-17 23:09:36 -0700 (Tue, 17 Jul 2007) $ *---------------------------------------------------------------------------- */ #include "eas_types.h" /*---------------------------------------------------------------------------- * ADPCM decode tables *---------------------------------------------------------------------------- */ const EAS_I16 imaIndexTable[16] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 }; const EAS_I16 imaStepSizeTable[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 }; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_pcm.c0000644000000000000000000000013214200302440025654 xustar0030 mtime=1644266784.805324168 30 atime=1644266784.965324271 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_pcm.c0000644000175000001440000013332014200302440026437 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_pcm.c * * Contents and purpose: * Implements the PCM engine including ADPCM decode for SMAF and CMX audio playback. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 849 $ * $Date: 2007-08-28 08:59:11 -0700 (Tue, 28 Aug 2007) $ *---------------------------------------------------------------------------- */ #include "eas_data.h" #include "eas_report.h" #include "eas_host.h" #include "eas_config.h" #include "eas_parser.h" #include "eas_pcm.h" #include "eas_math.h" #include "eas_mixer.h" #define PCM_MIXER_GUARD_BITS (NUM_MIXER_GUARD_BITS + 1) /*---------------------------------------------------------------------------- * Decoder interfaces *---------------------------------------------------------------------------- */ static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState); static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time); static const S_DECODER_INTERFACE PCMDecoder = { NULL, LinearPCMDecode, LinearPCMLocate, }; /* SMAF ADPCM decoder */ #ifdef _SMAF_PARSER extern S_DECODER_INTERFACE SmafDecoder; #define SMAF_DECODER &SmafDecoder extern S_DECODER_INTERFACE Smaf7BitDecoder; #define SMAF_7BIT_DECODER &Smaf7BitDecoder #else #define SMAF_DECODER NULL #define SMAF_7BIT_DECODER NULL #endif /* IMA ADPCM decoder */ #ifdef _IMA_DECODER extern S_DECODER_INTERFACE IMADecoder; #define IMA_DECODER &IMADecoder #else #define IMA_DECODER NULL #endif static const S_DECODER_INTERFACE * const decoders[] = { &PCMDecoder, SMAF_DECODER, IMA_DECODER, SMAF_7BIT_DECODER }; /*---------------------------------------------------------------------------- * Sample rate conversion *---------------------------------------------------------------------------- */ #define SRC_RATE_MULTIPLER (0x40000000 / _OUTPUT_SAMPLE_RATE) #ifdef _LOOKUP_SAMPLE_RATE static const EAS_U32 srcConvRate[][2] = { 4000L, (4000L << 15) / _OUTPUT_SAMPLE_RATE, 8000L, (8000L << 15) / _OUTPUT_SAMPLE_RATE, 11025L, (11025L << 15) / _OUTPUT_SAMPLE_RATE, 12000L, (12000L << 15) / _OUTPUT_SAMPLE_RATE, 16000L, (16000L << 15) / _OUTPUT_SAMPLE_RATE, 22050L, (22050L << 15) / _OUTPUT_SAMPLE_RATE, 24000L, (24000L << 15) / _OUTPUT_SAMPLE_RATE, 32000L, (32000L << 15) / _OUTPUT_SAMPLE_RATE }; static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate); #define SRC_CONV_RATE_ENTRIES (sizeof(srcConvRate)/sizeof(EAS_U32)/2) #endif /* interface prototypes */ static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples); /* local prototypes */ static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData); static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState); /*---------------------------------------------------------------------------- * EAS_PEInit() *---------------------------------------------------------------------------- * Purpose: * Initializes the PCM engine * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEInit (S_EAS_DATA *pEASData) { S_PCM_STATE *pState; EAS_INT i; /* check for static memory allocation */ if (pEASData->staticMemoryModel) pEASData->pPCMStreams = EAS_CMEnumData(EAS_CM_PCM_DATA); /* allocate dynamic memory */ else pEASData->pPCMStreams = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS); if (!pEASData->pPCMStreams) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate memory for PCM streams\n"); */ } return EAS_ERROR_MALLOC_FAILED; } //zero the memory to insure complete initialization EAS_HWMemSet((void *)(pEASData->pPCMStreams),0, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS); /* initialize the state data */ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++) pState->fileHandle = NULL; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PEShutdown() *---------------------------------------------------------------------------- * Purpose: * Shuts down the PCM engine * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEShutdown (S_EAS_DATA *pEASData) { /* free any dynamic memory */ if (!pEASData->staticMemoryModel) { if (pEASData->pPCMStreams) { EAS_HWFree(pEASData->hwInstData, pEASData->pPCMStreams); pEASData->pPCMStreams = NULL; } } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PERender() *---------------------------------------------------------------------------- * Purpose: * Render a buffer of PCM audio * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PERender (S_EAS_DATA* pEASData, EAS_I32 numSamples) { S_PCM_STATE *pState; EAS_RESULT result; EAS_INT i; /* render all the active streams */ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++) { if ((pState->fileHandle) && (pState->state != EAS_STATE_STOPPED) && (pState->state != EAS_STATE_PAUSED)) if ((result = RenderPCMStream(pEASData, pState, numSamples)) != EAS_SUCCESS) return result; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PEState() *---------------------------------------------------------------------------- * Purpose: * Returns the current state of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pState - pointer to variable to store state * * Outputs: * * * Side Effects: * * Notes: * This interface is also exposed in the internal library for use by the other modules. *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT EAS_PEState (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pInstData, EAS_STATE *pState) { /* return current state */ *pState = pInstData->state; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PEClose() *---------------------------------------------------------------------------- * Purpose: * Close the file and clean up * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEClose (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState) { EAS_RESULT result; if ((result = EAS_HWCloseFile(pEASData->hwInstData, pState->fileHandle)) != EAS_SUCCESS) return result; pState->fileHandle = NULL; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * PCM_Reset() *---------------------------------------------------------------------------- * Purpose: * Reset the sequencer. Used for locating backwards in the file. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEReset (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState) { EAS_RESULT result; /* reset file position to first byte of data in the stream */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d seeking to start of PCM file\n", result); */ } return result; } /* re-initialize stream */ return InitPCMStream(pEASData, pState); } /*---------------------------------------------------------------------------- * EAS_PEOpenStream() *---------------------------------------------------------------------------- * Purpose: * Starts up a PCM playback * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEOpenStream (S_EAS_DATA *pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle) { EAS_RESULT result; S_PCM_STATE *pState; EAS_I32 filePos; /* make sure we support this decoder */ if (pParams->decoder >= NUM_DECODER_MODULES) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder selector out of range\n"); */ } return EAS_ERROR_PARAMETER_RANGE; } if (decoders[pParams->decoder] == NULL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder module not available\n"); */ } return EAS_ERROR_FEATURE_NOT_AVAILABLE; } /* find a slot for the new stream */ if ((pState = FindSlot(pEASData, pParams->fileHandle, pParams->pCallbackFunc, pParams->cbInstData)) == NULL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to open ADPCM stream, too many streams open\n"); */ } return EAS_ERROR_MAX_PCM_STREAMS; } /* get the current file position */ if ((result = EAS_HWFilePos(pEASData->hwInstData, pState->fileHandle, &filePos)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWFilePos returned %ld\n",result); */ } pState->fileHandle = NULL; return result; } pState->pDecoder = decoders[pParams->decoder]; pState->startPos = filePos; pState->bytesLeftLoop = pState->byteCount = pParams->size; pState->loopStart = pParams->loopStart; pState->samplesTilLoop = (EAS_I32) pState->loopStart; pState->loopSamples = pParams->loopSamples; pState->samplesInLoop = 0; pState->blockSize = (EAS_U16) pParams->blockSize; pState->flags = pParams->flags; pState->envData = pParams->envData; pState->volume = pParams->volume; pState->sampleRate = (EAS_U16) pParams->sampleRate; /* set the base frequency */ pState->basefreq = (SRC_RATE_MULTIPLER * (EAS_U32) pParams->sampleRate) >> 15; /* calculate shift for frequencies > 1.0 */ pState->rateShift = 0; while (pState->basefreq > 32767) { pState->basefreq = pState->basefreq >> 1; pState->rateShift++; } /* initialize */ if ((result = InitPCMStream(pEASData, pState)) != EAS_SUCCESS) return result; *pHandle = pState; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PEOpenStream: StartPos=%d, byteCount = %d, loopSamples=%d\n", pState->startPos, pState->byteCount, pState->loopSamples); */ } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PEContinueStream() *---------------------------------------------------------------------------- * Purpose: * Continues a PCM stream * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -e{715} reserved for future use */ EAS_RESULT EAS_PEContinueStream (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 size) { /* add new samples to count */ pState->bytesLeft += size; if (pState->bytesLeft > 0) pState->flags &= ~PCM_FLAGS_EMPTY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PEGetFileHandle() *---------------------------------------------------------------------------- * Purpose: * Returns the file handle of a stream * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT EAS_PEGetFileHandle (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_FILE_HANDLE *pFileHandle) { *pFileHandle = pState->fileHandle; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PEUpdateParams() *---------------------------------------------------------------------------- * Purpose: * Update the pitch and volume parameters for a PCM stream * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_PCM_STATE for this stream * gainLeft - linear gain multipler in 1.15 fraction format * gainRight - linear gain multipler in 1.15 fraction format * pitch - pitch shift in cents * initial - initial settings, set current gain * * Outputs: * * * Side Effects: * * Notes * In mono mode, leftGain controls the output gain and rightGain is ignored *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ /*lint -esym(715, gainRight) used only in 2-channel version */ EAS_RESULT EAS_PEUpdateParams (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight) { pState->gainLeft = gainLeft; #if (NUM_OUTPUT_CHANNELS == 2) pState->gainRight = gainRight; #endif pState->pitch = pitch; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PELocate() *---------------------------------------------------------------------------- * Purpose: * This function seeks to the requested place in the file. Accuracy * is dependent on the sample rate and block size. * * Inputs: * pEASData - pointer to overall EAS data structure * pState - stream handle * time - media time in milliseconds *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PELocate (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 time) { if (pState->pDecoder->pfLocate == NULL) return EAS_ERROR_FEATURE_NOT_AVAILABLE; return pState->pDecoder->pfLocate(pEASData, pState, time); } /*---------------------------------------------------------------------------- * EAS_PEUpdateVolume() *---------------------------------------------------------------------------- * Purpose: * Update the volume parameters for a PCM stream * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_PCM_STATE for this stream * gainLeft - linear gain multipler in 1.15 fraction format * gainRight - linear gain multipler in 1.15 fraction format * initial - initial settings, set current gain * * Outputs: * * * Side Effects: * * Notes * In mono mode, leftGain controls the output gain and rightGain is ignored *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT EAS_PEUpdateVolume (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume) { pState->volume = volume; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PEUpdatePitch() *---------------------------------------------------------------------------- * Purpose: * Update the pitch parameter for a PCM stream * * Inputs: * pEASData - pointer to EAS library instance data * pState - pointer to S_PCM_STATE for this stream * pitch - new pitch value in pitch cents *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT EAS_PEUpdatePitch (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch) { pState->pitch = pitch; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PEPause() *---------------------------------------------------------------------------- * Purpose: * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback * at the end of the next audio frame. * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_PCM_STATE for this stream * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT EAS_PEPause (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState) { /* set state to stopping */ pState->state = EAS_STATE_PAUSING; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PEResume() *---------------------------------------------------------------------------- * Purpose: * Resume rendering a PCM stream. Sets the gain target back to its * previous setting and restarts playback at the end of the next audio * frame. * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_PCM_STATE for this stream * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT EAS_PEResume (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState) { /* set state to stopping */ pState->state = EAS_STATE_PLAY; return EAS_SUCCESS; } EAS_U32 getDecayScale(EAS_U32 index) { EAS_U32 utemp; //envelope decay segment switch (index) { case 0: //no decay utemp = 512;//32768; break; case 1: //.0156 dB per update utemp = 511;//32709; break; case 2: //.03125 utemp = 510;//32649; break; case 3: //.0625 utemp = 508;//32532; break; case 4: //.125 utemp = 505;//32298; break; case 5: //.25 utemp = 497;//31835; break; case 6: //.5 utemp = 483;//30929; break; case 7: //1.0 utemp = 456;//29193; break; case 8: //2.0 utemp = 406;//26008; break; case 9: //4.0 utemp = 323;//20642; break; case 10: //8.0 utemp = 203;//13004; break; case 11: //16.0 utemp = 81;//5160; break; case 12: //32.0 utemp = 13;//813; break; case 13: //64.0 utemp = 0;//20; break; case 14: //128.0 utemp = 0; break; case 15: //256.0 default: utemp = 0; break; } //printf("getdecayscale returned %d\n",utemp); return utemp; } EAS_U32 getAttackIncrement(EAS_U32 index) { EAS_U32 utemp; //envelope decay segment switch (index) { case 0: utemp = 32; break; case 1: utemp = 64; break; case 2: utemp = 128; break; case 3: utemp = 256; break; case 4: utemp = 512; break; case 5: utemp = 1024; break; case 6: utemp = 2048; break; case 7: utemp = 4096; break; case 8: utemp = 8192; break; case 9: utemp = 16384; break; case 10: utemp = 32768; break; case 11: utemp = 65536; break; case 12: utemp = 65536; break; case 13: utemp = 65536; break; case 14: utemp = 65535; break; case 15: default: utemp = 0; break; } //printf("getattackincrement returned %d\n",utemp); return utemp; } /*---------------------------------------------------------------------------- * EAS_PERelease() *---------------------------------------------------------------------------- * Purpose: * Put the PCM stream envelope into release. * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_PCM_STATE for this stream * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT EAS_PERelease (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState) { EAS_U32 utemp; //printf("handling note-off part of envelope\n"); /*if the note is not ignore release or sustained*/ if (((pState->envData >> 24) & 0x0F)==0) { /* set envelope state to release */ pState->envState = PCM_ENV_RELEASE; utemp = ((pState->envData >> 20) & 0x0F); pState->envScale = getDecayScale(utemp); //getReleaseScale(utemp); } else { /*else change envelope state to sustain */ pState->envState = PCM_ENV_SUSTAIN; utemp = ((pState->envData >> 28) & 0x0F); pState->envScale = getDecayScale(utemp); //getSustainScale(utemp); } //since we are in release, don't let anything hang around too long //printf("checking env scale, val = %d\n",((S_PCM_STATE*) handle)->envScale); if (pState->envScale > 505) pState->envScale = 505; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * FindSlot() *---------------------------------------------------------------------------- * Purpose: * Locates an empty stream slot and assigns the file handle * * Inputs: * pEASData - pointer to EAS library instance data * fileHandle - file handle * pCallbackFunc - function to be called back upon EAS_STATE_STOPPED * * Outputs: * returns handle to slot or NULL if all slots are used * * Side Effects: * *---------------------------------------------------------------------------- */ static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData) { EAS_INT i; S_PCM_STATE *pState; #ifndef NO_PCM_STEAL S_PCM_STATE *foundState = NULL; EAS_INT count = 0; EAS_U32 startOrder = 0xFFFFFFFF; S_PCM_STATE *stealState = NULL; EAS_U32 youngest = 0; /* find an empty slot, count total in use, and find oldest in use (lowest start order) */ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++) { /* if this one is available */ if (pState->fileHandle == NULL) { foundState = pState; } /* else this one is in use, so see if it is the oldest, and count total in use */ /* also find youngest */ else { /*one more voice in use*/ count++; /* is this the oldest? (lowest start order) */ if ((pState->state != EAS_STATE_STOPPING) && (pState->startOrder < startOrder)) { /* remember this one */ stealState = pState; /* remember the oldest so far */ startOrder = pState->startOrder; } /* is this the youngest? (highest start order) */ if (pState->startOrder >= youngest) { youngest = pState->startOrder; } } } /* if there are too many voices active, stop the oldest one */ if (count > PCM_STREAM_THRESHOLD) { //printf("stealing!!!\n"); /* make sure we got one, although we should always have one at this point */ if (stealState != NULL) { //flag this as stopping, so it will get shut off stealState->state = EAS_STATE_STOPPING; } } /* if there are no available open streams (we won't likely see this, due to stealing) */ if (foundState == NULL) return NULL; /* save info */ foundState->startOrder = youngest + 1; foundState->fileHandle = fileHandle; foundState->pCallback = pCallbackFunc; foundState->cbInstData = cbInstData; return foundState; #else /* find an empty slot*/ for (i = 0; i < MAX_PCM_STREAMS; i++) { pState = &pEASData->pPCMStreams[i]; if (pState->fileHandle != NULL) continue; pState->fileHandle = fileHandle; pState->pCallback = pCallbackFunc; pState->cbInstData = cbInstData; return pState; } return NULL; #endif } #ifdef _LOOKUP_SAMPLE_RATE /*---------------------------------------------------------------------------- * CalcBaseFreq() *---------------------------------------------------------------------------- * Purpose: * Calculates the fractional phase increment for the sample rate converter * * Inputs: * sampleRate - sample rate in samples/sec * * Outputs: * Returns fractional sample rate with a 15-bit fraction * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate) { EAS_INT i; /* look up the conversion rate */ for (i = 0; i < (EAS_INT)(SRC_CONV_RATE_ENTRIES); i ++) { if (srcConvRate[i][0] == sampleRate) return srcConvRate[i][1]; } /* if not found in table, do it the long way */ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Sample rate %u not in table, calculating by division\n", sampleRate); */ } return (SRC_RATE_MULTIPLER * (EAS_U32) sampleRate) >> 15; } #endif /*---------------------------------------------------------------------------- * InitPCMStream() *---------------------------------------------------------------------------- * Purpose: * Start an ADPCM stream playback. Decodes the header, preps the engine. * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState) { /* initialize the data structure */ pState->bytesLeft = pState->byteCount; pState->phase = 0; pState->srcByte = 0; pState->decoderL.acc = 0; pState->decoderL.output = 0; pState->decoderL.x0 = pState->decoderL.x1 = 0; pState->decoderL.step = 0; pState->decoderR.acc = 0; pState->decoderR.output = 0; pState->decoderR.x0 = pState->decoderR.x1 = 0; pState->decoderR.step = 0; pState->hiNibble = EAS_FALSE; pState->pitch = 0; pState->blockCount = 0; pState->gainLeft = PCM_DEFAULT_GAIN_SETTING; // pState->currentGainLeft = PCM_DEFAULT_GAIN_SETTING; pState->envValue = 0; pState->envState = PCM_ENV_START; #if (NUM_OUTPUT_CHANNELS == 2) pState->gainRight = PCM_DEFAULT_GAIN_SETTING; // pState->currentGainRight = PCM_DEFAULT_GAIN_SETTING; #endif pState->state = EAS_STATE_READY; /* initialize the decoder */ if (pState->pDecoder->pfInit) return (*pState->pDecoder->pfInit)(pEASData, pState); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RenderPCMStream() *---------------------------------------------------------------------------- * Purpose: * Decodes a buffer of ADPCM data. * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples) { EAS_RESULT result; EAS_U32 phaseInc; EAS_I32 gainLeft, gainIncLeft; EAS_I32 *pOut; EAS_I32 temp; EAS_U32 utemp; #if (NUM_OUTPUT_CHANNELS == 2) EAS_I32 gainRight, gainIncRight; #endif #if 0 printf("env data: AR = %d, DR = %d, SL = %d, SR = %d, RR = %d\n", ((pState->envData >> 12) & 0x0F), ((pState->envData >> 16) & 0x0F), ((pState->envData >> 8) & 0x0F), ((pState->envData >> 28) & 0x0F), ((pState->envData >> 20) & 0x0F)); #endif if (pState->envState == PCM_ENV_START) { //printf("env start\n"); utemp = ((pState->envData >> 12) & 0x0F); //if fastest rate, attack is already completed //do the same for slowest rate, since that allows zero to be passed for default envelope if (utemp == 0x0F || utemp == 0x00) { //start envelope at full pState->envValue = (32768<<7); //jump right into decay utemp = ((pState->envData >> 16) & 0x0F); pState->envScale = getDecayScale(utemp); pState->envState = PCM_ENV_DECAY; pState->currentGainLeft = (EAS_I16) FMUL_15x15(pState->gainLeft, pState->volume); pState->currentGainRight = (EAS_I16) FMUL_15x15(pState->gainRight, pState->volume); } //else attack has a ramp else { //start the envelope very low pState->envValue = (2<<7); pState->currentGainLeft = 0; pState->currentGainRight = 0; //get envelope attack scaling value pState->envScale = getAttackIncrement(utemp); //go to attack state pState->envState = PCM_ENV_ATTACK; } } if (pState->envState == PCM_ENV_ATTACK) { //printf("env attack, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale); //update envelope value pState->envValue = pState->envValue + (pState->envScale << 7); //check envelope level and update state if needed if (pState->envValue >= (32768<<7)) { pState->envValue = (32768<<7); utemp = ((pState->envData >> 16) & 0x0F); pState->envScale = getDecayScale(utemp); pState->envState = PCM_ENV_DECAY; } } else if (pState->envState == PCM_ENV_DECAY) { //printf("env decay, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale); //update envelope value pState->envValue = (pState->envValue * pState->envScale)>>9; //check envelope level against sustain level and update state if needed utemp = ((pState->envData >> 8) & 0x0F); if (utemp == (EAS_U32)0x0F) utemp = (2<<7); else { utemp = ((32769<<7) >> (utemp>>1)); } if (pState->envValue <= utemp) { utemp = ((pState->envData >> 28) & 0x0F); pState->envScale = getDecayScale(utemp); //getSustainScale(utemp); pState->envState = PCM_ENV_SUSTAIN; } } else if (pState->envState == PCM_ENV_SUSTAIN) { //printf("env sustain, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale); //update envelope value pState->envValue = (pState->envValue * pState->envScale)>>9; //check envelope level against bottom level and update state if needed if (pState->envValue <= (2<<7)) { //no more decay pState->envScale = 512; pState->envState = PCM_ENV_END; } } else if (pState->envState == PCM_ENV_RELEASE) { //printf("env release, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale); //update envelope value pState->envValue = (pState->envValue * pState->envScale)>>9; //check envelope level against bottom level and update state if needed if (pState->envValue <= (2<<7)) { //no more decay pState->envScale = 512; pState->envState = PCM_ENV_END; } } else if (pState->envState == PCM_ENV_END) { //printf("env end\n"); /* set state to stopping, already ramped down */ pState->state = EAS_STATE_STOPPING; } //pState->gainLeft = (EAS_U16)((pState->gainLeft * (pState->envValue>>7))>>15); //pState->gainRight = (EAS_U16)((pState->gainRight * (pState->envValue>>7))>>15); /* gain to 32-bits to increase resolution on anti-zipper filter */ /*lint -e{703} use shift for performance */ gainLeft = (EAS_I32) pState->currentGainLeft << SYNTH_UPDATE_PERIOD_IN_BITS; #if (NUM_OUTPUT_CHANNELS == 2) /*lint -e{703} use shift for performance */ gainRight = (EAS_I32) pState->currentGainRight << SYNTH_UPDATE_PERIOD_IN_BITS; #endif /* calculate a new gain increment, gain target is zero if pausing */ if ((pState->state == EAS_STATE_PAUSING) || (pState->state == EAS_STATE_PAUSED)) { gainIncLeft = -pState->currentGainLeft; #if (NUM_OUTPUT_CHANNELS == 2) gainIncRight= -pState->currentGainRight; #endif } else { EAS_I32 gain = FMUL_15x15(pState->envValue >> 7, pState->volume); gainIncLeft = FMUL_15x15(pState->gainLeft, gain) - pState->currentGainLeft; #if (NUM_OUTPUT_CHANNELS == 2) gainIncRight = FMUL_15x15(pState->gainRight, gain) - pState->currentGainRight; #endif } /* calculate phase increment */ phaseInc = pState->basefreq; /* convert pitch cents to linear multiplier */ if (pState->pitch) { temp = EAS_Calculate2toX(pState->pitch); phaseInc = FMUL_15x15(phaseInc, temp); } phaseInc = phaseInc << pState->rateShift; /* pointer to mix buffer */ pOut = pEASData->pMixBuffer; /* render a buffer of samples */ while (numSamples--) { /* interpolate an output sample */ pState->decoderL.output = pState->decoderL.x0 + FMUL_15x15((pState->decoderL.x1 - pState->decoderL.x0), pState->phase & PHASE_FRAC_MASK); /* stereo output */ #if (NUM_OUTPUT_CHANNELS == 2) /* stereo stream? */ if (pState->flags & PCM_FLAGS_STEREO) pState->decoderR.output = pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK); /* gain scale and mix */ /*lint -e{704} use shift instead of division */ *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS; gainLeft += gainIncLeft; /*lint -e{704} use shift instead of division */ if (pState->flags & PCM_FLAGS_STEREO) *pOut++ += (pState->decoderR.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS; else *pOut++ += (pState->decoderL.output * (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS; gainRight += gainIncRight; /* mono output */ #else /* if stereo stream, decode right channel and mix to mono */ if (pState->flags & PCM_FLAGS_STEREO) { pState->decoderR.output= pState->decoderR.x0 + FMUL_15x15((pState->decoderR.x1 - pState->decoderR.x0), pState->phase & PHASE_FRAC_MASK); /* for mono, sum stereo ADPCM to mono */ /*lint -e{704} use shift instead of division */ *pOut++ += ((pState->decoderL.output + pState->decoderR.output) * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS; } else /*lint -e{704} use shift instead of division */ *pOut++ += (pState->decoderL.output * (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS)) >> PCM_MIXER_GUARD_BITS; gainLeft += gainIncLeft; #endif /* advance phase accumulator */ pState->phase += phaseInc; /* if integer part of phase accumulator is non-zero, advance to next sample */ while (pState->phase & ~PHASE_FRAC_MASK) { pState->decoderL.x0 = pState->decoderL.x1; pState->decoderR.x0 = pState->decoderR.x1; /* give the source a chance to continue the stream */ if (!pState->bytesLeft && pState->pCallback && ((pState->flags & PCM_FLAGS_EMPTY) == 0)) { pState->flags |= PCM_FLAGS_EMPTY; (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY); { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "RenderPCMStream: After empty callback, bytesLeft = %d\n", pState->bytesLeft); */ } } /* decode the next sample */ if ((result = (*pState->pDecoder->pfDecodeSample)(pEASData, pState)) != EAS_SUCCESS) return result; /* adjust phase by one sample */ pState->phase -= (1L << NUM_PHASE_FRAC_BITS); } } /* save new gain */ /*lint -e{704} use shift instead of division */ pState->currentGainLeft = (EAS_I16) (gainLeft >> SYNTH_UPDATE_PERIOD_IN_BITS); #if (NUM_OUTPUT_CHANNELS == 2) /*lint -e{704} use shift instead of division */ pState->currentGainRight = (EAS_I16) (gainRight >> SYNTH_UPDATE_PERIOD_IN_BITS); #endif /* if pausing, set new state and notify */ if (pState->state == EAS_STATE_PAUSING) { pState->state = EAS_STATE_PAUSED; if (pState->pCallback) (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state); } /* if out of data, set stopped state and notify */ if (pState->bytesLeft == 0 || pState->state == EAS_STATE_STOPPING) { pState->state = EAS_STATE_STOPPED; /* do callback unless the file has already been closed */ if (pState->pCallback && pState->fileHandle) (*pState->pCallback)(pEASData, pState->cbInstData, pState, pState->state); } if (pState->state == EAS_STATE_READY) pState->state = EAS_STATE_PLAY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * LinearPCMDecode() *---------------------------------------------------------------------------- * Purpose: * Decodes a PCM sample * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState) { EAS_RESULT result; EAS_HW_DATA_HANDLE hwInstData; hwInstData = ((S_EAS_DATA*) pEASData)->hwInstData; /* if out of data, check for loop */ if ((pState->bytesLeft == 0) && (pState->loopSamples != 0)) { if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS) return result; pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop; pState->flags &= ~PCM_FLAGS_EMPTY; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "LinearPCMDecode: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ } } if (pState->bytesLeft) { /* check format byte for 8-bit samples */ if (pState->flags & PCM_FLAGS_8_BIT) { /* fetch left or mono sample */ if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS) return result; /* if unsigned */ if (pState->flags & PCM_FLAGS_UNSIGNED) { /*lint -e{734} converting unsigned 8-bit to signed 16-bit */ pState->decoderL.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000); } else { /*lint -e{734} converting signed 8-bit to signed 16-bit */ pState->decoderL.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8); } pState->bytesLeft--; /* fetch right sample */ if(pState->flags & PCM_FLAGS_STEREO) { if ((result = EAS_HWGetByte(hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS) return result; /* if unsigned */ if (pState->flags & PCM_FLAGS_UNSIGNED) { /*lint -e{734} converting unsigned 8-bit to signed 16-bit */ pState->decoderR.x1 = (EAS_PCM)(((EAS_PCM) pState->srcByte << 8) ^ 0x8000); } else { /*lint -e{734} converting signed 8-bit to signed 16-bit */ pState->decoderR.x1 = (EAS_PCM)((EAS_PCM) pState->srcByte << 8); } pState->bytesLeft--; } } /* must be 16-bit samples */ else { //unsigned 16 bit currently not supported if (pState->flags & PCM_FLAGS_UNSIGNED) { return EAS_ERROR_INVALID_PCM_TYPE; } /* fetch left or mono sample */ if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderL.x1, EAS_FALSE)) != EAS_SUCCESS) return result; pState->bytesLeft -= 2; /* fetch right sample */ if(pState->flags & PCM_FLAGS_STEREO) { if ((result = EAS_HWGetWord(hwInstData, pState->fileHandle, &pState->decoderR.x1, EAS_FALSE)) != EAS_SUCCESS) return result; pState->bytesLeft -= 2; } } } /* no more data, force zero samples */ else pState->decoderL.x1 = pState->decoderR.x1 = 0; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * LinearPCMLocate() *---------------------------------------------------------------------------- * Purpose: * Locate in a linear PCM stream *---------------------------------------------------------------------------- */ static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time) { EAS_RESULT result; EAS_I32 temp; EAS_I32 secs, msecs; EAS_INT shift; /* calculate size of sample frame */ if (pState->flags & PCM_FLAGS_8_BIT) shift = 0; else shift = 1; if (pState->flags & PCM_FLAGS_STEREO) shift++; /* break down into secs and msecs */ secs = time / 1000; msecs = time - (secs * 1000); /* calculate sample number fraction from msecs */ temp = (msecs * pState->sampleRate); temp = (temp >> 10) + ((temp * 49) >> 21); /* add integer sample count */ temp += secs * pState->sampleRate; /* calculate the position based on sample frame size */ /*lint -e{703} use shift for performance */ temp <<= shift; /* past end of sample? */ if (temp > (EAS_I32) pState->loopStart) { /* if not looped, flag error */ if (pState->loopSamples == 0) { pState->bytesLeft = 0; pState->flags |= PCM_FLAGS_EMPTY; return EAS_ERROR_LOCATE_BEYOND_END; } /* looped sample - calculate position in loop */ while (temp > (EAS_I32) pState->loopStart) temp -= (EAS_I32) pState->loopStart; } /* seek to new position */ if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS) return result; /* reset state */ if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED)) pState->state = EAS_STATE_READY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_PESeek *---------------------------------------------------------------------------- * Purpose: * Locate to a particular byte in a PCM stream *---------------------------------------------------------------------------- * This bit is tricky because the chunks may not be contiguous, * so we have to rely on the parser to position in the file. We * do this by seeking to the end of each chunk and simulating an * empty buffer condition until we get to where we want to go. * * A better solution would be a parser API for re-positioning, * but there isn't time at the moment to re-factor all the * parsers to support a new API. *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PESeek (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation) { EAS_RESULT result; /* seek to start of audio */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS) { pState->state = EAS_STATE_ERROR; return result; } pState->bytesLeft = pState->bytesLeftLoop; /* skip through chunks until we find the right chunk */ while (*pLocation > (EAS_I32) pState->bytesLeft) { /* seek to end of audio chunk */ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", pState->bytesLeft); */ } if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, pState->bytesLeft)) != EAS_SUCCESS) { pState->state = EAS_STATE_ERROR; return result; } *pLocation -= pState->bytesLeft; pState->bytesLeft = 0; pState->flags |= PCM_FLAGS_EMPTY; /* retrieve more data */ if (pState->pCallback) (*pState->pCallback)(pEASData, pState->cbInstData, pState, EAS_STATE_EMPTY); { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: bytesLeft=%d, byte location = %d\n", pState->bytesLeft, *pLocation); */ } /* no more samples */ if (pState->bytesLeft == 0) return EAS_ERROR_LOCATE_BEYOND_END; } /* seek to new offset in current chunk */ if (*pLocation > 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PESeek: Seek to offset = %d\n", *pLocation); */ } if ((result = EAS_HWFileSeekOfs(pEASData->hwInstData, pState->fileHandle, *pLocation)) != EAS_SUCCESS) { pState->state = EAS_STATE_ERROR; return result; } /* if not streamed, calculate number of bytes left */ if (pState->flags & PCM_FLAGS_STREAMING) pState->bytesLeft = 0x7fffffff; else pState->bytesLeft -= *pLocation; } return EAS_SUCCESS; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_mididata.c0000644000000000000000000000013214200302440026651 xustar0030 mtime=1644266784.813324173 30 atime=1644266784.969324273 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_mididata.c0000644000175000001440000000212314200302440027430 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_mididata.c * * Contents and purpose: * Data module for MIDI stream interface * * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 547 $ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $ *---------------------------------------------------------------------------- */ #include "eas_miditypes.h" S_INTERACTIVE_MIDI eas_MIDIData; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_pan.c0000644000000000000000000000013214200302440025653 xustar0030 mtime=1644266784.805324168 30 atime=1644266784.969324273 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_pan.c0000644000175000001440000000572314200302440026443 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_pan.c * * Contents and purpose: * Calculates left and right gain multipliers based on a pan value from -63 to +63 * * NOTES: * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine * whether the parser works for those particular file formats. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #include "eas_pan.h" #include "eas_math.h" /*---------------------------------------------------------------------------- * EAS_CalcPanControl() *---------------------------------------------------------------------------- * Purpose: * Assign the left and right gain values corresponding to the given pan value. * * This routine uses sin/cos approximations for an equal power curve: * * sin(x) = (2-4*c)*x^2 + c + x * cos(x) = (2-4*c)*x^2 + c - x * * where c = 1/sqrt(2) * using the a0 + x*(a1 + x*a2) approach * * Inputs: * pan - pan value (-63 to + 63) * * Outputs: * pGainLeft linear gain multiplier for left channel (15-bit fraction) * pGainRight linear gain multiplier for left channel (15-bit fraction) * * Side Effects: *---------------------------------------------------------------------------- */ void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight) { EAS_INT temp; EAS_INT netAngle; /* impose hard limit */ if (pan < -63) netAngle = -63; else if (pan > 63) netAngle = 63; else netAngle = pan; /*lint -e{701} */ netAngle = netAngle << 8; /* calculate sin */ temp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle); temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle); if (temp > SYNTH_FULL_SCALE_EG1_GAIN) temp = SYNTH_FULL_SCALE_EG1_GAIN; else if (temp < 0) temp = 0; *pGainRight = (EAS_I16) temp; /* calculate cos */ temp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle); temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle); if (temp > SYNTH_FULL_SCALE_EG1_GAIN) temp = SYNTH_FULL_SCALE_EG1_GAIN; else if (temp < 0) temp = 0; *pGainLeft = (EAS_I16) temp; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/wt_22khz.c0000644000000000000000000000013214200302440025717 xustar0030 mtime=1644266784.809324171 30 atime=1644266784.969324273 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/wt_22khz.c0000644000175000001440001266473414200302440026527 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * Filename: wt_200k_G.c * Source: wt_200k_G.dls * CmdLine: -w wt_200k_G.c -l wt_200k_G.log -ce -cf wt_200k_G.dls -w -l -ce -cf wt_200k_G.dls * Purpose: Wavetable sound libary * * Copyright (c) 2009 Sonic Network Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 960 $ * $Date: 2009-03-18 15:08:29 -0500 (Wed, 18 Mar 2009) $ *---------------------------------------------------------------------------- */ #include "eas_sndlib.h" /*---------------------------------------------------------------------------- * Articulations *---------------------------------------------------------------------------- */ const S_ARTICULATION eas_articulations[] = { { /* articulation 0 */ { 32767, 30725, 0, 30725 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 1 */ { 32767, 26863, 0, 26863 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 2 */ { 32767, 30484, 0, 30668 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 3 */ { 32767, 26439, 0, 26439 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 4 */ { 32767, 0, 32767, 32715 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 5 */ { 32767, 21333, 0, 21333 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 6 */ { 32767, 31882, 0, 31938 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 7 */ { 32767, 32663, 32767, 32663 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 8 */ { 32767, 0, 32767, 0 }, { 32767, 1902, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 9 */ { 32767, 32349, 0, 32349 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 10 */ { 32767, 0, 32767, 17213 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -1 }, { /* articulation 11 */ { 32767, 31730, 0, 31730 }, { 32767, 761, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -44 }, { /* articulation 12 */ { 32767, 23749, 0, 23749 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 56 }, { /* articulation 13 */ { 32767, 31730, 0, 31730 }, { 32767, 761, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -31 }, { /* articulation 14 */ { 9511, 21333, 0, 21333 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 56 }, { /* articulation 15 */ { 32767, 31617, 0, 31617 }, { 32767, 761, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -6 }, { /* articulation 16 */ { 32767, 32123, 0, 32194 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 56 }, { /* articulation 17 */ { 32767, 31550, 0, 31550 }, { 32767, 761, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 6 }, { /* articulation 18 */ { 32767, 31391, 0, 31391 }, { 32767, 951, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 31 }, { /* articulation 19 */ { 32767, 31964, 0, 31964 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 25 }, { /* articulation 20 */ { 32767, 31056, 0, 31056 }, { 32767, 951, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 63 }, { /* articulation 21 */ { 32767, 32289, 0, 32271 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -37 }, { /* articulation 22 */ { 19021, 31882, 0, 31911 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -37 }, { /* articulation 23 */ { 32767, 31988, 0, 32032 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -37 }, { /* articulation 24 */ { 32767, 0, 32767, 32663 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 12 }, { /* articulation 25 */ { 32767, 31352, 0, 31352 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -25 }, { /* articulation 26 */ { 32767, 0, 32767, 32663 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 25 }, { /* articulation 27 */ { 32767, 31817, 0, 31781 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -25 }, { /* articulation 28 */ { 32767, 30725, 0, 30725 }, { 32767, 95, 0, 0 }, 0, 0, 951, 240, 0, 0, 0, 0, -56 }, { /* articulation 29 */ { 32767, 32230, 0, 32218 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -37 }, { /* articulation 30 */ { 32767, 26439, 0, 26439 }, { 32767, 3804, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 50 }, { /* articulation 31 */ { 32767, 23749, 0, 23749 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -50 }, { /* articulation 32 */ { 32767, 29434, 0, 29434 }, { 32767, 3804, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -50 }, { /* articulation 33 */ { 32767, 30240, 0, 30234 }, { 32767, 3804, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -44 }, { /* articulation 34 */ { 32767, 32558, 0, 32558 }, { 32767, 254, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 25 }, { /* articulation 35 */ { 32767, 0, 32767, 32663 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -63 }, { /* articulation 36 */ { 3804, 23749, 0, 23749 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -63 }, { /* articulation 37 */ { 32767, 23749, 0, 23749 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -59 }, { /* articulation 38 */ { 32767, 30725, 0, 30725 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 50 }, { /* articulation 39 */ { 32767, 28809, 0, 28809 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 44 }, { /* articulation 40 */ { 1902, 30725, 0, 30725 }, { 32767, 380, 0, 0 }, 0, 0, 951, -100, 0, 0, 0, 0, 44 }, { /* articulation 41 */ { 32767, 9042, 0, 9042 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 25 }, { /* articulation 42 */ { 32767, 29889, 0, 29889 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 63 }, { /* articulation 43 */ { 32767, 30240, 0, 30234 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 63 }, { /* articulation 44 */ { 19021, 19970, 0, 19970 }, { 951, 32767, 32767, 0 }, 0, 0, 951, 100, 0, 0, 0, 0, -25 }, { /* articulation 45 */ { 3804, 17213, 0, 17213 }, { 951, 32767, 32767, 0 }, 0, 0, 951, 500, 0, 0, 0, 0, -25 }, { /* articulation 46 */ { 32767, 17213, 0, 17213 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -56 }, { /* articulation 47 */ { 32767, 30725, 0, 30725 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, -56 }, { /* articulation 48 */ { 32767, 0, 32767, 0 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 49 */ { 32767, 31180, 0, 31180 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 50 */ { 19021, 31964, 0, 32071 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 51 */ { 32767, 29669, 0, 29669 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 52 */ { 32767, 31742, 0, 31352 }, { 32767, 294, 0, 0 }, 0, 0, 951, 0, 10000, 7121, 0, 0, 0 }, { /* articulation 53 */ { 32767, 0, 32767, 31391 }, { 32767, 32767, 32767, 0 }, 0, 0, 1555, 0, -2300, 11920, 0, 0, 0 }, { /* articulation 54 */ { 1174, 0, 32767, 31988 }, { 32767, 127, 0, 0 }, 0, 0, 1555, 0, 2000, 10721, 0, 8, 15 }, { /* articulation 55 */ { 1174, 0, 32767, 31988 }, { 951, 127, 0, 0 }, 0, 0, 1555, 0, 2000, 9023, 0, 5, 15 }, { /* articulation 56 */ { 7608, 0, 32767, 30237 }, { 32767, 69, 5898, 0 }, 0, 0, 1555, 0, 6000, 9080, 0, 0, -2 }, { /* articulation 57 */ { 32767, 0, 32767, 29337 }, { 32767, 32767, 32767, 0 }, 0, 0, 1555, 0, 0, 0, 0, 0, 1 }, { /* articulation 58 */ { 5141, 0, 32767, 30194 }, { 32767, 32767, 32767, 0 }, 0, 0, 1555, 0, 0, 0, 0, 0, 0 }, { /* articulation 59 */ { 32767, 32558, 0, 26439 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 60 */ { 32767, 32349, 0, 26439 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 61 */ { 32767, 32072, 0, 32072 }, { 32767, 95, 0, 0 }, 0, 34, 989, 0, 2400, 9521, 0, 0, 0 }, { /* articulation 62 */ { 32767, 30234, 0, 30234 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 11738, 0, 16, 0 }, { /* articulation 63 */ { 32767, 32349, 0, 30073 }, { 32767, 634, 0, 0 }, 0, 34, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 64 */ { 32767, 31730, 0, 31476 }, { 32767, 634, 0, 0 }, 0, 34, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 65 */ { 32767, 32418, 0, 25329 }, { 32767, 95, 0, 0 }, 0, 34, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 66 */ { 32767, 32052, 0, 31964 }, { 32767, 634, 0, 0 }, 0, 34, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 67 */ { 32767, 31938, 0, 31938 }, { 32767, 634, 0, 0 }, 0, 34, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 68 */ { 9511, 32663, 18820, 23749 }, { 1902, 57, 13107, 0 }, 0, 0, 989, 0, 6000, 5535, 0, 4, 0 }, { /* articulation 69 */ { 32767, 31754, 0, 31730 }, { 32767, 1902, 0, 0 }, 0, 52, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 70 */ { 127, 32686, 3811, 32349 }, { 95, 38, 32767, 0 }, 0, 0, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 71 */ { 4755, 32663, 3566, 28809 }, { 3804, 32767, 32767, 0 }, 0, 0, 989, 100, 0, 11919, 0, 0, 0 }, { /* articulation 72 */ { 32767, 31935, 0, 31935 }, { 32767, 335, 0, 0 }, 0, 17, 989, 0, 7000, 9023, 0, 0, 0 }, { /* articulation 73 */ { 32767, 31391, 0, 31391 }, { 32767, 335, 0, 0 }, 0, 2, 951, 0, 7000, 9023, 0, 0, 0 }, { /* articulation 74 */ { 32767, 32628, 6208, 31935 }, { 380, 95, 0, 0 }, 0, 0, 989, 0, 3840, 8302, 0, 8, 0 }, { /* articulation 75 */ { 32767, 32072, 0, 32171 }, { 32767, 380, 0, 0 }, 0, 0, 989, 0, 5000, 8321, 0, 0, 0 }, { /* articulation 76 */ { 32767, 31935, 0, 31935 }, { 32767, 380, 0, 0 }, 0, 0, 951, 0, 5000, 7934, 0, 0, 0 }, { /* articulation 77 */ { 32767, 32117, 0, 30685 }, { 32767, 63, 0, 0 }, 0, 17, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 78 */ { 32767, 32245, 0, 23749 }, { 32767, 1902, 0, 0 }, 0, 172, 989, 0, 1000, 11107, 0, 0, 0 }, { /* articulation 79 */ { 32767, 32663, 6208, 31935 }, { 95, 95, 0, 0 }, 0, 34, 1622, 0, 3560, 8834, 1, 8, 0 }, { /* articulation 80 */ { 32767, 32362, 0, 26439 }, { 32767, 190, 0, 0 }, 0, 17, 989, 0, 6000, 9907, 0, 0, 0 }, { /* articulation 81 */ { 32767, 32245, 0, 23749 }, { 32767, 63, 0, 0 }, 0, 17, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 82 */ { 32767, 31730, 18820, 9042 }, { 32767, 32767, 32767, 0 }, 0, 17, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 83 */ { 32767, 32715, 128, 32168 }, { 32767, 127, 0, 0 }, 0, 0, 989, 0, 0, 11920, 0, 8, 0 }, { /* articulation 84 */ { 32767, 32072, 0, 32072 }, { 32767, 67, 0, 0 }, 3, 0, 572, 0, 5000, 5535, 0, 0, 0 }, { /* articulation 85 */ { 3804, 32663, 18820, 23749 }, { 32767, 2024, 0, 0 }, 10, 34, 1008, -30, 0, 0, 0, 0, 0 }, { /* articulation 86 */ { 19021, 32663, 18820, 23749 }, { 761, 95, 0, 0 }, 0, 34, 989, 0, 4473, 7131, 0, 8, 0 }, { /* articulation 87 */ { 1902, 32628, 6208, 32171 }, { 634, 38, 16384, 0 }, 0, 0, 989, 0, 2987, 7877, 0, 12, 0 }, { /* articulation 88 */ { 32767, 32593, 0, 31935 }, { 32767, 95, 0, 0 }, 0, 0, 1162, 0, 4053, 7930, 2, 12, 0 }, { /* articulation 89 */ { 380, 32684, 6208, 31935 }, { 32767, 112, 0, 0 }, 0, 0, 989, 0, 0, 8887, 0, 0, 0 }, { /* articulation 90 */ { 19021, 32663, 18820, 23749 }, { 1268, 95, 0, 0 }, 0, 34, 989, 0, 5113, 7981, 0, 4, 0 }, { /* articulation 91 */ { 1902, 32663, 6208, 30725 }, { 1902, 127, 0, 0 }, 0, 34, 989, 0, 3500, 7877, 0, 5, 0 }, { /* articulation 92 */ { 1902, 32663, 6208, 30725 }, { 1268, 95, 0, 0 }, 0, 34, 951, 0, 4773, 8355, 0, 5, 0 }, { /* articulation 93 */ { 476, 32663, 10809, 31935 }, { 32767, 32767, 32767, 0 }, 0, 34, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 94 */ { 3804, 32663, 18820, 30234 }, { 32767, 32767, 32767, 0 }, 0, 34, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 95 */ { 7608, 32663, 18820, 17213 }, { 2536, 261, 0, 0 }, 0, 34, 989, 0, 1200, 11690, 0, 4, 0 }, { /* articulation 96 */ { 32767, 32468, 15076, 30234 }, { 32767, 32767, 32767, 0 }, 0, 36, 2183, 0, 0, 11919, 1, 0, 0 }, { /* articulation 97 */ { 32767, 0, 32767, 32663 }, { 380, 32767, 32767, 0 }, 0, 0, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 98 */ { 32767, 31391, 0, 31391 }, { 32767, 634, 0, 0 }, 0, 0, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 99 */ { 32767, 32558, 0, 23749 }, { 1268, 190, 13107, 0 }, 0, 34, 989, 0, 3200, 8321, 0, 0, 0 }, { /* articulation 100 */ { 32767, 0, 32767, 0 }, { 32767, 32767, 32767, 0 }, 0, 0, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 101 */ { 32767, 32072, 0, 23749 }, { 32767, 1087, 0, 0 }, 0, 34, 989, 0, 8187, 5535, 0, 5, 0 }, { /* articulation 102 */ { 32767, 32558, 0, 29434 }, { 32767, 190, 7667, 0 }, 5, 0, 989, 0, 6053, 5535, 0, 5, 0 }, { /* articulation 103 */ { 32767, 32663, 18820, 23749 }, { 1902, 95, 0, 0 }, 0, 0, 989, 0, 2700, 9852, 0, 0, 0 }, { /* articulation 104 */ { 32767, 32663, 18820, 27897 }, { 1902, 95, 0, 0 }, 0, 0, 989, 0, 2700, 9852, 0, 0, 0 }, { /* articulation 105 */ { 32767, 32663, 18820, 23749 }, { 32767, 1268, 0, 0 }, 0, 52, 951, 0, 2500, 10490, 1, 8, 0 }, { /* articulation 106 */ { 32767, 32663, 23493, 23749 }, { 32767, 380, 0, 0 }, 0, 34, 988, 0, 4000, 10223, 1, 4, 0 }, { /* articulation 107 */ { 32767, 32663, 18820, 27897 }, { 32767, 126, 7667, 0 }, 0, 0, 989, 0, 1813, 9154, 0, 0, 0 }, { /* articulation 108 */ { 32767, 31730, 0, 31730 }, { 32767, 380, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 109 */ { 32767, 31180, 0, 30484 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 11690, 0, 0, 0 }, { /* articulation 110 */ { 32767, 30725, 0, 30725 }, { 32767, 380, 0, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 111 */ { 32767, 32349, 18820, 27897 }, { 32767, 95, 0, 0 }, 12, 34, 951, 0, 3000, 10223, 0, 0, 0 }, { /* articulation 112 */ { 32767, 32349, 18820, 27897 }, { 32767, 63, 0, 0 }, 12, 34, 951, 0, 1900, 10031, 0, 0, 0 }, { /* articulation 113 */ { 32767, 32663, 18820, 26439 }, { 32767, 63, 0, 0 }, 12, 34, 988, 0, 1000, 11107, 0, 0, 0 }, { /* articulation 114 */ { 32767, 32663, 18820, 26439 }, { 32767, 63, 0, 0 }, 12, 34, 988, 0, 2000, 11107, 0, 0, 0 }, { /* articulation 115 */ { 32767, 32505, 0, 26439 }, { 32767, 190, 0, 0 }, 0, 17, 989, 0, 4000, 8321, 0, 0, 0 }, { /* articulation 116 */ { 32767, 31832, 19893, 9042 }, { 32767, 476, 0, 0 }, 0, 34, 1452, 0, 0, 11919, 0, 0, 0 }, { /* articulation 117 */ { 19021, 32072, 23493, 9042 }, { 32767, 32767, 32767, 0 }, 0, 34, 1355, 0, 0, 11877, 1, 0, 0 }, { /* articulation 118 */ { 32767, 32468, 0, 23749 }, { 32767, 190, 0, 0 }, 0, 34, 989, 0, 3500, 9023, 0, 0, 0 }, { /* articulation 119 */ { 32767, 17213, 23493, 0 }, { 32767, 32767, 32767, 0 }, 0, 17, 1521, 0, 0, 10925, 1, 0, 0 }, { /* articulation 120 */ { 32767, 32505, 0, 26439 }, { 32767, 190, 0, 0 }, 0, 52, 989, 0, 3200, 8721, 0, 4, 0 }, { /* articulation 121 */ { 3804, 32663, 18820, 23749 }, { 32767, 32767, 32767, 0 }, 0, 34, 989, 0, 0, 0, 1, 0, 0 }, { /* articulation 122 */ { 9511, 32663, 18820, 25329 }, { 32767, 32767, 32767, 0 }, 0, 34, 989, 0, 0, 11877, 0, 8, 0 }, { /* articulation 123 */ { 32767, 32663, 18820, 23749 }, { 32767, 32, 0, 0 }, 0, 17, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 124 */ { 32767, 32558, 0, 23749 }, { 32767, 380, 0, 0 }, 0, 34, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 125 */ { 32767, 32663, 18820, 23749 }, { 32767, 24, 0, 0 }, 0, 17, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 126 */ { 32767, 30725, 0, 30725 }, { 32767, 761, 0, 0 }, 0, 0, 989, 0, 3000, 10223, 0, 8, 0 }, { /* articulation 127 */ { 127, 0, 32767, 32349 }, { 32767, 32767, 32767, 0 }, 0, 0, 1522, 0, 0, 11423, 4, 0, 0 }, { /* articulation 128 */ { 951, 32422, 0, 32387 }, { 32767, 19, 0, 0 }, 0, 0, 989, 0, 0, 11423, 0, 0, 0 }, { /* articulation 129 */ { 391, 0, 0, 31180 }, { 190, 32767, 32767, 0 }, 0, 0, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 130 */ { 32767, 30725, 0, 30725 }, { 32767, 761, 0, 0 }, 0, 0, 989, 1200, 0, 0, 0, 0, 0 }, { /* articulation 131 */ { 32767, 31730, 0, 31935 }, { 32767, 380, 0, 0 }, 0, 0, 989, 50, 0, 0, 0, 0, 0 }, { /* articulation 132 */ { 32767, 32072, 0, 32072 }, { 32767, 19021, 0, 0 }, 0, 0, 989, 0, 4700, 7769, 0, 0, 0 }, { /* articulation 133 */ { 32767, 30073, 0, 30073 }, { 32767, 32767, 0, 0 }, 0, 0, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 134 */ { 32767, 32558, 32767, 32558 }, { 32767, 32767, 32767, 0 }, 0, 0, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 135 */ { 32767, 32663, 18820, 17213 }, { 32767, 190, 0, 0 }, 10, 34, 951, 0, 2000, 10696, 0, 0, 0 }, { /* articulation 136 */ { 32767, 32663, 10809, 17213 }, { 32767, 190, 0, 0 }, 12, 34, 982, 0, 0, 10910, 0, 0, 0 }, { /* articulation 137 */ { 32767, 32663, 18820, 17213 }, { 32767, 190, 0, 0 }, 10, 34, 951, 0, 1200, 10218, 0, 0, 0 }, { /* articulation 138 */ { 32767, 32663, 18820, 17213 }, { 32767, 190, 0, 0 }, 10, 34, 951, 0, 1100, 9525, 0, 0, 0 }, { /* articulation 139 */ { 19021, 32558, 18820, 23749 }, { 32767, 19, 0, 0 }, 10, 34, 988, 0, 2000, 10962, 0, 0, 0 }, { /* articulation 140 */ { 32767, 32349, 18820, 23749 }, { 19021, 634, 0, 0 }, 10, 32, 1008, 0, 1200, 10090, 0, 0, 0 }, { /* articulation 141 */ { 2536, 0, 32767, 27897 }, { 1902, 380, 0, 0 }, 7, 34, 988, 0, 1620, 8933, 0, 0, 0 }, { /* articulation 142 */ { 32767, 32349, 10809, 23749 }, { 32767, 380, 0, 0 }, 7, 34, 988, 0, 2200, 8994, 0, 0, 0 }, { /* articulation 143 */ { 32767, 32663, 15076, 23749 }, { 32767, 1902, 0, 0 }, 10, 34, 982, 0, 2500, 9525, 0, 0, 0 }, { /* articulation 144 */ { 32767, 32663, 15076, 23749 }, { 32767, 190, 0, 0 }, 10, 34, 951, 0, 1500, 11423, 0, 0, 0 }, { /* articulation 145 */ { 32767, 32663, 18820, 23749 }, { 32767, 1902, 0, 0 }, 9, 34, 982, 0, 1500, 9521, 0, 0, 0 }, { /* articulation 146 */ { 3804, 0, 32767, 28809 }, { 32767, 32767, 32767, 0 }, 0, 0, 1521, 0, 0, 9521, 0, 0, 0 }, { /* articulation 147 */ { 32767, 32558, 0, 23749 }, { 32767, 19021, 0, 0 }, 0, 17, 989, 0, 5000, 10223, 0, 0, 0 }, { /* articulation 148 */ { 32767, 32663, 18820, 23749 }, { 32767, 63, 0, 0 }, 10, 34, 951, 0, 1500, 9907, 0, 0, 0 }, { /* articulation 149 */ { 32767, 32698, 11682, 23749 }, { 32767, 1902, 0, 0 }, 0, 34, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 150 */ { 32767, 32072, 0, 32072 }, { 32767, 380, 0, 0 }, 0, 17, 989, 0, 3440, 9260, 0, 0, 0 }, { /* articulation 151 */ { 32767, 30234, 0, 30725 }, { 32767, 1902, 0, 0 }, 0, 17, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 152 */ { 32767, 31730, 0, 30725 }, { 32767, 380, 0, 0 }, 0, 17, 989, 0, 4000, 7823, 0, 0, 0 }, { /* articulation 153 */ { 32767, 32558, 3566, 23749 }, { 783, 32767, 32767, 0 }, 100, 0, 1522, 500, 0, 11877, 0, 0, 0 }, { /* articulation 154 */ { 32767, 32663, 18820, 17213 }, { 32767, 1902, 0, 0 }, 8, 34, 989, -22, 0, 0, 0, 0, 0 }, { /* articulation 155 */ { 19021, 29007, 6784, 23749 }, { 32767, 1902, 0, 0 }, 0, 34, 951, 0, 5000, 9521, 1, 0, 0 }, { /* articulation 156 */ { 32767, 32558, 0, 31935 }, { 1902, 254, 16384, 0 }, 0, 52, 989, 0, 3627, 10547, 0, 5, 0 }, { /* articulation 157 */ { 3804, 0, 32767, 23749 }, { 1902, 1902, 0, 0 }, 0, 34, 989, 27, 0, 11919, 0, 0, 0 }, { /* articulation 158 */ { 32767, 0, 32767, 31730 }, { 76, 66, 10092, 0 }, 5, 0, 989, 0, 8007, 5535, 0, 8, 0 }, { /* articulation 159 */ { 32767, 32468, 0, 29434 }, { 32767, 127, 0, 0 }, 0, 52, 989, 0, 2500, 9032, 0, 0, 0 }, { /* articulation 160 */ { 9511, 32663, 10809, 25329 }, { 32767, 32767, 32767, 0 }, 0, 34, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 161 */ { 19021, 32558, 18820, 23749 }, { 32767, 190, 0, 0 }, 10, 34, 988, 0, 2600, 9513, 0, 0, 0 }, { /* articulation 162 */ { 32767, 32106, 9568, 23749 }, { 2348, 391, 0, 0 }, 10, 52, 980, 0, 6500, 9023, 0, 0, 0 }, { /* articulation 163 */ { 32767, 32558, 0, 26439 }, { 32767, 63, 0, 0 }, 0, 34, 989, 0, 0, 0, 0, 0, 0 }, { /* articulation 164 */ { 32767, 32072, 15076, 17213 }, { 32767, 1268, 0, 0 }, 0, 0, 951, 0, 2000, 10223, 0, 0, 0 }, { /* articulation 165 */ { 32767, 32558, 0, 23749 }, { 32767, 380, 0, 0 }, 0, 34, 989, 0, 3000, 9366, 0, 0, 0 }, { /* articulation 166 */ { 32767, 32663, 18820, 23749 }, { 1902, 127, 10879, 0 }, 0, 0, 989, 0, 6000, 7121, 0, 4, 0 }, { /* articulation 167 */ { 32767, 32505, 0, 26439 }, { 32767, 21, 0, 0 }, 0, 52, 989, 0, 3500, 6236, 0, 5, 0 }, { /* articulation 168 */ { 32767, 32505, 0, 26439 }, { 32767, 190, 0, 0 }, 0, 52, 989, 0, 2800, 7121, 0, 0, 0 }, { /* articulation 169 */ { 32767, 32418, 0, 29434 }, { 32767, 127, 0, 0 }, 0, 52, 989, 0, 2100, 9626, 0, 0, 0 }, { /* articulation 170 */ { 32767, 32349, 0, 30234 }, { 32767, 127, 0, 0 }, 0, 52, 989, 0, 3000, 9626, 0, 0, 0 }, { /* articulation 171 */ { 32767, 32288, 0, 28400 }, { 32767, 127, 0, 0 }, 0, 52, 989, 0, 1000, 9032, 0, 0, 0 }, { /* articulation 172 */ { 32767, 32072, 0, 28809 }, { 32767, 127, 0, 0 }, 0, 52, 989, 0, 1000, 9032, 0, 0, 0 }, { /* articulation 173 */ { 3804, 32072, 15076, 17213 }, { 32767, 1268, 0, 0 }, 0, 52, 991, 0, 0, 11107, 0, 8, 0 }, { /* articulation 174 */ { 32767, 32349, 15076, 23749 }, { 7608, 147, 0, 0 }, 0, 0, 989, 0, 4500, 9521, 0, 8, 0 }, { /* articulation 175 */ { 32767, 32663, 18820, 23749 }, { 32767, 95, 0, 0 }, 0, 0, 989, 0, 2000, 8321, 0, 8, 0 }, { /* articulation 176 */ { 32767, 32715, 128, 29669 }, { 32767, 1729, 0, 0 }, 0, 0, 989, 0, 6000, 7823, 0, 8, 0 }, { /* articulation 177 */ { 19021, 32448, 0, 31882 }, { 32767, 95, 0, 0 }, 0, 0, 989, 0, 4500, 7121, 0, 8, 0 }, { /* articulation 178 */ { 32767, 32560, 3646, 32107 }, { 32767, 190, 0, 0 }, 0, 0, 989, 0, 4000, 8321, 0, 8, 0 }, { /* articulation 179 */ { 32767, 32602, 13644, 26439 }, { 32767, 63, 0, 0 }, 12, 34, 988, 0, 2000, 11107, 0, 0, 0 }, { /* articulation 180 */ { 19021, 30484, 0, 23749 }, { 32767, 1902, 0, 0 }, 0, 0, 989, 0, 5000, 8321, 1, 0, 0 }, { /* articulation 181 */ { 261, 32466, 0, 31938 }, { 32767, 634, 0, 0 }, 0, 34, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 182 */ { 32767, 32418, 0, 31742 }, { 2348, 39, 0, 0 }, 0, 34, 989, 0, 3600, 7121, 0, 4, 0 }, { /* articulation 183 */ { 32767, 32090, 0, 32090 }, { 32767, 634, 0, 0 }, 0, 34, 951, 0, 0, 0, 0, 0, 0 }, { /* articulation 184 */ { 1669, 32715, 19242, 30194 }, { 32767, 296, 0, 0 }, 0, 0, 1555, 0, 3000, 9907, 0, 4, 0 } }; /*end Articulations */ /*---------------------------------------------------------------------------- * Regions *---------------------------------------------------------------------------- */ const S_WT_REGION eas_regions[] = { { { 0, 27, 27 }, -2868, 16422, 0, 0, 81, 0 }, /* region 0 */ { { 0, 28, 28 }, -3568, 32767, 0, 0, 40, 0 }, /* region 1 */ { { 0, 29, 29 }, -4553, 32767, 0, 0, 32, 1 }, /* region 2 */ { { 0, 30, 30 }, -4853, 32767, 0, 0, 32, 2 }, /* region 3 */ { { 0, 31, 31 }, -3868, 23197, 0, 0, 48, 3 }, /* region 4 */ { { 1536, 32, 32 }, -3200, 20675, 0, 0, 137, 4 }, /* region 5 */ { { 1537, 33, 33 }, -3703, 20675, 792, 879, 50, 5 }, /* region 6 */ { { 1537, 34, 34 }, -3803, 16422, 792, 879, 50, 6 }, /* region 7 */ { { 0, 35, 35 }, -4968, 32767, 0, 0, 83, 7 }, /* region 8 */ { { 0, 36, 36 }, -4968, 32767, 0, 0, 83, 7 }, /* region 9 */ { { 0, 37, 37 }, -4051, 18426, 0, 0, 53, 8 }, /* region 10 */ { { 0, 38, 38 }, -4151, 23197, 0, 0, 16, 9 }, /* region 11 */ { { 0, 39, 39 }, -3568, 32767, 0, 0, 40, 10 }, /* region 12 */ { { 0, 40, 40 }, -4151, 23197, 0, 0, 16, 4 }, /* region 13 */ { { 1, 41, 41 }, -5855, 26028, 798, 993, 45, 11 }, /* region 14 */ { { 257, 42, 42 }, -4200, 26028, 4288, 7488, 7, 12 }, /* region 15 */ { { 1, 43, 43 }, -5755, 26028, 798, 993, 45, 13 }, /* region 16 */ { { 257, 44, 44 }, -4400, 26028, 4288, 7488, 7, 14 }, /* region 17 */ { { 1, 45, 45 }, -5755, 26028, 798, 993, 45, 15 }, /* region 18 */ { { 257, 46, 46 }, -4600, 26028, 4288, 7488, 7, 16 }, /* region 19 */ { { 1, 47, 47 }, -5455, 26028, 798, 993, 45, 17 }, /* region 20 */ { { 1, 48, 48 }, -5355, 26028, 798, 993, 45, 18 }, /* region 21 */ { { 1, 49, 49 }, -5200, 16422, 1294, 5778, 8, 19 }, /* region 22 */ { { 1, 50, 50 }, -5255, 26028, 798, 993, 45, 20 }, /* region 23 */ { { 1, 51, 51 }, -5268, 16422, 6592, 9921, 6, 21 }, /* region 24 */ { { 1, 52, 52 }, -5600, 32767, 1294, 5778, 8, 22 }, /* region 25 */ { { 1, 53, 53 }, -5418, 14636, 6592, 9921, 6, 23 }, /* region 26 */ { { 0, 54, 54 }, -5751, 26028, 0, 0, 39, 24 }, /* region 27 */ { { 1, 55, 55 }, -5300, 32767, 1294, 5778, 8, 25 }, /* region 28 */ { { 0, 56, 56 }, -7255, 32767, 0, 0, 90, 26 }, /* region 29 */ { { 1, 57, 57 }, -5700, 32767, 1294, 5778, 8, 27 }, /* region 30 */ { { 1, 58, 58 }, -7053, 23197, 0, 166, 113, 28 }, /* region 31 */ { { 1, 59, 59 }, -5968, 16422, 6592, 9921, 6, 29 }, /* region 32 */ { { 1, 60, 60 }, -6453, 23197, 432, 582, 63, 30 }, /* region 33 */ { { 1, 61, 61 }, -6853, 16422, 432, 582, 63, 30 }, /* region 34 */ { { 1, 62, 62 }, -7253, 20675, 432, 582, 63, 31 }, /* region 35 */ { { 1, 63, 63 }, -7353, 23197, 432, 582, 63, 32 }, /* region 36 */ { { 1, 64, 64 }, -7953, 23197, 432, 582, 63, 33 }, /* region 37 */ { { 0, 65, 65 }, -7555, 32767, 0, 0, 14, 34 }, /* region 38 */ { { 0, 66, 66 }, -7955, 20675, 0, 0, 14, 34 }, /* region 39 */ { { 512, 67, 67 }, -7155, 18426, 0, 0, 90, 35 }, /* region 40 */ { { 512, 68, 68 }, -7755, 18426, 0, 0, 90, 35 }, /* region 41 */ { { 0, 69, 69 }, -7755, 32767, 0, 0, 86, 36 }, /* region 42 */ { { 0, 70, 70 }, -6855, 21900, 0, 0, 86, 37 }, /* region 43 */ { { 769, 71, 71 }, -6355, 23197, 0, 1226, 35, 38 }, /* region 44 */ { { 769, 72, 72 }, -6955, 26028, 0, 1226, 35, 38 }, /* region 45 */ { { 1024, 73, 73 }, -7955, 32767, 0, 0, 22, 39 }, /* region 46 */ { { 1024, 74, 74 }, -8455, 32767, 0, 0, 22, 40 }, /* region 47 */ { { 1, 75, 75 }, -7900, 23197, 0, 31, 139, 41 }, /* region 48 */ { { 0, 76, 76 }, -10455, 23197, 0, 0, 134, 42 }, /* region 49 */ { { 0, 77, 77 }, -10055, 23197, 0, 0, 134, 43 }, /* region 50 */ { { 0, 78, 78 }, -8853, 16422, 0, 0, 89, 44 }, /* region 51 */ { { 0, 79, 79 }, -10253, 16422, 0, 0, 89, 45 }, /* region 52 */ { { 1281, 80, 80 }, -6300, 13045, 209, 230, 103, 46 }, /* region 53 */ { { 1281, 81, 81 }, -6400, 16422, 209, 230, 103, 47 }, /* region 54 */ { { 0, 82, 82 }, -8455, 20675, 0, 0, 87, 48 }, /* region 55 */ { { 0, 83, 83 }, -8900, 32767, 0, 0, 13, 49 }, /* region 56 */ { { 1, 84, 84 }, -8400, 23197, 0, 10294, 5, 50 }, /* region 57 */ { { 0, 85, 85 }, -9655, 32767, 0, 0, 135, 4 }, /* region 58 */ { { 0, 86, 86 }, -9068, 16422, 0, 0, 24, 51 }, /* region 59 */ { { 32769, 87, 87 }, -9168, 32767, 1335, 1603, 24, 52 }, /* region 60 */ { { 1, 12, 67 }, -6605, 23197, 437, 16584, 2, 48 }, /* region 61 */ { { 1, 68, 73 }, -7196, 23197, 452, 16803, 0, 48 }, /* region 62 */ { { 32769, 74, 108 }, -8467, 23197, 404, 16698, 1, 48 }, /* region 63 */ { { 1, 12, 78 }, -6605, 16422, 437, 16584, 2, 48 }, /* region 64 */ { { 1, 79, 91 }, -7196, 16422, 452, 16803, 0, 48 }, /* region 65 */ { { 32769, 92, 108 }, -8467, 16422, 404, 16698, 1, 48 }, /* region 66 */ { { 1, 12, 78 }, -6605, 16422, 437, 16584, 2, 48 }, /* region 67 */ { { 1, 79, 91 }, -7196, 16422, 452, 16803, 0, 48 }, /* region 68 */ { { 32769, 92, 108 }, -8467, 16422, 404, 16698, 1, 48 }, /* region 69 */ { { 1, 12, 70 }, -6600, 23197, 437, 16584, 2, 48 }, /* region 70 */ { { 1, 71, 88 }, -7191, 23197, 452, 16803, 0, 48 }, /* region 71 */ { { 32769, 89, 108 }, -8462, 23197, 404, 16698, 1, 48 }, /* region 72 */ { { 1, 12, 54 }, -5956, 13045, 639, 4368, 10, 48 }, /* region 73 */ { { 32769, 55, 108 }, -6351, 18426, 702, 3112, 12, 48 }, /* region 74 */ { { 1, 12, 66 }, -6611, 23197, 437, 16584, 2, 48 }, /* region 75 */ { { 1, 67, 87 }, -7202, 23197, 452, 16803, 0, 48 }, /* region 76 */ { { 32769, 88, 108 }, -8473, 16422, 404, 16698, 1, 48 }, /* region 77 */ { { 1, 12, 43 }, -3055, 23197, 920, 1383, 30, 59 }, /* region 78 */ { { 32769, 44, 96 }, -5060, 18426, 885, 1176, 37, 59 }, /* region 79 */ { { 1, 12, 48 }, -3461, 18426, 1148, 1514, 26, 60 }, /* region 80 */ { { 32769, 49, 96 }, -6253, 16422, 1347, 1420, 29, 60 }, /* region 81 */ { { 1, 33, 56 }, -5600, 26028, 1064, 1170, 38, 61 }, /* region 82 */ { { 1, 57, 72 }, -6000, 26028, 930, 1014, 44, 61 }, /* region 83 */ { { 32769, 73, 108 }, -7600, 26028, 726, 826, 52, 61 }, /* region 84 */ { { 1, 36, 96 }, -7600, 20675, 635, 735, 58, 62 }, /* region 85 */ { { 32769, 97, 108 }, -10108, 13045, 0, 31, 139, 62 }, /* region 86 */ { { 1, 36, 96 }, -7600, 14636, 635, 735, 58, 0 }, /* region 87 */ { { 32769, 97, 108 }, -10108, 13045, 0, 31, 139, 0 }, /* region 88 */ { { 1, 36, 83 }, -6006, 13045, 838, 922, 47, 63 }, /* region 89 */ { { 1, 84, 93 }, -8406, 14636, 209, 230, 103, 63 }, /* region 90 */ { { 32769, 94, 108 }, -10108, 13045, 0, 31, 139, 63 }, /* region 91 */ { { 1, 36, 83 }, -6006, 13045, 838, 922, 47, 64 }, /* region 92 */ { { 1, 84, 93 }, -8406, 13045, 209, 230, 103, 64 }, /* region 93 */ { { 32769, 94, 108 }, -10108, 13045, 0, 31, 139, 64 }, /* region 94 */ { { 1, 21, 56 }, -5595, 23197, 1064, 1170, 38, 65 }, /* region 95 */ { { 1, 57, 72 }, -5995, 23197, 930, 1014, 44, 65 }, /* region 96 */ { { 32769, 73, 108 }, -7598, 23197, 726, 826, 52, 65 }, /* region 97 */ { { 1, 12, 83 }, -6006, 16422, 838, 922, 47, 66 }, /* region 98 */ { { 1, 84, 93 }, -8406, 16422, 209, 230, 103, 66 }, /* region 99 */ { { 32769, 94, 108 }, -10108, 16422, 0, 31, 139, 66 }, /* region 100 */ { { 1, 24, 83 }, -6006, 16422, 838, 922, 47, 67 }, /* region 101 */ { { 1, 84, 93 }, -8406, 16422, 209, 230, 103, 67 }, /* region 102 */ { { 32769, 94, 108 }, -10108, 16422, 0, 31, 139, 67 }, /* region 103 */ { { 1, 12, 83 }, -6020, 16422, 0, 83, 126, 68 }, /* region 104 */ { { 1, 84, 90 }, -8482, 16422, 0, 20, 145, 68 }, /* region 105 */ { { 32769, 91, 108 }, -9101, 16422, 6, 20, 147, 68 }, /* region 106 */ { { 1, 21, 75 }, -7241, 16422, 419, 460, 76, 69 }, /* region 107 */ { { 32769, 76, 108 }, -9690, 14636, 254, 264, 101, 69 }, /* region 108 */ { { 32769, 36, 84 }, -7755, 16422, 0, 2775, 17, 70 }, /* region 109 */ { { 32769, 12, 108 }, -6655, 23197, 30, 276, 100, 71 }, /* region 110 */ { { 0, 12, 60 }, -7914, 26028, 0, 0, 15, 72 }, /* region 111 */ { { 32768, 61, 96 }, -7914, 26028, 0, 0, 15, 73 }, /* region 112 */ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 74 }, /* region 113 */ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 74 }, /* region 114 */ { { 1, 12, 35 }, -5355, 16422, 2869, 3778, 11, 75 }, /* region 115 */ { { 1, 36, 48 }, -6555, 20675, 2869, 3778, 11, 75 }, /* region 116 */ { { 32769, 49, 72 }, -6555, 20675, 2869, 3778, 11, 76 }, /* region 117 */ { { 1, 16, 55 }, -6224, 20675, 1045, 1119, 41, 77 }, /* region 118 */ { { 32769, 56, 96 }, -6718, 20675, 907, 963, 46, 77 }, /* region 119 */ { { 1, 16, 53 }, -5994, 29204, 1140, 1479, 27, 78 }, /* region 120 */ { { 1, 54, 70 }, -7171, 29204, 726, 812, 55, 78 }, /* region 121 */ { { 32769, 71, 108 }, -7788, 29204, 718, 748, 56, 78 }, /* region 122 */ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 79 }, /* region 123 */ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 79 }, /* region 124 */ { { 1, 16, 54 }, -5727, 20675, 5362, 5461, 9, 80 }, /* region 125 */ { { 1, 55, 63 }, -5851, 26028, 1362, 1454, 28, 80 }, /* region 126 */ { { 32769, 64, 108 }, -6744, 16422, 311, 366, 88, 80 }, /* region 127 */ { { 1, 16, 48 }, -4798, 20675, 1132, 1301, 31, 81 }, /* region 128 */ { { 32769, 49, 108 }, -5988, 20675, 1099, 1184, 36, 81 }, /* region 129 */ { { 1, 21, 68 }, -8458, 20675, 87, 2170, 18, 82 }, /* region 130 */ { { 1, 69, 82 }, -8960, 20675, 120, 2167, 19, 82 }, /* region 131 */ { { 32769, 83, 108 }, -10160, 20675, 376, 2041, 20, 82 }, /* region 132 */ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 83 }, /* region 133 */ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 83 }, /* region 134 */ { { 32769, 55, 108 }, -7368, 20675, 0, 477, 75, 84 }, /* region 135 */ { { 32769, 36, 96 }, -6900, 14636, 101, 151, 116, 85 }, /* region 136 */ { { 1, 24, 83 }, -6020, 13045, 0, 83, 126, 86 }, /* region 137 */ { { 1, 84, 90 }, -8482, 13045, 0, 20, 145, 86 }, /* region 138 */ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 147, 86 }, /* region 139 */ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 87 }, /* region 140 */ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 87 }, /* region 141 */ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 88 }, /* region 142 */ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 88 }, /* region 143 */ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 89 }, /* region 144 */ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 89 }, /* region 145 */ { { 1, 24, 83 }, -6020, 13045, 0, 83, 126, 90 }, /* region 146 */ { { 1, 84, 90 }, -8482, 13045, 0, 20, 145, 90 }, /* region 147 */ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 147, 90 }, /* region 148 */ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 91 }, /* region 149 */ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 91 }, /* region 150 */ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 92 }, /* region 151 */ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 92 }, /* region 152 */ { { 1, 12, 62 }, -7053, 16422, 23, 10953, 4, 93 }, /* region 153 */ { { 32769, 63, 108 }, -7755, 20675, 11, 11753, 3, 93 }, /* region 154 */ { { 1, 12, 62 }, -7053, 16422, 23, 10953, 4, 94 }, /* region 155 */ { { 32769, 63, 108 }, -7755, 16422, 11, 11753, 3, 94 }, /* region 156 */ { { 1, 24, 79 }, -6020, 13045, 0, 83, 126, 95 }, /* region 157 */ { { 1, 80, 90 }, -8482, 13045, 0, 20, 145, 95 }, /* region 158 */ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 147, 95 }, /* region 159 */ { { 1, 12, 65 }, -7053, 13045, 23, 10953, 4, 96 }, /* region 160 */ { { 32769, 66, 108 }, -7755, 16422, 11, 11753, 3, 96 }, /* region 161 */ { { 32768, 36, 84 }, -7500, 20675, 0, 0, 25, 97 }, /* region 162 */ { { 32769, 36, 96 }, -8855, 20675, 1482, 1613, 23, 98 }, /* region 163 */ { { 32769, 12, 96 }, -4366, 32767, 818, 1033, 42, 99 }, /* region 164 */ { { 32769, 36, 84 }, -8568, 18426, 0, 293, 98, 100 }, /* region 165 */ { { 32769, 12, 96 }, -6020, 26028, 0, 83, 125, 101 }, /* region 166 */ { { 32769, 12, 96 }, -6020, 20675, 0, 83, 125, 102 }, /* region 167 */ { { 1, 12, 83 }, -6020, 13045, 0, 83, 125, 104 }, /* region 168 */ { { 1, 84, 90 }, -8482, 13045, 0, 20, 146, 104 }, /* region 169 */ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 148, 104 }, /* region 170 */ { { 32769, 36, 108 }, -8570, 32767, 472, 491, 74, 105 }, /* region 171 */ { { 32769, 36, 108 }, -8570, 20675, 472, 491, 74, 106 }, /* region 172 */ { { 1, 12, 72 }, -6012, 7336, 2, 86, 124, 107 }, /* region 173 */ { { 1, 73, 101 }, -8500, 8231, 2, 22, 143, 107 }, /* region 174 */ { { 32769, 102, 108 }, -9683, 20675, 173, 183, 110, 107 }, /* region 175 */ { { 1, 21, 96 }, -7768, 13045, 477, 507, 73, 108 }, /* region 176 */ { { 32769, 97, 108 }, -9683, 13045, 173, 183, 110, 109 }, /* region 177 */ { { 32769, 12, 108 }, -7771, 16422, 477, 507, 73, 110 }, /* region 178 */ { { 1, 12, 53 }, -4971, 16422, 388, 541, 68, 111 }, /* region 179 */ { { 32769, 54, 60 }, -5949, 11626, 473, 560, 65, 111 }, /* region 180 */ { { 32769, 36, 72 }, -5949, 16422, 473, 560, 65, 112 }, /* region 181 */ { { 1, 48, 58 }, -7053, 16422, 356, 402, 82, 113 }, /* region 182 */ { { 1, 59, 65 }, -7574, 16422, 514, 548, 67, 113 }, /* region 183 */ { { 1, 66, 78 }, -8174, 16422, 505, 529, 71, 113 }, /* region 184 */ { { 32769, 79, 96 }, -9233, 16422, 178, 191, 109, 113 }, /* region 185 */ { { 1, 55, 60 }, -7053, 16422, 356, 402, 82, 114 }, /* region 186 */ { { 1, 61, 69 }, -7574, 16422, 514, 548, 67, 114 }, /* region 187 */ { { 1, 70, 79 }, -8174, 16422, 505, 529, 71, 114 }, /* region 188 */ { { 32769, 80, 108 }, -9233, 16422, 178, 191, 109, 114 }, /* region 189 */ { { 1, 16, 82 }, -8029, 23197, 180, 206, 106, 115 }, /* region 190 */ { { 32769, 83, 108 }, -7240, 18426, 3, 44, 131, 115 }, /* region 191 */ { { 32769, 21, 108 }, -8869, 20675, 483, 515, 72, 116 }, /* region 192 */ { { 1, 21, 89 }, -7205, 18426, 3, 45, 130, 117 }, /* region 193 */ { { 32769, 90, 108 }, -9101, 10362, 6, 20, 148, 117 }, /* region 194 */ { { 1, 21, 42 }, -4686, 20675, 0, 180, 111, 118 }, /* region 195 */ { { 1, 43, 51 }, -5286, 23197, 0, 127, 120, 118 }, /* region 196 */ { { 1, 52, 58 }, -6292, 26028, 0, 71, 127, 118 }, /* region 197 */ { { 1, 59, 68 }, -7468, 23197, 0, 36, 136, 118 }, /* region 198 */ { { 32769, 69, 108 }, -8574, 20675, 0, 19, 149, 118 }, /* region 199 */ { { 1, 21, 89 }, -7199, 20675, 3, 45, 130, 119 }, /* region 200 */ { { 32769, 90, 108 }, -9101, 14636, 6, 20, 148, 119 }, /* region 201 */ { { 1, 21, 46 }, -5651, 26028, 236, 340, 92, 120 }, /* region 202 */ { { 1, 47, 71 }, -6563, 20675, 824, 885, 49, 120 }, /* region 203 */ { { 1, 72, 88 }, -7907, 18426, 719, 747, 57, 120 }, /* region 204 */ { { 1, 89, 93 }, -8876, 16422, 83, 99, 122, 120 }, /* region 205 */ { { 32769, 94, 108 }, -9689, 16422, 173, 183, 110, 120 }, /* region 206 */ { { 1, 60, 71 }, -7205, 16422, 0, 42, 132, 121 }, /* region 207 */ { { 1, 72, 78 }, -7903, 16422, 0, 28, 141, 121 }, /* region 208 */ { { 32769, 79, 96 }, -8405, 16422, 0, 21, 144, 121 }, /* region 209 */ { { 1, 48, 65 }, -6316, 11626, 0, 70, 128, 122 }, /* region 210 */ { { 1, 66, 79 }, -7724, 14636, 0, 31, 138, 122 }, /* region 211 */ { { 32769, 80, 96 }, -8030, 11626, 0, 26, 142, 122 }, /* region 212 */ { { 1, 16, 44 }, -5868, 14636, 163, 254, 102, 123 }, /* region 213 */ { { 1, 45, 51 }, -6418, 16422, 261, 393, 85, 123 }, /* region 214 */ { { 1, 52, 58 }, -7333, 18426, 190, 229, 104, 123 }, /* region 215 */ { { 1, 59, 66 }, -8100, 18426, 168, 193, 108, 123 }, /* region 216 */ { { 1, 67, 70 }, -8576, 18426, 138, 157, 115, 123 }, /* region 217 */ { { 1, 71, 80 }, -9103, 18426, 166, 180, 112, 123 }, /* region 218 */ { { 32769, 81, 108 }, -10074, 18426, 135, 151, 117, 123 }, /* region 219 */ { { 32769, 12, 96 }, -5004, 23197, 570, 719, 59, 124 }, /* region 220 */ { { 1, 12, 48 }, -5868, 14636, 163, 254, 102, 125 }, /* region 221 */ { { 1, 49, 54 }, -6418, 16422, 261, 393, 85, 125 }, /* region 222 */ { { 1, 55, 63 }, -7333, 18426, 190, 229, 104, 125 }, /* region 223 */ { { 1, 64, 70 }, -8100, 18426, 168, 193, 108, 125 }, /* region 224 */ { { 1, 71, 75 }, -8576, 18426, 138, 157, 115, 125 }, /* region 225 */ { { 1, 76, 82 }, -9103, 18426, 166, 180, 112, 125 }, /* region 226 */ { { 32769, 83, 108 }, -10074, 18426, 135, 151, 117, 125 }, /* region 227 */ { { 32770, 36, 84 }, -7200, 29204, 0, 0, 0, 126 }, /* region 228 */ { { 32770, 36, 84 }, -7600, 8231, 0, 0, 0, 127 }, /* region 229 */ { { 32770, 36, 84 }, -7200, 20675, 0, 0, 0, 128 }, /* region 230 */ { { 32769, 36, 84 }, -6000, -24285, 1294, 5778, 8, 129 }, /* region 231 */ { { 32769, 36, 84 }, -6555, 29204, 798, 993, 45, 130 }, /* region 232 */ { { 32769, 36, 84 }, -6855, 20675, 798, 993, 45, 131 }, /* region 233 */ { { 32769, 36, 84 }, -7755, 29204, 798, 993, 45, 132 }, /* region 234 */ { { 32768, 36, 84 }, -8155, 32767, 0, 0, 133, 133 }, /* region 235 */ { { 32768, 36, 84 }, -6555, 20675, 0, 0, 91, 134 }, /* region 236 */ { { 1, 24, 62 }, -7000, 23197, 286, 333, 94, 135 }, /* region 237 */ { { 1, 63, 66 }, -7364, 26028, 297, 335, 93, 135 }, /* region 238 */ { { 1, 67, 72 }, -7722, 23197, 368, 399, 84, 135 }, /* region 239 */ { { 32769, 73, 96 }, -8310, 23197, 116, 138, 119, 135 }, /* region 240 */ { { 1, 24, 48 }, -5141, 23197, 309, 447, 77, 136 }, /* region 241 */ { { 1, 49, 56 }, -6266, 26028, 211, 283, 99, 136 }, /* region 242 */ { { 1, 57, 63 }, -7000, 26028, 286, 333, 94, 136 }, /* region 243 */ { { 32769, 64, 84 }, -7722, 23197, 368, 399, 84, 136 }, /* region 244 */ { { 1, 24, 56 }, -6266, 29204, 211, 283, 99, 137 }, /* region 245 */ { { 1, 57, 63 }, -7000, 29204, 286, 333, 94, 137 }, /* region 246 */ { { 1, 64, 69 }, -7722, 29204, 368, 399, 84, 137 }, /* region 247 */ { { 32769, 70, 96 }, -8310, 29204, 116, 138, 119, 137 }, /* region 248 */ { { 1, 24, 68 }, -7722, 18426, 368, 399, 84, 138 }, /* region 249 */ { { 1, 69, 76 }, -8310, 26028, 116, 138, 119, 138 }, /* region 250 */ { { 32769, 77, 108 }, -8758, 23197, 127, 144, 118, 138 }, /* region 251 */ { { 1, 24, 82 }, -7613, 23197, 389, 422, 80, 139 }, /* region 252 */ { { 32769, 83, 108 }, -8764, 26028, 146, 163, 114, 139 }, /* region 253 */ { { 1, 12, 58 }, -6898, 29204, 386, 436, 78, 140 }, /* region 254 */ { { 32769, 59, 96 }, -7371, 26028, 290, 328, 95, 140 }, /* region 255 */ { { 1, 12, 58 }, -6898, 16422, 386, 436, 78, 141 }, /* region 256 */ { { 32769, 59, 96 }, -7371, 18426, 290, 328, 95, 141 }, /* region 257 */ { { 1, 12, 48 }, -6898, -28771, 386, 436, 78, 142 }, /* region 258 */ { { 32769, 49, 84 }, -7371, 29204, 290, 328, 95, 142 }, /* region 259 */ { { 1, 12, 60 }, -5453, 20675, 314, 430, 79, 143 }, /* region 260 */ { { 32769, 61, 84 }, -6553, 18426, 263, 324, 96, 143 }, /* region 261 */ { { 1, 24, 60 }, -6553, 16422, 263, 324, 96, 144 }, /* region 262 */ { { 1, 61, 70 }, -7669, 20675, 279, 311, 97, 144 }, /* region 263 */ { { 32769, 71, 96 }, -8098, 23197, 179, 204, 107, 144 }, /* region 264 */ { { 1, 24, 84 }, -8483, 20675, 191, 211, 105, 145 }, /* region 265 */ { { 32769, 85, 108 }, -9683, 20675, 92, 102, 121, 145 }, /* region 266 */ { { 1, 21, 69 }, -6553, 13045, 263, 324, 96, 146 }, /* region 267 */ { { 1, 70, 94 }, -7669, 20675, 279, 311, 97, 146 }, /* region 268 */ { { 1, 95, 96 }, -8098, -24285, 179, 204, 107, 146 }, /* region 269 */ { { 32769, 97, 108 }, -9683, -24285, 173, 183, 110, 146 }, /* region 270 */ { { 1, 16, 55 }, -8100, 20675, 168, 193, 108, 147 }, /* region 271 */ { { 1, 56, 74 }, -8576, 26028, 138, 157, 115, 147 }, /* region 272 */ { { 32769, 75, 96 }, -10074, 26028, 135, 151, 117, 147 }, /* region 273 */ { { 1, 24, 72 }, -8098, 26028, 179, 204, 107, 148 }, /* region 274 */ { { 1, 73, 85 }, -8483, 20675, 191, 211, 105, 148 }, /* region 275 */ { { 32769, 86, 108 }, -9683, 18426, 92, 102, 121, 148 }, /* region 276 */ { { 32769, 36, 108 }, -7730, 18426, 1839, 1901, 21, 149 }, /* region 277 */ { { 32769, 24, 108 }, -7273, 20675, 494, 534, 69, 150 }, /* region 278 */ { { 32769, 12, 108 }, -7273, 20675, 494, 534, 69, 151 }, /* region 279 */ { { 32769, 24, 108 }, -7273, 20675, 494, 534, 69, 152 }, /* region 280 */ { { 1, 36, 60 }, -4900, 5193, 2, 22, 143, 153 }, /* region 281 */ { { 32769, 61, 84 }, -6083, 20675, 173, 183, 110, 153 }, /* region 282 */ { { 32769, 24, 96 }, -6553, 14636, 263, 324, 96, 154 }, /* region 283 */ { { 32769, 36, 96 }, -7730, 26028, 1839, 1901, 21, 155 }, /* region 284 */ { { 32769, 24, 108 }, -7273, 20675, 494, 534, 69, 156 }, /* region 285 */ { { 1, 24, 58 }, -7851, 14636, 0, 29, 140, 157 }, /* region 286 */ { { 32769, 59, 96 }, -7851, 14636, 0, 29, 140, 157 }, /* region 287 */ { { 1, 12, 83 }, -6020, 13045, 0, 83, 125, 158 }, /* region 288 */ { { 1, 84, 90 }, -8482, 13045, 0, 20, 146, 158 }, /* region 289 */ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 148, 158 }, /* region 290 */ { { 1, 21, 42 }, -4663, 26028, 1047, 1229, 34, 159 }, /* region 291 */ { { 1, 43, 48 }, -5456, 29204, 1138, 1253, 33, 159 }, /* region 292 */ { { 1, 49, 53 }, -5845, 26028, 559, 651, 60, 159 }, /* region 293 */ { { 1, 54, 60 }, -6732, 26028, 508, 563, 64, 159 }, /* region 294 */ { { 1, 61, 65 }, -7080, 32767, 819, 864, 51, 159 }, /* region 295 */ { { 1, 66, 70 }, -6866, 26942, 981, 1032, 43, 159 }, /* region 296 */ { { 1, 71, 76 }, -8166, 26028, 790, 814, 54, 159 }, /* region 297 */ { { 1, 77, 82 }, -8766, 26028, 592, 609, 61, 159 }, /* region 298 */ { { 1, 83, 87 }, -9517, 23197, 543, 554, 66, 159 }, /* region 299 */ { { 1, 88, 96 }, -10071, 18426, 601, 609, 62, 159 }, /* region 300 */ { { 32769, 97, 108 }, -10566, 18426, 523, 529, 70, 159 }, /* region 301 */ { { 1, 48, 69 }, -6313, 14636, 0, 70, 128, 160 }, /* region 302 */ { { 1, 70, 79 }, -7724, 18426, 0, 31, 138, 160 }, /* region 303 */ { { 32769, 80, 96 }, -8030, 14636, 0, 26, 142, 160 }, /* region 304 */ { { 1, 36, 72 }, -7134, 29204, 0, 87, 123, 161 }, /* region 305 */ { { 32769, 73, 96 }, -7960, 29204, 0, 54, 129, 161 }, /* region 306 */ { { 32769, 36, 96 }, -7730, 26028, 1839, 1901, 21, 162 }, /* region 307 */ { { 32769, 12, 96 }, -4372, 32767, 818, 1033, 42, 163 }, /* region 308 */ { { 32769, 36, 108 }, -8570, 26028, 472, 491, 74, 164 }, /* region 309 */ { { 32769, 12, 96 }, -5004, 29204, 570, 719, 59, 165 }, /* region 310 */ { { 1, 12, 83 }, -6020, 13045, 0, 83, 125, 166 }, /* region 311 */ { { 1, 84, 90 }, -8482, 13045, 0, 20, 146, 166 }, /* region 312 */ { { 32769, 91, 108 }, -9101, 13045, 6, 20, 148, 166 }, /* region 313 */ { { 1, 21, 46 }, -5651, 32767, 236, 340, 92, 167 }, /* region 314 */ { { 1, 47, 75 }, -6563, 26028, 824, 885, 49, 167 }, /* region 315 */ { { 1, 76, 84 }, -7907, 23197, 719, 747, 57, 167 }, /* region 316 */ { { 1, 85, 93 }, -8876, 20675, 83, 99, 122, 167 }, /* region 317 */ { { 32769, 94, 108 }, -9689, 20675, 173, 183, 110, 167 }, /* region 318 */ { { 1, 21, 46 }, -5651, 26028, 236, 340, 92, 168 }, /* region 319 */ { { 1, 47, 71 }, -6563, 20675, 824, 885, 49, 168 }, /* region 320 */ { { 1, 72, 88 }, -7907, 18426, 719, 747, 57, 168 }, /* region 321 */ { { 1, 89, 93 }, -8876, 16422, 83, 99, 122, 168 }, /* region 322 */ { { 32769, 94, 108 }, -9689, 16422, 173, 183, 110, 168 }, /* region 323 */ { { 1, 21, 45 }, -4663, 26028, 1047, 1229, 34, 169 }, /* region 324 */ { { 1, 46, 51 }, -5456, 29204, 1138, 1253, 33, 169 }, /* region 325 */ { { 1, 52, 54 }, -5845, 26028, 559, 651, 60, 169 }, /* region 326 */ { { 1, 55, 63 }, -6732, 26028, 508, 563, 64, 169 }, /* region 327 */ { { 1, 64, 68 }, -7080, 32767, 819, 864, 51, 169 }, /* region 328 */ { { 1, 69, 73 }, -6866, 26942, 981, 1032, 43, 169 }, /* region 329 */ { { 1, 74, 79 }, -8166, 26028, 790, 814, 54, 169 }, /* region 330 */ { { 1, 80, 88 }, -8766, 23197, 592, 609, 61, 169 }, /* region 331 */ { { 1, 89, 99 }, -10071, 18426, 601, 609, 62, 169 }, /* region 332 */ { { 32769, 100, 108 }, -10566, 18426, 523, 529, 70, 169 }, /* region 333 */ { { 1, 21, 45 }, -4663, 26028, 1047, 1229, 34, 170 }, /* region 334 */ { { 1, 46, 51 }, -5456, 29204, 1138, 1253, 33, 170 }, /* region 335 */ { { 1, 52, 54 }, -5845, 26028, 559, 651, 60, 170 }, /* region 336 */ { { 1, 55, 63 }, -6732, 26028, 508, 563, 64, 170 }, /* region 337 */ { { 1, 64, 68 }, -7080, 32767, 819, 864, 51, 170 }, /* region 338 */ { { 1, 69, 73 }, -6866, 26942, 981, 1032, 43, 170 }, /* region 339 */ { { 1, 74, 79 }, -8166, 26028, 790, 814, 54, 170 }, /* region 340 */ { { 1, 80, 88 }, -8766, 23197, 592, 609, 61, 170 }, /* region 341 */ { { 1, 89, 99 }, -10071, 18426, 601, 609, 62, 171 }, /* region 342 */ { { 32769, 100, 108 }, -10566, 18426, 523, 529, 70, 172 }, /* region 343 */ { { 32769, 36, 108 }, -8570, 20675, 472, 491, 74, 173 }, /* region 344 */ { { 32769, 12, 108 }, -7730, 20675, 1839, 1901, 21, 174 }, /* region 345 */ { { 1, 12, 44 }, -5868, 18426, 163, 254, 102, 175 }, /* region 346 */ { { 1, 45, 51 }, -6418, 20675, 261, 393, 85, 175 }, /* region 347 */ { { 1, 52, 58 }, -7333, 23197, 190, 229, 104, 175 }, /* region 348 */ { { 1, 59, 66 }, -8100, 23197, 168, 193, 108, 175 }, /* region 349 */ { { 1, 67, 70 }, -8576, 23197, 138, 157, 115, 175 }, /* region 350 */ { { 1, 71, 80 }, -9103, 23197, 166, 180, 112, 175 }, /* region 351 */ { { 32769, 81, 108 }, -10074, 23197, 135, 151, 117, 175 }, /* region 352 */ { { 1, 12, 65 }, -7053, 16422, 23, 10953, 4, 176 }, /* region 353 */ { { 32769, 66, 108 }, -7755, 20675, 11, 11753, 3, 176 }, /* region 354 */ { { 1, 12, 48 }, -4798, 29204, 1132, 1301, 31, 177 }, /* region 355 */ { { 32769, 49, 108 }, -5988, 29204, 1099, 1184, 36, 177 }, /* region 356 */ { { 1, 12, 83 }, -7241, 20675, 419, 460, 76, 178 }, /* region 357 */ { { 32769, 84, 108 }, -10123, 20675, 0, 31, 139, 178 }, /* region 358 */ { { 1, 55, 60 }, -7053, 18426, 356, 402, 82, 179 }, /* region 359 */ { { 1, 61, 69 }, -7574, 18426, 514, 548, 67, 179 }, /* region 360 */ { { 1, 70, 79 }, -8174, 18426, 505, 529, 71, 179 }, /* region 361 */ { { 32769, 80, 108 }, -9233, 23197, 178, 191, 109, 179 }, /* region 362 */ { { 32769, 36, 96 }, -7730, -24285, 1839, 1901, 21, 180 }, /* region 363 */ { { 1, 12, 83 }, -6006, 16422, 838, 922, 47, 181 }, /* region 364 */ { { 1, 84, 93 }, -8406, 18426, 209, 230, 103, 181 }, /* region 365 */ { { 32769, 94, 108 }, -10108, 16422, 0, 31, 139, 181 }, /* region 366 */ { { 1, 12, 56 }, -5595, 23197, 1064, 1170, 38, 182 }, /* region 367 */ { { 1, 57, 72 }, -5995, 23197, 930, 1014, 44, 182 }, /* region 368 */ { { 32769, 73, 108 }, -7598, 23197, 726, 826, 52, 182 }, /* region 369 */ { { 32769, 24, 108 }, -7600, 23197, 635, 735, 58, 62 }, /* region 370 */ { { 1, 36, 83 }, -6006, 13045, 838, 922, 47, 183 }, /* region 371 */ { { 1, 84, 93 }, -8406, 13045, 209, 230, 103, 183 }, /* region 372 */ { { 32769, 94, 108 }, -10108, 13045, 0, 31, 139, 183 }, /* region 373 */ { { 1, 12, 66 }, -6611, 23197, 437, 16584, 2, 184 }, /* region 374 */ { { 1, 67, 87 }, -7202, 23197, 452, 16803, 0, 184 }, /* region 375 */ { { 32769, 88, 108 }, -8473, 16422, 404, 16698, 1, 184 } /* region 376 */ }; /* end Regions */ /*---------------------------------------------------------------------------- * Programs *---------------------------------------------------------------------------- */ const S_PROGRAM eas_programs[] = { { 7864320, 0 } /* program 0 */ }; /* end Programs */ /*---------------------------------------------------------------------------- * Banks *---------------------------------------------------------------------------- */ const S_BANK eas_banks[] = { { /* bank 0 */ 30976, { 291, 324, 314, 334, 202, 319, 95, 195, 107, 92, 371, 89, 87, 85, 135, 82, 200, 192, 130, 267, 193, 302, 207, 210, 128, 125, 190, 120, 118, 213, 221, 271, 80, 78, 308, 164, 220, 310, 166, 167, 186, 182, 181, 179, 160, 178, 176, 115, 155, 153, 151, 149, 75, 73, 374, 111, 252, 254, 258, 305, 256, 157, 146, 137, 249, 237, 245, 241, 274, 262, 260, 265, 172, 171, 309, 277, 284, 307, 136, 344, 173, 168, 345, 353, 346, 70, 110, 311, 357, 144, 104, 67, 364, 367, 64, 288, 142, 140, 98, 355, 133, 123, 61, 113, 285, 280, 279, 278, 370, 286, 359, 283, 101, 236, 163, 235, 234, 233, 232, 231, 162, 363, 230, 281, 165, 229, 109, 228 } } }; /* end Banks */ /*---------------------------------------------------------------------------- * Samples *---------------------------------------------------------------------------- */ /* NOTE: this array should have size of at least eas_sampleOffsets[last_element] + eas_sampleLengths[last_element] */ #ifdef _8_BIT_SAMPLES const EAS_SAMPLE eas_samples[0x00033cbd + 20] = { 0, 0, -3, -4, -6, -8, -10, -12, -12, -11, -8, -3, 3, 7, 10, 14, 16, 16, 15, 12, 9, 4, -4, -12, -18, -21, -21, -19, -18, -15, -10, -3, 10, 20, 34, 44, 51, 52, 48, 43, 38, 26, 8, -15, -37, -52, -61, -64, -66, -64, -59, -47, -31, -13, 4, 18, 30, 37, 40, 36, 30, 24, 19, 11, -2, -17, -24, -28, -28, -21, -18, -16, -10, -3, 12, 27, 39, 49, 53, 53, 50, 43, 37, 25, 11, -11, -31, -46, -57, -63, -66, -63, -57, -46, -34, -19, -3, 13, 27, 35, 39, 37, 32, 26, 20, 11, 0, -13, -20, -24, -25, -21, -19, -14, -8, -2, 9, 23, 37, 47, 53, 52, 49, 42, 35, 25, 13, -6, -28, -48, -60, -67, -67, -64, -60, -51, -39, -23, -7, 10, 23, 35, 39, 38, 32, 26, 21, 15, 4, -9, -20, -22, -21, -19, -14, -11, -5, 1, 9, 19, 31, 45, 51, 52, 47, 39, 35, 25, 15, -3, -23, -42, -58, -70, -71, -66, -60, -51, -43, -30, -13, 6, 22, 32, 40, 40, 38, 33, 27, 19, 9, -5, -17, -25, -26, -22, -16, -11, -8, -4, 7, 21, 35, 48, 53, 56, 50, 43, 34, 22, 13, -2, -22, -44, -63, -75, -76, -69, -61, -51, -43, -29, -13, 6, 23, 32, 41, 43, 41, 37, 26, 18, 7, -8, -19, -25, -25, -22, -15, -9, -5, 0, 10, 24, 37, 44, 48, 52, 52, 46, 33, 20, 8, -5, -20, -38, -59, -74, -79, -73, -67, -55, -43, -26, -11, 4, 18, 29, 41, 45, 45, 38, 29, 21, 11, -3, -15, -25, -27, -22, -16, -11, -8, 0, 10, 25, 38, 44, 47, 50, 53, 49, 37, 20, 7, -5, -17, -34, -58, -74, -82, -76, -67, -59, -47, -29, -12, 3, 14, 25, 38, 50, 52, 46, 33, 23, 14, 3, -11, -25, -28, -27, -21, -16, -13, -7, 8, 27, 41, 44, 45, 47, 54, 55, 44, 25, 7, -7, -18, -32, -53, -71, -81, -81, -72, -67, -55, -37, -16, 3, 15, 23, 34, 48, 57, 56, 44, 30, 19, 5, -12, -26, -33, -31, -25, -19, -16, -11, 7, 25, 45, 49, 49, 52, 57, 59, 48, 32, 11, -5, -22, -39, -56, -73, -82, -88, -84, -75, -60, -38, -16, 5, 21, 30, 39, 52, 59, 61, 53, 37, 22, 7, -12, -28, -35, -36, -30, -22, -19, -16, -2, 21, 41, 52, 51, 52, 57, 62, 54, 40, 18, -2, -18, -36, -54, -70, -80, -86, -87, -81, -69, -48, -23, 0, 18, 28, 35, 45, 57, 64, 59, 46, 27, 9, -11, -24, -30, -32, -29, -25, -20, -16, -5, 15, 36, 47, 50, 49, 53, 57, 54, 43, 24, 5, -14, -32, -50, -65, -75, -82, -86, -86, -77, -58, -32, -8, 14, 25, 30, 41, 56, 69, 69, 57, 36, 17, -4, -20, -29, -32, -27, -28, -27, -23, -13, 10, 33, 46, 50, 48, 50, 54, 55, 48, 34, 16, -6, -29, -50, -68, -75, -78, -82, -86, -84, -72, -47, -16, 11, 28, 34, 41, 51, 64, 70, 64, 49, 27, 5, -17, -30, -33, -29, -29, -30, -30, -22, -2, 23, 41, 49, 51, 51, 54, 56, 50, 42, 25, 4, -20, -44, -62, -70, -76, -83, -87, -89, -78, -56, -29, 0, 19, 31, 38, 48, 63, 72, 71, 60, 40, 14, -12, -25, -29, -26, -27, -33, -37, -30, -12, 11, 31, 41, 48, 51, 53, 55, 55, 51, 39, 17, -12, -38, -58, -67, -74, -82, -92, -98, -89, -69, -41, -13, 10, 29, 41, 50, 64, 72, 78, 74, 57, 29, 0, -18, -26, -28, -32, -38, -42, -38, -23, -3, 18, 30, 42, 52, 58, 60, 61, 57, 48, 28, 2, -30, -51, -62, -70, -81, -94, -101, -93, -75, -49, -23, -2, 18, 36, 50, 61, 69, 77, 78, 66, 42, 11, -11, -22, -27, -32, -39, -46, -46, -36, -14, 8, 25, 41, 52, 59, 62, 63, 62, 57, 38, 11, -20, -47, -61, -69, -78, -89, -98, -94, -80, -60, -37, -12, 13, 33, 48, 62, 70, 78, 81, 72, 52, 23, 0, -14, -24, -33, -43, -49, -49, -39, -23, -2, 15, 33, 47, 57, 63, 62, 62, 57, 40, 20, -7, -34, -52, -65, -74, -83, -94, -92, -81, -63, -42, -22, 0, 21, 39, 54, 63, 73, 79, 76, 61, 37, 12, -5, -19, -28, -37, -46, -51, -47, -32, -13, 7, 25, 43, 54, 58, 60, 60, 61, 48, 27, 3, -25, -45, -60, -72, -81, -90, -92, -84, -71, -52, -32, -9, 14, 33, 50, 61, 74, 80, 78, 67, 47, 24, 6, -12, -26, -37, -50, -56, -52, -37, -19, -2, 16, 35, 52, 61, 63, 61, 59, 51, 35, 12, -15, -38, -55, -66, -77, -83, -83, -80, -68, -55, -39, -19, 4, 25, 41, 54, 66, 73, 75, 68, 52, 31, 11, -7, -22, -33, -46, -54, -51, -39, -24, -5, 12, 32, 48, 56, 60, 61, 58, 50, 36, 17, -8, -30, -46, -63, -74, -80, -80, -74, -69, -58, -43, -27, -5, 15, 31, 48, 60, 68, 72, 68, 57, 39, 20, 2, -16, -30, -44, -51, -50, -41, -27, -10, 9, 28, 43, 53, 57, 57, 54, 48, 37, 19, -3, -25, -41, -56, -69, -75, -73, -69, -63, -59, -49, -32, -13, 9, 25, 37, 48, 58, 66, 65, 58, 42, 25, 8, -9, -22, -36, -41, -43, -37, -26, -14, 4, 21, 37, 48, 52, 53, 47, 42, 34, 21, 3, -18, -39, -51, -64, -67, -62, -60, -60, -58, -50, -36, -16, 3, 17, 29, 41, 49, 58, 61, 60, 49, 29, 11, -7, -19, -28, -32, -33, -30, -25, -14, 2, 19, 33, 41, 45, 42, 38, 36, 29, 20, 6, -14, -28, -43, -54, -58, -55, -50, -51, -54, -51, -41, -22, -4, 11, 19, 30, 37, 47, 55, 56, 51, 34, 16, 0, -15, -19, -23, -22, -22, -21, -14, 0, 15, 29, 39, 43, 37, 31, 25, 21, 18, 6, -11, -28, -42, -50, -51, -48, -44, -41, -44, -43, -41, -25, -8, 9, 16, 22, 26, 35, 43, 50, 48, 33, 16, -3, -13, -16, -16, -15, -13, -11, -6, 5, 16, 28, 38, 41, 35, 24, 15, 12, 10, 4, -11, -27, -39, -46, -46, -45, -40, -36, -36, -37, -38, -29, -13, 6, 16, 19, 22, 27, 37, 43, 42, 32, 19, 2, -10, -13, -12, -7, -4, -2, 2, 10, 18, 27, 36, 38, 32, 20, 9, 4, -2, -4, -11, -23, -34, -42, -42, -38, -31, -28, -29, -32, -33, -30, -18, 0, 10, 12, 12, 17, 26, 35, 36, 31, 19, 5, -6, -11, -9, -2, 7, 14, 13, 13, 16, 23, 31, 34, 29, 15, -3, -8, -10, -10, -14, -20, -26, -30, -32, -30, -25, -18, -17, -24, -31, -32, -26, -11, 2, 7, 8, 9, 17, 25, 29, 28, 21, 9, -2, -7, -5, 4, 12, 21, 24, 23, 25, 26, 29, 31, 27, 15, -2, -15, -21, -23, -23, -23, -28, -30, -31, -27, -19, -10, -9, -13, -21, -22, -20, -11, -4, -3, -5, -2, 5, 13, 17, 17, 16, 10, 6, 0, 3, 11, 23, 32, 33, 30, 28, 27, 24, 24, 19, 9, -6, -19, -29, -29, -26, -20, -19, -22, -24, -23, -16, -10, -9, -14, -20, -24, -21, -16, -10, -6, -5, 1, 5, 11, 12, 13, 11, 8, 6, 1, 4, 9, 23, 33, 39, 36, 32, 32, 28, 22, 17, 7, -7, -22, -31, -33, -31, -24, -19, -18, -18, -16, -13, -7, -6, -8, -14, -21, -24, -20, -15, -12, -9, -6, 0, 4, 6, 8, 8, 5, 5, 2, 7, 15, 27, 37, 42, 45, 41, 39, 32, 22, 13, 3, -11, -26, -37, -41, -37, -29, -21, -18, -15, -11, -6, -2, -2, -4, -7, -13, -16, -20, -21, -16, -14, -10, -6, -3, -3, 0, 3, 2, 3, 3, 9, 18, 32, 41, 46, 49, 44, 43, 35, 24, 12, 1, -14, -27, -39, -40, -36, -31, -22, -16, -13, -6, -3, -3, -4, -9, -9, -13, -16, -20, -21, -16, -15, -11, -6, -4, -4, -5, -5, -3, -3, 0, 10, 19, 33, 44, 51, 56, 52, 50, 40, 23, 11, -6, -19, -30, -40, -43, -40, -35, -24, -16, -7, 2, 6, 5, 1, -6, -9, -9, -9, -12, -19, -21, -21, -17, -9, -7, -9, -11, -15, -14, -9, -7, 7, 19, 36, 51, 57, 61, 59, 56, 48, 33, 13, -8, -24, -35, -45, -51, -46, -38, -26, -14, -7, 3, 11, 15, 12, 3, -5, -7, -6, -9, -15, -22, -25, -23, -17, -13, -12, -16, -19, -21, -18, -12, 3, 21, 38, 50, 58, 67, 65, 64, 55, 41, 21, -4, -25, -38, -46, -50, -49, -43, -33, -23, -11, 3, 14, 19, 16, 8, 0, -2, -2, 0, -8, -19, -27, -30, -25, -22, -20, -20, -22, -25, -24, -16, 1, 22, 43, 56, 62, 67, 68, 65, 60, 46, 24, -3, -25, -40, -45, -49, -50, -46, -37, -23, -10, 1, 12, 20, 20, 14, 7, 2, 3, 3, -4, -15, -26, -31, -30, -27, -26, -26, -29, -33, -33, -25, -8, 17, 41, 57, 65, 71, 73, 73, 66, 53, 33, 5, -23, -41, -48, -50, -48, -48, -40, -30, -14, 1, 12, 21, 24, 18, 13, 6, 5, 5, 0, -11, -25, -37, -39, -35, -31, -31, -33, -38, -37, -29, -12, 15, 40, 59, 67, 71, 72, 73, 69, 59, 39, 14, -16, -38, -50, -51, -50, -48, -45, -36, -21, -4, 12, 25, 30, 25, 18, 11, 11, 10, 6, -8, -25, -39, -46, -42, -38, -37, -37, -40, -42, -34, -15, 13, 40, 57, 66, 71, 72, 72, 69, 61, 45, 19, -10, -34, -46, -48, -47, -45, -45, -41, -28, -12, 7, 23, 27, 25, 18, 15, 17, 17, 12, 1, -20, -37, -47, -50, -46, -45, -44, -45, -46, -41, -21, 7, 37, 60, 69, 73, 72, 72, 72, 67, 52, 25, -6, -33, -47, -50, -47, -47, -47, -45, -35, -16, 6, 23, 31, 30, 24, 23, 24, 25, 18, 4, -15, -33, -50, -56, -57, -53, -48, -49, -49, -45, -29, 2, 35, 58, 68, 71, 72, 74, 73, 68, 56, 34, 5, -26, -43, -48, -45, -42, -46, -46, -41, -24, 0, 21, 33, 34, 31, 25, 27, 27, 19, 6, -14, -36, -55, -64, -64, -60, -50, -47, -45, -44, -31, -4, 32, 58, 71, 72, 68, 70, 70, 66, 57, 36, 11, -20, -43, -50, -48, -41, -37, -42, -40, -28, -5, 21, 36, 38, 34, 26, 29, 28, 20, 8, -13, -33, -52, -68, -69, -65, -55, -49, -47, -44, -31, -3, 30, 55, 67, 70, 68, 70, 70, 65, 57, 39, 15, -13, -38, -49, -47, -40, -35, -39, -41, -30, -9, 17, 37, 44, 45, 38, 32, 29, 22, 9, -10, -34, -54, -70, -75, -73, -64, -52, -45, -43, -31, -7, 25, 53, 67, 72, 70, 72, 70, 62, 53, 38, 16, -10, -32, -49, -50, -43, -35, -33, -36, -29, -10, 16, 35, 46, 46, 41, 35, 30, 23, 10, -10, -34, -53, -69, -75, -74, -66, -53, -45, -42, -34, -13, 17, 46, 63, 68, 66, 63, 65, 63, 54, 43, 24, 0, -20, -40, -43, -42, -36, -32, -32, -28, -16, 7, 29, 47, 52, 47, 39, 31, 21, 10, -9, -30, -50, -66, -78, -77, -71, -59, -49, -42, -34, -17, 9, 37, 56, 66, 66, 62, 62, 61, 56, 45, 30, 7, -13, -31, -39, -40, -36, -33, -32, -28, -18, 1, 21, 41, 54, 52, 44, 36, 26, 13, -8, -29, -48, -66, -76, -80, -74, -64, -55, -45, -34, -18, 5, 29, 50, 65, 68, 66, 64, 60, 59, 47, 33, 15, -5, -23, -37, -43, -41, -37, -35, -31, -21, -4, 16, 36, 52, 59, 54, 45, 33, 17, -5, -25, -45, -60, -74, -83, -82, -71, -59, -49, -37, -23, -2, 22, 43, 59, 66, 65, 64, 60, 58, 50, 39, 23, 2, -17, -32, -39, -40, -38, -35, -32, -23, -6, 14, 33, 49, 59, 58, 49, 34, 16, -5, -25, -43, -60, -74, -83, -83, -76, -63, -53, -40, -24, -5, 16, 36, 54, 65, 67, 65, 61, 57, 52, 43, 27, 9, -12, -26, -37, -40, -39, -36, -32, -28, -13, 6, 27, 46, 58, 60, 52, 39, 23, 5, -16, -36, -53, -66, -77, -84, -81, -72, -60, -45, -32, -15, 5, 25, 48, 62, 69, 71, 69, 65, 58, 50, 34, 16, -6, -24, -36, -42, -45, -44, -39, -33, -21, -2, 22, 43, 59, 64, 60, 47, 34, 17, -6, -28, -50, -66, -76, -84, -86, -82, -72, -57, -40, -21, -2, 21, 42, 58, 66, 73, 76, 71, 64, 53, 40, 26, 4, -17, -34, -45, -49, -48, -43, -38, -28, -10, 15, 40, 58, 66, 64, 56, 42, 25, 4, -21, -44, -62, -73, -81, -87, -86, -78, -65, -47, -31, -9, 15, 34, 52, 62, 72, 79, 80, 72, 61, 49, 34, 12, -12, -32, -43, -49, -54, -55, -48, -36, -16, 10, 35, 56, 67, 71, 67, 54, 38, 15, -10, -34, -57, -72, -85, -93, -97, -89, -76, -59, -40, -20, 8, 32, 50, 67, 77, 87, 89, 81, 66, 52, 35, 16, -6, -30, -47, -58, -61, -57, -50, -37, -19, 6, 29, 51, 65, 73, 73, 62, 44, 18, -6, -28, -49, -67, -81, -93, -97, -94, -83, -65, -47, -28, -5, 19, 42, 61, 76, 87, 90, 88, 80, 66, 48, 27, 3, -17, -40, -56, -65, -66, -58, -49, -30, -6, 17, 41, 59, 71, 77, 70, 56, 36, 11, -13, -34, -53, -71, -89, -98, -100, -94, -79, -62, -44, -21, 3, 27, 52, 74, 90, 98, 95, 86, 75, 59, 37, 12, -14, -35, -54, -64, -67, -64, -51, -34, -10, 11, 32, 50, 65, 73, 71, 58, 37, 14, -10, -29, -48, -64, -81, -93, -98, -94, -82, -63, -45, -26, -5, 16, 40, 65, 83, 94, 94, 84, 75, 63, 46, 23, -3, -27, -47, -58, -64, -64, -56, -39, -17, 3, 20, 38, 57, 71, 72, 61, 45, 24, 1, -19, -37, -56, -73, -91, -99, -100, -92, -74, -53, -34, -16, 7, 31, 59, 82, 97, 101, 92, 78, 65, 48, 29, 6, -21, -43, -55, -64, -66, -58, -40, -18, 3, 17, 32, 51, 69, 71, 62, 45, 27, 6, -15, -34, -50, -64, -81, -93, -99, -96, -80, -59, -40, -23, -4, 21, 50, 77, 94, 100, 93, 81, 67, 53, 36, 14, -12, -36, -53, -58, -63, -56, -42, -22, -5, 10, 23, 42, 63, 70, 62, 47, 29, 13, -6, -27, -43, -57, -72, -84, -98, -99, -87, -66, -44, -27, -11, 10, 38, 67, 91, 99, 92, 82, 70, 57, 41, 21, -3, -27, -47, -58, -63, -58, -44, -23, -5, 7, 17, 35, 55, 66, 61, 46, 29, 13, -4, -22, -39, -51, -65, -78, -90, -95, -85, -69, -47, -30, -12, 9, 30, 57, 83, 96, 91, 81, 67, 57, 42, 26, 6, -18, -39, -55, -62, -58, -43, -24, -8, 2, 14, 30, 47, 60, 60, 49, 34, 17, 0, -16, -31, -43, -58, -71, -86, -93, -86, -72, -52, -32, -15, 3, 22, 48, 76, 90, 89, 78, 69, 59, 46, 32, 14, -6, -27, -47, -57, -56, -45, -29, -12, -5, 4, 18, 37, 54, 58, 51, 36, 21, 6, -8, -20, -33, -52, -68, -84, -90, -85, -74, -58, -42, -22, 0, 20, 42, 67, 83, 87, 80, 68, 58, 47, 34, 19, 0, -20, -40, -52, -53, -45, -27, -13, -4, 6, 17, 33, 47, 53, 52, 38, 21, 3, -11, -24, -35, -50, -65, -80, -89, -85, -71, -55, -39, -21, -2, 20, 39, 59, 74, 81, 75, 67, 57, 47, 38, 23, 4, -17, -32, -43, -45, -39, -26, -14, -4, 4, 12, 26, 38, 47, 48, 35, 19, 4, -10, -20, -29, -41, -56, -71, -78, -81, -71, -56, -43, -23, -6, 15, 35, 49, 62, 72, 69, 63, 54, 45, 41, 28, 11, -11, -27, -37, -40, -35, -24, -17, -7, 2, 9, 22, 35, 46, 49, 37, 21, 4, -9, -18, -27, -41, -55, -71, -79, -79, -70, -53, -38, -23, -8, 9, 31, 46, 58, 63, 63, 59, 52, 45, 40, 32, 14, -6, -24, -32, -31, -30, -23, -18, -12, 1, 9, 21, 31, 41, 44, 33, 21, 5, -6, -20, -29, -43, -57, -69, -77, -73, -65, -52, -41, -27, -8, 11, 32, 49, 57, 64, 61, 55, 47, 39, 36, 29, 13, -8, -25, -36, -35, -26, -16, -9, -5, 1, 9, 22, 36, 45, 43, 33, 17, 1, -11, -21, -32, -45, -57, -71, -78, -73, -61, -45, -33, -23, -8, 11, 31, 46, 53, 57, 54, 48, 40, 34, 31, 27, 14, -4, -20, -29, -28, -22, -12, -4, 1, 4, 8, 21, 34, 43, 43, 31, 17, 1, -11, -22, -31, -44, -59, -72, -78, -70, -54, -40, -28, -19, -8, 10, 28, 45, 53, 57, 53, 43, 34, 28, 27, 26, 18, 0, -18, -31, -29, -20, -11, -3, 2, 5, 10, 19, 31, 43, 44, 34, 19, 2, -13, -23, -32, -43, -55, -68, -77, -73, -57, -41, -26, -15, -6, 11, 28, 43, 52, 52, 49, 41, 33, 24, 22, 21, 14, 1, -14, -25, -24, -18, -7, -2, 2, 7, 10, 20, 31, 40, 43, 33, 18, 3, -13, -24, -35, -44, -55, -70, -78, -74, -59, -40, -26, -11, 1, 13, 29, 44, 53, 57, 54, 45, 32, 24, 18, 13, 9, -4, -16, -26, -29, -22, -10, 1, 8, 13, 18, 23, 35, 42, 45, 37, 21, 5, -14, -30, -41, -49, -57, -69, -77, -76, -61, -39, -20, -5, 9, 20, 34, 47, 53, 55, 48, 39, 27, 14, 8, 3, 2, -4, -15, -23, -24, -16, -3, 6, 11, 19, 24, 30, 34, 41, 43, 35, 18, 1, -17, -31, -44, -52, -59, -68, -75, -73, -61, -38, -19, 1, 13, 23, 30, 42, 52, 52, 47, 36, 23, 14, 7, 4, 0, -6, -11, -20, -24, -18, -5, 7, 15, 18, 22, 28, 36, 43, 43, 38, 24, 4, -13, -30, -44, -55, -64, -69, -77, -76, -65, -44, -19, 1, 15, 27, 35, 46, 53, 53, 46, 36, 23, 11, 3, -5, -7, -9, -14, -20, -23, -19, -7, 11, 18, 21, 25, 30, 40, 43, 43, 38, 24, 7, -14, -30, -41, -55, -65, -73, -77, -74, -66, -49, -24, -2, 17, 29, 35, 44, 51, 54, 49, 35, 23, 11, 1, -6, -12, -15, -16, -20, -24, -21, -10, 8, 21, 27, 33, 35, 42, 48, 47, 37, 23, 7, -12, -28, -44, -60, -69, -75, -78, -74, -65, -49, -25, -2, 17, 30, 40, 48, 54, 55, 48, 36, 20, 6, -4, -9, -14, -20, -22, -24, -21, -15, -6, 7, 21, 32, 39, 43, 44, 49, 50, 38, 21, 4, -13, -28, -47, -62, -74, -77, -78, -77, -65, -48, -26, -4, 15, 28, 40, 50, 56, 54, 46, 33, 20, 9, -2, -10, -16, -21, -21, -23, -21, -15, -5, 9, 19, 30, 38, 42, 44, 46, 47, 36, 22, 6, -10, -23, -39, -57, -74, -78, -79, -75, -65, -51, -33, -11, 9, 25, 37, 46, 55, 56, 48, 34, 21, 10, 4, -4, -14, -20, -25, -24, -21, -12, -3, 8, 17, 26, 36, 47, 50, 50, 47, 36, 25, 10, -5, -21, -40, -57, -75, -82, -79, -75, -64, -51, -37, -16, 5, 25, 40, 48, 55, 55, 49, 37, 25, 15, 6, -6, -18, -26, -29, -25, -20, -16, -7, 5, 17, 29, 39, 49, 56, 56, 51, 39, 28, 15, 0, -17, -38, -58, -75, -86, -86, -80, -70, -54, -37, -16, 7, 25, 42, 50, 55, 58, 52, 40, 25, 11, 2, -5, -14, -21, -26, -26, -18, -12, -5, 4, 13, 25, 34, 45, 53, 55, 48, 39, 25, 16, 3, -13, -31, -54, -70, -83, -85, -78, -68, -55, -38, -20, 1, 20, 36, 46, 51, 55, 48, 39, 27, 17, 7, -5, -13, -20, -23, -23, -18, -10, -4, 3, 10, 21, 29, 40, 48, 52, 50, 40, 28, 20, 10, -5, -24, -48, -67, -82, -87, -81, -73, -56, -44, -25, -5, 15, 34, 46, 52, 55, 51, 39, 27, 18, 7, -2, -13, -22, -25, -24, -16, -9, 1, 8, 13, 22, 30, 42, 48, 50, 47, 38, 26, 15, 6, -8, -22, -41, -61, -77, -86, -81, -70, -54, -40, -27, -8, 12, 31, 42, 49, 50, 48, 38, 26, 16, 7, -4, -11, -18, -22, -21, -16, -9, 0, 9, 15, 21, 26, 35, 47, 50, 46, 36, 28, 18, 7, -7, -22, -37, -53, -70, -81, -83, -72, -58, -43, -30, -14, 5, 22, 37, 44, 46, 44, 37, 26, 17, 8, 2, -7, -12, -17, -16, -12, -6, 3, 8, 13, 17, 22, 31, 42, 43, 43, 35, 29, 25, 14, 2, -17, -35, -51, -65, -77, -80, -75, -63, -47, -34, -18, 4, 21, 32, 38, 41, 41, 36, 28, 17, 8, 1, -9, -12, -16, -15, -9, -2, 8, 13, 15, 17, 23, 28, 39, 43, 38, 30, 21, 17, 11, 4, -12, -28, -45, -60, -68, -71, -66, -58, -49, -38, -23, -5, 15, 27, 34, 34, 32, 28, 23, 18, 13, 4, -2, -7, -9, -7, -4, 5, 14, 16, 16, 14, 15, 24, 35, 39, 35, 23, 17, 15, 11, 8, -4, -19, -37, -53, -62, -65, -62, -57, -53, -43, -31, -14, 5, 19, 27, 31, 28, 26, 23, 20, 18, 11, 5, -2, -5, 0, 3, 8, 14, 16, 15, 11, 7, 12, 23, 32, 32, 21, 12, 10, 13, 12, 6, -9, -27, -43, -50, -55, -53, -51, -52, -44, -38, -23, -6, 7, 18, 22, 19, 16, 15, 16, 19, 17, 12, 6, 3, 7, 10, 16, 20, 23, 20, 14, 8, 9, 17, 27, 26, 17, 6, 3, 7, 10, 7, -5, -18, -32, -41, -46, -45, -45, -45, -44, -40, -30, -16, -3, 8, 15, 12, 10, 11, 16, 19, 19, 16, 12, 10, 11, 15, 20, 25, 26, 24, 18, 11, 6, 11, 17, 21, 15, 3, -6, -2, 4, 7, 2, -14, -25, -32, -36, -38, -37, -37, -35, -33, -33, -25, -15, -4, 3, 4, 0, -3, 2, 13, 21, 21, 20, 17, 19, 23, 27, 31, 33, 31, 24, 16, 4, 2, 7, 13, 13, 3, -10, -9, 0, 8, 7, -3, -15, -22, -24, -30, -32, -37, -39, -38, -37, -34, -28, -17, -8, -2, -4, -4, 4, 16, 26, 30, 26, 22, 22, 25, 29, 31, 30, 29, 24, 17, 6, -2, 7, 10, 13, 4, -11, -15, -10, 3, 8, 2, -10, -17, -17, -17, -23, -29, -35, -37, -34, -36, -35, -28, -19, -10, -11, -14, -8, 8, 21, 26, 26, 21, 24, 31, 38, 40, 38, 37, 33, 26, 15, 4, 1, 2, 1, -6, -19, -24, -18, -7, 2, 5, -4, -10, -9, -6, -7, -16, -27, -33, -35, -38, -41, -38, -32, -22, -20, -18, -10, 4, 20, 29, 31, 30, 28, 32, 38, 43, 42, 39, 34, 28, 14, 4, 1, 3, 4, -5, -21, -30, -26, -14, 1, 3, -4, -8, -8, 0, 0, -8, -15, -26, -29, -35, -40, -40, -36, -30, -28, -29, -22, -10, 9, 22, 28, 28, 27, 30, 39, 46, 50, 50, 43, 33, 21, 9, 3, 3, 1, -10, -22, -35, -34, -22, -8, 2, 0, -6, -7, 0, 5, -2, -9, -18, -28, -34, -41, -43, -39, -35, -33, -33, -25, -12, 5, 19, 26, 29, 31, 31, 39, 46, 51, 52, 47, 38, 27, 18, 10, 5, -3, -13, -22, -33, -36, -28, -16, -4, -2, -4, -6, 0, 8, 7, 0, -12, -22, -33, -40, -42, -39, -37, -38, -39, -32, -17, 2, 15, 24, 25, 28, 33, 39, 47, 51, 53, 51, 44, 35, 23, 15, 8, 1, -12, -25, -37, -41, -33, -22, -11, -4, -5, -3, 3, 10, 13, 6, -5, -17, -28, -38, -43, -44, -44, -44, -43, -36, -23, -7, 7, 20, 26, 29, 35, 43, 51, 54, 58, 56, 52, 44, 29, 18, 9, -2, -12, -28, -39, -45, -38, -26, -16, -7, -3, 1, 6, 12, 15, 12, 3, -11, -25, -37, -41, -43, -46, -47, -46, -39, -28, -15, 0, 11, 21, 25, 31, 38, 46, 53, 60, 62, 59, 53, 42, 32, 19, 6, -10, -27, -41, -47, -47, -39, -31, -21, -9, -2, 5, 11, 16, 19, 13, 2, -15, -30, -35, -37, -43, -47, -49, -42, -32, -21, -11, 0, 8, 19, 27, 38, 47, 51, 58, 63, 63, 59, 50, 41, 28, 10, -9, -26, -37, -43, -44, -40, -33, -23, -11, 0, 6, 9, 14, 15, 13, 1, -15, -25, -32, -34, -43, -49, -50, -43, -30, -20, -13, -9, 0, 10, 23, 36, 46, 52, 55, 62, 65, 66, 61, 51, 36, 15, -7, -24, -34, -42, -45, -46, -42, -34, -20, -5, 5, 11, 14, 16, 13, 2, -10, -18, -24, -31, -39, -49, -48, -42, -34, -24, -18, -15, -8, 2, 13, 29, 42, 51, 57, 62, 65, 70, 69, 60, 45, 20, -3, -24, -37, -43, -46, -49, -48, -39, -24, -6, 5, 12, 17, 20, 16, 6, -9, -15, -21, -26, -38, -50, -56, -50, -37, -26, -23, -19, -14, -4, 11, 27, 42, 54, 58, 63, 65, 68, 70, 63, 50, 26, 1, -21, -37, -43, -44, -44, -44, -40, -28, -11, 5, 10, 16, 18, 14, 5, -12, -19, -22, -24, -33, -47, -52, -52, -38, -25, -17, -17, -16, -10, 4, 22, 39, 53, 59, 62, 63, 66, 68, 66, 55, 32, 9, -17, -34, -43, -42, -39, -38, -38, -31, -19, -3, 10, 17, 19, 12, 3, -12, -21, -24, -24, -31, -40, -49, -52, -41, -30, -18, -15, -17, -10, 0, 16, 33, 47, 59, 65, 64, 65, 67, 63, 56, 38, 13, -12, -32, -41, -39, -35, -33, -32, -27, -17, -4, 8, 15, 16, 13, 4, -11, -20, -25, -27, -32, -40, -48, -52, -46, -37, -25, -18, -16, -10, 1, 16, 33, 49, 59, 66, 67, 65, 66, 62, 51, 38, 15, -9, -30, -38, -41, -33, -29, -26, -23, -17, -5, 7, 16, 15, 14, 5, -9, -19, -27, -31, -34, -40, -47, -52, -49, -40, -30, -22, -16, -8, 4, 19, 32, 46, 59, 67, 71, 69, 64, 57, 49, 36, 17, -7, -27, -38, -40, -35, -28, -23, -19, -12, -5, 6, 12, 16, 15, 10, -5, -19, -28, -32, -36, -39, -46, -53, -52, -45, -34, -25, -18, -7, 6, 20, 33, 46, 60, 67, 74, 71, 65, 56, 46, 37, 18, -2, -20, -33, -38, -38, -30, -22, -16, -12, -6, 2, 6, 15, 15, 11, 1, -11, -19, -31, -37, -42, -46, -51, -54, -53, -46, -35, -26, -14, 3, 17, 33, 45, 57, 67, 75, 77, 71, 62, 50, 36, 18, 0, -19, -31, -36, -37, -31, -23, -17, -11, -6, 1, 6, 11, 15, 14, 8, -3, -16, -27, -37, -41, -47, -52, -58, -60, -55, -46, -32, -16, 0, 17, 32, 46, 59, 70, 79, 80, 75, 65, 51, 35, 20, 2, -15, -27, -38, -42, -36, -27, -17, -10, -4, 3, 7, 12, 18, 19, 14, 5, -7, -22, -37, -46, -53, -57, -62, -67, -65, -58, -43, -22, 1, 20, 35, 48, 60, 69, 79, 82, 79, 68, 53, 36, 21, 4, -11, -24, -36, -40, -38, -31, -21, -14, -5, 1, 5, 11, 17, 22, 19, 14, -2, -17, -35, -48, -55, -63, -67, -73, -72, -64, -49, -27, -4, 19, 36, 52, 64, 73, 81, 85, 82, 72, 56, 36, 20, 3, -14, -24, -33, -36, -35, -32, -22, -13, -6, 2, 7, 10, 15, 19, 19, 17, 6, -10, -29, -48, -58, -67, -71, -75, -78, -72, -58, -35, -10, 16, 35, 52, 65, 74, 80, 86, 87, 79, 62, 39, 21, 5, -11, -22, -33, -39, -39, -34, -25, -15, -7, 3, 8, 16, 17, 21, 22, 19, 9, -6, -27, -47, -60, -71, -77, -80, -81, -73, -61, -39, -12, 16, 36, 52, 63, 73, 80, 85, 87, 76, 59, 41, 23, 8, -7, -18, -29, -36, -38, -33, -23, -13, -8, 1, 6, 14, 18, 19, 23, 23, 17, 1, -20, -43, -57, -67, -78, -83, -89, -81, -67, -45, -19, 9, 35, 55, 67, 74, 80, 87, 91, 83, 68, 44, 24, 6, -9, -21, -29, -36, -39, -39, -31, -20, -10, 1, 13, 20, 26, 26, 27, 28, 22, 8, -16, -40, -60, -75, -86, -93, -95, -89, -75, -52, -24, 7, 37, 57, 69, 77, 83, 90, 93, 85, 70, 48, 27, 8, -8, -19, -26, -32, -35, -39, -37, -28, -17, -2, 9, 19, 21, 27, 31, 32, 29, 12, -9, -32, -54, -71, -86, -94, -96, -90, -82, -62, -33, 2, 34, 56, 69, 78, 87, 94, 94, 85, 69, 49, 29, 9, -10, -21, -27, -30, -33, -37, -36, -29, -17, -5, 9, 19, 25, 27, 31, 33, 33, 21, -2, -25, -51, -71, -86, -95, -95, -92, -85, -69, -42, -8, 27, 52, 67, 74, 83, 92, 95, 89, 75, 56, 35, 16, -6, -17, -26, -28, -34, -41, -39, -37, -25, -9, 6, 20, 28, 31, 37, 37, 34, 24, 3, -20, -46, -69, -85, -96, -99, -97, -89, -73, -47, -11, 21, 45, 61, 73, 84, 92, 95, 89, 77, 61, 41, 20, -2, -13, -20, -28, -36, -43, -46, -40, -30, -16, 0, 12, 24, 30, 38, 43, 41, 33, 13, -14, -39, -63, -80, -93, -98, -100, -94, -76, -52, -19, 14, 38, 56, 70, 80, 90, 94, 88, 75, 58, 40, 22, 6, -8, -19, -25, -33, -39, -41, -38, -31, -19, -5, 7, 21, 31, 39, 45, 42, 32, 15, -8, -32, -55, -77, -93, -102, -101, -94, -80, -57, -29, 5, 34, 54, 70, 78, 88, 96, 92, 80, 62, 41, 24, 8, -9, -21, -32, -35, -38, -41, -39, -35, -22, -6, 6, 21, 31, 39, 46, 44, 35, 18, -5, -27, -49, -70, -86, -97, -102, -96, -84, -58, -30, -2, 26, 45, 62, 74, 82, 89, 89, 80, 66, 46, 28, 12, -3, -14, -26, -36, -39, -42, -40, -36, -28, -15, 0, 17, 30, 37, 45, 48, 40, 23, 3, -20, -43, -64, -81, -93, -98, -96, -85, -65, -38, -8, 20, 40, 55, 68, 80, 88, 88, 82, 68, 54, 35, 18, 2, -12, -24, -35, -40, -45, -45, -41, -33, -20, -4, 15, 31, 41, 49, 52, 48, 32, 13, -14, -38, -59, -77, -92, -101, -102, -91, -70, -45, -15, 15, 38, 53, 65, 77, 89, 91, 85, 71, 52, 38, 21, 5, -12, -26, -36, -42, -45, -45, -43, -34, -22, -7, 9, 26, 39, 50, 56, 50, 34, 14, -7, -29, -50, -69, -84, -96, -98, -90, -72, -50, -24, 7, 32, 48, 57, 68, 84, 91, 88, 74, 58, 44, 30, 11, -9, -26, -38, -41, -46, -45, -44, -38, -23, -7, 9, 24, 36, 49, 55, 51, 35, 18, -3, -24, -45, -64, -78, -89, -93, -90, -75, -54, -29, 0, 23, 42, 54, 67, 80, 90, 91, 81, 65, 48, 31, 13, -5, -24, -41, -50, -53, -51, -46, -42, -28, -10, 8, 23, 36, 50, 59, 56, 44, 26, 8, -13, -35, -56, -77, -89, -94, -92, -80, -61, -39, -11, 14, 33, 50, 63, 77, 88, 89, 81, 67, 54, 38, 21, 1, -23, -39, -50, -54, -53, -46, -42, -31, -17, 1, 17, 33, 46, 56, 56, 46, 33, 16, -4, -24, -46, -67, -82, -92, -94, -87, -67, -45, -19, 4, 22, 43, 62, 76, 87, 90, 87, 76, 59, 40, 20, 1, -22, -40, -55, -62, -58, -50, -40, -29, -17, -3, 14, 33, 49, 59, 58, 49, 35, 21, 2, -17, -39, -59, -76, -90, -93, -86, -70, -49, -29, -8, 12, 33, 57, 75, 84, 87, 84, 78, 65, 47, 28, 6, -18, -39, -58, -65, -64, -57, -44, -33, -22, -10, 6, 26, 44, 56, 56, 48, 40, 27, 11, -8, -30, -49, -65, -80, -86, -87, -72, -51, -31, -13, 5, 24, 48, 70, 81, 86, 83, 79, 69, 51, 30, 8, -16, -37, -55, -65, -67, -61, -48, -36, -21, -10, 5, 22, 40, 55, 58, 53, 43, 31, 16, -2, -23, -45, -60, -74, -82, -86, -75, -56, -36, -16, 1, 21, 44, 65, 81, 88, 85, 81, 72, 54, 33, 8, -18, -41, -58, -71, -74, -70, -56, -41, -23, -6, 8, 23, 38, 53, 60, 59, 50, 37, 22, 1, -20, -41, -56, -69, -79, -83, -78, -62, -42, -20, 2, 22, 41, 59, 77, 86, 87, 79, 67, 50, 31, 10, -15, -36, -52, -63, -69, -69, -59, -41, -23, -9, 4, 15, 29, 44, 55, 56, 53, 43, 27, 12, -8, -27, -44, -57, -68, -78, -77, -67, -48, -29, -12, 12, 32, 52, 70, 79, 84, 82, 73, 59, 38, 15, -9, -33, -52, -63, -71, -72, -66, -50, -30, -13, 2, 12, 27, 42, 50, 54, 54, 46, 34, 19, -2, -19, -35, -47, -61, -71, -72, -66, -51, -36, -19, 5, 27, 46, 63, 74, 79, 79, 70, 58, 41, 21, 3, -24, -44, -58, -66, -66, -65, -52, -36, -22, -10, 4, 18, 34, 43, 49, 52, 48, 43, 31, 14, -4, -21, -35, -51, -61, -66, -64, -56, -43, -29, -8, 16, 37, 54, 67, 72, 74, 70, 61, 46, 27, 7, -19, -40, -56, -62, -62, -63, -55, -43, -26, -10, 3, 13, 26, 38, 44, 47, 43, 39, 30, 19, 5, -12, -24, -40, -47, -51, -53, -51, -44, -32, -14, 6, 24, 41, 54, 61, 63, 61, 56, 47, 32, 13, -9, -31, -46, -56, -53, -54, -54, -48, -37, -18, -3, 8, 17, 27, 33, 38, 39, 39, 37, 30, 18, 1, -16, -29, -35, -39, -42, -47, -47, -39, -22, -3, 14, 29, 42, 51, 57, 56, 54, 45, 36, 20, -2, -23, -41, -50, -51, -52, -53, -51, -42, -27, -8, 5, 12, 19, 28, 35, 40, 39, 40, 37, 28, 12, -7, -23, -28, -30, -37, -43, -49, -45, -32, -15, 3, 19, 34, 45, 49, 49, 51, 47, 41, 26, 6, -18, -34, -43, -45, -45, -48, -51, -49, -33, -15, -2, 8, 12, 19, 26, 33, 38, 38, 38, 34, 25, 8, -11, -19, -20, -23, -32, -43, -48, -41, -24, -8, 10, 21, 31, 38, 43, 47, 48, 45, 34, 16, -9, -31, -41, -42, -42, -46, -52, -52, -40, -23, -6, 6, 11, 17, 24, 30, 35, 38, 39, 40, 29, 14, -3, -14, -14, -15, -24, -36, -47, -45, -33, -15, 3, 14, 23, 29, 35, 39, 44, 45, 38, 22, -3, -26, -38, -37, -37, -41, -50, -56, -45, -26, -8, 5, 12, 16, 22, 27, 32, 39, 41, 41, 33, 17, 1, -9, -8, -8, -16, -30, -41, -45, -35, -21, -5, 10, 18, 24, 28, 31, 38, 42, 39, 25, 2, -23, -36, -36, -37, -39, -47, -53, -47, -31, -11, 3, 12, 16, 23, 27, 32, 37, 40, 41, 33, 18, 2, -7, -8, -6, -10, -23, -36, -41, -35, -20, -6, 7, 14, 17, 24, 29, 36, 42, 40, 28, 5, -20, -35, -38, -38, -39, -45, -51, -46, -33, -15, 2, 13, 22, 27, 28, 27, 30, 37, 41, 35, 20, 5, -4, -4, -2, -3, -13, -28, -35, -32, -23, -10, 3, 11, 14, 14, 20, 28, 37, 40, 27, 7, -16, -31, -36, -37, -36, -41, -44, -45, -35, -18, 1, 12, 19, 25, 26, 27, 31, 34, 39, 34, 20, 8, 0, 0, 1, 0, -9, -23, -33, -34, -24, -10, 2, 8, 8, 10, 16, 27, 34, 35, 27, 10, -10, -27, -35, -35, -34, -39, -46, -47, -38, -22, -3, 10, 19, 26, 31, 32, 32, 35, 41, 39, 25, 9, -2, -3, -2, -2, -7, -19, -30, -33, -26, -14, -3, 6, 6, 7, 12, 26, 37, 37, 26, 10, -8, -25, -35, -39, -39, -42, -47, -49, -42, -27, -4, 12, 20, 29, 33, 36, 35, 35, 38, 37, 27, 10, -3, -6, -3, -2, -7, -16, -24, -28, -24, -13, -4, 4, 5, 7, 9, 19, 30, 33, 28, 12, -6, -24, -35, -40, -39, -42, -47, -47, -41, -26, -8, 10, 22, 31, 36, 41, 39, 34, 33, 33, 29, 15, 2, -7, -8, -6, -6, -10, -18, -24, -24, -15, -5, 6, 7, 7, 10, 17, 23, 23, 18, 9, -7, -23, -36, -42, -41, -41, -45, -45, -39, -28, -11, 7, 21, 31, 36, 39, 39, 34, 31, 33, 29, 19, 7, -5, -6, -6, -4, -6, -13, -17, -20, -16, -8, 1, 6, 7, 7, 11, 16, 20, 18, 9, -7, -24, -37, -43, -42, -42, -42, -45, -41, -28, -11, 7, 19, 28, 35, 40, 42, 38, 33, 29, 27, 21, 10, -2, -8, -8, -6, -8, -11, -13, -16, -14, -8, 1, 5, 8, 9, 15, 19, 20, 18, 9, -4, -18, -34, -42, -46, -47, -45, -47, -45, -36, -20, 0, 13, 26, 36, 45, 48, 42, 35, 29, 28, 26, 20, 6, -6, -10, -10, -6, -7, -8, -10, -14, -10, -7, 0, 6, 8, 13, 14, 16, 13, 7, -3, -13, -27, -37, -44, -49, -44, -42, -40, -37, -25, -9, 9, 23, 31, 41, 44, 44, 37, 30, 27, 28, 27, 15, 2, -7, -9, -6, -7, -9, -8, -13, -12, -8, -3, 4, 9, 13, 14, 14, 11, 6, 0, -9, -23, -34, -43, -49, -46, -42, -40, -35, -29, -13, 3, 19, 31, 41, 45, 43, 37, 31, 29, 30, 28, 19, 4, -5, -7, -7, -5, -8, -7, -9, -11, -9, -4, 0, 6, 12, 14, 13, 9, 5, -3, -9, -19, -28, -37, -48, -48, -45, -39, -34, -30, -18, -5, 12, 23, 34, 42, 44, 39, 34, 32, 31, 33, 30, 18, 8, 1, -5, -6, -5, -5, -8, -13, -16, -14, -7, 2, 7, 11, 10, 7, 4, -2, -7, -12, -22, -32, -45, -50, -45, -38, -33, -30, -24, -13, 2, 20, 31, 39, 43, 42, 38, 36, 33, 33, 33, 24, 14, 1, -8, -9, -7, -4, -5, -11, -16, -16, -11, -4, 2, 9, 8, 7, 3, -3, -6, -9, -15, -24, -38, -47, -48, -42, -35, -32, -29, -21, -9, 11, 27, 35, 42, 42, 42, 40, 40, 38, 36, 30, 19, 8, -4, -9, -8, -5, -5, -12, -18, -20, -15, -5, -2, 3, 4, 5, 6, 1, -3, -8, -12, -19, -31, -43, -47, -43, -36, -35, -36, -32, -19, 2, 19, 30, 38, 42, 46, 49, 50, 47, 43, 39, 28, 16, 1, -10, -13, -11, -9, -14, -21, -25, -20, -10, -4, 1, 3, 4, 7, 4, -3, -7, -7, -10, -23, -38, -47, -46, -41, -37, -38, -37, -27, -11, 11, 24, 33, 38, 45, 50, 53, 52, 48, 43, 37, 25, 10, -3, -11, -11, -11, -13, -20, -27, -29, -22, -14, -7, -2, 2, 6, 3, -2, -3, 0, 0, -11, -28, -41, -45, -39, -35, -36, -39, -37, -24, -7, 11, 22, 32, 41, 51, 55, 56, 54, 53, 50, 40, 23, 6, -5, -10, -11, -14, -20, -28, -34, -33, -25, -16, -10, -5, 0, 0, 1, 2, 4, 5, -4, -16, -29, -35, -37, -37, -35, -39, -39, -32, -19, 0, 13, 23, 36, 46, 54, 58, 57, 59, 56, 47, 33, 16, 3, -5, -9, -11, -19, -29, -36, -39, -33, -26, -18, -12, -7, -5, -2, 4, 11, 15, 10, -3, -18, -29, -32, -35, -36, -41, -44, -40, -30, -18, 0, 13, 28, 41, 50, 59, 63, 66, 66, 60, 44, 26, 11, 2, -6, -12, -19, -29, -38, -44, -41, -33, -25, -16, -9, -8, -6, 1, 11, 18, 16, 8, -6, -17, -27, -32, -36, -39, -43, -44, -37, -30, -12, 8, 26, 39, 46, 56, 64, 70, 72, 66, 51, 36, 18, 7, -4, -11, -18, -29, -42, -50, -51, -45, -35, -23, -14, -10, -9, 0, 14, 27, 29, 20, 7, -5, -15, -23, -30, -38, -45, -50, -49, -43, -30, -9, 13, 31, 41, 52, 65, 75, 79, 77, 66, 50, 30, 13, 3, -6, -14, -26, -41, -53, -57, -54, -44, -32, -23, -17, -13, -5, 10, 24, 31, 28, 20, 9, -5, -17, -26, -35, -40, -48, -54, -53, -44, -23, 0, 21, 35, 46, 60, 73, 81, 83, 77, 60, 42, 25, 11, 1, -11, -25, -42, -57, -64, -62, -54, -43, -33, -24, -17, -6, 9, 23, 37, 37, 33, 19, 6, -9, -20, -30, -41, -49, -57, -59, -54, -38, -16, 10, 31, 46, 58, 70, 78, 85, 84, 73, 54, 32, 16, 5, -5, -22, -41, -60, -72, -71, -66, -54, -43, -30, -19, -6, 10, 25, 41, 47, 43, 32, 20, 7, -10, -25, -40, -52, -61, -68, -65, -54, -34, -11, 16, 39, 57, 72, 80, 88, 91, 83, 67, 46, 28, 13, 1, -18, -40, -62, -77, -77, -70, -63, -54, -43, -30, -12, 7, 25, 40, 51, 51, 42, 31, 19, 3, -13, -32, -48, -60, -68, -71, -63, -49, -28, -2, 23, 46, 66, 77, 86, 92, 89, 82, 62, 43, 22, 7, -12, -39, -59, -74, -80, -78, -72, -63, -50, -35, -17, 5, 22, 35, 45, 49, 49, 42, 31, 13, -7, -25, -38, -49, -59, -66, -65, -57, -42, -20, 8, 34, 55, 69, 79, 84, 84, 84, 77, 64, 42, 18, -6, -29, -49, -69, -82, -87, -87, -78, -66, -48, -27, -4, 17, 33, 47, 56, 60, 58, 49, 31, 8, -18, -36, -47, -57, -67, -75, -74, -60, -36, -3, 25, 48, 65, 76, 83, 87, 90, 88, 77, 52, 24, -4, -26, -42, -61, -77, -91, -94, -85, -70, -54, -34, -11, 12, 30, 44, 56, 63, 66, 61, 43, 19, -8, -27, -39, -49, -62, -74, -80, -71, -49, -20, 9, 34, 56, 70, 79, 86, 93, 96, 91, 70, 41, 11, -18, -39, -58, -77, -91, -99, -95, -83, -65, -42, -17, 7, 27, 43, 57, 66, 69, 67, 55, 32, 5, -21, -32, -42, -56, -73, -84, -79, -60, -33, -5, 21, 44, 61, 72, 80, 92, 100, 99, 82, 54, 23, -10, -31, -51, -71, -87, -101, -101, -92, -76, -49, -24, 1, 21, 37, 52, 66, 72, 72, 64, 44, 18, -7, -23, -31, -45, -64, -79, -83, -71, -46, -18, 7, 27, 46, 62, 72, 85, 97, 100, 92, 65, 35, 2, -22, -40, -60, -78, -92, -100, -96, -82, -59, -29, -6, 15, 28, 44, 57, 65, 67, 65, 49, 27, 2, -17, -23, -35, -53, -70, -79, -73, -52, -27, -4, 16, 35, 54, 65, 77, 88, 95, 93, 73, 44, 12, -17, -38, -54, -74, -86, -97, -98, -89, -69, -37, -11, 9, 27, 42, 56, 65, 68, 71, 59, 39, 13, -9, -20, -30, -45, -62, -74, -75, -60, -41, -18, 3, 23, 43, 60, 74, 83, 91, 91, 78, 52, 22, -8, -30, -46, -66, -82, -90, -92, -85, -70, -44, -17, 5, 22, 33, 45, 56, 60, 63, 56, 39, 21, 5, -9, -20, -33, -49, -62, -70, -62, -47, -28, -9, 11, 29, 47, 60, 73, 83, 87, 81, 62, 32, 4, -21, -39, -60, -78, -88, -90, -86, -73, -55, -28, -2, 18, 30, 42, 50, 57, 58, 53, 44, 27, 15, 4, -10, -24, -40, -53, -59, -57, -49, -38, -21, -3, 17, 34, 49, 62, 75, 81, 76, 63, 39, 15, -11, -31, -50, -69, -79, -84, -82, -73, -57, -34, -7, 12, 26, 35, 42, 50, 56, 53, 42, 31, 20, 13, 1, -16, -30, -43, -50, -51, -49, -42, -28, -11, 7, 23, 38, 52, 65, 75, 73, 62, 43, 20, -2, -24, -43, -60, -69, -74, -74, -69, -59, -42, -19, 2, 19, 27, 34, 41, 48, 50, 45, 39, 33, 25, 13, -3, -18, -32, -42, -47, -49, -47, -40, -27, -8, 11, 28, 43, 57, 69, 73, 65, 50, 31, 8, -16, -36, -53, -63, -70, -72, -70, -62, -46, -25, -6, 11, 23, 30, 38, 45, 49, 50, 46, 42, 33, 22, 6, -13, -25, -37, -43, -48, -50, -45, -35, -18, 2, 21, 39, 51, 61, 64, 63, 53, 38, 19, -6, -30, -49, -59, -63, -65, -66, -64, -52, -31, -14, 2, 13, 25, 35, 42, 46, 46, 47, 48, 44, 33, 15, -6, -21, -32, -37, -42, -48, -46, -39, -26, -8, 12, 31, 45, 55, 58, 57, 51, 39, 22, 2, -21, -39, -49, -56, -59, -62, -59, -52, -38, -22, -9, 5, 16, 25, 32, 40, 46, 51, 54, 52, 40, 24, 5, -11, -20, -28, -35, -44, -48, -43, -33, -17, 0, 18, 32, 44, 48, 49, 48, 40, 28, 11, -10, -26, -37, -45, -52, -58, -57, -51, -41, -29, -19, -10, 3, 15, 27, 36, 40, 50, 59, 60, 51, 33, 15, 2, -11, -21, -34, -45, -49, -45, -36, -25, -11, 8, 26, 38, 43, 42, 41, 39, 31, 16, -5, -24, -31, -37, -43, -51, -54, -49, -40, -31, -24, -13, -3, 12, 22, 29, 33, 43, 55, 60, 53, 37, 18, 5, -4, -12, -23, -35, -44, -42, -35, -26, -15, -2, 15, 26, 33, 31, 31, 29, 28, 21, 6, -13, -27, -30, -37, -44, -48, -45, -39, -34, -28, -18, -8, 4, 17, 23, 31, 40, 51, 58, 56, 42, 25, 12, 2, -7, -16, -27, -36, -39, -37, -31, -21, -12, 3, 14, 21, 25, 23, 23, 25, 23, 11, -4, -16, -21, -26, -34, -39, -40, -34, -31, -30, -23, -17, -3, 9, 16, 23, 31, 42, 54, 57, 49, 29, 14, 7, 4, -3, -15, -26, -32, -32, -31, -24, -16, -5, 5, 8, 10, 9, 10, 16, 19, 14, 4, -8, -14, -16, -21, -29, -34, -33, -30, -29, -26, -20, -10, 2, 11, 20, 28, 40, 51, 55, 51, 33, 17, 9, 6, 4, -9, -20, -28, -32, -29, -25, -20, -11, -2, 3, 4, 1, 6, 12, 18, 16, 8, -5, -10, -14, -17, -20, -23, -25, -26, -28, -26, -21, -12, -2, 6, 13, 20, 29, 40, 48, 48, 37, 23, 13, 8, 7, 3, -6, -15, -22, -24, -24, -21, -16, -10, -6, -11, -15, -10, 1, 12, 15, 9, 4, 3, 1, -5, -11, -18, -18, -22, -25, -29, -27, -19, -7, 4, 10, 14, 21, 35, 46, 48, 40, 27, 16, 13, 11, 11, 5, -5, -14, -19, -21, -24, -19, -14, -13, -17, -21, -21, -11, 1, 11, 12, 5, 3, 2, 5, 6, 0, -6, -16, -20, -25, -26, -20, -12, -4, 1, 5, 11, 25, 38, 46, 41, 33, 21, 17, 15, 15, 14, 8, -3, -14, -23, -27, -26, -21, -20, -22, -26, -25, -20, -7, 5, 10, 10, 8, 5, 6, 6, 5, 1, -7, -14, -20, -23, -21, -17, -11, -4, 2, 7, 17, 29, 38, 40, 37, 30, 23, 21, 20, 17, 14, 5, -6, -19, -26, -29, -25, -24, -27, -28, -28, -26, -18, -4, 6, 9, 8, 4, 5, 10, 12, 11, 3, -8, -15, -18, -18, -15, -11, -10, -5, 1, 8, 16, 26, 35, 35, 31, 24, 22, 21, 22, 21, 16, 5, -12, -24, -30, -31, -29, -31, -32, -31, -32, -22, -12, 0, 7, 11, 12, 10, 11, 15, 13, 10, 2, -10, -13, -16, -17, -14, -14, -12, -6, 0, 10, 20, 26, 32, 30, 29, 27, 26, 28, 26, 22, 13, -2, -16, -25, -30, -32, -33, -35, -35, -34, -28, -19, -12, -5, 1, 5, 9, 11, 16, 17, 18, 11, 3, -4, -10, -12, -13, -12, -13, -14, -10, -4, 8, 20, 27, 31, 31, 28, 29, 31, 30, 26, 17, 5, -9, -23, -32, -37, -36, -34, -35, -34, -32, -24, -16, -7, 2, 4, 6, 10, 16, 17, 15, 12, 8, 3, -5, -11, -11, -10, -11, -12, -11, -5, 3, 13, 22, 30, 32, 27, 25, 25, 28, 27, 19, 7, -8, -22, -31, -34, -32, -30, -28, -31, -31, -29, -21, -12, -4, 1, 1, 3, 10, 16, 18, 18, 14, 12, 3, -5, -8, -7, -8, -10, -12, -12, -5, 6, 16, 26, 30, 29, 24, 25, 26, 29, 23, 13, -2, -16, -26, -32, -33, -30, -30, -30, -30, -29, -25, -18, -12, -5, -2, 2, 8, 14, 18, 16, 18, 14, 10, 4, 0, -5, -4, -7, -9, -14, -10, -3, 9, 19, 26, 26, 23, 23, 26, 29, 28, 21, 7, -10, -19, -25, -26, -27, -27, -29, -30, -32, -31, -27, -19, -13, -9, -7, 0, 9, 18, 24, 26, 21, 13, 9, 8, 4, -2, -6, -9, -11, -11, -7, 4, 16, 24, 26, 21, 19, 22, 26, 29, 23, 7, -10, -17, -19, -19, -23, -25, -25, -25, -26, -26, -29, -26, -17, -14, -9, -7, 1, 12, 21, 26, 23, 18, 13, 11, 11, 6, -4, -6, -10, -10, -9, -2, 9, 20, 25, 23, 18, 18, 23, 26, 24, 10, -5, -13, -17, -14, -15, -17, -20, -24, -25, -29, -31, -32, -28, -22, -16, -13, -8, 2, 14, 25, 27, 27, 22, 17, 15, 13, 10, 5, -3, -6, -8, -6, 1, 11, 18, 20, 13, 11, 15, 19, 20, 14, 4, -4, -12, -12, -12, -12, -14, -17, -23, -30, -35, -37, -31, -26, -20, -16, -12, -4, 9, 22, 28, 26, 22, 17, 14, 15, 11, 8, 6, 2, 0, -2, 4, 11, 16, 16, 12, 7, 8, 13, 13, 10, 1, -5, -8, -8, -8, -7, -7, -10, -20, -26, -34, -36, -33, -31, -29, -25, -19, -12, 4, 18, 27, 28, 23, 22, 18, 19, 17, 14, 9, 7, 4, 0, 2, 8, 14, 16, 12, 2, 0, 2, 5, 6, 2, -4, -7, -6, -2, -2, -3, -5, -11, -19, -28, -37, -37, -37, -34, -29, -24, -18, -8, 7, 20, 25, 25, 25, 22, 21, 21, 21, 19, 15, 11, 6, 6, 6, 10, 11, 6, -2, -5, -5, -2, 0, 0, 0, -4, 0, 2, 4, 2, -2, -8, -16, -25, -34, -39, -42, -39, -33, -26, -21, -16, -4, 11, 22, 25, 27, 25, 23, 23, 24, 25, 22, 17, 13, 10, 9, 12, 10, 4, -5, -12, -12, -11, -9, -8, -6, -5, 1, 4, 8, 10, 7, 4, -7, -18, -26, -34, -39, -43, -42, -34, -28, -22, -13, 2, 14, 18, 21, 23, 27, 30, 32, 31, 28, 23, 20, 20, 15, 14, 10, 2, -5, -13, -15, -16, -16, -12, -12, -5, 1, 5, 8, 8, 10, 8, 0, -13, -23, -27, -33, -40, -44, -41, -32, -24, -17, -6, 3, 9, 17, 22, 25, 29, 34, 39, 36, 32, 26, 25, 23, 19, 11, 1, -9, -16, -18, -17, -19, -21, -17, -8, 0, 4, 7, 8, 10, 11, 6, -4, -13, -21, -25, -35, -40, -41, -37, -26, -21, -13, -8, -3, 6, 15, 23, 27, 35, 40, 41, 38, 33, 31, 29, 24, 16, 5, -5, -16, -23, -23, -23, -18, -14, -6, 2, 3, 4, 7, 11, 13, 7, -5, -13, -21, -25, -32, -40, -42, -37, -28, -21, -14, -13, -9, 1, 11, 22, 27, 33, 39, 43, 42, 41, 33, 29, 25, 18, 7, -6, -17, -25, -24, -23, -21, -16, -9, 2, 6, 5, 5, 10, 15, 12, 3, -8, -16, -22, -29, -39, -44, -42, -34, -27, -22, -21, -17, -8, 4, 19, 29, 40, 48, 53, 51, 49, 43, 38, 28, 19, 6, -9, -19, -27, -30, -30, -24, -16, -10, -3, 3, 6, 5, 6, 9, 11, 7, 2, -7, -16, -25, -34, -37, -37, -33, -31, -28, -27, -24, -20, -10, 8, 22, 35, 46, 52, 53, 54, 49, 46, 37, 23, 9, -7, -18, -24, -30, -32, -28, -22, -12, -5, 1, 6, 4, 8, 9, 11, 9, 3, -3, -13, -21, -32, -37, -38, -35, -34, -32, -32, -32, -27, -14, 5, 24, 38, 48, 55, 56, 56, 54, 50, 40, 23, 4, -10, -18, -24, -26, -29, -29, -24, -17, -5, 2, 9, 9, 6, 6, 7, 12, 11, 6, -7, -18, -30, -36, -36, -37, -35, -38, -40, -41, -36, -24, -2, 20, 35, 47, 55, 60, 62, 62, 61, 47, 26, 7, -12, -18, -22, -24, -28, -33, -31, -24, -12, -2, 7, 9, 5, 4, 5, 11, 14, 13, 7, -8, -24, -37, -41, -38, -34, -37, -44, -50, -46, -33, -10, 16, 36, 49, 57, 61, 64, 66, 65, 55, 34, 11, -14, -24, -26, -26, -24, -30, -34, -33, -24, -7, 5, 12, 10, 5, 6, 9, 16, 22, 21, 10, -10, -32, -45, -44, -38, -38, -47, -61, -60, -48, -21, 11, 34, 51, 60, 63, 66, 70, 69, 63, 45, 18, -10, -27, -27, -23, -20, -28, -36, -37, -32, -17, -2, 8, 9, 5, 6, 8, 15, 24, 30, 25, 5, -22, -41, -44, -40, -38, -50, -64, -72, -62, -37, -3, 29, 52, 62, 66, 69, 73, 78, 72, 54, 26, -5, -25, -32, -29, -24, -27, -34, -37, -36, -26, -11, 5, 15, 15, 11, 9, 15, 26, 35, 33, 14, -14, -37, -49, -47, -45, -51, -63, -72, -66, -42, -10, 22, 49, 64, 69, 69, 70, 75, 73, 59, 34, 4, -20, -30, -30, -25, -24, -29, -36, -40, -35, -22, -2, 16, 20, 17, 14, 15, 27, 39, 41, 27, -4, -32, -48, -54, -53, -59, -65, -73, -71, -55, -23, 16, 49, 67, 70, 68, 71, 77, 78, 65, 40, 10, -17, -31, -34, -28, -24, -26, -31, -40, -40, -30, -10, 10, 21, 18, 15, 16, 26, 40, 48, 40, 13, -20, -44, -55, -61, -63, -69, -76, -76, -63, -35, 6, 41, 66, 75, 71, 71, 75, 77, 67, 44, 17, -10, -25, -34, -35, -29, -27, -28, -35, -40, -35, -18, 1, 16, 21, 20, 19, 25, 38, 47, 43, 23, -9, -34, -50, -59, -65, -72, -76, -74, -66, -43, -9, 27, 58, 71, 69, 70, 71, 73, 67, 48, 25, 2, -18, -28, -33, -29, -25, -25, -31, -39, -41, -28, -10, 8, 19, 20, 23, 27, 36, 45, 45, 31, 4, -22, -45, -58, -67, -74, -75, -73, -66, -50, -21, 16, 49, 67, 73, 72, 72, 74, 69, 53, 33, 9, -11, -25, -34, -35, -31, -27, -30, -38, -43, -33, -16, 6, 18, 24, 27, 30, 38, 45, 46, 34, 10, -16, -40, -61, -70, -77, -76, -72, -66, -52, -31, 2, 36, 60, 71, 72, 69, 71, 68, 57, 44, 20, 2, -17, -32, -36, -33, -31, -31, -40, -46, -41, -29, -5, 16, 27, 34, 35, 41, 49, 51, 41, 17, -11, -34, -56, -71, -79, -80, -76, -68, -57, -36, -10, 21, 48, 64, 71, 71, 73, 69, 61, 48, 32, 11, -5, -21, -31, -34, -34, -37, -43, -48, -45, -34, -14, 8, 25, 34, 41, 43, 49, 51, 43, 26, -2, -27, -49, -65, -74, -77, -74, -70, -58, -42, -20, 9, 38, 56, 64, 67, 69, 71, 66, 53, 37, 16, 1, -15, -30, -33, -39, -38, -41, -45, -42, -35, -15, 7, 25, 36, 41, 45, 49, 49, 40, 23, 1, -20, -41, -59, -71, -75, -73, -65, -57, -45, -28, -6, 22, 42, 56, 63, 67, 71, 70, 59, 44, 28, 12, -3, -19, -32, -40, -41, -46, -47, -46, -37, -20, -2, 20, 34, 45, 48, 52, 53, 42, 26, 4, -15, -35, -51, -65, -70, -70, -68, -61, -50, -34, -15, 9, 28, 45, 54, 64, 71, 72, 67, 53, 40, 24, 8, -10, -27, -37, -41, -49, -53, -53, -42, -25, -8, 14, 31, 43, 52, 56, 56, 46, 30, 11, -8, -26, -43, -59, -70, -69, -68, -62, -55, -44, -25, -4, 17, 36, 48, 62, 69, 69, 67, 57, 47, 33, 17, -2, -21, -33, -41, -47, -52, -53, -43, -25, -10, 9, 23, 36, 46, 52, 54, 47, 31, 14, -4, -19, -32, -49, -57, -62, -60, -57, -58, -51, -39, -19, 6, 23, 38, 51, 60, 68, 71, 67, 58, 44, 27, 7, -17, -32, -41, -47, -52, -54, -46, -31, -12, 7, 22, 35, 45, 51, 53, 46, 33, 18, 2, -12, -26, -42, -55, -61, -60, -56, -57, -55, -46, -29, -8, 10, 27, 42, 55, 65, 70, 69, 61, 49, 34, 16, -5, -23, -36, -45, -51, -54, -50, -35, -17, 3, 17, 29, 37, 44, 51, 47, 39, 21, 6, -8, -20, -31, -44, -52, -58, -60, -58, -58, -51, -39, -22, -4, 14, 31, 48, 62, 70, 69, 65, 57, 45, 28, 7, -15, -31, -44, -50, -53, -50, -39, -24, -6, 11, 24, 33, 43, 46, 45, 35, 25, 14, 1, -13, -23, -35, -44, -53, -57, -59, -59, -57, -47, -33, -15, 3, 21, 39, 56, 69, 72, 69, 60, 49, 36, 17, -5, -25, -42, -52, -52, -48, -40, -26, -9, 9, 20, 29, 34, 39, 40, 34, 25, 16, 6, -6, -16, -27, -34, -44, -50, -55, -58, -57, -52, -41, -27, -11, 11, 31, 51, 67, 70, 68, 61, 53, 43, 30, 7, -14, -35, -49, -54, -50, -40, -26, -13, -2, 9, 22, 30, 38, 41, 36, 28, 20, 12, 4, -5, -15, -26, -41, -52, -58, -60, -60, -59, -55, -41, -25, -5, 19, 42, 62, 74, 75, 70, 63, 55, 43, 22, -3, -24, -42, -51, -50, -45, -32, -22, -14, -2, 14, 28, 35, 34, 33, 30, 25, 21, 11, 4, -6, -18, -32, -46, -56, -61, -61, -62, -60, -51, -39, -16, 11, 37, 58, 70, 75, 72, 67, 58, 46, 31, 10, -17, -35, -48, -49, -41, -28, -17, -14, -7, 4, 18, 28, 32, 29, 27, 21, 19, 16, 7, 2, -11, -22, -35, -48, -57, -61, -60, -60, -56, -47, -30, -5, 23, 48, 63, 72, 75, 71, 64, 53, 39, 20, -2, -22, -40, -48, -45, -34, -21, -17, -10, -4, 10, 22, 27, 28, 29, 26, 26, 22, 14, 7, -3, -14, -30, -46, -59, -65, -65, -65, -64, -56, -41, -17, 15, 42, 62, 73, 77, 75, 69, 57, 43, 25, 6, -12, -31, -44, -46, -37, -24, -16, -11, -3, 6, 20, 24, 23, 24, 23, 25, 23, 16, 9, 1, -10, -23, -41, -56, -63, -67, -67, -66, -59, -47, -25, 3, 32, 54, 70, 75, 76, 70, 62, 47, 32, 15, -3, -21, -38, -44, -41, -31, -21, -15, -11, -2, 8, 18, 24, 27, 28, 29, 29, 24, 17, 8, -2, -17, -35, -54, -66, -73, -74, -71, -66, -55, -35, -6, 24, 50, 69, 77, 79, 74, 63, 51, 38, 22, 2, -17, -35, -42, -39, -32, -24, -17, -11, -5, 6, 13, 20, 28, 31, 33, 29, 23, 15, 10, 3, -12, -30, -51, -65, -73, -75, -71, -67, -58, -41, -18, 11, 38, 60, 75, 77, 74, 64, 53, 42, 31, 15, -7, -25, -38, -40, -37, -29, -24, -15, -11, -2, 9, 17, 28, 33, 36, 33, 27, 18, 13, 4, -8, -26, -48, -65, -75, -76, -72, -68, -58, -43, -18, 11, 37, 58, 72, 76, 73, 63, 51, 40, 28, 13, -6, -23, -35, -41, -40, -33, -24, -16, -9, -2, 7, 18, 29, 38, 42, 38, 31, 21, 11, 3, -10, -26, -47, -65, -75, -79, -75, -69, -58, -39, -19, 7, 33, 54, 71, 77, 75, 66, 52, 39, 27, 15, -2, -22, -35, -41, -41, -36, -27, -17, -8, 1, 11, 22, 33, 41, 47, 45, 35, 21, 11, 4, -7, -24, -46, -66, -77, -81, -79, -73, -62, -44, -24, -2, 23, 47, 69, 79, 79, 70, 57, 45, 33, 20, 5, -18, -36, -43, -41, -37, -32, -23, -14, -3, 8, 20, 34, 45, 53, 52, 41, 27, 16, 7, -5, -24, -47, -69, -83, -86, -84, -74, -62, -44, -22, 1, 24, 47, 66, 78, 76, 69, 57, 43, 31, 17, 5, -13, -33, -43, -46, -41, -31, -22, -12, 0, 11, 24, 39, 49, 57, 58, 48, 30, 15, 4, -8, -26, -52, -74, -86, -89, -83, -74, -60, -43, -21, 1, 22, 45, 65, 78, 79, 68, 54, 40, 26, 17, 7, -9, -31, -45, -46, -40, -31, -21, -11, 0, 8, 21, 39, 51, 60, 60, 52, 36, 19, 4, -9, -25, -49, -71, -87, -92, -89, -79, -63, -45, -24, 0, 22, 43, 65, 75, 80, 70, 57, 44, 30, 16, 2, -14, -31, -46, -52, -47, -35, -21, -9, 1, 12, 26, 44, 59, 68, 68, 59, 42, 22, 6, -11, -29, -49, -72, -87, -96, -95, -86, -67, -46, -23, -4, 16, 38, 59, 76, 82, 74, 61, 45, 31, 20, 3, -14, -30, -44, -51, -51, -41, -26, -11, 3, 13, 25, 44, 61, 71, 72, 59, 45, 28, 9, -10, -33, -53, -70, -83, -93, -96, -91, -74, -53, -27, -6, 15, 35, 53, 71, 80, 77, 66, 51, 34, 20, 3, -15, -30, -45, -53, -55, -48, -32, -17, 1, 16, 29, 47, 62, 73, 77, 67, 50, 30, 9, -10, -32, -55, -73, -86, -93, -94, -90, -76, -54, -27, -4, 17, 32, 48, 64, 74, 78, 68, 55, 38, 17, 1, -15, -28, -39, -47, -52, -49, -37, -21, -3, 16, 31, 46, 61, 70, 75, 70, 55, 36, 13, -9, -32, -56, -72, -84, -89, -93, -91, -81, -61, -30, -5, 18, 32, 45, 58, 71, 76, 70, 57, 40, 18, 1, -17, -28, -35, -45, -52, -50, -39, -25, -7, 15, 33, 48, 60, 67, 73, 70, 60, 42, 19, -8, -34, -57, -69, -77, -83, -87, -92, -85, -66, -39, -10, 12, 27, 39, 52, 62, 73, 72, 61, 46, 25, 4, -14, -27, -34, -41, -46, -48, -43, -30, -11, 14, 38, 53, 63, 66, 69, 72, 65, 48, 23, -4, -31, -56, -72, -81, -83, -87, -91, -87, -72, -46, -15, 11, 28, 40, 50, 60, 71, 75, 69, 54, 32, 8, -13, -29, -39, -45, -48, -50, -48, -40, -21, 9, 37, 57, 66, 71, 74, 75, 71, 55, 32, 2, -29, -55, -73, -81, -84, -87, -89, -88, -75, -49, -19, 10, 29, 39, 48, 53, 62, 72, 68, 58, 35, 9, -11, -27, -34, -39, -42, -44, -46, -41, -26, 5, 35, 56, 65, 69, 72, 73, 72, 59, 37, 9, -22, -50, -71, -83, -83, -83, -86, -88, -81, -55, -24, 5, 24, 37, 48, 54, 59, 64, 66, 59, 41, 17, -9, -27, -36, -38, -39, -42, -45, -41, -28, -2, 28, 53, 65, 68, 71, 71, 70, 58, 40, 16, -14, -46, -67, -79, -81, -80, -83, -87, -83, -64, -36, -4, 19, 35, 46, 51, 58, 65, 69, 64, 49, 26, -2, -25, -38, -41, -39, -40, -43, -45, -33, -8, 24, 52, 65, 72, 74, 72, 66, 55, 40, 20, -7, -38, -65, -80, -85, -80, -82, -84, -82, -65, -38, -9, 13, 29, 41, 49, 57, 62, 64, 59, 48, 29, 6, -19, -36, -39, -37, -35, -38, -39, -31, -11, 19, 47, 63, 70, 71, 71, 65, 55, 38, 17, -4, -33, -58, -76, -83, -79, -79, -80, -82, -70, -46, -19, 8, 25, 36, 43, 51, 59, 63, 62, 50, 34, 14, -9, -27, -35, -38, -36, -38, -39, -30, -15, 10, 34, 52, 67, 73, 74, 68, 54, 37, 21, 2, -21, -45, -68, -78, -81, -81, -80, -79, -70, -51, -28, -4, 17, 32, 40, 48, 56, 59, 57, 46, 34, 18, 3, -20, -34, -39, -35, -31, -30, -26, -13, 8, 31, 48, 61, 67, 69, 66, 53, 38, 16, -4, -23, -41, -58, -72, -78, -80, -76, -74, -64, -50, -33, -8, 12, 28, 35, 41, 50, 57, 53, 44, 31, 20, 10, -8, -24, -34, -34, -30, -25, -21, -13, 5, 22, 38, 52, 61, 66, 65, 53, 36, 15, -4, -18, -33, -45, -61, -73, -79, -78, -72, -62, -49, -33, -13, 3, 19, 29, 38, 48, 52, 49, 41, 29, 22, 14, 2, -11, -25, -27, -25, -20, -15, -8, 4, 19, 30, 42, 53, 57, 61, 50, 32, 15, -7, -18, -27, -37, -50, -65, -73, -72, -66, -57, -49, -37, -19, -3, 13, 23, 32, 41, 44, 41, 35, 29, 26, 21, 10, -2, -13, -21, -18, -14, -8, -4, 3, 12, 21, 29, 42, 51, 54, 49, 32, 14, -5, -15, -22, -28, -39, -55, -69, -68, -62, -52, -44, -37, -25, -11, 4, 16, 24, 32, 37, 35, 28, 23, 23, 23, 18, 8, -4, -12, -12, -8, -2, 5, 9, 14, 18, 23, 31, 41, 45, 43, 29, 11, -8, -18, -23, -21, -29, -43, -60, -65, -58, -50, -39, -32, -26, -17, -6, 8, 18, 25, 31, 29, 24, 17, 20, 24, 25, 19, 8, 0, -5, -3, 4, 11, 13, 12, 14, 16, 22, 31, 38, 37, 27, 9, -11, -22, -24, -22, -25, -36, -50, -57, -53, -46, -37, -30, -24, -17, -9, 1, 10, 16, 20, 19, 17, 13, 14, 21, 24, 24, 19, 10, 8, 9, 13, 18, 20, 15, 12, 11, 14, 21, 27, 30, 21, 8, -12, -23, -24, -22, -20, -29, -40, -49, -47, -41, -33, -26, -23, -20, -16, -11, -2, 7, 12, 14, 14, 13, 14, 19, 26, 30, 26, 20, 11, 11, 16, 21, 26, 22, 18, 15, 14, 15, 19, 20, 16, 4, -15, -29, -32, -27, -21, -24, -34, -40, -41, -33, -28, -24, -21, -20, -15, -14, -10, -5, 1, 7, 10, 10, 12, 18, 26, 36, 34, 27, 21, 17, 20, 23, 25, 24, 19, 11, 10, 9, 12, 16, 14, 3, -16, -32, -34, -27, -19, -20, -27, -34, -35, -31, -27, -22, -18, -18, -19, -19, -20, -15, -7, 2, 6, 8, 9, 18, 26, 38, 41, 37, 28, 21, 23, 25, 27, 25, 20, 13, 7, 3, 5, 9, 11, 4, -14, -31, -35, -29, -20, -18, -23, -26, -32, -29, -25, -23, -15, -17, -18, -21, -25, -23, -15, -6, 0, 5, 6, 16, 25, 37, 45, 43, 36, 27, 25, 28, 30, 29, 26, 16, 7, -2, -2, 2, 3, -2, -15, -31, -38, -35, -23, -15, -15, -19, -23, -26, -23, -21, -15, -12, -18, -24, -27, -25, -19, -9, -3, 2, 5, 12, 19, 32, 42, 45, 41, 31, 28, 31, 33, 37, 33, 26, 14, 4, -2, -3, -3, -5, -18, -34, -43, -42, -31, -20, -18, -17, -19, -18, -16, -13, -9, -8, -13, -22, -32, -32, -28, -19, -11, -6, -2, 7, 18, 31, 42, 46, 46, 41, 36, 32, 35, 39, 39, 30, 17, 5, -3, -3, -3, -7, -19, -32, -39, -41, -36, -26, -17, -12, -13, -18, -20, -14, -7, -6, -11, -23, -32, -34, -28, -23, -15, -9, -2, 9, 17, 28, 37, 44, 48, 45, 38, 32, 35, 41, 45, 37, 23, 10, 1, -3, -5, -8, -20, -35, -44, -44, -42, -34, -24, -14, -10, -12, -14, -11, -6, -2, -5, -15, -25, -32, -29, -24, -19, -15, -10, 1, 10, 20, 31, 40, 45, 48, 43, 39, 39, 45, 51, 43, 28, 15, 2, -4, -8, -13, -20, -34, -42, -45, -45, -36, -26, -13, -8, -11, -13, -8, -2, 1, -4, -13, -22, -30, -33, -28, -25, -18, -12, -5, 3, 13, 25, 37, 46, 47, 45, 40, 41, 47, 53, 49, 35, 21, 10, 2, -6, -11, -22, -32, -43, -50, -50, -47, -34, -17, -9, -9, -12, -9, 3, 7, 4, -8, -18, -25, -31, -31, -27, -21, -16, -11, -8, 2, 17, 31, 45, 47, 44, 40, 43, 54, 60, 58, 42, 26, 14, 4, -5, -14, -26, -37, -47, -54, -53, -49, -38, -22, -13, -9, -7, -3, 6, 11, 6, -5, -14, -22, -28, -31, -30, -29, -24, -18, -15, -2, 14, 29, 42, 45, 47, 45, 48, 56, 63, 59, 46, 29, 17, 5, -4, -11, -23, -36, -49, -53, -52, -48, -40, -29, -21, -16, -11, -2, 5, 6, 3, -5, -10, -13, -17, -21, -25, -26, -23, -19, -15, -8, 5, 20, 31, 38, 42, 41, 46, 55, 62, 63, 50, 36, 24, 12, 5, -7, -20, -33, -46, -51, -51, -48, -40, -33, -27, -20, -15, 0, 9, 7, 1, -6, -10, -11, -16, -22, -25, -30, -28, -25, -21, -11, 2, 17, 28, 32, 41, 47, 55, 64, 66, 64, 54, 41, 32, 19, 4, -9, -24, -37, -48, -54, -55, -51, -41, -33, -29, -24, -15, 0, 13, 14, 8, 1, -5, -6, -10, -17, -24, -30, -32, -33, -32, -22, -9, 9, 21, 25, 35, 45, 56, 67, 71, 71, 63, 49, 37, 25, 11, -5, -19, -32, -45, -54, -59, -54, -43, -36, -31, -27, -18, -3, 11, 13, 9, 2, -3, -6, -9, -13, -20, -25, -29, -33, -30, -23, -9, 2, 11, 19, 28, 40, 51, 63, 68, 71, 66, 55, 44, 31, 16, 1, -15, -30, -41, -50, -57, -56, -46, -37, -32, -30, -21, -7, 8, 17, 12, 5, 3, -2, -6, -11, -19, -23, -27, -33, -34, -28, -19, -6, 3, 13, 24, 38, 51, 62, 70, 72, 68, 60, 48, 38, 22, 6, -13, -27, -39, -46, -53, -52, -48, -42, -37, -36, -25, -9, 4, 11, 9, 7, 8, 6, 2, -6, -13, -20, -24, -28, -31, -30, -27, -19, -10, 4, 19, 33, 45, 57, 67, 74, 74, 70, 60, 47, 31, 10, -8, -25, -36, -42, -51, -56, -56, -51, -40, -35, -28, -16, -4, 7, 7, 10, 12, 13, 11, 3, -8, -18, -21, -25, -29, -33, -33, -30, -20, -8, 11, 27, 42, 54, 64, 72, 77, 76, 69, 56, 34, 14, -5, -20, -32, -43, -50, -57, -59, -57, -47, -39, -31, -17, -5, 6, 8, 9, 17, 19, 16, 5, -9, -13, -18, -21, -26, -33, -37, -35, -28, -15, 1, 18, 34, 47, 58, 68, 76, 77, 76, 65, 47, 25, 6, -12, -24, -37, -49, -57, -62, -64, -58, -50, -40, -24, -12, 3, 9, 13, 22, 26, 26, 17, 4, -9, -21, -25, -30, -36, -41, -44, -41, -27, -8, 12, 31, 44, 57, 68, 77, 81, 80, 72, 56, 34, 12, -6, -19, -30, -41, -53, -65, -68, -65, -56, -44, -30, -17, -8, 2, 10, 23, 31, 32, 25, 10, -4, -14, -20, -25, -31, -39, -45, -45, -35, -17, 2, 22, 37, 51, 63, 72, 79, 78, 74, 62, 43, 20, 2, -12, -24, -34, -49, -61, -69, -70, -63, -48, -35, -23, -11, 0, 9, 20, 31, 36, 32, 20, 7, -9, -18, -24, -30, -38, -47, -50, -44, -29, -9, 10, 27, 45, 60, 71, 78, 80, 78, 68, 54, 33, 13, -5, -18, -29, -44, -57, -68, -74, -66, -54, -41, -30, -18, -5, 8, 19, 26, 33, 32, 24, 13, -4, -15, -22, -24, -29, -40, -44, -42, -29, -14, 0, 15, 31, 48, 63, 69, 74, 74, 72, 64, 47, 27, 11, -4, -17, -33, -50, -66, -78, -78, -68, -54, -38, -25, -11, 4, 18, 31, 38, 40, 34, 21, 5, -12, -23, -28, -34, -43, -50, -51, -39, -22, -6, 10, 26, 46, 61, 70, 75, 79, 76, 67, 52, 34, 18, 4, -11, -27, -45, -63, -76, -78, -70, -57, -44, -29, -15, 0, 14, 26, 35, 39, 34, 23, 9, -7, -18, -23, -30, -40, -49, -51, -41, -24, -9, 5, 19, 39, 55, 67, 74, 77, 79, 72, 56, 39, 24, 12, -5, -23, -42, -60, -73, -78, -74, -62, -48, -33, -18, -6, 10, 25, 34, 37, 34, 26, 16, -2, -15, -23, -28, -32, -42, -46, -44, -31, -16, -4, 11, 28, 44, 56, 64, 69, 75, 73, 63, 50, 37, 22, 6, -10, -27, -47, -68, -81, -80, -68, -52, -39, -25, -13, 2, 17, 29, 36, 37, 32, 23, 4, -14, -24, -26, -26, -36, -44, -45, -36, -20, -7, 9, 25, 38, 49, 58, 66, 75, 77, 67, 52, 39, 26, 14, -3, -21, -43, -65, -81, -84, -74, -56, -40, -27, -15, -2, 15, 27, 37, 38, 35, 26, 8, -11, -23, -26, -27, -34, -42, -45, -40, -27, -13, 4, 19, 33, 45, 54, 60, 67, 72, 67, 57, 44, 32, 20, 5, -11, -32, -55, -72, -82, -76, -62, -46, -31, -21, -5, 6, 19, 29, 34, 33, 26, 12, -6, -17, -22, -23, -28, -38, -42, -38, -27, -14, 1, 14, 27, 40, 48, 53, 62, 68, 67, 58, 44, 32, 21, 9, -5, -22, -43, -63, -76, -75, -62, -46, -30, -24, -13, 0, 10, 20, 28, 31, 27, 12, -5, -16, -20, -19, -21, -29, -35, -35, -27, -16, -6, 9, 21, 33, 41, 47, 53, 61, 63, 60, 51, 39, 27, 15, 3, -13, -33, -55, -72, -75, -67, -52, -37, -26, -18, -7, 4, 15, 26, 27, 25, 14, 0, -10, -15, -16, -19, -24, -31, -32, -27, -17, -5, 5, 15, 26, 35, 43, 49, 54, 57, 57, 52, 42, 29, 18, 10, -3, -23, -46, -64, -71, -66, -53, -39, -27, -19, -11, 0, 5, 16, 22, 23, 15, 1, -10, -15, -18, -17, -17, -20, -24, -22, -14, -4, 7, 16, 25, 31, 36, 41, 47, 49, 49, 46, 41, 32, 21, 13, 3, -14, -33, -51, -60, -60, -52, -39, -28, -20, -14, -7, 1, 9, 14, 16, 10, 1, -10, -15, -14, -15, -15, -15, -17, -14, -11, -4, 5, 13, 22, 29, 33, 35, 39, 43, 45, 45, 42, 35, 26, 17, 7, -10, -25, -38, -48, -53, -53, -46, -33, -23, -16, -13, -8, -3, 4, 9, 7, 1, -6, -10, -13, -12, -12, -8, -7, -6, -2, 3, 6, 10, 14, 23, 28, 29, 30, 29, 34, 39, 40, 36, 30, 21, 13, 1, -15, -27, -36, -44, -48, -45, -36, -26, -17, -13, -10, -6, -2, 2, 3, -3, -6, -10, -14, -13, -12, -7, -3, 1, 2, 5, 6, 10, 15, 19, 25, 25, 26, 26, 29, 34, 35, 32, 29, 20, 13, 4, -12, -20, -27, -33, -38, -41, -36, -27, -19, -13, -10, -8, -8, -7, -5, -5, -7, -9, -13, -18, -15, -12, -5, 3, 7, 10, 10, 11, 13, 20, 27, 27, 23, 20, 20, 24, 27, 25, 26, 23, 17, 7, -6, -13, -16, -20, -26, -32, -33, -28, -20, -13, -12, -12, -16, -15, -15, -12, -10, -13, -13, -16, -12, -7, 0, 9, 14, 18, 18, 14, 11, 14, 18, 21, 17, 10, 11, 15, 20, 21, 20, 20, 17, 9, 2, -5, -10, -14, -21, -25, -29, -27, -23, -17, -13, -13, -16, -18, -20, -20, -12, -8, -9, -15, -16, -10, -2, 9, 14, 18, 18, 18, 14, 14, 17, 20, 18, 12, 8, 11, 13, 16, 18, 19, 16, 9, 3, 1, 1, -6, -13, -20, -23, -21, -19, -15, -15, -14, -17, -21, -22, -22, -17, -11, -11, -13, -18, -14, -4, 12, 21, 22, 23, 21, 20, 17, 16, 16, 12, 7, 1, 5, 7, 8, 12, 15, 15, 10, 3, 0, 3, 1, -5, -12, -19, -19, -16, -11, -9, -11, -14, -23, -28, -29, -24, -17, -13, -15, -19, -18, -10, 7, 22, 29, 30, 24, 22, 18, 17, 17, 11, 4, -2, -3, 2, 4, 8, 13, 16, 13, 7, 4, 9, 8, 2, -7, -16, -15, -14, -12, -10, -12, -12, -19, -25, -29, -25, -18, -15, -18, -21, -19, -12, 1, 16, 28, 34, 32, 29, 23, 18, 15, 11, 4, -3, -10, -8, -5, 0, 7, 12, 14, 10, 6, 10, 15, 13, 3, -7, -11, -13, -13, -13, -12, -14, -20, -28, -31, -29, -20, -13, -14, -18, -18, -15, -3, 12, 24, 33, 32, 29, 25, 22, 16, 11, 3, -3, -6, -7, -8, -3, 2, 8, 11, 11, 9, 10, 13, 13, 8, 0, -6, -9, -9, -9, -10, -11, -18, -26, -30, -29, -22, -17, -18, -20, -21, -17, -7, 6, 21, 34, 38, 34, 29, 21, 17, 13, 8, 1, -8, -13, -15, -10, -3, 5, 10, 11, 10, 11, 15, 16, 11, 3, -4, -7, -9, -8, -10, -13, -19, -26, -26, -23, -17, -15, -16, -17, -17, -15, -9, -2, 10, 26, 31, 31, 24, 21, 18, 13, 6, 1, -6, -8, -9, -8, -4, 0, 6, 10, 12, 15, 14, 13, 9, 5, -2, -7, -8, -9, -8, -10, -18, -25, -25, -23, -18, -16, -19, -22, -18, -16, -10, 0, 10, 24, 33, 35, 29, 22, 17, 13, 7, -3, -8, -12, -14, -12, -7, -3, 4, 10, 14, 16, 17, 16, 16, 11, 3, -7, -11, -10, -7, -10, -19, -26, -27, -23, -17, -14, -14, -17, -18, -16, -12, -3, 7, 20, 26, 28, 24, 20, 16, 15, 10, 2, -8, -13, -11, -7, -2, -2, 4, 6, 9, 14, 17, 19, 15, 8, -4, -12, -15, -11, -5, -8, -18, -25, -24, -17, -9, -6, -7, -11, -15, -15, -13, -6, 4, 11, 15, 16, 15, 16, 13, 9, 5, 1, -3, -7, -5, -2, 3, 5, 6, 8, 10, 14, 17, 18, 14, 3, -8, -15, -13, -9, -6, -9, -19, -22, -19, -13, -6, -4, -5, -8, -13, -15, -10, -5, 5, 8, 8, 8, 11, 14, 14, 8, 2, 1, 1, 2, -2, 1, 5, 6, 7, 7, 6, 11, 13, 16, 13, 3, -6, -13, -14, -8, -5, -6, -15, -20, -15, -10, -5, -2, -6, -6, -8, -12, -10, -8, -3, 5, 3, 3, 5, 7, 10, 6, 2, -3, -2, 2, 8, 9, 12, 11, 8, 9, 8, 11, 13, 11, 10, 0, -12, -20, -21, -13, -10, -11, -14, -16, -10, -3, 4, 8, 5, 2, -2, -4, -4, -7, -4, -4, -5, -7, -8, -5, 0, 2, 2, 0, 1, 6, 11, 15, 19, 19, 18, 14, 10, 12, 12, 11, 6, -6, -16, -23, -23, -17, -13, -12, -12, -13, -8, -2, 8, 13, 13, 8, 4, 1, -3, -3, -3, -4, -11, -16, -16, -13, -9, -5, -4, -2, 1, 6, 13, 17, 21, 24, 23, 18, 14, 10, 11, 12, 8, -3, -16, -26, -27, -20, -17, -21, -21, -17, -7, 2, 10, 16, 19, 18, 13, 10, 5, 2, -2, -5, -14, -22, -26, -21, -15, -11, -11, -6, -2, 6, 16, 22, 27, 28, 28, 23, 17, 13, 10, 12, 7, -4, -18, -29, -32, -24, -20, -21, -22, -18, -5, 5, 14, 19, 21, 20, 17, 13, 8, 5, -2, -9, -18, -26, -26, -21, -14, -12, -11, -8, -2, 10, 16, 21, 24, 25, 27, 24, 16, 11, 6, 7, 6, -4, -16, -25, -29, -25, -19, -19, -22, -18, -7, 6, 15, 17, 18, 19, 18, 15, 10, 8, 3, -5, -15, -24, -30, -27, -19, -15, -15, -13, -8, 5, 14, 20, 25, 28, 31, 30, 26, 18, 11, 9, 7, -2, -14, -27, -33, -30, -25, -25, -27, -26, -15, 2, 17, 22, 23, 23, 22, 22, 18, 14, 7, -4, -14, -24, -31, -30, -25, -19, -16, -16, -11, -3, 8, 17, 24, 29, 31, 31, 29, 22, 17, 12, 8, 2, -12, -26, -36, -35, -30, -26, -26, -29, -20, -5, 13, 24, 26, 26, 26, 28, 23, 19, 11, 1, -9, -24, -34, -33, -30, -24, -21, -21, -17, -11, 1, 9, 19, 27, 33, 34, 30, 28, 24, 21, 16, 7, -6, -23, -35, -40, -36, -33, -31, -32, -27, -13, 3, 17, 25, 29, 34, 34, 30, 23, 17, 11, 0, -14, -27, -32, -33, -30, -26, -21, -18, -15, -9, 1, 11, 22, 29, 32, 33, 30, 28, 23, 21, 13, 3, -15, -30, -37, -38, -35, -35, -33, -28, -18, -5, 10, 22, 30, 37, 36, 32, 26, 21, 14, 7, -6, -19, -28, -34, -32, -27, -21, -20, -21, -20, -11, 5, 17, 25, 29, 30, 33, 35, 31, 27, 19, 8, -7, -25, -37, -42, -41, -39, -35, -30, -22, -11, 4, 21, 32, 38, 39, 36, 29, 22, 15, 9, -4, -15, -24, -32, -35, -31, -24, -18, -18, -19, -14, -3, 11, 21, 27, 31, 32, 34, 34, 31, 27, 18, 1, -19, -33, -39, -38, -40, -39, -35, -28, -17, -3, 14, 28, 37, 41, 40, 34, 30, 24, 18, 7, -6, -20, -30, -36, -34, -30, -26, -26, -27, -26, -16, 0, 16, 26, 30, 33, 36, 42, 43, 38, 27, 10, -10, -27, -39, -43, -43, -43, -40, -34, -26, -14, 2, 21, 36, 42, 40, 36, 33, 30, 24, 16, 5, -11, -25, -34, -35, -32, -29, -30, -31, -31, -27, -15, 5, 21, 27, 30, 34, 42, 51, 48, 40, 20, -3, -21, -32, -38, -40, -43, -42, -38, -30, -18, -3, 15, 29, 40, 41, 39, 34, 31, 28, 20, 10, -4, -18, -29, -33, -34, -34, -35, -37, -38, -34, -21, -6, 12, 22, 26, 33, 44, 55, 56, 46, 26, 5, -11, -25, -36, -42, -47, -47, -43, -37, -24, -11, 9, 25, 36, 38, 38, 40, 39, 39, 28, 17, 3, -10, -23, -30, -37, -38, -42, -44, -43, -40, -30, -16, 3, 17, 26, 34, 44, 57, 61, 52, 34, 9, -7, -21, -30, -38, -46, -49, -48, -39, -27, -13, 5, 22, 32, 35, 35, 37, 41, 43, 33, 19, 4, -8, -16, -25, -32, -39, -42, -44, -42, -41, -33, -20, -4, 11, 21, 28, 38, 49, 58, 54, 36, 16, -6, -16, -21, -28, -36, -46, -49, -42, -29, -17, 0, 13, 26, 30, 30, 35, 41, 47, 41, 25, 9, -4, -12, -17, -28, -38, -46, -52, -51, -49, -39, -23, -9, 4, 12, 23, 39, 54, 66, 62, 43, 23, 2, -10, -16, -26, -36, -45, -51, -50, -37, -20, 0, 16, 27, 28, 29, 38, 47, 50, 44, 28, 13, -2, -10, -16, -26, -35, -45, -55, -57, -56, -44, -27, -13, -4, 5, 17, 34, 53, 64, 64, 46, 29, 13, 1, -8, -17, -28, -39, -48, -51, -42, -26, -8, 9, 18, 20, 24, 34, 46, 53, 47, 33, 15, 4, -4, -13, -22, -35, -47, -56, -59, -56, -48, -32, -18, -8, 3, 14, 33, 52, 65, 64, 49, 31, 17, 5, -3, -13, -25, -36, -45, -49, -44, -31, -14, 7, 16, 21, 21, 31, 48, 57, 53, 38, 20, 8, -3, -9, -21, -35, -47, -57, -62, -62, -54, -38, -22, -12, -5, 7, 26, 49, 66, 69, 56, 37, 24, 15, 6, -4, -17, -30, -43, -53, -47, -34, -18, -2, 9, 14, 17, 29, 46, 58, 56, 43, 25, 13, 2, -5, -15, -30, -45, -59, -66, -65, -57, -43, -28, -16, -10, 2, 21, 44, 66, 71, 62, 43, 28, 19, 13, 3, -12, -25, -42, -51, -50, -38, -18, -3, 5, 12, 17, 30, 48, 59, 58, 45, 26, 11, 0, -6, -15, -29, -45, -63, -71, -68, -58, -41, -28, -19, -12, -4, 16, 42, 62, 70, 61, 43, 29, 21, 16, 8, -6, -20, -35, -45, -45, -37, -21, -6, 3, 8, 14, 24, 42, 54, 58, 47, 29, 16, 3, -3, -12, -27, -42, -62, -73, -74, -66, -52, -34, -23, -14, -5, 12, 38, 60, 72, 68, 49, 34, 23, 17, 10, -3, -18, -31, -42, -42, -36, -20, -4, 5, 9, 11, 22, 37, 51, 55, 46, 29, 13, 2, -9, -14, -25, -38, -53, -67, -72, -67, -53, -35, -23, -17, -10, 6, 32, 55, 69, 67, 53, 36, 26, 19, 12, 2, -13, -26, -37, -40, -36, -24, -7, 3, 9, 13, 20, 36, 49, 52, 47, 32, 17, 3, -12, -19, -29, -38, -52, -66, -75, -72, -56, -36, -20, -15, -10, 2, 25, 48, 63, 63, 52, 39, 28, 20, 14, 5, -6, -19, -30, -38, -35, -25, -8, 4, 8, 11, 17, 33, 47, 54, 47, 34, 18, 4, -9, -19, -28, -40, -53, -65, -75, -74, -60, -41, -22, -15, -12, -2, 18, 43, 59, 63, 55, 41, 31, 27, 20, 13, 3, -11, -24, -35, -34, -26, -11, 2, 8, 9, 11, 22, 37, 47, 49, 39, 22, 6, -7, -19, -26, -36, -48, -60, -74, -77, -66, -47, -26, -13, -8, 1, 15, 36, 53, 63, 56, 45, 30, 22, 16, 10, 5, -7, -19, -32, -34, -25, -7, 8, 16, 17, 17, 23, 37, 48, 51, 40, 22, 4, -14, -24, -33, -39, -49, -61, -72, -77, -66, -47, -27, -13, -5, 1, 13, 30, 47, 59, 57, 47, 31, 23, 17, 15, 6, -5, -18, -26, -30, -24, -10, 8, 19, 21, 20, 22, 30, 40, 48, 41, 25, 3, -17, -29, -32, -37, -46, -59, -70, -73, -65, -46, -27, -14, -4, 3, 15, 29, 41, 52, 54, 45, 31, 19, 15, 15, 9, 1, -14, -26, -27, -21, -8, 10, 17, 23, 23, 23, 32, 39, 45, 44, 29, 7, -16, -32, -40, -42, -49, -61, -72, -76, -69, -50, -28, -12, -2, 5, 17, 31, 43, 48, 49, 44, 34, 24, 15, 13, 9, 5, -8, -24, -27, -21, -7, 10, 20, 25, 29, 29, 32, 36, 41, 41, 34, 14, -12, -35, -46, -49, -52, -61, -74, -78, -73, -56, -31, -14, 2, 10, 19, 31, 44, 54, 53, 47, 34, 24, 16, 9, 4, -2, -12, -25, -28, -22, -7, 9, 23, 32, 36, 36, 36, 37, 42, 42, 33, 15, -14, -36, -50, -57, -56, -62, -74, -81, -77, -59, -36, -15, 2, 11, 20, 31, 44, 56, 56, 51, 39, 26, 15, 7, 1, -3, -13, -26, -33, -31, -14, 9, 25, 36, 41, 40, 41, 40, 44, 44, 35, 17, -13, -39, -54, -61, -64, -69, -76, -81, -78, -63, -39, -15, 4, 14, 24, 35, 45, 54, 56, 53, 41, 25, 14, 7, 3, -4, -14, -26, -34, -31, -15, 9, 25, 36, 41, 43, 44, 43, 46, 45, 35, 16, -9, -31, -49, -63, -69, -75, -78, -84, -79, -66, -45, -22, 0, 13, 23, 35, 48, 56, 58, 53, 43, 30, 19, 10, 4, -7, -18, -26, -33, -30, -17, 4, 24, 37, 44, 50, 50, 49, 46, 43, 35, 16, -7, -30, -52, -65, -75, -78, -83, -85, -82, -70, -50, -26, -4, 14, 26, 39, 53, 63, 64, 59, 49, 35, 18, 6, -2, -13, -25, -35, -40, -36, -22, 3, 26, 38, 47, 54, 60, 61, 57, 50, 39, 20, -5, -26, -49, -66, -80, -87, -91, -93, -88, -74, -54, -34, -12, 8, 24, 40, 55, 68, 70, 66, 55, 41, 26, 14, 6, -9, -25, -37, -43, -39, -28, -9, 15, 32, 41, 48, 59, 65, 65, 58, 45, 25, 5, -17, -38, -61, -77, -91, -97, -100, -94, -79, -64, -44, -23, -2, 24, 42, 57, 72, 77, 74, 63, 48, 33, 21, 10, -7, -27, -43, -45, -41, -29, -14, 4, 26, 40, 49, 58, 66, 69, 64, 48, 29, 7, -13, -31, -53, -73, -89, -100, -102, -95, -83, -67, -51, -29, -7, 17, 37, 55, 72, 81, 77, 67, 55, 40, 25, 12, -4, -22, -40, -45, -42, -31, -19, -4, 15, 34, 48, 55, 63, 67, 66, 57, 41, 20, -4, -25, -46, -69, -88, -104, -110, -106, -95, -79, -63, -39, -13, 15, 39, 60, 75, 88, 91, 81, 66, 44, 27, 13, -3, -22, -41, -50, -48, -38, -26, -13, 6, 29, 46, 55, 62, 66, 69, 63, 48, 26, 5, -14, -33, -57, -84, -105, -115, -113, -102, -88, -73, -53, -26, 1, 31, 57, 78, 91, 95, 88, 75, 60, 41, 22, 1, -19, -38, -51, -53, -48, -36, -22, -6, 19, 39, 53, 62, 65, 69, 67, 55, 36, 14, -6, -28, -54, -79, -100, -111, -116, -110, -98, -83, -61, -35, -6, 26, 53, 75, 89, 96, 96, 87, 71, 50, 29, 10, -9, -30, -44, -53, -50, -45, -32, -19, 2, 23, 43, 55, 62, 66, 66, 62, 49, 30, 11, -12, -39, -70, -95, -112, -118, -118, -109, -94, -74, -48, -18, 17, 47, 70, 88, 98, 99, 95, 80, 61, 37, 14, -9, -26, -43, -51, -52, -48, -40, -25, -6, 17, 37, 52, 57, 63, 64, 62, 55, 36, 17, -8, -34, -62, -86, -106, -117, -118, -110, -99, -83, -57, -27, 10, 42, 67, 85, 96, 101, 101, 91, 69, 46, 21, 1, -21, -38, -49, -54, -49, -44, -35, -18, 2, 24, 44, 55, 64, 67, 63, 59, 46, 29, 7, -21, -51, -79, -104, -117, -122, -117, -108, -94, -70, -40, 0, 34, 63, 85, 96, 104, 105, 99, 82, 59, 31, 4, -20, -37, -46, -51, -51, -50, -44, -28, -8, 17, 38, 53, 60, 65, 67, 64, 54, 40, 18, -10, -40, -71, -98, -115, -121, -118, -113, -103, -82, -52, -14, 22, 53, 77, 94, 106, 109, 104, 93, 76, 50, 21, -11, -33, -43, -48, -53, -56, -56, -46, -27, 2, 29, 48, 58, 62, 63, 62, 58, 49, 33, 5, -27, -57, -87, -108, -119, -118, -114, -106, -91, -68, -31, 8, 42, 69, 88, 102, 110, 110, 100, 83, 60, 33, 3, -23, -39, -46, -52, -57, -57, -51, -35, -14, 15, 38, 54, 63, 65, 66, 58, 51, 40, 17, -11, -44, -76, -101, -114, -116, -111, -106, -96, -77, -47, -11, 28, 58, 81, 97, 109, 112, 105, 95, 77, 53, 23, -9, -30, -45, -52, -58, -64, -61, -52, -35, -9, 20, 44, 62, 67, 67, 65, 62, 54, 35, 7, -24, -60, -91, -110, -119, -116, -112, -105, -90, -65, -31, 8, 43, 73, 94, 109, 117, 113, 105, 91, 68, 39, 4, -24, -43, -56, -64, -67, -67, -61, -47, -21, 9, 35, 55, 63, 66, 66, 61, 56, 46, 23, -10, -46, -81, -100, -111, -115, -112, -107, -94, -75, -48, -12, 28, 59, 84, 103, 116, 120, 114, 103, 81, 56, 22, -10, -35, -53, -64, -71, -73, -71, -59, -39, -10, 19, 43, 60, 66, 68, 67, 64, 53, 33, 7, -27, -64, -91, -108, -115, -113, -108, -97, -82, -59, -27, 11, 46, 75, 98, 112, 119, 117, 109, 89, 64, 34, 4, -24, -50, -62, -69, -69, -70, -65, -49, -23, 8, 32, 52, 61, 64, 65, 64, 55, 39, 15, -16, -46, -76, -97, -109, -110, -107, -102, -91, -71, -42, -4, 34, 66, 90, 106, 116, 121, 118, 101, 78, 47, 15, -15, -44, -60, -70, -73, -75, -74, -63, -39, -7, 23, 45, 60, 66, 69, 69, 62, 49, 29, 1, -32, -65, -94, -108, -112, -109, -102, -97, -83, -58, -22, 18, 54, 84, 103, 116, 121, 120, 112, 91, 63, 29, -6, -34, -54, -66, -75, -79, -81, -72, -50, -22, 9, 33, 50, 59, 67, 70, 70, 60, 43, 13, -20, -51, -78, -97, -107, -111, -109, -105, -94, -72, -37, 5, 42, 72, 96, 114, 124, 127, 118, 100, 75, 42, 10, -22, -47, -62, -72, -79, -84, -82, -64, -35, -2, 23, 39, 50, 61, 69, 71, 66, 51, 27, -6, -36, -62, -81, -96, -104, -105, -106, -101, -83, -52, -11, 27, 57, 82, 103, 120, 127, 122, 107, 82, 53, 19, -12, -39, -55, -65, -73, -81, -81, -67, -40, -8, 16, 30, 41, 52, 62, 68, 66, 56, 34, 3, -28, -53, -71, -86, -96, -102, -106, -103, -88, -62, -25, 15, 47, 72, 90, 109, 120, 123, 115, 93, 63, 31, 1, -24, -40, -52, -64, -76, -82, -73, -50, -22, 1, 18, 27, 39, 51, 63, 67, 61, 44, 18, -13, -38, -53, -69, -83, -96, -105, -103, -93, -69, -36, -3, 30, 56, 77, 95, 111, 116, 113, 97, 72, 42, 13, -12, -25, -38, -54, -70, -79, -74, -57, -32, -11, 4, 15, 26, 40, 55, 65, 62, 51, 28, 1, -24, -40, -56, -73, -89, -101, -102, -95, -79, -50, -17, 16, 47, 68, 88, 104, 114, 115, 102, 80, 53, 24, 0, -18, -31, -45, -60, -73, -74, -63, -42, -21, -6, 6, 16, 28, 45, 56, 59, 51, 35, 14, -9, -26, -41, -57, -73, -87, -97, -95, -85, -62, -32, -2, 26, 50, 71, 91, 105, 111, 105, 89, 64, 40, 16, -4, -20, -35, -49, -64, -70, -68, -53, -35, -18, -6, 5, 14, 29, 45, 55, 54, 39, 21, 4, -13, -25, -42, -63, -77, -89, -90, -80, -66, -44, -19, 10, 35, 57, 76, 93, 104, 104, 91, 68, 48, 29, 13, -6, -24, -42, -56, -63, -61, -54, -42, -27, -17, -6, 5, 18, 33, 44, 47, 39, 25, 10, 0, -14, -29, -50, -67, -79, -85, -81, -70, -53, -32, -5, 24, 47, 67, 84, 98, 103, 95, 77, 56, 37, 22, 6, -14, -34, -48, -56, -57, -52, -48, -37, -28, -17, -6, 8, 23, 34, 41, 38, 28, 15, 4, -4, -16, -38, -59, -73, -78, -75, -66, -54, -37, -19, 7, 32, 53, 72, 87, 95, 92, 78, 58, 44, 32, 20, 2, -21, -38, -47, -48, -47, -46, -42, -36, -26, -14, -5, 9, 20, 32, 35, 30, 19, 12, 8, -5, -25, -48, -63, -71, -70, -63, -58, -44, -26, -6, 20, 40, 59, 79, 92, 93, 83, 60, 47, 37, 29, 13, -10, -28, -40, -44, -44, -48, -47, -41, -33, -22, -13, 0, 14, 29, 36, 34, 24, 18, 15, 4, -13, -39, -60, -69, -72, -68, -62, -51, -34, -13, 9, 31, 52, 73, 88, 95, 87, 70, 55, 45, 35, 20, -2, -23, -36, -42, -47, -48, -51, -50, -40, -30, -17, -8, 7, 23, 36, 37, 30, 22, 19, 13, -3, -24, -49, -65, -71, -71, -64, -54, -40, -20, -3, 21, 44, 65, 85, 92, 87, 72, 57, 48, 39, 29, 11, -12, -27, -36, -41, -42, -47, -49, -45, -37, -28, -17, -4, 13, 28, 33, 29, 26, 23, 17, 6, -11, -33, -53, -64, -66, -62, -55, -44, -29, -12, 10, 31, 51, 71, 84, 85, 77, 61, 50, 41, 36, 22, 2, -17, -33, -38, -42, -45, -48, -46, -41, -34, -23, -9, 7, 24, 35, 32, 28, 23, 17, 10, -4, -26, -49, -64, -68, -64, -58, -46, -32, -13, 8, 28, 45, 65, 78, 82, 76, 62, 52, 45, 37, 23, 6, -10, -26, -35, -41, -45, -46, -48, -48, -39, -27, -11, 3, 14, 23, 27, 28, 25, 23, 15, 2, -17, -34, -52, -60, -61, -56, -44, -32, -17, -3, 16, 34, 54, 66, 73, 68, 58, 47, 42, 37, 29, 17, 3, -14, -25, -31, -36, -39, -44, -48, -44, -33, -20, -9, 2, 13, 22, 26, 24, 20, 14, 5, -7, -22, -39, -50, -55, -51, -43, -32, -20, -7, 10, 28, 44, 57, 65, 67, 64, 54, 44, 36, 28, 18, 4, -9, -23, -32, -39, -42, -46, -44, -38, -29, -19, -12, -4, 10, 22, 27, 22, 14, 8, 1, -6, -17, -30, -43, -49, -47, -38, -26, -18, -10, 3, 17, 34, 45, 54, 59, 57, 53, 45, 37, 30, 22, 11, -3, -14, -24, -34, -40, -45, -43, -39, -29, -21, -14, -6, 3, 16, 20, 17, 10, 3, 0, -6, -15, -25, -33, -38, -37, -31, -21, -12, -6, 5, 15, 27, 39, 46, 50, 51, 47, 44, 36, 29, 20, 10, 1, -10, -18, -27, -36, -40, -42, -37, -29, -21, -14, -7, 1, 10, 16, 10, 3, -2, -3, -6, -12, -22, -28, -30, -28, -23, -16, -11, -7, 0, 7, 19, 31, 42, 47, 47, 46, 46, 40, 33, 21, 10, 2, -6, -12, -24, -33, -37, -38, -36, -31, -21, -14, -7, -2, 2, 7, 8, 4, -2, -7, -12, -14, -19, -23, -24, -20, -16, -11, -6, -2, 3, 9, 16, 24, 33, 37, 40, 44, 44, 40, 33, 22, 13, 5, -3, -8, -21, -30, -35, -34, -32, -30, -23, -13, -6, -3, -3, -2, -2, -4, -7, -9, -12, -13, -13, -14, -14, -11, -12, -4, -2, 2, 0, 3, 10, 18, 27, 32, 35, 38, 40, 37, 32, 23, 13, 8, 2, -4, -11, -22, -27, -31, -30, -29, -24, -14, -7, -8, -7, -10, -10, -10, -10, -11, -12, -13, -12, -11, -11, -7, -2, 4, 5, 3, -2, 0, 8, 15, 21, 26, 30, 32, 37, 37, 32, 26, 16, 10, 4, -4, -9, -16, -21, -26, -29, -28, -23, -15, -11, -9, -11, -13, -14, -14, -13, -13, -12, -13, -12, -8, -3, 3, 6, 8, 10, 7, 1, -3, 2, 8, 17, 22, 22, 27, 32, 37, 35, 29, 18, 11, 2, -4, -8, -14, -17, -21, -23, -25, -22, -17, -11, -9, -11, -16, -16, -16, -16, -14, -15, -14, -11, -5, 0, 4, 5, 6, 7, 6, 4, 0, 3, 8, 16, 21, 20, 24, 28, 34, 35, 29, 17, 8, 3, 1, -3, -9, -15, -20, -21, -23, -22, -21, -17, -13, -14, -18, -23, -22, -17, -13, -10, -9, -8, 0, 6, 9, 10, 8, 6, 6, 4, 0, -2, 1, 10, 17, 20, 22, 25, 29, 31, 29, 20, 10, 2, -2, 0, -5, -11, -18, -20, -19, -19, -19, -18, -16, -14, -18, -26, -26, -22, -16, -13, -9, -6, 1, 7, 10, 10, 7, 7, 7, 5, 0, -4, -2, 7, 14, 19, 22, 26, 30, 32, 30, 22, 13, 6, 1, -2, -7, -13, -16, -18, -19, -19, -21, -21, -19, -17, -16, -23, -25, -23, -17, -10, -9, -4, 2, 8, 10, 12, 9, 7, 5, 4, 2, -3, -2, 3, 9, 18, 23, 28, 29, 28, 27, 26, 19, 12, 6, 0, -7, -11, -15, -17, -20, -21, -20, -22, -23, -25, -24, -26, -27, -25, -20, -13, -5, 3, 9, 11, 15, 17, 15, 10, 4, 0, -4, -5, -4, 2, 5, 13, 19, 25, 29, 28, 26, 25, 20, 16, 11, 2, -5, -10, -10, -10, -14, -17, -21, -24, -26, -29, -27, -28, -28, -26, -23, -17, -8, 1, 12, 15, 16, 14, 13, 10, 6, 0, -5, -6, -5, 1, 6, 12, 20, 27, 30, 28, 24, 23, 21, 17, 11, 4, -6, -9, -10, -10, -11, -16, -18, -21, -24, -26, -29, -28, -27, -25, -23, -18, -11, -2, 11, 15, 15, 12, 11, 9, 6, 1, -6, -6, -2, 3, 7, 11, 19, 26, 28, 26, 22, 21, 23, 24, 17, 10, 4, 0, -2, -5, -10, -15, -20, -25, -32, -36, -36, -35, -32, -30, -26, -19, -10, 2, 14, 21, 21, 17, 13, 10, 7, 1, -5, -5, -6, -4, 0, 6, 12, 19, 22, 24, 20, 21, 24, 29, 28, 20, 13, 8, 3, 2, -4, -9, -16, -27, -34, -41, -44, -41, -38, -35, -31, -27, -18, -3, 13, 26, 29, 23, 18, 14, 11, 8, 4, -2, -8, -11, -9, -6, 4, 9, 16, 17, 16, 16, 23, 33, 37, 33, 26, 19, 12, 8, 1, -7, -15, -30, -41, -50, -53, -50, -43, -38, -34, -28, -17, -3, 13, 26, 30, 26, 19, 14, 12, 9, 4, -2, -10, -14, -13, -7, 4, 9, 12, 13, 13, 17, 25, 32, 40, 39, 32, 24, 15, 11, 8, 1, -10, -27, -43, -51, -55, -52, -49, -45, -40, -32, -21, -8, 9, 23, 31, 30, 24, 19, 17, 16, 11, 4, -7, -15, -18, -14, -6, 2, 5, 7, 9, 14, 24, 35, 45, 48, 45, 34, 25, 16, 8, 2, -11, -27, -46, -59, -64, -61, -53, -46, -40, -35, -24, -9, 8, 23, 30, 31, 27, 24, 21, 17, 12, 4, -6, -15, -19, -17, -12, -3, 3, 4, 6, 12, 25, 37, 45, 47, 47, 43, 35, 23, 12, 2, -10, -24, -42, -60, -71, -71, -63, -55, -45, -36, -22, -7, 9, 22, 30, 35, 34, 31, 24, 19, 13, 6, -3, -13, -20, -21, -16, -9, -3, -2, 4, 11, 26, 38, 45, 50, 49, 48, 42, 31, 16, 4, -9, -21, -38, -59, -72, -77, -70, -61, -53, -41, -26, -9, 7, 17, 26, 34, 41, 41, 35, 25, 17, 9, 0, -10, -21, -24, -22, -15, -9, -7, -2, 10, 25, 39, 44, 47, 49, 52, 50, 39, 22, 6, -8, -20, -34, -54, -70, -78, -77, -68, -61, -49, -33, -15, 3, 16, 25, 32, 43, 49, 47, 37, 25, 16, 3, -10, -22, -29, -27, -22, -15, -12, -7, 7, 25, 42, 47, 50, 53, 57, 57, 46, 31, 11, -5, -22, -39, -56, -72, -81, -85, -81, -71, -56, -36, -16, 4, 19, 29, 37, 48, 55, 56, 48, 34, 20, 7, -10, -25, -32, -34, -28, -21, -17, -14, 0, 20, 40, 50, 51, 53, 58, 61, 53, 39, 18, -2, -18, -36, -53, -70, -80, -85, -86, -79, -67, -46, -23, -2, 17, 27, 35, 44, 55, 62, 57, 44, 26, 9, -10, -23, -29, -32, -28, -24, -20, -15, -4, 15, 35, 47, 50, 49, 53, 57, 53, 43, 24, 5, -14, -32, -50, -64, -5, 0, -2, -3, -3, -3, -3, -2, -2, 1, 2, 3, 5, 8, 11, 11, 10, 8, 5, 1, -6, -13, -19, -21, -18, -15, -13, -10, -7, -2, 4, 8, 12, 17, 28, 33, 29, 23, 14, 7, -5, -19, -33, -42, -36, -28, -24, -17, -13, -8, 1, 7, 15, 23, 33, 42, 42, 35, 26, 15, 0, -16, -30, -44, -45, -34, -27, -20, -16, -13, -4, 4, 12, 21, 29, 40, 45, 40, 30, 20, 6, -13, -25, -38, -45, -38, -31, -24, -18, -15, -10, -4, 5, 17, 27, 35, 44, 43, 37, 27, 15, -4, -19, -31, -44, -44, -35, -30, -22, -19, -16, -8, 2, 15, 25, 32, 42, 47, 42, 32, 18, 0, -16, -26, -39, -45, -38, -31, -25, -19, -18, -14, -5, 11, 23, 29, 39, 46, 45, 38, 25, 7, -8, -18, -31, -44, -43, -35, -30, -25, -25, -20, -9, 7, 21, 27, 36, 48, 51, 44, 32, 14, -3, -16, -28, -42, -46, -41, -33, -27, -24, -23, -15, 1, 16, 27, 33, 42, 47, 46, 38, 21, 5, -9, -21, -34, -44, -45, -39, -31, -28, -26, -20, -8, 9, 25, 34, 41, 49, 51, 47, 31, 11, -6, -18, -30, -42, -48, -45, -36, -28, -26, -23, -12, 6, 23, 33, 38, 43, 51, 50, 36, 15, 0, -12, -22, -35, -50, -50, -40, -31, -29, -27, -18, 1, 20, 32, 36, 43, 52, 56, 45, 23, 2, -10, -20, -33, -48, -56, -49, -36, -30, -26, -18, -5, 17, 33, 39, 40, 46, 52, 49, 32, 9, -8, -18, -26, -40, -54, -53, -39, -30, -28, -23, -12, 10, 31, 39, 38, 42, 54, 54, 41, 17, -5, -15, -22, -35, -53, -59, -47, -36, -30, -24, -14, 6, 27, 40, 42, 43, 51, 56, 46, 26, 3, -13, -22, -33, -49, -61, -55, -41, -32, -26, -18, 0, 22, 38, 45, 43, 48, 55, 50, 33, 11, -10, -21, -29, -43, -59, -60, -46, -35, -28, -18, -6, 15, 35, 45, 46, 45, 52, 53, 41, 20, -6, -19, -26, -38, -54, -62, -53, -39, -29, -19, -11, 6, 29, 44, 48, 45, 47, 52, 49, 32, 5, -18, -26, -32, -45, -61, -61, -48, -35, -23, -14, -2, 22, 42, 52, 50, 46, 50, 50, 38, 12, -15, -26, -31, -43, -59, -65, -53, -37, -25, -16, -6, 16, 40, 53, 53, 47, 49, 51, 42, 22, -10, -27, -31, -38, -54, -67, -63, -46, -27, -18, -7, 10, 31, 52, 59, 53, 48, 50, 46, 32, 3, -24, -34, -39, -50, -66, -68, -54, -35, -20, -8, 6, 23, 47, 62, 59, 52, 50, 48, 37, 13, -18, -35, -40, -46, -62, -72, -63, -43, -25, -10, 6, 20, 41, 59, 63, 55, 49, 46, 39, 21, -9, -31, -39, -42, -52, -68, -68, -52, -32, -17, -4, 9, 31, 54, 66, 63, 54, 51, 44, 32, 6, -26, -40, -44, -51, -65, -72, -61, -41, -23, -5, 9, 25, 48, 64, 66, 59, 54, 46, 33, 12, -17, -36, -45, -51, -62, -73, -67, -48, -31, -11, 8, 21, 44, 64, 70, 64, 57, 49, 36, 20, -8, -34, -47, -52, -58, -68, -73, -59, -40, -19, 4, 17, 36, 58, 72, 73, 65, 56, 41, 26, 4, -24, -44, -55, -63, -69, -73, -66, -51, -28, -2, 18, 32, 51, 67, 75, 72, 62, 46, 29, 11, -13, -37, -54, -64, -70, -71, -70, -58, -38, -13, 14, 30, 48, 64, 73, 76, 69, 52, 34, 15, -7, -31, -50, -62, -69, -71, -71, -66, -47, -19, 8, 26, 40, 58, 73, 81, 76, 57, 39, 23, 2, -22, -45, -62, -71, -73, -71, -69, -57, -32, 0, 26, 41, 55, 70, 81, 83, 64, 41, 24, 6, -15, -39, -60, -71, -73, -69, -69, -62, -40, -11, 20, 39, 51, 65, 78, 86, 75, 50, 29, 11, -8, -30, -53, -70, -77, -71, -66, -67, -53, -22, 13, 37, 49, 60, 75, 89, 84, 58, 33, 16, -2, -22, -47, -68, -77, -72, -67, -68, -60, -34, 0, 29, 47, 56, 69, 85, 88, 69, 40, 20, 4, -13, -35, -61, -76, -74, -65, -66, -65, -47, -15, 20, 43, 53, 64, 81, 89, 77, 50, 26, 9, -10, -29, -51, -71, -78, -71, -66, -64, -52, -27, 9, 38, 54, 62, 73, 85, 82, 60, 34, 13, -3, -19, -40, -65, -80, -74, -68, -69, -61, -40, -4, 29, 49, 61, 72, 86, 86, 70, 45, 21, 3, -16, -33, -56, -80, -78, -70, -70, -65, -50, -18, 20, 48, 62, 68, 80, 88, 78, 53, 26, 5, -12, -26, -45, -72, -81, -71, -67, -64, -56, -34, 4, 37, 57, 63, 73, 85, 83, 63, 37, 16, 0, -17, -36, -63, -79, -74, -70, -69, -63, -44, -10, 26, 52, 62, 69, 81, 84, 69, 45, 22, 3, -15, -28, -52, -75, -76, -69, -67, -64, -52, -24, 14, 45, 60, 65, 74, 82, 75, 54, 32, 12, -6, -21, -44, -68, -78, -74, -71, -69, -60, -34, 2, 34, 55, 66, 73, 79, 78, 61, 39, 20, 2, -16, -34, -56, -72, -74, -70, -71, -66, -47, -14, 21, 48, 61, 68, 76, 80, 69, 46, 27, 11, -7, -26, -50, -68, -72, -70, -70, -69, -54, -24, 10, 39, 57, 66, 72, 76, 70, 52, 33, 16, -4, -20, -39, -59, -70, -71, -69, -67, -60, -37, -6, 27, 50, 62, 67, 72, 74, 61, 41, 25, 10, -10, -31, -51, -67, -74, -73, -73, -68, -48, -16, 17, 45, 60, 66, 73, 75, 66, 48, 29, 15, -3, -24, -45, -62, -70, -72, -74, -70, -55, -26, 7, 32, 51, 63, 70, 73, 67, 51, 35, 24, 9, -16, -38, -54, -64, -68, -75, -75, -62, -36, -5, 22, 45, 60, 69, 74, 68, 57, 43, 29, 15, -9, -29, -45, -60, -67, -75, -76, -64, -44, -16, 10, 32, 52, 63, 68, 66, 59, 48, 36, 24, 6, -17, -35, -51, -60, -70, -78, -72, -55, -27, 1, 20, 39, 56, 65, 68, 60, 51, 41, 31, 15, -9, -27, -44, -58, -67, -75, -73, -58, -35, -8, 11, 32, 50, 60, 61, 57, 53, 47, 37, 25, 4, -19, -35, -48, -60, -73, -76, -67, -46, -18, 2, 20, 40, 56, 64, 62, 56, 49, 43, 34, 15, -10, -31, -45, -57, -70, -78, -69, -52, -27, -4, 13, 34, 52, 60, 57, 53, 52, 46, 36, 22, 1, -19, -35, -50, -65, -73, -70, -58, -41, -17, 4, 22, 42, 55, 58, 57, 55, 50, 43, 32, 12, -11, -30, -47, -61, -71, -72, -63, -46, -26, -6, 13, 30, 47, 53, 54, 56, 52, 46, 38, 24, 5, -20, -39, -52, -63, -67, -66, -57, -37, -15, 3, 18, 37, 50, 55, 59, 55, 49, 45, 32, 15, -10, -34, -50, -61, -66, -66, -58, -42, -24, -4, 11, 27, 44, 50, 54, 57, 53, 49, 39, 23, 2, -23, -43, -57, -64, -67, -62, -50, -33, -14, 4, 18, 37, 48, 53, 57, 55, 52, 44, 30, 13, -14, -38, -54, -62, -65, -62, -54, -42, -24, -2, 13, 28, 41, 48, 56, 57, 52, 45, 37, 23, 0, -28, -47, -57, -62, -63, -59, -50, -34, -14, 1, 16, 35, 48, 56, 59, 59, 54, 45, 31, 8, -20, -42, -56, -62, -64, -60, -52, -40, -23, -5, 10, 28, 43, 52, 56, 57, 56, 49, 38, 21, -8, -33, -46, -56, -60, -59, -56, -47, -32, -15, 0, 17, 34, 47, 55, 58, 57, 53, 43, 30, 8, -24, -42, -52, -59, -58, -57, -51, -42, -26, -8, 11, 29, 42, 50, 57, 59, 55, 48, 34, 15, -15, -36, -45, -52, -55, -58, -55, -43, -31, -17, -2, 16, 37, 50, 56, 58, 58, 54, 43, 23, -8, -33, -40, -47, -54, -57, -58, -48, -34, -23, -10, 9, 31, 48, 54, 55, 55, 57, 50, 32, 3, -28, -37, -41, -49, -55, -58, -49, -36, -27, -17, 1, 21, 41, 50, 52, 51, 54, 55, 41, 13, -18, -32, -35, -42, -50, -57, -55, -41, -32, -24, -10, 10, 33, 47, 50, 51, 54, 59, 49, 24, -8, -26, -30, -37, -46, -56, -59, -46, -35, -29, -18, 2, 25, 44, 48, 47, 51, 57, 56, 36, 5, -20, -28, -31, -40, -51, -58, -52, -39, -33, -25, -8, 15, 38, 49, 47, 50, 56, 60, 46, 15, -11, -25, -30, -36, -49, -60, -54, -39, -33, -30, -14, 8, 32, 47, 44, 44, 51, 59, 52, 26, -4, -20, -24, -29, -41, -54, -55, -43, -34, -33, -26, -8, 17, 37, 43, 42, 48, 59, 60, 42, 13, -11, -21, -25, -36, -51, -59, -51, -38, -34, -32, -17, 10, 33, 43, 43, 44, 55, 60, 46, 21, -6, -18, -22, -28, -42, -54, -52, -39, -30, -32, -25, -4, 20, 36, 39, 39, 48, 60, 57, 36, 10, -11, -19, -22, -34, -51, -58, -48, -35, -36, -34, -13, 13, 35, 41, 38, 46, 59, 61, 44, 20, -5, -20, -22, -30, -46, -56, -53, -39, -34, -36, -22, 1, 25, 39, 39, 42, 53, 60, 54, 34, 10, -10, -17, -21, -39, -57, -59, -48, -38, -43, -35, -11, 16, 37, 43, 42, 52, 61, 58, 41, 19, -3, -16, -21, -31, -50, -59, -53, -40, -39, -39, -22, 5, 30, 40, 38, 45, 58, 64, 52, 28, 5, -12, -17, -23, -44, -58, -56, -46, -40, -43, -33, -7, 22, 39, 41, 44, 55, 64, 60, 40, 13, -7, -16, -21, -35, -56, -60, -52, -44, -43, -40, -21, 11, 34, 40, 40, 50, 61, 64, 53, 29, 6, -10, -16, -25, -47, -62, -61, -53, -49, -47, -35, -5, 26, 42, 45, 49, 58, 65, 59, 39, 15, -5, -16, -22, -37, -56, -61, -56, -50, -47, -42, -21, 11, 33, 40, 44, 53, 63, 66, 54, 29, 8, -6, -15, -28, -52, -64, -60, -57, -53, -49, -31, 1, 28, 40, 42, 51, 63, 66, 56, 36, 14, -3, -13, -25, -45, -61, -61, -58, -54, -47, -38, -11, 20, 36, 41, 44, 55, 64, 60, 47, 28, 9, -4, -15, -32, -56, -67, -64, -62, -55, -48, -27, 8, 29, 41, 47, 57, 66, 65, 56, 39, 17, 0, -13, -27, -49, -66, -68, -67, -58, -48, -36, -8, 22, 38, 45, 53, 63, 65, 61, 51, 28, 11, -4, -20, -40, -62, -70, -71, -68, -55, -44, -24, 9, 30, 42, 52, 66, 69, 64, 58, 42, 20, 4, -14, -34, -57, -71, -73, -73, -63, -51, -35, -5, 23, 38, 48, 62, 71, 69, 65, 54, 32, 14, -6, -26, -48, -68, -79, -82, -72, -57, -42, -18, 11, 33, 48, 63, 73, 72, 68, 62, 46, 22, 0, -21, -42, -63, -76, -83, -80, -65, -49, -28, -2, 23, 42, 58, 71, 75, 72, 68, 56, 33, 10, -12, -32, -54, -73, -84, -87, -73, -54, -36, -15, 11, 34, 52, 67, 73, 73, 72, 66, 48, 21, -6, -26, -47, -67, -80, -88, -81, -62, -41, -23, 0, 27, 47, 65, 74, 74, 71, 67, 57, 33, 4, -20, -42, -64, -77, -88, -88, -72, -49, -27, -7, 16, 40, 63, 75, 75, 74, 69, 64, 46, 16, -13, -35, -57, -74, -87, -93, -81, -58, -35, -17, 6, 33, 59, 73, 76, 76, 71, 68, 58, 29, -4, -29, -48, -68, -83, -94, -92, -70, -42, -22, -4, 21, 51, 73, 78, 76, 73, 70, 63, 40, 7, -24, -42, -60, -79, -91, -92, -76, -52, -30, -12, 9, 39, 66, 76, 76, 75, 74, 70, 54, 24, -12, -36, -52, -72, -93, -100, -90, -64, -38, -21, -5, 25, 61, 81, 81, 77, 78, 76, 63, 33, -5, -33, -49, -67, -90, -100, -92, -71, -44, -21, -8, 14, 49, 75, 82, 77, 76, 75, 66, 45, 10, -27, -45, -59, -80, -98, -98, -81, -52, -26, -12, 2, 34, 71, 86, 80, 75, 77, 71, 54, 23, -17, -44, -57, -74, -93, -99, -87, -65, -36, -14, -4, 20, 55, 79, 82, 78, 78, 75, 65, 41, 1, -34, -52, -67, -88, -104, -98, -76, -47, -23, -12, 6, 45, 81, 90, 81, 79, 81, 72, 50, 11, -28, -50, -61, -81, -102, -103, -84, -57, -30, -13, 1, 30, 70, 92, 88, 81, 80, 75, 59, 27, -15, -48, -62, -76, -97, -106, -94, -69, -39, -16, -4, 17, 59, 92, 94, 87, 86, 83, 67, 36, -4, -38, -61, -77, -96, -111, -102, -80, -53, -26, -8, 14, 50, 89, 101, 93, 87, 83, 73, 46, 7, -31, -58, -72, -87, -106, -106, -88, -59, -31, -12, 5, 33, 74, 99, 99, 90, 84, 78, 57, 22, -18, -49, -70, -84, -100, -108, -96, -72, -43, -21, -3, 24, 61, 95, 106, 99, 90, 82, 65, 34, -6, -40, -66, -83, -96, -106, -102, -82, -52, -27, -8, 15, 48, 86, 107, 105, 94, 85, 73, 45, 6, -32, -61, -80, -91, -102, -106, -92, -63, -35, -15, 8, 37, 74, 102, 109, 98, 87, 76, 54, 21, -16, -50, -76, -89, -98, -104, -98, -76, -46, -23, -2, 25, 60, 93, 111, 106, 92, 82, 65, 35, -5, -39, -66, -83, -95, -105, -105, -86, -57, -33, -11, 15, 50, 86, 111, 115, 102, 88, 71, 43, 7, -32, -64, -86, -96, -100, -102, -92, -67, -40, -13, 13, 42, 75, 103, 116, 106, 90, 74, 49, 16, -21, -54, -80, -94, -98, -100, -94, -75, -50, -23, 4, 30, 62, 95, 117, 115, 100, 81, 57, 28, -10, -46, -75, -95, -102, -101, -97, -83, -61, -32, -2, 24, 55, 87, 111, 118, 106, 88, 65, 35, 0, -36, -67, -89, -101, -102, -98, -89, -68, -43, -13, 16, 46, 80, 107, 121, 116, 98, 75, 47, 11, -27, -62, -87, -101, -104, -100, -93, -77, -51, -18, 13, 36, 67, 99, 119, 119, 103, 81, 53, 21, -16, -52, -79, -96, -106, -102, -93, -82, -60, -30, 3, 30, 59, 88, 111, 121, 111, 89, 61, 30, -4, -41, -74, -94, -106, -104, -95, -87, -70, -41, -8, 22, 49, 81, 106, 120, 118, 98, 73, 41, 8, -30, -64, -87, -104, -111, -100, -91, -77, -51, -21, 13, 41, 73, 100, 117, 122, 107, 83, 52, 19, -18, -55, -82, -101, -111, -105, -93, -83, -60, -29, 5, 35, 64, 92, 112, 121, 112, 88, 61, 29, -7, -45, -75, -94, -108, -108, -96, -87, -67, -37, -5, 26, 52, 83, 105, 116, 116, 97, 70, 41, 7, -33, -67, -91, -105, -110, -99, -88, -73, -48, -18, 15, 45, 74, 98, 114, 118, 104, 79, 51, 17, -21, -58, -86, -102, -109, -103, -90, -77, -54, -23, 9, 36, 62, 88, 107, 114, 107, 88, 63, 30, -8, -46, -77, -96, -107, -108, -97, -81, -63, -36, -4, 30, 59, 84, 104, 115, 112, 95, 69, 38, 5, -33, -69, -94, -104, -105, -99, -87, -72, -44, -11, 21, 47, 71, 97, 113, 113, 99, 77, 49, 17, -19, -57, -87, -101, -105, -103, -90, -72, -54, -24, 10, 41, 64, 86, 104, 111, 104, 85, 57, 25, -7, -42, -75, -96, -101, -98, -92, -79, -61, -36, -4, 28, 51, 74, 98, 110, 107, 94, 70, 38, 5, -30, -64, -89, -101, -101, -95, -79, -63, -43, -14, 21, 48, 68, 90, 105, 108, 97, 74, 44, 12, -20, -52, -83, -96, -96, -92, -82, -67, -49, -24, 10, 39, 59, 79, 99, 107, 101, 83, 54, 21, -11, -41, -71, -92, -98, -95, -84, -68, -54, -35, -5, 28, 54, 73, 92, 103, 103, 90, 64, 31, -4, -34, -63, -85, -94, -92, -84, -70, -56, -38, -11, 19, 44, 64, 83, 95, 98, 90, 66, 39, 9, -22, -50, -73, -86, -89, -84, -72, -59, -45, -23, 6, 35, 58, 75, 89, 96, 92, 75, 49, 19, -14, -42, -63, -80, -88, -84, -74, -60, -48, -30, -5, 23, 52, 70, 82, 91, 91, 79, 57, 29, -3, -33, -54, -70, -84, -87, -79, -65, -50, -35, -16, 10, 41, 68, 80, 85, 88, 82, 64, 36, 3, -28, -49, -60, -72, -83, -81, -66, -49, -37, -22, -2, 28, 58, 74, 78, 83, 81, 69, 45, 14, -18, -42, -55, -66, -77, -79, -68, -53, -39, -25, -8, 17, 46, 67, 72, 75, 74, 70, 53, 24, -9, -34, -48, -55, -64, -74, -70, -55, -40, -28, -17, 3, 33, 61, 70, 71, 69, 68, 61, 37, 3, -28, -44, -50, -57, -70, -73, -58, -41, -30, -21, -8, 21, 52, 67, 69, 66, 66, 64, 44, 10, -22, -39, -48, -52, -61, -72, -62, -43, -29, -20, -12, 7, 38, 62, 68, 61, 56, 60, 51, 23, -12, -36, -43, -44, -49, -65, -65, -45, -29, -22, -19, -7, 24, 52, 65, 57, 52, 58, 57, 36, 0, -30, -38, -37, -39, -55, -66, -52, -33, -23, -21, -14, 10, 40, 60, 59, 49, 51, 54, 43, 11, -21, -35, -37, -33, -42, -55, -49, -29, -19, -20, -19, -5, 23, 49, 54, 43, 42, 50, 49, 23, -12, -30, -34, -29, -31, -49, -54, -35, -19, -16, -18, -11, 10, 39, 55, 45, 35, 41, 47, 31, -3, -26, -33, -28, -23, -36, -47, -36, -18, -11, -16, -16, -3, 21, 42, 42, 32, 32, 40, 35, 13, -13, -25, -24, -17, -22, -37, -38, -25, -16, -16, -19, -11, 7, 30, 42, 34, 27, 33, 35, 19, -6, -21, -23, -17, -14, -23, -29, -21, -11, -10, -17, -16, -4, 14, 30, 31, 20, 21, 29, 24, 6, -11, -16, -11, -5, -10, -20, -22, -15, -12, -17, -21, -15, 0, 20, 29, 22, 17, 23, 25, 16, -2, -14, -14, -7, -2, -9, -14, -12, -9, -11, -17, -17, -11, 3, 18, 17, 9, 13, 19, 17, 7, -5, -5, 3, 8, 3, -7, -10, -12, -14, -20, -22, -17, -7, 9, 17, 10, 8, 15, 18, 11, 2, -3, 1, 8, 9, 5, -3, -9, -12, -18, -21, -21, -19, -4, 10, 9, 2, 5, 14, 16, 11, 4, 5, 13, 16, 14, 6, -8, -14, -19, -23, -24, -21, -13, -2, 7, 3, -2, 8, 12, 11, 9, 10, 14, 19, 20, 16, 4, -9, -17, -23, -26, -27, -24, -14, -2, 1, -5, 3, 15, 17, 14, 14, 17, 22, 25, 20, 9, -8, -19, -25, -30, -29, -26, -22, -11, 0, -3, -3, 9, 16, 19, 20, 21, 24, 28, 28, 20, 2, -16, -25, -30, -34, -33, -32, -23, -9, -6, -8, 2, 15, 21, 24, 26, 29, 33, 34, 30, 14, -11, -26, -33, -38, -38, -37, -34, -23, -12, -7, 0, 11, 21, 29, 34, 35, 37, 39, 35, 21, -5, -26, -34, -39, -40, -42, -42, -31, -17, -9, -4, 7, 19, 31, 38, 38, 41, 42, 40, 28, 3, -22, -36, -42, -45, -46, -46, -37, -23, -14, -6, 6, 20, 32, 40, 40, 44, 46, 41, 31, 13, -12, -32, -44, -47, -48, -49, -44, -32, -20, -8, 3, 15, 27, 40, 45, 47, 50, 47, 39, 21, -6, -29, -42, -46, -51, -56, -52, -41, -24, -13, -4, 11, 27, 41, 51, 52, 53, 52, 45, 29, 2, -25, -45, -50, -52, -57, -56, -49, -32, -16, -4, 9, 22, 36, 49, 55, 56, 56, 50, 35, 11, -14, -37, -51, -57, -61, -61, -56, -41, -23, -8, 8, 21, 33, 48, 61, 64, 60, 54, 40, 17, -8, -34, -52, -59, -62, -63, -60, -49, -30, -14, 2, 19, 33, 47, 60, 66, 67, 65, 50, 25, -3, -26, -47, -59, -68, -72, -66, -57, -38, -20, -5, 14, 30, 44, 61, 71, 71, 68, 57, 34, 7, -20, -43, -58, -68, -72, -69, -62, -45, -25, -10, 7, 24, 42, 59, 70, 74, 73, 65, 46, 16, -15, -38, -53, -65, -77, -77, -70, -54, -34, -19, 0, 20, 41, 60, 74, 82, 80, 71, 54, 27, -8, -36, -55, -68, -78, -82, -76, -61, -40, -20, -2, 17, 36, 57, 74, 83, 82, 74, 62, 39, 3, -31, -49, -62, -75, -84, -84, -69, -47, -27, -13, 6, 31, 56, 73, 82, 86, 80, 68, 49, 14, -24, -46, -60, -74, -83, -86, -76, -54, -32, -15, 3, 23, 48, 71, 85, 87, 80, 71, 57, 27, -12, -41, -57, -68, -78, -88, -84, -64, -41, -23, -5, 16, 40, 65, 84, 90, 87, 77, 63, 36, -3, -34, -57, -69, -76, -85, -87, -73, -48, -27, -8, 13, 34, 60, 83, 91, 86, 77, 66, 44, 9, -26, -53, -68, -74, -83, -88, -80, -56, -33, -13, 9, 29, 55, 79, 93, 89, 76, 67, 52, 21, -15, -46, -69, -74, -77, -84, -86, -67, -42, -20, 4, 23, 43, 71, 94, 95, 80, 67, 56, 32, 0, -37, -66, -74, -73, -78, -87, -76, -50, -25, 1, 21, 37, 61, 88, 97, 84, 67, 57, 38, 8, -25, -59, -77, -77, -76, -81, -80, -61, -34, -6, 20, 36, 55, 80, 96, 91, 70, 54, 39, 17, -14, -51, -75, -79, -75, -77, -80, -68, -40, -11, 15, 33, 48, 71, 92, 91, 73, 57, 45, 24, -3, -38, -68, -79, -77, -76, -80, -74, -51, -19, 12, 32, 46, 65, 88, 96, 83, 59, 40, 24, 4, -31, -67, -83, -80, -73, -73, -72, -55, -24, 9, 31, 44, 58, 78, 90, 84, 63, 42, 28, 10, -18, -53, -77, -82, -76, -73, -74, -65, -37, -2, 27, 42, 55, 73, 88, 90, 72, 47, 28, 13, -12, -45, -74, -84, -78, -70, -68, -63, -43, -9, 23, 42, 52, 64, 78, 84, 75, 52, 32, 17, -3, -32, -62, -79, -78, -71, -67, -65, -52, -19, 15, 38, 50, 61, 73, 80, 79, 59, 34, 18, 3, -21, -51, -75, -81, -72, -64, -61, -54, -31, 4, 31, 48, 55, 63, 73, 78, 67, 40, 21, 8, -12, -39, -65, -80, -76, -65, -58, -52, -38, -8, 25, 45, 56, 61, 67, 74, 69, 47, 22, 7, -10, -31, -56, -75, -77, -66, -57, -49, -37, -14, 16, 40, 53, 57, 61, 67, 69, 55, 30, 11, -6, -25, -47, -69, -78, -70, -59, -51, -40, -20, 10, 34, 51, 58, 59, 63, 66, 59, 36, 14, -2, -19, -40, -61, -75, -71, -59, -51, -41, -27, -2, 26, 47, 58, 58, 59, 64, 63, 46, 19, -2, -17, -35, -56, -71, -75, -64, -50, -40, -26, -6, 21, 43, 55, 57, 56, 58, 59, 47, 23, 1, -13, -29, -48, -63, -69, -61, -48, -40, -29, -11, 13, 35, 48, 53, 51, 53, 57, 50, 33, 9, -10, -25, -42, -56, -65, -64, -51, -40, -29, -13, 9, 30, 44, 50, 48, 47, 50, 46, 35, 13, -8, -20, -33, -47, -57, -56, -48, -38, -30, -16, 1, 21, 35, 44, 46, 42, 44, 44, 39, 21, -3, -18, -30, -40, -51, -57, -51, -37, -26, -14, 0, 16, 33, 42, 43, 37, 34, 37, 35, 22, 1, -17, -27, -34, -41, -48, -45, -36, -25, -11, 0, 11, 24, 34, 38, 35, 30, 29, 30, 24, 8, -11, -24, -31, -36, -42, -42, -35, -25, -12, -2, 9, 21, 29, 33, 32, 27, 25, 26, 23, 9, -8, -21, -31, -34, -36, -37, -33, -26, -13, -2, 8, 18, 24, 28, 29, 27, 22, 20, 21, 14, -2, -17, -27, -30, -31, -33, -32, -26, -14, -3, 6, 15, 22, 27, 26, 25, 22, 17, 17, 13, 3, -12, -25, -30, -31, -30, -27, -24, -14, 0, 8, 16, 20, 22, 22, 21, 16, 11, 13, 13, 3, -8, -21, -27, -26, -25, -25, -23, -12, 0, 6, 12, 18, 20, 22, 20, 15, 9, 9, 10, 3, -9, -21, -29, -28, -23, -20, -19, -10, 3, 13, 17, 19, 19, 21, 17, 11, 4, 1, 4, 0, -8, -17, -25, -24, -21, -19, -16, -9, 4, 13, 17, 19, 20, 22, 19, 11, 3, -4, -3, -4, -12, -18, -26, -28, -23, -16, -10, -5, 5, 18, 25, 25, 22, 21, 19, 9, 0, -9, -11, -10, -13, -16, -24, -27, -22, -14, -8, -2, 7, 17, 25, 25, 22, 20, 17, 10, -2, -10, -12, -13, -15, -18, -20, -24, -22, -16, -8, 3, 11, 17, 25, 27, 23, 21, 17, 9, 0, -10, -12, -13, -18, -19, -20, -24, -23, -17, -10, 0, 11, 19, 26, 30, 26, 24, 20, 12, 3, -8, -15, -18, -22, -25, -25, -25, -24, -20, -12, 2, 15, 20, 25, 31, 33, 29, 23, 12, 3, -5, -15, -23, -28, -28, -25, -22, -22, -18, -10, 2, 15, 19, 23, 30, 32, 28, 24, 15, 7, 1, -13, -23, -27, -29, -28, -26, -24, -20, -14, -2, 13, 20, 24, 32, 34, 32, 29, 22, 9, -2, -10, -21, -30, -34, -34, -29, -22, -20, -18, -5, 14, 23, 25, 31, 36, 35, 30, 22, 10, 0, -8, -21, -34, -39, -36, -32, -27, -20, -15, -5, 14, 27, 28, 32, 36, 35, 33, 25, 14, 0, -11, -21, -34, -40, -41, -39, -30, -20, -13, -6, 10, 27, 30, 32, 35, 34, 36, 29, 17, 5, -7, -16, -33, -45, -45, -43, -33, -24, -18, -9, 8, 26, 32, 33, 39, 38, 36, 31, 20, 10, -6, -19, -32, -45, -47, -46, -39, -25, -12, -3, 8, 22, 32, 32, 35, 35, 32, 31, 23, 14, 0, -15, -26, -43, -51, -50, -43, -29, -17, -6, 5, 19, 34, 36, 33, 37, 37, 34, 25, 16, 5, -11, -26, -41, -51, -55, -51, -36, -21, -7, 7, 16, 28, 37, 35, 35, 36, 34, 30, 20, 9, -7, -22, -37, -49, -56, -54, -42, -25, -11, 2, 13, 24, 35, 38, 37, 38, 37, 32, 25, 16, 1, -21, -38, -47, -56, -58, -50, -34, -14, 4, 13, 20, 31, 40, 39, 35, 36, 34, 28, 20, 5, -15, -33, -44, -55, -63, -54, -38, -19, -2, 10, 17, 30, 40, 41, 36, 38, 41, 33, 22, 9, -13, -36, -50, -55, -63, -61, -44, -22, 2, 18, 22, 28, 38, 42, 39, 34, 35, 34, 27, 14, -7, -29, -43, -51, -60, -63, -50, -30, -10, 8, 16, 21, 32, 40, 40, 38, 39, 41, 35, 24, 6, -20, -41, -54, -62, -65, -58, -39, -16, 7, 18, 22, 29, 39, 43, 40, 35, 38, 37, 27, 12, -14, -37, -51, -58, -64, -64, -47, -22, -2, 14, 18, 24, 36, 44, 45, 41, 43, 43, 32, 17, -8, -35, -54, -63, -67, -68, -56, -29, -4, 16, 24, 26, 35, 44, 47, 43, 38, 38, 36, 24, 0, -30, -50, -57, -59, -63, -61, -40, -11, 11, 20, 20, 26, 39, 48, 46, 40, 39, 42, 33, 12, -20, -47, -58, -60, -62, -61, -49, -23, 2, 17, 21, 22, 33, 48, 51, 45, 43, 43, 38, 20, -10, -41, -58, -61, -64, -62, -55, -35, -9, 10, 21, 23, 32, 50, 57, 49, 45, 45, 43, 26, -6, -38, -58, -62, -65, -67, -61, -44, -15, 10, 23, 26, 28, 44, 59, 55, 46, 42, 41, 33, 6, -30, -57, -64, -62, -64, -62, -50, -26, 2, 18, 26, 28, 39, 59, 60, 48, 43, 43, 37, 14, -22, -53, -67, -63, -65, -66, -55, -33, -2, 19, 28, 31, 37, 55, 64, 53, 41, 39, 37, 20, -16, -48, -66, -65, -62, -66, -60, -43, -12, 15, 26, 31, 37, 53, 69, 63, 46, 39, 38, 27, -5, -44, -72, -73, -65, -65, -63, -52, -24, 11, 31, 36, 38, 48, 65, 70, 53, 38, 34, 28, 5, -35, -69, -78, -70, -65, -63, -53, -30, 2, 26, 38, 43, 49, 62, 69, 58, 40, 33, 28, 9, -25, -61, -78, -75, -69, -64, -55, -37, -7, 22, 36, 43, 49, 57, 66, 62, 44, 31, 29, 15, -16, -52, -76, -77, -69, -63, -57, -44, -16, 14, 33, 42, 48, 54, 65, 68, 52, 33, 27, 19, -6, -41, -72, -82, -74, -65, -59, -48, -24, 7, 29, 43, 50, 53, 60, 67, 58, 39, 28, 22, 2, -31, -64, -82, -79, -71, -61, -49, -31, -2, 22, 40, 51, 55, 58, 65, 63, 46, 29, 21, 9, -21, -56, -79, -83, -77, -65, -54, -37, -10, 16, 36, 50, 57, 60, 65, 64, 50, 33, 22, 11, -13, -47, -73, -82, -80, -70, -57, -42, -19, 8, 30, 49, 58, 61, 62, 64, 56, 41, 24, 11, -6, -35, -66, -80, -82, -75, -61, -45, -25, -2, 22, 43, 57, 63, 64, 63, 58, 49, 31, 15, -2, -26, -58, -79, -85, -81, -66, -49, -31, -9, 17, 39, 55, 64, 69, 67, 61, 53, 35, 16, 1, -20, -49, -75, -86, -85, -74, -54, -34, -11, 11, 33, 53, 64, 70, 68, 59, 51, 40, 22, 5, -15, -40, -66, -79, -81, -78, -63, -41, -19, 4, 25, 44, 58, 67, 72, 65, 57, 47, 29, 11, -8, -31, -61, -81, -85, -82, -68, -47, -25, -3, 21, 44, 59, 68, 73, 68, 56, 47, 33, 15, -7, -27, -52, -76, -82, -82, -72, -52, -30, -7, 13, 36, 57, 67, 74, 72, 61, 48, 36, 20, -4, -25, -47, -71, -81, -81, -75, -56, -33, -10, 11, 30, 49, 63, 73, 74, 63, 48, 37, 25, 6, -20, -41, -63, -79, -81, -77, -65, -43, -19, 4, 25, 45, 63, 73, 76, 70, 55, 41, 28, 10, -15, -38, -59, -77, -83, -79, -70, -49, -25, -4, 20, 40, 59, 74, 76, 73, 62, 46, 33, 16, -10, -34, -51, -68, -83, -85, -75, -58, -34, -11, 14, 35, 55, 73, 79, 76, 69, 51, 33, 20, -2, -30, -53, -67, -81, -84, -76, -61, -39, -14, 11, 32, 49, 67, 77, 74, 68, 55, 37, 23, 5, -22, -45, -59, -73, -84, -82, -68, -46, -24, 3, 26, 43, 62, 75, 74, 72, 61, 42, 25, 10, -15, -40, -57, -70, -83, -84, -71, -49, -28, -6, 20, 41, 59, 72, 72, 69, 63, 48, 29, 13, -8, -31, -51, -66, -79, -84, -75, -56, -37, -16, 12, 36, 55, 71, 74, 72, 69, 54, 34, 16, -5, -28, -47, -61, -75, -85, -80, -60, -38, -20, 4, 30, 53, 68, 71, 69, 67, 57, 39, 20, 0, -21, -41, -58, -71, -79, -79, -66, -45, -25, -3, 23, 45, 61, 68, 69, 70, 63, 47, 29, 8, -16, -37, -56, -71, -80, -81, -71, -52, -30, -7, 17, 41, 60, 67, 67, 68, 65, 50, 30, 10, -14, -31, -47, -65, -77, -79, -70, -53, -33, -14, 8, 34, 56, 62, 62, 66, 64, 54, 36, 15, -8, -27, -42, -61, -73, -75, -70, -56, -36, -14, 5, 26, 49, 60, 59, 61, 60, 54, 42, 23, -2, -22, -35, -53, -69, -75, -70, -58, -41, -20, -3, 18, 43, 59, 57, 57, 60, 56, 44, 28, 7, -17, -32, -47, -63, -73, -72, -62, -46, -23, -6, 12, 35, 55, 60, 57, 59, 56, 49, 35, 14, -13, -28, -40, -58, -72, -73, -62, -50, -31, -13, 5, 30, 51, 59, 56, 58, 61, 56, 38, 17, -9, -26, -37, -52, -68, -74, -63, -50, -32, -14, 1, 22, 45, 57, 56, 51, 54, 54, 41, 21, -4, -22, -31, -44, -59, -69, -63, -48, -36, -21, -7, 11, 35, 52, 56, 53, 54, 58, 48, 30, 8, -17, -32, -43, -57, -68, -69, -56, -39, -22, -8, 6, 28, 49, 57, 54, 51, 55, 52, 35, 13, -13, -29, -36, -49, -64, -70, -58, -39, -23, -11, 0, 19, 43, 57, 55, 47, 49, 55, 43, 18, -9, -28, -35, -42, -57, -69, -65, -45, -25, -11, 1, 14, 37, 55, 60, 50, 45, 48, 42, 21, -4, -25, -35, -40, -50, -60, -61, -46, -27, -15, -6, 6, 25, 46, 56, 50, 43, 45, 47, 33, 9, -15, -30, -37, -45, -58, -64, -56, -36, -18, -8, 4, 18, 40, 58, 59, 47, 39, 41, 35, 12, -15, -32, -38, -39, -46, -57, -55, -37, -17, -7, 1, 11, 27, 48, 56, 47, 37, 38, 38, 21, -6, -24, -32, -37, -43, -54, -57, -44, -25, -9, 2, 11, 24, 44, 57, 51, 38, 32, 31, 21, -5, -28, -35, -36, -36, -45, -51, -41, -25, -8, 3, 8, 17, 33, 48, 49, 37, 31, 30, 25, 7, -18, -30, -34, -37, -40, -48, -47, -33, -16, 1, 11, 16, 28, 42, 50, 43, 30, 25, 22, 10, -12, -28, -33, -34, -35, -41, -44, -33, -18, -2, 9, 12, 20, 32, 43, 41, 29, 24, 22, 14, -3, -21, -29, -30, -31, -35, -41, -35, -21, -6, 9, 13, 18, 27, 38, 42, 29, 18, 16, 13, 4, -15, -27, -28, -27, -28, -34, -34, -23, -10, 5, 11, 14, 22, 32, 37, 31, 20, 16, 12, 6, -9, -22, -25, -27, -26, -32, -34, -27, -15, 0, 10, 12, 18, 28, 36, 35, 23, 14, 11, 8, -3, -19, -28, -28, -25, -27, -32, -28, -16, -2, 11, 14, 14, 22, 30, 31, 24, 15, 11, 8, 2, -11, -22, -25, -25, -26, -30, -28, -18, -7, 5, 12, 14, 19, 27, 30, 26, 19, 13, 9, 4, -6, -20, -26, -23, -24, -27, -27, -19, -6, 4, 12, 12, 13, 22, 26, 22, 15, 11, 10, 6, -2, -12, -19, -19, -21, -25, -25, -20, -11, -3, 5, 9, 13, 19, 24, 24, 21, 15, 12, 7, 2, -9, -20, -22, -22, -23, -24, -22, -11, -2, 7, 11, 13, 17, 21, 21, 18, 13, 11, 7, 1, -7, -15, -19, -19, -21, -20, -18, -12, -4, 2, 8, 11, 15, 17, 16, 15, 13, 11, 8, 4, -3, -11, -16, -15, -19, -20, -16, -12, -5, 2, 5, 8, 14, 17, 15, 11, 10, 9, 8, 4, -2, -6, -11, -12, -14, -18, -13, -7, -6, -3, 2, 6, 10, 13, 13, 9, 8, 9, 6, 1, 0, -5, -9, -12, -12, -13, -12, -4, 1, 3, 4, 4, 7, 11, 10, 7, 3, 3, 4, 2, -2, -3, -6, -7, -6, -6, -8, -5, 2, 1, 1, 0, 1, 5, 5, 3, 0, 0, 5, 5, 2, 3, 0, -3, -5, -6, -8, -7, -2, -3, -4, -2, -2, 3, 6, 4, 1, -3, 1, 5, 3, 2, 0, -2, -3, -4, -5, -5, 1, 2, -3, -3, -4, -3, 4, 4, 0, -5, -3, 3, 3, 2, 1, 1, 0, 0, 0, -3, -2, 1, -2, -4, -3, -4, 1, 5, 2, -5, -7, -2, 2, -2, -2, 0, 2, 3, 2, 2, 3, 6, 4, -2, -5, -6, -2, 3, -2, -9, -11, -5, 0, -3, -4, -2, 3, 7, 8, 4, 2, 4, 3, 0, -6, -8, -6, 2, 4, -3, -10, -10, -5, -2, -4, -5, -3, 5, 11, 11, 8, 5, 5, 4, -2, -9, -9, -2, 0, -5, -13, -14, -10, -5, -4, -2, 2, 6, 14, 15, 11, 8, 6, 1, -5, -10, -12, -6, 1, -2, -10, -15, -11, -4, -3, -6, -5, 2, 14, 19, 14, 10, 10, 8, 3, -6, -15, -12, -4, -4, -12, -18, -17, -10, -2, 0, 1, 6, 16, 25, 21, 12, 8, 4, -2, -8, -18, -20, -11, -6, -9, -14, -14, -10, -3, 0, 1, 6, 13, 23, 25, 17, 13, 9, 1, -6, -13, -18, -14, -11, -13, -17, -19, -14, -8, -3, 1, 7, 14, 24, 30, 24, 16, 12, 4, -5, -11, -18, -19, -15, -12, -14, -19, -18, -14, -9, 0, 8, 13, 19, 27, 28, 22, 18, 9, -4, -11, -14, -16, -15, -16, -16, -17, -16, -14, -13, -6, 4, 12, 19, 26, 31, 27, 19, 13, 3, -8, -12, -16, -18, -19, -17, -16, -20, -18, -15, -10, 1, 10, 18, 24, 31, 30, 22, 18, 9, -4, -10, -14, -17, -20, -22, -19, -19, -22, -18, -13, -2, 9, 16, 21, 29, 36, 29, 19, 12, 1, -7, -10, -15, -22, -24, -20, -18, -21, -21, -17, -8, 7, 16, 23, 27, 33, 35, 26, 17, 7, -5, -11, -14, -22, -27, -24, -19, -22, -25, -19, -11, 5, 16, 21, 25, 33, 38, 31, 18, 9, -2, -10, -13, -22, -29, -28, -21, -18, -24, -22, -15, -3, 14, 21, 24, 30, 38, 36, 24, 13, 4, -5, -9, -16, -28, -32, -25, -21, -25, -27, -18, -7, 8, 18, 24, 31, 40, 40, 29, 16, 6, -3, -8, -16, -27, -31, -27, -22, -24, -27, -21, -10, 4, 16, 22, 28, 37, 40, 33, 19, 7, 1, -5, -12, -23, -32, -28, -23, -23, -27, -26, -15, -2, 13, 21, 25, 34, 41, 38, 28, 14, 4, -3, -11, -22, -34, -35, -30, -26, -28, -29, -20, -3, 14, 24, 27, 32, 41, 42, 34, 17, 4, -4, -11, -20, -32, -38, -33, -28, -27, -27, -22, -9, 7, 20, 29, 34, 39, 40, 37, 24, 10, 2, -7, -16, -28, -40, -40, -33, -29, -28, -27, -16, 5, 21, 28, 32, 36, 41, 40, 30, 12, 1, -6, -11, -22, -37, -42, -34, -30, -29, -27, -20, -3, 16, 27, 32, 34, 39, 41, 35, 20, 6, -4, -11, -16, -32, -45, -41, -33, -31, -27, -23, -10, 13, 28, 33, 35, 38, 39, 36, 25, 8, -6, -11, -14, -26, -42, -45, -34, -29, -25, -23, -15, 6, 26, 36, 36, 36, 37, 36, 29, 14, -2, -12, -14, -23, -42, -50, -42, -32, -23, -18, -15, 3, 25, 38, 39, 35, 35, 37, 33, 18, -3, -15, -18, -20, -34, -48, -47, -34, -22, -14, -12, -4, 17, 35, 41, 37, 34, 33, 33, 24, 6, -13, -22, -22, -30, -45, -51, -39, -23, -10, -6, -3, 13, 32, 41, 37, 30, 29, 31, 27, 10, -10, -22, -23, -26, -38, -48, -44, -28, -12, -5, -3, 9, 27, 38, 38, 32, 28, 29, 27, 17, -4, -21, -26, -27, -35, -47, -49, -33, -12, 2, 5, 9, 23, 35, 40, 34, 21, 23, 25, 22, 5, -20, -28, -28, -29, -39, -50, -43, -19, 3, 10, 7, 15, 29, 41, 43, 28, 22, 23, 22, 12, -16, -33, -32, -32, -38, -46, -43, -21, 3, 15, 13, 16, 29, 35, 35, 27, 19, 19, 19, 15, -8, -30, -31, -30, -32, -40, -44, -29, -2, 18, 17, 11, 22, 34, 37, 32, 21, 18, 20, 17, -2, -28, -37, -34, -34, -38, -42, -30, -7, 16, 22, 16, 20, 31, 31, 29, 23, 17, 18, 19, 6, -21, -37, -35, -34, -35, -38, -35, -15, 14, 27, 21, 13, 23, 31, 31, 26, 16, 12, 16, 12, -10, -35, -39, -35, -36, -36, -34, -21, 6, 24, 24, 16, 20, 29, 28, 27, 22, 16, 17, 15, -4, -29, -41, -39, -40, -39, -36, -29, -6, 20, 27, 21, 19, 28, 33, 31, 27, 18, 14, 13, 2, -22, -41, -43, -40, -39, -34, -28, -12, 16, 28, 24, 19, 25, 29, 27, 24, 19, 15, 12, 4, -15, -34, -41, -40, -37, -32, -26, -18, 5, 24, 24, 20, 21, 26, 27, 26, 24, 18, 12, 6, -9, -30, -44, -45, -41, -33, -26, -19, -2, 23, 29, 24, 22, 24, 28, 25, 22, 18, 13, 7, -7, -24, -40, -46, -42, -36, -28, -21, -6, 15, 28, 25, 22, 25, 29, 28, 23, 20, 14, 6, -6, -22, -40, -47, -42, -36, -28, -23, -10, 13, 30, 28, 21, 23, 27, 28, 21, 18, 16, 9, -2, -17, -33, -44, -44, -38, -31, -23, -14, 5, 25, 32, 25, 23, 26, 29, 24, 16, 13, 8, -2, -15, -31, -43, -44, -37, -30, -23, -14, 1, 21, 31, 27, 22, 24, 28, 25, 17, 13, 10, 3, -10, -27, -40, -44, -38, -32, -26, -17, -3, 16, 31, 31, 25, 25, 30, 29, 17, 8, 7, 3, -8, -25, -39, -43, -37, -31, -27, -18, -4, 13, 29, 32, 26, 24, 27, 27, 17, 9, 8, 6, -5, -20, -34, -39, -37, -34, -30, -21, -8, 6, 23, 34, 31, 29, 28, 27, 22, 13, 6, 5, -4, -18, -34, -40, -37, -34, -29, -23, -10, 5, 21, 32, 29, 27, 29, 26, 20, 12, 4, 3, 0, -12, -28, -37, -35, -31, -29, -23, -13, 1, 16, 30, 33, 29, 27, 25, 21, 15, 5, -2, -3, -9, -22, -35, -36, -31, -29, -24, -14, 0, 12, 27, 35, 31, 29, 26, 21, 16, 8, -2, -3, -7, -19, -34, -36, -32, -31, -28, -18, -3, 11, 22, 32, 32, 30, 29, 23, 16, 11, 2, -3, -6, -17, -32, -37, -32, -30, -31, -23, -6, 9, 18, 30, 36, 32, 31, 25, 17, 13, 4, -6, -8, -14, -26, -36, -34, -31, -31, -25, -11, 6, 16, 24, 34, 35, 33, 28, 17, 16, 10, -3, -9, -13, -23, -34, -36, -32, -31, -27, -16, 2, 16, 22, 30, 35, 33, 30, 21, 15, 11, 0, -7, -11, -20, -31, -35, -31, -31, -29, -21, -6, 13, 21, 25, 32, 34, 33, 26, 18, 13, 4, -6, -10, -19, -29, -34, -34, -29, -27, -24, -12, 7, 20, 25, 30, 33, 32, 29, 21, 13, 7, -5, -11, -18, -28, -35, -36, -29, -25, -24, -16, 3, 21, 26, 28, 34, 37, 34, 26, 12, 4, -5, -13, -20, -30, -35, -39, -35, -24, -19, -13, -2, 15, 27, 30, 32, 34, 31, 28, 18, 5, -6, -15, -20, -24, -31, -37, -35, -24, -19, -16, -9, 8, 24, 30, 30, 33, 35, 35, 24, 5, -5, -11, -20, -27, -34, -40, -39, -30, -21, -16, -9, 4, 20, 32, 36, 36, 36, 35, 31, 13, -3, -13, -23, -27, -29, -41, -44, -33, -19, -11, -10, -4, 14, 32, 38, 34, 33, 36, 33, 18, -4, -13, -20, -25, -28, -37, -43, -34, -22, -14, -8, -4, 9, 26, 39, 38, 35, 35, 34, 23, 3, -12, -21, -28, -28, -31, -41, -40, -27, -15, -7, -6, 2, 20, 37, 42, 36, 34, 35, 28, 9, -10, -18, -24, -26, -29, -38, -42, -32, -21, -11, -6, -3, 12, 33, 45, 41, 37, 37, 29, 13, -4, -17, -26, -28, -28, -33, -39, -37, -26, -15, -8, -7, 6, 29, 47, 46, 39, 34, 30, 20, 1, -18, -26, -26, -25, -29, -37, -40, -31, -17, -8, -7, 0, 20, 42, 51, 45, 38, 30, 18, 7, -10, -24, -27, -26, -24, -29, -38, -37, -27, -14, -9, -6, 11, 36, 51, 47, 42, 34, 24, 14, -3, -20, -25, -23, -22, -26, -37, -42, -33, -17, -8, -7, 4, 28, 50, 54, 45, 35, 24, 15, 3, -16, -24, -25, -22, -23, -32, -41, -37, -22, -11, -8, 0, 21, 44, 54, 46, 34, 26, 18, 7, -11, -22, -21, -20, -21, -28, -40, -43, -30, -15, -10, -3, 16, 40, 56, 52, 37, 24, 16, 9, -6, -21, -22, -18, -17, -22, -35, -43, -34, -21, -14, -9, 7, 34, 53, 54, 40, 29, 21, 14, 4, -14, -21, -17, -17, -22, -33, -46, -45, -31, -16, -8, 4, 25, 50, 60, 49, 31, 20, 15, 9, -5, -17, -18, -15, -17, -26, -42, -50, -40, -24, -11, -2, 18, 43, 56, 52, 35, 21, 17, 11, 0, -12, -18, -14, -15, -22, -36, -50, -46, -30, -15, -3, 12, 35, 53, 55, 41, 24, 18, 12, 5, -4, -15, -18, -15, -20, -33, -46, -49, -37, -21, -7, 7, 25, 46, 54, 45, 27, 18, 14, 10, 3, -8, -15, -16, -18, -28, -41, -49, -44, -29, -12, 4, 17, 35, 49, 49, 34, 19, 16, 15, 9, 1, -10, -14, -16, -24, -38, -50, -49, -36, -18, -3, 10, 26, 43, 49, 38, 22, 18, 20, 16, 9, -5, -13, -16, -23, -36, -50, -53, -43, -25, -8, 6, 21, 38, 48, 44, 27, 19, 21, 19, 13, -2, -13, -17, -21, -30, -45, -52, -46, -29, -10, 3, 14, 29, 42, 44, 30, 17, 19, 21, 17, 6, -8, -14, -19, -26, -39, -49, -48, -36, -18, -2, 11, 27, 37, 42, 37, 22, 18, 21, 19, 9, -5, -13, -18, -24, -33, -45, -46, -39, -24, -8, 6, 20, 33, 40, 38, 27, 19, 22, 23, 17, 4, -8, -14, -22, -29, -43, -48, -43, -32, -16, -2, 13, 25, 34, 39, 33, 23, 21, 23, 20, 9, -4, -11, -19, -25, -33, -43, -42, -34, -20, -7, 3, 14, 24, 32, 31, 22, 20, 26, 28, 20, 6, -5, -11, -18, -28, -42, -44, -38, -28, -15, -5, 8, 19, 28, 31, 24, 21, 25, 27, 22, 10, 0, -6, -12, -22, -34, -38, -34, -30, -20, -11, 0, 11, 20, 26, 23, 19, 22, 27, 25, 17, 7, -2, -7, -17, -29, -35, -35, -34, -26, -16, -5, 7, 15, 23, 28, 24, 21, 22, 24, 20, 11, -2, -8, -14, -24, -29, -31, -31, -27, -18, -9, 0, 8, 15, 22, 23, 20, 21, 24, 24, 19, 7, -4, -10, -19, -26, -32, -34, -33, -24, -12, -2, 6, 14, 22, 26, 23, 22, 22, 22, 21, 10, 0, -6, -15, -21, -24, -28, -31, -28, -17, -7, 2, 7, 13, 19, 23, 23, 21, 19, 21, 18, 8, -2, -11, -17, -21, -24, -30, -33, -25, -11, 0, 4, 9, 16, 20, 21, 20, 18, 18, 20, 14, 4, -6, -12, -15, -17, -25, -32, -32, -20, -6, -3, -3, 7, 18, 23, 19, 16, 19, 26, 24, 11, 0, -6, -9, -15, -25, -33, -35, -26, -15, -9, -6, 5, 17, 22, 21, 17, 18, 25, 26, 16, 4, -5, -7, -9, -18, -29, -38, -35, -21, -11, -9, -4, 9, 22, 25, 20, 16, 22, 30, 24, 8, -4, -5, -5, -13, -25, -36, -38, -26, -16, -11, -10, 2, 19, 25, 18, 12, 19, 30, 28, 14, 1, -2, 3, -3, -17, -31, -36, -29, -21, -18, -19, -11, 7, 20, 16, 10, 16, 30, 36, 24, 8, 4, 8, 6, -12, -32, -40, -35, -26, -21, -20, -14, 2, 19, 20, 10, 12, 24, 35, 29, 13, 5, 7, 9, -3, -23, -37, -37, -31, -23, -21, -19, -8, 12, 19, 10, 6, 19, 36, 37, 23, 11, 12, 16, 7, -15, -35, -43, -38, -30, -27, -23, -16, 2, 18, 16, 7, 13, 30, 38, 29, 17, 12, 16, 15, -4, -27, -40, -39, -32, -28, -28, -24, -8, 12, 14, 5, 7, 26, 40, 36, 24, 18, 21, 21, 4, -20, -38, -41, -37, -34, -30, -26, -15, 4, 14, 7, 3, 18, 37, 41, 33, 24, 22, 25, 14, -10, -33, -44, -42, -36, -32, -29, -22, -6, 10, 9, 2, 9, 29, 40, 37, 32, 28, 29, 21, 0, -24, -39, -44, -44, -38, -31, -24, -16, 0, 7, 3, 8, 24, 38, 43, 41, 32, 28, 25, 9, -15, -34, -44, -44, -39, -31, -26, -20, -10, 3, 2, 1, 14, 32, 44, 46, 39, 33, 31, 20, -7, -31, -45, -47, -44, -38, -30, -26, -16, 0, 5, 4, 12, 30, 45, 52, 47, 36, 30, 22, 0, -24, -40, -50, -49, -42, -31, -24, -19, -10, -3, 3, 11, 24, 39, 51, 55, 49, 37, 27, 8, -18, -36, -50, -54, -47, -36, -29, -25, -16, -6, 4, 10, 18, 34, 52, 59, 53, 39, 28, 15, -8, -29, -45, -53, -51, -43, -34, -29, -23, -14, -4, 7, 17, 33, 52, 62, 61, 50, 37, 23, -4, -28, -44, -55, -55, -48, -38, -30, -25, -18, -8, 5, 13, 25, 46, 61, 65, 57, 43, 30, 8, -17, -36, -50, -55, -53, -47, -39, -32, -24, -15, -3, 11, 25, 45, 62, 68, 63, 51, 37, 14, -14, -34, -46, -56, -57, -51, -44, -33, -25, -18, -6, 8, 19, 36, 55, 67, 65, 53, 42, 23, -4, -26, -40, -50, -56, -54, -49, -41, -31, -23, -12, 1, 15, 34, 53, 65, 68, 59, 49, 33, 6, -21, -37, -47, -57, -60, -56, -48, -38, -28, -16, -2, 14, 33, 51, 64, 70, 63, 53, 38, 13, -14, -34, -44, -53, -59, -59, -53, -42, -30, -19, -8, 5, 26, 47, 61, 68, 64, 57, 48, 26, -3, -26, -39, -49, -58, -63, -59, -49, -37, -24, -13, 1, 20, 42, 55, 65, 69, 64, 54, 34, 7, -18, -34, -44, -55, -65, -64, -54, -42, -31, -19, -8, 12, 37, 54, 61, 67, 67, 60, 46, 22, -8, -29, -40, -50, -64, -70, -63, -50, -34, -21, -13, 2, 28, 51, 62, 68, 68, 61, 51, 32, 3, -23, -36, -47, -60, -70, -67, -58, -44, -27, -14, -2, 22, 45, 58, 65, 70, 68, 56, 38, 16, -11, -32, -45, -58, -69, -70, -62, -52, -34, -17, -6, 13, 38, 54, 64, 70, 67, 59, 47, 29, -2, -28, -40, -51, -65, -74, -67, -54, -37, -20, -11, 5, 33, 53, 59, 63, 67, 62, 51, 34, 7, -20, -35, -46, -59, -72, -70, -60, -46, -27, -12, 1, 24, 47, 60, 64, 69, 66, 54, 39, 15, -13, -32, -44, -54, -68, -71, -60, -48, -32, -18, -7, 14, 38, 54, 61, 68, 70, 60, 46, 26, -2, -23, -38, -50, -63, -72, -68, -55, -39, -24, -13, 5, 31, 52, 61, 67, 71, 64, 53, 34, 7, -21, -36, -46, -57, -69, -72, -60, -42, -27, -17, -2, 21, 45, 58, 65, 69, 66, 57, 42, 15, -13, -30, -43, -54, -66, -72, -65, -47, -30, -18, -5, 15, 40, 57, 64, 67, 62, 56, 46, 23, -6, -27, -39, -50, -58, -67, -67, -51, -32, -20, -9, 9, 31, 51, 60, 64, 64, 58, 48, 27, 1, -20, -34, -46, -56, -65, -70, -57, -37, -22, -14, 2, 26, 48, 62, 66, 64, 59, 51, 34, 8, -18, -31, -42, -52, -61, -70, -63, -42, -24, -15, -3, 19, 43, 60, 63, 60, 57, 52, 39, 14, -14, -28, -36, -46, -54, -65, -66, -49, -29, -17, -9, 10, 33, 54, 64, 62, 58, 53, 42, 23, -5, -25, -35, -46, -54, -63, -67, -54, -33, -17, -7, 7, 30, 51, 61, 58, 55, 51, 43, 28, 3, -21, -30, -37, -46, -56, -63, -56, -39, -22, -12, -5, 16, 40, 57, 58, 55, 53, 48, 38, 19, -10, -27, -35, -45, -56, -66, -65, -49, -28, -14, -6, 8, 34, 57, 60, 55, 54, 50, 42, 26, -4, -28, -35, -42, -52, -62, -63, -51, -32, -14, -5, 3, 24, 47, 57, 53, 50, 47, 41, 33, 11, -20, -35, -40, -46, -56, -65, -58, -38, -17, -4, 1, 15, 41, 57, 55, 47, 45, 42, 35, 17, -13, -33, -38, -41, -49, -58, -55, -41, -21, -4, 0, 7, 29, 50, 52, 45, 42, 40, 37, 25, 0, -28, -38, -38, -44, -53, -58, -46, -26, -6, 3, 4, 18, 42, 53, 47, 41, 39, 37, 30, 10, -21, -41, -43, -41, -47, -54, -46, -29, -8, 7, 9, 13, 31, 46, 45, 37, 33, 33, 28, 15, -10, -35, -42, -38, -39, -45, -46, -32, -10, 6, 9, 8, 19, 38, 44, 38, 30, 29, 30, 19, -3, -29, -42, -38, -34, -40, -43, -32, -14, 3, 11, 11, 15, 30, 41, 39, 30, 25, 25, 19, 4, -21, -40, -42, -32, -30, -33, -29, -15, 2, 11, 10, 8, 17, 30, 35, 30, 23, 24, 23, 11, -11, -32, -43, -34, -26, -29, -29, -18, -3, 9, 12, 9, 12, 26, 35, 32, 21, 18, 18, 12, -6, -29, -43, -36, -22, -22, -25, -15, 1, 10, 11, 10, 8, 17, 29, 29, 21, 16, 17, 15, 2, -21, -39, -39, -24, -17, -20, -16, -5, 9, 13, 10, 7, 12, 24, 28, 23, 14, 12, 11, 4, -14, -33, -39, -28, -15, -14, -12, -6, 5, 11, 9, 7, 7, 16, 26, 25, 16, 10, 11, 6, -8, -24, -37, -32, -17, -12, -11, -5, 5, 11, 11, 10, 7, 12, 21, 21, 16, 7, 4, 3, -6, -20, -32, -32, -20, -8, -5, 0, 5, 11, 11, 9, 8, 8, 13, 17, 16, 9, 3, 2, -3, -13, -25, -31, -23, -9, -4, -2, 5, 11, 14, 11, 7, 6, 12, 15, 12, 5, -2, -2, -3, -11, -22, -29, -24, -9, 0, 3, 8, 13, 13, 12, 8, 4, 5, 7, 9, 6, -3, -5, -4, -5, -14, -24, -23, -13, 0, 4, 6, 10, 14, 14, 9, 3, 3, 5, 6, 4, -4, -6, -5, -5, -9, -18, -20, -15, -4, 6, 9, 11, 13, 13, 10, 5, 1, 0, -3, 0, -4, -6, -6, -5, -4, -11, -16, -16, -9, 3, 8, 11, 11, 10, 11, 8, 3, -2, -5, -4, -3, -5, -6, -6, -2, -5, -12, -15, -13, -2, 8, 9, 11, 11, 11, 7, 4, 0, -6, -6, -4, -4, -6, -6, -2, 0, -7, -13, -15, -5, 8, 13, 12, 9, 11, 9, 4, -5, -11, -11, -8, -5, -5, -5, 0, 4, 3, -4, -11, -8, 3, 11, 12, 8, 7, 4, 2, -2, -10, -14, -13, -7, -3, -4, -2, 3, 4, 1, -8, -8, 3, 13, 17, 12, 11, 7, 1, -6, -16, -21, -19, -13, -7, -2, 3, 7, 10, 10, 1, -6, -2, 8, 14, 12, 10, 4, -2, -6, -15, -21, -20, -15, -8, -2, 3, 5, 9, 14, 5, -6, 1, 12, 18, 14, 9, 7, 2, -4, -18, -28, -27, -22, -12, -5, 3, 9, 13, 18, 16, 5, 1, 7, 14, 13, 8, 5, -5, -9, -17, -26, -26, -23, -15, -4, 5, 8, 11, 17, 17, 7, 2, 7, 16, 18, 10, 4, -2, -6, -16, -31, -33, -27, -18, -9, 0, 7, 12, 18, 22, 16, 9, 9, 16, 20, 13, 5, -2, -9, -18, -33, -37, -29, -22, -13, -4, 7, 15, 21, 25, 21, 15, 13, 17, 20, 14, 5, -3, -8, -18, -35, -42, -36, -24, -16, -6, 5, 13, 23, 27, 25, 20, 17, 19, 20, 15, 5, -3, -8, -21, -35, -45, -39, -25, -18, -11, 3, 16, 25, 29, 27, 26, 24, 23, 21, 17, 8, -4, -12, -23, -35, -46, -46, -34, -22, -15, -3, 13, 25, 31, 33, 34, 31, 28, 25, 20, 11, -4, -12, -22, -38, -49, -51, -39, -26, -21, -11, 8, 24, 34, 35, 36, 37, 35, 29, 21, 13, 0, -11, -20, -36, -48, -52, -46, -31, -22, -14, 1, 19, 34, 38, 39, 40, 38, 34, 24, 15, 0, -14, -21, -34, -47, -53, -50, -35, -22, -17, -5, 13, 31, 37, 38, 42, 41, 37, 28, 21, 9, -8, -19, -30, -44, -50, -53, -46, -32, -23, -11, 7, 26, 39, 43, 49, 48, 42, 32, 20, 9, -9, -21, -31, -46, -52, -54, -50, -35, -24, -13, 4, 23, 40, 46, 48, 49, 46, 37, 26, 13, -4, -20, -29, -42, -50, -53, -54, -43, -31, -21, -2, 17, 36, 47, 53, 56, 51, 42, 29, 17, 3, -16, -30, -41, -51, -55, -57, -51, -35, -24, -9, 11, 30, 47, 53, 57, 55, 46, 34, 20, 6, -12, -29, -43, -52, -55, -55, -55, -42, -29, -12, 8, 25, 41, 55, 62, 59, 51, 37, 23, 10, -6, -24, -40, -51, -56, -58, -58, -48, -33, -19, 2, 22, 41, 55, 61, 61, 56, 45, 28, 11, -3, -19, -37, -51, -57, -58, -58, -54, -39, -23, -2, 20, 36, 52, 64, 65, 58, 48, 33, 19, 4, -13, -35, -51, -58, -61, -62, -60, -47, -29, -7, 17, 34, 50, 67, 70, 62, 50, 35, 20, 6, -8, -29, -47, -57, -62, -61, -60, -54, -37, -15, 10, 29, 44, 60, 68, 66, 56, 42, 24, 12, 1, -19, -41, -55, -60, -62, -61, -57, -43, -21, 7, 24, 36, 53, 66, 67, 59, 46, 30, 15, 5, -11, -32, -48, -58, -63, -62, -59, -50, -32, -3, 22, 35, 49, 60, 66, 63, 53, 38, 19, 8, -5, -25, -43, -57, -64, -64, -62, -54, -39, -13, 16, 32, 46, 59, 65, 66, 56, 45, 26, 11, 3, -17, -39, -56, -65, -67, -62, -56, -44, -21, 10, 29, 40, 54, 63, 68, 61, 49, 33, 13, 2, -14, -34, -50, -64, -67, -63, -56, -44, -26, 2, 27, 38, 49, 57, 64, 61, 50, 36, 17, 6, -7, -27, -44, -60, -67, -63, -57, -48, -32, -7, 22, 36, 44, 53, 60, 62, 55, 41, 21, 7, -3, -20, -40, -58, -68, -65, -57, -47, -34, -14, 16, 37, 42, 47, 55, 59, 53, 42, 27, 10, -2, -14, -30, -47, -60, -63, -57, -49, -38, -20, 5, 30, 40, 44, 52, 57, 57, 46, 31, 13, -2, -12, -27, -44, -57, -64, -61, -50, -38, -20, 2, 25, 39, 41, 49, 55, 54, 45, 32, 17, 0, -12, -23, -37, -50, -59, -61, -52, -38, -22, -6, 17, 35, 39, 42, 48, 53, 48, 36, 22, 4, -9, -18, -30, -45, -56, -59, -54, -42, -27, -10, 12, 29, 37, 38, 44, 50, 47, 37, 25, 9, -5, -13, -23, -38, -50, -55, -54, -45, -32, -17, 5, 25, 34, 35, 39, 46, 48, 40, 29, 13, -3, -11, -21, -33, -44, -51, -54, -47, -34, -17, 2, 21, 32, 34, 34, 38, 42, 39, 27, 15, 1, -7, -13, -25, -36, -45, -49, -46, -36, -23, -6, 15, 27, 31, 31, 34, 39, 38, 30, 18, 3, -6, -10, -19, -32, -40, -46, -45, -36, -24, -11, 8, 24, 29, 27, 29, 34, 36, 30, 18, 4, -5, -5, -12, -25, -34, -39, -41, -37, -24, -11, 4, 18, 24, 25, 25, 29, 29, 26, 19, 5, -6, -6, -6, -18, -28, -33, -37, -34, -24, -11, 2, 15, 24, 23, 20, 24, 27, 22, 14, 4, -4, -4, -5, -15, -24, -26, -29, -32, -27, -13, 2, 14, 21, 21, 18, 21, 23, 20, 13, 5, -3, -5, -4, -9, -16, -21, -25, -28, -25, -14, 1, 10, 16, 19, 16, 16, 18, 16, 11, 5, -2, -5, -4, -6, -12, -17, -20, -22, -22, -17, -4, 8, 13, 16, 15, 13, 15, 14, 10, 4, -4, -6, -6, -5, -7, -11, -15, -17, -17, -15, -3, 10, 13, 14, 11, 7, 8, 9, 5, -3, -8, -7, -4, -2, -2, -6, -10, -9, -10, -12, -5, 11, 15, 13, 11, 5, 6, 7, 3, -6, -10, -8, -6, -6, -2, 1, -2, -6, -6, -7, -5, 8, 14, 10, 7, 4, 0, 1, -2, -6, -12, -11, -6, -2, 4, 8, 4, -2, -2, -4, -5, 3, 12, 8, 5, 4, 0, 0, -2, -8, -13, -15, -12, -7, -3, 6, 10, 7, 5, 6, 4, 6, 14, 10, 3, 0, -6, -10, -7, -10, -16, -19, -15, -8, 0, 11, 17, 13, 10, 11, 7, 5, 8, 9, 2, -4, -7, -12, -10, -10, -16, -21, -19, -13, -4, 10, 21, 22, 17, 17, 14, 9, 9, 9, 3, -7, -12, -17, -16, -14, -20, -25, -21, -15, -5, 10, 23, 27, 25, 22, 18, 11, 8, 4, -2, -9, -14, -18, -19, -14, -15, -23, -25, -20, -10, 9, 22, 29, 29, 26, 23, 16, 12, 6, 1, -6, -14, -18, -22, -20, -19, -27, -28, -25, -18, 0, 19, 32, 36, 33, 31, 23, 14, 7, 1, -4, -15, -23, -25, -24, -19, -25, -32, -29, -20, -3, 16, 31, 40, 38, 36, 29, 16, 9, 1, -4, -12, -23, -26, -28, -24, -26, -34, -33, -24, -8, 12, 29, 41, 44, 44, 37, 22, 11, 4, -4, -11, -24, -31, -32, -31, -30, -36, -39, -30, -11, 11, 29, 43, 51, 50, 44, 32, 15, 4, -4, -11, -24, -32, -33, -33, -34, -38, -42, -35, -17, 4, 24, 42, 56, 60, 52, 38, 19, 7, 1, -13, -28, -37, -37, -35, -37, -39, -43, -37, -19, 3, 22, 41, 57, 64, 57, 44, 26, 7, -2, -11, -24, -35, -41, -40, -38, -39, -43, -40, -24, 0, 20, 37, 55, 65, 63, 50, 32, 9, -4, -10, -24, -36, -42, -42, -41, -41, -41, -39, -26, -2, 19, 34, 51, 64, 66, 55, 38, 15, -3, -8, -20, -34, -42, -44, -43, -44, -45, -45, -35, -12, 14, 31, 50, 66, 73, 65, 49, 28, 7, -6, -18, -35, -45, -49, -51, -53, -51, -47, -37, -16, 10, 30, 49, 69, 78, 72, 56, 35, 14, -4, -17, -33, -46, -51, -55, -56, -54, -51, -40, -20, 5, 26, 44, 64, 76, 77, 64, 41, 19, 1, -14, -30, -43, -50, -57, -60, -58, -54, -43, -24, -2, 21, 39, 61, 76, 79, 72, 52, 28, 9, -10, -26, -41, -49, -54, -61, -62, -59, -51, -33, -10, 14, 34, 55, 75, 81, 79, 63, 39, 19, -2, -23, -40, -51, -56, -64, -67, -64, -56, -39, -16, 9, 29, 51, 73, 83, 82, 73, 50, 27, 9, -18, -40, -52, -56, -63, -69, -69, -61, -43, -20, 2, 21, 42, 66, 81, 82, 76, 59, 36, 19, -6, -33, -50, -57, -61, -71, -76, -68, -52, -28, -2, 17, 36, 62, 83, 86, 82, 69, 43, 22, 2, -28, -51, -60, -63, -67, -76, -74, -57, -34, -7, 14, 29, 53, 76, 87, 84, 75, 54, 33, 14, -18, -46, -58, -62, -69, -80, -84, -68, -44, -18, 7, 26, 49, 75, 91, 92, 82, 64, 42, 21, -8, -43, -63, -68, -68, -75, -86, -76, -48, -22, 4, 23, 41, 66, 87, 92, 83, 69, 51, 31, 6, -31, -59, -67, -69, -74, -88, -87, -62, -34, -7, 17, 36, 62, 87, 96, 90, 76, 60, 39, 14, -23, -58, -70, -71, -73, -83, -89, -68, -37, -13, 9, 26, 51, 79, 94, 91, 80, 68, 52, 28, -8, -48, -67, -70, -73, -84, -96, -83, -49, -22, 0, 20, 44, 75, 96, 98, 88, 75, 61, 40, 6, -39, -67, -72, -75, -83, -95, -91, -60, -29, -7, 13, 36, 66, 89, 97, 92, 78, 65, 50, 22, -21, -58, -71, -73, -78, -91, -98, -79, -45, -15, 4, 25, 56, 84, 101, 99, 86, 73, 60, 35, -9, -53, -72, -77, -80, -90, -98, -85, -51, -20, -2, 18, 48, 77, 96, 99, 87, 75, 62, 46, 9, -39, -68, -75, -75, -83, -95, -94, -67, -30, -7, 8, 34, 68, 92, 102, 93, 82, 72, 58, 26, -24, -61, -75, -78, -85, -97, -99, -78, -42, -12, 6, 28, 59, 87, 102, 99, 86, 74, 62, 38, -7, -52, -76, -81, -83, -93, -100, -90, -57, -23, -2, 18, 48, 80, 102, 103, 92, 81, 71, 51, 9, -41, -72, -83, -85, -93, -100, -92, -65, -32, -7, 13, 39, 72, 97, 103, 95, 85, 73, 55, 25, -21, -61, -79, -83, -90, -99, -97, -77, -45, -17, 1, 24, 59, 93, 107, 103, 92, 85, 72, 42, -6, -54, -80, -86, -91, -104, -105, -87, -56, -23, 0, 18, 48, 85, 106, 106, 96, 87, 77, 52, 13, -35, -71, -84, -88, -98, -106, -96, -70, -40, -14, 6, 31, 70, 103, 111, 103, 95, 88, 68, 29, -19, -61, -84, -91, -99, -106, -101, -80, -51, -22, 2, 23, 56, 91, 109, 108, 98, 89, 76, 45, 1, -44, -76, -87, -92, -102, -104, -90, -64, -34, -11, 8, 37, 78, 108, 113, 106, 96, 85, 61, 19, -29, -68, -88, -94, -102, -104, -93, -73, -46, -21, 2, 28, 63, 98, 113, 109, 100, 89, 70, 33, -14, -55, -81, -91, -98, -104, -98, -79, -54, -30, -9, 18, 52, 89, 108, 110, 104, 96, 79, 46, 2, -40, -71, -90, -100, -104, -100, -86, -67, -44, -19, 7, 40, 77, 105, 115, 109, 99, 86, 58, 17, -29, -63, -86, -97, -101, -101, -92, -74, -50, -26, -4, 28, 66, 98, 114, 113, 102, 90, 68, 33, -15, -53, -76, -93, -101, -104, -96, -79, -57, -34, -15, 15, 56, 90, 110, 115, 105, 93, 75, 44, 0, -43, -68, -86, -98, -101, -98, -83, -65, -42, -22, 4, 41, 79, 104, 113, 107, 96, 81, 57, 16, -31, -59, -79, -95, -101, -100, -90, -71, -49, -30, -9, 28, 67, 97, 110, 107, 97, 86, 65, 30, -14, -47, -67, -84, -98, -102, -96, -79, -59, -41, -22, 14, 53, 90, 110, 111, 101, 90, 75, 45, 2, -39, -64, -79, -93, -102, -101, -87, -64, -44, -28, 0, 39, 81, 108, 110, 102, 93, 82, 58, 18, -25, -54, -70, -85, -101, -103, -94, -72, -53, -39, -14, 25, 70, 104, 112, 103, 96, 88, 70, 34, -13, -48, -65, -78, -97, -108, -101, -79, -55, -42, -24, 11, 56, 96, 111, 103, 94, 90, 77, 46, 5, -34, -56, -71, -92, -109, -109, -91, -64, -46, -30, 0, 44, 89, 112, 108, 95, 88, 80, 57, 16, -27, -54, -66, -82, -104, -112, -100, -71, -46, -34, -13, 29, 80, 111, 112, 97, 86, 84, 69, 32, -15, -48, -61, -72, -94, -109, -106, -82, -54, -37, -23, 11, 61, 101, 113, 101, 85, 80, 75, 48, 4, -37, -56, -64, -84, -107, -112, -90, -60, -37, -29, -7, 43, 91, 111, 103, 86, 80, 77, 58, 20, -24, -52, -61, -75, -100, -111, -99, -72, -44, -27, -12, 29, 77, 105, 106, 91, 80, 75, 64, 33, -9, -43, -58, -69, -94, -111, -104, -78, -49, -28, -18, 11, 62, 97, 107, 94, 80, 75, 69, 47, 6, -36, -55, -62, -81, -105, -108, -87, -59, -33, -18, 1, 46, 86, 103, 97, 83, 75, 69, 52, 19, -23, -50, -59, -74, -97, -106, -91, -64, -38, -21, -9, 26, 70, 95, 95, 80, 71, 69, 60, 35, -6, -40, -53, -64, -87, -102, -96, -72, -45, -25, -14, 13, 56, 87, 95, 86, 75, 69, 60, 41, 6, -32, -54, -62, -77, -95, -99, -79, -51, -23, -8, 6, 39, 75, 92, 87, 72, 64, 62, 49, 21, -17, -47, -57, -67, -86, -97, -87, -59, -32, -16, -4, 25, 63, 89, 92, 78, 67, 63, 53, 27, -10, -40, -55, -63, -78, -93, -89, -65, -36, -17, -7, 11, 44, 77, 89, 79, 65, 61, 58, 41, 8, -26, -50, -59, -67, -83, -90, -76, -47, -25, -13, 3, 30, 63, 85, 82, 70, 63, 58, 45, 14, -18, -43, -56, -63, -74, -84, -78, -52, -26, -13, -2, 19, 46, 73, 81, 68, 57, 55, 49, 27, -5, -32, -48, -54, -63, -77, -80, -60, -34, -17, -5, 10, 34, 62, 79, 71, 57, 52, 48, 31, 2, -26, -45, -50, -53, -65, -75, -63, -37, -16, -6, 4, 19, 45, 68, 70, 57, 49, 49, 39, 16, -11, -33, -45, -49, -56, -70, -71, -51, -26, -8, 2, 13, 35, 63, 76, 63, 48, 43, 38, 23, -7, -32, -45, -47, -47, -58, -67, -55, -30, -8, 0, 4, 20, 46, 68, 65, 47, 38, 38, 31, 8, -19, -37, -44, -42, -48, -63, -62, -41, -16, -2, 5, 16, 37, 61, 68, 53, 38, 34, 31, 14, -14, -33, -40, -38, -41, -54, -60, -46, -20, -5, -3, 6, 25, 49, 63, 55, 38, 32, 33, 24, 1, -23, -34, -35, -36, -45, -59, -55, -30, -9, -3, 2, 16, 39, 59, 59, 44, 32, 30, 26, 7, -20, -33, -33, -32, -40, -53, -54, -35, -12, -3, -2, 10, 29, 48, 55, 45, 32, 28, 27, 14, -10, -27, -30, -28, -34, -46, -53, -41, -17, -5, -5, 5, 24, 44, 54, 46, 32, 25, 25, 18, -4, -25, -31, -24, -27, -39, -47, -42, -21, -4, -2, 1, 15, 35, 46, 44, 31, 22, 23, 20, 6, -15, -26, -23, -20, -29, -41, -42, -29, -11, -4, -4, 7, 26, 42, 47, 37, 25, 21, 19, 9, -10, -25, -25, -18, -24, -38, -40, -29, -11, 1, 0, 3, 19, 34, 42, 33, 19, 14, 15, 10, -5, -21, -24, -15, -13, -26, -35, -31, -17, -2, 0, -2, 11, 26, 37, 34, 20, 14, 13, 12, 2, -17, -25, -17, -12, -21, -31, -30, -19, -4, 4, 1, 9, 22, 32, 32, 19, 9, 9, 10, 4, -11, -21, -16, -9, -14, -23, -26, -20, -8, 0, -2, 3, 15, 26, 31, 24, 12, 9, 10, 6, -5, -17, -19, -12, -11, -18, -25, -22, -10, 1, 2, 2, 11, 22, 29, 24, 10, 3, 5, 4, -4, -13, -15, -8, -5, -10, -16, -18, -14, -5, -2, 0, 6, 13, 20, 23, 16, 6, 5, 5, 0, -7, -12, -12, -8, -7, -12, -19, -18, -7, 0, 2, 7, 13, 18, 20, 13, 3, -2, 1, -2, -6, -8, -6, -3, -2, -2, -10, -14, -10, -6, -4, 0, 4, 9, 14, 15, 6, -2, -2, -2, -4, -4, -5, -3, 2, 3, -3, -10, -9, -5, 0, 0, 0, 3, 8, 10, 3, -5, -7, -6, -4, 0, -2, -2, 3, 7, 7, 2, -5, -6, -3, 2, 2, 0, 0, 2, 2, -4, -9, -9, -7, -3, 2, 4, 8, 9, 6, 2, -3, -4, -3, -2, -2, -2, 0, 1, -3, -8, -11, -8, -6, -4, 2, 6, 9, 10, 9, 8, 5, -4, -7, -3, 1, 1, -6, -7, -6, -6, -11, -14, -10, -5, 3, 9, 12, 14, 13, 10, 9, 1, -6, -5, -4, -3, -4, -6, -8, -12, -12, -13, -13, -11, -3, 9, 16, 18, 15, 13, 14, 11, -2, -6, -4, -3, -5, -11, -13, -12, -14, -15, -14, -10, -4, 6, 15, 22, 21, 16, 13, 12, 3, -7, -8, -7, -7, -10, -14, -17, -16, -13, -12, -10, -7, 3, 15, 24, 26, 19, 16, 18, 12, -3, -9, -10, -9, -11, -18, -22, -21, -17, -14, -14, -10, 0, 14, 26, 32, 28, 23, 22, 21, 5, -9, -12, -16, -18, -22, -27, -27, -23, -17, -13, -8, 2, 12, 25, 35, 36, 29, 21, 20, 11, -6, -14, -17, -19, -22, -27, -28, -24, -20, -15, -11, -4, 7, 19, 32, 39, 35, 28, 25, 19, 4, -10, -17, -24, -28, -31, -33, -30, -26, -19, -11, -3, 8, 19, 31, 42, 42, 34, 27, 21, 9, -9, -19, -26, -31, -35, -34, -30, -26, -23, -13, -4, 4, 14, 25, 42, 49, 41, 31, 27, 20, 3, -15, -28, -37, -38, -39, -38, -35, -29, -16, 0, 9, 17, 26, 41, 52, 48, 36, 26, 19, 6, -16, -30, -39, -43, -41, -39, -33, -29, -22, -5, 7, 13, 21, 36, 55, 56, 46, 34, 24, 15, -8, -29, -44, -54, -50, -44, -39, -35, -27, -7, 11, 20, 25, 34, 54, 63, 53, 38, 22, 14, 0, -27, -45, -56, -56, -46, -39, -36, -31, -14, 8, 19, 23, 29, 46, 63, 61, 47, 30, 20, 8, -15, -39, -56, -62, -54, -44, -41, -38, -23, -2, 16, 23, 28, 42, 63, 69, 58, 41, 25, 13, -7, -34, -56, -68, -64, -50, -45, -43, -29, -7, 15, 26, 29, 40, 58, 72, 67, 48, 30, 16, 0, -26, -53, -68, -69, -57, -47, -46, -36, -16, 9, 25, 30, 38, 53, 71, 74, 58, 37, 17, 2, -21, -49, -70, -76, -64, -49, -43, -38, -21, 3, 25, 33, 37, 49, 65, 74, 65, 45, 24, 8, -11, -40, -68, -79, -72, -57, -48, -42, -29, -6, 20, 34, 39, 48, 63, 77, 74, 56, 31, 11, -8, -33, -61, -79, -80, -68, -53, -45, -34, -16, 11, 31, 41, 51, 61, 75, 78, 64, 42, 19, -3, -27, -55, -78, -84, -73, -59, -48, -37, -20, 5, 27, 40, 49, 58, 71, 80, 71, 49, 23, 2, -20, -47, -72, -86, -82, -66, -52, -39, -26, -5, 20, 39, 51, 59, 69, 79, 77, 61, 34, 7, -16, -42, -68, -88, -90, -75, -58, -41, -26, -8, 17, 39, 52, 59, 65, 74, 77, 65, 41, 12, -12, -35, -60, -81, -89, -79, -60, -45, -33, -17, 6, 31, 49, 59, 64, 73, 80, 74, 51, 22, -5, -29, -54, -78, -92, -90, -70, -49, -35, -18, 3, 26, 48, 60, 64, 68, 75, 75, 58, 31, 1, -25, -48, -73, -88, -90, -77, -56, -41, -23, -3, 21, 43, 58, 64, 70, 75, 77, 64, 40, 12, -18, -44, -70, -87, -94, -87, -64, -42, -22, -4, 16, 39, 58, 65, 66, 67, 74, 68, 46, 18, -12, -38, -62, -82, -92, -89, -67, -45, -28, -9, 13, 31, 52, 64, 67, 66, 72, 71, 53, 29, -3, -34, -59, -79, -94, -96, -77, -50, -29, -8, 12, 30, 49, 63, 68, 67, 68, 70, 56, 34, 6, -29, -57, -77, -92, -99, -84, -56, -32, -10, 11, 29, 45, 61, 69, 69, 68, 70, 60, 37, 12, -20, -50, -73, -90, -100, -91, -64, -37, -14, 7, 25, 42, 57, 66, 67, 65, 67, 64, 45, 21, -9, -41, -66, -84, -98, -95, -74, -47, -21, 3, 23, 39, 54, 64, 69, 69, 67, 63, 50, 27, 0, -33, -63, -83, -94, -95, -79, -54, -26, -2, 18, 35, 49, 61, 67, 67, 65, 64, 55, 33, 6, -25, -55, -82, -95, -98, -84, -60, -32, -6, 17, 36, 48, 56, 64, 66, 65, 62, 55, 39, 14, -16, -46, -76, -92, -96, -88, -69, -41, -9, 15, 33, 46, 54, 62, 68, 66, 59, 54, 44, 20, -12, -41, -72, -92, -97, -90, -71, -46, -14, 15, 34, 48, 55, 59, 62, 63, 60, 51, 42, 24, -6, -34, -63, -87, -95, -89, -75, -52, -23, 10, 31, 45, 54, 58, 62, 66, 63, 51, 42, 30, 1, -32, -59, -84, -96, -93, -80, -58, -28, 7, 32, 45, 53, 60, 64, 67, 62, 52, 41, 31, 9, -25, -55, -78, -92, -91, -82, -65, -39, -2, 30, 43, 49, 56, 61, 65, 63, 54, 44, 33, 16, -15, -47, -72, -88, -91, -84, -70, -45, -12, 22, 42, 48, 54, 58, 61, 63, 56, 43, 32, 20, -4, -36, -65, -82, -87, -82, -72, -53, -23, 15, 40, 46, 48, 55, 61, 62, 55, 43, 32, 21, 4, -26, -57, -75, -82, -80, -73, -58, -30, 5, 35, 46, 47, 51, 57, 61, 57, 46, 34, 22, 9, -15, -47, -71, -81, -80, -75, -62, -36, -4, 28, 46, 47, 49, 56, 60, 57, 48, 35, 23, 12, -9, -39, -67, -78, -76, -71, -65, -45, -13, 21, 45, 50, 46, 50, 58, 59, 49, 35, 23, 12, -4, -31, -62, -78, -74, -70, -65, -49, -18, 18, 43, 51, 45, 48, 56, 56, 45, 30, 20, 12, 0, -24, -53, -71, -69, -63, -60, -51, -25, 9, 36, 50, 47, 44, 50, 52, 45, 32, 21, 12, 1, -18, -44, -66, -70, -64, -59, -51, -31, 2, 32, 50, 51, 46, 47, 52, 47, 32, 17, 9, 0, -14, -34, -57, -67, -62, -56, -50, -33, -6, 24, 44, 51, 48, 47, 48, 46, 34, 21, 12, 2, -13, -32, -51, -62, -62, -56, -51, -38, -13, 18, 40, 51, 50, 45, 47, 46, 36, 20, 9, -2, -14, -28, -45, -59, -61, -54, -48, -37, -15, 14, 36, 49, 52, 48, 44, 42, 33, 19, 10, 0, -13, -26, -39, -52, -58, -54, -47, -37, -19, 9, 30, 44, 52, 48, 40, 38, 31, 19, 7, -3, -12, -22, -31, -42, -51, -49, -43, -36, -22, 1, 22, 35, 45, 47, 41, 37, 31, 23, 13, 3, -11, -22, -28, -36, -48, -53, -46, -35, -23, -4, 17, 31, 45, 49, 41, 33, 29, 23, 13, 2, -11, -22, -26, -29, -38, -46, -45, -34, -21, -6, 14, 25, 38, 46, 43, 35, 27, 19, 10, 3, -7, -20, -28, -28, -32, -38, -41, -35, -23, -8, 10, 23, 33, 44, 44, 36, 27, 18, 10, 0, -9, -22, -28, -28, -28, -33, -37, -32, -21, -7, 8, 20, 28, 38, 41, 36, 27, 17, 8, -2, -6, -17, -28, -31, -28, -27, -30, -30, -22, -7, 9, 19, 26, 35, 41, 37, 26, 16, 6, -5, -11, -18, -28, -31, -28, -22, -23, -23, -18, -4, 11, 19, 24, 27, 33, 33, 24, 14, 3, -8, -11, -15, -23, -29, -29, -21, -18, -19, -15, -5, 9, 16, 21, 26, 30, 32, 25, 13, 2, -9, -13, -16, -21, -27, -27, -20, -12, -13, -14, -7, 9, 17, 20, 24, 25, 26, 27, 15, 2, -9, -17, -17, -20, -25, -28, -23, -11, -6, -8, -5, 7, 19, 23, 24, 24, 24, 25, 16, 0, -13, -22, -22, -22, -26, -28, -22, -8, 2, 1, 0, 8, 18, 24, 24, 20, 18, 20, 15, 1, -12, -22, -24, -22, -23, -25, -22, -13, 2, 7, 3, 8, 16, 25, 28, 21, 15, 15, 15, 4, -13, -25, -29, -24, -20, -24, -21, -12, 1, 12, 10, 9, 16, 23, 27, 21, 14, 12, 10, 3, -10, -21, -28, -27, -22, -22, -20, -14, -4, 10, 14, 11, 17, 23, 29, 26, 15, 11, 10, 4, -12, -25, -33, -33, -26, -23, -22, -12, 0, 13, 22, 19, 20, 25, 29, 25, 12, 5, 3, 0, -12, -25, -32, -34, -27, -21, -20, -11, -2, 7, 18, 21, 22, 26, 30, 29, 21, 11, 4, -5, -14, -29, -38, -38, -33, -27, -23, -10, 4, 12, 22, 29, 30, 30, 31, 30, 21, 10, 0, -11, -19, -30, -39, -40, -36, -28, -20, -9, 4, 12, 20, 29, 32, 30, 32, 32, 23, 12, 3, -8, -18, -27, -39, -44, -40, -32, -25, -15, 1, 13, 22, 30, 37, 38, 36, 34, 26, 14, 2, -11, -22, -31, -40, -45, -42, -35, -26, -14, 0, 12, 19, 26, 35, 39, 36, 33, 28, 18, 6, -7, -18, -28, -37, -43, -43, -37, -30, -19, -6, 8, 20, 25, 34, 42, 41, 37, 32, 22, 8, -7, -19, -32, -40, -44, -44, -38, -30, -20, -6, 8, 19, 24, 30, 40, 41, 36, 29, 23, 13, -3, -16, -28, -39, -43, -44, -41, -34, -23, -11, 2, 16, 25, 32, 41, 46, 42, 34, 26, 15, 0, -16, -29, -40, -45, -45, -40, -32, -24, -12, -2, 12, 22, 26, 37, 45, 44, 34, 24, 18, 6, -12, -24, -37, -41, -40, -40, -36, -30, -17, -4, 9, 18, 25, 37, 45, 45, 40, 29, 19, 8, -8, -22, -38, -43, -42, -42, -35, -28, -17, -4, 7, 17, 23, 33, 43, 43, 38, 28, 19, 12, -3, -19, -34, -40, -38, -40, -38, -31, -22, -8, 5, 14, 21, 31, 44, 47, 41, 31, 20, 13, 3, -15, -33, -45, -45, -41, -38, -31, -24, -10, 4, 15, 21, 29, 42, 47, 41, 33, 22, 13, 4, -13, -29, -40, -41, -41, -41, -36, -26, -14, -2, 8, 17, 29, 42, 50, 46, 37, 27, 17, 7, -9, -27, -41, -48, -45, -42, -38, -29, -15, -2, 10, 18, 26, 38, 50, 51, 40, 28, 17, 6, -7, -24, -36, -43, -45, -41, -38, -31, -18, -8, 2, 13, 26, 38, 44, 49, 42, 33, 22, 8, -4, -20, -32, -41, -46, -44, -37, -32, -21, -8, 2, 14, 25, 35, 42, 47, 44, 31, 19, 7, -4, -15, -28, -36, -42, -40, -34, -31, -24, -9, 0, 7, 18, 30, 40, 44, 42, 32, 22, 12, 2, -10, -23, -31, -38, -42, -38, -31, -26, -13, -3, 2, 14, 29, 40, 41, 40, 36, 26, 13, 1, -10, -19, -26, -35, -43, -41, -33, -27, -17, -6, 1, 12, 27, 43, 47, 42, 37, 29, 14, 0, -10, -21, -29, -34, -40, -42, -33, -26, -18, -5, 3, 10, 23, 39, 45, 39, 33, 30, 18, 3, -8, -15, -22, -29, -37, -43, -36, -27, -22, -13, -4, 6, 19, 36, 47, 47, 37, 33, 25, 6, -8, -15, -25, -31, -36, -43, -42, -32, -21, -11, 0, 5, 15, 32, 46, 45, 35, 31, 28, 12, -6, -13, -20, -24, -31, -41, -46, -38, -26, -18, -9, 1, 14, 31, 43, 48, 42, 33, 28, 15, -5, -15, -18, -24, -31, -38, -41, -34, -26, -19, -8, 1, 10, 23, 37, 43, 41, 32, 26, 19, 3, -12, -15, -18, -24, -34, -42, -38, -28, -20, -13, -4, 6, 21, 37, 44, 43, 36, 28, 21, 8, -9, -16, -19, -25, -34, -42, -39, -29, -21, -13, -3, 8, 19, 34, 42, 41, 36, 28, 20, 8, -7, -15, -16, -19, -30, -41, -42, -31, -23, -15, -8, 3, 19, 36, 43, 39, 36, 30, 23, 13, -6, -19, -21, -20, -26, -38, -43, -35, -25, -15, -7, 3, 14, 30, 42, 40, 35, 28, 23, 16, 0, -14, -20, -19, -22, -34, -42, -37, -26, -15, -8, 0, 12, 27, 40, 41, 35, 29, 22, 16, 4, -9, -19, -20, -20, -29, -39, -39, -30, -19, -10, -3, 10, 24, 37, 42, 37, 31, 25, 18, 7, -7, -17, -21, -20, -28, -38, -40, -33, -22, -11, -5, 9, 25, 37, 44, 40, 32, 24, 17, 10, -5, -18, -24, -23, -28, -35, -38, -35, -26, -14, -5, 5, 19, 34, 44, 42, 33, 23, 18, 13, 0, -15, -20, -22, -26, -33, -39, -35, -28, -18, -10, 1, 18, 33, 43, 45, 38, 28, 20, 11, 2, -12, -22, -24, -28, -31, -36, -35, -29, -21, -11, 0, 15, 30, 40, 44, 39, 31, 21, 13, 8, -5, -17, -20, -25, -28, -32, -36, -34, -27, -18, -7, 9, 26, 39, 46, 45, 36, 25, 14, 10, -2, -16, -24, -29, -31, -31, -36, -36, -27, -16, -7, 6, 23, 37, 45, 44, 36, 26, 14, 8, 1, -14, -22, -23, -29, -32, -35, -36, -29, -21, -14, 0, 16, 35, 46, 45, 39, 33, 20, 8, 3, -9, -21, -28, -32, -34, -35, -36, -32, -25, -15, 1, 17, 32, 45, 49, 44, 35, 23, 7, 0, -7, -17, -25, -30, -31, -32, -34, -31, -25, -18, -7, 10, 27, 43, 50, 45, 35, 24, 13, 3, -7, -17, -24, -28, -30, -30, -33, -34, -26, -19, -11, 5, 22, 39, 50, 48, 37, 26, 16, 5, -7, -18, -23, -27, -28, -28, -33, -34, -24, -16, -11, 2, 17, 33, 48, 48, 37, 27, 18, 7, -5, -14, -20, -25, -30, -31, -32, -37, -31, -20, -15, -3, 15, 30, 46, 53, 43, 31, 20, 11, 0, -12, -21, -27, -31, -30, -30, -36, -33, -20, -10, -5, 9, 25, 41, 52, 46, 34, 23, 15, 6, -9, -21, -27, -30, -31, -31, -37, -39, -25, -12, -7, 1, 18, 36, 52, 53, 40, 28, 22, 13, -2, -18, -29, -32, -35, -34, -39, -40, -28, -13, -7, -2, 12, 33, 50, 56, 44, 30, 24, 18, 4, -15, -29, -32, -33, -33, -35, -40, -35, -20, -7, -2, 8, 25, 43, 54, 49, 35, 25, 18, 8, -7, -23, -32, -32, -34, -34, -37, -36, -24, -11, -5, 2, 18, 36, 51, 51, 39, 30, 24, 14, 0, -19, -32, -35, -35, -37, -38, -39, -29, -12, -2, 3, 14, 29, 47, 54, 45, 33, 26, 17, 5, -12, -31, -37, -36, -38, -38, -38, -32, -17, -3, 3, 9, 25, 42, 53, 49, 39, 31, 23, 10, -9, -27, -38, -40, -41, -41, -41, -36, -23, -5, 5, 8, 18, 36, 51, 51, 43, 34, 26, 16, 1, -20, -36, -40, -41, -42, -40, -38, -28, -10, 4, 7, 14, 30, 48, 51, 45, 39, 31, 21, 4, -16, -33, -41, -43, -43, -39, -38, -32, -15, 1, 7, 13, 25, 42, 52, 48, 39, 31, 22, 9, -10, -29, -40, -40, -40, -38, -35, -34, -20, -2, 5, 9, 17, 33, 49, 50, 43, 34, 25, 13, -4, -21, -36, -44, -44, -40, -35, -34, -26, -8, 5, 11, 17, 26, 43, 51, 46, 36, 27, 16, 1, -16, -31, -42, -46, -43, -37, -35, -29, -12, 3, 11, 17, 23, 37, 50, 52, 41, 29, 20, 4, -15, -30, -43, -49, -46, -39, -37, -33, -15, 3, 13, 19, 23, 35, 52, 55, 44, 29, 20, 8, -12, -28, -40, -48, -45, -39, -35, -32, -20, -2, 12, 16, 19, 28, 45, 55, 49, 35, 24, 14, -3, -20, -36, -49, -53, -45, -38, -35, -27, -9, 8, 19, 23, 26, 40, 55, 55, 41, 25, 15, -2, -19, -33, -46, -53, -47, -39, -35, -29, -14, 6, 19, 24, 25, 35, 53, 59, 47, 29, 17, 7, -12, -30, -47, -58, -56, -47, -39, -35, -22, -2, 17, 28, 30, 34, 50, 63, 56, 35, 19, 8, -9, -26, -43, -56, -58, -49, -42, -38, -27, -9, 12, 26, 33, 34, 44, 60, 62, 44, 23, 9, -4, -20, -40, -56, -63, -56, -44, -39, -30, -14, 8, 26, 35, 35, 43, 60, 64, 50, 28, 13, 2, -16, -37, -53, -62, -61, -50, -42, -32, -17, 2, 18, 32, 40, 44, 54, 63, 55, 37, 17, 4, -10, -31, -48, -61, -67, -59, -45, -36, -24, -5, 17, 33, 43, 47, 54, 64, 59, 42, 20, 3, -10, -28, -49, -63, -68, -63, -50, -37, -25, -7, 13, 31, 44, 48, 54, 61, 59, 48, 27, 6, -10, -24, -43, -59, -67, -67, -56, -39, -28, -13, 8, 24, 42, 51, 54, 58, 58, 52, 37, 14, -6, -20, -38, -54, -65, -70, -63, -45, -29, -17, 2, 18, 37, 52, 56, 58, 56, 51, 42, 23, -2, -19, -34, -50, -62, -70, -69, -52, -30, -17, -3, 15, 33, 50, 58, 58, 56, 52, 46, 29, 3, -15, -31, -45, -58, -68, -71, -60, -38, -20, -5, 11, 25, 42, 58, 62, 58, 51, 44, 36, 15, -10, -29, -43, -53, -64, -72, -67, -45, -21, -8, 4, 20, 40, 60, 65, 57, 53, 48, 42, 21, -8, -27, -40, -50, -62, -71, -71, -54, -29, -9, 3, 18, 34, 54, 68, 65, 57, 48, 40, 28, 2, -23, -41, -52, -60, -71, -75, -60, -34, -12, 0, 13, 31, 52, 69, 66, 56, 50, 44, 33, 7, -21, -38, -47, -55, -65, -75, -67, -41, -15, 2, 11, 23, 41, 61, 68, 59, 49, 40, 34, 17, -11, -35, -47, -48, -55, -69, -72, -50, -21, 0, 8, 15, 33, 56, 69, 62, 52, 44, 40, 26, -4, -30, -44, -48, -56, -69, -77, -59, -28, -7, 7, 15, 30, 52, 68, 66, 55, 45, 38, 30, 6, -24, -43, -49, -52, -64, -75, -65, -35, -10, 4, 11, 25, 45, 65, 67, 55, 48, 43, 34, 13, -18, -39, -45, -49, -61, -75, -72, -45, -17, -2, 9, 20, 39, 61, 70, 62, 52, 45, 36, 18, -9, -34, -47, -52, -58, -69, -72, -52, -23, -5, 7, 17, 35, 54, 65, 63, 55, 45, 37, 23, 0, -27, -45, -49, -53, -63, -71, -59, -31, -8, 7, 15, 28, 47, 61, 65, 58, 47, 38, 27, 6, -21, -41, -49, -53, -62, -69, -62, -39, -14, 3, 14, 28, 46, 59, 64, 62, 51, 39, 29, 11, -16, -40, -52, -55, -58, -65, -65, -47, -20, 1, 14, 24, 39, 52, 59, 64, 56, 43, 33, 16, -8, -32, -49, -55, -58, -63, -65, -54, -29, -3, 12, 21, 36, 51, 60, 65, 59, 46, 35, 21, -4, -28, -48, -56, -57, -59, -60, -55, -37, -12, 9, 19, 32, 46, 54, 58, 58, 48, 36, 26, 7, -18, -41, -53, -53, -52, -57, -58, -45, -19, 6, 15, 26, 42, 54, 59, 59, 52, 39, 28, 10, -16, -40, -56, -56, -52, -51, -53, -45, -22, 4, 17, 24, 35, 46, 56, 57, 52, 40, 30, 18, -7, -33, -54, -58, -52, -49, -53, -51, -33, -5, 17, 26, 34, 43, 54, 58, 53, 42, 31, 19, 0, -24, -47, -60, -55, -46, -46, -50, -39, -13, 13, 25, 32, 38, 48, 56, 52, 41, 30, 20, 7, -15, -41, -58, -55, -44, -41, -44, -40, -19, 10, 25, 28, 32, 41, 53, 52, 42, 31, 21, 13, -5, -32, -55, -60, -47, -36, -38, -40, -26, 2, 24, 29, 28, 32, 46, 48, 40, 29, 21, 14, 1, -23, -48, -56, -46, -34, -33, -36, -29, -7, 20, 28, 25, 26, 37, 46, 42, 30, 19, 15, 7, -13, -39, -58, -54, -37, -27, -27, -29, -17, 13, 29, 28, 24, 31, 42, 42, 34, 21, 11, 5, -10, -32, -51, -52, -40, -28, -24, -24, -18, 6, 27, 30, 26, 28, 36, 38, 33, 22, 11, 6, -7, -26, -44, -49, -42, -30, -21, -17, -16, -5, 18, 29, 26, 25, 29, 33, 33, 25, 13, 7, 0, -18, -36, -46, -45, -31, -20, -16, -16, -9, 12, 28, 29, 24, 25, 29, 31, 26, 13, 2, -5, -15, -26, -39, -46, -37, -19, -9, -9, -11, 1, 21, 31, 26, 21, 23, 26, 25, 15, 4, -4, -10, -20, -32, -41, -38, -22, -10, -7, -9, -6, 11, 26, 29, 22, 20, 21, 24, 19, 7, -6, -12, -17, -23, -30, -36, -27, -12, -3, 0, -5, 3, 18, 28, 25, 18, 15, 16, 15, 7, -4, -10, -14, -19, -24, -30, -26, -13, -3, 2, -3, -2, 12, 23, 26, 18, 13, 13, 14, 9, 0, -11, -14, -15, -18, -24, -26, -16, -4, 4, 0, -5, 6, 17, 25, 21, 11, 7, 8, 8, 1, -11, -14, -11, -10, -13, -20, -18, -7, 5, 7, -3, -2, 8, 21, 23, 12, 4, 4, 8, 7, -5, -15, -14, -11, -9, -15, -20, -13, 1, 8, 3, 0, 6, 17, 24, 16, 3, -2, 1, 0, -10, -17, -14, -8, -4, -5, -11, -12, 0, 9, 6, -3, 1, 10, 18, 16, 5, -3, 0, 3, -4, -13, -15, -10, -6, -4, -8, -13, -8, 5, 8, 5, 3, 9, 17, 18, 13, 0, -7, -5, -5, -11, -14, -11, -6, 2, 2, -6, -9, 1, 8, 5, -2, 1, 8, 14, 12, 2, -6, -5, -2, -6, -12, -10, -2, 3, 4, -5, -11, -6, 5, 6, 0, 0, 7, 12, 14, 6, -7, -8, -6, -6, -9, -10, -5, 4, 8, 4, -7, -11, -2, 6, 3, -2, 2, 9, 15, 12, -2, -8, -6, -3, -5, -11, -9, 2, 10, 7, -5, -15, -10, 4, 6, -2, -2, 8, 14, 14, 3, -9, -8, -5, -4, -8, -10, 0, 8, 9, 3, -9, -12, -3, 6, 3, -3, 1, 8, 13, 5, -9, -13, -7, -2, -2, -6, -2, 9, 13, 6, -6, -13, -10, 2, 4, -3, -2, 7, 13, 9, -6, -12, -11, -6, 0, -5, -5, 7, 15, 13, 1, -10, -13, -4, 5, -2, -7, -2, 9, 9, -3, -11, -11, -8, 2, 1, -3, 7, 15, 12, 4, -7, -13, -11, -2, 1, -4, -3, 7, 11, 3, -8, -11, -10, 0, 1, -5, 2, 12, 17, 11, -2, -11, -11, -3, 4, -4, -9, 1, 10, 3, -9, -11, -8, 0, 5, 1, 2, 11, 14, 9, 1, -11, -15, -11, -3, 1, -3, 3, 12, 11, 1, -7, -9, -6, -3, -5, -5, 5, 12, 9, 4, -3, -8, -8, -5, 0, -4, -3, 5, 6, -3, -10, -7, -3, 0, 2, 3, 10, 14, 11, 4, -3, -11, -15, -15, -9, -5, -5, 5, 13, 5, -2, 0, 2, 4, 1, -3, 4, 12, 11, 2, -5, -10, -13, -13, -11, -6, -4, 3, 13, 9, 1, -2, 4, 5, 1, -5, 3, 12, 13, 4, -9, -12, -14, -16, -17, -12, -5, 5, 16, 17, 6, 3, 9, 9, 2, -8, -7, 2, 7, 4, -8, -12, -10, -13, -14, -13, -6, 4, 13, 19, 10, 0, 6, 14, 8, -6, -9, 0, 7, 5, -8, -17, -13, -9, -14, -18, -13, 2, 15, 23, 16, 4, 5, 16, 15, 0, -10, -6, 3, 6, -4, -15, -15, -10, -11, -16, -16, -5, 10, 21, 18, 7, 2, 12, 18, 6, -7, -9, 1, 7, 1, -14, -19, -15, -13, -16, -18, -8, 7, 19, 24, 16, 5, 8, 16, 9, -4, -9, -5, 3, 4, -9, -19, -18, -13, -12, -17, -12, 2, 16, 22, 17, 6, 4, 14, 13, 1, -8, -6, 2, 6, -5, -18, -20, -16, -14, -18, -17, -5, 12, 23, 24, 14, 9, 15, 19, 9, -5, -8, -3, 2, -6, -17, -23, -19, -14, -16, -17, -8, 7, 19, 24, 19, 10, 11, 17, 13, 3, -5, -3, -2, -4, -14, -24, -25, -20, -18, -16, -10, 3, 16, 26, 28, 18, 11, 15, 17, 9, -4, -7, -6, -6, -12, -24, -29, -22, -16, -15, -10, 0, 13, 24, 27, 22, 14, 13, 16, 13, 2, -6, -7, -9, -12, -21, -29, -27, -21, -15, -10, -3, 8, 21, 29, 26, 17, 13, 17, 19, 9, -5, -10, -9, -12, -21, -30, -29, -22, -14, -10, -4, 7, 17, 26, 23, 17, 13, 12, 18, 16, 5, -6, -10, -11, -19, -29, -32, -27, -18, -10, -4, 4, 13, 25, 26, 21, 16, 11, 16, 17, 8, -5, -12, -12, -16, -25, -30, -27, -19, -10, -6, 0, 10, 21, 24, 18, 15, 13, 16, 20, 14, 1, -10, -12, -15, -26, -31, -29, -22, -12, -5, 0, 8, 19, 25, 22, 17, 14, 14, 19, 17, 4, -10, -15, -15, -22, -30, -30, -26, -16, -6, 1, 7, 15, 23, 23, 18, 17, 17, 17, 17, 8, -6, -15, -18, -24, -31, -29, -26, -19, -8, 2, 7, 15, 23, 24, 21, 17, 15, 15, 17, 13, -4, -16, -20, -23, -30, -32, -27, -19, -8, 3, 7, 14, 23, 24, 20, 16, 16, 15, 14, 10, 0, -12, -20, -24, -31, -32, -25, -19, -10, 0, 9, 14, 22, 27, 23, 17, 17, 18, 12, 8, 1, -12, -18, -23, -31, -34, -26, -17, -9, -2, 6, 14, 22, 27, 22, 16, 15, 18, 17, 10, 3, -9, -17, -21, -31, -38, -32, -23, -13, -5, 4, 14, 21, 30, 30, 21, 17, 18, 17, 10, 3, -8, -20, -23, -29, -38, -34, -25, -12, 0, 3, 11, 17, 26, 31, 23, 15, 13, 16, 14, 5, -4, -15, -19, -23, -35, -38, -32, -19, -7, -5, 6, 16, 25, 36, 32, 22, 19, 19, 15, 3, -7, -16, -23, -26, -35, -42, -34, -19, -3, 1, 6, 18, 26, 37, 34, 20, 15, 14, 14, 5, -7, -15, -21, -23, -28, -39, -37, -22, -5, 1, 3, 15, 25, 35, 40, 27, 14, 14, 14, 6, -7, -14, -20, -25, -27, -36, -41, -28, -8, 2, 4, 14, 24, 33, 40, 32, 17, 13, 12, 5, -7, -14, -17, -24, -28, -34, -40, -32, -14, 1, 4, 13, 26, 33, 41, 40, 26, 15, 12, 4, -9, -17, -20, -25, -31, -34, -41, -38, -20, 0, 7, 12, 24, 32, 40, 41, 30, 17, 11, 4, -10, -18, -19, -21, -27, -31, -35, -36, -24, -5, 5, 9, 21, 31, 37, 41, 36, 21, 11, 4, -8, -15, -18, -21, -26, -31, -34, -37, -30, -12, 3, 9, 18, 30, 38, 44, 42, 29, 15, 7, -6, -18, -23, -24, -25, -31, -34, -36, -33, -15, 3, 9, 17, 28, 38, 44, 42, 34, 20, 8, -5, -18, -23, -22, -24, -30, -35, -35, -35, -24, -6, 6, 14, 25, 36, 42, 45, 42, 28, 13, 1, -15, -26, -27, -26, -29, -35, -39, -38, -28, -10, 5, 13, 21, 36, 47, 48, 45, 36, 21, 6, -11, -25, -31, -30, -29, -35, -41, -41, -34, -18, 1, 15, 24, 35, 47, 52, 51, 42, 26, 8, -9, -25, -32, -34, -32, -34, -40, -41, -35, -22, -5, 11, 21, 30, 44, 52, 51, 45, 32, 15, -3, -19, -28, -33, -34, -36, -42, -44, -41, -30, -13, 6, 20, 29, 43, 54, 56, 50, 37, 22, 4, -17, -31, -39, -39, -38, -40, -44, -41, -31, -14, 4, 18, 26, 37, 52, 57, 54, 44, 29, 11, -9, -26, -38, -42, -40, -41, -45, -46, -39, -24, -2, 17, 25, 35, 49, 59, 59, 52, 36, 19, -2, -22, -38, -46, -45, -43, -44, -47, -41, -28, -7, 12, 22, 32, 45, 58, 60, 52, 40, 26, 9, -14, -36, -46, -47, -44, -44, -50, -47, -34, -14, 8, 21, 30, 42, 58, 65, 58, 46, 32, 14, -7, -30, -47, -51, -50, -45, -50, -51, -38, -20, 4, 19, 28, 38, 53, 67, 63, 50, 40, 23, 2, -22, -43, -54, -55, -50, -53, -57, -48, -31, -6, 17, 28, 39, 53, 69, 72, 60, 47, 29, 7, -18, -39, -54, -59, -56, -53, -55, -52, -37, -16, 10, 25, 36, 48, 65, 75, 68, 54, 40, 20, -6, -31, -52, -61, -61, -59, -63, -62, -46, -24, 2, 20, 33, 50, 67, 79, 75, 62, 49, 30, 2, -29, -50, -63, -66, -65, -64, -64, -50, -28, -6, 18, 34, 48, 62, 74, 79, 70, 54, 38, 14, -19, -45, -62, -70, -71, -67, -68, -61, -39, -15, 10, 28, 45, 63, 77, 82, 77, 62, 47, 25, -9, -40, -61, -70, -73, -69, -70, -66, -47, -23, 2, 23, 41, 57, 71, 79, 83, 72, 55, 37, 6, -27, -51, -67, -76, -78, -77, -75, -60, -35, -12, 13, 37, 59, 75, 82, 86, 81, 66, 48, 17, -23, -50, -66, -77, -83, -83, -78, -66, -43, -18, 7, 31, 54, 73, 83, 87, 87, 74, 55, 29, -10, -41, -61, -76, -85, -88, -84, -72, -53, -28, -3, 22, 51, 75, 84, 88, 92, 87, 67, 40, 0, -38, -60, -77, -89, -94, -89, -77, -59, -34, -7, 17, 44, 73, 88, 90, 91, 88, 74, 49, 12, -29, -57, -73, -84, -93, -94, -84, -68, -44, -17, 8, 33, 64, 85, 90, 92, 91, 83, 63, 30, -15, -50, -71, -82, -92, -96, -90, -74, -52, -26, 0, 24, 56, 82, 92, 93, 92, 89, 74, 42, 0, -41, -67, -80, -93, -100, -97, -83, -62, -35, -8, 16, 43, 74, 91, 96, 96, 93, 83, 56, 16, -28, -61, -79, -92, -99, -99, -90, -71, -45, -16, 9, 36, 66, 88, 98, 97, 93, 87, 68, 31, -16, -52, -75, -89, -98, -103, -98, -81, -54, -23, 1, 25, 56, 83, 97, 98, 92, 88, 76, 46, 1, -42, -68, -81, -91, -99, -97, -82, -58, -30, -6, 15, 44, 73, 91, 94, 89, 85, 78, 55, 16, -28, -59, -77, -87, -93, -95, -85, -65, -40, -16, 6, 33, 62, 85, 94, 90, 86, 81, 66, 32, -15, -52, -73, -84, -90, -93, -87, -69, -45, -22, 0, 22, 48, 75, 88, 88, 85, 80, 67, 42, 4, -36, -62, -77, -87, -90, -85, -72, -52, -30, -11, 11, 36, 63, 83, 86, 86, 82, 74, 54, 17, -25, -55, -72, -81, -88, -87, -77, -57, -34, -16, 4, 26, 54, 77, 84, 84, 82, 75, 58, 27, -12, -45, -65, -76, -84, -84, -76, -61, -41, -24, -7, 15, 41, 67, 78, 81, 80, 76, 67, 42, 5, -30, -54, -67, -79, -85, -79, -67, -50, -32, -16, 6, 32, 58, 73, 77, 81, 78, 68, 49, 16, -19, -45, -63, -74, -80, -77, -67, -53, -35, -20, -3, 20, 45, 65, 72, 76, 75, 68, 56, 29, -6, -33, -52, -65, -75, -77, -70, -57, -42, -28, -13, 9, 34, 57, 70, 73, 75, 72, 63, 41, 7, -24, -46, -60, -70, -75, -72, -59, -45, -31, -18, 0, 25, 48, 63, 68, 70, 71, 65, 47, 17, -13, -33, -49, -62, -73, -73, -61, -48, -37, -25, -10, 14, 39, 57, 64, 67, 70, 69, 54, 28, -3, -27, -44, -57, -68, -74, -66, -50, -39, -26, -13, 5, 30, 50, 60, 62, 64, 65, 58, 38, 9, -17, -35, -46, -59, -69, -67, -52, -40, -31, -20, -6, 18, 42, 55, 58, 60, 65, 62, 47, 20, -10, -28, -39, -51, -66, -70, -58, -44, -34, -23, -10, 11, 34, 51, 57, 58, 62, 63, 51, 29, 2, -21, -34, -46, -60, -69, -63, -49, -37, -27, -15, 3, 26, 45, 55, 56, 58, 62, 55, 37, 11, -14, -29, -39, -52, -65, -66, -52, -40, -30, -18, -5, 17, 39, 52, 54, 55, 58, 57, 44, 21, -8, -24, -33, -45, -59, -66, -57, -43, -31, -20, -11, 7, 30, 47, 53, 51, 52, 55, 51, 33, 4, -20, -29, -36, -49, -64, -63, -50, -36, -24, -14, 0, 22, 43, 55, 53, 49, 52, 51, 39, 12, -16, -27, -33, -45, -60, -66, -53, -37, -25, -16, -6, 16, 40, 53, 53, 47, 49, 51, 43, 22, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, -2, -2, -2, -2, 0, -2, 0, 0, 1, 2, 3, 4, 4, 4, 5, 6, 7, 6, 3, 1, 0, -3, -5, -11, -17, -20, -20, -18, -16, -17, -17, -14, -10, -9, -13, -18, -19, -15, -13, -12, -13, -8, 1, 12, 25, 32, 40, 45, 50, 49, 41, 32, 24, 16, 9, 1, -12, -20, -23, -24, -20, -20, -18, -12, -11, -12, -7, 0, 10, 17, 23, 25, 24, 21, 22, 23, 21, 10, 1, -5, -8, -11, -19, -29, -33, -32, -26, -19, -16, -14, -12, -8, -7, -11, -19, -27, -29, -27, -25, -25, -24, -17, -4, 13, 26, 34, 43, 54, 59, 56, 46, 33, 23, 15, 5, -11, -23, -32, -35, -32, -30, -27, -23, -16, -11, -5, 3, 11, 23, 31, 36, 33, 28, 27, 26, 21, 11, 1, -9, -14, -18, -23, -28, -35, -33, -26, -18, -12, -11, -7, -4, -2, 0, -8, -19, -29, -33, -32, -30, -30, -25, -17, -4, 13, 26, 36, 47, 55, 59, 53, 43, 32, 23, 12, 0, -14, -23, -30, -35, -35, -35, -33, -28, -19, -11, -6, 3, 11, 22, 33, 39, 38, 34, 30, 27, 20, 11, 0, -9, -17, -21, -26, -31, -34, -29, -19, -8, -3, 0, -3, 1, 4, 1, -11, -25, -35, -37, -39, -35, -32, -27, -17, 0, 15, 29, 42, 55, 63, 62, 55, 47, 38, 27, 14, -4, -20, -31, -40, -44, -46, -45, -41, -34, -25, -14, -3, 8, 22, 32, 43, 44, 40, 36, 34, 26, 18, 8, -2, -11, -20, -25, -29, -33, -31, -21, -10, -2, -2, -2, 4, 6, 9, 0, -14, -28, -35, -39, -38, -38, -36, -30, -16, 0, 16, 29, 41, 55, 65, 67, 59, 49, 39, 28, 13, -3, -19, -32, -42, -48, -51, -53, -47, -36, -22, -12, 0, 10, 24, 38, 46, 48, 43, 39, 32, 26, 17, 6, -7, -16, -21, -26, -31, -34, -28, -16, -2, 3, 1, 2, 8, 16, 12, 2, -15, -27, -34, -37, -41, -47, -44, -33, -16, 1, 16, 31, 47, 65, 75, 73, 63, 52, 41, 27, 9, -14, -34, -47, -54, -55, -58, -57, -50, -35, -17, 0, 8, 20, 34, 47, 54, 49, 42, 36, 29, 21, 9, -4, -14, -21, -26, -30, -33, -28, -18, -5, 4, 6, 6, 8, 13, 17, 12, -4, -21, -33, -39, -44, -49, -50, -46, -35, -15, 4, 22, 36, 55, 72, 81, 78, 69, 54, 42, 27, 6, -19, -38, -52, -57, -62, -65, -64, -52, -35, -17, -3, 8, 19, 33, 45, 50, 48, 42, 35, 29, 18, 7, -5, -11, -20, -26, -29, -27, -20, -13, -4, 3, 8, 9, 11, 12, 12, 5, -8, -22, -33, -42, -50, -53, -51, -42, -27, -11, 9, 27, 45, 62, 75, 78, 73, 60, 48, 32, 14, -8, -30, -46, -54, -60, -64, -62, -53, -39, -23, -8, 5, 17, 30, 41, 46, 44, 38, 30, 22, 11, 4, -5, -12, -20, -25, -26, -24, -17, -7, 3, 8, 11, 12, 14, 15, 14, 9, -4, -17, -32, -44, -54, -57, -56, -48, -36, -22, -5, 18, 41, 61, 74, 79, 75, 67, 55, 39, 20, -2, -20, -37, -47, -56, -62, -63, -57, -44, -31, -18, -5, 7, 16, 28, 35, 38, 37, 32, 25, 16, 8, 3, -2, -5, -11, -19, -21, -16, -7, 3, 6, 8, 7, 8, 10, 9, 5, -4, -13, -23, -37, -49, -54, -54, -47, -38, -25, -9, 9, 30, 50, 67, 77, 75, 69, 58, 42, 26, 7, -12, -31, -46, -52, -56, -59, -58, -49, -36, -19, -5, 8, 14, 22, 28, 33, 35, 30, 23, 13, 4, 3, 3, 0, -8, -12, -13, -10, -6, 2, 8, 11, 12, 11, 9, 4, -2, -5, -12, -23, -35, -46, -52, -54, -48, -36, -22, -8, 9, 28, 46, 61, 70, 72, 68, 58, 45, 27, 9, -8, -22, -35, -43, -48, -48, -46, -39, -33, -23, -12, 1, 8, 11, 14, 16, 19, 19, 17, 11, 7, 8, 11, 13, 7, 5, 2, 2, 2, 4, 6, 6, 5, 2, -3, -5, -9, -11, -17, -23, -29, -34, -40, -45, -41, -32, -18, -5, 7, 19, 36, 54, 64, 67, 61, 55, 48, 36, 18, 3, -11, -23, -36, -45, -46, -42, -39, -34, -27, -20, -11, 0, 10, 13, 14, 12, 13, 13, 10, 7, 6, 9, 11, 11, 11, 10, 10, 8, 9, 9, 9, 6, 1, -4, -12, -16, -22, -25, -28, -29, -30, -39, -43, -39, -26, -11, 0, 8, 19, 33, 48, 58, 63, 61, 56, 50, 40, 25, 8, -5, -15, -24, -35, -41, -42, -39, -32, -29, -25, -21, -13, -6, 0, 4, 2, 2, 3, 6, 6, 7, 11, 17, 20, 22, 23, 24, 23, 21, 17, 12, 4, -5, -13, -22, -29, -37, -41, -40, -36, -31, -32, -34, -34, -22, -6, 8, 14, 20, 29, 41, 50, 56, 56, 49, 45, 39, 30, 17, 5, -8, -19, -28, -34, -35, -32, -27, -25, -25, -23, -19, -12, -7, -4, -6, -10, -11, -7, 0, 4, 10, 14, 19, 26, 32, 35, 34, 31, 25, 16, 6, -5, -17, -29, -39, -47, -51, -50, -44, -35, -28, -27, -25, -18, -6, 10, 18, 21, 25, 31, 40, 46, 49, 48, 44, 42, 37, 29, 19, 8, -5, -14, -21, -29, -30, -30, -27, -28, -32, -33, -31, -22, -17, -15, -17, -19, -19, -9, 5, 16, 22, 25, 31, 38, 44, 47, 43, 34, 20, 6, -9, -21, -35, -49, -59, -62, -60, -53, -42, -30, -22, -15, -6, 4, 14, 23, 27, 28, 27, 30, 35, 38, 39, 42, 38, 35, 30, 25, 20, 12, 4, -6, -18, -23, -22, -20, -22, -30, -37, -39, -34, -29, -27, -27, -26, -23, -16, -3, 10, 21, 29, 35, 43, 46, 50, 49, 41, 28, 15, -2, -19, -35, -50, -62, -67, -67, -60, -50, -36, -23, -14, -6, 3, 11, 21, 27, 27, 24, 25, 27, 29, 31, 36, 41, 42, 39, 33, 27, 22, 17, 8, -3, -11, -15, -15, -18, -25, -35, -42, -45, -42, -41, -41, -40, -38, -28, -12, 7, 22, 34, 43, 51, 59, 62, 59, 49, 37, 20, 1, -19, -38, -54, -65, -73, -74, -69, -55, -35, -19, -10, -2, 8, 18, 23, 25, 25, 22, 20, 19, 20, 22, 30, 39, 44, 42, 39, 35, 32, 29, 18, 4, -8, -13, -15, -17, -24, -33, -43, -47, -44, -42, -40, -40, -39, -32, -17, 3, 16, 28, 39, 47, 53, 56, 56, 52, 40, 24, 5, -12, -29, -43, -54, -65, -72, -71, -56, -36, -20, -13, -4, 5, 12, 18, 21, 23, 20, 18, 14, 16, 19, 27, 38, 45, 45, 42, 41, 42, 37, 27, 15, 1, -8, -12, -13, -17, -30, -40, -47, -48, -47, -46, -46, -45, -41, -28, -9, 11, 26, 38, 45, 51, 55, 58, 55, 47, 31, 10, -12, -27, -39, -49, -58, -67, -69, -62, -46, -26, -13, -4, 2, 7, 14, 18, 21, 20, 15, 11, 12, 14, 21, 32, 40, 44, 42, 42, 40, 37, 33, 22, 11, 1, -7, -11, -11, -19, -30, -39, -43, -43, -42, -43, -44, -44, -36, -20, 0, 14, 25, 35, 42, 46, 50, 50, 48, 36, 17, -3, -18, -30, -36, -43, -52, -59, -60, -49, -35, -20, -12, -7, -4, 2, 8, 12, 12, 9, 9, 12, 16, 23, 29, 39, 45, 46, 46, 43, 41, 37, 30, 20, 7, -5, -10, -11, -15, -25, -39, -46, -45, -43, -42, -45, -46, -39, -26, -8, 8, 20, 31, 41, 45, 48, 46, 44, 36, 21, 1, -20, -31, -33, -36, -44, -53, -59, -54, -41, -26, -17, -12, -6, -3, 5, 7, 9, 11, 11, 12, 15, 20, 29, 36, 42, 46, 45, 42, 40, 38, 33, 25, 13, 4, -7, -10, -11, -17, -29, -38, -38, -34, -35, -39, -41, -39, -31, -16, -6, 4, 14, 24, 30, 34, 34, 35, 32, 22, 8, -9, -16, -16, -17, -22, -33, -43, -46, -41, -34, -30, -25, -19, -14, -9, -6, -2, 5, 9, 13, 15, 21, 29, 36, 43, 47, 46, 46, 42, 39, 37, 31, 20, 10, 0, -6, -9, -14, -22, -29, -33, -31, -30, -34, -37, -37, -30, -21, -12, -5, 1, 10, 20, 28, 31, 31, 28, 20, 12, 0, -8, -10, -10, -16, -24, -33, -39, -44, -42, -35, -28, -23, -18, -14, -10, -4, 6, 12, 16, 17, 22, 29, 33, 35, 38, 41, 43, 41, 38, 34, 30, 24, 16, 9, 3, -4, -10, -15, -21, -23, -23, -23, -24, -28, -32, -31, -28, -22, -15, -10, -6, 2, 11, 20, 23, 25, 19, 14, 9, 5, 3, 2, -2, -8, -19, -28, -36, -42, -44, -39, -33, -28, -26, -20, -11, 0, 8, 15, 22, 28, 33, 35, 36, 37, 38, 41, 40, 38, 32, 27, 21, 17, 11, 4, -3, -8, -12, -17, -18, -16, -16, -15, -18, -22, -25, -26, -25, -23, -19, -15, -9, -2, 8, 13, 17, 18, 17, 16, 15, 13, 10, 6, 0, -9, -21, -32, -42, -47, -46, -43, -36, -30, -22, -15, -6, 4, 14, 22, 28, 33, 36, 37, 36, 35, 37, 36, 36, 32, 27, 23, 16, 10, 5, 0, -7, -10, -12, -11, -11, -11, -10, -9, -11, -16, -22, -27, -30, -30, -30, -25, -19, -9, 0, 7, 13, 18, 23, 27, 27, 26, 20, 12, 1, -13, -27, -40, -50, -54, -54, -49, -42, -33, -21, -10, 1, 14, 24, 30, 39, 44, 43, 38, 36, 38, 37, 34, 31, 28, 22, 13, 7, 5, -2, -7, -11, -14, -13, -13, -8, -6, -6, -10, -12, -14, -19, -26, -34, -38, -33, -26, -15, -7, 2, 7, 17, 26, 35, 40, 37, 29, 19, 7, -12, -31, -44, -53, -56, -61, -62, -59, -46, -27, -9, 5, 14, 25, 36, 47, 53, 51, 45, 37, 34, 32, 29, 26, 23, 18, 13, 5, 0, -3, -4, -6, -10, -12, -12, -6, 2, 6, 2, -6, -12, -17, -21, -31, -41, -47, -43, -32, -20, -11, -4, 9, 21, 40, 50, 48, 42, 34, 22, 5, -16, -36, -53, -58, -63, -69, -73, -63, -43, -19, -2, 9, 19, 34, 50, 60, 61, 53, 42, 37, 32, 30, 24, 21, 16, 11, 4, -4, -7, -6, -5, -5, -10, -14, -11, -4, 3, 2, -2, -8, -13, -19, -26, -36, -42, -40, -33, -21, -9, 1, 10, 22, 36, 49, 53, 47, 36, 19, 1, -18, -36, -51, -60, -65, -67, -67, -63, -47, -24, -4, 11, 20, 33, 48, 57, 57, 52, 42, 33, 30, 28, 25, 19, 16, 12, 8, 3, -2, -2, -2, -2, -5, -8, -10, -5, -2, 0, 0, -5, -8, -15, -23, -32, -39, -38, -33, -24, -15, -7, 5, 16, 30, 45, 52, 49, 40, 23, 4, -14, -29, -42, -55, -63, -67, -67, -61, -50, -35, -19, 0, 16, 31, 46, 56, 59, 56, 47, 38, 34, 31, 28, 23, 16, 10, 4, 0, -2, -2, 0, -5, -9, -12, -11, -7, -3, -3, -4, -5, -4, -7, -14, -26, -33, -32, -27, -20, -15, -7, 2, 13, 21, 34, 42, 46, 40, 25, 7, -13, -27, -35, -44, -54, -62, -64, -60, -51, -39, -26, -10, 8, 24, 40, 51, 58, 60, 54, 44, 36, 29, 24, 19, 13, 8, 0, -6, -5, 0, 1, 0, -4, -3, -2, 0, 1, -2, -5, -5, -4, -7, -17, -27, -31, -29, -24, -19, -15, -9, -3, 7, 18, 27, 34, 39, 37, 26, 9, -9, -24, -32, -39, -47, -55, -60, -57, -51, -42, -32, -20, -6, 14, 31, 48, 57, 60, 58, 52, 45, 35, 25, 21, 17, 9, 0, -8, -10, -8, -7, -6, -9, -9, -6, -2, 0, -3, -6, -6, -2, 1, -6, -15, -25, -25, -20, -17, -13, -11, -7, 1, 8, 16, 24, 31, 34, 29, 16, -3, -17, -28, -35, -41, -47, -54, -56, -54, -46, -37, -27, -15, 4, 23, 40, 50, 58, 60, 58, 50, 42, 34, 26, 19, 14, 4, -6, -13, -13, -13, -14, -16, -15, -12, -9, -7, -7, -4, -4, 2, 7, 5, 0, -8, -11, -13, -13, -11, -10, -11, -11, -9, 0, 8, 14, 22, 24, 19, 9, -3, -14, -23, -29, -32, -38, -47, -54, -52, -44, -32, -23, -9, 8, 23, 39, 52, 59, 58, 51, 46, 43, 33, 25, 16, 9, 4, -4, -11, -15, -16, -16, -15, -14, -15, -16, -13, -7, -5, 2, 5, 5, 5, 6, 3, -4, -6, -4, -5, -10, -16, -16, -13, -6, 4, 12, 15, 17, 14, 10, 4, -8, -17, -23, -30, -38, -46, -52, -51, -41, -30, -20, -8, 9, 29, 47, 56, 57, 55, 52, 50, 45, 34, 20, 10, 2, -2, -9, -16, -22, -24, -22, -21, -22, -19, -14, -7, -4, 1, 5, 11, 15, 20, 17, 9, 3, 3, 0, -6, -15, -21, -23, -16, -9, -3, 4, 10, 13, 15, 13, 4, -9, -15, -20, -27, -39, -48, -51, -47, -38, -29, -21, -7, 16, 36, 48, 51, 52, 55, 60, 59, 49, 33, 20, 12, 7, -2, -13, -24, -28, -27, -26, -30, -32, -29, -20, -9, 0, 3, 8, 16, 25, 28, 23, 17, 12, 6, -2, -14, -26, -31, -27, -18, -10, -3, 7, 15, 22, 24, 18, 9, 0, -9, -19, -34, -46, -57, -57, -51, -44, -38, -26, -5, 21, 42, 48, 53, 58, 67, 75, 71, 57, 37, 23, 12, 3, -12, -27, -39, -43, -43, -45, -47, -42, -28, -12, 2, 7, 12, 20, 32, 38, 37, 30, 21, 13, 1, -13, -26, -34, -33, -26, -17, -10, -3, 9, 20, 25, 22, 13, 5, -3, -13, -28, -43, -53, -56, -51, -46, -40, -31, -14, 10, 31, 41, 47, 56, 67, 76, 73, 63, 46, 30, 19, 9, -7, -25, -39, -47, -50, -54, -52, -50, -38, -22, -9, 4, 12, 22, 30, 39, 41, 39, 31, 22, 12, -3, -19, -30, -32, -29, -23, -17, -9, 1, 12, 20, 24, 18, 10, 2, -7, -19, -35, -50, -59, -59, -54, -49, -43, -31, -9, 15, 32, 41, 53, 70, 85, 87, 80, 64, 49, 37, 23, 2, -23, -42, -52, -59, -66, -69, -68, -56, -38, -18, -2, 9, 19, 31, 41, 49, 51, 44, 35, 21, 5, -9, -22, -29, -30, -26, -20, -14, -7, 5, 15, 17, 14, 9, 2, -4, -16, -29, -45, -55, -56, -50, -46, -44, -36, -19, 1, 19, 33, 46, 63, 79, 86, 84, 73, 60, 47, 32, 12, -10, -30, -48, -59, -68, -72, -73, -64, -49, -30, -12, 2, 12, 26, 35, 45, 51, 51, 44, 30, 15, 3, -9, -17, -20, -21, -19, -18, -14, 0, 10, 16, 15, 7, -4, -10, -14, -24, -38, -51, -58, -55, -50, -44, -36, -23, -7, 10, 26, 41, 57, 76, 89, 89, 81, 70, 59, 45, 25, 0, -24, -41, -56, -67, -75, -80, -76, -63, -45, -26, -9, 6, 20, 32, 44, 52, 54, 53, 47, 35, 18, 3, -6, -11, -14, -16, -19, -19, -12, -4, 5, 5, 0, -8, -12, -15, -21, -34, -47, -51, -45, -39, -34, -30, -23, -12, 4, 17, 31, 45, 60, 72, 78, 75, 69, 62, 53, 40, 18, -5, -24, -38, -50, -62, -73, -78, -74, -59, -41, -28, -17, -4, 14, 33, 47, 55, 58, 55, 48, 39, 29, 16, 4, -5, -11, -18, -21, -20, -15, -8, -7, -9, -13, -15, -16, -17, -23, -33, -43, -44, -41, -34, -28, -23, -16, -8, 5, 21, 36, 50, 62, 73, 76, 73, 68, 59, 48, 30, 9, -16, -35, -48, -59, -70, -77, -79, -72, -54, -38, -24, -8, 8, 29, 45, 56, 61, 62, 56, 51, 39, 27, 16, 4, -8, -16, -22, -23, -25, -19, -16, -17, -19, -20, -21, -18, -19, -25, -32, -38, -34, -24, -19, -15, -12, -7, 3, 15, 28, 39, 48, 56, 63, 63, 63, 57, 47, 32, 14, -5, -22, -36, -46, -58, -68, -73, -71, -61, -47, -35, -23, -9, 10, 29, 43, 52, 56, 56, 56, 52, 45, 33, 19, 6, -5, -15, -22, -25, -26, -26, -29, -29, -26, -24, -20, -19, -23, -27, -30, -27, -21, -18, -14, -10, -7, 0, 8, 18, 30, 40, 47, 52, 54, 54, 55, 49, 39, 22, 7, -9, -24, -37, -50, -58, -65, -71, -67, -59, -50, -39, -23, -6, 15, 32, 43, 51, 57, 61, 64, 61, 52, 37, 21, 4, -11, -20, -26, -30, -35, -37, -39, -35, -29, -22, -17, -20, -22, -20, -18, -17, -16, -13, -8, -3, 2, 7, 10, 17, 27, 35, 42, 43, 44, 45, 44, 38, 28, 16, 3, -10, -22, -33, -46, -57, -64, -64, -59, -53, -46, -34, -17, 3, 21, 32, 41, 48, 55, 60, 60, 54, 44, 31, 18, 3, -10, -19, -27, -30, -32, -34, -35, -30, -23, -17, -17, -20, -20, -20, -17, -15, -13, -11, -8, 1, 8, 12, 17, 23, 30, 39, 39, 37, 36, 35, 34, 27, 14, 0, -10, -15, -23, -34, -46, -56, -60, -56, -49, -39, -32, -23, -8, 8, 23, 32, 38, 44, 54, 58, 57, 48, 37, 29, 17, 4, -11, -21, -28, -29, -31, -34, -35, -27, -20, -15, -16, -16, -17, -13, -10, -10, -11, -10, -4, 5, 11, 13, 15, 21, 29, 33, 32, 28, 25, 25, 23, 16, 5, -6, -10, -16, -21, -30, -42, -48, -48, -43, -34, -29, -21, -13, -3, 11, 22, 27, 34, 39, 48, 53, 48, 42, 32, 23, 16, 4, -7, -18, -24, -24, -26, -28, -24, -19, -14, -13, -16, -18, -18, -16, -14, -15, -16, -15, -7, 3, 11, 14, 21, 27, 33, 36, 33, 30, 25, 22, 17, 9, -4, -15, -21, -24, -31, -39, -44, -44, -39, -30, -23, -16, -8, 4, 14, 21, 23, 25, 29, 37, 43, 42, 36, 31, 25, 18, 11, 4, -7, -11, -13, -16, -21, -22, -18, -14, -13, -16, -19, -21, -21, -19, -19, -20, -18, -11, -2, 8, 14, 18, 23, 30, 34, 35, 31, 27, 21, 13, 2, -11, -17, -23, -28, -36, -39, -40, -37, -31, -23, -14, -9, 0, 7, 13, 15, 15, 16, 22, 27, 30, 28, 29, 32, 29, 23, 16, 9, 4, 1, -2, -7, -14, -19, -14, -10, -10, -14, -18, -22, -24, -23, -26, -28, -27, -18, -8, -3, 2, 9, 22, 33, 40, 40, 36, 30, 25, 20, 8, -8, -22, -29, -32, -39, -48, -50, -42, -30, -19, -13, -8, 2, 11, 22, 25, 21, 17, 15, 20, 23, 21, 20, 20, 19, 19, 16, 11, 9, 7, 7, 3, 0, -3, -5, -5, -5, -7, -12, -22, -28, -32, -35, -35, -36, -30, -21, -12, -4, 3, 16, 29, 39, 46, 45, 40, 34, 26, 13, -2, -17, -28, -37, -48, -57, -60, -52, -36, -19, -12, -8, 2, 16, 28, 33, 28, 23, 21, 22, 21, 19, 18, 16, 14, 12, 8, 6, 5, 5, 7, 5, 4, 5, 7, 9, 7, 3, -5, -13, -22, -28, -35, -44, -49, -48, -38, -26, -14, -7, 4, 20, 38, 49, 54, 53, 49, 40, 26, 8, -11, -24, -33, -46, -61, -70, -67, -52, -31, -14, -5, 4, 14, 27, 36, 36, 33, 29, 26, 25, 21, 14, 10, 7, 8, 6, 5, 5, 6, 8, 9, 10, 14, 18, 17, 13, 5, -4, -12, -20, -28, -37, -49, -56, -56, -48, -36, -25, -15, -2, 16, 36, 51, 55, 57, 55, 48, 37, 20, 1, -17, -30, -43, -60, -73, -76, -63, -43, -24, -14, -6, 7, 23, 39, 44, 38, 34, 31, 32, 30, 24, 16, 8, 5, 6, 6, 5, 5, 6, 10, 10, 13, 16, 19, 19, 14, 5, -7, -18, -25, -34, -45, -55, -61, -59, -51, -39, -25, -12, 5, 27, 48, 58, 60, 61, 58, 49, 32, 14, -4, -20, -36, -54, -69, -79, -75, -57, -35, -21, -15, -4, 12, 28, 39, 42, 41, 38, 38, 38, 33, 23, 13, 8, 9, 11, 9, 5, 3, 6, 10, 13, 14, 15, 17, 16, 9, -6, -16, -21, -27, -40, -56, -65, -67, -57, -45, -33, -23, -5, 21, 44, 60, 66, 67, 65, 61, 47, 25, 2, -16, -34, -53, -72, -83, -82, -70, -51, -33, -20, -8, 8, 25, 39, 46, 43, 43, 43, 43, 38, 27, 17, 9, 8, 10, 11, 9, 5, 5, 8, 13, 14, 18, 20, 18, 12, -2, -13, -19, -25, -34, -48, -62, -69, -67, -58, -46, -32, -14, 9, 30, 48, 60, 69, 72, 69, 57, 36, 13, -6, -27, -47, -66, -79, -83, -77, -64, -46, -29, -13, 4, 17, 30, 39, 41, 46, 48, 45, 40, 31, 20, 12, 10, 13, 14, 12, 11, 10, 10, 15, 17, 20, 20, 17, 12, 0, -14, -24, -30, -37, -47, -60, -69, -68, -62, -51, -36, -18, 5, 25, 45, 58, 65, 68, 67, 59, 42, 20, -2, -22, -42, -61, -75, -81, -77, -66, -51, -35, -20, -4, 14, 28, 37, 38, 38, 42, 47, 43, 35, 24, 17, 14, 14, 17, 20, 20, 17, 13, 14, 17, 18, 18, 17, 11, -2, -15, -24, -31, -38, -46, -52, -58, -62, -61, -52, -38, -22, -4, 16, 35, 48, 55, 60, 62, 57, 46, 26, 6, -17, -35, -53, -68, -76, -75, -66, -51, -38, -23, -7, 10, 25, 35, 38, 37, 39, 40, 39, 30, 21, 16, 15, 15, 16, 20, 24, 26, 27, 27, 26, 24, 21, 19, 11, -3, -16, -29, -40, -44, -50, -54, -57, -58, -55, -48, -36, -21, -5, 13, 29, 41, 48, 52, 53, 50, 41, 26, 7, -14, -33, -49, -62, -70, -69, -61, -48, -36, -21, -5, 16, 30, 35, 35, 35, 32, 31, 29, 24, 17, 13, 13, 14, 15, 18, 26, 34, 39, 37, 32, 29, 26, 22, 13, 1, -15, -29, -40, -46, -51, -54, -55, -52, -46, -40, -32, -22, -10, 5, 19, 28, 33, 35, 37, 38, 33, 21, 8, -7, -20, -35, -50, -57, -57, -49, -37, -28, -21, -8, 10, 25, 32, 32, 31, 27, 24, 22, 20, 15, 13, 13, 15, 15, 19, 26, 36, 42, 43, 40, 33, 27, 22, 16, 3, -13, -26, -37, -44, -50, -55, -54, -48, -42, -32, -24, -18, -10, -3, 8, 20, 30, 31, 26, 22, 20, 15, 7, -7, -20, -32, -43, -52, -52, -46, -36, -25, -16, -5, 9, 24, 38, 42, 39, 30, 23, 19, 15, 11, 8, 6, 6, 6, 9, 18, 30, 42, 47, 45, 43, 38, 31, 22, 8, -9, -21, -33, -45, -55, -59, -56, -47, -37, -29, -21, -13, -5, 2, 8, 13, 19, 22, 20, 15, 9, 5, -3, -9, -20, -30, -39, -46, -45, -40, -31, -24, -16, -6, 7, 21, 35, 39, 36, 31, 24, 22, 15, 10, 8, 5, 6, 3, 4, 12, 25, 40, 48, 50, 48, 43, 37, 30, 17, -2, -18, -33, -45, -57, -64, -62, -53, -40, -31, -23, -13, -3, 4, 11, 16, 19, 18, 17, 13, 7, -3, -10, -16, -22, -31, -40, -45, -45, -41, -32, -24, -15, -5, 8, 24, 39, 47, 44, 38, 32, 26, 20, 12, 3, -4, -4, -5, -4, 1, 11, 29, 41, 49, 51, 49, 45, 38, 27, 9, -11, -27, -38, -52, -60, -64, -58, -45, -32, -21, -14, -5, 3, 10, 13, 13, 14, 14, 12, 4, -6, -12, -17, -21, -25, -31, -35, -40, -39, -33, -27, -19, -12, 1, 16, 29, 38, 42, 40, 36, 33, 30, 22, 11, 1, -2, -2, -3, -2, 2, 16, 32, 44, 48, 46, 44, 39, 31, 19, 1, -21, -36, -48, -58, -62, -59, -49, -38, -28, -20, -12, -2, 9, 16, 16, 15, 16, 14, 9, 2, -7, -14, -19, -25, -31, -36, -38, -38, -36, -34, -28, -20, -7, 8, 22, 33, 41, 46, 46, 42, 39, 33, 25, 14, 4, -4, -8, -8, -4, 4, 16, 30, 38, 42, 46, 45, 38, 25, 10, -7, -24, -39, -51, -58, -59, -53, -43, -34, -28, -21, -9, 5, 15, 17, 16, 15, 16, 15, 10, 2, -10, -17, -21, -26, -33, -38, -40, -37, -34, -33, -28, -17, 0, 15, 29, 40, 48, 50, 48, 44, 40, 34, 26, 15, 3, -6, -11, -11, -4, 7, 18, 24, 30, 36, 38, 35, 31, 24, 13, -7, -25, -40, -50, -53, -51, -47, -41, -38, -33, -25, -10, 4, 14, 19, 21, 22, 19, 19, 17, 7, -5, -15, -23, -31, -39, -46, -49, -49, -46, -41, -33, -19, 0, 21, 39, 53, 61, 64, 63, 56, 50, 42, 31, 15, -2, -13, -19, -19, -11, 0, 10, 15, 19, 27, 33, 37, 35, 25, 9, -13, -28, -38, -44, -46, -50, -53, -51, -46, -38, -23, -7, 10, 20, 21, 24, 25, 28, 28, 19, 8, -7, -18, -28, -36, -43, -52, -56, -57, -51, -44, -31, -13, 7, 29, 46, 60, 66, 71, 68, 61, 54, 45, 32, 13, -5, -17, -22, -20, -15, -8, -2, 8, 14, 24, 31, 35, 32, 21, 4, -13, -24, -34, -42, -49, -55, -58, -54, -48, -38, -23, -4, 14, 26, 32, 31, 32, 36, 34, 23, 7, -12, -25, -35, -47, -61, -68, -68, -61, -53, -42, -26, -7, 22, 45, 61, 71, 75, 78, 74, 66, 56, 42, 24, 7, -13, -24, -29, -25, -18, -11, -7, 2, 14, 27, 36, 38, 32, 19, 1, -14, -22, -33, -44, -56, -64, -65, -60, -47, -32, -16, 3, 18, 31, 37, 37, 38, 41, 35, 20, 0, -18, -31, -43, -56, -64, -69, -68, -60, -50, -36, -15, 6, 31, 50, 62, 71, 77, 78, 74, 66, 54, 38, 20, 2, -15, -23, -26, -24, -22, -17, -7, 8, 20, 29, 35, 33, 25, 13, -2, -14, -29, -42, -57, -67, -72, -67, -57, -42, -24, -5, 13, 31, 43, 46, 47, 48, 43, 32, 14, -5, -22, -40, -55, -63, -68, -69, -66, -57, -44, -25, -5, 18, 37, 55, 66, 75, 78, 75, 70, 62, 47, 28, 9, -7, -19, -27, -30, -27, -21, -11, 5, 18, 28, 34, 36, 32, 24, 12, -4, -20, -38, -55, -68, -75, -71, -65, -53, -35, -14, 6, 24, 39, 47, 50, 48, 44, 36, 22, 5, -16, -34, -47, -56, -60, -60, -59, -54, -45, -28, -9, 9, 25, 41, 53, 63, 67, 66, 65, 62, 54, 40, 22, 6, -8, -16, -22, -23, -20, -11, 1, 13, 22, 27, 29, 26, 24, 15, 2, -15, -33, -49, -64, -74, -74, -67, -55, -39, -20, -2, 16, 32, 45, 50, 49, 43, 35, 26, 11, -9, -25, -35, -44, -49, -52, -54, -50, -39, -26, -12, 1, 14, 27, 39, 48, 53, 55, 57, 56, 48, 36, 25, 15, 6, -5, -12, -17, -14, -8, 3, 14, 21, 26, 23, 21, 21, 14, 3, -11, -26, -44, -61, -72, -72, -68, -56, -42, -25, -11, 7, 24, 37, 44, 44, 40, 33, 25, 13, 0, -12, -24, -32, -39, -41, -39, -36, -30, -24, -18, -10, 1, 11, 21, 29, 36, 41, 47, 51, 51, 42, 35, 27, 19, 10, 1, -6, -10, -9, -2, 6, 11, 13, 13, 15, 14, 10, 4, -9, -19, -31, -45, -58, -67, -68, -56, -43, -31, -20, -9, 7, 21, 31, 35, 35, 33, 27, 18, 7, -3, -9, -13, -20, -27, -32, -33, -29, -23, -19, -16, -12, -4, 6, 15, 23, 30, 39, 47, 49, 42, 35, 31, 27, 22, 14, 2, -8, -9, -4, 5, 8, 8, 9, 7, 6, 3, 0, -5, -12, -22, -35, -50, -58, -58, -50, -39, -32, -26, -19, -8, 7, 21, 26, 27, 25, 22, 18, 11, 5, 2, 1, -3, -10, -19, -24, -23, -16, -15, -17, -20, -17, -10, -2, 6, 12, 21, 32, 44, 45, 38, 30, 27, 31, 31, 21, 8, 1, 0, 2, 8, 10, 7, 1, -3, -2, -4, -9, -12, -17, -25, -37, -47, -53, -50, -42, -32, -27, -26, -22, -11, 5, 15, 18, 20, 22, 23, 22, 18, 15, 14, 11, 7, -3, -14, -18, -17, -18, -22, -27, -27, -21, -14, -6, 3, 12, 24, 34, 40, 39, 35, 32, 31, 34, 30, 19, 10, 4, 2, 5, 7, 7, 1, -6, -10, -9, -8, -8, -11, -16, -25, -34, -41, -41, -36, -32, -33, -33, -29, -22, -11, -2, 6, 13, 17, 22, 23, 22, 22, 24, 23, 20, 12, 0, -7, -11, -14, -20, -26, -28, -26, -22, -15, -9, 2, 13, 25, 32, 33, 35, 36, 37, 38, 35, 29, 19, 9, 5, 7, 6, 4, -3, -9, -12, -11, -6, -4, -5, -10, -17, -26, -33, -37, -38, -38, -38, -41, -39, -31, -20, -9, -2, 6, 15, 23, 31, 31, 31, 30, 29, 28, 21, 13, 2, -9, -17, -20, -23, -26, -27, -26, -20, -14, -6, 6, 14, 22, 26, 32, 34, 35, 37, 37, 36, 27, 15, 6, 6, 7, 5, -3, -13, -17, -17, -11, -5, -5, -6, -11, -18, -24, -27, -30, -35, -40, -44, -44, -39, -28, -16, -6, 1, 9, 20, 31, 34, 36, 37, 36, 33, 23, 14, 5, -3, -10, -17, -23, -30, -34, -31, -22, -14, -8, 0, 7, 15, 20, 26, 30, 35, 40, 40, 34, 27, 18, 14, 9, 8, 5, -2, -11, -15, -13, -8, -4, 0, 1, -6, -12, -18, -23, -29, -38, -45, -52, -53, -47, -37, -28, -16, -5, 6, 17, 28, 37, 42, 43, 40, 37, 31, 19, 8, 1, -7, -14, -22, -27, -33, -34, -28, -18, -8, 0, 5, 10, 14, 19, 25, 33, 38, 39, 35, 27, 18, 13, 9, 8, 4, -3, -8, -12, -13, -10, -4, 4, 4, -2, -7, -14, -21, -28, -36, -45, -53, -54, -50, -44, -34, -20, -5, 7, 18, 28, 37, 39, 42, 40, 35, 28, 17, 7, 0, -7, -12, -18, -23, -28, -28, -23, -17, -8, 2, 8, 9, 10, 12, 17, 25, 32, 33, 28, 20, 13, 10, 10, 8, 6, 5, 1, -5, -6, -3, 3, 10, 10, 5, -6, -15, -21, -28, -38, -49, -59, -62, -59, -51, -39, -25, -8, 7, 17, 28, 37, 42, 44, 43, 38, 30, 17, 7, 0, -4, -10, -16, -24, -26, -27, -21, -14, -9, -2, 5, 11, 14, 12, 13, 19, 26, 29, 26, 19, 13, 8, 8, 9, 5, 2, 2, 4, 3, 1, 1, 5, 8, 7, 0, -10, -18, -25, -32, -42, -52, -56, -53, -48, -38, -29, -14, 1, 14, 23, 30, 33, 33, 35, 33, 26, 17, 9, 2, 1, 0, -5, -12, -19, -22, -21, -13, -8, -4, 5, 10, 12, 10, 10, 14, 21, 25, 24, 15, 5, 3, 5, 7, 5, 2, 5, 10, 12, 10, 9, 11, 13, 10, 2, -8, -18, -25, -32, -40, -50, -55, -53, -45, -35, -27, -17, -4, 11, 20, 28, 30, 28, 29, 30, 28, 19, 10, 6, 6, 5, 0, -10, -18, -20, -18, -14, -11, -10, -4, 6, 13, 13, 11, 13, 20, 25, 24, 15, 7, 3, 4, 5, 4, 0, 3, 9, 14, 15, 11, 9, 8, 8, 6, -5, -16, -24, -29, -35, -43, -48, -47, -42, -31, -23, -17, -7, 5, 17, 24, 26, 22, 19, 19, 20, 17, 11, 5, 2, 2, 0, -4, -10, -14, -14, -10, -8, -6, 1, 10, 19, 23, 22, 17, 16, 19, 18, 11, 1, -8, -11, -10, -7, -4, 1, 7, 15, 22, 22, 18, 17, 16, 12, 4, -8, -21, -29, -34, -39, -46, -49, -46, -37, -28, -19, -9, -2, 8, 19, 22, 20, 18, 18, 19, 19, 12, 6, 3, 2, 0, -5, -10, -16, -18, -14, -9, -8, -3, 6, 17, 25, 27, 26, 24, 25, 22, 15, 3, -8, -13, -13, -12, -11, -6, 0, 9, 16, 19, 19, 16, 13, 10, 6, -5, -14, -22, -26, -32, -37, -41, -39, -32, -23, -17, -14, -10, -3, 9, 17, 18, 10, 7, 10, 16, 18, 12, 5, 1, 1, -4, -13, -18, -18, -15, -12, -11, -10, 1, 15, 29, 37, 35, 31, 30, 30, 24, 11, -8, -18, -18, -15, -17, -20, -17, -6, 8, 15, 18, 16, 15, 11, 12, 8, 0, -10, -16, -20, -28, -35, -38, -33, -27, -23, -21, -19, -13, 0, 11, 14, 12, 9, 11, 18, 21, 19, 10, 2, -3, -5, -12, -21, -28, -26, -20, -15, -12, -6, 9, 25, 38, 43, 42, 40, 38, 34, 23, 6, -12, -18, -18, -18, -23, -25, -22, -13, 0, 7, 9, 8, 8, 11, 12, 9, 6, 2, -5, -14, -21, -24, -24, -22, -22, -21, -22, -20, -12, -3, 4, 5, 5, 6, 11, 15, 16, 10, 4, -2, -7, -11, -20, -25, -27, -21, -13, -11, -5, 6, 22, 37, 46, 50, 49, 44, 39, 31, 16, -3, -15, -21, -24, -27, -32, -33, -28, -17, -5, 5, 7, 7, 10, 15, 16, 15, 10, 4, -4, -11, -18, -22, -22, -20, -22, -21, -21, -17, -10, 1, 6, 9, 10, 15, 19, 18, 12, 5, 0, -9, -15, -23, -31, -36, -32, -24, -17, -11, -4, 12, 31, 47, 53, 58, 60, 56, 49, 35, 15, -4, -16, -21, -25, -32, -42, -45, -35, -23, -14, -8, 0, 6, 13, 20, 21, 19, 15, 9, 1, -6, -11, -13, -16, -18, -20, -23, -20, -14, -8, 0, 2, 5, 11, 18, 18, 14, 6, -2, -10, -18, -27, -34, -41, -40, -31, -20, -12, -7, 4, 23, 47, 64, 71, 71, 63, 56, 46, 30, 12, -7, -22, -35, -42, -49, -52, -48, -34, -22, -14, -7, 3, 15, 24, 27, 27, 24, 15, 6, -4, -8, -11, -13, -13, -15, -16, -14, -12, -7, -2, 3, 10, 12, 14, 15, 7, 0, -7, -16, -25, -32, -40, -44, -44, -36, -24, -11, 0, 6, 16, 36, 58, 72, 76, 71, 62, 51, 38, 24, 5, -13, -30, -42, -50, -52, -53, -46, -33, -21, -15, -6, 7, 20, 25, 25, 21, 18, 14, 7, 2, -5, -9, -9, -7, -8, -9, -10, -7, -3, 1, 6, 7, 8, 9, 6, -2, -13, -23, -30, -35, -41, -45, -44, -38, -26, -15, -3, 11, 19, 33, 52, 69, 75, 72, 65, 54, 42, 29, 13, -6, -25, -41, -49, -54, -55, -48, -38, -26, -18, -8, 1, 13, 24, 29, 26, 19, 11, 5, 2, -2, -6, -6, -6, -5, -7, -5, 1, 5, 9, 11, 8, 8, 7, 4, -6, -17, -28, -35, -42, -47, -48, -45, -39, -29, -16, -5, 7, 18, 32, 45, 57, 64, 67, 62, 54, 45, 35, 22, 5, -13, -28, -40, -47, -49, -46, -42, -32, -21, -11, -4, 6, 15, 21, 21, 16, 12, 6, 1, -3, -5, -3, 3, 8, 9, 8, 7, 7, 11, 12, 11, 6, -2, -9, -13, -20, -29, -40, -47, -47, -45, -42, -37, -29, -16, -5, 7, 17, 27, 38, 48, 56, 59, 53, 44, 40, 37, 30, 17, -2, -16, -25, -32, -35, -36, -35, -31, -23, -16, -10, -3, 4, 10, 11, 8, 1, 0, 0, 0, 0, 1, 6, 14, 20, 21, 19, 15, 14, 13, 11, 7, 0, -13, -21, -28, -37, -46, -51, -48, -43, -37, -32, -28, -21, -9, 4, 17, 27, 32, 40, 45, 50, 51, 46, 40, 38, 35, 27, 12, -3, -13, -23, -27, -29, -30, -29, -28, -23, -15, -10, -5, 2, 5, 5, 1, -2, -2, 1, 4, 4, 8, 14, 19, 25, 26, 21, 15, 13, 12, 12, 5, -9, -21, -30, -37, -43, -50, -51, -47, -42, -38, -34, -27, -17, -5, 10, 22, 30, 38, 44, 49, 50, 46, 40, 37, 38, 33, 19, 4, -8, -14, -18, -22, -24, -24, -22, -18, -16, -14, -10, -6, 1, 1, -6, -8, -9, -6, 0, 2, 8, 14, 21, 28, 31, 27, 24, 21, 20, 16, 9, -3, -16, -26, -33, -42, -50, -55, -56, -50, -43, -39, -38, -29, -13, 6, 18, 27, 33, 42, 51, 54, 53, 48, 41, 39, 38, 29, 12, -5, -15, -19, -20, -23, -24, -22, -18, -17, -13, -12, -10, -4, -3, -4, -7, -8, -9, -9, -7, 2, 9, 14, 21, 26, 27, 27, 22, 20, 19, 17, 12, 1, -14, -25, -35, -41, -45, -50, -53, -54, -51, -47, -41, -31, -18, -3, 12, 24, 35, 47, 55, 58, 57, 55, 49, 46, 40, 26, 11, -5, -17, -22, -23, -23, -22, -21, -21, -18, -15, -9, -5, -3, -4, -6, -7, -9, -12, -12, -8, 1, 7, 13, 14, 19, 23, 27, 26, 25, 25, 20, 13, 4, -9, -22, -36, -42, -48, -55, -61, -62, -59, -54, -43, -32, -18, 0, 18, 35, 49, 57, 60, 62, 63, 61, 57, 48, 33, 15, -2, -15, -24, -28, -27, -22, -23, -24, -21, -13, -4, 3, 3, 1, -2, -4, -4, -9, -15, -16, -13, -9, -5, 2, 7, 11, 19, 24, 28, 31, 29, 28, 24, 12, -4, -21, -33, -38, -48, -61, -72, -76, -71, -61, -47, -34, -20, 2, 26, 45, 58, 65, 69, 74, 75, 68, 55, 41, 28, 13, -7, -22, -32, -32, -29, -24, -23, -22, -19, -7, 6, 7, 2, -2, -3, 0, -3, -10, -20, -24, -19, -12, -5, 1, 5, 14, 23, 30, 33, 37, 39, 36, 24, 8, -10, -25, -33, -43, -55, -71, -82, -82, -71, -57, -44, -29, -11, 13, 34, 52, 64, 70, 73, 77, 76, 65, 50, 35, 20, 4, -13, -26, -31, -32, -27, -26, -25, -21, -10, 2, 8, 5, 3, 0, 1, 2, -3, -12, -22, -24, -21, -16, -9, -3, 6, 14, 22, 28, 34, 41, 42, 35, 23, 6, -10, -21, -32, -45, -61, -76, -85, -82, -70, -54, -43, -29, -7, 18, 40, 55, 64, 71, 77, 81, 76, 62, 48, 32, 19, 6, -10, -23, -30, -29, -28, -30, -27, -20, -10, -2, 3, 1, 0, 3, 6, 4, -9, -18, -24, -22, -18, -14, -8, 0, 8, 16, 24, 32, 38, 42, 42, 31, 15, -2, -14, -25, -38, -52, -67, -81, -85, -76, -63, -49, -37, -19, 3, 26, 43, 57, 67, 75, 82, 79, 70, 56, 41, 28, 15, 1, -12, -22, -27, -27, -28, -26, -21, -12, -3, 3, -2, -2, 1, 3, 1, -12, -22, -28, -29, -27, -23, -18, -11, 3, 16, 25, 34, 44, 51, 52, 43, 27, 12, -2, -17, -34, -51, -71, -82, -86, -83, -75, -61, -45, -27, -7, 16, 37, 53, 63, 72, 78, 77, 68, 60, 45, 33, 20, 10, -2, -9, -15, -18, -22, -23, -19, -15, -8, -5, -7, -8, -7, -4, -3, -10, -22, -29, -29, -24, -21, -18, -14, -3, 12, 23, 27, 35, 44, 49, 47, 34, 18, 1, -11, -23, -40, -57, -73, -81, -80, -74, -64, -50, -36, -19, 2, 22, 38, 49, 61, 69, 74, 69, 60, 50, 40, 29, 20, 10, 2, -5, -9, -12, -16, -18, -14, -9, -6, -10, -13, -12, -10, -11, -15, -23, -30, -31, -27, -25, -23, -19, -8, 8, 20, 28, 36, 45, 49, 49, 41, 29, 15, -2, -15, -31, -49, -65, -76, -79, -77, -67, -55, -43, -30, -13, 7, 25, 40, 51, 60, 66, 66, 62, 54, 45, 37, 29, 22, 14, 7, 3, -3, -7, -10, -12, -10, -8, -12, -18, -19, -16, -13, -15, -23, -31, -33, -29, -26, -25, -23, -15, 1, 14, 23, 31, 40, 50, 52, 46, 36, 21, 7, -8, -24, -41, -58, -70, -75, -74, -67, -57, -43, -30, -18, -3, 13, 26, 39, 48, 56, 60, 58, 51, 45, 42, 36, 29, 25, 20, 14, 9, 6, 3, 0, -5, -6, -12, -17, -22, -21, -20, -24, -33, -37, -38, -35, -30, -28, -24, -17, -3, 12, 24, 33, 43, 50, 52, 49, 40, 28, 13, -3, -18, -34, -51, -63, -71, -72, -67, -59, -49, -37, -24, -10, 3, 16, 27, 37, 46, 50, 53, 51, 49, 46, 43, 37, 32, 29, 25, 21, 17, 10, 4, -3, -8, -10, -11, -18, -25, -29, -31, -34, -37, -40, -40, -37, -31, -25, -20, -13, 0, 17, 31, 41, 48, 50, 49, 46, 36, 22, 8, -5, -20, -36, -49, -61, -67, -67, -61, -51, -44, -36, -23, -9, 4, 13, 20, 30, 38, 46, 48, 47, 44, 44, 44, 46, 42, 35, 31, 28, 24, 15, 5, -3, -6, -10, -18, -28, -35, -39, -41, -41, -43, -45, -42, -36, -29, -23, -15, 1, 15, 28, 40, 47, 51, 51, 46, 37, 27, 14, 2, -14, -29, -42, -49, -54, -62, -63, -57, -49, -41, -31, -21, -12, -3, 6, 17, 25, 32, 40, 45, 49, 50, 48, 49, 49, 48, 44, 39, 34, 26, 13, 4, -4, -11, -17, -23, -32, -41, -48, -48, -49, -48, -44, -39, -36, -31, -21, -5, 13, 24, 35, 44, 51, 52, 47, 39, 30, 21, 8, -6, -18, -34, -44, -50, -54, -59, -58, -53, -46, -38, -28, -18, -10, -4, 6, 16, 24, 30, 37, 42, 48, 49, 47, 48, 51, 51, 49, 45, 35, 27, 17, 9, 0, -12, -23, -32, -41, -48, -53, -55, -54, -53, -49, -43, -38, -27, -13, 5, 20, 33, 44, 52, 58, 57, 50, 40, 29, 16, 5, -11, -29, -43, -53, -56, -62, -65, -63, -54, -42, -33, -24, -16, -8, 3, 16, 23, 29, 33, 38, 44, 46, 45, 43, 45, 49, 52, 48, 42, 37, 28, 19, 10, 0, -13, -25, -36, -42, -47, -56, -58, -56, -53, -49, -48, -40, -26, -6, 13, 27, 39, 49, 59, 64, 62, 53, 42, 29, 16, 2, -18, -37, -52, -60, -65, -71, -75, -68, -55, -41, -30, -19, -10, 0, 14, 24, 33, 37, 38, 39, 42, 45, 45, 43, 45, 48, 47, 46, 41, 35, 28, 19, 8, -6, -20, -30, -38, -44, -50, -55, -57, -59, -57, -53, -46, -35, -19, 0, 17, 32, 45, 59, 66, 66, 59, 54, 46, 32, 15, -5, -24, -43, -57, -65, -71, -76, -78, -71, -58, -41, -27, -16, -5, 5, 15, 27, 37, 43, 43, 42, 42, 42, 43, 46, 46, 46, 45, 42, 41, 35, 28, 18, 7, -6, -18, -29, -37, -44, -51, -56, -59, -61, -60, -55, -45, -33, -18, -2, 18, 37, 50, 61, 67, 68, 65, 59, 47, 31, 10, -11, -32, -47, -58, -71, -81, -86, -83, -70, -52, -36, -21, -9, 2, 13, 25, 35, 41, 44, 43, 40, 39, 39, 40, 43, 43, 40, 39, 40, 40, 36, 28, 18, 9, -5, -18, -28, -36, -44, -52, -57, -61, -64, -63, -56, -43, -27, -13, 6, 26, 44, 56, 66, 71, 71, 64, 55, 42, 23, 3, -19, -38, -52, -66, -76, -82, -86, -81, -67, -49, -32, -19, -8, 3, 15, 28, 36, 42, 43, 43, 41, 41, 40, 40, 41, 40, 40, 41, 41, 36, 30, 24, 17, 10, -5, -19, -29, -37, -43, -50, -57, -64, -66, -60, -50, -40, -28, -10, 12, 32, 45, 54, 59, 64, 67, 63, 54, 35, 14, -6, -22, -35, -50, -64, -75, -82, -81, -73, -59, -46, -33, -21, -8, 5, 19, 27, 33, 40, 44, 44, 42, 40, 42, 41, 40, 38, 39, 38, 38, 35, 30, 21, 13, 4, -8, -16, -25, -35, -45, -53, -62, -65, -63, -56, -47, -39, -25, -6, 15, 32, 45, 53, 58, 64, 65, 60, 48, 30, 9, -7, -19, -31, -47, -60, -72, -79, -79, -73, -61, -50, -37, -24, -10, 3, 12, 22, 33, 43, 47, 46, 44, 43, 45, 46, 45, 45, 43, 41, 38, 34, 26, 16, 7, -2, -10, -19, -29, -39, -50, -59, -64, -62, -58, -51, -44, -34, -22, -2, 16, 30, 41, 52, 56, 57, 58, 54, 42, 29, 13, 2, -12, -27, -42, -56, -67, -71, -73, -70, -63, -55, -42, -26, -10, 2, 11, 20, 33, 41, 46, 45, 43, 49, 53, 52, 48, 44, 43, 42, 38, 33, 22, 12, 4, -5, -13, -23, -34, -43, -50, -57, -61, -60, -55, -49, -40, -29, -14, -2, 12, 25, 35, 44, 51, 56, 56, 49, 39, 30, 20, 10, -2, -17, -32, -48, -60, -67, -74, -77, -74, -66, -50, -36, -21, -9, 0, 14, 30, 43, 51, 53, 57, 62, 64, 62, 58, 53, 48, 42, 36, 25, 12, 4, -4, -12, -21, -31, -38, -43, -45, -47, -49, -47, -44, -40, -34, -28, -22, -11, 1, 11, 21, 28, 39, 49, 53, 52, 49, 44, 38, 29, 16, -4, -24, -41, -57, -74, -86, -90, -86, -73, -59, -44, -30, -16, 1, 21, 40, 54, 61, 66, 67, 71, 72, 65, 57, 49, 41, 33, 24, 12, 1, -8, -12, -15, -22, -31, -37, -35, -31, -33, -36, -39, -40, -38, -34, -32, -29, -24, -14, -2, 11, 24, 36, 48, 56, 61, 63, 59, 54, 44, 27, 6, -19, -46, -68, -84, -94, -99, -98, -90, -72, -51, -30, -15, 1, 22, 46, 64, 76, 78, 80, 81, 78, 72, 60, 45, 34, 24, 13, 0, -13, -18, -18, -18, -22, -28, -29, -24, -19, -19, -26, -33, -38, -40, -40, -41, -42, -41, -32, -15, 6, 22, 37, 50, 62, 74, 79, 76, 65, 50, 30, 6, -24, -54, -78, -94, -106, -110, -103, -89, -69, -49, -29, -10, 11, 36, 57, 73, 78, 80, 82, 83, 77, 66, 51, 37, 24, 14, 5, -5, -12, -17, -17, -17, -18, -19, -17, -13, -13, -19, -28, -37, -44, -44, -48, -53, -59, -54, -35, -12, 11, 29, 46, 61, 78, 88, 90, 84, 68, 49, 24, -6, -39, -71, -92, -104, -115, -116, -108, -89, -66, -43, -21, 1, 24, 49, 68, 78, 82, 81, 81, 79, 71, 56, 37, 24, 15, 6, -4, -9, -11, -9, -6, -6, -10, -11, -6, -4, -8, -20, -33, -44, -55, -61, -65, -70, -68, -55, -31, -6, 15, 38, 61, 82, 97, 101, 94, 80, 61, 37, 9, -25, -60, -88, -107, -119, -123, -116, -99, -77, -53, -30, -5, 20, 47, 68, 80, 82, 82, 80, 77, 70, 57, 40, 23, 10, 3, -2, -3, -4, -3, 2, 5, 7, 5, 5, 4, -4, -17, -32, -45, -60, -69, -74, -79, -80, -70, -47, -20, 9, 32, 55, 76, 94, 104, 103, 91, 71, 46, 16, -16, -48, -75, -97, -115, -121, -117, -101, -80, -57, -32, -8, 15, 39, 58, 68, 73, 73, 73, 69, 61, 50, 39, 26, 15, 7, 4, 7, 12, 18, 19, 20, 18, 17, 15, 10, -4, -20, -41, -57, -68, -77, -85, -91, -90, -76, -53, -25, 2, 28, 55, 79, 97, 106, 104, 94, 77, 52, 22, -9, -39, -67, -92, -111, -119, -115, -99, -79, -55, -33, -11, 15, 37, 55, 67, 71, 68, 61, 51, 44, 40, 35, 24, 10, 3, 4, 13, 25, 36, 42, 41, 34, 29, 20, 12, -2, -21, -43, -66, -84, -94, -96, -96, -93, -81, -55, -26, 4, 30, 56, 80, 98, 107, 106, 95, 77, 53, 24, -8, -38, -64, -85, -101, -109, -109, -100, -80, -55, -31, -8, 13, 31, 46, 56, 61, 59, 52, 43, 36, 30, 25, 16, 8, 7, 11, 23, 37, 48, 56, 59, 56, 48, 33, 17, -5, -29, -54, -79, -96, -106, -109, -105, -96, -82, -57, -25, 8, 38, 61, 79, 94, 103, 102, 92, 73, 46, 19, -10, -36, -62, -81, -95, -101, -100, -90, -71, -47, -25, -3, 18, 31, 41, 49, 53, 50, 42, 32, 21, 13, 9, 7, 8, 8, 12, 30, 49, 63, 71, 76, 75, 67, 48, 25, -3, -30, -59, -87, -107, -120, -124, -117, -105, -89, -63, -31, 5, 40, 63, 81, 92, 100, 100, 88, 69, 46, 20, -6, -31, -55, -73, -87, -91, -88, -80, -64, -45, -22, 1, 16, 27, 34, 39, 45, 41, 31, 20, 9, 4, 3, 1, 3, 6, 15, 32, 53, 71, 81, 85, 86, 78, 61, 35, 3, -29, -63, -93, -113, -124, -128, -124, -110, -89, -64, -32, 5, 38, 62, 80, 91, 98, 93, 80, 63, 42, 19, -5, -29, -51, -68, -78, -81, -79, -72, -58, -40, -19, 0, 13, 21, 29, 35, 35, 29, 21, 14, 8, 2, -2, -3, 1, 10, 20, 36, 56, 73, 84, 89, 89, 81, 65, 41, 6, -32, -63, -90, -110, -124, -127, -123, -110, -89, -61, -30, 2, 33, 56, 71, 81, 86, 85, 74, 58, 38, 17, -5, -21, -38, -52, -62, -69, -69, -64, -50, -34, -18, -5, 5, 13, 23, 28, 27, 22, 15, 10, 6, 1, 0, -2, 2, 9, 23, 41, 56, 72, 84, 88, 89, 81, 66, 45, 15, -20, -55, -84, -106, -119, -121, -116, -105, -89, -67, -38, -7, 21, 44, 58, 69, 75, 74, 64, 50, 36, 22, 8, -10, -26, -39, -47, -54, -56, -53, -47, -36, -25, -11, -2, 5, 14, 23, 24, 20, 12, 7, 6, 6, 6, 4, 5, 10, 22, 39, 57, 72, 80, 82, 80, 73, 62, 45, 18, -13, -48, -78, -96, -105, -105, -104, -97, -81, -64, -40, -15, 10, 28, 40, 49, 54, 53, 49, 42, 31, 22, 13, 2, -9, -17, -22, -30, -38, -40, -37, -33, -28, -22, -16, -10, -5, 5, 11, 11, 6, 3, 5, 11, 16, 16, 18, 22, 29, 40, 54, 68, 75, 74, 72, 63, 49, 35, 15, -10, -37, -63, -83, -94, -95, -89, -82, -73, -63, -46, -24, -2, 16, 25, 31, 35, 39, 41, 37, 30, 22, 15, 11, 4, -3, -11, -18, -25, -31, -35, -33, -28, -22, -18, -16, -13, -4, 5, 10, 11, 10, 5, 6, 14, 21, 23, 24, 27, 33, 45, 59, 68, 72, 67, 57, 46, 34, 19, 0, -24, -49, -70, -81, -82, -77, -70, -65, -60, -49, -34, -15, 2, 9, 13, 14, 18, 20, 21, 19, 18, 17, 16, 15, 13, 10, 5, -3, -12, -20, -26, -28, -27, -24, -26, -25, -18, -9, 3, 9, 10, 10, 11, 18, 27, 32, 33, 33, 35, 42, 51, 58, 59, 55, 46, 36, 25, 16, 3, -15, -33, -50, -61, -65, -64, -59, -57, -56, -52, -42, -29, -14, -5, -2, -3, 1, 8, 12, 13, 13, 16, 16, 18, 19, 19, 14, 4, -3, -10, -19, -24, -24, -22, -20, -24, -23, -16, -2, 10, 16, 14, 13, 16, 28, 35, 36, 35, 32, 33, 40, 45, 49, 47, 41, 31, 20, 12, 4, -8, -16, -29, -41, -50, -53, -50, -49, -51, -51, -48, -40, -30, -20, -13, -13, -12, -6, 2, 8, 12, 13, 16, 21, 26, 27, 23, 15, 8, 0, -10, -19, -23, -24, -24, -26, -25, -21, -9, 5, 15, 19, 20, 22, 28, 36, 39, 38, 36, 33, 33, 35, 37, 38, 36, 30, 20, 9, 4, -3, -10, -17, -26, -35, -40, -45, -47, -51, -52, -49, -46, -39, -30, -23, -19, -17, -12, -5, 1, 4, 7, 11, 18, 22, 22, 22, 20, 17, 12, 3, -8, -16, -18, -16, -17, -19, -18, -12, 3, 13, 19, 20, 24, 29, 34, 35, 33, 32, 31, 31, 30, 26, 24, 24, 25, 21, 14, 6, 0, -4, -5, -10, -19, -31, -37, -40, -47, -51, -50, -49, -45, -39, -31, -25, -19, -12, -6, -3, 0, 2, 6, 13, 17, 18, 16, 15, 16, 14, 7, -3, -10, -12, -13, -13, -14, -13, -6, 6, 18, 24, 25, 26, 29, 33, 32, 26, 24, 23, 23, 22, 18, 14, 15, 21, 24, 22, 14, 6, 4, 4, 1, -9, -21, -32, -41, -47, -50, -54, -54, -51, -47, -37, -30, -21, -10, -3, 1, 4, 6, 7, 8, 7, 7, 7, 7, 6, 6, 5, 2, -3, -8, -8, -6, -3, 1, 3, 9, 17, 25, 29, 32, 33, 29, 26, 24, 23, 20, 17, 14, 11, 8, 8, 14, 21, 22, 17, 13, 9, 9, 7, 1, -11, -25, -37, -44, -52, -53, -55, -55, -51, -43, -35, -24, -14, -4, 3, 4, 4, 6, 7, 6, 3, -2, -2, 2, 6, 5, 1, -4, -8, -7, -5, 3, 9, 9, 12, 17, 25, 32, 37, 37, 32, 25, 21, 19, 17, 15, 9, 6, 6, 6, 8, 14, 23, 24, 20, 15, 14, 11, 3, -6, -18, -31, -44, -53, -54, -57, -58, -55, -47, -37, -26, -16, -4, 7, 10, 10, 9, 7, 3, -2, -6, -8, -6, -5, -4, -7, -10, -8, -6, 0, 6, 12, 16, 20, 27, 33, 35, 35, 36, 34, 28, 21, 16, 10, 7, 7, 5, 3, 1, 5, 12, 21, 25, 23, 17, 14, 13, 9, -3, -17, -30, -41, -50, -54, -59, -61, -55, -46, -37, -26, -15, -4, 7, 14, 15, 12, 6, 1, -3, -7, -12, -14, -15, -13, -12, -12, -12, -8, 0, 8, 15, 20, 25, 31, 36, 40, 41, 41, 38, 33, 27, 21, 12, 4, 1, 0, -4, -5, -2, 5, 12, 17, 19, 19, 18, 14, 11, 2, -9, -21, -32, -42, -49, -55, -57, -56, -49, -39, -30, -20, -8, 3, 12, 17, 18, 12, 5, -2, -8, -14, -18, -21, -22, -21, -21, -19, -13, -7, 4, 14, 24, 32, 39, 44, 48, 47, 44, 41, 38, 33, 27, 17, 7, -3, -5, -5, -5, -5, -5, 3, 12, 17, 19, 16, 11, 7, 3, -6, -15, -26, -36, -42, -48, -53, -54, -50, -40, -31, -22, -12, -2, 11, 19, 20, 13, 6, 2, -5, -12, -21, -26, -29, -31, -30, -27, -21, -13, -2, 12, 25, 36, 48, 57, 62, 60, 51, 46, 43, 37, 28, 15, 3, -8, -12, -14, -12, -10, -7, -4, 8, 16, 20, 17, 14, 10, 6, -2, -12, -24, -32, -39, -45, -51, -54, -52, -43, -32, -21, -12, -2, 11, 22, 28, 24, 13, 4, -6, -14, -23, -32, -38, -41, -42, -39, -31, -20, -8, 6, 21, 37, 50, 63, 69, 68, 61, 55, 48, 39, 29, 20, 9, -6, -15, -17, -13, -11, -7, -4, 3, 11, 13, 16, 15, 10, 5, 0, -8, -15, -25, -31, -37, -42, -49, -52, -46, -37, -30, -21, -12, 0, 14, 25, 28, 25, 15, 2, -11, -22, -29, -36, -44, -49, -49, -43, -32, -18, -5, 13, 30, 50, 66, 74, 75, 71, 68, 61, 50, 37, 26, 15, 3, -13, -22, -22, -20, -16, -14, -9, 1, 9, 11, 11, 9, 9, 9, 6, -3, -15, -25, -32, -37, -41, -50, -53, -50, -41, -30, -20, -8, 6, 21, 31, 33, 26, 15, 0, -12, -23, -34, -46, -56, -60, -54, -44, -31, -19, -2, 21, 44, 66, 77, 81, 79, 75, 72, 63, 51, 35, 23, 10, -4, -16, -25, -28, -26, -22, -16, -12, -7, -2, 4, 8, 10, 14, 14, 7, -3, -12, -20, -28, -36, -42, -48, -53, -53, -43, -31, -19, -6, 12, 25, 31, 30, 26, 15, -2, -17, -28, -40, -52, -60, -61, -53, -40, -25, -9, 11, 32, 56, 74, 84, 85, 81, 76, 72, 61, 46, 29, 13, -2, -16, -23, -29, -33, -31, -25, -19, -14, -8, 2, 10, 14, 18, 19, 17, 8, 1, -12, -24, -35, -42, -49, -54, -57, -53, -43, -30, -13, 7, 22, 32, 34, 32, 26, 11, -8, -24, -40, -50, -60, -66, -63, -53, -36, -17, 2, 23, 45, 67, 84, 90, 91, 85, 78, 72, 62, 44, 24, 4, -9, -21, -32, -39, -41, -36, -30, -23, -17, -9, 2, 13, 23, 27, 26, 19, 12, 2, -12, -26, -38, -47, -54, -59, -59, -53, -41, -23, -5, 14, 28, 36, 36, 31, 21, 6, -13, -31, -46, -58, -66, -70, -65, -50, -28, -7, 14, 35, 58, 76, 89, 96, 94, 90, 82, 72, 54, 35, 16, -5, -21, -31, -40, -48, -47, -38, -28, -20, -13, 1, 15, 28, 33, 33, 27, 18, 8, -6, -21, -37, -52, -64, -66, -65, -58, -47, -30, -9, 13, 28, 38, 43, 40, 31, 15, -5, -24, -40, -57, -69, -75, -74, -65, -48, -26, -2, 24, 47, 66, 83, 97, 102, 102, 101, 91, 73, 51, 28, 7, -15, -33, -45, -56, -60, -54, -42, -28, -17, -4, 13, 26, 36, 38, 36, 29, 16, 2, -14, -34, -52, -62, -66, -65, -63, -53, -36, -15, 9, 27, 36, 41, 40, 35, 25, 8, -16, -37, -55, -68, -77, -81, -75, -60, -37, -12, 12, 35, 57, 75, 94, 105, 107, 103, 97, 84, 64, 41, 18, -6, -25, -40, -51, -57, -56, -46, -32, -19, -6, 7, 20, 30, 34, 32, 24, 12, 0, -17, -33, -47, -60, -65, -64, -58, -46, -31, -12, 8, 26, 37, 43, 44, 41, 28, 11, -12, -31, -49, -67, -81, -87, -85, -72, -52, -30, -6, 21, 45, 69, 87, 101, 110, 113, 110, 100, 77, 51, 27, 8, -11, -32, -49, -59, -59, -53, -41, -27, -11, 3, 14, 24, 28, 28, 24, 17, 5, -15, -32, -45, -54, -61, -58, -54, -44, -32, -13, 8, 26, 37, 41, 40, 36, 29, 16, -3, -24, -47, -66, -81, -89, -88, -76, -58, -37, -16, 10, 34, 58, 78, 94, 106, 111, 107, 97, 81, 58, 37, 17, 0, -17, -33, -45, -51, -48, -38, -26, -14, -3, 9, 16, 19, 17, 14, 10, 0, -15, -30, -42, -49, -52, -49, -44, -37, -25, -8, 9, 21, 29, 32, 35, 33, 29, 19, 1, -18, -38, -58, -75, -85, -85, -79, -70, -52, -29, -6, 20, 44, 67, 89, 101, 110, 114, 107, 93, 72, 49, 28, 10, -9, -25, -38, -48, -49, -42, -31, -20, -11, 0, 9, 13, 12, 7, 5, 0, -11, -24, -36, -42, -44, -43, -38, -28, -16, -4, 8, 16, 22, 29, 30, 29, 24, 13, 2, -14, -32, -51, -68, -79, -83, -77, -69, -56, -41, -19, 6, 31, 53, 74, 90, 101, 108, 109, 101, 83, 60, 38, 24, 9, -10, -25, -36, -40, -37, -29, -21, -13, -8, 0, 3, 0, -5, -6, -8, -16, -27, -35, -39, -40, -33, -27, -21, -11, 3, 14, 21, 24, 27, 26, 22, 19, 13, 3, -14, -32, -53, -66, -74, -80, -80, -75, -63, -47, -28, -4, 19, 41, 66, 85, 99, 105, 106, 104, 95, 76, 51, 29, 13, 2, -12, -27, -36, -38, -32, -22, -15, -12, -8, -3, -4, -9, -12, -14, -18, -26, -31, -35, -36, -29, -20, -10, -2, 7, 16, 25, 25, 24, 19, 15, 10, 4, -4, -16, -30, -44, -57, -67, -73, -75, -70, -60, -48, -34, -16, 5, 27, 51, 71, 85, 92, 99, 101, 95, 82, 64, 44, 28, 14, 1, -12, -22, -28, -27, -22, -18, -17, -15, -15, -15, -21, -23, -25, -24, -27, -31, -34, -30, -21, -6, 7, 13, 17, 22, 27, 28, 24, 16, 7, -3, -10, -17, -27, -35, -43, -50, -58, -68, -70, -65, -53, -42, -32, -22, -4, 15, 36, 54, 70, 83, 89, 92, 91, 82, 68, 54, 42, 29, 14, 2, -9, -17, -21, -22, -20, -21, -20, -23, -26, -30, -32, -32, -29, -27, -28, -30, -26, -15, 0, 15, 25, 25, 25, 26, 27, 21, 11, 0, -9, -17, -24, -30, -38, -45, -47, -49, -55, -59, -56, -48, -39, -28, -20, -9, 7, 26, 44, 55, 65, 72, 79, 80, 77, 66, 57, 49, 41, 30, 19, 7, -2, -7, -12, -17, -22, -25, -29, -33, -36, -39, -41, -36, -29, -26, -26, -22, -11, 2, 17, 28, 32, 31, 29, 28, 23, 11, -2, -9, -17, -24, -36, -44, -48, -49, -50, -53, -54, -54, -47, -36, -25, -17, -7, 7, 21, 36, 47, 55, 63, 70, 72, 69, 60, 52, 46, 42, 34, 23, 15, 8, 3, 0, -7, -14, -21, -24, -27, -32, -39, -44, -43, -37, -29, -25, -23, -16, -2, 14, 26, 32, 33, 32, 30, 25, 16, 4, -6, -16, -25, -36, -45, -50, -54, -51, -51, -54, -54, -48, -36, -23, -15, -6, 5, 17, 31, 42, 51, 59, 62, 63, 61, 56, 51, 43, 40, 38, 28, 20, 13, 9, 7, 2, -8, -16, -23, -27, -31, -36, -40, -43, -39, -31, -23, -20, -15, -4, 11, 24, 31, 32, 31, 30, 25, 17, 7, -3, -13, -23, -36, -48, -56, -58, -57, -53, -50, -52, -51, -40, -25, -12, 0, 7, 16, 25, 36, 49, 58, 60, 59, 57, 54, 49, 43, 36, 31, 26, 18, 13, 10, 6, 4, 0, -6, -12, -19, -22, -26, -31, -35, -35, -32, -27, -22, -16, -7, 4, 13, 21, 26, 30, 29, 27, 22, 15, 4, -7, -19, -31, -44, -55, -59, -59, -58, -54, -52, -49, -41, -28, -14, 0, 10, 18, 26, 33, 44, 50, 53, 51, 50, 48, 46, 41, 37, 30, 24, 21, 18, 15, 13, 8, 4, 0, -6, -9, -14, -19, -23, -27, -33, -33, -31, -25, -19, -11, -3, 3, 11, 20, 28, 31, 28, 22, 14, 8, -3, -15, -29, -40, -49, -57, -62, -60, -56, -50, -47, -42, -32, -18, -3, 11, 20, 25, 29, 35, 43, 49, 51, 47, 43, 41, 37, 33, 29, 24, 18, 15, 14, 13, 11, 8, 5, 1, 0, -5, -11, -19, -23, -24, -25, -25, -26, -22, -15, -9, -3, 4, 12, 19, 25, 26, 24, 17, 11, 2, -11, -26, -37, -45, -53, -58, -59, -57, -53, -47, -42, -35, -25, -10, 5, 15, 19, 22, 29, 37, 45, 48, 47, 44, 44, 43, 40, 33, 24, 19, 14, 13, 12, 8, 2, -2, 1, 1, 1, -4, -12, -15, -14, -13, -14, -18, -18, -15, -12, -8, -5, 2, 10, 18, 21, 20, 15, 10, 3, -7, -18, -31, -42, -47, -50, -53, -57, -57, -51, -42, -34, -25, -15, -5, 7, 16, 22, 30, 35, 40, 43, 42, 39, 39, 38, 38, 31, 22, 16, 14, 15, 17, 16, 12, 6, 4, 5, 7, 6, 0, -8, -12, -13, -15, -19, -21, -20, -17, -14, -11, -6, 2, 10, 18, 21, 21, 19, 11, -2, -17, -29, -37, -42, -46, -52, -55, -58, -52, -42, -34, -24, -15, -5, 5, 12, 17, 24, 32, 37, 37, 36, 33, 33, 35, 35, 32, 26, 22, 16, 17, 19, 19, 14, 7, 5, 5, 6, 5, 0, -7, -10, -9, -6, -7, -13, -17, -15, -11, -8, -7, -6, 1, 7, 12, 13, 11, 7, 0, -12, -25, -35, -40, -42, -43, -44, -47, -49, -43, -34, -22, -12, -7, 0, 4, 9, 17, 25, 31, 33, 33, 31, 30, 27, 28, 30, 29, 25, 20, 17, 20, 24, 22, 17, 11, 10, 9, 9, 5, -6, -11, -13, -9, -5, -9, -16, -19, -16, -9, -6, -6, -2, 4, 8, 11, 11, 6, -4, -11, -21, -34, -39, -41, -40, -38, -40, -44, -38, -28, -17, -10, -6, -5, -3, 3, 10, 15, 17, 20, 23, 26, 25, 24, 26, 28, 30, 30, 28, 25, 24, 23, 25, 22, 18, 14, 9, 5, 0, -7, -12, -13, -12, -7, -6, -9, -12, -10, -4, 2, 2, 3, 3, 3, 6, 7, 3, -9, -21, -28, -35, -40, -40, -37, -37, -36, -36, -29, -22, -11, -3, 2, 3, 0, 1, 3, 6, 9, 10, 10, 10, 13, 16, 21, 24, 29, 31, 33, 33, 33, 32, 30, 27, 23, 16, 12, 7, -2, -7, -14, -19, -16, -10, -5, -7, -9, -9, -6, 2, 6, 8, 7, 4, 3, 1, -3, -9, -16, -25, -34, -39, -41, -37, -33, -31, -31, -29, -22, -12, -4, 2, 7, 5, 1, -2, 0, 4, 4, 2, 2, 5, 10, 14, 19, 24, 28, 32, 36, 38, 36, 34, 31, 27, 23, 18, 11, 3, -5, -12, -15, -15, -11, -6, -5, -6, -8, -7, -3, 1, 4, 6, 3, -2, -7, -9, -12, -19, -24, -30, -34, -36, -35, -32, -29, -26, -22, -16, -10, -3, 4, 8, 9, 4, 0, -3, 0, 1, -5, -7, -5, 1, 7, 13, 14, 17, 27, 35, 38, 37, 35, 33, 31, 29, 25, 19, 11, 3, 0, -6, -10, -10, -7, -5, -5, -7, -7, -6, -3, 1, 4, 3, 0, -8, -15, -18, -20, -23, -27, -30, -32, -33, -29, -28, -25, -20, -16, -13, -6, 1, 6, 7, 4, 0, -5, -5, -5, -6, -7, -6, -2, 5, 10, 15, 20, 25, 32, 34, 34, 34, 32, 29, 24, 22, 19, 14, 9, 6, 4, 2, 0, 0, 2, 2, -2, -4, -6, -5, -5, -4, -4, -7, -12, -19, -25, -26, -26, -26, -26, -29, -28, -28, -25, -22, -18, -14, -10, -5, 0, 3, 4, 5, 4, 3, -2, -7, -10, -12, -9, -6, 0, 6, 11, 14, 16, 22, 30, 33, 34, 29, 25, 23, 21, 22, 22, 20, 18, 16, 14, 13, 11, 11, 11, 6, -4, -12, -16, -17, -16, -13, -16, -22, -26, -30, -30, -25, -21, -18, -17, -19, -18, -20, -19, -15, -13, -9, -7, -6, -5, -2, 3, 5, 4, 0, -5, -8, -6, -6, -6, -2, 4, 9, 11, 13, 15, 19, 23, 25, 22, 19, 16, 17, 20, 21, 22, 23, 24, 25, 24, 23, 22, 21, 16, 7, -4, -14, -21, -23, -24, -24, -28, -34, -38, -36, -31, -21, -13, -9, -8, -10, -11, -12, -14, -13, -12, -9, -10, -12, -11, -9, -4, 3, 4, 1, -3, -4, 1, 4, 7, 10, 10, 11, 12, 11, 8, 9, 11, 13, 11, 5, 4, 11, 20, 26, 29, 32, 35, 39, 39, 34, 30, 23, 15, 5, -10, -23, -31, -34, -32, -33, -37, -42, -41, -32, -21, -11, -6, -3, -3, -6, -8, -11, -14, -15, -14, -14, -14, -19, -20, -15, -7, 0, -2, -3, 0, 4, 10, 17, 19, 18, 18, 20, 18, 11, 5, 1, -2, -4, -7, -8, -4, 4, 14, 24, 32, 38, 46, 51, 52, 46, 37, 28, 19, 5, -12, -29, -39, -44, -46, -46, -50, -48, -39, -29, -14, -4, 6, 9, 8, 6, 0, -8, -13, -15, -18, -22, -28, -30, -26, -18, -9, -7, -4, 2, 10, 18, 24, 26, 26, 23, 22, 21, 14, 3, -5, -9, -14, -16, -16, -11, -4, 6, 14, 24, 37, 50, 58, 58, 53, 45, 36, 28, 17, 1, -18, -36, -47, -53, -54, -53, -51, -43, -33, -20, -8, 5, 15, 17, 13, 5, -4, -12, -14, -18, -23, -30, -34, -32, -24, -15, -10, -6, -3, 7, 18, 27, 32, 33, 30, 28, 24, 19, 12, 2, -10, -18, -24, -26, -23, -16, -6, 4, 12, 25, 39, 53, 60, 60, 58, 51, 42, 30, 16, 0, -20, -37, -49, -57, -61, -57, -50, -40, -29, -17, -4, 9, 17, 17, 11, 5, -3, -8, -13, -21, -30, -35, -34, -29, -22, -16, -11, -6, 1, 12, 24, 34, 39, 39, 35, 28, 21, 16, 8, -3, -16, -29, -35, -34, -26, -16, -9, 1, 14, 30, 46, 56, 60, 62, 59, 57, 46, 32, 15, -2, -17, -35, -51, -61, -61, -55, -46, -39, -30, -19, -4, 10, 14, 13, 7, 3, -2, -6, -15, -24, -31, -33, -31, -26, -23, -19, -11, -2, 6, 17, 30, 38, 41, 39, 34, 25, 18, 14, 6, -9, -24, -34, -38, -34, -28, -18, -9, 0, 14, 32, 44, 52, 58, 63, 66, 59, 45, 31, 18, 4, -17, -36, -53, -60, -59, -54, -46, -39, -30, -18, -3, 6, 8, 6, 3, 1, -3, -11, -22, -29, -28, -23, -20, -20, -18, -10, -2, 7, 17, 27, 34, 37, 38, 33, 26, 19, 15, 11, 0, -17, -31, -39, -40, -34, -27, -20, -11, 1, 16, 31, 43, 52, 59, 67, 70, 62, 47, 32, 19, 4, -18, -39, -53, -60, -57, -51, -44, -37, -30, -17, -6, 1, 2, 1, 0, -2, -7, -15, -23, -27, -25, -19, -16, -15, -12, -4, 5, 15, 25, 33, 37, 34, 31, 27, 22, 17, 11, 2, -11, -25, -35, -41, -41, -34, -23, -13, -4, 6, 18, 31, 43, 54, 61, 65, 62, 53, 44, 34, 22, 2, -20, -38, -47, -50, -47, -43, -42, -41, -32, -19, -13, -11, -10, -7, -5, -5, -9, -14, -18, -17, -12, -9, -8, -6, 1, 6, 12, 16, 21, 25, 25, 23, 19, 18, 14, 11, 8, 0, -10, -23, -34, -36, -32, -24, -16, -12, -6, 4, 15, 30, 42, 52, 59, 60, 58, 53, 46, 39, 27, 5, -19, -35, -43, -44, -43, -45, -49, -48, -39, -31, -27, -24, -19, -11, -6, -3, -4, -6, -8, -5, 3, 5, 7, 6, 7, 9, 12, 13, 15, 14, 12, 11, 11, 9, 8, 5, 4, 0, -12, -22, -28, -26, -21, -17, -13, -10, -5, 4, 14, 22, 32, 44, 56, 61, 59, 56, 48, 38, 25, 7, -10, -24, -33, -38, -44, -50, -51, -47, -41, -41, -41, -37, -26, -14, -6, 0, -2, -3, 5, 13, 19, 21, 16, 12, 9, 9, 10, 7, 3, 2, 2, 1, -2, 0, 3, 4, 1, -4, -12, -16, -16, -9, -9, -10, -9, -5, 2, 7, 11, 17, 27, 39, 51, 54, 52, 52, 49, 42, 28, 10, -4, -15, -25, -36, -48, -56, -58, -56, -52, -53, -54, -45, -28, -11, -2, 3, 8, 15, 24, 30, 34, 30, 22, 16, 12, 6, -4, -9, -9, -8, -12, -14, -12, -5, 3, 4, 2, -3, -4, 0, 3, 2, -4, -6, -6, -5, -4, -5, -3, 8, 21, 36, 44, 50, 55, 58, 55, 45, 33, 20, 5, -11, -27, -43, -55, -60, -61, -62, -64, -66, -58, -40, -20, -6, 3, 8, 16, 26, 34, 39, 38, 30, 21, 11, 2, -9, -14, -13, -13, -15, -16, -14, -6, 1, 4, 4, 3, 4, 7, 10, 10, 5, -3, -7, -8, -9, -12, -14, -11, 0, 13, 28, 40, 51, 58, 61, 60, 56, 47, 33, 15, -8, -28, -44, -55, -62, -72, -81, -83, -74, -58, -39, -21, -6, 8, 18, 30, 40, 47, 49, 44, 33, 19, 6, -6, -14, -19, -23, -26, -24, -19, -13, -5, -2, 2, 5, 8, 11, 14, 13, 9, 2, -4, -8, -12, -15, -19, -18, -13, -3, 14, 30, 44, 53, 62, 66, 66, 59, 48, 33, 12, -10, -31, -46, -58, -71, -79, -84, -81, -71, -54, -34, -14, 1, 14, 26, 37, 44, 48, 49, 41, 29, 12, -3, -13, -17, -19, -24, -26, -22, -16, -8, -3, -2, 3, 6, 10, 13, 12, 10, 6, 2, -4, -11, -18, -22, -22, -19, -14, -3, 13, 30, 46, 61, 68, 71, 70, 64, 52, 32, 10, -12, -31, -51, -67, -81, -88, -91, -84, -69, -51, -32, -12, 8, 25, 37, 43, 47, 52, 50, 40, 23, 5, -8, -13, -18, -23, -28, -26, -19, -12, -6, -4, -2, 2, 6, 11, 11, 5, 3, 4, 1, -9, -17, -21, -23, -22, -19, -14, 0, 17, 37, 54, 65, 70, 75, 76, 67, 50, 30, 6, -15, -35, -56, -75, -88, -93, -88, -78, -64, -47, -26, -3, 17, 31, 37, 42, 46, 48, 42, 27, 10, 0, -3, -7, -14, -21, -21, -13, -4, 1, -2, -3, 1, 5, 7, 4, -3, -8, -7, -7, -14, -19, -22, -23, -21, -20, -16, -6, 12, 32, 51, 63, 70, 76, 78, 75, 63, 44, 20, -5, -26, -46, -67, -83, -94, -93, -83, -69, -55, -40, -17, 8, 25, 34, 38, 43, 48, 45, 35, 20, 8, 2, 3, -2, -12, -18, -15, -8, 0, 0, -5, -6, -4, -3, -5, -11, -15, -14, -12, -13, -16, -19, -20, -20, -16, -10, -2, 11, 24, 42, 57, 64, 70, 73, 72, 64, 48, 26, 4, -15, -35, -50, -68, -81, -88, -81, -68, -55, -44, -29, -10, 9, 22, 25, 30, 37, 38, 35, 24, 14, 11, 13, 14, 9, 0, -5, -3, 3, 4, -2, -10, -15, -15, -15, -19, -25, -24, -20, -18, -19, -20, -18, -16, -13, -9, 1, 12, 25, 37, 53, 63, 69, 74, 73, 69, 56, 37, 15, -6, -25, -42, -59, -75, -82, -81, -72, -61, -50, -35, -17, -2, 13, 20, 27, 31, 34, 34, 28, 19, 14, 13, 15, 14, 8, 4, 3, 5, 5, 1, -6, -15, -18, -22, -27, -33, -34, -31, -25, -24, -20, -19, -17, -10, -2, 9, 18, 28, 39, 51, 60, 67, 71, 72, 67, 53, 35, 16, -4, -21, -40, -57, -70, -76, -74, -65, -55, -44, -34, -21, -7, 6, 15, 18, 20, 24, 24, 21, 16, 15, 16, 17, 17, 16, 13, 12, 13, 13, 9, 0, -12, -17, -22, -31, -40, -43, -40, -35, -30, -26, -24, -20, -11, -2, 9, 19, 29, 39, 46, 54, 60, 66, 67, 66, 58, 41, 21, 5, -11, -29, -47, -62, -68, -68, -65, -57, -49, -39, -27, -13, -2, 6, 11, 18, 23, 24, 21, 19, 19, 21, 21, 18, 15, 11, 13, 15, 15, 10, -2, -8, -14, -21, -30, -39, -44, -44, -40, -33, -29, -27, -21, -12, -3, 6, 16, 28, 40, 48, 54, 56, 59, 61, 62, 57, 44, 28, 12, -3, -22, -40, -55, -64, -63, -61, -56, -51, -41, -29, -15, -6, 1, 8, 15, 20, 20, 18, 17, 18, 23, 23, 20, 17, 15, 18, 20, 20, 15, 4, -5, -11, -20, -32, -43, -49, -48, -43, -36, -32, -29, -21, -13, 0, 11, 20, 30, 38, 46, 50, 51, 53, 56, 53, 48, 41, 30, 19, 5, -10, -26, -42, -50, -56, -57, -56, -53, -46, -38, -27, -18, -10, -2, 8, 16, 19, 24, 24, 22, 23, 25, 23, 17, 16, 15, 16, 14, 10, 3, -5, -11, -20, -28, -35, -42, -44, -42, -35, -29, -25, -19, -11, 0, 10, 20, 26, 31, 38, 45, 48, 46, 46, 44, 41, 37, 30, 22, 13, 1, -15, -27, -36, -44, -49, -51, -52, -49, -44, -37, -27, -20, -12, 1, 10, 19, 23, 28, 29, 28, 28, 24, 19, 17, 16, 15, 14, 10, 4, -3, -10, -15, -23, -31, -36, -41, -41, -39, -32, -24, -19, -11, -3, 5, 15, 24, 31, 36, 42, 45, 44, 41, 37, 33, 31, 29, 23, 14, 2, -8, -16, -22, -31, -40, -44, -46, -46, -46, -44, -37, -28, -20, -10, 2, 11, 20, 28, 32, 32, 29, 26, 22, 19, 17, 14, 12, 11, 8, 2, -5, -14, -20, -24, -30, -34, -37, -38, -36, -30, -21, -14, -6, 2, 11, 19, 26, 30, 34, 41, 44, 42, 38, 32, 27, 25, 24, 21, 11, 1, -9, -16, -25, -34, -40, -43, -45, -48, -50, -49, -40, -27, -15, -6, 4, 15, 27, 36, 40, 37, 32, 27, 22, 15, 11, 10, 8, 6, 0, -8, -14, -16, -17, -18, -24, -31, -33, -33, -27, -22, -17, -10, -4, 6, 13, 17, 22, 27, 33, 38, 39, 37, 35, 33, 31, 27, 23, 19, 11, 3, -7, -20, -30, -38, -42, -42, -46, -53, -58, -53, -41, -27, -13, -2, 10, 19, 30, 39, 43, 38, 29, 23, 18, 12, 8, 6, 6, 4, -3, -8, -12, -13, -10, -12, -17, -24, -25, -23, -23, -23, -19, -12, -4, 2, 5, 9, 14, 22, 32, 37, 39, 39, 37, 37, 33, 28, 27, 21, 12, 0, -14, -25, -33, -38, -43, -48, -54, -60, -59, -48, -36, -20, -8, 2, 12, 26, 39, 44, 40, 32, 27, 23, 16, 8, 3, 3, 2, 1, -4, -9, -9, -6, -6, -8, -13, -16, -18, -21, -22, -21, -16, -7, -2, 0, -2, 2, 13, 25, 30, 34, 34, 34, 34, 33, 33, 31, 26, 21, 11, -3, -15, -25, -31, -37, -48, -57, -62, -63, -56, -46, -35, -25, -12, 5, 18, 32, 40, 40, 36, 32, 29, 22, 15, 7, 3, 0, 0, 0, 1, -2, -2, 0, 0, -3, -4, -7, -13, -22, -28, -25, -17, -10, -10, -11, -10, -4, 12, 26, 36, 39, 40, 41, 40, 37, 35, 33, 28, 19, 3, -11, -22, -30, -37, -46, -56, -63, -65, -59, -52, -43, -29, -17, -4, 10, 23, 32, 36, 36, 34, 29, 24, 19, 12, 5, -2, 0, 4, 7, 10, 9, 6, 5, 5, 5, 0, -10, -20, -26, -29, -26, -20, -18, -19, -17, -9, 3, 16, 28, 36, 40, 42, 43, 41, 40, 36, 33, 26, 16, 3, -10, -21, -31, -42, -53, -61, -65, -63, -58, -52, -41, -31, -18, -4, 9, 21, 26, 29, 30, 31, 31, 28, 21, 12, 6, 5, 10, 13, 13, 14, 9, 8, 7, 5, 0, -8, -17, -24, -28, -27, -23, -17, -14, -12, -8, 2, 15, 26, 32, 36, 39, 38, 37, 36, 33, 28, 21, 16, 10, 1, -13, -25, -34, -41, -50, -59, -62, -62, -53, -44, -37, -28, -19, -6, 7, 14, 18, 22, 26, 28, 28, 21, 13, 6, 6, 15, 19, 21, 20, 20, 18, 16, 13, 7, -3, -12, -21, -27, -31, -30, -24, -15, -11, -8, 0, 10, 23, 29, 32, 34, 34, 34, 33, 32, 27, 23, 20, 17, 10, -2, -15, -25, -34, -43, -52, -61, -63, -58, -49, -43, -41, -33, -22, -9, 3, 11, 17, 21, 26, 30, 28, 23, 17, 15, 18, 22, 22, 20, 21, 21, 18, 12, 4, -5, -11, -16, -22, -28, -32, -24, -14, -7, -5, 1, 11, 20, 27, 30, 26, 25, 29, 30, 29, 22, 17, 18, 22, 20, 9, -8, -18, -25, -31, -40, -53, -60, -58, -54, -46, -45, -42, -32, -20, -10, -2, 5, 12, 19, 25, 27, 22, 18, 18, 21, 24, 25, 22, 24, 26, 27, 22, 10, 0, -7, -9, -12, -21, -28, -28, -20, -9, -4, -2, 5, 14, 22, 24, 21, 15, 18, 24, 28, 24, 19, 21, 26, 30, 22, 7, -6, -15, -23, -34, -50, -61, -66, -61, -52, -50, -49, -45, -36, -22, -10, 1, 11, 15, 20, 26, 26, 24, 21, 21, 27, 28, 24, 21, 22, 26, 24, 16, 5, -5, -7, -5, -11, -17, -22, -17, -7, 0, 1, 4, 9, 16, 19, 18, 13, 12, 16, 22, 24, 23, 23, 28, 33, 27, 16, 2, -12, -23, -33, -45, -57, -64, -64, -55, -51, -52, -49, -39, -25, -13, -6, 1, 6, 12, 16, 18, 20, 18, 20, 25, 28, 28, 29, 31, 36, 37, 28, 15, 7, 3, 0, -4, -14, -21, -23, -16, -7, -4, -3, 1, 10, 16, 17, 10, 7, 9, 18, 24, 24, 24, 28, 34, 34, 26, 12, -3, -15, -26, -40, -53, -61, -65, -62, -59, -57, -55, -49, -39, -27, -18, -6, 3, 8, 14, 17, 21, 25, 26, 27, 28, 30, 32, 32, 31, 32, 28, 22, 14, 6, 3, 0, -3, -8, -12, -12, -5, 0, 2, 1, 3, 6, 11, 11, 7, 4, 6, 13, 20, 24, 28, 31, 32, 28, 19, 7, -7, -20, -32, -44, -53, -58, -58, -55, -54, -53, -50, -46, -40, -27, -14, -6, -6, -5, 0, 8, 16, 20, 23, 25, 30, 37, 42, 43, 41, 39, 34, 28, 18, 9, 4, 3, 0, -10, -13, -12, -10, -5, 1, 1, 0, 4, 8, 7, 5, 6, 11, 19, 23, 27, 32, 33, 27, 20, 10, 0, -15, -30, -41, -49, -52, -54, -55, -55, -53, -50, -45, -40, -32, -24, -16, -11, -10, -8, -3, 6, 13, 17, 21, 29, 37, 43, 48, 47, 43, 38, 35, 30, 19, 11, 7, 2, -5, -9, -9, -5, 1, 1, 0, -2, 1, 3, 6, 5, 4, 5, 10, 16, 20, 24, 27, 25, 18, 10, 3, -9, -21, -31, -39, -44, -47, -47, -44, -46, -48, -48, -45, -39, -36, -30, -26, -25, -23, -19, -9, 4, 14, 24, 32, 41, 48, 54, 56, 57, 52, 47, 40, 28, 17, 10, 4, -3, -8, -10, -8, -6, -5, -5, -5, -3, 0, 3, 4, 4, 5, 7, 12, 19, 26, 27, 24, 18, 12, 5, -3, -12, -24, -34, -43, -46, -48, -48, -46, -46, -45, -44, -42, -38, -33, -29, -26, -26, -22, -14, -5, 5, 13, 23, 32, 40, 47, 52, 56, 57, 55, 52, 47, 36, 27, 19, 11, 3, -5, -6, -8, -10, -13, -15, -14, -13, -11, -6, 1, 4, 7, 11, 17, 21, 26, 28, 26, 19, 10, 2, -7, -17, -26, -36, -41, -45, -47, -45, -44, -44, -41, -39, -40, -40, -37, -33, -34, -32, -26, -18, -9, 2, 12, 26, 40, 47, 56, 63, 66, 66, 63, 60, 53, 40, 27, 14, 3, -8, -11, -12, -15, -19, -19, -18, -15, -12, -8, 0, 6, 11, 13, 14, 17, 23, 29, 27, 18, 9, 1, -7, -16, -25, -35, -43, -49, -47, -44, -43, -42, -40, -36, -34, -33, -33, -33, -35, -34, -30, -23, -16, -9, 2, 14, 27, 39, 49, 58, 66, 69, 68, 66, 61, 53, 45, 32, 18, 1, -11, -14, -17, -17, -20, -23, -21, -17, -13, -3, 4, 10, 13, 14, 17, 18, 21, 24, 22, 15, 6, -4, -12, -22, -28, -38, -49, -51, -48, -45, -43, -40, -38, -36, -35, -34, -33, -33, -34, -35, -33, -29, -18, -6, 6, 19, 33, 46, 59, 71, 78, 78, 78, 74, 67, 54, 39, 22, 6, -8, -16, -22, -25, -25, -26, -22, -17, -12, -3, 6, 15, 17, 16, 14, 14, 16, 17, 16, 13, 6, -2, -11, -20, -27, -34, -43, -49, -48, -44, -41, -39, -36, -33, -34, -33, -34, -32, -33, -35, -35, -30, -21, -11, 0, 9, 23, 38, 52, 65, 74, 76, 76, 74, 70, 62, 47, 28, 13, 2, -6, -14, -21, -23, -20, -18, -16, -13, -7, 1, 8, 10, 11, 9, 11, 11, 13, 15, 16, 13, 8, -2, -11, -19, -27, -37, -47, -52, -51, -48, -46, -43, -40, -38, -36, -35, -35, -38, -38, -33, -27, -21, -16, -7, 6, 21, 36, 49, 61, 70, 75, 79, 78, 73, 62, 49, 35, 22, 8, -3, -12, -17, -20, -18, -14, -13, -15, -12, -5, 4, 7, 8, 8, 9, 8, 9, 11, 14, 14, 10, 4, -6, -15, -25, -35, -41, -48, -54, -53, -47, -42, -38, -37, -35, -31, -31, -30, -30, -29, -26, -24, -19, -12, -2, 10, 22, 35, 48, 60, 70, 76, 76, 73, 67, 57, 44, 28, 14, 5, -3, -8, -13, -14, -13, -10, -11, -11, -8, -2, 4, 6, 5, 5, 5, 6, 10, 11, 10, 8, 4, -2, -9, -15, -24, -35, -44, -50, -52, -49, -45, -42, -42, -40, -37, -37, -37, -33, -29, -26, -24, -21, -16, -7, 6, 18, 30, 41, 54, 66, 75, 77, 79, 76, 67, 53, 37, 21, 8, 2, -5, -10, -14, -14, -12, -12, -11, -10, -5, 4, 7, 4, 1, 2, 6, 9, 9, 7, 5, 4, 0, -7, -14, -23, -32, -37, -43, -48, -50, -51, -47, -42, -34, -32, -32, -34, -32, -26, -21, -18, -17, -14, -11, -4, 5, 13, 24, 40, 55, 67, 72, 74, 76, 75, 67, 51, 37, 23, 11, 4, -4, -11, -15, -17, -17, -16, -14, -13, -8, -2, 1, 1, 1, 3, 5, 9, 7, 5, 4, 4, 3, -5, -14, -24, -32, -38, -41, -47, -52, -53, -49, -41, -35, -34, -35, -33, -29, -24, -19, -13, -10, -9, -7, -2, 8, 17, 29, 43, 56, 67, 74, 75, 75, 72, 64, 53, 38, 23, 13, 4, -5, -12, -16, -20, -21, -18, -16, -14, -11, -8, -5, -3, 0, 2, 6, 6, 6, 5, 5, 6, 3, -6, -19, -31, -37, -41, -45, -50, -52, -53, -48, -39, -32, -30, -26, -25, -22, -16, -10, -7, -11, -10, -8, -2, 6, 17, 31, 45, 58, 68, 78, 80, 76, 70, 65, 55, 37, 18, 5, -4, -10, -19, -25, -26, -24, -18, -13, -11, -9, -6, -2, 4, 6, 5, 4, 3, 4, 2, 1, -3, -4, -11, -20, -29, -38, -43, -45, -48, -51, -48, -44, -39, -35, -34, -31, -30, -25, -15, -8, -8, -10, -8, 1, 11, 22, 33, 42, 54, 66, 76, 80, 75, 70, 66, 59, 42, 23, 6, -4, -9, -17, -22, -27, -25, -19, -9, -7, -8, -5, 0, 4, 5, 2, -2, -5, -5, -4, -6, -7, -6, -10, -16, -21, -29, -34, -37, -38, -41, -44, -42, -36, -32, -33, -37, -39, -35, -27, -17, -12, -13, -12, -6, 6, 22, 36, 44, 54, 66, 77, 82, 80, 75, 68, 59, 47, 29, 10, -3, -13, -18, -23, -26, -27, -24, -16, -9, -5, -4, -2, 3, 6, 4, -2, -6, -8, -7, -8, -8, -9, -10, -13, -16, -22, -29, -31, -30, -34, -36, -36, -32, -28, -30, -36, -39, -38, -33, -28, -24, -24, -22, -15, -2, 13, 26, 38, 53, 67, 78, 84, 88, 85, 81, 71, 59, 39, 13, -5, -14, -19, -26, -32, -34, -30, -22, -13, -5, 0, 6, 7, 10, 8, 2, -4, -10, -12, -15, -18, -20, -20, -20, -22, -24, -26, -26, -23, -23, -23, -24, -21, -17, -18, -25, -31, -35, -37, -37, -36, -33, -29, -22, -10, 5, 19, 31, 45, 62, 75, 84, 86, 88, 87, 80, 66, 45, 22, 4, -9, -18, -26, -34, -37, -33, -24, -15, -9, -3, 6, 13, 15, 11, 2, -5, -10, -13, -20, -25, -27, -26, -25, -26, -29, -29, -23, -18, -16, -19, -18, -15, -9, -6, -12, -21, -32, -36, -36, -40, -39, -36, -30, -21, -10, 6, 20, 36, 55, 69, 79, 85, 90, 92, 88, 75, 56, 33, 12, -3, -15, -24, -33, -37, -35, -28, -20, -12, -4, 6, 14, 18, 16, 9, 0, -8, -15, -19, -27, -33, -35, -34, -34, -36, -36, -29, -19, -10, -10, -10, -8, -4, -2, -2, -8, -18, -28, -36, -43, -48, -46, -36, -25, -14, -4, 10, 27, 46, 65, 78, 86, 89, 87, 85, 78, 64, 42, 19, 0, -12, -20, -29, -34, -36, -30, -22, -12, -6, 1, 8, 16, 18, 13, 2, -7, -12, -17, -24, -33, -38, -39, -36, -36, -36, -34, -26, -18, -11, -7, -6, -5, -5, 1, 1, -5, -14, -24, -33, -41, -42, -37, -28, -19, -10, 3, 16, 30, 47, 64, 76, 83, 85, 83, 78, 69, 54, 37, 17, -2, -14, -21, -28, -32, -32, -27, -18, -11, -6, 2, 12, 18, 16, 5, -5, -11, -14, -19, -30, -40, -47, -45, -38, -36, -34, -33, -26, -15, -6, -2, 1, 1, 3, 5, 4, -3, -13, -26, -35, -41, -39, -33, -23, -13, -5, 7, 21, 36, 53, 68, 79, 82, 78, 72, 66, 59, 47, 30, 10, -6, -16, -21, -22, -25, -27, -25, -18, -10, -4, 4, 10, 11, 6, -4, -11, -13, -18, -25, -34, -43, -45, -41, -36, -34, -32, -27, -19, -10, -5, 0, 2, 5, 5, 5, 1, -7, -16, -25, -33, -38, -35, -25, -13, -6, 0, 11, 27, 46, 60, 69, 70, 68, 69, 68, 62, 52, 39, 22, 8, -2, -11, -18, -21, -22, -23, -24, -17, -10, -5, 1, 5, 5, 2, -3, -5, -9, -17, -28, -41, -46, -48, -43, -42, -42, -39, -30, -19, -9, -3, 6, 11, 15, 16, 12, 5, -2, -12, -23, -33, -37, -34, -25, -18, -8, 1, 15, 32, 48, 62, 69, 68, 67, 63, 62, 58, 50, 34, 15, -2, -8, -10, -11, -16, -24, -24, -19, -12, -6, -2, 2, 3, 1, 0, -6, -10, -17, -26, -37, -46, -48, -45, -44, -42, -38, -32, -22, -12, -6, 4, 10, 14, 16, 15, 11, 5, -2, -11, -23, -31, -29, -22, -18, -16, -11, 3, 17, 34, 50, 56, 59, 61, 63, 62, 59, 53, 44, 32, 16, 3, -8, -9, -13, -20, -26, -27, -21, -16, -11, -9, -6, 1, 7, 7, 0, -10, -15, -20, -30, -39, -45, -48, -48, -46, -41, -36, -29, -20, -11, 3, 11, 14, 19, 21, 19, 15, 6, -3, -13, -18, -18, -17, -20, -19, -12, 2, 15, 26, 36, 43, 51, 59, 61, 61, 57, 54, 49, 37, 21, 9, 1, -8, -17, -25, -29, -28, -27, -23, -19, -13, -5, 2, 8, 5, -4, -11, -13, -17, -27, -40, -49, -53, -53, -50, -44, -37, -28, -19, -7, 8, 18, 22, 26, 26, 23, 17, 10, 0, -8, -15, -20, -25, -23, -19, -11, 0, 13, 25, 34, 44, 54, 60, 62, 60, 58, 56, 52, 38, 21, 6, -6, -16, -26, -32, -33, -30, -26, -24, -17, -8, 3, 13, 16, 10, 1, -7, -12, -18, -34, -50, -61, -63, -58, -54, -50, -45, -33, -13, 6, 21, 27, 34, 37, 36, 30, 20, 11, -2, -13, -24, -32, -37, -34, -24, -10, 2, 12, 25, 41, 55, 61, 64, 65, 67, 64, 59, 48, 32, 16, 0, -12, -20, -27, -33, -33, -31, -28, -23, -12, 0, 10, 13, 9, 2, -2, -7, -13, -25, -41, -56, -65, -66, -62, -56, -53, -42, -25, -5, 13, 24, 34, 39, 42, 39, 32, 22, 11, -2, -15, -27, -36, -37, -31, -22, -13, 0, 12, 27, 43, 55, 61, 64, 65, 63, 60, 53, 42, 28, 10, -6, -20, -27, -28, -28, -25, -23, -20, -13, -2, 11, 16, 14, 8, 2, -6, -14, -25, -38, -53, -67, -73, -73, -67, -58, -46, -32, -14, 6, 24, 36, 43, 45, 44, 39, 30, 18, 5, -11, -25, -35, -39, -37, -28, -17, -7, 4, 16, 32, 48, 58, 64, 66, 63, 61, 56, 46, 31, 18, 3, -13, -21, -25, -23, -19, -15, -11, -7, -2, 6, 13, 14, 8, -3, -12, -21, -32, -40, -55, -70, -78, -75, -67, -56, -47, -29, -12, 10, 29, 40, 47, 49, 48, 43, 31, 15, 0, -16, -29, -39, -45, -41, -32, -18, -6, 3, 13, 27, 43, 57, 64, 65, 61, 58, 52, 43, 32, 18, 6, -9, -18, -20, -17, -12, -4, 1, 3, 7, 12, 17, 16, 9, -3, -15, -27, -39, -48, -60, -72, -82, -82, -73, -58, -45, -33, -14, 7, 28, 42, 49, 51, 51, 48, 38, 22, 2, -16, -30, -37, -42, -45, -40, -26, -11, 3, 11, 20, 34, 52, 65, 69, 64, 54, 46, 38, 28, 16, 4, -11, -18, -16, -10, -4, 3, 13, 21, 23, 22, 20, 18, 11, -2, -16, -34, -47, -59, -70, -76, -83, -83, -76, -64, -48, -31, -12, 10, 30, 42, 50, 53, 51, 46, 37, 25, 8, -13, -30, -41, -45, -43, -35, -23, -15, -5, 8, 17, 28, 40, 56, 64, 63, 55, 45, 34, 24, 14, 7, -4, -12, -13, -9, -2, 11, 23, 31, 33, 33, 31, 26, 17, 4, -14, -31, -48, -62, -75, -86, -90, -87, -79, -68, -54, -39, -18, 4, 23, 39, 47, 52, 52, 47, 39, 29, 15, -5, -23, -35, -41, -40, -34, -26, -16, -8, 2, 12, 22, 30, 43, 52, 58, 54, 45, 36, 25, 16, 7, -2, -7, -8, -3, 4, 13, 24, 32, 39, 42, 39, 30, 19, 6, -10, -25, -44, -62, -79, -88, -90, -85, -78, -70, -59, -45, -24, 0, 20, 35, 43, 48, 48, 46, 42, 33, 20, 2, -19, -32, -38, -41, -37, -29, -19, -8, 1, 11, 19, 26, 35, 43, 48, 48, 41, 35, 26, 16, 7, 0, 0, 3, 6, 10, 16, 24, 32, 40, 44, 43, 33, 21, 8, -5, -19, -37, -54, -72, -84, -87, -81, -75, -68, -61, -50, -33, -12, 8, 22, 29, 34, 40, 42, 41, 35, 24, 13, -2, -16, -27, -33, -33, -27, -22, -17, -13, -4, 9, 18, 25, 31, 36, 42, 44, 40, 32, 21, 12, 9, 7, 8, 9, 13, 17, 23, 29, 35, 40, 40, 35, 26, 13, 0, -11, -24, -41, -60, -74, -80, -79, -73, -68, -63, -56, -43, -27, -10, 6, 18, 24, 29, 34, 38, 37, 30, 20, 9, -3, -14, -24, -27, -27, -25, -23, -18, -9, 2, 10, 19, 25, 30, 37, 40, 41, 33, 22, 16, 10, 6, 6, 10, 16, 21, 28, 31, 35, 38, 44, 45, 34, 19, 5, -5, -17, -33, -52, -68, -76, -78, -75, -71, -67, -62, -51, -37, -20, -7, 4, 13, 21, 29, 34, 36, 33, 26, 17, 10, 0, -8, -13, -19, -21, -21, -17, -11, -6, 4, 10, 13, 19, 25, 30, 31, 28, 20, 14, 10, 7, 7, 11, 20, 26, 32, 36, 39, 41, 44, 46, 41, 30, 13, 0, -13, -27, -44, -62, -72, -74, -74, -74, -71, -66, -57, -47, -32, -19, -9, 2, 14, 24, 28, 32, 34, 33, 25, 17, 9, 2, -5, -10, -17, -22, -18, -13, -7, 0, 4, 10, 17, 23, 26, 25, 21, 15, 9, 9, 7, 4, 7, 16, 27, 34, 39, 43, 48, 49, 52, 49, 39, 24, 9, -3, -17, -32, -52, -67, -75, -75, -71, -70, -70, -66, -56, -43, -31, -21, -12, -2, 11, 21, 27, 30, 33, 31, 29, 22, 15, 8, 0, -6, -13, -14, -14, -11, -5, 0, 4, 8, 13, 16, 18, 15, 12, 10, 7, 7, 6, 7, 14, 24, 36, 44, 46, 46, 49, 52, 53, 47, 35, 21, 9, -6, -23, -43, -59, -68, -71, -74, -74, -76, -73, -64, -52, -39, -31, -25, -15, 0, 12, 20, 24, 29, 32, 30, 26, 21, 16, 10, 4, -2, -7, -7, -5, -3, 0, 3, 5, 6, 9, 8, 8, 6, 3, 2, 4, 5, 7, 14, 22, 34, 43, 49, 57, 57, 55, 52, 48, 43, 31, 17, 2, -13, -33, -49, -59, -63, -66, -72, -75, -76, -70, -61, -52, -44, -37, -30, -18, -4, 11, 20, 25, 28, 32, 32, 30, 26, 19, 13, 5, 0, -4, -5, -3, 1, 2, 1, -3, -2, 2, 6, 4, 2, -3, -2, 3, 10, 13, 18, 27, 40, 49, 56, 59, 60, 56, 52, 47, 41, 30, 17, 1, -19, -39, -55, -64, -67, -70, -76, -81, -78, -69, -56, -46, -40, -33, -24, -12, 3, 15, 22, 25, 26, 29, 27, 23, 19, 14, 9, 4, 0, -2, 1, 5, 9, 7, 2, -3, -3, 3, 3, -2, -10, -13, -10, -2, 7, 14, 22, 31, 45, 59, 65, 68, 65, 62, 58, 50, 41, 28, 12, -9, -31, -49, -59, -65, -70, -76, -84, -84, -77, -63, -50, -45, -40, -32, -21, -7, 7, 16, 24, 28, 29, 28, 23, 18, 15, 11, 6, 0, -4, -3, 4, 11, 14, 11, 6, 5, 7, 7, 2, -7, -12, -16, -13, -6, 1, 8, 17, 32, 50, 63, 68, 68, 69, 70, 65, 56, 43, 27, 7, -17, -38, -52, -62, -71, -78, -86, -88, -84, -73, -59, -50, -43, -34, -25, -11, 2, 11, 19, 23, 26, 26, 21, 17, 12, 9, 7, 5, 2, 2, 4, 11, 16, 14, 10, 9, 10, 9, 1, -8, -16, -19, -16, -11, -6, 0, 8, 24, 43, 57, 66, 70, 72, 72, 67, 63, 52, 37, 18, -5, -23, -41, -54, -62, -70, -78, -81, -82, -76, -67, -56, -45, -36, -31, -22, -12, 0, 10, 16, 20, 21, 17, 13, 7, 3, 3, 6, 6, 6, 9, 14, 20, 21, 20, 17, 17, 15, 9, -3, -15, -23, -27, -20, -14, -9, -4, 9, 31, 49, 64, 70, 75, 78, 76, 70, 60, 45, 31, 12, -11, -31, -46, -58, -66, -70, -73, -77, -74, -67, -59, -52, -44, -36, -29, -22, -14, -6, 1, 11, 14, 14, 11, 6, 6, 7, 10, 11, 12, 15, 18, 24, 23, 21, 19, 20, 18, 12, 0, -13, -20, -27, -27, -22, -16, -11, 1, 19, 36, 52, 64, 73, 79, 81, 77, 69, 56, 43, 26, 5, -16, -37, -54, -62, -66, -69, -72, -71, -65, -62, -56, -47, -39, -33, -26, -19, -14, -12, -3, 9, 9, 3, -6, -4, 5, 11, 12, 11, 12, 20, 29, 31, 29, 25, 25, 27, 24, 11, -6, -17, -25, -31, -32, -30, -26, -16, 0, 17, 35, 51, 66, 78, 87, 88, 84, 73, 57, 40, 23, 3, -20, -42, -57, -65, -69, -71, -70, -68, -63, -58, -52, -45, -38, -30, -26, -24, -23, -16, -8, -2, -5, -9, -6, 1, 9, 12, 13, 17, 24, 32, 37, 37, 34, 32, 33, 31, 19, 2, -15, -25, -31, -36, -38, -35, -27, -13, 4, 23, 40, 59, 76, 91, 96, 91, 80, 69, 55, 35, 13, -12, -35, -52, -61, -66, -71, -70, -63, -54, -48, -44, -42, -36, -31, -30, -34, -36, -33, -26, -20, -20, -21, -18, -9, 5, 13, 18, 21, 29, 40, 47, 50, 49, 44, 40, 34, 23, 6, -14, -27, -39, -45, -48, -45, -35, -23, -7, 11, 30, 51, 73, 89, 97, 96, 89, 80, 63, 44, 25, 4, -18, -39, -53, -59, -63, -61, -58, -55, -52, -49, -45, -39, -35, -37, -41, -46, -43, -38, -33, -29, -25, -18, -11, 3, 13, 20, 25, 30, 38, 46, 51, 50, 47, 43, 37, 26, 9, -7, -19, -32, -45, -52, -51, -40, -28, -12, 4, 19, 38, 61, 83, 94, 95, 89, 82, 67, 50, 30, 12, -8, -26, -40, -52, -57, -56, -52, -48, -46, -44, -40, -34, -32, -32, -37, -44, -47, -45, -41, -39, -35, -28, -17, -6, 7, 15, 23, 32, 40, 47, 52, 52, 51, 46, 39, 32, 17, 1, -14, -26, -37, -46, -50, -45, -35, -25, -11, 5, 24, 44, 62, 79, 88, 86, 79, 70, 59, 45, 25, 7, -13, -25, -36, -46, -50, -51, -50, -46, -43, -41, -37, -34, -33, -36, -40, -43, -46, -46, -41, -36, -31, -22, -10, 4, 13, 21, 30, 40, 47, 50, 53, 52, 47, 39, 30, 18, 3, -12, -22, -33, -42, -47, -45, -36, -25, -14, -2, 14, 34, 52, 67, 76, 77, 72, 65, 55, 43, 27, 12, -7, -21, -29, -36, -41, -44, -43, -39, -36, -32, -27, -26, -26, -29, -33, -36, -43, -49, -48, -44, -38, -32, -22, -11, 4, 15, 25, 34, 44, 50, 53, 54, 52, 44, 35, 23, 9, -4, -15, -27, -37, -43, -45, -42, -34, -21, -9, 5, 19, 34, 50, 63, 70, 69, 63, 54, 46, 35, 20, 4, -11, -23, -29, -33, -37, -41, -40, -33, -25, -20, -19, -21, -22, -23, -26, -34, -42, -47, -46, -43, -36, -30, -22, -11, 5, 17, 28, 37, 45, 52, 55, 53, 49, 41, 30, 19, 4, -12, -23, -33, -41, -45, -45, -40, -31, -18, -3, 11, 23, 38, 51, 63, 64, 58, 51, 45, 36, 25, 10, -4, -15, -24, -28, -32, -36, -35, -29, -19, -13, -13, -14, -13, -13, -13, -21, -33, -43, -45, -45, -41, -38, -34, -25, -11, 4, 17, 29, 39, 49, 57, 60, 55, 48, 39, 29, 16, 1, -14, -27, -35, -42, -47, -48, -42, -29, -15, -3, 10, 20, 34, 48, 56, 57, 51, 45, 38, 30, 20, 7, -7, -17, -22, -26, -32, -36, -31, -21, -9, -6, -8, -8, -4, 1, -4, -13, -26, -35, -39, -40, -42, -44, -40, -29, -13, 3, 16, 29, 43, 58, 67, 67, 59, 49, 39, 27, 11, -9, -28, -39, -47, -50, -53, -52, -44, -29, -12, 5, 13, 25, 38, 51, 57, 52, 45, 38, 30, 21, 9, -4, -14, -21, -26, -29, -33, -28, -18, -7, 2, 2, 2, 4, 8, 10, 5, -10, -25, -36, -42, -45, -49, -49, -45, -33, -14, 5, 22, 35, 54, 69, 78, 76, 67, 53, 41, 27, 6, -17, -36, -50, -55, -60, -63, -62, -51, -34, -16, -2, 9, 20, 34, 45, 50, 48, 42, 35, 29, 18, 7, 0, 0, 0, 0, 0, 0, 7, 0, -1, -7, -18, -16, 3, 6, -18, -29, -21, 6, 6, -12, -10, -10, -2, 4, 15, 21, 14, 4, 9, 29, 27, 15, 9, 13, 20, 0, -21, -11, 3, -11, -37, -36, -7, 11, -4, -26, -23, -4, 15, -4, -15, -11, -10, -1, 9, 23, 15, 8, 6, 24, 35, 19, 14, 6, 17, 10, -15, -26, -7, -1, -23, -40, -24, 4, 10, -16, -25, -13, 11, 10, -14, -15, -12, -6, 1, 19, 22, 6, 7, 15, 40, 31, 22, 7, 7, 15, 5, -22, -21, -5, -9, -33, -32, -15, 5, -4, -19, -20, 1, 17, -4, -15, -11, -12, -4, 9, 27, 13, 7, 11, 32, 44, 30, 14, 2, 7, 9, -8, -25, -18, -9, -19, -30, -21, -4, 2, -10, -21, -13, 15, 8, -11, -13, -16, -12, 0, 20, 24, 9, 9, 19, 44, 47, 25, 6, 2, 11, -1, -21, -27, -19, -17, -20, -23, -17, -5, -5, -14, -20, 0, 15, -4, -7, -17, -17, -8, 7, 25, 18, 7, 11, 31, 54, 41, 14, -1, 10, 3, -14, -27, -29, -21, -16, -16, -18, -17, -11, -10, -16, -16, 10, 6, -3, -9, -19, -16, -2, 18, 27, 16, 8, 19, 45, 54, 29, 5, 6, 4, -9, -18, -29, -30, -18, -10, -9, -14, -20, -12, -13, -17, -5, 12, 7, 2, -16, -22, -13, 8, 25, 23, 12, 11, 32, 53, 48, 17, 9, 9, -7, -16, -24, -37, -28, -12, -4, -2, -18, -21, -18, -23, -17, 7, 11, 10, -4, -16, -22, -7, 21, 28, 18, 9, 20, 43, 55, 37, 11, 11, 1, -14, -17, -31, -34, -21, -10, 4, -2, -20, -23, -26, -29, -3, 6, 13, 8, -5, -23, -27, 7, 28, 27, 15, 12, 32, 48, 50, 24, 9, 8, -12, -19, -26, -37, -35, -19, 3, 6, -12, -21, -31, -38, -17, 6, 4, 14, 6, -8, -35, -15, 19, 26, 21, 7, 23, 43, 52, 42, 14, 9, -2, -16, -21, -25, -33, -33, -4, 13, 3, -13, -30, -47, -37, 1, 6, 7, 12, 6, -15, -31, -1, 22, 30, 14, 9, 37, 48, 50, 26, 8, 6, -11, -22, -22, -25, -45, -22, 13, 15, 1, -22, -43, -56, -21, 7, 6, 10, 15, -7, -25, -21, 7, 28, 21, 2, 25, 47, 53, 39, 11, 10, 1, -20, -22, -18, -37, -42, 2, 15, 15, -8, -32, -57, -48, -9, 9, 5, 14, 8, -14, -20, -13, 17, 33, 8, 9, 37, 52, 55, 25, 7, 8, -11, -23, -15, -23, -47, -20, 12, 21, 10, -23, -50, -57, -31, 2, 10, 9, 11, -8, -10, -18, -3, 30, 22, 1, 22, 45, 57, 45, 11, 11, 0, -23, -22, -16, -36, -36, -6, 15, 18, -3, -43, -56, -49, -21, 5, 11, 12, -2, -8, -9, -15, 12, 31, 9, 10, 34, 48, 60, 29, 16, 10, -17, -24, -21, -27, -31, -17, 5, 14, 12, -22, -50, -48, -41, -9, 7, 13, -1, -8, -2, -11, -5, 26, 19, 6, 21, 37, 55, 49, 25, 22, -5, -20, -24, -26, -29, -23, -9, 8, 13, -1, -41, -48, -47, -30, -3, 12, 7, -12, -2, 1, -8, 10, 20, 11, 16, 26, 40, 54, 42, 36, 7, -13, -18, -26, -29, -26, -14, -2, 7, 8, -18, -45, -48, -45, -19, 6, 11, -10, -8, 5, -7, 2, 12, 17, 15, 16, 23, 45, 55, 48, 27, -7, -12, -18, -30, -31, -17, -5, -3, 4, 5, -24, -40, -50, -38, -8, 8, 1, -13, 1, -1, 3, 8, 15, 18, 15, 15, 28, 52, 59, 47, 9, -9, -10, -25, -40, -29, -3, -5, -13, 1, 3, -26, -47, -53, -23, -2, 5, -11, -6, 4, 6, 10, 10, 19, 11, 13, 15, 42, 61, 61, 32, 3, -5, -12, -35, -43, -14, 1, -16, -13, 9, -1, -33, -57, -46, -19, -3, -1, -16, -2, 5, 15, 6, 17, 9, 5, 9, 26, 54, 65, 52, 21, 3, -6, -21, -48, -33, -4, -7, -22, -2, 18, -4, -47, -58, -33, -11, 2, -13, -15, 3, 16, 15, 9, 15, -1, 5, 14, 48, 66, 65, 37, 23, 2, -11, -42, -48, -20, -4, -23, -18, 18, 19, -17, -61, -52, -27, -2, -5, -24, -7, 9, 20, 14, 18, 2, -3, 7, 34, 63, 68, 50, 37, 19, -9, -25, -49, -38, -14, -14, -28, 6, 25, 9, -40, -62, -45, -17, 3, -21, -16, -3, 12, 18, 18, 10, -6, 0, 16, 56, 69, 63, 43, 38, 2, -20, -42, -44, -33, -14, -25, -10, 22, 18, -11, -55, -57, -37, -3, -10, -26, -10, 2, 17, 21, 20, -3, -2, 5, 39, 67, 73, 56, 47, 22, -17, -35, -43, -36, -28, -18, -20, 9, 22, 8, -33, -56, -53, -26, -2, -23, -24, -11, 4, 23, 30, 4, -3, 0, 27, 60, 71, 69, 58, 43, -6, -35, -43, -35, -36, -27, -18, -2, 19, 17, -9, -41, -51, -45, -10, -12, -31, -21, -9, 8, 33, 17, 0, 2, 8, 50, 69, 75, 70, 64, 16, -31, -47, -35, -32, -34, -25, -14, 10, 16, 5, -26, -42, -50, -32, -8, -22, -31, -22, -8, 22, 32, 7, 6, 4, 28, 63, 69, 71, 78, 43, -20, -51, -41, -23, -34, -30, -22, 2, 13, 9, -10, -31, -45, -44, -21, -19, -27, -36, -26, 2, 29, 24, 12, 11, 13, 45, 69, 68, 81, 70, 6, -47, -52, -28, -23, -27, -26, -14, 11, 10, -2, -18, -33, -43, -34, -25, -22, -36, -44, -14, 14, 29, 27, 22, 18, 29, 60, 65, 71, 86, 41, -32, -57, -41, -23, -22, -22, -24, -4, 10, 0, -11, -21, -31, -37, -37, -29, -29, -53, -33, -3, 16, 33, 31, 27, 23, 46, 64, 65, 85, 71, -4, -48, -47, -31, -20, -15, -15, -19, 1, 0, -5, -14, -21, -26, -40, -39, -28, -51, -50, -18, 4, 26, 38, 36, 30, 32, 61, 64, 70, 80, 31, -35, -43, -40, -25, -19, -6, -17, -11, 0, -6, -11, -17, -15, -31, -47, -39, -45, -62, -34, -8, 12, 36, 38, 41, 37, 51, 65, 60, 71, 56, -7, -36, -38, -35, -27, -11, -5, -17, -8, -8, -9, -17, -13, -20, -37, -47, -50, -62, -49, -16, 1, 25, 34, 43, 53, 49, 62, 58, 62, 65, 22, -23, -31, -34, -35, -19, -3, -8, -18, -7, -4, -14, -17, -9, -27, -40, -56, -68, -64, -27, -4, 9, 28, 37, 54, 60, 61, 59, 54, 63, 43, -1, -25, -23, -37, -28, -8, 4, -10, -15, -3, -7, -26, -15, -11, -29, -51, -71, -71, -49, -8, 5, 14, 30, 48, 66, 68, 63, 51, 56, 51, 18, -18, -20, -25, -39, -23, -5, 3, -13, -6, -5, -21, -28, -10, -18, -43, -67, -78, -64, -25, 1, 8, 15, 38, 60, 75, 74, 58, 54, 57, 28, -7, -18, -8, -31, -34, -15, 4, -2, -4, 0, -15, -32, -21, -8, -28, -57, -77, -75, -44, -12, 6, 8, 20, 49, 68, 77, 71, 53, 61, 41, 3, -18, -4, -14, -36, -28, -7, 1, 7, 6, -8, -34, -35, -16, -15, -41, -66, -75, -59, -31, -4, 10, 11, 31, 56, 72, 85, 63, 58, 55, 14, -17, -10, -1, -24, -30, -22, -6, 11, 16, 9, -27, -43, -27, -15, -26, -53, -63, -66, -46, -21, 3, 13, 15, 40, 63, 83, 78, 60, 67, 38, -9, -20, 4, -7, -23, -25, -22, 6, 24, 20, -8, -48, -43, -24, -16, -39, -55, -57, -57, -36, -10, 9, 11, 22, 50, 73, 88, 71, 65, 59, 14, -24, -9, -3, -15, -18, -31, -14, 25, 28, 10, -36, -56, -41, -21, -29, -48, -47, -51, -50, -26, -2, 11, 6, 30, 57, 82, 83, 69, 65, 35, -12, -16, -3, -10, -12, -21, -26, 11, 33, 26, -7, -56, -54, -32, -26, -41, -39, -37, -52, -41, -16, 5, 7, 11, 37, 72, 91, 78, 66, 55, 11, -19, -14, -15, -9, -7, -19, -8, 22, 30, 13, -32, -62, -44, -31, -34, -40, -29, -40, -46, -29, -8, 2, 1, 18, 49, 84, 86, 72, 67, 39, -6, -21, -25, -16, 2, -6, -12, 6, 23, 18, -7, -51, -56, -39, -33, -41, -30, -24, -41, -36, -17, -8, -5, 7, 32, 66, 84, 78, 75, 58, 20, -15, -29, -33, 2, 4, -1, 1, 11, 17, 4, -27, -56, -46, -36, -37, -39, -22, -24, -38, -23, -16, -16, -7, 18, 46, 72, 82, 81, 72, 44, -1, -25, -41, -18, 14, 8, 10, 0, 5, 2, -11, -40, -50, -42, -38, -37, -33, -11, -27, -26, -20, -22, -13, 0, 31, 52, 73, 82, 80, 61, 26, -16, -37, -40, 0, 18, 17, 12, -5, -8, -10, -21, -41, -43, -44, -36, -35, -20, -12, -23, -14, -32, -21, -12, 15, 38, 58, 76, 82, 72, 46, 4, -26, -41, -23, 14, 25, 18, 2, -23, -18, -14, -29, -35, -45, -42, -35, -29, -15, -19, -3, -23, -32, -19, -1, 27, 40, 67, 81, 76, 61, 26, -11, -33, -36, -6, 28, 28, 13, -15, -38, -19, -20, -26, -36, -46, -35, -32, -20, -21, -4, -4, -28, -25, -16, 13, 31, 49, 74, 79, 69, 48, 8, -16, -33, -21, 7, 33, 24, 5, -32, -38, -22, -21, -22, -41, -43, -32, -25, -23, -16, 6, -9, -29, -28, -5, 20, 39, 58, 75, 71, 60, 22, 0, -18, -27, -10, 16, 30, 15, -14, -49, -34, -19, -16, -27, -43, -31, -25, -27, -24, -1, 7, -15, -32, -22, 3, 28, 50, 61, 67, 59, 38, 13, 5, -17, -16, -3, 21, 23, 3, -34, -49, -28, -17, -19, -34, -34, -18, -26, -32, -16, 14, 6, -23, -34, -11, 14, 44, 54, 56, 60, 44, 25, 18, 2, -18, -9, 3, 21, 9, -14, -45, -39, -24, -22, -28, -32, -18, -17, -36, -30, 5, 21, -5, -31, -27, 1, 30, 56, 46, 50, 47, 32, 29, 20, -4, -9, -9, 4, 10, -2, -28, -38, -31, -33, -26, -26, -19, -9, -24, -38, -11, 24, 10, -17, -36, -14, 14, 48, 49, 37, 43, 39, 33, 32, 11, 1, -5, -11, -6, -3, -16, -29, -28, -40, -38, -27, -20, -6, -11, -31, -29, 15, 22, 0, -25, -25, 2, 31, 51, 38, 35, 41, 41, 34, 27, 8, 6, -7, -20, -14, -7, -20, -19, -34, -52, -35, -23, -11, -5, -18, -33, -5, 26, 5, -11, -27, -11, 17, 43, 43, 30, 29, 46, 45, 38, 17, 6, 2, -22, -27, -16, -16, -18, -18, -53, -48, -23, -19, -3, -10, -21, -19, 18, 12, -6, -20, -21, 6, 29, 42, 31, 23, 37, 54, 48, 31, 13, 13, -13, -31, -25, -16, -16, -11, -38, -62, -33, -28, -7, -3, -12, -17, 6, 16, 2, -11, -17, -5, 15, 35, 34, 25, 23, 44, 55, 41, 22, 14, 2, -29, -32, -23, -11, -13, -18, -60, -50, -32, -16, -6, -11, -4, 3, 11, 3, -1, -14, -8, 5, 20, 39, 31, 24, 26, 54, 57, 37, 16, 8, -19, -32, -27, -17, -17, -17, -36, -58, -40, -32, -11, -11, -2, 6, 10, 2, 0, -4, -12, 1, 8, 33, 42, 26, 17, 35, 63, 53, 26, 6, -9, -27, -30, -25, -17, -23, -24, -47, -51, -38, -17, -11, -6, 12, 17, 8, -8, -1, -10, -7, 4, 18, 40, 33, 18, 22, 49, 70, 46, 12, -11, -16, -23, -27, -19, -28, -26, -36, -50, -48, -31, -13, -13, 10, 20, 21, 0, -6, -1, -7, 3, 15, 32, 40, 24, 17, 31, 58, 67, 28, -2, -21, -14, -31, -18, -24, -33, -33, -49, -49, -41, -18, -20, -2, 20, 23, 19, -12, -7, -2, -3, 10, 22, 33, 37, 21, 23, 39, 72, 51, 10, -17, -18, -20, -29, -17, -33, -36, -49, -48, -47, -24, -16, -15, 11, 24, 30, 6, -12, -2, -2, -1, 18, 29, 35, 27, 25, 25, 56, 63, 23, -5, -19, -14, -23, -21, -21, -38, -52, -54, -40, -32, -15, -23, -7, 18, 31, 22, -2, -7, 3, 0, 12, 21, 34, 31, 28, 22, 35, 66, 40, 2, -19, -19, -15, -21, -16, -30, -60, -62, -42, -33, -18, -18, -22, 4, 29, 29, 14, -2, -4, 5, 6, 16, 28, 36, 24, 29, 26, 52, 49, 14, -13, -24, -19, -14, -15, -17, -53, -75, -54, -32, -18, -11, -26, -18, 18, 28, 25, 13, -6, 4, 13, 9, 17, 37, 24, 28, 33, 37, 49, 26, 1, -19, -26, -16, -11, -7, -33, -77, -71, -45, -15, -8, -18, -30, 1, 25, 21, 26, 3, 5, 17, 14, 11, 33, 27, 17, 34, 38, 42, 33, 6, -11, -28, -22, -12, -3, -16, -60, -81, -62, -25, -2, -14, -27, -17, 20, 18, 24, 18, 6, 16, 21, 12, 24, 28, 12, 26, 44, 42, 35, 13, -5, -21, -31, -18, -2, -2, -42, -77, -76, -47, -10, -6, -22, -24, 4, 16, 18, 25, 18, 18, 24, 20, 20, 32, 14, 11, 40, 49, 41, 21, -6, -13, -27, -28, -5, 5, -18, -59, -79, -63, -30, -6, -11, -28, -11, 8, 10, 23, 27, 17, 24, 25, 25, 28, 19, 8, 25, 47, 46, 27, -5, -15, -18, -33, -20, -5, -3, -35, -70, -66, -51, -22, -7, -21, -19, -3, 6, 17, 29, 26, 23, 28, 25, 32, 23, 14, 11, 39, 50, 38, 3, -19, -10, -21, -29, -12, -3, -12, -55, -65, -56, -42, -14, -10, -23, -11, -3, 10, 23, 32, 26, 28, 28, 35, 29, 22, 13, 18, 41, 43, 18, -16, -18, -14, -29, -21, -11, -8, -32, -61, -52, -52, -30, -11, -18, -16, -10, 2, 22, 35, 30, 25, 32, 34, 40, 27, 19, 11, 23, 39, 32, -1, -22, -14, -22, -23, -14, -11, -17, -45, -52, -51, -51, -22, -17, -19, -17, -10, 11, 35, 39, 29, 26, 34, 43, 43, 27, 16, 12, 25, 31, 18, -13, -20, -19, -22, -12, -14, -15, -28, -44, -47, -53, -33, -15, -22, -24, -20, 5, 27, 38, 31, 21, 27, 46, 51, 40, 18, 8, 13, 23, 24, 3, -21, -22, -22, -8, -9, -22, -26, -31, -40, -51, -44, -17, -15, -26, -31, -10, 24, 35, 37, 25, 21, 42, 57, 53, 30, 11, 7, 11, 21, 12, -11, -23, -25, -12, 0, -18, -32, -31, -30, -45, -46, -26, -13, -25, -39, -25, 15, 36, 29, 25, 20, 37, 58, 63, 46, 15, 3, -2, 19, 16, -2, -19, -25, -23, 4, -4, -31, -36, -29, -32, -43, -37, -17, -16, -39, -43, -2, 34, 31, 21, 17, 30, 62, 67, 62, 27, 9, -9, 3, 26, 8, -18, -26, -26, -5, 9, -23, -44, -33, -26, -33, -40, -28, -12, -30, -52, -24, 23, 33, 15, 14, 22, 54, 75, 68, 47, 14, -9, -12, 19, 23, -12, -20, -20, -13, 11, -6, -40, -41, -19, -23, -34, -34, -14, -13, -48, -48, 4, 35, 23, 7, 13, 40, 77, 78, 57, 31, -3, -18, 3, 27, 7, -24, -19, -16, 1, 5, -29, -49, -28, -13, -26, -34, -26, -4, -30, -57, -24, 22, 30, 6, 7, 31, 63, 86, 68, 42, 10, -19, -13, 15, 25, -10, -22, -14, -7, 6, -11, -45, -40, -14, -24, -35, -31, -12, -8, -51, -44, -2, 29, 11, -1, 22, 47, 74, 78, 49, 25, -8, -26, -4, 26, 12, -16, -19, -11, -1, -1, -28, -45, -22, -13, -29, -29, -23, -1, -26, -55, -26, 14, 20, -3, 13, 39, 63, 80, 61, 33, 8, -22, -25, 10, 22, -1, -14, -15, -7, -1, -14, -37, -26, -13, -25, -28, -26, -2, -5, -48, -44, -7, 18, 3, 9, 30, 49, 71, 70, 45, 23, -13, -33, -5, 22, 11, -7, -17, -14, -6, -8, -29, -29, -15, -19, -26, -31, -15, 6, -25, -52, -30, 7, 7, 2, 21, 40, 60, 67, 52, 33, 7, -29, -19, 16, 22, 4, -8, -15, -11, -6, -23, -24, -10, -11, -23, -27, -22, 1, 0, -34, -45, -14, 2, 1, 15, 35, 52, 62, 49, 36, 21, -16, -26, 1, 20, 12, -7, -10, -20, -10, -19, -28, -9, -8, -15, -26, -27, -11, 2, -15, -41, -34, -10, -7, 6, 32, 48, 56, 51, 35, 26, 1, -24, -10, 15, 18, 2, -9, -17, -18, -11, -32, -6, 2, -9, -18, -22, -17, -3, -2, -21, -34, -26, -13, -8, 20, 47, 53, 52, 38, 24, 5, -14, -15, 9, 14, 4, -6, -14, -21, -14, -28, -22, 12, 0, -10, -23, -24, -13, 2, -10, -23, -34, -26, -13, 4, 39, 58, 51, 45, 28, 6, -9, -11, 3, 17, 7, -3, -10, -18, -15, -22, -35, 2, 18, 2, -11, -23, -20, -1, 0, -15, -24, -39, -25, -6, 17, 52, 56, 47, 35, 6, -10, -8, 0, 13, 13, -2, -9, -13, -13, -25, -43, -16, 21, 19, -3, -21, -25, -10, 2, -5, -14, -30, -40, -13, -1, 34, 58, 51, 44, 18, -10, -9, -2, 6, 12, 7, -7, -12, -12, -18, -40, -33, 9, 32, 19, -9, -23, -15, 1, 3, -9, -18, -40, -28, -4, 7, 47, 59, 49, 24, 1, -13, -5, 1, 10, 11, 5, -12, -12, -15, -35, -42, -9, 23, 33, 9, -22, -24, -5, 1, -5, -12, -30, -40, -7, -3, 22, 56, 58, 35, 11, -12, -9, -5, -1, 7, 13, -4, -13, -13, -25, -43, -29, 10, 34, 32, -6, -27, -8, 3, -5, -13, -22, -40, -18, -3, -1, 37, 61, 46, 23, -5, -13, -4, -4, -7, 12, 14, -10, -18, -22, -34, -35, -10, 22, 39, 23, -15, -14, 5, 3, -8, -15, -36, -23, -1, -7, 14, 51, 57, 37, 8, -13, -7, -2, -14, -6, 20, 3, -21, -26, -27, -30, -27, 1, 28, 36, 7, -10, 0, 5, -8, -14, -30, -29, -3, -10, -5, 31, 56, 46, 19, -7, -10, 3, -11, -21, 9, 19, -10, -30, -29, -19, -24, -20, 10, 35, 29, 8, -1, 5, -2, -13, -28, -33, -3, -1, -13, 12, 49, 55, 31, -1, -12, 2, -3, -26, -2, 21, 2, -28, -34, -21, -17, -29, -12, 23, 34, 19, 6, 7, 4, -4, -23, -40, -10, 7, -12, -2, 34, 55, 36, 8, -10, 1, 3, -19, -18, 15, 15, -10, -33, -30, -9, -19, -25, 4, 32, 30, 16, 11, 10, 3, -15, -35, -27, 9, -4, -10, 16, 52, 42, 12, -7, -6, 4, -6, -21, -2, 17, 0, -20, -41, -13, -9, -31, -16, 18, 34, 23, 14, 9, 10, -7, -26, -34, -3, 10, -10, 2, 42, 51, 16, -8, -11, -2, -2, -11, -9, 9, 2, -8, -36, -31, 3, -23, -30, -1, 27, 27, 23, 15, 18, 3, -17, -31, -19, 8, 1, -4, 24, 51, 30, -11, -16, -6, -3, -5, -10, 3, 1, -10, -22, -41, -4, -6, -29, -18, 12, 25, 26, 23, 20, 11, -10, -21, -27, -4, 7, 0, 13, 41, 40, 3, -24, -11, -1, -2, -3, 5, 5, -14, -15, -35, -20, 0, -19, -24, -4, 11, 23, 31, 24, 16, -3, -13, -23, -14, 2, 3, 18, 32, 38, 21, -20, -29, -5, -2, 0, 5, 11, -14, -22, -25, -26, -3, -11, -26, -11, -2, 8, 32, 34, 24, 2, -8, -16, -13, 1, 1, 10, 31, 31, 33, 1, -36, -22, 0, 0, 8, 18, -3, -27, -22, -22, -10, -9, -24, -16, -5, -16, 16, 40, 34, 8, -3, -13, -12, 1, 1, 3, 30, 30, 24, 18, -28, -35, -13, -2, 6, 19, 10, -25, -28, -15, -9, -10, -19, -20, -3, -15, -8, 27, 42, 25, 1, -14, -18, 7, 9, -1, 19, 37, 19, 23, -10, -41, -26, -9, 2, 20, 19, -17, -35, -21, 0, -9, -18, -20, -7, -8, -24, 6, 37, 43, 14, -10, -22, 3, 18, 4, 6, 36, 23, 16, 4, -32, -37, -19, -3, 17, 27, 0, -37, -34, -3, 7, -17, -27, -19, -1, -20, -13, 17, 44, 35, 2, -22, -9, 19, 20, 2, 26, 32, 15, 5, -17, -40, -29, -9, 10, 28, 17, -23, -41, -21, 9, -2, -27, -30, -5, -7, -21, -4, 27, 47, 27, -14, -21, 11, 29, 14, 15, 32, 20, 4, -11, -31, -38, -15, 2, 22, 22, -3, -32, -34, -6, 8, -13, -38, -19, 0, -16, -14, 6, 37, 39, 11, -18, -4, 25, 25, 16, 24, 27, 7, -10, -24, -38, -25, 0, 12, 23, 8, -16, -31, -23, 0, 0, -27, -33, -2, -9, -16, -11, 17, 41, 32, 5, -15, 12, 25, 24, 21, 27, 14, -4, -21, -31, -29, -4, 9, 19, 9, -9, -19, -25, -10, -5, -15, -38, -13, -6, -13, -17, -1, 30, 36, 27, -2, 2, 20, 24, 25, 24, 19, 2, -16, -32, -29, -13, 8, 18, 16, -6, -13, -21, -15, -14, -13, -26, -22, -6, -11, -14, -14, 11, 30, 37, 17, 1, 13, 20, 23, 24, 21, 5, -10, -32, -31, -15, 0, 17, 22, -3, -15, -17, -11, -15, -19, -23, -22, -8, -8, -13, -18, -8, 18, 40, 38, 12, 12, 15, 21, 23, 24, 7, -9, -22, -34, -19, -6, 11, 30, 9, -17, -20, -16, -11, -22, -30, -27, -8, -7, -10, -19, -16, -2, 32, 52, 31, 17, 16, 13, 21, 19, 19, -9, -17, -30, -25, -7, 3, 29, 25, -9, -21, -20, -11, -14, -29, -37, -14, 2, -5, -14, -22, -12, 13, 50, 49, 27, 23, 15, 13, 9, 18, 7, -22, -22, -28, -11, -5, 19, 35, 13, -20, -24, -18, -8, -22, -38, -31, 2, 3, -6, -26, -22, -3, 38, 56, 42, 34, 21, 12, 6, 11, 17, -15, -24, -20, -15, -6, 9, 29, 29, -4, -28, -23, -14, -13, -30, -39, -16, 9, 6, -12, -33, -16, 19, 57, 49, 41, 30, 13, 4, -1, 6, -4, -27, -21, -13, -6, 2, 12, 34, 12, -24, -24, -20, -16, -24, -38, -33, 2, 12, -2, -30, -31, 2, 45, 59, 46, 41, 24, 8, -3, -6, 1, -15, -25, -16, -3, 5, 2, 21, 28, -11, -26, -23, -18, -20, -32, -40, -14, 14, 11, -10, -40, -20, 30, 60, 55, 42, 34, 15, 6, -12, -12, -4, -19, -21, -9, 8, 4, 10, 28, 6, -25, -22, -20, -22, -29, -38, -27, 5, 16, 4, -24, -39, 12, 51, 61, 51, 41, 27, 10, -7, -25, -9, -10, -17, -15, 0, 9, 5, 21, 15, -13, -27, -17, -21, -23, -38, -33, -11, 10, 6, -4, -38, -17, 36, 55, 55, 45, 35, 21, 4, -27, -25, -2, -10, -14, -13, 3, 5, 14, 16, 0, -24, -21, -18, -22, -36, -39, -17, -3, 5, 3, -15, -28, 16, 50, 53, 52, 43, 29, 13, -14, -36, -10, -1, -15, -15, -6, 6, 5, 13, 4, -11, -24, -17, -18, -27, -43, -18, -12, -7, 4, 3, -17, -4, 38, 53, 52, 48, 41, 23, 0, -31, -30, 2, -7, -14, -13, -5, 3, 11, 7, -4, -21, -25, -21, -19, -39, -23, -9, -19, -8, 5, -1, -10, 24, 46, 48, 46, 44, 32, 10, -18, -37, -7, 0, -12, -14, -13, -4, 8, 9, 1, -16, -29, -28, -17, -33, -31, -6, -21, -21, -4, 12, 3, 13, 41, 46, 44, 46, 44, 20, -7, -36, -27, 6, -3, -18, -21, -12, 2, 12, 6, -5, -27, -36, -21, -20, -34, -12, -8, -29, -16, 11, 15, 10, 28, 47, 46, 41, 45, 35, 5, -24, -30, -5, 3, -14, -26, -16, -7, 7, 8, -3, -18, -39, -32, -16, -28, -26, -8, -23, -26, 0, 19, 16, 20, 42, 55, 45, 38, 39, 20, -11, -24, -13, -2, -6, -25, -22, -7, -5, 13, 0, -11, -36, -41, -20, -16, -29, -16, -14, -28, -12, 13, 17, 15, 32, 50, 57, 41, 38, 30, 2, -14, -9, -3, -3, -19, -33, -10, -7, 7, 7, -13, -30, -42, -28, -13, -17, -26, -14, -22, -15, 7, 19, 15, 26, 46, 59, 51, 34, 33, 12, -7, -11, -4, -5, -13, -38, -23, -3, 3, 15, -7, -32, -45, -34, -21, -11, -27, -25, -21, -19, -1, 13, 15, 22, 37, 53, 62, 46, 34, 15, -2, 0, -4, -8, -9, -34, -38, -8, 4, 17, 3, -25, -50, -44, -26, -12, -13, -32, -24, -20, -7, 11, 18, 17, 33, 50, 65, 57, 41, 24, 0, 5, 5, -9, -11, -25, -44, -25, -1, 17, 13, -18, -42, -51, -33, -20, -7, -27, -29, -23, -16, 0, 14, 14, 28, 48, 60, 66, 51, 34, 4, 0, 15, -3, -14, -20, -35, -37, -12, 12, 27, -7, -37, -50, -40, -29, -15, -15, -30, -24, -15, -7, 6, 17, 25, 46, 59, 68, 63, 43, 20, -6, 14, 10, -8, -20, -30, -34, -22, -2, 24, 15, -30, -49, -49, -37, -28, -15, -26, -28, -18, -11, -7, 7, 27, 42, 58, 70, 70, 53, 35, 4, 0, 18, -1, -15, -32, -31, -26, -12, 12, 28, -4, -44, -53, -44, -39, -25, -23, -28, -19, -11, -12, -16, 13, 42, 56, 71, 71, 57, 45, 23, -3, 10, 11, -6, -27, -35, -25, -22, -1, 23, 17, -29, -54, -46, -44, -39, -29, -28, -21, -15, -15, -26, -12, 39, 57, 70, 73, 60, 49, 41, 13, 1, 11, 0, -16, -32, -25, -15, -14, 10, 23, -5, -48, -46, -42, -49, -43, -31, -24, -15, -13, -24, -32, 18, 59, 71, 77, 67, 57, 47, 33, 3, 5, 5, -9, -23, -33, -16, -14, -5, 17, 12, -29, -44, -35, -50, -57, -43, -30, -18, -11, -22, -39, -9, 44, 68, 82, 69, 61, 49, 42, 18, 5, 5, -8, -12, -26, -14, -7, -9, 5, 16, -6, -36, -32, -42, -62, -55, -39, -29, -15, -14, -34, -30, 20, 59, 82, 79, 66, 58, 45, 38, 9, 1, -7, -11, -16, -19, -3, -6, -6, 9, 5, -22, -32, -32, -58, -70, -56, -42, -24, -16, -25, -39, -9, 41, 72, 86, 73, 65, 46, 40, 30, -4, -7, -14, -12, -20, -3, 4, -5, 1, 8, -9, -27, -25, -40, -67, -67, -55, -38, -24, -17, -25, -28, 16, 61, 81, 82, 71, 60, 37, 42, 17, -14, -17, -11, -13, -8, 10, 2, -2, 1, -1, -17, -20, -26, -54, -69, -70, -58, -34, -25, -16, -23, -9, 37, 70, 87, 80, 68, 44, 38, 39, -5, -27, -19, -12, -6, 13, 10, 4, 1, 1, -5, -19, -20, -37, -59, -71, -71, -54, -35, -17, -9, -20, 11, 49, 80, 86, 72, 54, 36, 45, 23, -25, -34, -16, -9, 11, 17, 8, 5, -4, -2, -15, -19, -26, -50, -69, -77, -71, -51, -29, -7, -11, -6, 26, 64, 87, 78, 60, 40, 42, 45, 2, -38, -34, -12, 10, 24, 10, 11, 3, -1, -6, -20, -16, -31, -61, -81, -80, -69, -41, -16, -5, -8, 10, 47, 81, 86, 70, 44, 36, 48, 32, -21, -48, -31, -3, 24, 24, 10, 15, 0, 2, -17, -21, -18, -45, -81, -87, -80, -57, -33, -11, -6, 2, 30, 74, 86, 77, 55, 34, 42, 48, 13, -39, -50, -20, 15, 34, 14, 16, 12, 4, -5, -26, -16, -19, -64, -92, -91, -65, -43, -26, -12, -1, 16, 47, 83, 76, 66, 40, 33, 45, 33, -8, -52, -41, -5, 32, 30, 15, 25, 13, 8, -22, -28, -11, -34, -85, -101, -86, -52, -36, -25, -13, 15, 32, 69, 80, 69, 52, 32, 37, 39, 19, -30, -54, -24, 10, 38, 25, 25, 22, 18, -6, -35, -20, -14, -59, -98, -99, -68, -41, -30, -23, 5, 28, 52, 74, 67, 59, 43, 32, 35, 32, -2, -47, -38, -13, 23, 33, 31, 26, 27, 16, -29, -37, -15, -33, -80, -104, -89, -54, -35, -31, -11, 17, 42, 63, 68, 60, 59, 37, 27, 33, 22, -28, -37, -26, 3, 32, 38, 30, 25, 30, -3, -41, -29, -23, -55, -90, -98, -76, -39, -32, -21, 4, 36, 52, 61, 61, 63, 48, 24, 28, 34, -10, -31, -29, -14, 15, 37, 37, 28, 31, 19, -27, -40, -24, -38, -69, -95, -96, -60, -32, -26, -10, 19, 45, 53, 58, 59, 58, 29, 23, 39, 14, -21, -25, -23, 1, 27, 43, 34, 34, 21, 0, -36, -32, -31, -49, -84, -102, -83, -41, -22, -19, -1, 35, 49, 52, 53, 56, 39, 23, 34, 33, -3, -23, -22, -10, 17, 36, 36, 39, 26, 8, -16, -34, -29, -36, -61, -93, -95, -58, -26, -18, -11, 22, 48, 53, 53, 51, 41, 31, 33, 37, 16, -15, -24, -14, 4, 29, 34, 41, 32, 8, -7, -19, -28, -30, -54, -83, -101, -76, -40, -20, -21, 1, 36, 54, 55, 44, 33, 32, 35, 36, 30, 7, -26, -19, -5, 22, 36, 37, 37, 15, -3, -5, -15, -24, -43, -75, -94, -87, -47, -29, -25, -14, 26, 48, 62, 49, 29, 23, 35, 45, 38, 19, -16, -28, -7, 10, 29, 32, 38, 23, -2, -10, -6, -12, -28, -67, -90, -98, -59, -32, -28, -25, 3, 43, 56, 59, 25, 16, 24, 46, 43, 31, 0, -31, -14, 5, 25, 29, 32, 29, 6, -13, -6, -3, -8, -49, -85, -97, -75, -31, -30, -30, -12, 31, 50, 61, 40, 12, 14, 34, 53, 43, 20, -23, -20, -3, 21, 29, 23, 24, 15, -10, -8, -1, 2, -25, -75, -98, -92, -42, -31, -35, -24, 14, 41, 50, 49, 22, 11, 20, 45, 52, 39, 0, -26, -12, 9, 35, 25, 18, 14, 1, -13, -6, 4, 3, -49, -89, -102, -61, -27, -30, -27, -4, 34, 46, 46, 32, 17, 13, 26, 47, 50, 29, -19, -22, -4, 30, 37, 15, 7, 7, -5, -10, -4, 9, -20, -72, -100, -86, -41, -33, -31, -16, 18, 43, 34, 32, 27, 23, 15, 31, 47, 48, 9, -24, -16, 12, 43, 25, -2, 0, 9, -9, -15, 2, 8, -40, -87, -99, -69, -37, -31, -19, 6, 38, 35, 25, 31, 35, 26, 18, 36, 49, 40, -10, -22, -9, 29, 40, 6, -12, 6, 6, -16, -11, 9, -6, -61, -95, -90, -58, -35, -26, -5, 23, 36, 18, 21, 36, 41, 28, 22, 38, 52, 23, -17, -17, 7, 39, 21, -12, -13, 16, -8, -22, -5, 6, -25, -77, -93, -79, -46, -30, -11, 15, 36, 22, 5, 29, 47, 47, 24, 22, 41, 48, 7, -15, -4, 22, 33, 6, -23, 4, 8, -21, -15, -1, -5, -49, -79, -92, -71, -43, -20, 11, 31, 29, 4, 16, 40, 55, 41, 22, 31, 50, 25, -9, -2, 8, 23, 16, -17, -6, 8, -10, -15, -6, -4, -29, -56, -80, -86, -61, -42, 0, 30, 33, 12, 2, 24, 47, 55, 37, 28, 39, 40, 4, -1, 6, 6, 16, -4, -13, 1, -2, -9, -11, -11, -21, -35, -55, -82, -80, -64, -24, 27, 36, 23, 3, 10, 35, 61, 55, 40, 35, 35, 19, 6, 12, 4, 1, 3, -12, -3, -2, -4, -4, -14, -23, -30, -37, -58, -83, -84, -58, 8, 37, 33, 11, 3, 20, 46, 62, 55, 50, 28, 16, 12, 15, 9, -4, -9, -9, -4, -5, -7, 2, -7, -28, -35, -31, -36, -67, -90, -86, -23, 28, 38, 25, 5, 13, 34, 58, 58, 69, 50, 15, 10, 20, 16, -3, -14, -14, -2, 1, -12, -3, 3, -20, -36, -39, -26, -46, -81, -98, -61, 6, 27, 30, 16, 12, 25, 50, 57, 66, 74, 31, 4, 16, 21, 8, -13, -21, -10, 8, -5, -11, 6, -8, -31, -40, -29, -30, -66, -93, -84, -22, 17, 22, 26, 16, 20, 43, 56, 56, 70, 60, 17, 8, 18, 15, -10, -26, -21, 6, 7, -12, -1, 1, -20, -33, -34, -31, -51, -79, -92, -52, -6, 9, 19, 23, 21, 40, 57, 59, 60, 72, 43, 17, 13, 18, 3, -23, -32, -5, 14, -7, -11, 7, -12, -26, -31, -37, -46, -66, -85, -67, -21, -5, 3, 16, 22, 37, 54, 59, 55, 60, 58, 30, 16, 13, 11, -15, -34, -23, 9, 7, -12, -2, -4, -19, -16, -31, -49, -64, -76, -72, -35, -12, -14, 0, 15, 34, 53, 60, 58, 53, 57, 43, 30, 18, 12, -4, -27, -28, -8, 14, -3, -9, -2, -13, -9, -17, -49, -66, -70, -69, -44, -15, -19, -11, 2, 21, 53, 64, 68, 55, 48, 44, 36, 28, 15, -1, -18, -23, -19, -4, 5, -3, 1, -9, -7, -1, -35, -70, -74, -70, -50, -21, -14, -22, -7, -1, 39, 66, 77, 69, 46, 38, 36, 38, 22, 5, -12, -16, -12, -17, -8, -5, 2, 1, -6, 5, -13, -64, -78, -73, -60, -31, -14, -17, -16, -10, 7, 61, 79, 81, 57, 38, 28, 32, 24, 9, -4, -10, -4, -11, -20, -13, -2, 11, 4, 4, -2, -41, -76, -76, -69, -43, -22, -12, -17, -14, -14, 25, 74, 92, 79, 47, 31, 26, 26, 11, 3, -5, 0, 0, -20, -26, -11, 9, 14, 9, 4, -24, -61, -76, -74, -53, -30, -13, -8, -12, -25, -8, 51, 90, 93, 63, 42, 21, 18, 13, 6, 2, 1, 8, -12, -30, -27, -2, 14, 18, 11, -13, -48, -68, -79, -70, -44, -19, -2, -5, -21, -31, 18, 77, 100, 81, 55, 29, 7, 8, 6, 7, 4, 14, 0, -26, -34, -13, 9, 16, 17, 1, -35, -58, -70, -82, -62, -29, -2, 1, -14, -36, -15, 50, 89, 95, 71, 46, 5, -6, 4, 11, 3, 11, 14, -12, -31, -22, -2, 8, 16, 16, -15, -53, -56, -80, -81, -41, -5, 9, -3, -30, -34, 17, 73, 97, 86, 63, 25, -12, -6, 11, 13, 1, 15, 4, -19, -25, -5, 2, 9, 19, 10, -39, -48, -61, -95, -67, -17, 12, 8, -23, -43, -9, 49, 85, 91, 76, 50, 1, -23, 2, 22, 5, 2, 14, -5, -23, -12, 0, -2, 13, 17, -15, -48, -43, -83, -88, -38, 5, 17, -11, -41, -28, 27, 67, 83, 82, 65, 29, -21, -18, 21, 19, -7, 3, 6, -8, -14, 1, 0, 0, 13, 2, -34, -42, -59, -99, -63, -12, 17, 0, -35, -42, 1, 53, 69, 79, 72, 53, -1, -34, 2, 32, 3, -8, 1, 2, -2, -3, 8, -2, 3, 7, -18, -40, -39, -76, -81, -35, 9, 17, -22, -46, -24, 34, 59, 68, 74, 66, 27, -26, -22, 31, 24, -10, -11, 0, 14, 1, 5, 8, -5, -2, -10, -34, -35, -48, -77, -59, -13, 20, -4, -37, -35, 8, 47, 55, 68, 74, 49, -4, -34, 10, 39, 1, -13, -11, 14, 14, 3, 20, 6, -9, -14, -29, -37, -28, -56, -66, -42, 9, 9, -25, -38, -14, 27, 45, 54, 72, 61, 21, -25, -14, 31, 19, -10, -15, -2, 22, 6, 22, 24, -4, -20, -28, -38, -24, -28, -54, -57, -20, 14, -10, -29, -26, 2, 29, 39, 61, 66, 39, -6, -25, 16, 30, 0, -16, -8, 12, 13, 18, 38, 10, -20, -36, -34, -31, -16, -33, -56, -42, 0, 0, -21, -22, -12, 11, 25, 49, 68, 53, 14, -20, -3, 29, 15, -11, -12, 3, 13, 13, 42, 34, -12, -39, -37, -27, -22, -18, -44, -50, -21, 3, -12, -15, -18, -5, 9, 27, 60, 60, 32, -6, -12, 21, 25, -4, -12, -2, 7, 8, 33, 53, 8, -37, -41, -25, -22, -16, -27, -47, -34, -10, -10, -15, -15, -15, -5, 5, 41, 63, 44, 12, -11, 10, 32, 10, -14, -8, 8, 5, 19, 53, 34, -24, -43, -25, -14, -15, -19, -35, -35, -20, -12, -8, -14, -17, -19, -13, 19, 55, 53, 22, -8, 4, 31, 26, -8, -13, 6, 10, 7, 39, 50, -2, -41, -31, -10, -13, -23, -31, -33, -24, -15, -7, -13, -16, -22, -23, -6, 38, 55, 34, 1, -1, 23, 34, 9, -18, -3, 14, 9, 20, 51, 24, -28, -37, -6, 2, -20, -30, -27, -21, -22, -6, -12, -17, -21, -32, -27, 9, 49, 43, 12, -4, 14, 34, 24, -9, -12, 12, 19, 13, 30, 37, -3, -35, -15, 12, -10, -31, -30, -15, -18, -13, -3, -19, -20, -31, -35, -17, 28, 44, 22, 0, 7, 28, 27, 5, -15, 1, 20, 20, 17, 28, 19, -21, -23, 12, 8, -22, -32, -20, -8, -15, 0, -13, -23, -25, -43, -36, 4, 37, 30, 11, 4, 22, 28, 15, 0, -10, 9, 23, 14, 11, 24, 5, -21, 2, 17, -8, -27, -27, -7, -10, -6, -1, -20, -26, -39, -53, -20, 23, 36, 17, 7, 14, 28, 16, 12, -3, 2, 19, 16, 2, 14, 19, -8, -5, 17, 4, -15, -26, -10, -4, -12, 1, -8, -23, -38, -58, -41, 0, 29, 23, 11, 16, 21, 15, 9, 11, -6, 11, 20, 4, 3, 24, 5, -5, 10, 17, -6, -15, -15, 6, -15, -8, 0, -11, -37, -54, -56, -24, 13, 29, 12, 15, 20, 19, 6, 16, 5, -2, 10, 11, -3, 22, 18, 0, 6, 20, 10, -6, -12, 1, -6, -23, 0, 1, -23, -56, -60, -43, -10, 19, 22, 15, 22, 18, 6, 11, 17, -2, -5, 10, 4, 7, 23, 1, 3, 16, 22, 5, -1, 0, 5, -21, -14, 6, -6, -46, -64, -54, -29, 1, 17, 18, 24, 25, 10, 1, 17, 9, -8, -1, 15, 6, 20, 11, 2, 14, 25, 16, 9, 5, 7, -11, -26, -5, 4, -27, -62, -62, -40, -17, 8, 11, 21, 29, 17, -2, 10, 17, -8, -16, 6, 13, 11, 15, 3, 8, 24, 26, 14, 12, 12, 4, -26, -15, 1, -12, -50, -64, -48, -27, -10, 5, 8, 32, 31, 1, -1, 18, 0, -23, -6, 18, 14, 11, 5, 3, 17, 35, 25, 16, 18, 14, -11, -27, -8, -6, -30, -55, -53, -36, -20, -5, 5, 14, 43, 13, -6, 11, 11, -22, -22, 7, 19, 13, 10, 1, 7, 30, 36, 22, 23, 23, 6, -28, -20, -6, -23, -43, -49, -43, -29, -19, 3, 1, 34, 29, -4, 3, 13, -13, -32, -3, 20, 14, 11, 5, 2, 23, 42, 34, 22, 23, 21, -13, -26, -14, -19, -32, -38, -43, -32, -29, -6, 4, 16, 35, 9, -4, 11, 0, -33, -22, 9, 13, 12, 9, 3, 14, 35, 47, 34, 23, 27, 8, -22, -19, -16, -30, -29, -42, -33, -32, -23, 4, 9, 24, 20, -1, 3, 10, -20, -36, -5, 13, 9, 11, 8, 8, 21, 43, 48, 27, 22, 23, -7, -25, -20, -28, -25, -31, -36, -28, -33, -8, 11, 14, 14, 6, -8, 7, -5, -39, -25, 7, 14, 9, 10, 12, 15, 29, 55, 41, 23, 22, 9, -12, -23, -28, -24, -23, -34, -26, -31, -21, 9, 19, 9, 1, -3, -1, 7, -32, -38, -9, 13, 11, 9, 11, 14, 21, 46, 53, 32, 24, 12, -2, -16, -26, -24, -17, -34, -33, -25, -24, -4, 17, 14, -3, -4, -7, 3, -13, -46, -25, 2, 17, 5, 8, 12, 18, 32, 56, 38, 29, 15, 8, -4, -22, -30, -14, -22, -42, -25, -15, -10, 6, 17, 1, -5, -7, -10, -2, -38, -37, -7, 15, 9, 2, 8, 21, 26, 43, 44, 29, 18, 7, 12, -9, -25, -24, -11, -35, -43, -17, -5, 3, 10, 9, -3, -3, -23, -9, -23, -45, -22, 7, 15, 2, 4, 17, 33, 31, 45, 35, 23, 8, 17, 6, -16, -26, -14, -20, -48, -27, -2, 6, 11, 9, -1, 6, -15, -28, -18, -39, -32, -7, 11, 7, 6, 7, 33, 30, 31, 41, 27, 7, 13, 24, -3, -18, -22, -9, -40, -41, -10, 4, 9, 17, 3, 5, -4, -37, -29, -29, -35, -19, 1, 10, 3, 7, 25, 41, 19, 31, 32, 13, 5, 27, 14, -6, -19, -12, -23, -48, -22, 7, 8, 16, 11, 1, 6, -29, -46, -32, -32, -20, -5, 7, 4, 3, 21, 43, 32, 15, 29, 16, 8, 19, 26, 3, -9, -22, -13, -42, -37, -8, 11, 14, 25, 9, 4, -17, -50, -44, -30, -25, -14, -1, 11, 1, 18, 36, 41, 12, 14, 18, 14, 15, 20, 17, 6, -14, -18, -27, -39, -19, 5, 12, 24, 27, 8, -13, -49, -53, -32, -27, -19, -12, 7, 7, 12, 31, 43, 26, 2, 8, 14, 22, 13, 17, 18, 6, -17, -26, -36, -28, -6, 14, 25, 35, 20, -6, -42, -57, -37, -23, -23, -20, 0, 9, 8, 25, 41, 40, 7, -4, 1, 23, 21, 14, 22, 20, -2, -24, -34, -31, -13, 8, 24, 37, 33, 8, -32, -62, -44, -20, -22, -27, -9, 9, 7, 16, 31, 42, 20, -10, -13, 10, 26, 7, 13, 25, 18, -11, -35, -39, -20, 0, 17, 37, 37, 19, -17, -58, -55, -26, -18, -25, -21, 0, 14, 12, 20, 38, 35, 0, -19, -9, 24, 19, 3, 21, 31, 17, -24, -42, -30, -3, 13, 34, 42, 28, -2, -45, -62, -38, -22, -19, -20, -12, 12, 17, 11, 29, 42, 18, -16, -20, 3, 24, 2, 4, 26, 36, 0, -38, -45, -13, 12, 27, 41, 34, 14, -27, -62, -55, -30, -19, -15, -16, -2, 18, 11, 14, 37, 31, -6, -22, -12, 15, 10, -10, 12, 36, 30, -19, -46, -33, 11, 24, 28, 35, 28, -5, -44, -65, -44, -23, -11, -9, -8, 5, 14, 10, 25, 37, 14, -17, -18, -2, 14, -7, -6, 23, 43, 10, -33, -38, -9, 24, 24, 28, 30, 11, -21, -57, -61, -39, -12, -5, -5, -3, 7, 10, 17, 31, 30, -3, -20, -14, 6, 1, -16, 2, 38, 38, -5, -30, -24, 13, 25, 21, 28, 15, 1, -34, -64, -62, -23, 0, 2, -1, -1, 5, 14, 24, 33, 14, -12, -23, -4, 7, -18, -18, 18, 43, 25, -9, -22, -2, 21, 19, 24, 20, 11, -13, -47, -69, -46, -7, 5, 6, -1, -4, 9, 21, 31, 25, 5, -15, -20, 3, -8, -33, -7, 29, 37, 20, -10, -10, 9, 15, 17, 14, 12, 1, -23, -55, -70, -30, 5, 13, 2, -8, -1, 15, 25, 30, 15, -1, -20, -8, -3, -31, -28, 8, 31, 41, 15, -6, 0, 9, 14, 12, 9, 8, -10, -28, -63, -55, -12, 17, 11, -7, -13, 8, 22, 26, 19, 9, -7, -13, -5, -23, -39, -10, 17, 41, 38, 8, 0, 5, 7, 12, 5, 7, -6, -8, -39, -60, -35, 7, 19, 6, -10, -6, 15, 26, 22, 15, 9, -8, -13, -24, -45, -29, -1, 29, 48, 30, 2, 6, 5, 9, 5, -1, -5, -4, -13, -51, -51, -16, 20, 13, 0, -11, 7, 25, 22, 18, 17, 10, -8, -22, -50, -43, -13, 15, 46, 42, 16, 7, 8, 7, 7, -1, -6, -10, -4, -27, -45, -36, 5, 16, 7, -5, -5, 20, 22, 19, 19, 22, 7, -15, -43, -62, -29, 3, 35, 43, 27, 11, 9, 8, 4, 2, -9, -13, -7, -15, -30, -43, -16, 12, 13, 4, -8, 12, 24, 17, 16, 24, 25, -3, -38, -72, -52, -9, 25, 42, 30, 21, 8, 14, 4, 6, -3, -13, -12, -13, -18, -36, -34, 3, 14, 9, -9, 5, 26, 18, 13, 26, 34, 13, -31, -69, -68, -16, 19, 35, 29, 22, 6, 16, 3, 2, 6, -5, -15, -20, -19, -21, -34, -17, 8, 16, -2, -3, 24, 27, 16, 23, 34, 32, -10, -56, -80, -45, 6, 29, 29, 22, 10, 14, 13, -4, 6, 7, -8, -27, -27, -18, -20, -28, -8, 14, 8, -7, 11, 29, 21, 17, 25, 35, 16, -36, -77, -67, -14, 25, 30, 22, 11, 10, 19, 5, 2, 6, 5, -18, -34, -25, -13, -23, -19, 4, 13, 0, 7, 24, 32, 24, 22, 31, 30, -12, -62, -76, -41, 9, 28, 24, 15, 6, 18, 16, 6, 6, 7, -7, -32, -37, -16, -18, -24, -8, 11, 7, 7, 20, 31, 35, 25, 24, 33, 9, -40, -72, -58, -16, 17, 27, 16, 6, 10, 22, 12, 8, 8, 2, -23, -43, -26, -16, -24, -18, 2, 6, 7, 21, 29, 36, 32, 21, 27, 22, -21, -57, -67, -38, -4, 26, 21, 9, 3, 18, 25, 18, 10, 2, -11, -42, -36, -24, -27, -23, -9, 5, 2, 17, 32, 42, 36, 27, 18, 25, -2, -39, -58, -51, -27, 11, 27, 11, 1, 9, 24, 25, 21, 5, -8, -31, -37, -30, -33, -24, -15, 0, -2, 13, 31, 48, 47, 33, 15, 18, 10, -27, -50, -52, -44, -12, 21, 21, 5, -1, 13, 33, 30, 16, -6, -26, -39, -33, -35, -28, -20, -10, -8, 4, 27, 51, 61, 45, 21, 13, 14, -11, -39, -40, -44, -36, 1, 25, 16, 1, 2, 27, 40, 28, 3, -22, -38, -38, -32, -33, -21, -18, -14, -8, 18, 50, 66, 60, 27, 7, 12, -3, -31, -36, -37, -46, -27, 18, 26, 5, -3, 8, 35, 43, 16, -14, -36, -43, -32, -32, -25, -16, -23, -14, 6, 46, 64, 74, 49, 9, 4, 7, -23, -37, -34, -41, -44, -8, 31, 19, -5, 0, 21, 47, 33, -2, -33, -43, -43, -32, -29, -14, -22, -23, -6, 34, 62, 75, 71, 30, 0, 8, -13, -37, -34, -35, -45, -34, 18, 31, 5, -5, 7, 35, 44, 12, -23, -45, -49, -40, -29, -18, -18, -27, -15, 22, 57, 74, 80, 57, 15, 4, -1, -39, -34, -34, -40, -46, -4, 25, 13, -3, 2, 22, 44, 25, -10, -38, -44, -50, -34, -20, -14, -31, -21, 5, 47, 63, 81, 76, 38, 8, 9, -30, -45, -35, -36, -43, -20, 9, 14, 5, 3, 7, 36, 32, 3, -32, -43, -50, -40, -28, -13, -24, -28, -2, 35, 56, 73, 86, 58, 23, 21, -10, -49, -45, -33, -39, -25, -3, 5, 5, 8, 5, 18, 32, 17, -19, -45, -49, -41, -35, -22, -19, -31, -12, 28, 52, 59, 76, 74, 41, 31, 10, -39, -58, -41, -32, -27, -5, -3, 3, 8, 8, 10, 24, 22, -4, -39, -52, -42, -35, -30, -18, -28, -22, 20, 53, 52, 60, 73, 62, 43, 31, -18, -56, -61, -35, -28, -9, -6, -3, 3, 9, 10, 12, 18, 8, -23, -53, -50, -31, -35, -24, -28, -26, 3, 48, 55, 52, 59, 66, 57, 46, 7, -37, -67, -53, -24, -11, -4, -6, 0, 3, 13, 10, 7, 10, -6, -38, -58, -36, -30, -30, -26, -26, -11, 33, 60, 56, 49, 59, 67, 58, 32, -15, -58, -69, -34, -14, -8, -6, 1, -4, 7, 8, 2, 4, 4, -21, -54, -49, -30, -30, -28, -29, -18, 13, 53, 60, 50, 44, 63, 61, 49, 11, -33, -71, -49, -19, -9, -10, 5, 2, -1, 4, -1, 4, 5, -5, -38, -55, -40, -28, -21, -25, -26, -2, 40, 61, 56, 39, 53, 66, 54, 33, -4, -55, -63, -29, -18, -12, 3, 11, -4, -4, -9, -3, 4, 4, -18, -49, -49, -35, -18, -18, -25, -16, 24, 51, 60, 42, 43, 66, 57, 42, 21, -23, -63, -44, -26, -18, -10, 13, 9, -8, -18, -17, 5, 5, -4, -35, -47, -42, -24, -11, -20, -21, 5, 36, 56, 53, 37, 60, 59, 40, 34, 11, -34, -52, -33, -21, -15, 1, 21, 2, -19, -33, -10, 8, 3, -20, -42, -41, -33, -14, -16, -18, -7, 21, 43, 54, 39, 47, 61, 44, 31, 27, -4, -41, -47, -28, -23, -9, 11, 15, -9, -34, -34, 1, 10, -2, -30, -38, -34, -18, -15, -17, -10, 10, 27, 43, 42, 42, 53, 54, 36, 24, 14, -15, -42, -36, -32, -22, 1, 13, 7, -26, -48, -24, 11, 10, -14, -35, -32, -19, -16, -15, -11, 5, 18, 31, 34, 41, 48, 51, 46, 28, 26, 8, -26, -36, -33, -35, -12, 7, 12, -8, -45, -47, -9, 13, 5, -24, -32, -17, -14, -16, -11, 6, 14, 20, 26, 27, 47, 49, 49, 34, 25, 22, -6, -31, -27, -39, -30, -10, 13, 6, -28, -57, -31, -3, 12, -7, -28, -19, -8, -21, -18, -2, 18, 17, 17, 19, 34, 47, 53, 42, 34, 30, 13, -22, -20, -30, -44, -32, -4, 15, -7, -45, -49, -18, 4, 10, -14, -18, 0, -11, -26, -7, 15, 23, 10, 10, 20, 34, 51, 49, 38, 41, 30, -8, -28, -15, -39, -47, -28, 5, 10, -26, -55, -34, -9, 10, 3, -13, -4, 1, -21, -19, 3, 25, 13, 5, 9, 18, 36, 54, 39, 40, 46, 16, -27, -17, -23, -47, -47, -18, 9, -2, -47, -51, -23, 0, 4, 0, 1, 9, -11, -20, -9, 20, 23, 4, 2, 8, 20, 45, 46, 38, 53, 41, -13, -30, -19, -36, -52, -40, -9, 5, -23, -53, -35, -6, 4, 3, 6, 10, 5, -16, -17, 6, 30, 12, 0, -4, 9, 32, 47, 43, 55, 57, 16, -27, -30, -28, -44, -52, -31, -6, -8, -43, -43, -15, -1, -1, 8, 10, 13, 2, -18, -11, 21, 23, 6, -5, 0, 19, 33, 41, 56, 67, 44, -5, -34, -35, -32, -46, -47, -27, -7, -30, -44, -23, -2, -2, 3, 7, 14, 18, -1, -19, 4, 20, 16, -5, -9, 10, 27, 30, 46, 65, 63, 26, -22, -42, -34, -41, -46, -40, -18, -25, -39, -28, -4, 1, -1, 5, 10, 24, 19, -8, -6, 11, 20, 4, -13, 2, 22, 24, 36, 59, 70, 51, 5, -39, -39, -43, -47, -45, -31, -30, -39, -33, -7, 1, -2, 1, 4, 19, 25, 5, -5, 1, 12, 13, -12, -12, 18, 25, 21, 46, 68, 69, 36, -17, -39, -44, -51, -43, -33, -35, -41, -38, -15, 8, 0, 0, 0, 13, 26, 19, 5, 0, -1, 10, -2, -14, 5, 25, 19, 29, 54, 71, 59, 9, -31, -43, -56, -50, -32, -38, -47, -42, -26, 8, 10, -3, -3, 7, 20, 23, 16, 8, -5, 3, 2, -17, -6, 22, 20, 18, 40, 66, 71, 37, -13, -36, -52, -61, -38, -32, -47, -51, -38, -7, 19, 6, -6, 4, 14, 19, 21, 19, 2, -5, 0, -13, -12, 14, 21, 13, 27, 53, 71, 57, 12, -25, -42, -61, -54, -33, -38, -52, -50, -22, 13, 17, -4, 1, 16, 17, 19, 25, 11, -2, -2, -11, -18, 6, 21, 15, 18, 43, 66, 67, 34, -7, -30, -49, -58, -42, -36, -42, -54, -36, -2, 20, 4, -4, 11, 16, 17, 26, 17, 4, 1, -8, -22, -8, 17, 16, 17, 27, 55, 66, 48, 10, -25, -36, -49, -52, -42, -39, -47, -46, -18, 13, 14, -1, 3, 13, 19, 27, 18, 2, 5, 1, -14, -17, 6, 13, 16, 26, 44, 64, 54, 27, -15, -30, -33, -49, -50, -43, -44, -45, -30, -1, 13, 3, 6, 10, 22, 30, 21, 3, 2, 2, -3, -18, -9, 8, 11, 23, 35, 55, 58, 37, 1, -25, -18, -33, -51, -48, -46, -41, -30, -17, 6, 3, 7, 9, 16, 30, 27, 9, 3, 3, 1, -10, -18, 0, 3, 12, 37, 46, 52, 40, 15, -23, -16, -14, -39, -48, -48, -45, -31, -20, -7, 1, 4, 14, 13, 21, 26, 16, 2, 1, 1, 1, -16, -12, 1, 5, 29, 50, 47, 39, 21, -11, -21, -3, -23, -41, -45, -47, -37, -21, -13, -6, 1, 16, 20, 22, 22, 18, 10, 2, 1, 6, -7, -16, -10, 0, 16, 51, 53, 38, 22, -1, -21, -1, -4, -30, -41, -45, -45, -28, -13, -13, -8, 13, 24, 26, 15, 13, 15, 8, -4, 1, -2, -11, -15, -11, 2, 40, 56, 44, 21, 1, -16, -10, 5, -16, -32, -38, -41, -36, -22, -14, -15, 4, 24, 32, 18, 7, 14, 14, 4, -2, -1, -8, -12, -15, -6, 24, 50, 51, 28, 1, -13, -14, 4, 1, -18, -31, -35, -36, -33, -21, -21, -5, 19, 38, 23, 3, 5, 17, 15, 2, -3, -7, -8, -18, -14, 12, 39, 50, 35, 2, -14, -14, -3, 6, -6, -24, -27, -32, -40, -25, -22, -12, 8, 35, 34, 10, 2, 5, 19, 9, -6, -4, -3, -15, -18, 4, 30, 42, 40, 13, -17, -16, -7, 3, 5, -14, -21, -24, -41, -37, -23, -18, -1, 22, 37, 17, 4, -1, 11, 17, 1, -7, -4, -12, -22, -6, 24, 35, 33, 25, -7, -26, -15, 2, 14, 3, -16, -19, -33, -42, -27, -23, -10, 15, 28, 27, 8, 2, 5, 20, 11, -4, -6, -7, -19, -11, 17, 31, 26, 25, 6, -24, -25, -6, 11, 14, -3, -13, -25, -39, -33, -23, -17, 7, 19, 26, 19, 4, 1, 15, 14, -1, -5, -10, -14, -22, 8, 33, 28, 20, 16, -13, -26, -17, 9, 22, 5, -8, -18, -37, -35, -28, -23, -4, 12, 16, 28, 12, 1, 12, 18, 3, -2, -9, -10, -27, -10, 29, 34, 18, 16, 2, -26, -29, -3, 27, 19, -4, -10, -29, -36, -30, -29, -12, 9, 3, 18, 21, 7, 12, 17, 3, -2, -7, -7, -19, -26, 15, 36, 21, 12, 9, -15, -30, -18, 19, 30, 6, -5, -21, -32, -25, -29, -22, 6, 0, 3, 20, 14, 12, 18, 12, 0, -9, -12, -9, -26, -4, 31, 28, 11, 10, -6, -24, -29, 3, 35, 19, -3, -15, -26, -19, -23, -31, -6, 4, -7, 13, 19, 17, 20, 18, 9, -9, -19, -5, -17, -20, 16, 34, 18, 9, 0, -16, -25, -10, 30, 29, 3, -10, -19, -19, -16, -29, -19, 3, -9, -5, 13, 21, 24, 16, 13, 1, -23, -14, -12, -19, -2, 28, 21, 8, 1, -11, -23, -19, 16, 41, 14, -8, -13, -9, -13, -18, -27, -4, -5, -12, -1, 19, 31, 18, 10, 16, -20, -22, -13, -14, -12, 18, 26, 12, 4, -4, -17, -18, -1, 38, 31, -5, -14, -7, -7, -14, -24, -13, -3, -13, -12, 7, 30, 34, 14, 18, -5, -33, -18, -10, -14, 1, 19, 14, 6, -8, -13, -15, -2, 19, 40, 8, -13, -9, -4, -8, -18, -20, -9, -14, -16, -7, 22, 37, 23, 16, 10, -26, -28, -13, -9, -5, 14, 14, 9, -9, -17, -13, -1, 8, 31, 26, -6, -10, -4, -2, -12, -19, -11, -11, -17, -12, 6, 34, 29, 15, 16, -7, -35, -25, -9, -6, 8, 14, 12, 1, -15, -14, 3, 10, 19, 29, 8, -10, -9, 1, -7, -20, -10, -9, -17, -17, -1, 30, 35, 18, 15, 5, -28, -33, -17, -6, -4, 8, 13, 5, -14, -19, 1, 14, 14, 20, 17, 0, -8, -2, -3, -14, -18, -9, -12, -18, -6, 21, 37, 26, 7, 10, -13, -33, -24, -6, -2, 0, 9, 11, -5, -19, -7, 16, 18, 13, 18, 11, -2, -6, -3, -6, -22, -10, -11, -16, -11, 17, 34, 32, 9, 9, 2, -26, -30, -14, -2, -5, 3, 8, 3, -16, -12, 8, 21, 13, 13, 15, 2, -3, -5, -5, -20, -16, -8, -16, -20, 6, 32, 34, 14, -4, 6, -12, -26, -20, -7, -6, -4, 4, 7, -2, -15, 1, 17, 15, 9, 15, 10, 0, -3, -7, -15, -22, -4, -7, -19, -7, 29, 36, 20, -6, -1, 0, -17, -19, -12, -9, -7, -1, 2, 6, -3, -8, 10, 18, 9, 8, 21, 4, -2, -8, -13, -20, -12, -2, -16, -14, 14, 39, 26, -3, -17, 1, -6, -16, -12, -7, -9, -9, 0, 3, 11, -3, 0, 15, 13, 3, 19, 12, -8, -6, -14, -19, -16, 0, -6, -17, 3, 33, 35, 5, -18, -9, 1, -15, -11, -8, -8, -16, -8, 1, 15, 15, 3, 11, 19, 2, 12, 26, 0, -10, -13, -21, -11, 1, -1, -18, -2, 23, 35, 17, -12, -21, -2, -8, -9, -8, -9, -12, -17, -5, 10, 22, 8, 7, 18, 7, -1, 23, 13, -13, -19, -23, -14, 5, 2, -15, -13, 17, 30, 22, -3, -24, -7, -2, -9, -6, -10, -8, -21, -19, 5, 22, 22, 13, 15, 13, -3, 11, 18, -4, -20, -28, -20, 4, 11, -10, -18, 6, 26, 17, 3, -20, -12, -2, -11, -7, -8, -8, -16, -27, -7, 19, 30, 21, 19, 15, 4, 3, 18, 2, -17, -33, -24, 0, 17, 1, -16, -6, 24, 19, 5, -17, -18, 1, -8, -12, -7, -11, -10, -22, -14, 10, 29, 29, 32, 23, 13, 0, 9, 6, -12, -28, -36, -7, 13, 12, -8, -17, 12, 24, 6, -10, -20, 1, 1, -13, -9, -12, -16, -20, -17, 0, 21, 27, 31, 35, 20, 7, 0, 2, -13, -19, -37, -19, 8, 18, 9, -16, -9, 20, 11, -2, -25, -13, 8, -4, -16, -13, -18, -23, -17, 0, 14, 29, 27, 43, 35, 17, -1, -4, -13, -22, -29, -31, -2, 17, 20, -5, -21, 6, 16, 5, -16, -25, 4, 11, -12, -17, -20, -27, -19, -2, 13, 26, 27, 36, 46, 32, 7, -8, -18, -26, -25, -32, -16, 12, 26, 11, -18, -11, 4, 13, -1, -27, -12, 14, 2, -21, -23, -31, -26, -11, 10, 24, 30, 29, 43, 50, 24, -4, -16, -34, -28, -28, -27, -1, 27, 24, -5, -21, -12, 6, 16, -13, -28, 1, 13, -9, -23, -33, -32, -18, 2, 24, 34, 33, 34, 50, 49, 12, -11, -34, -37, -28, -25, -14, 14, 28, 10, -10, -25, -9, 21, 15, -27, -15, 12, 2, -18, -33, -36, -24, -7, 13, 30, 39, 42, 35, 54, 36, 1, -29, -45, -35, -26, -17, -1, 20, 19, 2, -23, -30, 1, 30, -5, -32, 1, 7, -8, -27, -37, -25, -12, -1, 23, 37, 51, 38, 41, 49, 16, -15, -41, -40, -31, -21, -11, 4, 19, 15, -8, -33, -19, 22, 20, -21, -13, 2, -6, -17, -36, -32, -11, -8, 9, 28, 48, 54, 36, 48, 30, 3, -30, -41, -34, -24, -15, -6, 2, 17, 8, -19, -37, 0, 31, 3, -20, -6, -4, -7, -31, -35, -9, -3, -4, 16, 37, 62, 44, 41, 33, 13, -11, -36, -39, -29, -21, -11, -11, 6, 14, -2, -28, -24, 15, 22, -5, -10, -11, -10, -20, -35, -13, 2, -5, 2, 21, 55, 64, 46, 37, 19, 2, -23, -36, -28, -23, -17, -18, -17, 10, 11, -12, -32, -7, 23, 16, -7, -14, -17, -8, -27, -23, 1, 1, 0, 6, 31, 63, 60, 46, 21, 7, -12, -29, -24, -18, -24, -23, -27, -11, 11, 5, -16, -19, 11, 21, 4, -9, -21, -15, -17, -30, -5, 7, 2, -1, 9, 48, 65, 59, 30, 13, -4, -25, -19, -6, -22, -33, -32, -31, -3, 7, -3, -20, -4, 14, 11, -1, -11, -19, -13, -20, -16, 9, 7, 2, -3, 27, 60, 69, 44, 12, 7, -18, -20, 1, -4, -35, -38, -34, -22, -9, 4, -2, -11, 8, 8, 2, -6, -19, -23, -14, -16, 3, 13, 2, 2, 12, 47, 65, 62, 22, 10, -3, -21, -9, 9, -17, -46, -40, -34, -23, -6, 4, -1, 3, 7, 2, -4, -13, -25, -18, -11, -4, 18, 3, -2, 5, 30, 58, 66, 39, 12, 9, -10, -18, 8, 5, -41, -49, -38, -33, -18, -4, 2, 7, 8, 2, -7, -12, -18, -23, -12, -6, 18, 15, -8, 0, 21, 44, 62, 48, 22, 14, 7, -16, -7, 18, -18, -52, -44, -42, -32, -18, -1, 12, 10, 6, -8, -20, -11, -18, -19, -10, 14, 24, 2, -5, 14, 34, 57, 51, 27, 19, 20, -1, -13, 15, -1, -42, -45, -49, -38, -28, -15, 13, 19, 10, -1, -23, -16, -11, -24, -10, 6, 21, 14, -5, 3, 24, 48, 58, 29, 17, 24, 18, -6, 4, 8, -28, -38, -46, -50, -36, -29, 3, 22, 15, 4, -18, -31, -7, -20, -17, 5, 11, 18, 4, -2, 15, 37, 58, 35, 11, 26, 31, 11, -2, 6, -13, -32, -39, -55, -45, -38, -17, 21, 23, 11, -10, -31, -18, -11, -25, 1, 9, 14, 15, 0, 7, 26, 49, 49, 13, 10, 33, 26, 8, 4, -5, -25, -35, -46, -53, -41, -35, 5, 24, 17, 0, -25, -26, -14, -24, -9, 6, 5, 17, 6, 6, 20, 38, 55, 30, 3, 25, 38, 18, 10, -4, -16, -30, -42, -51, -46, -41, -16, 21, 23, 14, -16, -30, -16, -17, -17, 0, 2, 12, 16, 3, 17, 28, 46, 49, 14, 13, 39, 30, 17, 4, -9, -20, -38, -49, -50, -50, -34, 4, 21, 20, 4, -29, -23, -15, -15, -8, -3, 7, 19, 8, 9, 26, 35, 47, 29, 6, 29, 35, 26, 13, -5, -18, -29, -42, -49, -51, -50, -16, 11, 23, 18, -17, -34, -14, -15, -9, -10, -2, 17, 14, 5, 21, 33, 44, 38, 14, 23, 37, 30, 20, 6, -8, -26, -34, -47, -52, -54, -34, 0, 16, 19, 5, -29, -20, -13, -10, -9, -10, 4, 19, 11, 13, 29, 37, 36, 22, 22, 39, 32, 23, 10, 2, -18, -32, -40, -54, -56, -49, -23, 8, 17, 11, -15, -26, -11, -13, -9, -15, -11, 14, 17, 10, 23, 34, 36, 24, 21, 35, 42, 26, 12, 2, -4, -23, -31, -47, -57, -50, -33, -7, 17, 11, -2, -18, -12, -12, -11, -10, -21, -6, 18, 19, 21, 33, 35, 28, 23, 34, 51, 40, 12, -2, 1, -9, -27, -43, -59, -53, -39, -23, 4, 15, 1, -10, -14, -9, -8, -10, -22, -18, 5, 19, 16, 27, 34, 28, 23, 27, 47, 53, 27, -3, -4, -1, -13, -33, -53, -57, -45, -31, -13, 14, 4, -4, -11, -9, -9, -11, -19, -28, -16, 10, 24, 23, 35, 24, 26, 26, 38, 60, 44, 2, -13, -3, -5, -19, -44, -58, -49, -33, -26, 1, 14, 1, -4, -5, 0, -7, -14, -29, -26, -11, 20, 27, 30, 32, 21, 27, 34, 59, 58, 22, -11, -10, -6, -10, -29, -55, -53, -38, -34, -16, 12, 9, -5, -8, 5, 1, -16, -31, -32, -28, 0, 26, 26, 33, 23, 24, 33, 49, 61, 37, 3, -15, -8, -11, -19, -43, -56, -44, -34, -25, -2, 17, 5, -11, 2, 12, -2, -23, -32, -35, -23, 14, 26, 27, 35, 23, 32, 45, 58, 47, 19, -5, -9, -10, -16, -27, -46, -48, -41, -34, -18, 11, 20, -6, -10, 12, 9, -18, -34, -38, -29, -7, 17, 27, 32, 30, 30, 46, 52, 51, 28, 6, -8, -9, -15, -24, -32, -41, -45, -40, -30, -1, 23, 10, -12, 2, 17, -2, -31, -39, -32, -18, -6, 18, 29, 38, 32, 45, 54, 54, 33, 11, 2, -9, -11, -19, -32, -33, -41, -45, -40, -18, 16, 19, 2, -6, 13, 12, -20, -43, -35, -21, -18, -5, 21, 35, 36, 46, 58, 52, 38, 17, 9, -5, -9, -13, -29, -32, -28, -41, -43, -36, 0, 22, 18, -4, -3, 17, 2, -33, -43, -25, -18, -16, 4, 27, 38, 47, 64, 57, 40, 18, 10, 5, -7, -10, -22, -39, -24, -30, -42, -39, -22, 13, 28, 14, -9, 3, 17, -16, -51, -36, -17, -23, -18, 8, 35, 50, 66, 68, 43, 23, 12, 13, -1, -11, -17, -32, -27, -22, -40, -38, -37, -10, 22, 34, 1, -10, 8, 6, -39, -48, -27, -19, -25, -10, 18, 49, 66, 78, 54, 26, 17, 16, 3, -7, -15, -25, -29, -12, -32, -37, -35, -28, 3, 38, 26, -7, -4, 11, -15, -46, -42, -26, -23, -24, -2, 34, 66, 81, 70, 30, 19, 21, 10, -5, -11, -25, -29, -12, -20, -37, -33, -39, -17, 25, 46, 6, -11, 2, 0, -29, -44, -41, -30, -27, -17, 12, 58, 79, 84, 46, 19, 22, 19, 2, -7, -26, -35, -12, -1, -29, -33, -39, -36, 3, 46, 31, -11, -6, -1, -14, -38, -46, -39, -32, -22, -5, 40, 76, 88, 64, 23, 22, 30, 12, -8, -20, -39, -22, 0, -13, -29, -33, -43, -20, 24, 49, 13, -12, 2, -6, -26, -45, -45, -39, -32, -15, 19, 68, 85, 77, 32, 22, 35, 27, 0, -18, -36, -38, -6, 3, -17, -29, -44, -37, -2, 40, 34, -8, -6, 3, -18, -44, -47, -44, -43, -21, 3, 49, 76, 80, 53, 21, 35, 39, 15, -18, -35, -42, -23, 2, -3, -19, -33, -42, -23, 16, 46, 16, -8, 2, -6, -37, -45, -47, -51, -33, -8, 31, 68, 74, 66, 33, 35, 45, 36, -3, -33, -40, -34, -7, 5, -8, -18, -35, -39, -13, 32, 32, 3, -1, 5, -26, -46, -50, -52, -44, -20, 15, 59, 68, 69, 50, 32, 42, 48, 21, -26, -42, -42, -24, 2, 2, -8, -20, -38, -35, 6, 33, 17, -2, 5, -6, -41, -55, -57, -46, -33, -6, 40, 64, 62, 63, 45, 38, 54, 40, -4, -42, -50, -40, -11, 6, -2, -8, -24, -41, -19, 17, 28, 10, 0, 1, -26, -52, -64, -51, -40, -23, 19, 54, 56, 61, 60, 38, 52, 55, 24, -30, -50, -47, -27, 4, 8, -6, -11, -30, -36, -6, 19, 25, 4, 1, -9, -38, -64, -61, -42, -36, 0, 44, 55, 51, 66, 50, 49, 62, 46, -5, -48, -51, -40, -11, 11, 4, -14, -15, -36, -25, 1, 19, 15, -1, -2, -18, -53, -69, -48, -42, -20, 21, 51, 45, 56, 62, 51, 60, 59, 23, -32, -53, -49, -28, 5, 17, -12, -18, -22, -32, -12, 9, 20, 1, -6, -5, -29, -70, -62, -48, -32, 2, 36, 45, 44, 62, 62, 60, 64, 47, -10, -45, -54, -42, -11, 21, 5, -19, -18, -23, -20, -1, 15, 4, -6, -2, -6, -51, -72, -57, -44, -13, 19, 40, 41, 51, 65, 66, 69, 63, 14, -32, -47, -50, -30, 10, 14, -12, -16, -18, -16, -14, 7, 8, -6, -8, -1, -21, -65, -67, -54, -29, 1, 26, 38, 44, 53, 69, 77, 73, 37, -17, -41, -46, -37, -10, 13, -1, -11, -14, -14, -10, -6, 9, -5, -6, -11, -3, -43, -67, -68, -42, -15, 12, 27, 40, 47, 65, 80, 83, 55, 7, -34, -43, -34, -22, -5, 2, -3, -2, -13, -10, -11, 3, -2, -4, -13, -5, -15, -51, -72, -63, -31, -3, 16, 29, 42, 55, 78, 91, 68, 25, -11, -40, -32, -22, -21, -9, -1, 8, -1, -19, -11, -3, 1, -5, -11, -12, -3, -29, -58, -70, -48, -18, 6, 15, 35, 50, 68, 89, 84, 37, 11, -27, -38, -19, -20, -23, -8, 10, 18, -10, -19, -8, 4, 0, -11, -14, -7, -20, -42, -63, -60, -37, -4, 7, 23, 41, 67, 82, 90, 53, 19, -4, -34, -23, -20, -31, -22, 5, 25, 8, -17, -20, 0, 10, -5, -20, -9, -12, -31, -47, -60, -53, -26, -3, 12, 32, 58, 81, 85, 70, 27, 9, -19, -26, -19, -28, -31, -8, 24, 21, -2, -26, -11, 14, 10, -20, -18, -8, -24, -33, -53, -56, -44, -23, 3, 22, 44, 77, 85, 74, 40, 17, -3, -21, -21, -24, -36, -25, 11, 22, 15, -13, -28, 5, 23, 0, -28, -12, -19, -26, -42, -56, -48, -39, -17, 12, 34, 62, 84, 73, 52, 26, 9, -12, -21, -22, -31, -30, -1, 15, 16, 6, -25, -14, 23, 19, -17, -21, -13, -24, -34, -54, -44, -39, -36, -9, 27, 46, 79, 79, 59, 38, 16, -2, -17, -25, -25, -27, -10, 5, 10, 15, -4, -24, 5, 29, 5, -24, -18, -19, -28, -48, -50, -35, -38, -28, 10, 33, 62, 82, 62, 46, 27, 4, -8, -23, -24, -25, -15, -3, 0, 8, 6, -12, -9, 22, 25, -6, -21, -22, -28, -45, -53, -39, -30, -37, -11, 20, 43, 75, 66, 53, 41, 10, -8, -16, -25, -23, -15, -2, -4, -5, 4, 1, -7, 8, 29, 19, -9, -21, -24, -42, -55, -48, -30, -31, -19, 5, 23, 61, 74, 58, 53, 26, -7, -11, -18, -25, -14, 0, 1, -16, -8, 4, 0, 3, 20, 28, 11, -16, -19, -38, -58, -55, -35, -27, -16, -1, 5, 32, 63, 61, 56, 44, 3, -17, -13, -22, -19, -4, 5, -8, -21, -6, 7, 8, 12, 25, 25, 2, -17, -26, -54, -64, -47, -32, -11, 5, 3, 16, 40, 60, 58, 56, 26, -16, -19, -16, -20, -8, 0, -4, -20, -22, 1, 12, 9, 17, 30, 20, -2, -15, -42, -68, -57, -44, -19, 11, 6, 10, 19, 42, 58, 58, 45, 6, -23, -18, -13, -13, -3, -3, -10, -26, -14, 9, 15, 12, 26, 27, 10, -7, -25, -61, -68, -54, -36, 10, 15, 13, 16, 19, 42, 55, 52, 31, -9, -25, -18, -15, -7, -3, -9, -23, -26, -2, 15, 19, 19, 26, 18, 7, -10, -41, -72, -60, -51, -8, 25, 22, 20, 13, 19, 45, 51, 44, 19, -15, -28, -15, -7, -4, -9, -19, -28, -14, 6, 18, 18, 24, 22, 12, 1, -17, -55, -67, -56, -35, 19, 33, 30, 20, 9, 23, 44, 48, 39, 6, -22, -25, -9, -8, -9, -15, -29, -21, -3, 10, 16, 20, 23, 13, 7, -4, -31, -63, -61, -50, -11, 33, 37, 30, 12, 7, 24, 44, 48, 28, -4, -28, -14, -4, -14, -14, -27, -27, -8, 5, 13, 15, 19, 19, 11, 3, -12, -44, -64, -58, -31, 17, 40, 39, 24, 8, 3, 30, 46, 42, 16, -18, -21, -6, -16, -18, -26, -32, -15, 1, 6, 10, 10, 15, 12, 10, -3, -23, -51, -63, -50, -4, 34, 41, 33, 17, -4, 10, 35, 42, 32, 5, -15, -8, -10, -18, -21, -30, -22, 0, 3, -2, -2, 6, 5, 4, 3, -7, -25, -45, -45, -18, 25, 33, 32, 21, 7, 8, 20, 30, 31, 20, 3, -7, -10, -14, -17, -23, -29, -12, 6, -2, -11, -11, -4, 2, 3, -7, -10, -27, -33, -21, 13, 27, 23, 19, 8, 15, 17, 18, 21, 23, 19, 2, -12, -10, -9, -15, -27, -28, -2, 9, -8, -18, -17, -4, 9, -6, -7, -10, -17, -13, 2, 21, 20, 14, 4, 15, 25, 15, 11, 14, 19, 13, -13, -17, -6, -5, -20, -36, -23, 4, 6, -18, -28, -20, 6, 6, 0, 3, 5, 5, 28, 31, 31, 49, 55, 35, 11, 27, 26, 4, 7, 11, 31, 54, 38, 26, 34, 35, 20, -10, -32, -43, -47, -43, -20, -7, -37, -55, -62, -61, -63, -34, -21, -35, -28, -10, 15, 24, 23, 5, -31, -38, -6, 23, 19, 15, 24, 20, 31, 57, 54, 28, 13, 33, 20, 1, 4, 17, 38, 44, 33, 31, 43, 36, 10, -14, -34, -53, -53, -46, -22, -22, -38, -46, -54, -60, -58, -29, -25, -39, -29, -12, 11, 25, 27, 6, -31, -33, -3, 27, 32, 21, 13, 16, 38, 60, 53, 26, 18, 28, 11, -2, 8, 26, 37, 34, 36, 42, 47, 31, 6, -14, -41, -61, -54, -49, -26, -30, -41, -40, -44, -54, -48, -23, -28, -41, -33, -7, 14, 26, 29, 3, -32, -27, 6, 33, 35, 18, 5, 21, 45, 61, 49, 25, 30, 22, 0, -5, 9, 37, 39, 27, 33, 47, 50, 31, 1, -22, -51, -65, -59, -45, -31, -40, -36, -29, -35, -49, -41, -28, -39, -44, -26, -8, 6, 27, 31, -5, -31, -18, 14, 33, 31, 17, 4, 25, 48, 57, 45, 32, 27, 9, -6, -5, 14, 43, 36, 29, 39, 51, 50, 31, 0, -32, -65, -73, -62, -37, -36, -46, -36, -23, -26, -37, -32, -35, -46, -42, -22, -11, 2, 30, 28, -8, -29, -12, 22, 33, 32, 15, 4, 25, 49, 58, 50, 36, 20, 2, -9, -3, 21, 43, 37, 32, 44, 55, 53, 33, -7, -42, -67, -72, -64, -43, -43, -46, -35, -17, -17, -24, -31, -40, -47, -39, -18, -15, 0, 33, 22, -14, -22, 5, 29, 29, 28, 11, 7, 23, 49, 54, 50, 37, 13, -6, -11, -6, 25, 44, 38, 26, 40, 57, 54, 28, -12, -48, -70, -73, -66, -43, -43, -43, -29, -12, -15, -16, -32, -48, -51, -38, -24, -19, 4, 31, 12, -16, -14, 21, 34, 24, 24, 13, 10, 27, 49, 53, 53, 33, 6, -9, -16, -4, 33, 48, 37, 24, 45, 61, 54, 23, -15, -60, -76, -76, -60, -48, -45, -38, -26, -11, -3, -5, -33, -49, -52, -35, -25, -21, 7, 24, 1, -15, -1, 34, 30, 23, 29, 17, 5, 26, 49, 55, 53, 26, -3, -16, -16, 4, 38, 43, 33, 33, 49, 59, 45, 19, -18, -63, -78, -79, -58, -50, -39, -31, -21, -11, -2, -3, -30, -49, -51, -35, -29, -20, 8, 12, -10, -11, 17, 37, 27, 29, 29, 13, 2, 33, 56, 55, 38, 18, -7, -19, -17, 13, 40, 42, 33, 35, 52, 58, 40, 10, -28, -68, -84, -78, -56, -47, -36, -30, -17, -7, 5, -4, -30, -49, -51, -34, -30, -18, 10, 1, -18, -9, 30, 39, 26, 32, 28, 9, 7, 38, 51, 45, 35, 16, -13, -28, -11, 27, 41, 41, 34, 45, 58, 54, 29, 7, -33, -69, -80, -78, -59, -43, -31, -24, -15, -3, 9, -4, -29, -51, -51, -33, -27, -8, 8, -13, -24, -1, 40, 41, 29, 31, 22, 7, 15, 46, 48, 38, 33, 11, -19, -28, -7, 26, 42, 36, 39, 54, 54, 48, 20, 3, -39, -68, -79, -78, -54, -37, -32, -27, -16, 5, 11, -6, -31, -50, -49, -33, -24, -3, -3, -29, -26, 13, 44, 36, 30, 32, 17, 7, 28, 43, 37, 31, 28, 4, -17, -27, -5, 24, 46, 43, 48, 56, 50, 41, 20, -1, -47, -64, -82, -78, -48, -35, -34, -26, -14, 6, 9, -10, -31, -46, -43, -33, -21, 1, -16, -38, -15, 24, 38, 35, 44, 33, 10, 15, 37, 43, 30, 22, 18, 4, -20, -29, 0, 30, 43, 48, 54, 52, 46, 35, 19, -9, -41, -60, -83, -73, -44, -29, -37, -27, -12, 6, 8, -10, -28, -45, -43, -25, -9, -3, -33, -43, -4, 32, 35, 37, 49, 24, 7, 26, 47, 35, 17, 11, 14, 3, -21, -30, 6, 30, 44, 60, 56, 44, 37, 33, 15, -11, -40, -63, -82, -61, -36, -33, -39, -26, -13, 0, 4, -9, -29, -42, -37, -18, -7, -13, -39, -34, 2, 30, 34, 45, 49, 16, 11, 37, 45, 26, 11, 8, 9, -1, -26, -25, 17, 31, 46, 62, 52, 42, 29, 26, 15, -12, -45, -64, -71, -48, -34, -35, -33, -27, -16, 1, 2, -10, -23, -41, -32, -12, -6, -29, -46, -28, 12, 26, 36, 54, 43, 10, 23, 52, 43, 18, -2, 5, 5, -7, -25, -11, 19, 22, 49, 61, 50, 40, 24, 20, 15, -10, -47, -62, -62, -45, -34, -30, -30, -23, -16, -6, -1, -8, -25, -38, -29, -9, -10, -39, -42, -19, 5, 23, 48, 57, 33, 7, 32, 57, 39, 8, -7, 3, -2, -16, -16, 1, 20, 22, 48, 55, 46, 39, 17, 16, 17, -9, -48, -58, -54, -40, -37, -28, -26, -22, -23, -5, 2, -11, -28, -37, -27, -10, -18, -44, -35, -18, 3, 31, 54, 52, 25, 13, 45, 61, 29, -4, -10, 0, -5, -16, -8, 4, 21, 21, 50, 54, 45, 31, 4, 20, 18, -15, -43, -48, -48, -39, -33, -28, -25, -22, -21, 0, -1, -19, -29, -29, -22, -11, -29, -42, -30, -17, 3, 38, 61, 46, 24, 25, 53, 58, 20, -10, -9, -5, -16, -12, 4, 11, 22, 17, 48, 51, 43, 16, 2, 18, 13, -15, -35, -46, -43, -38, -31, -23, -27, -24, -13, 3, -8, -25, -29, -27, -22, -18, -36, -38, -31, -19, 6, 46, 60, 36, 24, 33, 56, 44, 10, -8, -9, -12, -24, -7, 14, 23, 18, 11, 45, 47, 39, 13, 5, 16, 1, -19, -22, -39, -45, -45, -31, -20, -24, -16, -6, -3, -19, -24, -25, -26, -22, -24, -39, -35, -25, -13, 8, 54, 64, 36, 29, 41, 56, 36, 5, -12, -11, -14, -26, -6, 24, 33, 7, 12, 45, 44, 30, 13, 10, 17, -4, -17, -16, -34, -46, -50, -30, -20, -23, -12, 1, -11, -26, -27, -24, -21, -19, -34, -48, -32, -23, -10, 13, 66, 65, 33, 32, 48, 55, 25, 0, -8, -1, -18, -36, -4, 40, 33, -1, 17, 37, 35, 25, 10, 14, 10, -13, -15, -9, -26, -46, -51, -32, -18, -15, -4, 3, -17, -31, -28, -25, -20, -26, -48, -48, -27, -20, -13, 19, 71, 61, 28, 33, 56, 50, 12, -8, -2, 5, -24, -41, 2, 52, 29, -1, 24, 36, 26, 16, 14, 19, 6, -19, -12, 1, -21, -49, -50, -28, -12, -3, 2, -2, -25, -32, -29, -24, -14, -31, -61, -44, -17, -15, -9, 28, 72, 61, 25, 38, 61, 41, 7, -7, 4, 3, -32, -36, 9, 45, 21, 4, 30, 33, 15, 11, 18, 17, -1, -18, -7, -4, -22, -47, -45, -24, -6, 2, 5, -7, -27, -34, -28, -21, -14, -42, -69, -40, -11, -16, -3, 41, 68, 53, 29, 48, 61, 32, 0, -5, 8, 2, -33, -28, 9, 31, 16, 16, 34, 22, 0, 10, 24, 10, -9, -19, -6, -8, -26, -38, -34, -20, -10, 1, 11, -9, -33, -31, -32, -25, -18, -50, -65, -40, -15, -8, 13, 47, 65, 50, 33, 54, 62, 24, -2, 2, 12, -6, -31, -20, 12, 21, 10, 28, 34, 9, -5, 20, 20, -2, -13, -10, -4, -18, -33, -26, -16, -19, -14, 6, 8, -14, -31, -32, -29, -29, -31, -51, -69, -47, -12, 2, 21, 49, 56, 43, 45, 62, 54, 16, -2, 7, 9, -13, -22, -4, 12, 7, 13, 37, 33, 7, -4, 23, 9, -8, -8, -2, -8, -33, -38, -7, -1, -22, -19, 11, 7, -21, -29, -29, -29, -31, -32, -55, -80, -49, -7, 16, 31, 43, 45, 44, 56, 66, 45, 12, 2, 10, 3, -18, -13, 7, 9, -2, 17, 38, 22, 1, 5, 17, 4, -14, -12, -1, -11, -43, -38, 6, 5, -22, -15, 12, 0, -23, -26, -28, -31, -32, -36, -60, -82, -46, 3, 24, 35, 38, 41, 46, 59, 62, 41, 13, -1, 3, -6, -18, 3, 22, 2, -9, 20, 36, 18, 10, 7, 4, -5, -17, -9, -2, -18, -55, -30, 17, 6, -20, -10, 6, -5, -16, -26, -32, -27, -30, -42, -69, -84, -41, 13, 31, 42, 37, 38, 45, 63, 65, 41, 12, 3, 1, -18, -10, 23, 27, -2, -12, 17, 36, 26, 13, 4, -2, -5, -14, -14, -11, -26, -54, -19, 21, 8, -16, -8, 6, -7, -20, -30, -33, -24, -33, -50, -74, -82, -32, 18, 34, 42, 38, 34, 50, 69, 58, 34, 16, 7, -9, -29, -2, 41, 32, -7, -15, 11, 34, 30, 9, 2, -3, -7, -23, -21, -15, -30, -52, -10, 18, 10, -8, -4, 5, -4, -25, -33, -26, -22, -42, -59, -79, -72, -20, 23, 36, 41, 37, 34, 54, 74, 53, 22, 17, 15, -17, -34, 10, 52, 37, -8, -11, 12, 33, 23, 8, 4, -1, -16, -31, -25, -18, -38, -49, -3, 19, 11, -4, 0, 7, -8, -34, -31, -19, -26, -52, -62, -79, -55, -7, 23, 41, 47, 41, 33, 61, 75, 43, 22, 21, 13, -26, -33, 17, 58, 39, -6, -8, 13, 27, 10, 5, 13, -2, -32, -43, -32, -19, -38, -36, -3, 12, 4, 4, 13, 6, -22, -41, -31, -13, -33, -59, -71, -76, -35, 2, 20, 39, 53, 47, 39, 60, 62, 37, 26, 22, 5, -33, -29, 26, 64, 40, 0, -5, 12, 21, 8, 16, 10, -13, -39, -49, -37, -25, -41, -30, -6, 9, 9, 13, 23, 0, -30, -44, -26, -13, -45, -67, -76, -68, -20, 10, 19, 39, 55, 50, 46, 57, 50, 37, 30, 16, -3, -34, -22, 34, 65, 40, 13, -2, 6, 19, 12, 21, 5, -23, -49, -52, -38, -33, -36, -24, -9, 10, 12, 25, 23, -11, -29, -43, -27, -21, -55, -73, -77, -50, -2, 19, 19, 35, 59, 59, 49, 45, 40, 36, 27, 4, -10, -24, -12, 31, 59, 44, 22, -5, 4, 19, 20, 12, -4, -27, -52, -50, -45, -39, -24, -23, -13, 16, 20, 30, 15, -16, -28, -37, -30, -36, -64, -79, -73, -28, 17, 24, 14, 36, 65, 68, 45, 33, 39, 40, 22, -2, -5, -11, -11, 28, 58, 57, 20, -13, 0, 27, 23, 1, -15, -35, -58, -55, -52, -39, -20, -22, -9, 20, 29, 30, 10, -15, -31, -39, -32, -48, -72, -86, -59, -4, 27, 19, 17, 44, 77, 69, 31, 26, 40, 38, 14, -6, 0, 1, -11, 26, 67, 62, 10, -18, 6, 31, 20, -5, -22, -44, -66, -61, -50, -31, -17, -24, -7, 24, 34, 31, 3, -17, -31, -36, -40, -61, -73, -76, -46, 11, 34, 20, 22, 56, 83, 60, 22, 24, 46, 32, 5, -4, 9, 0, -8, 31, 73, 53, 0, -13, 16, 28, 14, -15, -31, -51, -74, -64, -43, -25, -22, -25, -1, 30, 37, 20, -2, -20, -36, -39, -55, -69, -75, -69, -32, 21, 36, 22, 31, 63, 76, 50, 22, 25, 49, 29, 3, 4, 9, 2, 0, 43, 74, 37, -8, -1, 28, 24, 8, -22, -42, -65, -80, -60, -31, -25, -31, -24, 8, 41, 37, 10, -3, -22, -40, -45, -60, -69, -69, -55, -15, 32, 37, 25, 42, 72, 70, 37, 21, 32, 41, 20, 5, 15, 8, 0, 9, 46, 62, 26, -7, 8, 28, 21, 4, -29, -53, -79, -82, -57, -25, -27, -32, -21, 14, 48, 35, -1, -7, -24, -44, -52, -70, -69, -60, -38, 1, 34, 33, 32, 57, 70, 58, 34, 26, 31, 31, 16, 14, 14, 3, 8, 25, 47, 47, 18, -2, 13, 25, 19, -2, -33, -64, -87, -83, -53, -24, -29, -32, -17, 21, 46, 27, -4, -12, -30, -51, -61, -73, -60, -46, -17, 9, 25, 32, 47, 69, 61, 48, 41, 30, 26, 24, 18, 24, 15, 2, 14, 37, 42, 34, 17, 9, 19, 20, 11, -7, -35, -79, -97, -79, -45, -21, -29, -33, -12, 26, 43, 27, -3, -15, -43, -58, -66, -69, -52, -37, -2, 16, 24, 38, 61, 72, 56, 43, 41, 32, 28, 22, 22, 26, 12, 1, 23, 45, 34, 21, 8, 17, 22, 19, 4, -18, -47, -93, -97, -70, -40, -29, -33, -22, -5, 24, 44, 19, -6, -23, -53, -60, -74, -63, -41, -20, 10, 18, 19, 40, 70, 70, 47, 41, 43, 37, 27, 14, 24, 32, 10, 1, 29, 44, 27, 12, 7, 28, 32, 9, -11, -27, -56, -100, -94, -64, -43, -38, -31, -7, 0, 27, 41, 11, -7, -35, -60, -62, -75, -54, -29, -5, 17, 22, 14, 46, 80, 72, 46, 42, 44, 42, 24, 16, 31, 32, 9, 4, 33, 45, 22, 5, 8, 41, 34, 0, -22, -36, -69, -100, -92, -65, -40, -44, -25, 0, 5, 28, 36, 4, -12, -50, -64, -64, -68, -46, -19, 2, 25, 28, 19, 44, 72, 67, 46, 45, 44, 39, 21, 21, 38, 29, 1, 9, 39, 39, 13, -4, 9, 54, 41, -11, -38, -51, -76, -91, -92, -65, -44, -47, -17, 12, 11, 21, 27, 6, -24, -59, -65, -67, -61, -40, -17, 8, 31, 26, 20, 49, 74, 65, 45, 48, 47, 36, 25, 28, 36, 25, 5, 19, 42, 28, 6, -2, 21, 56, 27, -22, -45, -62, -83, -92, -84, -65, -49, -37, -8, 15, 16, 22, 23, -1, -38, -65, -66, -65, -51, -35, -15, 20, 42, 26, 25, 51, 70, 60, 45, 52, 47, 25, 25, 39, 33, 24, 16, 31, 37, 14, 3, 2, 33, 55, 14, -35, -55, -67, -84, -88, -84, -68, -47, -28, -1, 17, 22, 24, 17, -14, -54, -66, -64, -61, -46, -32, -10, 26, 45, 24, 29, 52, 66, 57, 49, 56, 41, 16, 29, 46, 31, 22, 24, 37, 30, 12, -1, 5, 40, 39, 1, -41, -63, -72, -89, -89, -77, -62, -48, -17, 5, 13, 26, 31, 10, -29, -62, -64, -65, -54, -41, -25, -4, 32, 52, 29, 32, 55, 61, 55, 56, 57, 35, 17, 33, 40, 28, 27, 37, 36, 26, 14, -3, 13, 41, 22, -13, -45, -65, -78, -90, -87, -70, -56, -47, -12, 9, 18, 35, 27, -5, -41, -63, -61, -65, -52, -37, -17, 5, 35, 52, 34, 38, 55, 58, 53, 60, 54, 31, 21, 33, 34, 30, 35, 40, 32, 29, 15, -4, 18, 30, 11, -25, -53, -69, -85, -91, -82, -66, -54, -36, -7, 6, 20, 40, 19, -17, -52, -63, -60, -65, -50, -32, -11, 9, 34, 50, 40, 46, 51, 56, 60, 60, 50, 28, 23, 33, 33, 31, 40, 43, 38, 38, 13, -6, 13, 19, -2, -34, -57, -78, -91, -85, -73, -63, -55, -28, -1, 6, 26, 39, 13, -28, -56, -61, -55, -61, -43, -27, -13, 12, 38, 48, 49, 54, 46, 52, 64, 64, 48, 27, 22, 28, 33, 36, 44, 42, 39, 44, 15, -3, 10, 6, -19, -46, -60, -81, -92, -83, -73, -52, -44, -22, -5, 5, 38, 37, -6, -41, -55, -54, -49, -53, -45, -28, -9, 19, 41, 47, 56, 57, 41, 56, 69, 64, 42, 26, 23, 27, 36, 39, 44, 39, 48, 53, 12, -4, 2, -8, -33, -61, -72, -84, -87, -80, -73, -49, -36, -12, -5, 9, 42, 24, -15, -44, -50, -51, -51, -51, -45, -26, -4, 20, 40, 47, 64, 58, 38, 61, 71, 55, 37, 32, 23, 30, 34, 39, 50, 43, 58, 53, 9, 4, -3, -27, -49, -71, -79, -79, -79, -82, -70, -44, -26, -7, -5, 16, 36, 9, -18, -40, -47, -49, -45, -42, -43, -20, 1, 21, 40, 53, 72, 54, 36, 64, 66, 41, 30, 36, 26, 28, 31, 44, 57, 48, 62, 45, 13, 3, -14, -47, -65, -77, -87, -78, -71, -75, -68, -43, -16, -2, -1, 18, 20, -4, -18, -37, -46, -50, -36, -39, -46, -15, 7, 23, 41, 62, 72, 49, 41, 69, 59, 33, 29, 38, 24, 28, 31, 52, 59, 49, 61, 45, 21, 2, -31, -64, -73, -78, -89, -79, -71, -77, -62, -36, -8, 3, 5, 15, 5, -10, -17, -34, -49, -50, -27, -37, -43, -12, 14, 25, 45, 67, 68, 48, 48, 64, 48, 27, 33, 41, 25, 24, 32, 64, 66, 51, 62, 41, 21, -7, -43, -77, -81, -83, -87, -74, -71, -77, -54, -29, -1, 7, 13, 12, -6, -9, -18, -38, -54, -44, -21, -37, -41, -8, 16, 28, 53, 73, 61, 46, 52, 60, 35, 25, 34, 38, 20, 25, 42, 73, 62, 60, 58, 39, 22, -19, -54, -85, -88, -95, -88, -65, -69, -73, -47, -22, 3, 14, 15, -5, -14, -6, -23, -42, -52, -34, -19, -42, -38, 0, 18, 30, 62, 76, 61, 49, 52, 49, 26, 23, 34, 33, 22, 21, 50, 78, 68, 66, 47, 40, 22, -23, -66, -95, -102, -97, -74, -61, -77, -68, -36, -12, 9, 15, 13, -18, -14, -5, -31, -50, -44, -21, -25, -49, -25, 8, 16, 30, 70, 82, 56, 45, 55, 39, 21, 25, 31, 24, 21, 28, 64, 81, 68, 64, 47, 44, 15, -30, -77, -101, -104, -96, -71, -66, -76, -53, -22, -9, 6, 22, 10, -22, -15, -13, -38, -48, -32, -9, -33, -49, -14, 10, 11, 37, 77, 85, 51, 44, 48, 30, 18, 21, 26, 16, 21, 36, 71, 76, 73, 68, 48, 35, 4, -38, -81, -103, -109, -91, -67, -71, -69, -40, -15, -12, 3, 23, 7, -23, -17, -24, -41, -45, -24, -11, -46, -46, -1, 10, 8, 49, 84, 83, 48, 50, 48, 27, 16, 18, 20, 14, 26, 44, 72, 75, 82, 71, 47, 26, -6, -45, -80, -107, -110, -88, -70, -69, -58, -28, -9, -12, 2, 23, 2, -21, -19, -35, -38, -33, -13, -17, -50, -35, 8, 9, 10, 57, 89, 74, 45, 52, 41, 24, 15, 11, 14, 13, 22, 54, 72, 74, 86, 72, 41, 13, -14, -47, -86, -113, -111, -88, -72, -67, -42, -18, -11, -11, 2, 18, -2, -17, -27, -44, -37, -28, -12, -26, -49, -22, 9, 3, 21, 69, 87, 63, 46, 49, 36, 24, 13, 11, 11, 8, 26, 64, 68, 76, 89, 74, 38, 3, -17, -44, -86, -117, -114, -86, -65, -58, -38, -19, -7, 0, 8, 9, -5, -20, -37, -45, -29, -19, -15, -36, -39, -10, 6, 4, 33, 79, 81, 55, 48, 42, 30, 23, 10, 13, 10, 3, 27, 62, 60, 76, 88, 68, 30, -5, -21, -49, -89, -120, -115, -81, -54, -46, -34, -14, -1, 7, 9, 1, -6, -18, -45, -52, -29, -16, -17, -35, -36, -12, 5, 11, 47, 81, 72, 53, 51, 39, 28, 24, 9, 13, 7, 5, 36, 57, 55, 82, 90, 62, 31, -10, -29, -55, -91, -121, -115, -76, -47, -38, -34, -13, 1, 13, 9, -4, -9, -17, -49, -56, -26, -9, -12, -33, -40, -17, 12, 25, 57, 71, 62, 52, 50, 35, 22, 21, 14, 11, -2, 10, 41, 50, 48, 85, 87, 66, 29, -15, -34, -64, -97, -121, -108, -73, -43, -37, -28, -7, 7, 16, 6, -7, -5, -15, -59, -56, -19, -4, -14, -37, -42, -10, 21, 38, 66, 63, 57, 52, 49, 28, 22, 28, 16, 5, -3, 22, 47, 38, 45, 79, 85, 68, 23, -16, -34, -70, -100, -122, -107, -62, -39, -38, -25, -4, 15, 18, 2, -3, 0, -27, -70, -51, -17, -3, -16, -44, -40, -1, 27, 45, 67, 57, 54, 48, 39, 17, 18, 28, 17, 3, -3, 27, 49, 37, 42, 69, 86, 66, 16, -17, -37, -72, -99, -117, -101, -55, -39, -36, -24, 1, 20, 13, 4, 4, -5, -46, -74, -43, -9, -4, -28, -49, -33, 6, 33, 63, 68, 54, 53, 49, 33, 18, 21, 24, 15, 7, 9, 33, 42, 35, 39, 70, 85, 55, 10, -16, -40, -75, -98, -113, -92, -47, -38, -35, -21, 1, 21, 15, 8, 7, -14, -62, -70, -30, -11, -15, -34, -49, -23, 9, 39, 64, 58, 51, 56, 42, 20, 16, 19, 16, 16, 4, 13, 40, 46, 33, 31, 65, 83, 49, 3, -24, -41, -73, -98, -105, -77, -45, -41, -30, -13, 7, 19, 12, 13, 8, -26, -68, -61, -22, -14, -25, -38, -40, -18, 12, 47, 68, 59, 49, 51, 42, 19, 17, 17, 12, 13, 5, 18, 41, 47, 26, 26, 67, 78, 44, -2, -31, -47, -71, -97, -96, -67, -44, -42, -29, -11, 13, 21, 13, 17, 8, -34, -68, -54, -17, -18, -36, -43, -35, -12, 14, 50, 69, 56, 49, 44, 35, 16, 13, 17, 13, 13, 6, 27, 46, 50, 24, 28, 66, 64, 28, 0, -25, -49, -75, -99, -87, -54, -42, -38, -28, -8, 20, 19, 11, 17, 1, -41, -62, -49, -18, -27, -41, -39, -29, -8, 15, 55, 73, 55, 42, 42, 33, 16, 12, 12, 9, 6, 14, 40, 52, 48, 21, 31, 60, 50, 23, 0, -32, -60, -76, -90, -73, -44, -39, -36, -32, 1, 29, 20, 6, 13, -3, -41, -53, -43, -21, -34, -47, -38, -22, -2, 22, 54, 65, 49, 38, 42, 32, 17, 12, 7, 6, 3, 21, 48, 53, 42, 24, 39, 53, 38, 15, -3, -38, -65, -76, -85, -59, -36, -35, -40, -26, 15, 26, 12, 6, 10, -12, -40, -49, -33, -26, -41, -53, -36, -12, 5, 28, 50, 61, 46, 34, 37, 31, 20, 12, 1, 0, 5, 32, 53, 56, 41, 23, 39, 48, 35, 13, -10, -44, -72, -81, -79, -50, -27, -34, -41, -18, 20, 27, 12, 5, 1, -19, -36, -40, -22, -34, -50, -55, -33, -3, 14, 33, 52, 54, 35, 27, 36, 37, 25, 7, -13, 1, 19, 41, 50, 50, 38, 32, 43, 41, 32, 6, -17, -46, -69, -79, -75, -43, -20, -34, -38, -8, 23, 26, 12, 6, -8, -23, -30, -30, -23, -46, -56, -52, -29, 6, 23, 35, 44, 47, 31, 25, 33, 40, 26, -4, -22, 3, 28, 39, 40, 50, 40, 28, 34, 37, 28, 0, -22, -50, -70, -81, -72, -34, -22, -36, -33, 2, 24, 25, 12, 4, -15, -24, -26, -25, -23, -46, -56, -50, -24, 10, 33, 36, 40, 35, 21, 25, 43, 47, 25, -13, -25, 11, 40, 36, 40, 56, 38, 27, 31, 33, 24, -4, -24, -53, -71, -80, -59, -34, -27, -31, -27, 8, 24, 25, 17, 2, -22, -25, -26, -19, -24, -51, -58, -40, -9, 14, 37, 36, 35, 27, 14, 28, 48, 46, 19, -19, -24, 18, 40, 29, 41, 50, 29, 29, 27, 33, 18, -12, -29, -53, -71, -75, -48, -33, -32, -25, -14, 13, 24, 19, 17, 2, -25, -28, -28, -18, -28, -55, -59, -30, -3, 20, 41, 34, 24, 15, 15, 36, 49, 39, 17, -17, -17, 22, 41, 33, 45, 38, 26, 30, 24, 27, 10, -11, -34, -58, -70, -66, -38, -32, -36, -21, -2, 14, 28, 19, 14, 0, -25, -29, -28, -17, -30, -57, -51, -22, 3, 23, 39, 34, 15, 11, 17, 38, 46, 39, 15, -18, -14, 27, 40, 37, 45, 32, 28, 30, 29, 28, 1, -16, -38, -55, -65, -62, -37, -31, -34, -17, 9, 18, 27, 18, 9, -1, -22, -35, -29, -17, -32, -57, -45, -17, 15, 30, 30, 25, 8, 10, 19, 35, 46, 37, 4, -19, -8, 31, 33, 33, 42, 28, 22, 24, 29, 23, -6, -21, -43, -54, -59, -55, -32, -34, -39, -10, 19, 30, 25, 9, 2, -2, -20, -38, -30, -23, -41, -51, -35, -12, 24, 32, 22, 12, 8, 16, 23, 32, 48, 33, 1, -16, 0, 29, 30, 33, 36, 24, 23, 22, 33, 14, -14, -20, -42, -55, -50, -44, -27, -38, -41, -3, 31, 35, 23, 5, -2, -4, -15, -34, -33, -38, -47, -40, -26, -3, 31, 31, 9, 2, 13, 14, 20, 38, 53, 27, -6, -14, 11, 30, 23, 32, 28, 25, 22, 24, 32, 5, -20, -26, -45, -49, -40, -36, -37, -48, -40, 8, 40, 37, 16, -3, -6, -2, -9, -27, -42, -52, -48, -32, -21, 8, 39, 28, -2, -5, 13, 17, 23, 40, 45, 19, -4, -3, 18, 15, 19, 33, 30, 29, 22, 21, 22, 0, -17, -27, -46, -48, -33, -31, -38, -53, -33, 23, 43, 31, 11, -7, -5, -3, -8, -26, -49, -59, -48, -25, -14, 15, 41, 23, -8, -6, 11, 10, 26, 49, 41, 12, 0, 10, 19, 4, 22, 31, 25, 25, 24, 20, 12, -4, -10, -37, -50, -37, -23, -26, -43, -55, -18, 34, 41, 28, 10, -9, -6, -3, -8, -27, -57, -62, -37, -15, -8, 24, 44, 23, -10, -6, 3, 8, 39, 55, 30, 12, 11, 20, 8, 3, 27, 26, 20, 21, 24, 19, -1, -10, -14, -42, -47, -25, -14, -28, -49, -50, -5, 38, 38, 23, 9, -11, -9, -1, -5, -33, -64, -59, -34, -14, -2, 32, 49, 17, -11, -6, -2, 11, 46, 46, 19, 16, 23, 24, -3, 3, 29, 29, 16, 17, 22, 11, -12, -12, -18, -50, -43, -15, -11, -30, -53, -38, 10, 31, 31, 25, 3, -16, -3, 3, -8, -41, -67, -53, -24, -14, 3, 35, 46, 17, -2, -7, -9, 16, 49, 41, 20, 22, 34, 21, -5, 5, 31, 29, 12, 14, 18, 8, -22, -17, -20, -52, -38, -13, -19, -32, -48, -25, 11, 23, 29, 26, 1, -14, 1, 1, -18, -47, -60, -47, -31, -11, 13, 45, 39, 8, -2, -2, -11, 16, 43, 35, 25, 34, 40, 18, -7, 6, 34, 28, 14, 7, 11, 2, -23, -25, -29, -51, -30, -11, -24, -38, -40, -15, 9, 18, 29, 32, -1, -10, 0, -9, -27, -48, -52, -46, -30, -2, 27, 47, 30, 10, 7, -6, -15, 12, 35, 28, 30, 45, 42, 19, -4, 11, 29, 21, 6, 1, 3, -3, -27, -31, -34, -40, -22, -18, -31, -35, -30, -18, 5, 19, 32, 28, -9, -7, 1, -14, -30, -42, -45, -47, -28, 7, 38, 45, 23, 14, 20, -2, -24, 7, 32, 30, 37, 43, 41, 22, 7, 18, 22, 14, 4, -7, 4, -7, -36, -37, -37, -27, -15, -26, -34, -34, -29, -18, 4, 19, 31, 20, -4, 0, -3, -21, -32, -37, -41, -40, -25, 14, 49, 44, 18, 19, 25, -1, -19, 5, 26, 35, 38, 46, 41, 18, 18, 16, 13, 12, 2, -5, -3, -23, -44, -37, -32, -20, -20, -33, -28, -32, -32, -16, 1, 17, 31, 17, -2, 2, -3, -22, -33, -39, -40, -34, -23, 15, 56, 44, 15, 27, 23, -4, -14, 2, 22, 38, 37, 48, 40, 25, 24, 15, 11, 2, -2, -3, -15, -31, -40, -37, -33, -17, -17, -28, -29, -41, -34, -7, 1, 13, 31, 17, -2, 4, 1, -20, -35, -47, -37, -24, -10, 22, 52, 38, 26, 35, 26, -2, -9, 4, 23, 40, 38, 46, 39, 32, 31, 16, 2, -7, -8, -2, -21, -38, -44, -38, -31, -18, -15, -29, -35, -45, -32, -1, -3, 4, 30, 16, 3, 8, 4, -20, -42, -48, -30, -17, -8, 21, 49, 41, 30, 38, 23, -2, -5, 1, 21, 35, 37, 44, 40, 40, 33, 17, 1, -13, -10, -9, -35, -41, -41, -39, -33, -19, -12, -27, -40, -48, -28, -4, -10, 10, 28, 15, 9, 12, 5, -24, -43, -43, -23, -18, 0, 26, 47, 43, 35, 40, 20, -1, 1, 4, 20, 28, 37, 42, 42, 46, 31, 22, 8, -17, -15, -15, -42, -41, -37, -44, -37, -16, -13, -33, -41, -41, -20, -11, -17, 10, 18, 13, 16, 17, 1, -24, -38, -38, -27, -21, 9, 29, 46, 44, 43, 38, 18, 3, 6, 6, 12, 19, 38, 41, 47, 44, 28, 29, 11, -26, -25, -27, -45, -39, -39, -48, -41, -18, -13, -33, -38, -36, -21, -19, -14, 13, 11, 11, 26, 17, -6, -25, -32, -32, -35, -14, 21, 31, 38, 49, 49, 34, 19, 13, 10, 4, 9, 20, 37, 41, 45, 39, 29, 35, 6, -28, -28, -35, -43, -37, -42, -50, -44, -20, -20, -37, -37, -27, -16, -23, -11, 10, 5, 17, 36, 16, -16, -23, -21, -33, -38, -5, 23, 28, 35, 55, 55, 31, 17, 18, 12, 3, 4, 21, 33, 41, 45, 31, 32, 39, 3, -29, -35, -41, -40, -38, -45, -55, -45, -26, -31, -36, -26, -22, -22, -29, 1, 9, -1, 24, 39, 8, -19, -17, -14, -32, -34, 5, 29, 29, 35, 58, 51, 32, 29, 23, 11, 1, 6, 29, 37, 38, 36, 24, 43, 39, -2, -32, -44, -45, -36, -36, -45, -55, -51, -37, -35, -30, -22, -20, -32, -24, 6, 2, 3, 30, 36, 3, -17, -16, -18, -29, -24, 10, 31, 25, 34, 58, 44, 33, 37, 26, 8, 5, 10, 37, 36, 35, 29, 22, 47, 36, -6, -36, -51, -49, -34, -38, -48, -58, -53, -46, -42, -24, -23, -22, -32, -13, 4, -7, 8, 35, 30, 6, -14, -20, -19, -21, -20, 14, 34, 29, 43, 52, 37, 39, 43, 24, 8, 7, 15, 45, 33, 36, 24, 25, 43, 25, -10, -39, -53, -47, -34, -39, -53, -56, -54, -56, -42, -21, -23, -29, -25, -5, 1, -10, 12, 35, 27, 7, -14, -25, -19, -11, -10, 13, 31, 37, 44, 42, 37, 45, 44, 24, 14, 13, 24, 40, 28, 35, 23, 31, 35, 15, -16, -38, -53, -45, -37, -48, -56, -54, -63, -63, -40, -23, -24, -27, -19, 3, 1, -11, 14, 33, 24, 5, -16, -28, -17, -6, -1, 15, 38, 39, 38, 29, 36, 54, 42, 20, 20, 19, 32, 38, 30, 31, 23, 33, 23, -1, -17, -35, -44, -43, -47, -51, -51, -56, -71, -67, -45, -28, -23, -23, -13, 12, -1, -15, 15, 33, 20, -2, -22, -25, -17, -3, 10, 24, 46, 44, 31, 26, 41, 53, 42, 23, 23, 26, 39, 37, 32, 24, 28, 36, 11, -7, -19, -38, -39, -37, -49, -54, -51, -62, -76, -68, -51, -28, -19, -21, 1, 22, -3, -11, 14, 25, 16, -5, -25, -25, -15, -2, 20, 36, 51, 42, 19, 19, 43, 58, 43, 25, 21, 35, 46, 41, 34, 17, 26, 33, 5, -15, -25, -39, -34, -37, -55, -50, -49, -69, -80, -67, -50, -31, -18, -12, 12, 17, -5, -5, 14, 17, 6, -15, -27, -22, -14, 3, 37, 49, 48, 40, 22, 22, 36, 51, 44, 29, 22, 42, 49, 41, 29, 16, 29, 31, -9, -30, -33, -35, -29, -38, -55, -45, -54, -79, -80, -65, -51, -34, -16, -2, 18, 18, 5, 7, 8, 6, 3, -19, -21, -22, -19, 12, 51, 53, 48, 39, 22, 18, 36, 46, 42, 35, 31, 44, 46, 42, 31, 24, 35, 21, -25, -39, -33, -30, -24, -41, -53, -47, -60, -81, -81, -63, -53, -40, -14, 6, 24, 20, 8, 7, 0, -1, -4, -21, -23, -29, -16, 30, 60, 55, 50, 37, 19, 19, 35, 43, 46, 37, 29, 43, 49, 43, 32, 27, 31, 13, -35, -46, -36, -26, -28, -44, -52, -47, -65, -84, -84, -68, -49, -27, 0, 10, 15, 19, 15, 9, -3, -10, -16, -20, -26, -28, -2, 41, 59, 62, 56, 37, 16, 15, 31, 43, 50, 42, 30, 41, 49, 49, 38, 28, 23, 5, -42, -55, -42, -21, -22, -40, -49, -54, -71, -86, -81, -62, -44, -21, 5, 17, 16, 25, 23, 0, -13, -17, -17, -24, -32, -21, 15, 45, 58, 66, 52, 33, 15, 9, 35, 42, 44, 44, 36, 38, 50, 52, 40, 28, 16, -11, -48, -60, -43, -22, -21, -40, -53, -58, -78, -90, -79, -61, -42, -9, 14, 15, 16, 22, 21, -4, -20, -21, -19, -30, -31, -10, 26, 54, 63, 69, 51, 33, 12, 13, 40, 42, 45, 42, 33, 36, 53, 57, 44, 24, 3, -24, -53, -63, -45, -21, -15, -39, -57, -63, -78, -89, -76, -55, -34, 3, 18, 9, 16, 21, 15, -8, -26, -28, -25, -32, -24, 4, 34, 56, 67, 75, 48, 22, 7, 23, 44, 39, 40, 40, 35, 40, 59, 59, 44, 18, -6, -31, -54, -58, -44, -20, -13, -43, -63, -69, -80, -88, -71, -48, -21, 12, 16, 12, 18, 13, 6, -12, -27, -32, -30, -34, -20, 13, 46, 63, 74, 73, 40, 15, 13, 39, 46, 33, 32, 35, 36, 48, 58, 61, 43, 16, -13, -36, -57, -62, -41, -22, -16, -42, -66, -73, -79, -85, -65, -38, -7, 13, 9, 7, 16, 11, -2, -18, -36, -39, -26, -25, -16, 21, 53, 64, 74, 68, 36, 19, 22, 38, 44, 32, 28, 32, 38, 52, 60, 56, 43, 13, -25, -39, -54, -52, -35, -30, -27, -46, -70, -79, -80, -79, -58, -26, 3, 15, 6, 0, 12, 6, -8, -27, -45, -39, -17, -16, -13, 28, 57, 67, 71, 57, 37, 22, 25, 41, 46, 29, 24, 34, 44, 56, 55, 52, 44, 7, -27, -38, -48, -44, -35, -31, -29, -46, -77, -83, -73, -70, -48, -15, 6, 9, 1, 1, 9, -3, -20, -41, -48, -30, -5, -14, -9, 39, 63, 70, 66, 47, 36, 25, 32, 40, 43, 26, 21, 36, 47, 59, 50, 49, 35, 0, -26, -36, -44, -41, -36, -35, -33, -50, -79, -79, -66, -63, -36, -8, 6, -3, -9, 2, 3, -13, -30, -49, -46, -18, -2, -15, 4, 42, 58, 65, 61, 50, 38, 28, 37, 40, 38, 28, 30, 38, 48, 50, 42, 46, 28, -3, -28, -37, -36, -36, -39, -36, -37, -59, -79, -69, -62, -52, -24, -2, 3, -12, -11, 4, -5, -29, -42, -53, -39, -12, -4, -4, 14, 37, 52, 63, 58, 50, 37, 34, 37, 36, 37, 38, 36, 35, 47, 46, 44, 42, 18, -7, -30, -34, -32, -34, -41, -37, -45, -66, -74, -64, -57, -36, -12, 1, -8, -23, -7, 6, -18, -39, -49, -53, -29, -5, -1, 10, 19, 30, 46, 59, 58, 50, 36, 37, 37, 32, 40, 46, 38, 34, 44, 42, 41, 36, 9, -9, -27, -29, -26, -34, -40, -40, -56, -69, -66, -56, -46, -22, -7, -7, -19, -21, 3, 1, -35, -48, -53, -49, -22, -3, 12, 23, 18, 22, 46, 66, 59, 47, 38, 43, 35, 30, 46, 51, 39, 33, 41, 37, 42, 24, 2, -8, -22, -23, -24, -33, -39, -50, -66, -69, -59, -49, -31, -13, -10, -17, -25, -16, 1, -17, -50, -55, -58, -42, -17, -1, 20, 31, 14, 15, 48, 70, 59, 42, 38, 45, 33, 33, 51, 53, 36, 35, 37, 36, 37, 12, 0, -9, -16, -18, -22, -33, -42, -59, -67, -62, -52, -40, -20, -11, -15, -23, -23, -11, -3, -28, -51, -59, -61, -38, -14, 4, 26, 30, 10, 18, 53, 71, 56, 40, 42, 45, 32, 34, 53, 52, 37, 36, 32, 37, 32, 10, -3, -10, -10, -11, -17, -31, -46, -62, -63, -54, -44, -30, -14, -14, -23, -27, -22, -11, -11, -35, -51, -65, -59, -32, -11, 11, 29, 25, 8, 24, 63, 73, 51, 38, 46, 44, 29, 34, 51, 51, 39, 34, 27, 34, 23, 3, -5, -9, -6, -10, -18, -33, -51, -66, -60, -50, -35, -20, -10, -21, -33, -29, -17, -9, -20, -39, -55, -71, -57, -26, -7, 11, 23, 22, 11, 35, 70, 71, 46, 39, 48, 42, 29, 33, 51, 47, 38, 31, 28, 35, 17, 0, -12, -7, 0, -4, -15, -36, -56, -67, -56, -42, -26, -15, -12, -29, -36, -28, -15, -13, -25, -40, -58, -70, -49, -23, -6, 8, 19, 17, 18, 49, 76, 66, 40, 42, 49, 39, 25, 35, 51, 43, 40, 30, 31, 32, 15, -1, -14, -7, 1, -2, -17, -40, -59, -61, -51, -38, -21, -10, -17, -34, -35, -28, -18, -17, -24, -40, -64, -65, -40, -18, -8, 5, 13, 17, 31, 61, 75, 60, 41, 43, 47, 34, 20, 36, 47, 43, 41, 31, 32, 26, 7, -7, -16, -6, 0, -3, -22, -44, -60, -56, -47, -34, -19, -8, -20, -39, -40, -27, -18, -20, -29, -44, -63, -56, -38, -23, -11, 4, 14, 21, 42, 65, 71, 59, 45, 42, 34, 21, 20, 42, 48, 44, 41, 31, 34, 24, 6, -10, -20, -11, 4, 0, -20, -48, -57, -47, -39, -30, -17, -4, -24, -43, -40, -26, -19, -24, -29, -45, -59, -51, -37, -25, -14, 3, 15, 27, 51, 72, 76, 61, 44, 38, 23, 12, 21, 43, 46, 45, 40, 31, 35, 21, 5, -17, -22, -13, 3, 1, -24, -51, -52, -43, -37, -28, -8, -7, -38, -46, -36, -21, -21, -31, -33, -45, -51, -47, -40, -30, -13, 4, 14, 33, 60, 76, 76, 61, 47, 30, 16, 8, 20, 40, 45, 48, 37, 37, 37, 22, 3, -19, -20, -10, 4, -6, -30, -49, -44, -41, -38, -23, -1, -14, -41, -44, -36, -22, -26, -35, -33, -45, -52, -48, -40, -32, -9, 6, 18, 35, 65, 85, 80, 62, 46, 24, 6, -1, 23, 41, 48, 45, 31, 42, 40, 23, -6, -21, -15, -6, 0, -13, -31, -44, -41, -38, -32, -15, 0, -22, -40, -41, -36, -24, -31, -28, -32, -46, -49, -47, -43, -30, -6, 9, 19, 46, 77, 87, 77, 61, 42, 18, -2, -7, 22, 39, 51, 41, 32, 43, 35, 13, -18, -18, -10, -5, -8, -21, -29, -39, -42, -41, -23, -3, -3, -32, -39, -38, -34, -31, -35, -23, -32, -46, -50, -51, -46, -26, 0, 12, 20, 54, 87, 91, 72, 60, 38, 13, -10, -11, 24, 44, 52, 43, 39, 45, 34, 2, -19, -8, -1, -8, -19, -19, -25, -35, -42, -39, -17, 7, -7, -38, -36, -36, -37, -37, -31, -20, -34, -49, -53, -50, -43, -19, 6, 10, 25, 66, 91, 84, 67, 60, 36, 1, -18, -10, 27, 48, 52, 42, 42, 38, 25, -3, -18, -5, -2, -13, -22, -24, -28, -35, -45, -35, -4, 14, -17, -41, -36, -33, -35, -41, -29, -20, -38, -51, -54, -46, -33, -14, 6, 14, 37, 74, 87, 76, 65, 64, 29, -9, -22, -7, 23, 52, 55, 46, 42, 25, 17, -5, -12, -4, -3, -17, -25, -33, -36, -33, -39, -30, 5, 12, -25, -37, -33, -34, -42, -41, -25, -22, -41, -52, -53, -40, -25, -10, 11, 21, 43, 72, 78, 74, 69, 58, 15, -13, -15, -4, 22, 54, 58, 53, 41, 15, 6, -2, -1, -3, -6, -18, -24, -42, -40, -29, -32, -20, 13, 8, -25, -35, -34, -29, -42, -43, -27, -27, -42, -51, -50, -30, -14, -5, 17, 26, 46, 70, 72, 72, 69, 48, 2, -13, -9, -3, 19, 55, 59, 53, 30, 1, -1, 5, 8, -7, -15, -19, -25, -48, -45, -31, -28, -10, 15, 1, -24, -35, -35, -22, -37, -43, -36, -35, -41, -47, -45, -18, -6, -1, 24, 32, 51, 65, 65, 67, 63, 37, -3, -13, -9, 1, 29, 54, 60, 50, 18, -4, -4, 13, 9, -10, -15, -17, -30, -54, -47, -29, -20, -8, 4, -8, -15, -29, -35, -21, -37, -43, -46, -37, -33, -48, -39, -10, 3, 13, 31, 34, 54, 56, 57, 63, 56, 32, -3, -16, -6, 14, 38, 48, 53, 40, 11, -3, 1, 6, -2, -11, -9, -11, -28, -54, -54, -29, -8, 2, -8, -16, -13, -27, -31, -21, -32, -45, -54, -36, -27, -44, -33, 1, 16, 25, 29, 39, 56, 48, 51, 57, 48, 22, 3, -14, 0, 22, 39, 42, 46, 36, 7, -7, 0, 0, -3, -8, -8, -15, -34, -50, -49, -27, -3, 0, -15, -14, -16, -28, -26, -21, -34, -56, -55, -32, -30, -41, -23, 8, 20, 31, 33, 45, 53, 38, 42, 54, 40, 18, -3, -9, 14, 33, 37, 34, 34, 27, 8, -5, -1, -9, -3, -1, -8, -19, -35, -43, -42, -28, -7, 1, -18, -13, -17, -29, -24, -21, -34, -55, -52, -34, -30, -26, -9, 15, 28, 28, 32, 55, 50, 29, 38, 45, 35, 17, -3, -1, 18, 36, 40, 27, 24, 19, 0, -5, -1, -14, -7, -2, -12, -20, -30, -40, -42, -25, -5, -5, -24, -14, -16, -25, -20, -26, -38, -52, -49, -35, -31, -13, 8, 16, 28, 29, 42, 57, 40, 23, 32, 35, 30, 12, -5, 9, 22, 40, 38, 19, 17, 16, -1, -9, -7, -12, -6, -5, -13, -18, -29, -39, -39, -18, -3, -19, -26, -11, -18, -24, -19, -30, -40, -51, -45, -30, -24, 0, 19, 22, 28, 36, 49, 54, 41, 22, 30, 31, 26, 10, 2, 10, 26, 43, 28, 14, 16, 7, -6, -12, -9, -9, -5, -12, -19, -16, -29, -35, -34, -8, -8, -35, -20, -7, -26, -23, -23, -30, -39, -53, -38, -25, -12, 11, 24, 24, 29, 47, 50, 48, 36, 20, 29, 24, 15, 5, 8, 12, 32, 40, 21, 17, 11, 0, -3, -15, -14, -7, -4, -13, -17, -16, -28, -31, -23, -6, -20, -37, -15, -12, -29, -22, -28, -30, -38, -54, -34, -20, -4, 21, 33, 24, 33, 50, 45, 40, 33, 27, 28, 14, 8, 8, 11, 11, 30, 33, 26, 20, -1, -8, -4, -17, -16, -2, -7, -22, -20, -20, -26, -26, -15, -10, -27, -35, -12, -19, -31, -21, -23, -23, -42, -57, -31, -11, 9, 35, 33, 23, 39, 53, 47, 40, 31, 31, 21, 10, 9, 11, 10, 13, 26, 35, 33, 13, -11, -10, -4, -19, -22, 3, -2, -28, -26, -16, -21, -24, -12, -12, -31, -34, -17, -27, -34, -25, -17, -19, -48, -59, -29, -2, 27, 46, 26, 22, 43, 54, 44, 38, 30, 29, 16, 6, 15, 15, 6, 9, 22, 36, 37, 9, -20, -10, -5, -21, -21, 2, -5, -29, -31, -18, -11, -17, -11, -15, -32, -34, -23, -30, -30, -25, -15, -22, -52, -50, -17, 9, 36, 42, 26, 29, 50, 53, 40, 33, 32, 27, 14, 7, 9, 7, 4, 12, 22, 36, 36, 3, -27, -16, -9, -20, -21, -1, -12, -31, -27, -13, -12, -18, -12, -17, -33, -39, -29, -34, -35, -23, -7, -25, -55, -42, -10, 20, 43, 40, 27, 33, 51, 51, 37, 34, 31, 21, 9, 8, 5, 2, 11, 16, 18, 34, 35, 3, -22, -17, -16, -20, -17, -7, -20, -32, -28, -14, -12, -10, -8, -17, -34, -41, -35, -34, -31, -19, -8, -27, -48, -29, -4, 26, 50, 44, 32, 37, 50, 49, 40, 36, 22, 11, 11, 12, 5, 3, 14, 12, 13, 34, 37, 9, -23, -24, -16, -21, -16, -17, -30, -27, -27, -20, -10, -10, -9, -18, -39, -46, -42, -35, -31, -14, -9, -33, -42, -19, 1, 36, 55, 41, 32, 46, 55, 47, 35, 32, 18, 6, 7, 9, -2, 7, 17, 8, 13, 34, 32, 10, -22, -27, -14, -20, -21, -26, -31, -23, -27, -22, -6, -5, -11, -21, -39, -46, -46, -37, -30, -14, -12, -33, -31, -8, 6, 41, 55, 40, 38, 54, 57, 39, 30, 33, 17, 2, 1, 4, 7, 14, 14, -2, 11, 37, 31, 11, -26, -30, -16, -20, -18, -21, -27, -32, -28, -12, 0, -4, -11, -23, -40, -46, -43, -33, -26, -16, -15, -29, -19, -1, 13, 44, 58, 41, 49, 68, 59, 36, 28, 36, 18, -9, -9, 4, 17, 20, 7, -6, 18, 36, 22, -1, -30, -26, -19, -25, -26, -31, -35, -33, -21, -3, -8, -10, -14, -24, -40, -45, -43, -35, -20, -18, -20, -22, -12, 0, 15, 48, 58, 41, 58, 77, 57, 30, 27, 33, 7, -23, -16, 11, 23, 21, 2, -5, 24, 33, 10, -10, -24, -19, -25, -37, -30, -30, -34, -29, -14, -5, -16, -8, -8, -26, -50, -47, -41, -30, -16, -25, -24, -14, -6, 3, 23, 50, 51, 49, 69, 81, 56, 29, 33, 30, -2, -29, -14, 15, 26, 18, 2, -1, 31, 28, 0, -20, -21, -21, -32, -43, -34, -33, -36, -23, -4, -8, -20, -8, -11, -25, -44, -41, -39, -32, -17, -30, -22, -4, 1, 6, 31, 48, 47, 63, 80, 82, 52, 31, 38, 23, -13, -33, -11, 20, 29, 14, -1, 9, 34, 19, -12, -26, -13, -23, -46, -46, -38, -39, -35, -24, -3, -7, -17, -15, -16, -25, -45, -37, -37, -33, -26, -36, -20, 5, 3, 4, 32, 42, 50, 76, 83, 75, 49, 34, 36, 17, -24, -33, -12, 23, 32, 10, 1, 23, 30, 7, -17, -22, -8, -27, -49, -50, -42, -38, -28, -18, -3, -8, -13, -14, -15, -24, -43, -35, -33, -29, -27, -34, -15, 16, 8, 5, 32, 43, 62, 84, 84, 73, 53, 40, 30, 6, -26, -34, -15, 25, 28, 8, 9, 38, 27, -4, -26, -21, -12, -33, -54, -47, -48, -38, -21, -14, -2, -3, -11, -25, -18, -26, -32, -34, -34, -29, -31, -35, -10, 18, 11, 7, 33, 47, 68, 83, 81, 71, 58, 42, 20, -5, -25, -36, -15, 23, 23, 7, 20, 40, 21, -14, -35, -21, -16, -40, -58, -52, -52, -31, -11, -9, -6, -1, -15, -26, -15, -29, -31, -36, -31, -29, -36, -32, -4, 17, 8, 15, 36, 48, 66, 77, 83, 77, 59, 38, 9, -11, -20, -34, -12, 22, 20, 14, 33, 39, 16, -22, -36, -23, -21, -40, -56, -52, -47, -24, -10, -4, 3, 1, -17, -22, -18, -28, -26, -32, -30, -32, -30, -22, 1, 15, 15, 27, 42, 52, 62, 75, 85, 80, 59, 35, 1, -16, -20, -35, -12, 18, 17, 18, 40, 34, 5, -34, -38, -27, -28, -42, -60, -58, -48, -18, -4, 0, 3, -4, -18, -20, -22, -35, -29, -27, -34, -42, -28, -12, 3, 8, 19, 31, 40, 45, 60, 75, 79, 76, 62, 37, -2, -20, -22, -31, -11, 13, 15, 31, 43, 27, 0, -28, -33, -36, -37, -43, -58, -61, -47, -13, 1, 1, 3, -5, -12, -17, -25, -36, -27, -25, -39, -45, -24, 1, 0, 8, 25, 43, 45, 42, 57, 76, 76, 73, 60, 37, -8, -25, -22, -25, -6, 9, 21, 41, 41, 15, -6, -18, -33, -48, -40, -38, -57, -64, -46, -6, 9, -4, 1, -1, -9, -18, -28, -33, -24, -27, -42, -45, -18, 2, 3, 13, 31, 49, 43, 37, 60, 74, 68, 68, 60, 30, -12, -28, -23, -19, -8, 5, 26, 48, 37, 11, -12, -17, -37, -54, -40, -41, -58, -65, -42, 5, 12, -8, 0, 2, -6, -22, -29, -30, -28, -37, -44, -42, -9, 6, 7, 17, 33, 44, 42, 40, 61, 72, 57, 63, 61, 24, -16, -34, -21, -15, -12, 3, 31, 47, 28, 7, -10, -15, -43, -51, -38, -45, -61, -61, -31, 10, 8, -3, 6, 5, -8, -24, -27, -28, -31, -44, -42, -29, -3, 6, 10, 24, 40, 44, 45, 46, 57, 62, 56, 65, 56, 16, -13, -32, -18, -12, -10, 11, 32, 39, 25, 6, -10, -19, -48, -44, -38, -49, -63, -61, -19, 12, 3, 4, 6, 3, -9, -25, -26, -27, -38, -46, -39, -18, 1, 12, 20, 29, 33, 36, 49, 47, 54, 59, 49, 63, 51, 8, -12, -25, -18, -18, -6, 20, 33, 28, 19, 4, -9, -27, -43, -41, -45, -55, -64, -51, -13, 7, -3, 0, 7, 3, -12, -28, -27, -33, -46, -51, -33, -10, -5, 15, 31, 34, 26, 32, 47, 51, 53, 47, 50, 61, 41, 1, -8, -12, -21, -20, 5, 27, 29, 16, 13, 8, -9, -28, -40, -40, -44, -55, -62, -40, -8, 5, -2, 4, 11, 4, -15, -26, -26, -37, -49, -47, -27, -8, -3, 22, 45, 38, 22, 34, 47, 55, 52, 39, 44, 58, 32, 2, 0, -7, -25, -21, 10, 29, 30, 9, 0, 0, -7, -26, -38, -40, -53, -61, -53, -30, -5, 1, -2, 5, 10, 3, -18, -25, -33, -43, -51, -46, -20, -10, -8, 26, 52, 35, 19, 32, 47, 56, 46, 33, 44, 48, 20, 10, 11, -7, -29, -20, 15, 35, 28, 2, -9, -8, -6, -26, -32, -36, -54, -64, -52, -22, 1, 3, 2, 3, 15, 2, -22, -24, -34, -41, -45, -39, -19, -9, 1, 35, 57, 37, 18, 27, 46, 52, 41, 37, 44, 40, 18, 16, 13, -7, -29, -14, 23, 36, 17, -6, -17, -2, 1, -24, -38, -43, -59, -62, -44, -22, -4, 7, 2, 5, 16, -2, -24, -27, -36, -43, -48, -37, -20, -5, 14, 40, 52, 36, 20, 26, 43, 46, 40, 41, 42, 28, 19, 19, 9, -4, -21, -10, 27, 32, 10, -6, -16, -4, -5, -14, -37, -48, -59, -58, -36, -24, -1, 13, -3, 7, 16, -5, -19, -32, -38, -46, -43, -32, -22, -7, 22, 49, 57, 37, 22, 20, 37, 41, 36, 46, 41, 21, 19, 16, 9, -2, -25, -9, 27, 24, 8, -12, -11, -2, -9, -10, -39, -51, -59, -59, -35, -21, 2, 15, -5, 10, 11, -12, -19, -35, -39, -46, -35, -29, -26, -5, 37, 60, 53, 36, 26, 19, 33, 37, 33, 48, 41, 18, 17, 19, 11, -8, -23, -3, 30, 21, -5, -14, -2, -6, -9, -9, -42, -59, -64, -54, -33, -16, 6, 14, 0, 15, 4, -14, -17, -35, -45, -46, -33, -27, -22, 2, 42, 56, 49, 37, 26, 19, 26, 23, 36, 58, 44, 11, 8, 23, 10, -7, -15, 3, 26, 12, -10, -8, 3, -10, -7, -13, -46, -58, -60, -57, -40, -11, 9, 9, 3, 13, -6, -12, -17, -42, -53, -45, -28, -23, -14, 11, 49, 60, 49, 40, 27, 14, 16, 13, 43, 62, 46, 6, 8, 22, 7, -9, -10, 11, 23, 4, -17, 2, 6, -6, -7, -21, -51, -58, -58, -55, -38, -12, 12, 10, 13, 1, -15, -7, -14, -47, -62, -45, -29, -19, -2, 21, 51, 63, 46, 37, 31, 16, 0, 4, 43, 64, 43, 6, 9, 24, 4, -15, -2, 14, 9, -9, -15, 14, 7, -11, -10, -29, -53, -54, -57, -48, -35, -9, 13, 9, 11, -5, -6, -2, -22, -57, -60, -39, -24, -11, 5, 30, 52, 62, 49, 42, 38, 11, -9, 7, 45, 61, 44, 10, 15, 21, -4, -15, 3, 13, 1, -13, -9, 13, 7, -9, -13, -32, -51, -53, -56, -44, -35, -9, 15, 11, 7, -8, 0, -2, -34, -65, -56, -31, -24, -7, 20, 37, 49, 56, 47, 47, 39, -3, -16, 12, 40, 53, 45, 16, 23, 17, -7, -8, 7, 8, -5, -12, -7, 7, 7, -4, -17, -38, -56, -60, -50, -37, -33, -8, 7, 9, 0, -6, 7, -8, -47, -71, -50, -25, -23, 0, 33, 41, 46, 52, 53, 54, 35, -6, -9, 13, 32, 50, 48, 23, 25, 13, -4, -3, 0, -1, -7, -7, -8, 3, 6, -3, -22, -41, -55, -62, -46, -30, -24, -5, 0, 5, 2, 3, 10, -20, -57, -69, -41, -19, -16, 5, 37, 47, 46, 49, 54, 58, 29, -4, -6, 7, 21, 49, 49, 24, 24, 12, -2, -5, -9, 0, 0, -10, -15, 2, 8, -4, -23, -42, -57, -66, -43, -22, -16, -11, -8, 3, 5, 7, 4, -28, -61, -61, -36, -19, -11, 10, 45, 51, 43, 46, 52, 54, 26, 3, -8, -3, 15, 52, 48, 27, 30, 15, -1, -9, -14, 0, -2, -15, -17, -2, -1, -5, -23, -37, -62, -64, -34, -17, -15, -19, -8, 4, 7, 8, -8, -37, -55, -50, -33, -19, -5, 16, 49, 54, 44, 45, 52, 53, 32, 3, -12, -5, 14, 46, 46, 38, 34, 21, 6, -13, -21, -2, -3, -18, -19, -14, -9, -2, -14, -44, -74, -56, -26, -15, -16, -18, -6, -1, 7, 6, -20, -43, -48, -35, -32, -24, 1, 23, 51, 54, 41, 42, 52, 49, 32, 3, -14, -5, 19, 42, 47, 43, 38, 27, 10, -18, -19, -5, -7, -18, -27, -23, -9, 2, -8, -51, -75, -41, -19, -15, -13, -15, -11, -5, 10, 1, -30, -37, -40, -30, -33, -24, 6, 30, 49, 49, 45, 43, 52, 39, 24, 7, -10, -7, 12, 33, 44, 48, 43, 36, 7, -29, -18, -6, -14, -23, -36, -32, -12, 2, -16, -60, -65, -27, -22, -22, -9, -6, -14, -6, 11, -10, -38, -35, -27, -26, -35, -15, 18, 39, 47, 48, 51, 55, 51, 28, 22, 13, -5, -6, 5, 27, 46, 57, 49, 39, 1, -29, -12, -7, -15, -28, -48, -39, -11, -1, -28, -61, -51, -22, -30, -22, -3, -4, -21, -6, 8, -23, -45, -29, -18, -27, -32, -11, 24, 44, 40, 46, 56, 61, 44, 17, 18, 19, 1, -11, -2, 24, 48, 57, 54, 45, 2, -27, -12, -11, -18, -32, -49, -41, -16, -10, -32, -47, -33, -25, -34, -13, 6, -5, -24, -13, -4, -29, -43, -29, -18, -25, -21, -1, 25, 44, 40, 49, 67, 60, 31, 12, 18, 24, -2, -18, -5, 22, 45, 62, 65, 46, -5, -21, -12, -12, -17, -36, -57, -48, -23, -15, -29, -35, -28, -33, -31, -3, 12, -16, -32, -12, -19, -36, -33, -25, -22, -29, -10, 14, 30, 41, 35, 51, 73, 57, 27, 16, 21, 14, -4, -12, -2, 21, 41, 62, 71, 43, -7, -12, -19, -22, -23, -46, -57, -51, -35, -20, -17, -22, -26, -37, -27, 7, 12, -24, -31, -14, -29, -34, -30, -22, -20, -21, 2, 15, 26, 40, 45, 55, 66, 52, 28, 20, 17, 10, -1, -12, -4, 21, 43, 65, 74, 39, 1, -9, -25, -27, -24, -45, -61, -55, -43, -22, -9, -12, -24, -32, -26, 9, 7, -25, -31, -30, -40, -31, -26, -19, -20, -11, 14, 18, 27, 45, 54, 52, 61, 49, 33, 24, 15, 5, 0, -14, -2, 24, 44, 62, 67, 37, 12, -9, -30, -29, -33, -49, -66, -58, -51, -25, -2, -6, -19, -31, -24, 6, 3, -21, -37, -43, -42, -31, -25, -17, -19, -5, 15, 19, 30, 52, 56, 45, 54, 52, 38, 22, 11, 8, 0, -16, 2, 27, 44, 63, 60, 34, 16, -10, -25, -31, -38, -55, -68, -62, -53, -18, 5, -2, -17, -31, -16, 5, -4, -22, -43, -50, -38, -32, -21, -16, -11, 8, 10, 19, 32, 60, 60, 43, 46, 51, 37, 24, 13, 8, -6, -17, 4, 32, 52, 56, 52, 39, 23, -5, -23, -41, -48, -64, -65, -63, -57, -14, 9, 3, -18, -28, -9, 0, -11, -25, -47, -53, -38, -30, -19, -11, 0, 10, 11, 23, 42, 66, 60, 42, 49, 53, 36, 24, 20, 9, -17, -18, 3, 39, 59, 49, 41, 39, 26, 1, -24, -53, -59, -70, -61, -66, -58, -12, 17, 7, -20, -26, -7, -7, -16, -30, -51, -60, -45, -26, -11, -5, 5, 8, 10, 23, 48, 66, 55, 40, 48, 48, 33, 30, 25, 2, -21, -15, 10, 41, 51, 44, 37, 41, 27, 6, -28, -60, -65, -70, -63, -70, -55, -6, 21, 1, -20, -15, -2, -15, -24, -32, -54, -66, -45, -22, -8, 6, 13, 5, 15, 31, 51, 64, 58, 41, 42, 44, 35, 36, 29, 0, -20, -9, 14, 43, 53, 46, 39, 39, 24, 7, -33, -69, -75, -73, -70, -75, -46, 4, 17, -2, -18, -6, 3, -18, -32, -38, -61, -65, -39, -17, -2, 10, 10, 5, 19, 33, 55, 61, 54, 39, 40, 41, 41, 40, 30, -6, -25, -6, 22, 44, 48, 42, 42, 37, 23, 11, -42, -73, -77, -75, -74, -75, -39, 4, 8, -5, -15, 1, -1, -30, -33, -38, -69, -66, -40, -14, 3, 16, 8, 5, 21, 39, 60, 59, 48, 40, 38, 39, 42, 42, 30, -8, -20, 0, 26, 48, 51, 48, 43, 29, 21, 1, -47, -70, -80, -83, -80, -70, -25, 0, -2, -9, -6, 9, -7, -29, -33, -49, -72, -59, -29, -3, 3, 11, 6, 14, 27, 47, 61, 54, 47, 43, 34, 42, 45, 39, 21, -10, -17, 4, 29, 53, 54, 47, 39, 29, 22, -11, -53, -70, -83, -86, -77, -61, -19, -6, -7, -12, -2, 9, -14, -29, -35, -61, -70, -54, -25, -8, 2, 11, 8, 17, 27, 54, 60, 50, 45, 42, 40, 43, 39, 35, 18, -9, -7, 8, 28, 55, 56, 49, 32, 30, 15, -21, -53, -71, -88, -87, -74, -45, -12, -11, -15, -14, 6, 12, -12, -30, -48, -66, -60, -44, -18, -8, 5, 13, 15, 21, 31, 51, 57, 48, 43, 42, 40, 43, 37, 29, 16, -3, -1, 7, 35, 60, 54, 38, 26, 29, 5, -30, -54, -72, -93, -87, -69, -34, -14, -19, -25, -12, 13, 6, -17, -37, -56, -66, -49, -38, -18, -11, 1, 17, 24, 26, 32, 47, 52, 50, 49, 45, 39, 40, 33, 32, 13, 4, 3, 3, 47, 65, 52, 29, 27, 20, -5, -35, -56, -76, -90, -79, -63, -27, -17, -26, -24, 0, 12, -2, -16, -33, -61, -61, -42, -33, -17, -16, -6, 22, 30, 25, 29, 45, 50, 46, 53, 41, 37, 37, 33, 28, 17, 15, 2, 15, 54, 64, 46, 21, 25, 9, -12, -39, -58, -77, -87, -75, -46, -21, -23, -34, -24, 9, 9, -7, -17, -40, -67, -53, -33, -27, -22, -26, -4, 34, 34, 25, 27, 46, 44, 52, 59, 37, 30, 35, 32, 26, 25, 16, 2, 30, 62, 57, 33, 19, 17, -7, -25, -43, -58, -80, -82, -64, -36, -26, -26, -33, -17, 11, 4, -9, -18, -45, -62, -44, -30, -24, -28, -29, 5, 38, 32, 25, 30, 48, 41, 53, 57, 35, 28, 26, 27, 31, 29, 14, 12, 47, 63, 48, 35, 24, 4, -19, -32, -46, -55, -76, -77, -58, -31, -30, -33, -36, -8, 12, -4, -9, -22, -51, -57, -30, -23, -27, -40, -31, 18, 36, 31, 30, 33, 39, 36, 56, 51, 32, 27, 20, 24, 39, 30, 16, 29, 55, 53, 43, 36, 21, -5, -28, -39, -45, -55, -71, -70, -47, -27, -35, -36, -25, -2, 1, -4, -6, -23, -48, -48, -25, -16, -25, -46, -23, 24, 30, 35, 34, 29, 33, 37, 51, 41, 30, 21, 12, 27, 47, 33, 19, 38, 51, 43, 39, 36, 15, -17, -35, -35, -42, -55, -68, -62, -45, -33, -40, -36, -19, -5, -4, -3, -6, -24, -47, -38, -17, -13, -37, -48, -13, 26, 30, 36, 32, 27, 29, 36, 48, 38, 27, 9, 5, 34, 47, 31, 30, 49, 47, 36, 38, 28, 11, -21, -32, -32, -47, -56, -60, -54, -40, -39, -42, -31, -12, -5, -7, -1, -4, -21, -39, -28, -11, -13, -45, -42, -2, 23, 25, 42, 33, 26, 26, 33, 44, 34, 20, 1, 5, 36, 47, 38, 40, 47, 37, 35, 38, 20, 1, -23, -26, -35, -49, -56, -55, -48, -40, -46, -42, -28, -12, -12, -10, 2, -6, -25, -32, -25, -13, -22, -43, -30, 5, 18, 24, 45, 35, 29, 21, 27, 39, 28, 16, 2, 9, 39, 40, 44, 55, 45, 25, 31, 34, 15, -1, -18, -25, -41, -49, -50, -52, -46, -42, -48, -40, -23, -9, -18, -13, 9, -1, -24, -27, -22, -14, -30, -41, -26, 8, 15, 25, 40, 36, 26, 15, 26, 35, 21, 11, 2, 17, 44, 37, 54, 63, 37, 16, 31, 27, 12, -3, -12, -24, -45, -47, -46, -45, -40, -44, -55, -40, -17, -12, -22, -7, 19, -2, -22, -24, -15, -17, -36, -36, -11, 16, 10, 17, 38, 43, 25, 15, 25, 26, 14, 7, 2, 25, 39, 38, 63, 67, 30, 16, 25, 18, 14, -5, -9, -26, -43, -45, -47, -42, -38, -52, -57, -35, -14, -22, -27, 0, 23, -5, -24, -22, -12, -21, -40, -31, 1, 19, 6, 11, 35, 44, 22, 18, 28, 14, 4, 4, 11, 32, 34, 38, 70, 68, 22, 18, 17, 15, 17, 0, -10, -31, -45, -43, -42, -34, -36, -62, -61, -25, -11, -28, -29, 3, 25, -3, -26, -15, -12, -28, -34, -21, 9, 17, 2, 10, 31, 40, 24, 23, 28, 5, -3, 6, 19, 35, 33, 42, 72, 59, 22, 22, 12, 17, 17, 2, -11, -31, -40, -40, -36, -28, -40, -66, -57, -18, -15, -32, -22, 9, 22, -3, -23, -8, -12, -31, -32, -12, 18, 15, -1, 9, 25, 36, 26, 27, 20, -7, -5, 12, 23, 29, 33, 45, 70, 48, 25, 20, 8, 16, 9, 4, -11, -33, -39, -37, -34, -30, -46, -65, -50, -23, -22, -30, -19, 13, 22, -4, -21, -6, -15, -32, -28, -3, 18, 9, 0, 9, 21, 30, 28, 30, 12, -14, -1, 17, 19, 27, 41, 51, 63, 35, 28, 22, 12, 10, 6, 9, -14, -31, -36, -31, -27, -38, -49, -62, -48, -29, -25, -27, -13, 13, 13, -3, -9, -9, -21, -30, -20, 4, 12, 4, 5, 12, 19, 27, 33, 29, 6, -12, 2, 21, 17, 31, 45, 54, 55, 31, 31, 25, 14, 3, 5, 11, -14, -27, -33, -24, -27, -41, -49, -63, -53, -37, -26, -22, -7, 11, 8, 0, -3, -14, -19, -27, -14, 8, 5, 2, 9, 12, 20, 25, 31, 18, 0, -6, 8, 20, 14, 27, 43, 59, 48, 24, 28, 25, 14, 2, 8, 6, -15, -26, -30, -16, -28, -44, -53, -61, -58, -37, -27, -21, -4, 8, 3, 1, -2, -18, -21, -24, -11, 3, -4, 3, 15, 17, 20, 22, 29, 15, 3, -2, 8, 17, 18, 30, 46, 56, 40, 21, 29, 26, 14, -1, 5, 4, -6, -22, -29, -13, -27, -46, -51, -62, -61, -37, -28, -14, 2, 7, 0, 5, -2, -16, -17, -19, -10, -7, -9, 11, 20, 22, 18, 17, 25, 19, 4, -1, 10, 19, 25, 32, 44, 53, 36, 19, 29, 24, 10, -4, 5, 4, -2, -22, -24, -13, -31, -48, -56, -63, -60, -40, -31, -11, 8, 8, 2, 8, -6, -20, -17, -12, -10, -20, -12, 14, 30, 26, 10, 14, 24, 24, -1, -7, 12, 25, 27, 30, 40, 52, 34, 17, 28, 24, 7, -9, 1, 8, 3, -20, -20, -16, -33, -53, -59, -62, -61, -47, -29, -5, 15, 5, 1, 9, -8, -20, -14, -5, -12, -30, -11, 20, 37, 25, 10, 19, 25, 19, -5, -2, 18, 28, 26, 29, 41, 49, 31, 20, 30, 24, 1, -8, 4, 10, 3, -17, -12, -18, -40, -57, -61, -62, -59, -48, -23, 0, 18, 5, 5, 12, -9, -19, -9, -2, -20, -37, -7, 25, 39, 23, 11, 25, 26, 10, -10, 5, 23, 24, 26, 30, 40, 42, 27, 23, 31, 18, -7, -5, 2, 7, -1, -10, -10, -22, -45, -59, -63, -62, -58, -45, -21, -1, 17, 10, 13, 7, -18, -21, -5, -3, -27, -38, -7, 26, 38, 21, 20, 31, 23, 0, -9, 15, 25, 21, 28, 33, 35, 35, 29, 28, 31, 12, -5, 0, 0, 4, 0, -3, -14, -27, -48, -57, -69, -66, -61, -40, -19, 1, 16, 13, 16, -3, -18, -17, -4, -9, -30, -33, -1, 24, 35, 28, 34, 31, 16, -4, -2, 22, 29, 20, 27, 38, 33, 30, 30, 31, 33, 9, 1, -3, -7, 2, 6, -1, -22, -31, -50, -61, -74, -67, -52, -34, -25, 1, 19, 21, 14, -8, -18, -14, -10, -14, -27, -26, -5, 21, 35, 38, 40, 31, 12, -1, 5, 22, 29, 19, 31, 41, 28, 30, 28, 31, 28, 12, 7, -13, -11, -2, 13, -5, -26, -32, -52, -67, -80, -65, -46, -34, -26, 2, 15, 25, 9, -8, -14, -16, -10, -18, -25, -25, -9, 20, 37, 46, 35, 26, 10, 7, 8, 18, 27, 18, 31, 39, 25, 29, 29, 34, 26, 20, 2, -18, -10, -5, 12, -9, -22, -31, -48, -74, -79, -66, -42, -34, -22, -1, 14, 25, 13, -6, -19, -16, -8, -19, -22, -21, -5, 21, 41, 51, 32, 25, 14, 19, 13, 14, 21, 21, 32, 34, 26, 26, 30, 32, 25, 25, -3, -19, -13, -2, 8, -12, -24, -32, -46, -75, -79, -67, -43, -33, -18, -7, 12, 25, 18, 0, -23, -13, -7, -23, -18, -15, -4, 21, 48, 51, 27, 27, 23, 22, 12, 12, 19, 22, 28, 28, 28, 28, 31, 28, 23, 28, -3, -20, -22, -5, 0, -14, -23, -28, -50, -78, -81, -63, -44, -34, -19, -14, 10, 25, 18, -6, -19, -5, -11, -30, -17, -8, 2, 21, 54, 45, 25, 28, 33, 25, 9, 12, 21, 26, 23, 24, 33, 37, 35, 20, 23, 32, -1, -21, -25, -12, -11, -12, -19, -27, -53, -78, -79, -55, -42, -31, -26, -18, 12, 24, 13, -9, -12, 0, -20, -33, -13, 1, 6, 26, 55, 38, 25, 33, 45, 26, 7, 13, 21, 26, 16, 18, 38, 44, 33, 14, 25, 30, 4, -24, -32, -21, -18, -19, -19, -25, -54, -79, -78, -53, -43, -29, -28, -20, 6, 20, 12, -3, 0, -3, -35, -28, 1, 9, 8, 25, 46, 34, 30, 37, 44, 19, 13, 20, 17, 20, 12, 18, 49, 49, 23, 13, 28, 33, 3, -34, -37, -28, -30, -21, -10, -26, -57, -77, -74, -52, -40, -25, -32, -22, 3, 17, 12, 3, 8, -15, -40, -18, 10, 10, 4, 32, 39, 27, 38, 48, 39, 11, 18, 28, 17, 15, 5, 23, 61, 46, 21, 23, 35, 26, -3, -31, -37, -39, -38, -23, -3, -29, -60, -74, -68, -58, -37, -27, -35, -22, -7, 15, 23, 14, 8, -27, -41, -6, 19, 14, 9, 35, 31, 31, 48, 54, 35, 11, 27, 26, 4, 7, 11, 31, 54, 38, 25, 34, 35, 20, -10, 19, 3, -8, -45, 64, -15, -41, 23, 40, -58, 22, 29, -27, -28, 42, -36, 21, -12, -19, 39, -14, 3, -18, 32, -27, 18, -8, -43, 43, 25, -52, 6, 19, 13, -7, -50, 55, 5, -46, -22, 94, -53, -33, 35, 27, -45, -2, 20, 19, -30, -23, 47, 8, -58, 5, 76, -67, -22, 42, 30, -54, 8, 23, 11, -51, 3, 47, -33, -7, 5, 27, -33, 34, -35, 17, 4, -26, 5, 17, -30, 33, 5, -29, -5, 44, -18, -50, 60, -33, 10, -5, 10, -7, 1, -5, 19, -36, 3, 37, -17, -51, 52, 37, -64, 9, 4, 37, -44, -13, 25, 45, -75, -9, 79, -34, -57, 53, 24, -59, 18, 22, -3, -24, 10, -2, 18, -53, 29, 35, -20, -43, 37, 18, -17, -31, 8, 45, -49, 8, 11, 9, -23, 30, -24, -22, 29, 14, -43, 27, 13, -22, -1, 2, 22, -37, 5, -5, 38, -43, 6, 36, -21, -20, 20, 0, -5, -27, 27, 21, -53, 4, 52, -2, -84, 70, 5, -29, -19, 36, -6, -8, -12, 3, 35, -32, -25, 48, 6, -60, 49, 4, -27, -13, 31, -15, -9, -4, 31, -13, -25, 29, 12, -34, -6, 30, -41, 36, -23, 6, 31, -30, 0, 17, -45, 47, -5, -47, 19, 28, -8, -30, 27, -6, 15, -54, 34, 21, -27, -9, 25, 3, -45, 26, 27, -52, 22, 20, -29, 34, -46, 22, 40, -69, -27, 108, -49, -54, 69, -11, -3, -18, 3, 15, -12, -23, 29, -8, 4, -23, 50, -38, -8, 33, -32, -2, 26, -27, 12, 13, -39, 56, -31, -22, 28, 2, -39, 54, -20, -36, 51, -6, -34, 15, 2, 1, 2, -36, 42, 2, -10, -39, 64, -36, -16, 24, 1, -1, -18, -10, 54, -27, -54, 80, -18, -61, 51, 27, -76, 64, -30, -1, 9, -19, 24, 13, -29, -13, 49, -18, -46, 43, 6, -47, 42, -28, 14, 18, -18, 2, 14, -39, 25, 16, -58, 33, 29, -49, 16, 41, -62, 43, -17, -17, 25, -10, -28, 41, -5, -30, 27, 14, -53, 27, 35, -63, 16, 30, 0, -30, -10, 22, 31, -57, 0, 68, -59, 2, 37, -30, 6, -3, -19, 35, -29, 1, 20, 22, -68, 33, 39, -71, 21, 27, -22, -1, 3, 0, 18, -16, -13, 17, 4, -37, 44, -15, -26, 48, -29, -11, 34, -25, -4, 25, -48, 43, 4, -49, 28, 42, -72, 7, 59, -36, -28, 45, -9, -28, 25, -19, 23, -9, -40, 47, 18, -85, 78, -2, -53, 39, -17, 2, 14, -36, 10, 63, -78, 17, 59, -66, -8, 54, -49, 14, 1, 5, 2, -18, 16, -12, 30, -58, 22, 53, -83, 17, 79, -84, 19, 17, -34, 44, -33, -27, 82, -62, -19, 91, -93, 22, 49, -51, -25, 48, -12, -6, 1, -2, -1, 22, -32, -1, 59, -78, 12, 58, -49, -26, 70, -40, -8, 16, -8, 12, 10, -65, 74, -1, -97, 90, 0, -56, 23, 25, -17, 11, -23, 14, 9, -24, -31, 77, -41, -48, 95, -38, -46, 59, -1, -57, 49, -33, 19, 18, -46, 34, 31, -79, 47, 11, -38, 10, 19, -14, -10, 26, -29, 28, -17, -27, 48, -15, -51, 78, -14, -73, 64, 12, -55, 29, 3, -24, 52, -65, 26, 50, -75, -5, 81, -76, 0, 42, -6, -26, 10, 18, -14, 4, -24, 33, 2, -69, 61, 43, -101, 40, 54, -73, 22, 18, -41, 44, -19, -43, 94, -69, -13, 65, -26, -46, 35, 24, -34, -2, 23, -13, 6, -19, 4, 38, -56, 14, 40, -37, -19, 66, -57, -9, 50, -47, 21, 6, -31, 55, -34, -50, 98, -44, -47, 44, 28, -51, 6, 31, -3, -34, 8, 11, 6, -18, -27, 78, -48, -28, 55, -2, -60, 57, -37, 14, 15, -48, 49, 22, -96, 74, 23, -83, 36, 18, -17, -25, 41, -12, -4, -2, 1, 9, -14, -18, 36, 12, -77, 54, 32, -67, 20, 38, -67, 61, -53, 32, 21, -60, 27, 41, -74, 27, 33, -30, -6, 22, -1, -30, 20, 1, -4, -22, 9, 8, 37, -65, 18, 61, -69, -3, 37, -19, -15, 15, -16, 57, -78, 20, 66, -67, -27, 76, -37, -16, 11, 11, -5, -18, 10, 16, -5, -38, 36, 9, -20, -32, 73, -41, -36, 62, -33, -9, 34, -41, 35, -7, -40, 65, -35, -26, 33, 2, -43, 42, -4, -9, 5, -11, 19, -10, -16, 11, 16, -28, -9, 41, 2, -70, 67, -3, -55, 23, 33, -26, 6, -29, 43, 16, -85, 51, 28, -54, 7, 27, -9, 2, -18, 27, -4, -42, 31, 10, -19, -9, 18, 8, -24, -3, 45, -57, 25, 0, -7, 15, -28, 10, 33, -46, -6, 52, -36, -15, 46, -29, -4, 12, -14, 34, -57, 16, 40, -41, 3, 16, 8, -32, 16, 15, -17, -27, 47, -30, -1, 14, -5, 16, -17, -33, 70, -44, -42, 84, -34, -27, 18, 15, 3, -20, -22, 55, -35, -22, 31, 10, -11, -27, 27, 13, -28, -10, 41, -21, -3, -22, 41, -21, -13, 6, 34, -68, 46, 25, -65, 50, -21, -1, 10, -33, 34, 1, -43, 58, -34, -2, 13, 8, -25, 0, -2, 34, -29, -26, 45, -12, 4, -34, 32, 15, -54, 17, 53, -76, 41, 4, -17, 13, -26, 13, 31, -47, 1, 52, -53, 11, 8, 14, -31, -7, 19, 30, -60, 26, 27, -22, -10, 0, 18, -13, -24, 52, -38, -17, 68, -60, 26, -9, -25, 41, -29, -8, 40, -25, -9, 26, -28, 15, -9, -3, 11, -21, -1, 44, -47, 19, 0, 3, -14, -12, 38, -22, -23, 37, -10, -13, 9, -6, 21, -14, -39, 61, -4, -68, 60, 6, -43, 28, -14, 21, -22, -13, 36, -7, -40, 46, -14, -5, -18, 20, 22, -49, 22, 10, -18, 21, -30, 9, 34, -54, 19, 22, -34, 27, 7, -45, 30, 0, -20, 23, -23, 29, -10, -21, 25, 3, -23, -1, 5, 16, -33, 14, 25, -21, -11, 16, 3, -22, 5, 6, 32, -73, 27, 62, -72, 5, 26, -21, 30, -37, 4, 40, -45, 5, 18, -18, -1, 12, -3, 0, -18, 28, -8, -14, 11, -11, 13, -15, -3, 27, -17, -30, 65, -45, -5, 28, -25, 1, 20, -36, 38, -11, -20, 35, -23, -20, 27, 11, -42, 13, 17, 1, -25, 20, 10, -33, 10, 6, -7, 9, -26, 40, -3, -63, 74, -30, -11, 10, -10, 5, 17, -47, 53, -10, -47, 29, 31, -45, 4, 16, 14, -15, -33, 40, -11, -3, -10, 2, 18, -20, 9, 22, -44, 19, 20, -42, 25, -5, -11, 25, -25, -3, 47, -63, 28, 20, -42, 7, 39, -41, 2, 13, 10, -24, -8, 41, -26, -1, -13, 9, 42, -60, 0, 61, -54, -4, 19, -6, 11, -19, -13, 52, -37, -26, 66, -38, -30, 49, -18, -11, 5, 7, 10, -30, 4, 17, 2, -12, -15, 38, -19, -20, 30, -16, -23, 38, -13, -16, 29, -22, 26, -17, -35, 62, -30, -35, 51, -16, -27, 40, -16, 3, -8, -4, 9, 4, -26, 11, 20, -11, -38, 56, -19, -29, 31, 7, -39, 17, 10, 6, -8, -41, 45, 26, -79, 36, 42, -58, 21, 6, -10, 7, -19, 17, -1, -15, -12, 53, -22, -32, 24, 25, -59, 24, 22, -36, 10, 18, -27, 44, -45, 0, 42, -45, -2, 30, -27, 12, 23, -38, 13, 5, 4, -4, -20, 1, 43, -27, -36, 43, 14, -51, 12, 40, -41, 5, 18, -11, -1, -5, -11, 53, -56, -29, 91, -41, -45, 57, -7, -18, -3, -4, 29, -20, -19, 20, 26, -57, 31, 17, -22, -13, 28, -31, 3, 36, -33, 9, 17, -39, 42, -9, -54, 58, 6, -69, 44, 30, -50, 24, 3, -17, 9, -20, 17, 8, -23, 1, 46, -50, 1, 27, 1, -49, 37, 5, -17, 4, -5, 7, 18, -55, 39, 36, -85, 37, 48, -63, 5, 27, -13, -6, -4, 5, 24, -26, -12, 42, -25, -34, 33, 20, -33, -13, 29, -2, 7, -34, 12, 37, -50, 1, 47, -46, -1, 56, -54, -18, 59, -35, -6, 12, -16, 20, -2, -27, 43, -12, -34, 22, 25, -41, -7, 43, -20, -18, 19, -1, 1, -6, -20, 54, -55, -12, 67, -24, -56, 56, -8, -12, -7, -3, 16, 20, -48, 20, 32, -46, 8, 23, -17, -38, 54, 1, -34, 2, 30, -1, -21, -18, 38, -14, -35, 41, 3, -36, 19, 22, -45, 40, -32, 12, 12, -26, 2, 35, -54, 34, 14, -25, -30, 47, 10, -53, 24, 13, -4, -18, 3, 5, 27, -61, 38, 15, -39, 6, 40, -36, 0, 2, -6, 28, -40, 7, 46, -37, -30, 59, -21, -29, 6, 48, -55, 12, 30, -21, -6, 5, -2, 1, -14, -7, 46, -41, -4, 35, -8, -33, 29, -20, 26, -31, -10, 63, -46, -4, 12, 7, -11, -15, 26, -14, -22, 54, -47, 12, 9, -1, -8, -7, -8, 41, -12, -60, 77, -21, -26, 11, 13, 1, -26, -9, 59, -45, -16, 38, -3, -27, -1, 28, -8, -19, 11, 20, -41, 34, -23, 22, -20, -9, 6, 51, -79, 40, 18, -40, 23, -5, -19, 13, 2, 3, -4, -35, 71, -39, 5, -30, 33, 6, -29, -3, 38, -29, -5, 18, -9, -4, -11, 16, 15, -32, -14, 77, -83, 30, 10, -10, -19, 20, 15, -17, -19, 29, 7, -32, 6, -1, 14, -14, -6, 5, 36, -58, 47, -18, -14, 4, 8, 8, -24, -15, 60, -36, -20, 43, -32, 3, -2, 1, 9, -5, -8, 30, -33, 6, 6, 2, -12, -11, 24, 1, -22, 9, 34, -61, 25, 11, -5, -18, -1, 38, -19, -33, 49, -19, -21, 18, -7, 1, 5, -4, -3, 13, -30, 25, -5, -12, 2, 8, 17, -37, 0, 50, -38, -26, 40, -15, 7, -24, 31, -11, -8, 6, -6, -3, 1, 9, -8, 6, -20, 25, 0, -21, 7, 22, -48, 29, -4, 10, -22, 7, 22, -9, -34, 45, -15, -31, 30, -2, 0, -30, 46, -18, -6, -17, 31, -6, -7, -21, 8, 45, -47, -7, 31, -17, -11, 25, -20, 17, -30, 47, -38, -2, 5, 16, -36, 24, -2, 3, -7, 6, 10, -23, 5, -11, 35, -42, 17, 0, 21, -35, 11, 16, -18, -15, 36, -24, -3, 9, 5, 13, -49, 36, -11, -2, -14, 37, -32, 13, -1, 0, -2, -2, -8, 17, -11, -21, 30, -1, -1, -41, 72, -65, 14, 14, 12, -41, 21, 4, 15, -32, -1, 25, -9, -18, 3, 29, -38, 35, -22, 14, -20, 16, -6, -6, -13, 29, -4, -17, 7, 14, -6, -38, 54, -32, 3, -16, 36, -39, 42, -40, 36, -22, -13, 17, 14, -36, 12, 23, -25, 6, -25, 53, -33, -12, 5, 37, -46, 6, 20, 9, -53, 52, -16, -22, 24, -9, 10, -17, 12, -20, 48, -73, 40, 18, -30, -20, 52, -34, 11, -6, 0, 1, -15, 24, -16, 16, -30, 44, -27, -10, 0, 34, -52, 24, 3, 2, -6, 12, -25, 35, -38, -14, 72, -73, 7, 31, 15, -50, 20, 12, -5, -25, 23, 3, -10, -9, 15, 9, -41, 28, 6, -5, -36, 44, -13, 10, -19, 2, 14, -10, -29, 56, -27, -35, 58, -19, -27, 17, 16, -30, 10, -7, 15, -12, -3, 11, 18, -30, -13, 38, -17, -16, 3, 32, -37, 23, -24, 30, -12, -26, 40, -14, -52, 59, 12, -55, 16, 35, -20, -30, 39, -24, 21, -26, 12, 13, -10, -19, 23, 2, -35, 17, 33, -30, -17, 39, -15, 12, -53, 50, -13, -25, 2, 50, -42, -1, 25, -22, 6, -5, 3, -4, 2, -18, 39, -25, -3, 1, 29, -57, 22, 26, -22, -18, 34, -10, -10, -11, 13, 31, -77, 46, 23, -22, -35, 61, -24, -13, 7, -3, 0, 4, -24, 27, 12, -50, 35, 13, -19, -37, 69, -46, -4, 13, 5, -8, 6, -25, 40, -26, -13, 38, -12, -28, 21, 22, -57, 40, -15, 11, -19, 4, 19, 9, -36, 3, 42, -35, -30, 46, 0, -50, 59, -26, 9, -16, 12, -10, 10, -33, 44, -8, -29, 8, 42, -43, -6, 26, -19, 14, -30, 34, 4, -21, -17, 49, -31, -24, 34, 14, -53, 32, 13, -26, 12, -22, 26, -3, -22, -11, 66, -59, 0, 43, -27, -23, 42, -32, 7, -7, 11, 9, -19, -1, 15, 16, -58, 43, 1, -32, 11, 36, -44, 18, 0, 4, -4, -7, -22, 50, -22, -44, 67, -14, -43, 37, 2, -32, 15, 7, 8, -22, -1, 14, 19, -43, 0, 40, -30, -14, 28, 10, -32, 11, 1, 21, -33, -9, 31, 15, -72, 61, 4, -40, 21, 14, -37, 22, 4, -4, -9, 5, -8, 23, -16, -22, 35, -24, 0, 12, 3, -17, 15, 2, -10, -6, -8, 21, 7, -58, 40, 43, -75, 25, 28, -25, -18, 28, -15, 6, -5, -4, 22, -5, -39, 37, 1, -30, 12, 23, -27, -8, 34, -22, 0, -12, 15, 10, -28, 2, 45, -45, -9, 36, -22, -7, 13, -7, 6, 2, -18, 17, 10, -34, 9, 18, -22, -1, 22, -9, -17, 23, -1, -22, 21, -20, 20, -17, -6, 38, -33, -18, 55, -32, -21, 26, -5, -9, 5, -8, 16, 9, -47, 36, 11, -36, -3, 38, -7, -48, 44, -2, -11, 2, -16, 15, 11, -36, 33, -3, -18, 9, 19, -46, 26, -1, -11, 20, -24, 12, 16, -16, -17, 37, -32, -6, 13, 13, -33, 25, 14, -27, 8, 1, -18, 22, -5, -15, 32, -46, 37, -2, -19, -13, 38, -32, 8, 2, -4, 15, -12, -4, 19, -25, -10, 37, -19, -11, -10, 57, -54, 19, -17, 18, 3, -18, -9, 27, -6, -36, 57, -23, -21, 14, 11, -23, 32, -53, 56, -24, -5, -3, 11, -16, 16, -7, -20, 17, 11, -3, -31, 42, -33, 14, -6, -2, -8, 39, -56, 48, -21, -20, 30, -8, -20, 12, 15, -32, 41, -36, 29, -25, 14, -22, 22, -19, 9, 4, 10, -31, 17, 11, -14, -1, -7, 17, -16, 6, -18, 64, -88, 47, 6, -20, -5, 22, -13, 18, -28, 2, 25, -19, -10, -3, 29, -23, 11, -22, 39, -25, 13, -27, 20, -2, -18, 15, -3, 3, 9, -17, -8, 38, -57, 35, 1, -9, -24, 43, -32, 30, -30, -3, 19, -3, -21, 12, 14, -12, 2, -5, 11, -37, 37, -3, -13, -4, 10, 11, -4, -38, 41, -9, -27, 37, -37, 16, 17, -7, -15, 22, -40, 33, -2, -16, 4, 3, 8, -4, -20, 21, -3, -10, 8, -26, 37, -21, 8, 0, -3, -3, 0, -8, 20, -15, -32, 54, -10, -26, 17, -12, 10, 24, -71, 51, 3, -21, 9, -3, 17, -22, 2, 15, -21, -11, 39, -25, 11, -27, 28, 3, -11, -26, 45, -43, 24, 7, -39, 47, -24, -15, 27, -13, -15, 35, -27, 15, -17, 9, 0, -7, 0, 4, -9, 13, -3, -16, 28, -29, 21, -23, 11, -4, 10, -30, 64, -63, 13, 28, -30, 16, -13, 0, 25, -39, -2, 53, -40, 5, -19, 41, -25, -6, -3, 37, -40, 6, 8, 0, 6, -34, 32, 4, -27, 13, 15, -34, 52, -63, 40, -5, -22, 5, 24, -32, 22, 11, -26, 14, -22, 26, -21, 10, -8, 5, -10, 46, -66, 44, -20, 14, -7, -27, 23, 30, -53, 24, 10, -37, 44, -40, 21, -11, 3, 6, 20, -47, 27, 5, -2, -18, -4, 29, -13, -20, 27, 9, -47, 43, -37, 55, -62, 14, 33, -13, -28, 24, -9, 23, -35, -4, 32, -14, -13, 28, -10, -30, 46, -43, 43, -46, 13, 13, -10, 7, -3, -20, 39, -19, -19, 14, -15, 39, -31, -10, 25, 2, -34, 41, -35, 15, -4, -3, 22, -18, -27, 46, -1, -36, 10, -4, 42, -56, 13, 31, -19, -18, 28, -29, 27, -32, 24, 10, -44, 20, 32, -32, -17, 32, -13, 13, -35, 20, 32, -53, 20, 9, -16, 16, -36, 39, -3, -33, 43, -26, 2, 2, 2, -17, 24, -22, 14, -3, -12, 31, -28, -8, 26, -29, 19, -4, -15, 33, -39, 22, 16, -37, 6, 17, -4, -13, -12, 37, 9, -65, 34, 25, -27, -9, 7, 5, 10, -36, 45, -11, -41, 42, -6, -21, 7, -5, 31, -5, -57, 62, -12, -15, -16, 23, 4, -24, 12, 26, -35, -11, 44, -25, -8, -1, -4, 28, -11, -37, 61, -48, 23, -1, -30, 29, -8, -2, 6, -19, 18, 15, -41, 30, -4, -11, -11, 28, -10, -4, -37, 81, -45, -43, 61, -19, 1, -11, 0, 31, -30, -25, 68, -43, -11, 0, 27, -1, -33, -7, 77, -54, -30, 44, -6, -5, -14, 17, -6, -10, 6, 30, -68, 50, -16, 5, 5, -30, 30, 26, -69, 36, 8, -34, 37, -28, 11, 0, -1, 9, 1, -41, 53, -22, -24, 23, 5, -9, -11, 12, 28, -61, 28, 36, -68, 51, -33, 25, -6, -26, 7, 53, -65, 2, 47, -25, -23, 17, 20, -4, -51, 38, 29, -67, 31, 1, 22, -35, -8, 40, -9, -46, 47, -13, -8, 5, -15, 37, -27, -20, 45, -16, -45, 59, -37, 19, -6, 2, 1, -11, -3, 34, -42, 0, 33, -30, 16, -13, 13, 2, -23, 18, -5, -26, 43, -24, 15, -26, 4, 35, -15, -62, 64, 19, -75, 50, -8, 8, -14, -12, 31, -19, -30, 45, -10, -12, -10, 36, 3, -53, 14, 45, -37, -22, 42, -25, 21, -36, 21, 37, -61, 5, 47, -49, 19, -4, 5, 1, -12, 7, 3, -11, 2, 18, -28, 13, -4, 18, -13, -20, 33, -22, -8, 21, -12, -10, 24, -9, 2, -27, 15, 33, -41, -18, 56, -40, 9, -5, 6, 20, -44, 11, 39, -35, -22, 50, -7, -36, -6, 41, -10, -30, 15, 20, -22, 7, -11, 16, 6, -51, 59, -21, -26, 24, 12, -24, 8, -7, 12, 3, -36, 27, 18, -42, 22, 9, -22, 11, -2, 15, -40, 38, -13, -16, 8, 24, -33, 15, -13, 4, 23, -42, 17, 30, -34, -5, 28, -22, 11, -23, 30, -14, -28, 37, 12, -46, 11, 31, -23, -12, -7, 36, -17, -6, -4, 25, -18, 4, -29, 53, -48, 4, 24, -9, -21, 30, -1, -20, 2, -13, 51, -51, -1, 39, -23, -18, 33, -23, 3, 3, 2, -13, 11, 4, -13, 15, -14, -3, 1, 24, -53, 55, -24, -17, 36, -1, -49, 45, -7, -12, -2, -4, 24, -23, 1, 6, 23, -51, 30, -8, 14, -29, 17, 12, -9, -21, 21, 1, 3, -32, 21, 30, -59, 27, 25, -21, -26, 36, -24, 16, -23, 15, 10, -15, 11, -11, -3, 14, 1, -30, 32, -24, 27, -25, 10, -12, 29, -33, 7, -5, 25, -29, 14, 15, -42, 20, 18, -27, 1, 21, -19, 17, -18, 2, 19, -12, -34, 47, -21, -6, 9, -2, 14, -32, 32, -23, 14, -21, 21, 0, -13, -8, 42, -35, -19, 33, 4, -34, 23, -5, -6, 22, -31, 21, -8, -5, -3, 15, -22, 10, 2, 7, -17, 11, 3, -10, 2, -1, -2, -9, 25, -20, 11, -18, 17, -3, -12, 2, 9, -1, -10, 5, 0, 15, -40, 36, -5, -28, 16, 24, -34, 16, -1, 13, -32, 11, 9, 5, -26, 5, 32, -32, 4, -1, 29, -38, 8, 7, -6, 5, -2, -5, 18, -26, -2, 39, -42, 0, 26, 2, -43, 45, -30, 20, -11, -6, -3, 16, -7, -6, 3, 12, -13, 5, -7, -21, 47, -29, -11, 9, 36, -45, 8, 0, 22, -28, -7, 32, -22, -9, 20, 12, -40, 24, -8, 14, -28, 10, 9, 12, -29, 15, -7, 15, -23, 5, 14, -24, 12, 8, 4, -38, 36, -4, -7, -30, 47, -13, -24, 16, 23, -46, 29, -3, -10, 20, -43, 35, 0, -4, -30, 47, -18, -21, 16, 19, -35, 11, 19, -21, -11, 27, -12, -9, 16, -21, 23, -32, 30, 3, -22, -15, 51, -38, -1, -2, 11, 15, -28, -1, 16, 13, -42, 23, 4, -6, -32, 61, -24, -35, 34, 29, -55, 4, 13, 9, -6, -26, 35, -6, -11, -11, 19, -6, -3, -15, 43, -41, 4, 22, -1, -34, 18, 15, -35, 18, -1, 23, -35, 18, -2, -9, 1, 10, -18, 17, -18, 21, -8, -17, 24, -1, -20, -7, 26, -11, 6, -33, 42, 0, -40, 9, 46, -48, -6, 24, 13, -39, 8, 41, -43, 3, 6, 6, -7, -6, -8, 42, -37, -11, 39, -16, -26, 25, 3, -24, 9, 11, 6, -34, 17, 14, -12, -22, 20, 0, 14, -38, 27, 10, -37, 22, -1, -5, -7, 11, 4, -3, -29, 38, -5, -26, 4, 20, -17, 6, 2, 11, -17, -10, 40, -49, 10, 26, -8, -24, 11, 12, 5, -36, 21, 20, -22, -29, 28, 30, -30, -24, 31, 25, -70, 39, 4, -16, 3, 9, -13, 16, -26, 23, 19, -46, 1, 29, 6, -37, 8, 27, -8, -33, 36, -24, 5, 14, -8, -8, 1, 4, 15, -27, -11, 44, -38, 6, 12, -3, -12, 20, -17, 16, -35, 28, -4, 0, -13, 8, 23, -24, -16, 28, 11, -58, 48, 6, -39, 11, 24, -9, -8, -25, 42, -16, -14, 12, 2, 13, -31, 6, 26, -10, -48, 64, -22, -21, 6, 28, -15, -11, -2, 22, -30, 11, 15, -25, 13, 2, -1, -7, -4, 6, 17, -37, 17, 0, 1, 14, -23, 4, 16, -23, 6, 12, -31, 30, 6, -18, -25, 45, -7, -20, -15, 44, -38, 9, 22, -37, 24, 6, -20, 14, -17, -8, 44, -27, -22, 16, 30, -33, -18, 20, 31, -50, 11, 27, -21, -4, -3, 26, -15, -24, 15, 20, -27, 16, -12, 9, 5, -24, 3, 26, -27, 5, 15, -19, 9, -9, 26, -25, -5, 10, -4, -6, 31, -45, 18, 24, -23, -23, 27, -3, 2, -18, 9, 13, -18, 19, -17, 7, -1, -24, 31, 5, -49, 31, 32, -40, -7, 10, 14, -12, -12, 5, 21, -30, 25, -12, 4, -18, 9, 11, -13, -20, 37, -8, -3, -13, -3, 33, -21, -32, 44, -7, -22, 28, -24, 5, 12, -19, 2, 6, 2, -16, 11, 10, -6, -23, 31, -25, 7, 6, -16, 18, 1, -35, 40, -9, -18, 12, 4, -2, -25, 20, 19, -16, -35, 46, -14, -8, -3, -1, 24, -12, -25, 26, -4, -6, 3, -12, 20, -24, 18, 9, -20, -2, 18, -13, -1, -16, 8, 26, -35, 12, 10, -11, 6, 2, -30, 46, -43, 16, 6, 1, -20, 26, -18, 8, -13, 9, -3, 3, 1, -25, 29, 13, -50, 12, 41, -47, 15, 14, -12, 2, -3, -1, 14, -25, -3, 26, -23, 19, -35, 41, -5, -23, -1, 31, -30, 8, -15, 32, -29, -7, 22, 10, -35, 12, 6, -2, 20, -50, 36, 7, -17, -4, -1, 7, 2, -21, 19, -12, 1, 28, -25, -5, 9, -3, -12, 32, -45, 16, 21, 0, -43, 21, 28, -19, -38, 45, -15, -8, 28, -43, 39, -12, -23, 13, 19, -39, 23, -3, 17, -32, 6, 20, -5, -32, 23, 8, -15, -1, 11, 9, -28, 5, 20, -18, -6, 9, -18, 50, -50, -8, 49, -30, -5, -4, 14, -19, 28, -21, 2, 4, 11, -20, 6, 3, -5, -24, 54, -34, -14, 26, -4, -2, -16, 5, 20, -23, 1, 6, -9, 32, -37, 1, 25, -22, -8, 31, -6, -37, 31, 0, 3, -37, 24, 25, -27, -20, 27, 1, 4, -26, 13, 3, -14, 12, -6, 6, -3, -6, 18, -14, -27, 38, 5, -36, 14, 13, -22, 26, -13, -22, 36, -23, -5, 3, 18, -12, -23, 31, -5, -24, 23, -15, 17, -7, -23, 20, 6, -4, -19, 20, -8, 15, -32, 13, 17, -30, 17, 13, -19, -8, 4, 24, -18, -29, 36, 7, -21, -20, 28, 13, -17, -31, 36, -9, -7, 7, 6, -9, -4, 7, -6, 10, -32, 41, -26, 12, -10, -12, 35, -10, -39, 36, -9, -7, 7, 6, -9, -4, 11, -14, 5, -7, 9, -13, 24, -27, 4, 14, 7, -31, 19, -14, 17, -5, -34, 57, -31, -7, -6, 28, -15, -11, 2, 25, -21, -14, 15, 18, -35, 12, 1, 9, -20, -2, 32, -37, 26, -17, 7, 1, -10, -18, 54, -37, -16, 23, 11, -13, -23, 34, -5, -16, -10, 25, -28, 30, -10, -7, -5, 18, -24, 25, -24, 18, -11, 0, 3, -19, 34, -12, -12, 2, 3, -13, 32, -37, 20, 4, -6, -25, 29, -3, -2, -11, -2, 28, -38, 18, 7, -5, -7, 0, -4, 21, -36, 30, -19, 25, -29, -15, 48, -11, -43, 33, 33, -64, 17, 26, -12, -18, 9, -1, 18, -33, 23, -13, 21, -18, -13, 18, -2, -20, 20, 6, -15, 4, -12, 28, -27, 1, 10, -5, 3, 0, -17, 15, 17, -30, 2, 5, -8, 17, -11, -2, 9, -20, 23, -27, 23, -10, -3, 7, -3, -25, 31, 9, -28, -9, 30, -5, -28, 15, 29, -36, -9, 29, -11, -20, 33, -27, 21, -14, -12, 21, -3, -9, -2, 12, -5, -27, 27, 7, -20, -11, 32, -9, -15, -1, 9, 20, -42, 12, 9, -4, 3, -6, -3, 6, 0, -12, 15, -25, 27, -6, -6, -6, 6, -2, -4, 5, 9, -20, 12, 8, -17, -10, 30, -12, -24, 25, -15, 18, -21, 21, -8, -6, -9, 12, -6, 15, -33, 26, 8, -32, 13, 21, -12, -28, 20, 11, -6, -28, 27, 11, -21, -10, 22, -1, -11, -7, 24, -12, -27, 35, -8, 0, -20, 23, -10, 9, -30, 32, -15, 3, -7, 6, -2, 10, -17, 1, 8, -4, -5, -3, 14, -9, 1, -11, 18, -13, 15, -33, 22, 14, -32, 11, 9, -1, -17, 14, 0, -3, -16, 29, -21, -4, -1, 28, -24, -2, -11, 41, -25, -23, 24, 6, -18, -13, 37, -21, -2, -4, 29, -40, 11, 12, 4, -25, 12, -9, 23, -17, -14, 27, -2, -26, 9, 18, -14, -1, -15, 29, -18, -4, 5, 12, -26, 18, -3, -7, 3, 13, -10, -25, 44, -38, 11, 8, -2, -25, 28, -9, 12, -13, -13, 10, 27, -53, 19, 16, -4, -20, 12, 12, -21, 5, 12, 3, -35, 22, 8, 0, -28, 18, 16, -25, -3, 9, 8, -3, -19, 8, 24, -34, -4, 38, -16, -30, 29, -1, -2, -25, 28, -1, -21, 11, 10, -18, -1, 10, 1, -7, 0, 1, -7, 15, -15, -5, 16, 2, -22, 8, 0, -1, 26, -34, -22, 56, -26, -11, 12, 9, -9, -9, 4, 7, -8, -1, 8, 0, -21, 10, 19, -8, -25, 17, 10, -18, 3, -4, 26, -15, -29, 30, 9, -46, 36, 12, -33, 1, 18, -2, -16, 4, 16, -10, -16, 11, 2, 8, -19, 5, 1, 10, -21, 20, -8, -1, -3, 1, 7, -19, 7, 11, -12, 5, 5, -26, 29, -11, -5, -2, 12, -13, 9, -22, 23, 3, -20, 4, 17, -16, -13, 17, 15, -16, -34, 37, -5, 8, -32, 23, 17, -36, -2, 36, -25, -4, 28, -18, -20, 15, 4, 7, -12, -24, 43, -19, 0, -11, 25, -9, -12, -7, 10, -1, 11, -2, -12, 13, -27, 30, -9, -15, 8, 17, -28, 18, -9, 3, 7, -8, -10, 16, -26, 35, -22, -10, 37, -35, 1, 11, 11, -19, -2, 9, 17, -37, 11, 10, 9, -16, -12, 27, -11, -22, 16, 24, -48, 25, -1, -3, 4, -20, 13, 39, -72, 34, 1, 2, -6, 4, -1, -8, 2, -8, 18, -10, -1, -5, 19, -30, 5, 30, -16, -26, 36, -26, 3, 21, -27, 10, 4, -10, 0, -4, 15, 9, -41, 32, -11, 2, -11, 15, -3, -7, -8, 16, -3, -21, 23, -2, -9, -4, -2, 20, -5, -37, 49, -20, -6, -9, 17, 17, -36, -8, 40, -24, -5, 3, 8, 5, -12, -6, 15, 2, -27, 28, -4, -23, 16, 5, -1, -26, 29, 11, -38, 22, -12, -8, 38, -34, -3, 10, 4, -2, -5, -8, 24, -16, -20, 21, 1, -7, 11, -7, -4, -15, 15, 15, -21, -6, 10, -1, 17, -45, 23, 29, -42, 2, 18, -5, -6, -1, 22, -20, -19, 16, 21, -20, -18, 23, 2, 5, -41, 36, 10, -34, 12, 12, -25, 11, 1, 6, -6, -11, 20, -11, 10, -11, -12, 13, 8, -21, 5, -1, 14, 3, -26, 5, 27, -39, 18, 7, -27, 34, -20, 13, -20, 7, -4, 25, -23, -16, 7, 47, -35, -29, 37, 10, -35, 4, 12, -1, 0, -15, 25, -23, -12, 35, 7, -51, 28, -1, 16, -33, 5, 27, -21, 2, -5, 13, -3, 0, -20, 27, -30, 8, 16, -4, -13, 14, -15, 19, -12, -6, 8, -9, 19, -27, 4, 20, -9, -12, 21, -37, 41, -22, 1, 1, 13, -33, 20, 14, -30, -2, 22, 21, -51, 3, 38, -7, -35, 17, 6, 11, -43, 33, 9, -36, 10, 31, -24, -13, 16, -6, 24, -36, -1, 16, 19, -45, 20, 11, 2, -30, 31, -21, -14, 29, -4, -12, 3, -6, 9, 15, -37, 20, -4, 8, -18, 12, -7, 17, -8, -12, -9, 23, 8, -28, 1, 29, -19, -18, 27, -2, -8, -28, 44, -4, -36, 15, 33, -30, -13, 13, 14, -20, -7, 25, -11, -5, -8, 21, -1, -8, -37, 50, 1, -53, 27, 28, -21, -10, 4, 16, -24, 10, 6, -12, 0, 2, 6, 1, -13, 2, 21, -26, 3, 13, -19, 10, 9, -18, -3, 22, -18, -1, -2, 14, -1, -23, 21, -6, -2, -9, 20, 5, -35, 1, 34, -21, -16, 22, 1, -8, -5, 1, 18, -12, -23, 18, 5, -17, -7, 37, -6, -35, 6, 47, -44, -7, 20, 5, -10, -23, 35, -6, -12, -12, 39, -27, -10, 9, 21, -21, -6, 2, 5, 1, 6, -28, 17, 20, -31, -3, 15, 7, -26, 31, -40, 43, -32, 23, -19, 11, -22, 26, -6, -1, -25, 33, 2, -25, -7, 9, 26, -16, -30, 29, 20, -47, 13, 16, -9, -19, 18, 23, -32, -17, 32, 21, -38, -13, 14, 43, -66, 19, 23, 5, -50, 47, -20, 2, -11, 22, -5, -6, -21, 4, 38, -15, -32, 12, 35, -35, -4, 7, 18, -17, -1, -7, 6, 5, 0, 0, -7, 0, -8, 21, -10, 5, -28, 30, 3, -17, -29, 57, -16, -17, -10, 28, -9, -20, 26, -12, 3, -20, 27, -3, -7, -42, 65, -9, -45, -3, 63, -33, -11, -6, 28, -17, -1, -6, 6, 7, -12, 0, 25, -21, -30, 54, -9, -37, 1, 28, 7, -42, 18, 11, 17, -46, 24, -9, 27, -38, 22, -20, 23, -21, 11, -6, 42, -71, 20, 32, -11, -43, 44, -3, -4, -27, 12, 24, -8, -18, -8, 30, -19, -23, 44, -8, -30, 0, 45, -39, 0, -1, 28, -16, -17, -15, 44, -13, -11, -13, 36, -24, -11, 12, 17, -30, 8, 17, -10, -18, 9, 22, -18, -15, 3, 25, -25, 11, -6, 5, 7, -18, -3, 15, -1, -17, 8, 28, -32, -17, 36, 8, -41, 12, 7, 13, -22, -14, 18, 41, -57, -1, 25, 10, -40, 18, 11, -8, -23, 25, -16, 37, -45, 17, 10, 2, -60, 64, -15, -3, -16, 22, -9, 9, -27, 30, -7, -21, 3, 20, -10, 6, -12, 15, -19, 14, -19, 3, 22, -8, -29, 37, -28, 29, -26, 11, -15, 15, -17, 21, -26, 18, 5, -5, -11, 2, 16, -10, -10, -5, 29, -30, 4, 3, 18, -21, 4, 1, 8, -13, -10, 1, 40, -35, -26, 44, 5, -38, 8, 30, -24, 0, -1, 0, 12, -18, -1, 18, -8, -28, 39, -18, 24, -35, 24, -36, 46, -41, 12, -3, 24, -37, 31, -28, 32, -16, 2, -27, 39, -34, 7, 24, -19, -6, 14, -10, -1, 14, -16, -4, 25, -26, -4, 8, 22, -40, 33, -30, 22, -15, 36, -63, 39, 1, 10, -54, 36, 9, 5, -51, 49, -13, 5, -7, -7, 15, -9, -10, 2, 12, -18, 6, 3, 18, -29, 9, 10, -10, 1, -20, 20, -3, -1, -13, 21, -26, 41, -36, 2, 23, -23, -10, 39, -41, 17, -10, 8, 7, -13, 23, -54, 66, -26, -50, 54, 17, -66, 59, -46, 30, -10, 6, -8, -18, 19, 16, -32, 12, 6, -2, 3, -36, 33, -6, -7, 12, -16, 6, 14, -21, 14, 16, -58, 37, 3, 0, -35, 44, -16, 17, -38, 28, -14, 25, -45, 28, -21, 32, -31, 11, 17, -24, 11, 5, -24, 18, -6, -3, 0, -3, 21, -33, 24, 20, -78, 66, -8, -24, 3, 17, -14, 24, -41, 34, -25, 27, -32, 17, -5, 13, -26, 28, -29, 22, -8, -16, 33, -30, 2, 25, -27, 1, 31, -36, -7, 31, -8, -12, -5, 17, -7, 5, -26, 32, 1, -18, -16, 27, -7, -10, 2, 21, -42, 30, -3, -19, 33, -40, 19, 6, -13, -5, 17, -10, 28, -63, 40, 6, -10, -9, 7, -3, 12, -20, -1, 17, -1, -6, -14, 18, 1, -19, 12, 5, -9, -2, -14, 33, -3, -44, 51, -17, -6, -16, 36, -35, 29, -31, 31, -24, 15, -23, 33, -35, 20, -4, -1, -19, 27, -1, -29, 25, 1, -20, 25, -23, -13, 62, -50, -18, 43, -20, 1, -4, 16, -18, 4, -16, 36, -42, 42, -42, 38, -28, 9, -10, 31, -40, 30, -39, 30, 8, -28, 11, 9, -7, -6, -8, 10, 22, -36, -5, 26, 4, -41, 30, 12, -11, -10, -14, 37, -29, 3, -6, 9, -5, 15, -30, 40, -26, 12, -25, 25, -21, -12, 46, -17, -39, 47, 7, -57, 45, -14, 1, -13, 21, -21, 14, -7, 7, -11, 18, -34, 25, 7, -28, 22, 1, -12, 11, -24, 4, 38, -44, 17, 2, -12, 19, -17, 0, 9, 17, -55, 29, 3, 3, -27, 48, -38, 16, -17, 24, -19, 26, -49, 29, 9, -18, -25, 50, 2, -31, -20, 43, -3, -35, 23, 13, -34, 9, 20, -15, -8, 29, -37, 29, -21, 4, -8, 36, -52, 29, -8, 6, -18, 35, -34, 22, -21, 10, 5, -11, -13, 35, -26, -3, 12, -17, 13, 1, -12, -4, 24, -18, -6, 18, -7, -13, 17, -4, -30, 48, -41, 10, 34, -39, -22, 73, -48, -12, 12, 22, -14, -31, 18, 29, -17, -21, 22, -3, -8, -12, 25, -11, 13, -41, 36, -3, -2, -27, 37, -6, -36, 17, 18, -7, -10, 4, -5, 10, -21, 13, 15, -21, 2, -1, -5, 8, -1, -16, 29, -24, 14, -18, 26, -24, 17, -26, 21, -18, 24, -49, 82, -52, -11, 36, -22, -17, 30, -21, 1, 1, -1, 8, -2, -7, 2, 17, -9, -36, 37, -5, -15, -4, 27, -20, 11, -31, 46, -18, -13, -11, 58, -67, 19, -4, 40, -43, 9, -14, 41, -32, -16, 46, -19, -13, 5, -5, 6, 2, -16, 10, -9, 18, -13, 3, 24, -37, 11, 1, 0, -8, -9, 28, -1, -41, 40, -10, 6, -13, 1, -11, 30, -28, -10, 30, 1, -36, 17, 28, -54, 51, -24, 1, -6, 6, -12, 33, -48, 23, 18, -17, -23, 27, 11, -23, -13, 27, -7, -1, -24, 35, 3, -48, 35, 8, -20, -3, 3, 16, -11, 8, -35, 32, 7, -27, -22, 81, -85, 36, -7, 16, -16, 2, 0, 13, -28, 12, -16, 24, 6, -25, -14, 47, -15, -25, 3, 37, -41, -5, 32, -25, 11, 6, -16, 25, -34, 14, 8, 13, -52, 30, 6, 13, -56, 56, -27, 13, -11, -6, 16, -12, -1, 18, -40, 18, 19, -13, -11, 7, -2, 9, 10, -39, 9, 46, -48, -18, 59, -32, -3, 14, -10, 10, -13, 10, -13, 14, -11, -10, 5, 31, -43, 10, 23, -16, 3, -29, 50, -23, -19, 16, 15, -19, 3, -20, 39, -19, -14, -6, 54, -44, -12, 18, 30, -56, 28, -15, 22, -16, -15, 31, -8, -9, -1, 1, 1, 2, -8, 9, 10, -43, 41, -9, 8, -48, 62, -30, -9, 13, 6, -24, 32, -31, 8, -4, 16, -27, 27, -19, -1, -6, 37, -40, 14, -3, 0, 25, -59, 34, 18, -18, -21, 17, 13, -11, -8, -11, 43, -40, 1, 6, 24, -37, 10, 14, -4, -12, -2, 17, 11, -40, 10, 16, 17, -51, 24, 14, -4, -31, 22, 18, -32, 15, -24, 46, -38, 9, 2, -2, 14, -15, -12, 15, 3, -28, 29, -7, -6, 13, -7, -6, 2, 3, -17, 28, -28, -9, 37, -17, 0, 3, 10, -19, -5, 19, -17, 12, -25, 30, -19, 8, -27, 49, -15, -27, 9, 10, 7, -31, 6, 30, -12, -45, 41, 24, -42, -1, 28, -2, -38, 29, -18, 23, -4, -43, 35, 26, -54, 23, 7, 6, -30, 17, -14, 32, -40, 24, -13, 17, -15, -11, 16, 16, -20, -26, 47, -10, -26, -6, 41, -19, -22, 36, -41, 33, 5, -32, 12, 28, -51, 19, 27, -40, 7, 35, -34, 9, -22, 42, -20, -15, -3, 43, -55, 15, 23, -10, -11, 3, 14, -32, 31, -26, 21, 7, -44, 15, 40, -22, -41, 54, -17, -17, 8, -6, 10, 11, -17, -6, 15, -2, -20, 31, -19, 4, -17, 22, 0, 2, -36, 39, 0, -31, 23, -38, 59, -15, -29, -13, 69, -50, -22, 43, -11, -16, 0, 16, -9, -10, 13, 5, -8, -18, 27, -8, -2, -12, 13, -1, -16, 16, -18, 27, -11, -19, 39, -28, -26, 28, 36, -85, 72, -40, 24, -10, 0, -9, 30, -29, -11, 22, -13, -7, 23, -10, -14, 6, 13, -15, 22, -31, 12, 0, 0, -3, -15, 19, 14, -21, -22, 27, 35, -72, 36, -3, 18, -54, 50, -29, 38, -47, 14, 19, -11, -25, 27, 9, -23, -2, 2, 16, -6, -24, 22, 10, -27, 7, 16, -30, 11, 24, -40, 31, -28, 29, 1, -28, 7, 17, 3, -45, 40, -11, -7, 4, 19, -45, 24, 24, -50, 48, -35, 11, 9, -12, -14, 30, -23, 8, 7, -15, -7, 53, -59, 13, 5, 15, -46, 49, -48, 57, -36, -20, 34, 1, -10, -15, 15, 20, -36, -9, 35, 6, -39, 7, 14, 27, -81, 70, -21, 5, -22, 21, -6, 1, -13, 19, -19, 4, -10, 35, -43, 31, -3, -7, -15, 40, -56, 33, -1, -33, 51, -35, -2, 24, -18, 5, 0, 4, -16, 10, -6, 9, -28, 37, -38, 45, -35, 0, 37, -38, 7, 19, -32, 3, 17, -2, -23, 19, 15, -23, 5, -2, 13, 1, -37, 8, 59, -80, 26, 13, 15, -31, -8, 30, -7, -7, -19, 22, -2, -9, -2, 12, -7, 3, 1, -25, 47, -53, 35, -5, -27, 21, 15, -25, 13, -24, 42, -41, 19, 2, -13, 1, 23, -40, 37, -45, 46, -8, -41, 44, -11, -17, 23, -9, -20, 22, -3, -15, 22, -23, 19, -7, 2, -34, 65, -56, 7, 28, -8, -37, 37, 3, -8, -34, 39, -11, 9, -29, 6, 35, -14, -49, 48, 5, -25, 5, -25, 66, -47, -9, 28, -7, -12, 0, 17, -20, -2, 21, -12, -23, 54, -50, 20, 7, -20, 7, -2, 3, 4, -26, 26, -6, -14, 15, -3, -10, 12, -10, -4, 23, -33, 14, -12, 38, -55, 36, 0, -6, -5, 0, -4, 7, 0, -14, 2, 8, -11, 13, 5, -33, 41, 4, -62, 40, 8, -6, -8, -31, 52, -4, -44, 25, 20, -18, -24, 32, -11, -9, -4, 30, -37, 34, -31, 7, 30, -29, -14, 28, -10, -9, 6, 0, -5, 14, -9, -3, -2, 10, -22, 29, -22, -2, 6, -5, 16, -25, 6, 27, -19, -9, -11, 29, -13, -5, -6, 16, 5, -20, -1, 30, -20, -8, 7, -8, -2, 3, 14, -9, -24, 35, -7, -14, -12, 32, -5, -18, -15, 35, -7, -13, -1, -4, 27, -20, -30, 58, -15, -29, 9, 15, -16, -3, 1, 4, 5, -4, -11, 17, 3, -29, 28, -10, -18, 20, -7, -2, 4, 2, -17, 22, -3, -31, 23, 23, -32, -14, 34, -3, -14, -13, 11, 21, -26, -16, 36, -7, -13, 15, -8, -3, -1, -11, 15, -8, -4, -4, 24, -21, 1, 11, 3, -22, 5, 15, -24, 0, 37, -31, 7, -18, 15, 16, -15, -19, 26, 0, -10, -26, 31, 6, -19, -6, 21, -19, 20, -13, -3, 13, -2, -32, 24, 2, -8, -10, 36, -29, -10, 19, 10, -25, 5, -9, 31, -23, -21, 21, 26, -25, -9, -5, 35, -17, -34, 17, 42, -44, -11, 30, 11, -40, 18, 8, -6, -11, 11, -26, 39, -18, -23, 37, -12, -32, 45, -8, -22, 5, 16, -15, -10, 6, 17, -15, -3, 9, -22, 41, -22, -25, 29, 5, -30, 6, 12, 17, -32, 7, 20, -26, 9, 9, -10, 7, -17, 10, 11, -16, -7, 12, 5, -4, -26, 25, 24, -46, -4, 50, -39, -11, 8, 35, -36, 2, -9, 33, -7, -22, -26, 76, -37, -41, 33, 28, -43, 14, 6, 2, -8, 2, -20, 34, -19, -2, -4, 15, -6, -23, 28, -3, -32, 33, -16, 7, -11, 14, 9, -10, -30, 35, -25, 17, -14, 1, 14, 12, -38, 16, 15, -7, -30, 15, 18, -24, -6, 47, -38, 6, 7, -9, -2, -3, 1, 12, -8, -23, 20, 35, -47, -14, 51, -9, -48, 19, 20, 0, -25, -2, 20, 16, -29, -25, 60, -17, -23, -8, 31, -4, -30, 12, 20, -14, -4, -1, 17, -11, -9, 7, 7, -17, 1, -12, 25, -5, -20, 15, 19, -29, 2, 5, 11, -19, -18, 31, 1, -27, 18, -17, 51, -53, -2, 29, 4, -37, 17, 11, -11, -23, 41, -17, -10, 13, -4, -8, 18, -27, 17, 1, -19, -7, 51, -37, -28, 53, 4, -47, 5, 18, 17, -32, -8, 14, 36, -46, 3, 11, 11, -24, 4, 0, 16, -7, -26, 25, 20, -44, 7, 20, -12, 2, -14, 4, 33, -38, 1, 8, 20, -34, -12, 61, -46, -19, 44, -10, -4, -18, 12, 12, -8, -26, 16, 22, 2, -51, 18, 53, -56, -5, 30, -9, -22, 32, -11, -18, 18, 13, -25, -7, 8, 9, 3, -20, 1, 32, -27, -9, 5, 19, -20, -13, 18, 8, 3, -35, 22, 31, -47, -2, 16, -8, 15, -10, -22, 54, -20, -23, -6, 51, -52, -13, 48, -23, -11, 28, -30, 38, -6, -50, 28, 33, -58, 2, 34, 16, -53, -1, 55, -13, -42, 15, 23, -7, -33, 13, 21, -14, -6, 2, -2, 27, -43, 27, 11, -19, -16, 26, -16, -4, 16, -17, 1, 20, -17, 8, -17, 6, 26, -25, -24, 40, -13, 6, -14, -14, 29, 3, -32, -5, 46, -21, -28, 38, -30, 6, 28, -47, 3, 65, -67, -5, 61, -34, -27, 31, 12, -30, -7, 11, 19, 0, -43, 18, 47, -52, -20, 52, -14, -9, -10, -5, 55, -45, -29, 55, 16, -83, 28, 36, -23, 6, -8, -13, 37, -17, -30, 32, -9, -6, 10, -19, 16, 4, 9, -35, 22, -1, -17, 3, 8, 10, -10, -21, 40, -27, -5, 16, -6, -27, 47, -23, -26, 48, -18, -19, 14, -1, -9, 5, 1, -20, 58, -57, -14, 55, -16, -40, 37, -6, 11, -19, -22, 43, 2, -55, 27, 37, -38, -29, 58, -6, -11, -22, 4, 26, -7, -67, 67, 21, -56, 19, 15, -5, 0, 2, -41, 37, 10, -65, 49, 8, 1, -19, 1, 9, 8, -20, -9, 22, -14, -3, 4, -1, 13, -6, -11, 15, -8, -15, 13, 16, -38, 14, 24, -39, 20, 9, -17, 14, -15, 7, 3, -12, -3, 30, -25, -24, 43, -1, -40, 18, 17, 0, -22, -14, 31, 20, -68, 35, 32, -43, -9, 35, -16, 4, 2, -35, 35, 27, -81, 40, 31, -21, -30, 29, -12, 13, 10, -42, 26, 17, -33, -1, 16, 12, -29, 6, 4, 21, -27, -9, 39, -6, -54, 40, -14, 15, -4, -17, 20, 4, -18, -4, 23, -24, -3, 30, -41, 15, 17, -4, -29, 19, 4, -9, -10, 12, 17, -21, -7, 26, -19, -17, 17, 3, 1, -3, -30, 47, 16, -62, -4, 68, -29, -54, 43, -1, -4, 20, -42, 22, 34, -32, -43, 63, -12, -26, 8, -6, 10, 22, -66, 55, 25, -65, 15, 9, 21, -22, -28, 36, 5, -16, -51, 102, -49, -12, 6, 21, -12, -23, 24, -15, 11, -14, -8, 31, 4, -53, 64, -35, 13, -28, 23, -23, 22, -16, 13, -22, 23, 27, -51, -8, 41, 6, -66, 36, 13, 4, -26, 7, 11, 9, -34, 0, 35, -21, -15, 10, 34, -57, 60, -69, 60, -22, 1, -27, 27, 14, -27, 1, -13, 35, -2, -51, 36, 35, -49, 5, -1, 31, -42, 25, -26, 34, -7, -60, 98, -46, -22, -1, 49, -45, -2, 10, 26, -33, 25, -36, 37, -19, 4, -3, -7, 9, 7, -8, -29, 48, -23, 0, -33, 45, 0, -23, -16, 47, -7, -31, -9, 38, -2, -36, 18, -8, 43, -55, 16, -1, 41, -72, 54, -35, 24, 4, -46, 47, -11, 6, -40, 24, 10, 8, -38, 16, 16, 24, -98, 80, 2, -28, -28, 44, 11, -47, 31, -7, 35, -42, -25, 41, 12, -64, 34, 14, -2, -21, 24, -14, 11, -3, -24, 22, -28, 46, -51, 38, -22, 35, -40, 2, 11, 22, -48, 23, -9, 34, -35, -24, 52, -7, -37, 9, 36, -21, 0, -32, 61, -44, 6, -1, -16, 41, -28, 19, -37, 49, -11, -38, -8, 65, -53, 9, -21, 59, -37, 8, -33, 59, -13, -80, 67, 19, -39, -28, 70, -21, -25, -3, 23, 17, -29, -44, 83, -41, 0, -23, 53, -27, -12, 21, -19, 21, -21, 13, -4, -12, -5, 38, -58, 34, 10, -22, -16, 47, -8, -39, 19, 12, 4, -46, 39, -24, 48, -69, 45, -18, 10, -5, -2, -4, 10, -5, 7, -17, -3, 20, 0, -40, 26, 40, -64, 11, 34, 1, -49, 11, 35, -22, -14, -32, 98, -47, -37, 9, 76, -70, -8, 7, 63, -92, 56, -49, 77, -64, 2, 41, -28, -25, 37, 0, -26, 35, -40, 16, 3, 14, -46, 22, 18, -6, -9, -11, 22, 26, -44, -46, 94, -60, 18, -37, 69, -33, 5, -20, 42, -32, -20, 24, -1, -10, -12, 39, -31, 13, 1, 9, -47, 42, -26, 39, -73, 48, 48, -73, -13, 56, 14, -78, 38, 11, 12, -50, 8, 39, 3, -79, 73, 2, -25, -17, 23, 27, -58, 26, -37, 67, -49, 11, -12, 62, -82, 64, -41, 3, 26, -17, -45, 55, -4, -22, 10, -2, 38, -54, 8, 5, 47, -79, 7, 54, -7, -64, 41, 49, -73, 29, -24, 54, -51, -4, 14, 33, -84, 82, -46, 17, -25, 57, -44, -2, 11, 8, 15, -66, 46, 19, -25, -44, 58, 10, -38, -23, 77, -48, -3, -12, 24, 24, -70, 37, 21, -15, -48, 81, -66, 44, -29, 6, 4, 9, -30, 31, -24, 5, 19, -51, 34, 21, 11, -92, 78, 19, -44, -54, 104, -47, -8, -19, 29, 45, -78, 6, 55, -11, -75, 66, -10, 8, -38, 24, 10, 4, -57, 66, -20, -25, 20, 6, 9, -71, 100, -60, -6, 8, 28, -37, 29, -42, 78, -58, -22, 42, 10, -69, 34, 33, -36, 29, -54, 81, -54, 0, 7, 1, -19, 22, -14, 4, -3, 32, -13, -59, 86, -54, 4, 0, 21, -35, 43, -68, 91, -31, -53, 38, 48, -72, -15, 50, 3, -11, -72, 96, -1, -49, -23, 81, -21, -57, 15, 63, -67, 5, 25, -27, 34, -48, 49, -26, 12, -33, 66, -73, 14, 35, -20, -27, 45, -24, 12, -12, 0, 24, -50, 33, -26, 45, -65, 47, -7, -4, -9, 19, -19, -2, 15, -17, 30, -39, 25, 2, -3, -57, 109, -86, 10, 14, 31, -53, 7, 32, 5, -44, -20, 84, -35, -34, -6, 99, -97, 1, 23, 40, -65, 15, 9, 36, -45, -22, 55, 4, -55, -3, 73, -80, 63, -49, 28, 2, -10, -19, 24, -13, 8, 1, -15, 5, 22, -4, -57, 72, -41, 16, -45, 76, -57, 30, -26, 38, -16, -34, 32, 12, -53, 22, 47, -46, -4, 6, 45, -65, 32, -21, 45, -44, -22, 69, -44, -16, 29, 19, -59, 40, -7, 42, -77, 39, -4, 29, -74, 27, 38, -12, -60, 69, 7, -32, 1, -9, 50, -56, -15, 19, 47, -75, 44, 5, -22, 27, -7, -22, 0, 23, -30, 1, 4, 33, -44, 29, -24, 57, -67, 17, 18, 4, -59, 32, 48, -72, 28, -2, 13, -10, -21, 16, 58, -117, 85, -14, -5, -34, 21, 29, -27, -20, 31, 23, -49, 16, -14, 51, -74, 24, 38, -38, -16, 56, -33, -7, 3, 0, 36, -80, 49, 23, -19, -48, 76, -61, 43, -41, 27, -11, 23, -30, 8, 3, 15, -14, -22, 16, 3, 15, -39, 11, 38, -13, -70, 88, -41, 2, 4, -30, 80, -84, 15, 37, -6, -61, 58, -19, 27, -72, 64, -6, -16, -30, 59, -21, -21, -12, 44, 22, -101, 78, -10, -16, -11, 20, -21, 31, -36, 37, -18, -20, 46, -24, -23, 10, 21, -36, 32, -38, 68, -50, 12, -6, 19, -33, 14, -16, 20, -11, -14, 47, -59, 56, -14, -27, 5, 29, -43, 49, -96, 106, -35, -41, 28, 35, -30, -29, 37, 12, -11, -58, 79, -31, -16, -11, 43, -13, -25, 3, 71, -76, -13, 64, -39, 3, -45, 66, -13, -1, -45, 80, -40, 6, -29, 26, -12, 6, -19, 21, -4, 9, 0, -37, 44, -28, 11, -22, 19, 7, 1, -45, 60, -13, -42, 32, -16, 31, -50, 35, 10, -22, -23, 60, -62, 21, -2, 39, -49, -4, 24, 30, -53, -23, 66, -33, 2, -34, 69, -33, -10, 7, 24, -51, 28, 0, 9, -24, -3, 38, -24, -16, -9, 68, -81, 38, -16, 35, -34, -4, 16, 20, -43, 10, 7, -3, 14, -30, 38, -39, 38, -20, -12, -20, 78, -79, 22, -4, 44, -48, -6, 37, -2, -25, -24, 60, -41, 15, -30, 50, -43, 7, 9, 27, -64, 45, 5, -15, -17, 1, 49, -56, 3, -11, 69, -78, 37, -5, 38, -60, 26, -2, 9, -51, 53, -20, -3, 9, -1, 38, -74, 40, 6, -13, -54, 69, -24, 6, -22, 31, 0, -17, 12, -13, 8, -9, 20, -53, 56, -27, 29, -63, 41, 8, 11, -73, 59, 15, -25, -21, -1, 61, -69, 10, 17, 28, -59, 34, -14, 32, -54, 17, 22, -11, -47, 63, 7, -56, 46, -28, 50, -96, 60, 2, 0, -37, 36, -11, 15, -38, 41, -19, -31, 46, -12, -25, 9, 49, -67, 47, -48, 51, -30, -15, 23, 19, -43, 8, 17, 4, -11, -29, 54, -48, 38, -28, 10, -9, 38, -48, 27, -47, 55, 3, -59, 22, 41, -5, -59, 38, 5, 31, -101, 72, 11, -36, -18, 54, -25, -1, -30, 54, -28, -34, 61, -27, 13, -46, 55, -21, -10, -21, 52, -34, -8, 30, -21, 20, -11, -21, 22, -2, -46, 79, -84, 60, -9, 13, -57, 51, 2, -16, -38, 34, 15, -23, -7, -6, 53, -38, -22, 29, 23, -63, 65, -34, -21, 34, -7, -19, -8, 24, 13, -8, -63, 110, -56, -8, -37, 79, -56, -3, -3, 62, -57, 19, 9, 8, -20, -29, 27, 13, -28, -19, 79, -80, 58, -31, 24, -16, -35, 46, 0, -52, 36, 21, -29, 16, -23, 26, -29, 38, -42, 26, -41, 60, -29, -16, -4, 42, 7, -85, 53, 47, -54, -29, 67, -53, 39, -58, 45, -5, 5, -37, 61, -56, 27, 17, -40, 1, 15, 17, -43, 19, 4, 30, -49, 12, -1, 49, -64, -27, 96, -41, -47, 45, 8, -38, 35, -50, 74, -81, 54, -14, 24, -64, 57, -5, -25, -19, 27, 16, -27, 4, 16, 2, -25, 26, -31, 22, -35, 56, -54, 0, 55, -23, -29, 9, 38, -38, 12, -41, 74, -28, -29, -3, 61, -71, 36, -32, 43, -19, -14, 21, 0, -10, -19, 32, -42, 20, 11, 23, -94, 107, -13, -53, 5, 35, -17, -11, -25, 32, 40, -76, 29, 32, -9, -65, 80, -42, 6, -22, 42, -27, -2, 10, -2, 13, -41, 32, 10, -17, -26, 53, -50, 40, -42, 30, -19, 41, -50, 33, -20, -1, 40, -67, 8, 29, 15, -58, 25, 32, 15, -81, 46, 14, -8, -51, 24, 40, -44, 17, 10, 2, -26, 47, -68, 49, -49, 50, -27, -3, -20, 84, -62, -32, 52, 12, -52, 0, 42, -30, 24, -47, 45, -16, 11, -51, 74, -47, -9, 45, -19, -18, -5, 41, -39, 11, -33, 56, -20, -14, -8, 64, -85, 60, -23, -13, -3, 33, -20, -25, 57, -34, 2, -23, 42, -21, 3, -49, 85, -35, -27, 1, 54, -34, -31, 24, 15, 6, -45, 54, -30, 12, -27, 40, -61, 39, 1, -5, -18, 17, 14, 7, -33, -27, 83, -44, -40, 21, 66, -82, 32, -7, 33, -54, 27, 3, 2, -13, -15, 52, -57, 14, 14, -6, -27, 54, -45, 23, -11, 16, -27, 27, -33, -3, 36, -46, 47, -15, -8, -7, 67, -93, 12, 34, 17, -73, 32, 15, 29, -44, -17, 47, 2, -40, -31, 81, -43, 3, -24, 52, -32, 4, 1, 20, -48, 20, 40, -68, 23, 14, 19, -64, 46, -8, 17, -48, 55, -29, 23, -59, 48, -2, -27, 11, 1, 21, -30, 25, -24, 29, -41, 21, 0, -15, -17, 64, -47, 1, 31, -22, 2, -11, 22, -56, 69, -53, 32, -30, 31, -16, 32, -68, 29, 42, -39, -49, 80, 17, -74, 17, 0, 55, -88, 25, 29, 14, -72, 56, 0, 0, -33, 20, 5, -34, 35, -33, 45, -37, 23, -9, 10, -54, 67, -22, -13, -15, 41, -14, -16, 8, 0, 19, -51, 56, -51, 39, -20, 19, -34, 26, -18, 19, -31, 23, 0, 12, -31, 7, 45, -65, 22, 4, 24, -73, 74, -13, -34, 18, 23, -16, -25, -2, 40, 5, -84, 76, -4, 6, -74, 75, -7, -10, -51, 60, -13, 0, -45, 50, 18, -57, 20, 21, -7, -26, 47, -51, 28, -19, 12, -13, 3, -1, 20, -23, 1, 28, -18, 3, -41, 67, -72, 34, -11, 33, -47, 47, -9, -20, -2, 28, -21, -27, 11, 26, -15, -25, 57, -44, 46, -67, 49, -5, -30, 1, 42, -36, -9, 22, 7, -13, -34, 67, -29, -16, -26, 84, -49, -21, -11, 77, -53, -43, 62, 0, -3, -32, 23, 13, -5, -69, 88, -42, 7, -17, 37, -35, 27, -6, -13, -11, 31, -17, -28, 45, -17, 8, -32, 41, -48, 39, -35, 41, -16, -28, 41, -3, -13, -26, 23, 12, -22, -50, 104, -57, 9, -28, 67, -53, -7, 0, 45, -41, -22, 50, -8, -21, -9, 38, -19, -18, -2, 55, -76, 38, -12, 39, -49, -14, 64, -24, -45, 25, 50, -66, 23, -15, 32, -36, 32, -46, 44, -14, 2, -16, 22, -7, -11, 14, -28, 21, 4, -10, -18, 63, -66, 30, -20, 36, -35, -16, 26, 12, -37, 6, 50, -35, -15, 6, 48, -64, 4, 12, 46, -85, 33, 12, 25, -49, -11, 77, -53, -18, 19, 29, -41, -1, 3, 39, -70, 55, -6, -1, -23, 38, -22, -12, 1, -11, 36, -39, 5, 15, 33, -55, 32, -8, 6, -37, 39, -32, 4, 27, -23, 11, -1, 10, -28, 19, -24, 52, -69, 27, 21, 11, -72, 52, 17, -35, -13, 16, 33, -44, 4, 19, 18, -60, 13, 35, 12, -93, 82, 9, -35, -20, 26, 40, -74, 14, 18, 28, -66, 37, 4, 9, -43, 34, -15, 17, -35, 38, -11, -14, 14, -5, 2, -36, 54, -35, 2, 1, 29, -35, 9, -4, 24, -32, -5, 31, -19, -17, 28, 34, -86, 49, 13, -16, -52, 71, -29, 3, -30, 51, -1, -36, 6, 25, 4, -75, 56, 10, -21, -18, 37, -16, 17, -53, 60, -7, -38, -9, 63, -18, -70, 67, 1, -19, -32, 50, -20, 11, -23, 24, -10, -3, -21, 32, -26, 7, 12, -19, 35, -29, 26, -41, 32, -22, 14, -43, 41, 7, -16, -24, 57, -20, -35, 25, 7, -11, -20, 31, -18, 10, -34, 44, -7, -22, -9, 49, -33, -18, 26, -4, 12, -63, 51, 11, -16, -40, 80, -28, -37, 5, 61, -78, 22, 16, -3, -10, -5, 26, -8, -2, -43, 68, -42, -24, 39, 11, -31, 15, -9, 18, -20, -1, 7, -17, 26, -30, 31, -31, 42, -28, -1, -15, 49, -51, -2, 26, 3, -12, -11, 7, 22, -9, -51, 70, -27, -14, -13, 53, -37, -12, 9, 44, -57, -14, 51, -6, -27, -10, 60, -55, 2, 14, 18, -45, 32, -19, 29, -27, -12, 31, 14, -54, 17, 41, -62, 51, -40, 40, -40, 12, -8, 28, -39, 16, 10, 10, -46, 37, 12, -42, 17, -4, 2, -17, 35, -34, 38, -30, 21, -6, -36, 36, 13, -56, 14, 53, -36, -13, -1, 61, -64, 7, -3, 54, -63, 5, 14, 34, -67, 10, 46, -27, -18, 26, 20, -41, 14, -13, 40, -66, 20, 38, -34, -11, 39, -16, 11, -26, 7, 28, -58, 26, 0, 30, -61, 44, 11, -30, -17, 66, -40, -33, 35, 6, -21, -2, 9, 16, -13, -39, 79, -71, 27, 9, -9, -29, 28, 4, -17, 1, 14, 2, -20, -2, 16, 24, -67, 20, 37, -4, -80, 75, 18, -46, 2, 10, 25, -31, -28, 43, 19, -75, 59, -13, 14, -40, 29, 7, -22, -20, 44, -20, -16, 10, 32, -21, -42, 61, -19, -29, 12, 39, -55, 32, -4, 0, -2, -24, 40, -19, -38, 34, 22, -33, 11, -3, 31, -49, 21, -16, 40, -54, 12, 29, -19, -8, 17, 17, -52, 28, 22, -39, -2, 45, -42, 23, -46, 51, 11, -68, 26, 55, -34, -44, 45, 9, -19, -43, 57, -16, -5, -9, 40, -24, -12, 8, 29, -54, -4, 50, -37, 0, 11, 7, -4, 0, -25, 57, -62, 19, 18, -7, -22, 12, 19, -27, 9, -5, 15, -19, 2, 15, 4, -45, 36, -5, 8, -48, 60, -13, -35, 36, -19, 21, -24, -7, 23, -24, -22, 73, -58, -5, 34, 25, -71, 19, 30, 0, -43, -4, 50, -9, -21, -21, 69, -28, -46, 24, 29, -45, 12, 3, 21, -13, -28, 47, -9, -37, 21, 22, -46, 21, 8, -1, -32, 42, -22, 14, -27, 19, 16, -29, 3, 17, -1, -39, 28, 21, -42, 8, 47, -45, 2, -16, 50, -20, -54, 50, 9, -25, -12, 41, -29, 8, -3, -5, -13, 25, -16, 19, -30, 15, 15, -2, -52, 38, 38, -69, 12, 37, 9, -54, 10, 36, 5, -79, 27, 57, -35, -40, 48, 21, -41, 13, -3, 10, -29, 4, 18, 4, -50, 52, 1, -28, -6, 41, -25, -22, 34, -22, 10, -5, 3, -6, -1, 2, 26, -48, 24, 12, 5, -54, 36, 18, -32, -6, -3, 48, -28, -21, 22, 35, -63, 6, 43, -28, -27, 42, -7, -22, 6, 21, 8, -56, 31, 23, -10, -73, 76, 18, -49, -26, 70, -21, -23, -8, 35, 0, -42, 7, 42, -26, -28, 47, -31, 0, 13, 11, -25, 14, -6, 10, -13, -26, 40, -14, -5, -8, 42, -36, 1, 15, -10, -34, 47, -24, 5, -22, 38, 14, -39, -10, 53, -26, -67, 72, 0, -15, -25, 29, 19, -29, -25, 50, -14, -31, 10, 42, -44, -24, 81, -40, -32, 12, 45, -41, -5, -1, 47, -27, -54, 54, 32, -64, 4, 26, 1, -1, -41, 44, 4, -22, -22, 47, -30, 7, 5, 3, -37, 45, 1, -53, 44, -1, -20, 7, 12, -13, 9, -23, 26, -2, -47, 32, 37, -61, 6, 42, 0, -25, -43, 76, -23, -38, -10, 73, -24, -57, 47, 45, -70, 3, 19, 7, -19, -8, 10, 24, -12, -36, 66, -60, -1, 50, -32, -19, 8, 26, 2, -44, 11, 53, -42, -26, 20, 42, -52, 14, 16, -26, -11, 42, -41, 16, 16, -23, 13, 1, -6, 17, -18, -41, 71, -39, -23, 40, 13, -30, 2, 19, 0, -39, 10, 24, -15, -25, 12, 66, -81, 6, 47, 9, -69, 12, 47, -9, -36, -27, 76, 9, -107, 58, 53, -68, 19, -10, 39, -49, 8, 14, -11, -17, 21, 18, -25, -17, 47, -4, -48, 32, -9, -4, -3, 8, -5, 29, -40, 13, 14, -31, 24, 7, -48, 27, 37, -61, 22, 15, 7, -46, 17, 10, 22, -45, -9, 56, 1, -73, 43, 34, -51, -15, 40, 2, -47, 35, 8, 27, -87, 31, 86, -94, -27, 67, 10, -44, -15, 43, 11, -46, 6, 9, 33, -71, 35, 26, -30, -18, 37, -18, -9, 20, -15, 1, 5, 9, -2, -23, -11, 50, -42, -3, 24, 6, -21, 17, -5, -8, 11, -26, 24, -19, -9, 33, 22, -78, 38, 44, -48, -53, 80, 6, -66, 14, 36, 8, -37, -15, 66, -24, -75, 87, -14, -27, -10, 45, -12, -38, 13, 33, 7, -67, 20, 75, -55, -67, 85, 8, -52, -11, 45, -10, 13, -34, 12, 26, -36, 7, -1, -1, -7, 23, -27, 18, 15, -12, -28, 27, -6, 9, -52, 40, 26, -50, 3, 51, -10, -71, 67, 10, -59, 4, 56, -27, -20, -19, 58, 6, -81, 38, 49, -39, -39, 47, 14, -25, -40, 54, -2, -20, -38, 82, -25, -51, 44, 24, -60, 8, 51, -47, -2, 6, 22, 9, -34, -20, 78, -56, -25, 36, 19, -49, 17, 32, -50, 44, -29, 4, -11, 14, 3, -13, -11, 19, 13, -24, 28, -32, 33, -37, 39, -61, 119, -76, 120, -70, 99, -122, 89, -113, 91, -123, 122, -123, 77, 86, -116, 6, -118, 123, -23, 64, -93, 17, 24, -125, 124, -125, 124, -24, -12, 56, 87, -54, 38, -91, 64, -2, -41, 126, -127, 20, 8, -48, -62, 127, -128, 88, -43, -18, 86, -100, 44, -32, -26, 71, -13, 6, 51, -33, -50, 106, -59, 33, 5, -20, 69, -56, 54, -48, -6, 38, -5, -38, 35, -1, 12, -1, 4, 23, -56, 19, -7, 5, -4, 31, -38, 3, -12, -9, -25, -7, 24, -32, 17, -21, -22, 24, -20, 6, -18, 0, -15, 5, -16, 15, 3, 2, -10, 3, 27, -31, 37, -12, 32, -5, 2, -21, 27, -14, 20, -8, 5, 15, -7, -11, 20, -37, 7, -23, 17, -22, 11, -14, 8, -44, 39, -52, 26, 3, 14, -10, 51, -45, 29, -19, 19, -3, 41, -21, 46, -23, 10, 16, -25, 3, 7, -30, 19, -9, -5, -1, 1, -19, 1, -24, -23, 51, -48, -10, 17, -34, -38, 60, -71, 26, -43, 65, -59, 70, -26, 61, -51, 63, -51, 42, -25, 58, -36, 31, 10, -14, -9, 8, -18, 8, 4, 8, 7, 31, -52, 39, -53, 53, -56, 24, 11, 1, -20, -8, -32, -18, -10, -25, 4, 1, 37, -37, 42, -42, 53, -57, 52, -18, 30, 11, 20, -52, 55, -61, 56, -50, 24, -26, 38, -42, 36, -1, -43, 58, -46, 6, 18, -35, 31, -36, 28, -55, 55, -98, 52, -41, 26, -24, 48, -31, 48, -26, 30, 19, -17, 23, -8, 13, 15, 19, -7, -23, 41, -36, 20, -39, 65, -64, 66, -38, -9, 7, -14, -10, -3, 6, 15, -19, -40, 53, -67, -11, -12, -25, 23, -11, -12, 46, -48, 39, -20, 20, -14, 31, -54, 71, -25, 2, -8, -5, -9, 1, 7, 27, 17, -14, 43, -31, 27, 11, -33, 20, -2, -33, 45, -38, 17, -9, -11, -17, -22, -19, 20, -25, 4, 29, -35, 14, -17, 1, -7, 19, 2, 16, 32, -3, -17, 4, 0, -9, 17, 5, -8, 52, -32, 40, -39, -5, -18, 14, -21, 31, 10, -17, 8, -34, -7, 1, -44, 7, 10, -8, -6, -18, -25, -1, -19, 16, -29, 62, 6, 9, 21, 0, -14, 4, 5, 20, 13, 27, -1, 18, -5, 21, -31, 11, 2, -9, -4, 21, -27, 8, -21, -28, -19, 14, -12, 5, -20, 20, -36, 4, -18, -27, -4, -4, 15, 4, 48, -7, -11, 20, -6, 7, 20, 1, 20, 0, 35, -35, 28, -37, 7, -43, 21, -22, 23, -18, 12, -22, -13, -20, -11, 7, 23, -10, 19, -18, 17, -41, 4, -16, -8, 21, 11, -4, 10, 30, -24, 32, -15, 15, -13, 28, -5, 38, -10, 0, -22, -13, -12, 24, -18, 30, -7, 4, -16, 27, -28, -3, -1, 18, -14, 31, -24, -3, -13, -19, -36, -2, -31, 9, -2, -12, 17, 12, -50, 46, -49, 43, -15, 13, 22, 15, -25, 10, -8, -6, 14, -2, 24, 15, 9, 17, -13, 5, 14, -15, 7, 20, 4, 4, 18, -16, 3, -47, 31, -46, 19, -24, 5, -19, -1, -42, 14, -44, 18, -7, -1, 15, 9, -35, 32, -44, 39, -46, 23, -16, 36, -25, 45, -34, 32, -8, 10, 5, 28, 0, 12, 11, 3, 20, -23, 6, -8, 16, 7, 17, -19, 32, -44, 3, -8, -21, -8, -5, 2, -29, 2, -3, -19, -14, 3, 7, -23, 10, 1, 3, 8, 13, -44, 20, 21, -16, 23, 3, 5, 10, -11, 32, -11, 13, -7, 30, 4, 16, -7, -6, -7, 14, -40, 4, -16, -26, 3, -1, 0, -6, 5, -50, 37, -27, 18, -16, -14, 6, -1, -4, -15, 8, -12, 14, 9, -22, 42, -10, 23, -11, 36, -15, 13, 30, 1, 47, -20, 33, -14, -12, 1, -20, -9, -9, -11, -13, 7, -37, 25, -47, 14, -13, 4, -12, 9, -32, 18, -48, -1, -35, -1, -7, 35, -20, 53, -4, 34, -7, 13, 19, 9, 30, 6, 45, -22, 23, -18, -6, -1, 3, -30, 14, -15, 9, -39, 10, -33, -13, -24, 10, 14, 14, -10, 2, -34, -4, -20, -21, -14, 40, -10, 17, -14, 28, -17, 37, -26, 69, -15, 38, 2, 21, -25, 37, -61, 13, -9, 5, -17, 18, -41, 22, -57, -1, -9, -13, 24, -10, 38, -5, 8, -16, -2, 1, 12, -25, -2, -13, 2, 2, -16, -19, 32, -30, 22, 20, -4, 12, 11, -17, 19, -17, -3, 20, -33, 65, -27, 32, -14, 8, -8, 13, -19, 9, -2, 7, 33, -40, 18, -18, -18, 6, -23, -11, -11, -28, 4, -11, -15, -14, -8, -5, 34, -6, 19, 1, -3, 9, -1, 5, 5, 14, -11, 40, -3, 18, -20, 16, -7, 2, -5, 9, -16, 9, -17, 0, -17, 4, -17, -3, 3, 8, -14, -19, 12, -21, -7, 1, -2, -8, 16, 3, -6, 35, -23, 33, -13, 11, 12, 3, -7, 26, -11, 19, -18, 23, -22, 39, -49, 39, -50, 11, -38, 26, -29, 10, -6, -22, 15, -8, 15, -37, 36, -43, 39, -43, 18, -26, 1, 11, 4, -2, 9, 7, 2, 7, 19, 1, 1, -4, 16, -5, 16, -9, -3, 4, -4, -1, -17, 0, 11, 16, -27, 12, -15, 15, -3, 0, 10, -3, -5, 12, -13, -7, -13, -31, -1, -3, -17, 15, -31, 25, -10, 15, -1, 2, 4, 10, 7, 32, -13, 7, -22, 2, -10, 16, 1, -15, 19, -24, 16, -18, -12, 18, -9, 9, 24, -8, 8, 11, 0, -31, 17, -55, 21, -43, 40, -40, 29, -54, 44, -34, 22, 11, 16, 7, 19, 21, -6, 2, -7, -16, 22, 0, -1, -4, 5, -8, 26, -42, 4, -6, -21, 35, -16, 8, 0, -22, -13, 11, -31, 7, -28, 4, 17, -12, -18, -2, -23, 23, -1, 19, 34, 7, 7, 35, -19, 11, -8, -17, 8, 4, 16, -16, -13, 9, -15, -5, -1, -6, 7, 3, 11, 1, -7, -24, 21, -31, 36, -3, -10, 8, 2, -17, 12, -24, 6, -3, 9, 15, 3, 13, -8, -13, -3, 6, -19, 14, -33, 16, -17, -5, -31, 3, -29, 24, -7, -6, 35, -20, -5, 34, -20, 25, -3, 10, 25, 8, 14, -13, 0, 1, 17, -33, 51, -38, 45, -32, 39, -3, -2, -24, 3, -18, 14, -4, -44, 2, -25, -15, -2, -23, 3, -2, -2, 20, -14, 8, -10, -4, 21, 11, -13, 32, -4, 8, 19, -16, -2, -2, -2, 14, -2, -1, 27, -26, 20, 11, -13, 10, -3, -7, 12, -13, -3, -30, -16, 10, -26, -3, -10, -2, -9, 15, -17, 1, -2, -7, 14, -8, 12, -3, -1, 2, 47, -26, 22, -19, 16, 2, 13, -3, 21, -10, 22, -32, 43, -24, 16, 0, 5, -2, 12, -44, -12, 1, -26, 1, -36, 5, 2, 9, -17, 20, -37, 14, -9, -5, 6, -3, -13, 23, -19, 25, -33, 6, 17, 10, 19, 15, -4, 12, 5, -9, 33, -20, 26, -9, 11, -2, 11, -21, -7, -13, -4, -8, -12, 0, -10, -9, 8, -33, 9, -26, 8, 6, -8, 12, 7, -8, 0, 7, -16, 25, -8, 27, 12, 0, 9, -9, 4, -17, 14, -16, 11, -8, 18, -2, 4, 2, -20, -18, 22, -16, -5, 3, -24, 13, -10, -12, -10, 2, -16, 33, -15, 21, -15, -4, -19, 29, -22, 18, 2, 20, 12, 18, -22, -7, -16, 7, -19, 14, 1, -17, 33, -22, 38, -8, 3, -3, 21, -17, 51, -43, 15, -22, -23, -6, -12, -14, 14, 9, 6, 4, -31, 3, -16, -14, 22, -22, 5, 13, -25, 17, -2, -18, 7, 1, 5, 36, -16, 23, 4, -15, 29, -20, 10, 1, 24, 17, 16, -4, -16, -37, -11, 1, -33, 27, -36, 17, -22, 2, -33, 16, -29, 32, -7, 24, -12, 14, -12, 22, -16, 15, -20, 19, 9, 14, 12, -1, -24, 13, -6, -1, 32, -19, 24, 12, -26, 4, -31, -38, 18, -16, -13, 3, -14, -1, 11, -15, 15, 0, -2, 30, -6, 35, -23, 10, -35, 5, -14, 17, -21, 20, 4, 7, 8, -5, -15, 20, -25, 26, 6, -3, 3, 5, -24, 26, -35, 4, 0, -6, 13, -23, 8, -25, 1, -2, 9, 3, 17, 4, 0, 13, -15, 3, -21, -16, 4, -5, -10, 11, -2, 7, 23, -22, 25, -19, 18, 25, -9, 14, -21, -7, 11, -24, 22, -12, -7, 6, 9, -33, 11, -20, 2, -9, 2, 3, -13, 12, -15, 23, -21, 16, -16, -2, 8, 13, -12, 18, -10, 16, -12, 20, -18, 18, -1, 21, -21, 20, -30, -6, 10, -2, 13, -6, -15, 6, 2, -1, 1, -19, 9, -15, -3, -11, 0, -5, 1, 5, 1, -4, -8, 1, -16, 23, 0, -23, 2, 8, -6, 38, -4, 2, 13, -17, 31, -4, -8, 22, -14, 0, 12, -22, 7, -7, 11, 4, -4, -12, -9, -22, 2, -17, -17, -11, 7, -17, 19, -24, 9, -8, -6, 29, -4, 10, 4, 4, 23, -1, 9, -6, -12, 23, 16, -6, 33, -29, 12, -7, -10, 17, -4, -18, 21, 0, -14, -2, -20, -21, 10, -28, 5, -18, -4, 0, -11, 1, 5, -17, 3, 9, 20, 6, 1, -7, 2, -7, 3, 9, -22, 29, 6, -1, 25, -10, 6, -1, 4, 12, 18, -13, 28, -11, 6, -15, -14, -22, -7, 5, -14, 1, -16, -12, -5, 5, -9, 4, -1, -14, 21, -10, -5, 0, -17, -7, 2, -10, 6, 11, 1, 37, -17, 6, 21, -24, 41, 2, 23, 0, 10, -18, 16, -26, 14, -21, -19, 18, -9, -14, -1, -9, -14, -3, -7, -10, 7, -7, 19, -11, 15, -25, -3, -6, 2, 8, -10, 4, 12, -3, 11, -2, -2, 5, 31, -9, 39, -21, 14, -23, 18, -16, -1, -3, -6, 0, 22, -9, -5, -17, -4, -12, 2, -3, -7, 10, -10, 7, -20, -19, -10, 0, -14, 32, -15, -18, 13, -9, 2, 17, -14, 6, 36, -9, 28, 1, 0, 17, -10, 5, 17, -8, 12, -2, 3, 2, -22, -6, -14, 6, 8, -11, -14, 2, -23, 25, -35, 3, -18, 1, -14, 22, -1, -12, -7, -9, 13, -4, 12, 4, -3, 18, 0, 1, 8, -14, 14, -2, 1, 17, -3, -14, 35, -17, 19, -14, -6, 1, -9, 18, -17, -4, -13, -2, -14, 10, -10, -6, 0, 3, 5, -12, -13, -3, -6, -6, 11, -13, -7, 13, -2, 6, 13, -7, 11, -5, 23, 1, 29, -17, 23, -10, 18, -16, 12, -20, 10, 7, -9, -5, -21, -9, 5, -13, -2, 0, -15, -11, 3, 0, -18, 5, -25, -2, 3, -2, -3, 4, 8, 14, -7, 15, 4, 8, 19, 9, 11, 7, -3, 14, -11, 1, 15, -35, 3, 3, -10, -16, 0, -15, 2, 3, -12, 27, -23, 32, -15, 10, -14, 3, -27, 10, -15, 12, -24, 7, 2, 9, -2, -2, -1, 3, 1, 1, 8, -4, 0, 6, -6, 1, 1, -1, 8, -11, 31, -27, 13, 4, -3, 5, -1, 0, 2, 9, 0, 12, -31, 4, -27, 1, -25, 20, -21, -14, 12, -14, 0, -5, -23, 18, -1, 15, 19, -5, 20, -8, 14, -7, 16, 3, 0, 8, 10, 0, -8, -10, 3, -8, 9, -12, 4, 15, -6, 2, -12, -29, -3, -16, -11, 35, -18, -1, -28, 7, -12, 0, 7, -5, 22, 10, 10, -4, 6, -13, 21, -23, 20, 8, -13, 11, 15, -6, -6, -22, -1, 3, 14, 7, 11, -27, 12, -17, -12, 8, -15, 3, -8, 12, -12, 5, -30, 12, -18, 9, -2, 3, 4, 15, 1, 5, -9, 0, -8, 24, -2, 21, 5, -4, -4, 14, -15, 0, -1, 3, 17, -5, 13, -19, -10, -4, -6, -4, -7, 18, -27, 8, 1, -12, -21, -13, 1, -9, 11, 1, -3, -1, 22, -21, 9, 6, -3, 20, -2, 17, 7, -12, 1, 4, 4, -9, 9, -20, 24, 7, -9, -3, -7, -6, 10, 7, 3, 9, -2, -3, -4, 1, -19, -8, -16, 0, -12, 0, -25, 4, -22, 10, -9, 0, -3, 15, -1, 8, 11, -15, 10, 13, 1, 22, -5, 15, 1, 24, 6, 0, -6, 5, 5, 10, 8, -1, -11, -14, 3, -31, 2, -22, -4, -8, -15, -2, -31, -12, 6, -7, 5, 2, 3, -4, 19, 3, 4, 7, 7, -8, 31, -6, 26, 1, -2, 2, -3, -10, -4, -4, 9, 3, 12, -16, 16, -9, -1, 5, 4, -7, 13, -17, 0, -11, -13, -22, 1, -9, 4, -7, 7, -10, 5, -1, -6, -3, -21, 7, -10, 18, -3, 1, -7, -11, 11, -8, 12, 20, 3, 13, 16, -1, 3, 13, -3, 23, 16, -3, 15, -14, 12, -6, -8, -28, 0, -33, 4, -11, -12, -13, -21, -17, -16, -5, -12, 16, -7, 15, -6, -5, 3, -9, 21, 17, 13, 14, 11, 21, -12, 31, -18, 7, 12, 8, 9, 7, 1, -3, -7, -14, 17, -35, -10, -2, -18, -8, -10, -20, -22, 2, -10, -3, 1, -1, 4, -5, 11, -20, 11, -6, 27, 7, 18, 8, -1, 2, 3, 11, -9, 5, 5, -7, 29, -6, 20, -21, 23, -15, 19, -19, 2, -22, 11, -26, -7, -10, -30, -1, -3, -6, 15, -22, 16, -7, -9, -2, -7, -5, 11, 17, -13, 2, 8, -5, 6, 27, -6, 12, -6, 4, 15, 3, 14, -3, -12, 11, -2, 6, 5, 4, -6, -12, 0, -32, 2, -22, 22, -12, -5, -7, -11, -7, 6, -1, -3, -3, -16, 2, -1, 0, 0, -7, -2, 1, 12, -4, 5, 20, 1, 16, -2, 14, -1, 19, 8, 29, -8, 7, -14, -2, 3, -13, 8, -40, 22, -18, 2, -14, -8, -11, -8, 12, -21, -1, -10, -12, -6, -4, -14, 6, -19, 7, 14, 1, 11, 11, -11, 25, 1, 14, -5, 31, 0, 22, 4, 1, 3, 6, -3, 4, -2, -20, -7, -26, 1, -12, -7, -10, 2, -1, -5, -7, -8, -10, 6, -7, -6, 10, -17, 6, 3, 15, -8, 15, -7, 12, 1, 9, -4, -2, 10, 9, -1, 10, -4, 9, -8, 17, 0, -13, -7, -2, -11, 3, -2, -15, -4, -11, -5, -9, 1, 8, -10, 8, -8, -6, -18, 21, -19, 26, -19, -1, -11, 10, 4, 12, -10, 16, -10, 17, 8, 13, -1, 17, 1, 5, -1, 11, -8, 9, 16, -17, 3, -26, -17, -14, 6, -17, 4, -20, 0, -1, -6, -4, 2, -15, 13, -3, -1, 0, -2, -8, 11, 7, -3, -8, 5, 14, -1, 28, -19, 13, -4, 8, 1, 11, 7, 6, -8, -2, -13, -10, -22, 6, 11, -1, -1, -5, -13, 18, 3, -10, 9, -17, -8, 9, -9, 1, -17, -4, -16, 18, -6, 15, -10, 17, 5, 0, -5, 0, -11, 12, 15, 4, 8, 5, -4, 0, -2, 3, -17, -2, -1, 11, -6, -7, 2, -33, 23, -6, -1, -2, -2, -1, -8, 3, -29, -2, -34, 16, -3, 16, 1, 10, -12, 23, 0, -3, 16, 12, 19, 23, -1, 8, -26, 16, -32, 26, -13, 2, -11, 5, -1, -15, -9, -16, 7, -6, 14, -15, 5, -10, -7, -9, -9, 6, -17, 13, 18, -5, -3, -4, -4, -18, 28, -6, 13, 17, 24, -2, 9, -14, 1, -11, 7, 17, 1, -15, 10, -23, -4, -12, 5, -20, 17, -10, 6, 0, -9, 4, -8, -15, 6, -16, 7, 9, 3, 6, -12, -17, 0, 4, 13, 22, -4, 10, -8, 7, -12, 5, 5, 1, 11, 2, 10, -3, -2, 3, -10, -5, -7, -4, -18, 17, -2, -14, -16, -7, -10, -3, 6, -1, 14, -11, 15, -18, 2, -6, 0, -1, 0, 20, -17, 1, 6, 2, 6, 12, -3, 7, 25, -5, 17, -14, 0, -6, 0, -2, -5, -1, -10, 8, 2, -9, -19, -7, -17, 5, 3, -7, 4, -15, -5, 9, -12, -1, -5, 3, -5, 26, -2, 3, -4, 5, 3, 7, 10, 5, 6, 6, 26, -17, 0, -1, 3, -3, 10, -7, -7, -9, 11, -18, 0, -16, -6, -5, 3, 7, -14, -14, 0, -21, 14, -8, -1, -12, 2, 1, 2, -3, -1, -3, 18, 5, 5, 9, 12, 7, 18, 8, 5, -25, 16, -15, 16, -7, 9, -22, 1, 14, -13, -5, 2, -6, -8, 13, -17, 6, -16, 1, -5, -14, -6, -6, -15, -2, 9, -9, -18, 15, -19, 12, 7, 4, 8, 14, 15, 6, 10, -3, 9, -7, 23, -17, 21, -20, 7, 0, -9, 8, -10, 1, 4, 2, 3, -9, -9, -15, -6, -21, -16, -6, 0, -11, 19, -8, -9, 5, -6, 0, 5, 14, 7, 1, 12, 8, 7, -5, 12, 8, -4, 19, 4, -7, 2, 3, -12, -8, -1, 0, 5, 7, -5, -8, -22, -8, -21, -2, -9, 10, -20, 13, -6, 8, -17, -9, -6, 2, 5, 8, 6, -3, 10, -9, -2, 15, -6, 20, 7, 11, 10, -3, -4, -8, 25, -25, 18, -12, 17, -6, 20, -22, -1, -17, -10, 5, -10, 9, -13, -9, -6, 10, -25, -5, -2, -5, 13, 2, -5, -8, -10, 11, -27, 10, -4, 11, 0, 33, -4, 10, -14, 1, 12, -2, 27, -8, 6, 11, 9, -12, -4, -10, -13, 12, 5, 1, -10, -14, -15, -8, -7, -9, 3, -5, 10, 3, -11, -12, -13, -3, -3, 3, 2, 9, 17, -6, 25, -3, -3, -8, 19, 3, 30, -10, 12, -22, 7, -5, -10, -3, 21, -8, 12, 6, -5, -13, -13, -9, -9, -1, -23, 13, -17, 15, -22, -11, -18, 8, -14, 20, 1, 4, -5, 3, 3, 5, 11, 1, 2, 27, 1, 10, -7, -8, -2, -2, 7, -1, 17, -5, 24, -7, 5, -10, -20, -6, 5, -4, -5, -1, -18, -5, -14, -1, -20, 1, 7, -7, 12, -4, -2, -4, 2, 8, 0, 7, 1, 6, -2, 18, -5, -7, 4, 3, -2, 13, 4, 0, 2, -3, 2, -10, -6, 1, -6, 6, -7, -3, -21, -2, -12, 5, -1, -9, 7, -3, 13, 5, 5, -8, 0, -8, 19, -5, 13, 13, -7, 3, 0, -10, 0, -8, 20, -8, 13, -20, -5, -7, 3, 5, -7, 2, -5, -4, -14, 11, -23, -13, 2, -1, 12, 13, 5, -6, 23, -9, 9, -6, -9, 18, -13, 16, -3, -7, -17, 3, -13, 12, -9, 4, 0, 0, 13, -18, -1, 3, -13, 20, -5, 1, -20, 15, -23, 18, -4, -8, 5, -7, 16, 4, 6, -3, 7, -21, 19, -17, -7, 9, 5, 3, -5, -3, -16, -9, 25, -9, 12, -5, 10, -5, 9, -4, -6, -3, 4, 10, -2, 11, -12, -2, -14, 8, -23, -5, 0, -8, 9, -2, -11, -3, -9, 9, 2, 2, 4, -5, 7, 11, -16, 0, -6, 7, 6, 25, 5, 6, -4, 3, 4, 3, 2, -8, -3, 5, -1, -11, -4, -9, -3, -15, 10, -12, -5, 11, -4, -7, 6, -29, -5, 6, 11, 3, 9, -18, 13, -14, 19, -1, -2, 4, 5, 12, 1, 5, -8, 3, 1, 20, -6, 2, 3, -16, 10, -10, -18, -11, -7, -7, 9, -4, -8, 9, -15, 13, -13, -3, -7, 3, 8, 11, -6, -16, 1, -8, 20, 4, 15, -5, -3, 11, -5, 6, 0, -5, 10, 13, 0, -6, -11, 0, 11, -11, 10, -7, -8, 1, 16, -9, 2, -22, -9, 0, 4, 5, -12, -22, 2, -8, -8, 14, -16, 0, 13, 0, 9, -7, 2, -1, 7, 8, -3, -3, 2, 15, 5, 10, -7, 12, -4, 22, -4, -3, -12, -2, -15, 8, -2, -22, 7, -10, 5, 12, -20, -9, -11, -2, -12, 2, -9, 5, -3, 11, 7, -9, 4, -4, 24, -7, 21, -15, -3, 2, 14, -1, 5, 18, -12, 13, 3, 5, -10, -11, 0, -8, -2, -4, 2, -15, 9, -10, -16, -9, -7, 0, -1, 3, -8, -10, 5, -8, 4, -3, 8, -2, 20, 1, 6, -4, -9, 4, 14, 7, -1, 3, -5, 18, -7, 20, -6, -10, 8, 1, -2, 3, -4, -5, -3, -6, 0, -16, -7, 12, 0, -17, 4, -31, -7, 1, 1, -4, 8, -11, 6, -1, 11, -5, -7, -4, 2, 4, 15, -3, 21, -5, 20, 3, -12, 21, -1, 10, 5, 6, -20, -1, -18, 2, 3, -4, -5, -1, 6, -2, -11, -17, -15, -13, 0, 6, -18, 7, -18, 7, -7, 6, 7, -10, 18, 16, 2, -1, 3, -11, 6, 14, 1, 15, -2, 29, -8, 17, -14, 2, -19, 12, 8, -6, -1, -23, 6, -11, 7, -19, -18, 0, 1, -8, -8, -4, -20, 8, -8, 4, 10, -12, 13, 0, 18, -10, -3, -4, 6, 4, 17, 7, -2, 18, -9, 14, -10, -4, -11, 4, 3, 23, -17, -6, -2, -7, -7, 9, -10, 1, 2, -4, -14, -7, -6, -8, -4, 7, 2, -3, 3, 0, 13, -10, -4, -9, -6, 18, 11, -4, 16, -8, -4, 1, -1, 7, 3, 3, 3, 10, -15, -2, -9, 9, 0, 2, 2, -9, 12, -7, 0, -23, -7, -19, 2, -1, 0, 4, -15, 7, 3, -3, 0, 9, -12, 19, 4, 8, -13, -6, 5, -1, 14, 10, 9, 13, -3, 16, -18, 13, -18, 7, -10, 13, -6, -11, -3, 7, -23, -6, -11, -21, 9, -1, 4, -3, -16, 0, -12, 7, 14, -5, 15, 0, 6, -5, -3, -9, 9, 4, 10, 4, -2, -7, 10, -1, 10, -6, -14, 15, -4, 13, -4, -4, -14, 5, -2, 4, -9, 3, -14, 2, 3, -10, -1, -9, 0, 3, -6, 12, -16, 0, 4, 10, -25, 6, -5, 2, 8, 3, -2, -4, 15, 4, 7, 2, -1, -6, 10, 11, 2, -2, -14, 6, -3, 0, -3, -9, -10, 1, -1, -15, 9, -29, 9, -10, 7, -3, -3, -10, -2, 14, 4, -6, 0, 1, 12, 4, 18, -15, 19, 1, 15, 1, 1, 3, -10, 8, -1, 7, -30, 8, -19, -2, -5, -9, -10, 0, -1, 6, -4, -12, 1, -18, 10, -1, -12, 2, 7, 12, 11, 0, -4, -1, 6, 10, 17, -8, 1, -12, 5, -2, 1, -7, -1, 4, 3, -3, -1, -18, 8, -9, 0, -2, 8, -12, 12, 7, -5, -2, -16, -7, 9, -5, 11, -9, -4, 3, 1, -9, -1, -2, -6, 7, 12, 0, -8, 9, -10, 3, 0, 2, -3, 11, 14, 4, 3, -12, 3, -3, 2, 12, -4, -2, -2, 9, -21, -5, -28, -6, -10, 6, 7, -6, -3, -24, 7, -11, 10, 0, 8, 13, 10, 6, -7, -2, -5, 7, -1, 9, 18, -2, 12, -4, 7, -26, 13, -6, 19, 6, 6, -5, -16, -6, -8, -18, -2, 1, -11, 3, 4, -16, -8, -10, -3, 2, -3, 5, 5, 0, 11, 0, -14, 0, 1, 14, 11, 13, 0, -2, 5, -1, -4, -2, -4, 5, 21, 3, 14, -5, -22, 5, -11, -3, -6, -3, -11, 0, -5, -13, -10, -18, 3, 9, -10, 2, 3, -11, 11, -11, 5, -19, 23, -1, 20, 18, 4, -3, -6, 9, 4, -3, 8, 4, 6, 2, 5, -14, -6, -3, 2, -6, -4, -3, -11, 0, -5, 0, -21, -2, -10, 11, 5, -4, -5, -5, -8, 10, -10, 4, -1, 6, 12, 9, 2, 8, -20, 8, -2, 11, -11, 1, -4, 5, 6, -6, 6, -14, 14, 4, -2, 12, -3, -10, 8, -5, -15, -9, -1, 5, 8, -3, 0, -23, -9, -11, 4, -12, 3, -4, 4, 1, 15, -12, 3, 13, 2, 5, 8, -8, 7, 11, -3, 17, -11, 5, 3, 19, 13, 3, -11, -11, -2, -9, -7, -4, -24, -1, -17, -3, -17, 0, -15, 2, -1, -5, -4, 3, 2, 2, 11, -4, 3, -6, 11, 8, 3, 6, 3, 7, 7, 6, -6, 2, 0, 14, 14, 3, 8, -6, 4, -3, 6, -13, -2, -9, -4, 5, -13, -5, -21, -1, -6, -1, -5, -14, 8, -7, 5, -7, -17, -11, 7, 3, 20, 7, 1, -3, 4, 5, 14, -3, 5, 3, 10, 8, 6, -6, -2, 6, 3, 7, -6, -3, -3, -6, -1, -27, -11, -17, 0, 11, 7, 1, -7, -9, -13, 5, -11, 0, -10, 15, 2, 5, -2, -5, 1, 6, 6, -6, -5, 6, 2, 5, 3, 10, -16, 11, 8, 18, 3, 13, -11, 7, 5, -7, -6, -20, 15, -1, 10, -1, -13, -17, -11, -3, -13, -4, -14, -3, -2, -6, 6, -28, 9, -8, 10, 0, 12, -2, 10, 9, 1, 3, -6, 5, 17, 24, 18, 3, 4, -9, -4, 2, -8, -4, -2, -11, 1, -8, -12, -9, -10, 5, 0, -7, -9, 7, -18, 6, -10, -12, -1, -1, 13, 1, 18, 2, -3, 4, 3, 3, -3, 3, 10, 9, 7, 5, -8, -7, 0, 3, -7, 7, -2, -2, 5, -10, 2, -5, -3, -1, 4, 1, -2, -10, 4, -9, -5, -12, -18, 3, 6, -3, 3, -15, -1, -13, 6, -2, 8, 0, 8, 16, -2, 17, -4, 8, 3, 23, -1, 11, -8, 10, -4, -5, -3, -13, -2, -1, -2, 2, -9, -13, -13, -2, -11, -2, -20, -5, 0, 3, 2, -1, -10, 1, 8, 3, 9, 6, 4, -3, 13, 3, 4, 11, 2, 11, 8, -2, -1, -2, -2, -2, -1, -21, -1, -14, 8, 6, -8, -10, 2, -16, 4, -3, -1, -10, 7, -1, 4, -4, -12, 3, -2, 13, 2, -3, -9, -2, 6, -7, 8, -8, -5, 12, 7, 8, -3, 6, -1, 16, 0, 7, -8, 3, -7, -1, 0, -6, -4, -8, 6, -1, 4, -19, 2, -3, -8, -3, -12, 4, -6, 2, -7, 1, -13, 2, 9, -1, 17, -19, 3, -3, 23, 9, 6, 3, 6, 6, -5, 11, -11, 1, 0, -5, 6, -6, -4, -5, -7, 3, -4, -14, -9, -7, -1, 5, -11, 4, -19, 14, -4, 3, 4, 2, 0, 9, -2, -3, 2, -2, 10, 15, -3, 14, -6, -4, 6, 1, -8, 11, -9, 4, 3, -9, 2, 2, -2, 2, -2, -9, -2, -2, 1, -6, -6, -22, -16, -10, 12, 0, 5, -8, -2, -4, -2, 5, -1, 7, 7, 9, 1, 7, 6, -1, 10, 11, 5, -3, 8, 1, -1, 8, -15, -6, -10, 12, 0, 2, -5, -9, -12, -7, -4, -14, -4, 0, -1, 5, -7, -8, -12, 0, 2, 16, -3, 11, -4, 16, 11, 2, -3, 2, 8, -1, 7, -13, 4, -3, -1, 3, -10, -2, -11, 3, 2, 3, -7, -10, -5, -10, 12, -8, 5, -7, 15, 1, -10, 7, -16, 1, 3, 4, -5, 7, -7, 4, -2, -1, -8, 0, -2, 17, 10, -2, 6, -5, 3, 10, -7, 2, -3, 4, 5, 5, -3, -8, -8, -1, 1, 7, -5, -11, -2, -10, -4, -15, -7, -10, -2, 2, -4, -10, -8, 0, 2, 6, 3, 2, 3, 10, 14, 8, 7, 3, 5, -5, 20, -6, -1, -2, 0, 1, -2, -2, -8, 3, -3, 10, -14, 3, -3, -2, 0, -5, 0, -15, 4, -2, 0, 4, -7, 3, -8, 7, -14, -2, -6, 4, 2, 3, -10, -2, 5, -3, 12, -2, -5, -9, 1, 4, 1, 11, -12, 15, 5, 20, 10, -5, 1, 5, 3, -13, 6, -16, 5, 1, -5, -8, -3, -14, -6, -2, -5, -8, -17, -9, 3, -6, -2, -3, -3, 1, 14, 2, 4, 5, 3, 8, 7, 12, 0, 11, 4, 16, 2, -3, -9, -1, 1, -1, -3, -6, -14, 4, -6, 2, -14, -9, -11, -1, 0, 0, -5, -6, -10, 5, -5, 2, -3, 2, 2, 17, -2, -1, -3, 3, 11, 1, 10, 2, 7, 6, 5, -5, -3, -3, -2, 7, 2, 1, -18, -5, -2, -3, -5, 0, -2, 0, 8, -9, -10, -15, -7, -2, -1, 6, -8, 16, -10, 13, -4, 2, -4, 4, 7, 9, 6, -5, -2, 8, -1, 11, -6, -1, 5, 8, 0, 9, -20, 0, -9, 4, -3, 1, -4, -11, 2, -6, 0, -12, 0, 1, 5, -2, 1, -7, -4, 3, -1, -10, 3, -3, 7, 4, 8, -9, -6, -10, 0, 0, 2, -4, 6, 9, 10, 2, 0, -1, 2, 14, 3, 7, -7, 2, -2, -2, -6, -9, 2, -3, 6, -3, -7, -9, -10, -2, 2, -1, -11, 2, 1, 7, -4, -7, -19, 3, -1, 6, 6, 6, 6, 0, 6, 7, 3, -1, 3, 8, 3, 4, -10, -5, -7, 5, -4, -14, 2, -8, 5, -2, 2, -16, -4, -11, 2, 4, -1, 2, -1, 0, 5, 4, -12, 3, 9, 7, 13, -3, -7, 2, 6, -1, 7, -1, -1, 5, -5, 7, -11, -9, -13, 2, 5, 2, -2, -7, 5, 4, -4, -2, -15, -4, 3, 0, 0, -5, 2, -7, -1, 9, -2, -1, 5, 1, 1, -4, -5, -4, 6, 8, 7, -5, 4, -7, 4, 0, 1, -6, -5, -2, 5, -1, 0, 1, 1, 3, 9, -4, -2, -4, -9, -1, 4, -17, 1, -13, 11, -1, 6, -9, -1, 5, 1, 8, -3, 4, -5, 1, 7, -5, 1, -3, 5, 3, 4, -7, -11, -7, 1, 5, -13, 11, -11, 1, 3, 6, -9, 6, -5, -7, 4, -13, 5, -7, 10, 5, 6, -15, -1, 6, 4, 18, -7, -7, -3, -4, 2, -5, 3, -4, 9, -4, 3, 3, -3, -10, 0, -1, 2, 5, -3, 7, 3, 2, -6, -11, -2, -1, 4, -5, 4, -5, 0, -5, 5, -5, -4, 2, 4, 2, 5, -8, -13, -3, 0, -1, -2, 4, 6, 9, 1, 3, -7, -1, 1, 12, 1, 1, -1, -5, -1, 2, -8, -9, -7, -2, 3, 10, -6, -7, -12, -7, -4, -5, 6, 0, 10, 5, 7, -4, -2, -8, 10, 5, 9, 4, -1, -1, -1, -1, -1, -2, -3, 3, 9, -2, 9, -14, -13, -8, -10, 1, 1, 3, 3, 1, -3, -12, -5, -7, 1, 6, 6, -2, -7, -3, -3, 2, 2, 4, -9, 14, 8, 11, -3, 5, -11, 1, -1, 5, 3, 8, 2, 8, -2, -6, -13, -10, 0, 4, 3, 4, -3, -9, 1, -5, -5, -6, 1, -2, 2, -10, -6, -15, 1, -5, 4, -1, 2, 2, 4, 10, 4, 2, -13, 0, 4, 8, 17, 2, 5, 4, 2, -6, 5, -5, 0, 8, -2, -1, -5, -4, -5, -1, -5, -4, -5, 0, 0, 1, -9, -15, -3, -12, 1, -1, -7, 10, 2, 5, -1, 2, -6, 2, 2, 10, 10, -1, 2, -2, 4, 5, 0, -6, 12, 5, 3, -1, -8, -8, -4, -4, 3, -11, 0, -1, -1, 0, -2, -14, -6, -9, 2, 1, 7, -4, 3, -1, 0, -3, 1, 2, 7, 5, 4, 3, -2, -3, 1, 6, -1, 6, -11, 7, 2, -6, 2, -4, 0, 2, 3, -7, -9, 3, 0, 4, -6, 0, -21, 0, -5, -1, 0, -1, 1, -6, -1, -1, 0, -7, 5, 7, -2, 8, -4, -1, 3, 9, -6, 10, -6, 7, 9, 10, 9, -6, 5, -14, 6, -5, 1, 2, -3, 0, -9, -10, -14, -2, -3, 6, -8, -15, 3, -9, 0, -3, 0, -6, -1, 3, 9, 10, 3, 3, -10, 6, 1, 3, -1, 9, 12, 4, 4, -9, -7, -5, 8, 6, 1, 1, -4, -5, -5, -1, -11, -3, -4, 1, -1, 1, -10, -7, -2, -3, -4, -3, -6, 11, 5, 3, 2, -8, -5, -2, 3, 9, 13, 5, 4, 4, 0, -5, -1, -5, 9, 2, 3, -9, -4, 3, -6, 2, 1, -9, 5, -2, 3, -2, -9, -8, -15, -5, -3, 3, -13, 11, 6, -3, 1, -6, -6, -1, 6, 4, 6, 7, 1, 5, 0, 8, -6, 7, 2, 6, 2, -5, 0, -3, -1, 3, -7, -1, -3, 5, 7, 6, -18, -10, -11, -7, -3, 10, -4, 3, -4, -8, -5, -12, -3, -4, 12, 10, 2, -4, 6, 3, 1, 2, 0, -3, 3, 7, 7, -5, 2, -4, 1, 3, 11, 2, 3, 4, -2, -7, -5, -17, -11, 4, -3, 5, -7, -7, -6, -1, -8, -5, -5, 1, 7, 1, 2, -1, -9, 7, 1, 7, 3, 3, 6, 9, 6, 1, -6, -4, 2, 5, 7, 4, -2, 1, 3, -11, -1, -16, -2, -6, 1, 3, -8, -15, -11, 4, -1, 9, -2, -5, 0, 6, 0, -7, 0, -8, 4, 2, 6, 2, 0, 2, 6, 2, -2, 4, -2, 4, 14, 2, 2, -6, -6, -3, 4, -4, -1, -4, 1, -3, -6, -1, -13, -1, -2, 7, -8, -7, -10, 0, 4, 3, -8, -3, 1, 4, 6, 4, 6, -3, 5, 3, 4, 0, 6, 1, 4, 7, -3, -10, 8, -1, 9, -1, 1, -11, -7, -3, -3, -6, -8, -9, -6, 1, -3, -6, -6, -5, 0, 0, 2, -3, 0, 6, 4, 3, 2, 7, 4, 11, 14, 5, -1, -5, 1, -2, 7, 3, 0, 1, 2, -5, -7, -10, -12, -10, -5, -5, -6, -6, -9, 1, -8, -2, -1, -9, 1, 8, 2, -5, -2, -5, 0, 5, 6, 6, 7, 8, 10, 2, 0, -3, -1, 2, 13, 3, 0, -6, 0, 1, -3, 0, -12, -2, 4, -4, 4, -8, -11, -1, -2, 1, -1, 2, -12, 3, -6, 1, -12, -7, -7, 3, 0, 9, 0, 1, 6, 1, -1, 2, 1, 2, 8, 9, -3, -1, 0, 7, 3, 8, -1, -4, -1, 1, 3, -9, -1, -17, -3, -2, -4, -4, -3, -4, -6, -11, -15, -2, -5, 6, 10, 1, 3, -1, -3, 13, 7, 1, 6, 4, 4, 9, 5, -3, -5, 9, 3, 5, -3, 1, -3, 3, 0, -7, -5, -7, 0, -5, 0, -1, -15, -11, -4, -5, -10, 2, -7, 5, -4, 1, -9, 2, 1, 8, 7, 10, 2, 2, 0, 4, 3, -2, 0, 4, 2, 6, 8, -2, 4, 4, -2, 5, -3, -6, 3, -3, -5, -9, -8, -11, -5, -1, -1, -5, -7, -5, -8, 0, -3, 5, -7, 11, 1, 0, 2, -3, -1, 3, 9, 6, -3, 8, 1, 11, 2, 8, -3, -3, 6, 2, 1, 2, -7, -3, -2, -4, -8, -3, -3, 5, -10, -10, -4, -12, -2, 3, -5, 3, -6, -8, -2, 5, -3, 0, 1, 4, 8, 4, 5, 0, 4, 8, 1, 7, -3, 0, 3, 4, 4, -5, -2, -7, -3, 0, 5, -5, -9, 3, -2, -1, -2, -5, -1, -4, -3, -11, -4, -5, -6, 0, 5, 0, -5, 5, 3, 8, -1, 3, 3, 2, 5, 7, -4, 3, 1, 3, 10, 2, -7, 1, 0, 6, -4, -3, -5, -7, -2, -4, -3, -6, 0, -10, 4, -6, -4, -7, -2, 1, -4, -1, -3, -1, 2, 6, 2, 4, -2, 2, 4, 2, 5, -3, 4, 2, 1, 0, 8, -3, 2, 5, -5, 3, -5, -2, 5, -5, 3, -1, -4, -3, 4, -10, -5, -7, -4, -4, 0, 0, -7, -1, -1, 2, 1, -2, -12, -4, -1, 0, 4, -5, 2, 0, 3, 12, 11, 3, 11, -1, -3, 6, -6, 1, 1, 7, 6, -7, -1, -7, -4, -4, -7, -8, -1, -6, -6, -2, -3, -5, 0, -4, 8, -7, 1, 4, -3, 6, 1, -7, 3, 5, 6, 5, 13, 2, 2, -4, 4, -3, 1, 4, -4, 2, -3, -10, -10, -7, -2, -2, -2, 0, -6, -2, 1, -3, -4, -2, -5, -2, 7, 1, 6, -5, 6, -1, -1, 2, -3, 4, 11, 2, -1, 2, -7, -5, 8, 0, 3, -3, -5, -1, -2, 3, 1, -4, 4, 7, 0, 2, 3, -3, 0, 1, -5, -15, -5, -3, 1, 3, -3, -11, -4, -7, 1, -2, -1, -1, 0, 1, 1, -5, -1, 3, -2, 7, 1, -4, -1, 0, 4, 5, 3, 3, -1, 8, 11, 1, 4, 1, -5, 7, -6, -4, -2, -4, -2, 3, -8, -3, -13, -6, 3, -3, -7, -4, -7, 3, 3, -3, 2, -1, 1, -4, -2, -2, -5, 1, 11, 9, -2, 6, -3, 7, 7, 1, 1, -7, 2, -3, 1, 4, -4, -4, 5, 1, 0, -3, -6, 2, -3, 0, -8, -12, -6, -2, -3, 6, -1, -9, 0, -1, 1, 3, -2, -1, 0, 1, 6, 0, -3, 5, 1, 6, 1, -1, 4, 1, 7, -3, -1, -1, -4, 4, 14, -1, -1, 2, -4, -1, -6, -8, -8, -3, -2, 2, -9, -5, -7, -12, 5, 0, -3, -4, -3, 5, 4, 3, -2, -6, 4, 7, 3, 5, 7, -3, 8, 0, -5, -1, -1, 11, 10, 3, 4, -8, -3, -3, 1, -3, 0, -4, -3, 1, -7, -8, -16, -7, -6, -2, 3, -7, -2, 1, -4, 0, -5, -5, 1, 5, 10, 5, 0, 3, 0, 1, 13, 0, 5, 9, 6, 8, -1, -4, 0, -3, 6, 4, -4, 0, -3, -15, -2, -12, -15, -3, -6, 2, 1, -3, -4, -9, -9, -3, -3, -2, 3, 4, 9, 0, 2, 1, 2, 14, 5, 3, 8, 2, 7, 4, -4, -4, -1, -9, 9, -5, -1, -7, -10, -2, -7, -4, 0, -5, 2, 5, 1, 0, -5, -5, -1, -1, -3, 4, -8, 5, 3, -4, 4, -5, -3, 9, 4, 8, 0, 0, 2, 0, -2, 0, -2, -7, 12, -1, 5, -4, 2, -3, 0, 2, -2, -4, -2, 2, -5, 3, -7, -9, -4, -3, -2, -6, -6, -2, -6, -1, -7, -8, 1, 3, 6, 10, 4, 5, 0, 5, 8, 1, 3, 8, 5, 11, 12, -7, 4, 0, -3, 2, -1, -8, -7, -4, -2, -6, -9, -6, -13, -4, -1, 0, -9, -5, -3, -4, -2, 3, 1, 1, 9, 4, 2, 6, -1, 3, 6, 2, 0, -3, 3, 2, 6, 3, -1, -4, 4, 1, 2, 2, -5, -8, -1, -3, -1, -9, -4, 1, -5, 5, -7, -4, 0, 3, -10, 3, -3, -5, 1, 5, 4, 1, -5, 1, -5, 4, 1, -6, 0, 5, 8, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3, 3, -10, -6, -8, -2, -1, -3, -6, -6, -5, -6, -6, -5, 5, -3, 5, 6, -2, -1, -1, -4, 6, -2, 6, 6, 2, 12, 8, -2, 3, -6, -2, 5, 4, -3, -2, -5, -4, -7, -6, 1, -5, 2, 2, 0, 1, -7, 0, -4, -2, -1, -2, -5, 7, -5, -2, -3, -2, -3, 4, 4, 9, 0, 1, 1, -5, -3, -4, -4, 4, 3, 6, 1, -2, -2, -7, 4, 1, 1, -3, 3, -1, 2, 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5, -5, -1, 5, 5, 2, 2, -3, 4, 3, 4, 6, 3, -1, 10, -4, -3, -2, -3, 0, -4, 0, -2, -2, 0, 2, -5, -2, -5, -9, 8, -2, -1, -1, -3, -3, -2, -6, 2, 1, 2, 9, 0, 1, 4, -5, 2, 4, -6, -1, 2, -1, 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3, -4, -2, 0, 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6, -2, -6, -1, -3, 2, 4, 1, -1, 0, 1, 1, 3, -1, 5, -1, 7, 6, 1, -2, 0, -6, -2, -2, -8, -2, -2, -3, -5, -5, -8, -3, -1, 5, -3, 1, 2, 1, 2, -3, -2, -3, 2, 6, 2, 6, 0, 0, -2, 9, -1, 3, -2, 3, 0, 0, 0, -6, -6, -1, -5, -7, 1, -3, -6, 2, -2, -1, -5, -2, 1, 4, 2, 2, -3, -1, 6, -2, 2, 4, -3, 2, 2, 2, -3, 1, 0, -4, 2, -1, -2, 3, 1, 1, -1, -5, -8, -2, -5, 0, 1, -6, 3, -4, 2, 3, -6, 3, 0, 2, -2, -1, -4, -2, -4, 4, 0, -3, 0, -6, -3, 10, -3, 3, 0, 4, 7, 3, 0, 5, 1, 5, 1, -3, -2, 0, -6, 3, -1, -7, -5, -7, -1, -2, -2, -2, -3, -2, 2, -2, -1, -3, -3, 2, -2, -6, -3, -3, 4, 3, 2, 0, -1, 5, 5, 8, 2, 2, -2, 4, 0, 5, -5, -3, -1, -3, -3, -6, -4, -2, 3, 0, -2, -2, -5, 5, -1, 3, -1, -1, -3, 0, 0, -5, -4, -3, -2, 5, 0, -4, -4, 1, 2, 6, 0, -3, -1, 2, 3, 7, -3, 0, -4, -2, 4, 3, 0, 1, 3, -3, 1, -7, -4, 0, 1, 1, -4, -4, -4, -9, -1, -2, -3, -2, -3, -3, 4, 3, -1, -4, 2, 4, 4, 3, 2, -1, 0, 9, -1, 4, 2, 7, -1, 6, -2, -2, -5, -1, -9, -2, -2, -6, -1, -1, 1, -8, -6, -5, -1, -1, 1, -4, -5, 3, 1, 5, 3, -3, 0, -2, 7, 0, 1, -2, 3, -1, 5, -1, -5, 7, -1, 3, 2, -5, -6, -2, 4, 2, -1, -3, -1, -1, -1, -1, -2, -4, 1, -5, 3, -1, -3, -5, 2, 6, -6, -1, -5, -4, 4, -1, -1, -2, -1, 2, 0, 3, 1, 4, 2, 7, -1, 2, 0, -2, 1, 4, -5, -3, -7, -2, 0, -1, -1, -3, 0, 0, -2, -6, 2, -4, 2, -4, 1, -7, -2, -1, 5, 3, -2, -7, -4, 1, 6, 4, 5, 1, 4, 0, 5, 1, -1, 2, 0, -3, -3, -5, -6, 3, -1, 5, -1, -2, 1, 1, 4, 2, -6, -3, -4, -3, 2, -2, -8, -3, -6, -4, -2, -11, 0, 0, 1, 6, -3, -2, 1, 2, 10, 8, 4, -2, -1, 2, 2, 1, -2, 3, 1, 5, 3, -1, 0, -4, 4, -7, -2, -7, -8, -4, -3, -2, -7, -7, -3, -1, 5, -2, 0, -7, 2, -1, 3, 1, 4, 6, 5, 8, 3, 2, -1, 3, -3, 0, 0, -5, -1, 1, 1, -5, -3, -2, 6, 4, 5, -4, -8, -4, -3, -2, -5, -4, -4, -4, 2, -3, -2, -4, -4, -4, 6, 1, 0, 1, 3, 3, 5, 2, 1, 0, 6, 2, -1, 1, -3, -3, 2, -1, 0, 1, 3, 1, 4, -4, -5, -10, -8, 1, -6, -3, -4, -6, -3, 0, 2, -3, -1, 2, 0, 8, 1, 4, 4, 3, 6, 3, 1, 3, 5, 1, 2, -4, -7, -3, -3, 3, 0, -7, -5, 0, -3, -1, -2, -4, 0, -5, 1, -6, -1, -5, -3, 1, 4, -1, -3, 3, 3, 5, -1, -2, 2, -1, 2, 1, -1, -5, 5, 1, 2, 2, -4, 0, -1, 3, 0, -2, -1, 2, 1, 5, 4, -3, -5, 0, -2, -2, -6, -3, -3, -4, -1, -5, -4, -1, -2, 0, 2, -2, -6, -3, 1, 1, 1, -1, 3, 4, 7, 2, 3, 4, -1, 7, 2, 3, 1, -1, 1, -2, 0, -4, -5, -6, 0, -2, -7, -2, -5, -5, 1, -4, -5, -5, 3, -1, 1, 2, -2, 0, 1, 4, 1, -4, 2, 2, 0, 9, 2, 0, 4, 3, 1, 2, -4, -2, -4, 3, -4, -2, -6, 0, -1, 5, 2, -4, 0, -4, -4, -1, -5, -4, -7, -3, 1, 0, -2, -1, -5, 1, 0, -1, 0, 2, 4, 0, 3, -2, 1, 2, 6, 0, 1, 5, 0, 3, 3, 2, -5, -2, 1, 5, 2, -2, -5, -9, 0, -6, -1, -6, -7, -5, -4, 0, -2, -5, -3, 2, -2, 3, 2, 0, 9, 2, 0, 4, -3, 4, 5, 8, 6, -2, -4, -1, 0, -2, -2, 1, -5, 2, -5, -1, -4, -3, -4, 0, -2, -7, -3, -1, 0, -1, 0, -6, 3, -2, 5, 2, -1, -2, 1, 0, 1, -1, -3, 2, 3, 1, 2, -4, -3, -1, 5, 5, 3, -4, 0, 1, 2, 5, -5, 1, -5, 2, -2, 2, -4, -3, 0, -4, -3, -9, -7, -4, 2, -2, 1, -6, -3, 0, 1, 5, 1, -5, 0, 0, 2, 1, 2, 0, 6, 4, 6, 3, 2, 3, 1, -2, -2, -9, -4, -1, 4, 0, -1, -5, -8, -5, -4, 0, -4, -1, -3, 0, 0, -4, -3, -1, 1, 2, 0, -2, -3, 1, 3, 2, 3, 3, 0, 8, 2, 7, -1, 3, -2, 4, 0, 0, 1, -4, 5, -1, -3, -3, -6, -4, 2, 1, -5, -4, -7, -4, -4, -7, -2, -10, 1, 0, 1, -3, 4, -2, 5, 2, 1, -3, -1, 2, 8, 4, 5, 0, 1, 4, 5, 2, 2, -2, 1, -4, 0, -3, -3, -1, 0, 2, -4, -4, -5, -1, -7, 0, -4, -5, -1, -3, 2, -2, 0, 3, 0, 2, 0, 1, -2, 2, 4, -1, 0, -3, -1, 1, 3, 2, -3, 2, 0, 2, 2, -1, 2, -2, -3, 0, 0, -2, 2, -2, 4, -3, -6, -7, -6, 2, -1, -4, -1, -7, -1, -3, 3, -1, 0, -2, 2, 2, -3, 3, -4, 5, 7, 6, 3, 1, -1, 6, 2, 1, 0, -1, -1, 1, -3, 1, -3, -5, -5, -3, -8, -3, -11, -1, -1, 0, -8, -2, -5, 3, 4, 0, 1, -2, 2, 0, 6, 4, 1, 4, 1, 5, 0, 0, 1, 2, 5, 0, 1, -10, 0, -5, 2, 0, -6, -6, -2, -2, 2, -3, 0, -4, 2, -4, 1, -3, -4, 1, -2, 2, 1, -2, 0, 3, 2, -3, -1, -5, -3, 4, 2, 3, -1, 4, 1, 5, -1, 2, -3, 2, -3, 0, -3, -2, 1, 1, 5, 1, -2, -5, 1, -1, -4, -3, -7, 0, -5, -4, -4, 0, -4, 4, 0, -1, 1, -8, 1, 0, 9, 1, 2, -2, 5, 5, 1, 6, -1, 6, 3, 1, 1, -2, -2, -4, -3, -2, -3, -7, -4, -4, -1, -3, -8, -1, -8, 4, -5, 0, -3, 1, 0, 4, -1, 0, 1, 3, 3, 4, -4, 6, -2, 2, 5, 4, -3, 4, -3, 5, 0, -4, 0, 0, -1, 0, -4, -4, 3, -1, -2, -4, -8, -9, -5, -4, 4, -4, 1, -4, 1, 1, -1, -1, -1, 3, 2, 3, 0, 1, 2, 1, 5, 3, 1, 0, 5, 3, 3, 0, -5, -4, -2, 5, 0, -2, -5, -2, -6, -2, -5, -8, -2, 1, -1, -3, -7, -8, -6, 0, 4, 7, -2, 7, -1, 7, 3, 2, -5, 0, 2, 0, 1, -3, 2, 2, 3, 3, -3, 0, -2, 3, -1, -1, -4, -6, -2, -3, 4, -4, 0, -4, 6, -2, -6, -2, -7, 1, 2, -1, -3, -2, -2, 3, -1, 0, -3, -1, 4, 7, 4, 0, 2, -1, 0, 6, -2, 1, 1, 5, 4, 1, -3, -3, -2, 2, 2, 1, -6, -6, -3, -4, -2, -6, -5, -4, -5, -2, -8, -8, -3, 0, 4, 0, 1, -1, 2, 5, 4, 2, 2, 3, 3, 4, 10, 0, 2, 0, 3, 1, 1, 0, -3, 1, -3, 1, -7, 0, 1, -2, 1, -6, -4, -10, -1, -4, -2, -2, -3, 2, -4, 1, -5, -4, -4, 2, 1, 1, -4, -1, 3, 1, 6, 2, -2, -2, 3, 3, 2, 7, -5, 5, 0, 8, 1, -1, 2, 3, -1, -6, 0, -10, 3, -1, -1, -5, -6, -8, -2, 0, -3, -5, -8, -4, 2, -3, -1, -2, 0, -1, 7, -1, 3, 2, 4, 7, 3, 4, -1, 5, 1, 9, 1, -2, -1, -1, 1, -3, -2, -6, -7, 1, -3, -1, -9, -4, -6, 0, 2, -3, -2, -4, -3, 0, -4, -1, -4, 0, 1, 6, -1, 1, -1, 3, 5, -1, 3, 4, 5, 7, 4, -2, 0, -2, 0, 3, 1, -1, -8, -2, -1, -2, -5, -1, -2, -2, 2, -5, -7, -9, -2, -3, -2, 1, -5, 4, -4, 5, -1, -1, -3, 2, 3, 7, 3, -1, 3, 4, -1, 5, -4, 0, 4, 4, 3, 4, -9, 1, -5, 2, -2, -2, -3, -7, -1, -2, -2, -5, -3, -1, 1, -2, -1, -4, -4, 1, -1, -7, 0, -1, 2, 5, 4, -4, -5, -4, 0, 2, 1, -1, 3, 5, 4, 0, 0, -1, 3, 8, 3, 3, -4, 0, 1, 0, -2, -6, -2, -4, 3, -2, -3, -5, -6, -3, -1, -1, -7, 0, 0, 3, -5, -4, -11, 0, 0, 3, 3, 1, 1, 1, 4, 6, 1, 1, 2, 9, 3, 3, -4, -4, -3, 2, -1, -6, 1, -5, 2, 0, -1, -8, -5, -6, 1, 0, -2, -1, -2, -1, 2, 0, -9, 0, 5, 4, 7, -3, -3, 3, 4, 2, 4, 0, -1, 3, 1, 5, -5, -6, -7, 0, 3, 0, -2, -4, 3, 3, -3, -4, -7, -2, 4, 1, -1, -4, -1, -6, -2, 3, -2, -3, 1, 4, 1, -1, -4, -3, 3, 4, 5, -2, 2, -3, 4, 0, 3, -3, -3, 0, 3, 1, -2, -1, -3, 2, 4, -2, -2, -3, -1, -1, 3, -11, -2, -8, 5, -1, 3, -5, -2, 2, -1, 3, -3, 0, -1, -1, 5, -2, 0, -2, 3, 2, 3, -2, -6, -3, 2, 4, -6, 5, -6, 1, 2, 3, -6, 2, -3, -4, 3, -9, 2, -6, 3, 4, 2, -9, -1, 1, 2, 8, -3, -4, -1, -2, 2, -2, 2, -3, 3, -1, 1, 2, -1, -6, 1, 2, 2, 1, -2, 2, 3, 1, -3, -6, -3, 0, 1, -3, 0, -3, -1, -4, 2, -4, -3, -1, 4, 0, 5, -6, -7, -1, 0, 0, -3, -1, 2, 4, 0, 3, -4, -1, 1, 7, 4, 2, -1, -4, 0, 2, -4, -5, -5, -1, 1, 4, -5, -4, -6, -3, -2, -3, 2, -2, 5, 2, 3, -4, -2, -5, 6, 3, 4, 2, -3, 1, 0, 0, 1, -3, -1, 1, 7, 0, 6, -6, -7, -2, -7, 0, -1, 0, 2, 1, -2, -7, -2, -5, 0, 2, 0, -3, -5, -1, -3, 0, -1, 0, -6, 8, 4, 5, -1, 1, -4, 1, 1, 4, 2, 5, 3, 6, 0, -2, -9, -4, -1, 0, 0, 1, -1, -4, -1, -5, -5, -5, 0, 0, 1, -6, -5, -9, 0, -3, 0, -2, 0, 0, 3, 4, 2, 1, -7, 1, 3, 4, 9, 1, 4, 4, 2, -4, 2, -2, 1, 5, -2, 0, -3, -4, -3, -2, -4, -4, -4, 1, -1, 2, -6, -8, -3, -8, -1, -2, -4, 5, 2, 3, -1, 0, -4, 2, -1, 5, 5, -1, 3, 0, 3, 3, 0, -4, 9, 4, 2, -1, -6, -4, -2, -2, 2, -7, 0, 0, -2, -2, -2, -10, -4, -7, 0, -2, 2, -2, 2, 1, 0, -3, 0, 1, 6, 3, 2, 0, 0, -1, 2, 3, -1, 4, -5, 6, 2, -3, 0, -3, 0, 1, 0, -5, -6, 1, 0, 1, -5, -2, -14, 0, -4, -1, -1, -1, 1, -3, 0, -2, -1, -4, 4, 5, -1, 5, -1, 3, 3, 5, -3, 5, -3, 5, 5, 6, 4, -6, 2, -9, 4, -4, 0, 1, -2, -1, -8, -6, -11, -2, -3, 3, -6, -8, 3, -5, 1, -3, 1, -3, 1, 3, 5, 6, 2, 1, -6, 4, -1, 1, 0, 7, 7, 2, 3, -6, -4, -4, 3, 3, 0, 1, -1, -2, -4, 0, -8, -2, -3, 1, -2, 1, -5, -2, -1, -3, -3, -4, -3, 7, 4, 1, -1, -6, -5, -3, 2, 5, 8, 3, 3, 2, 1, -4, -1, -2, 6, 3, 2, -4, -1, 1, -5, -1, -1, -5, 2, -2, 1, -2, -7, -5, -11, -4, -3, 3, -8, 8, 4, -2, -2, -4, -4, -1, 4, 3, 5, 5, 2, 4, -1, 6, -3, 6, 2, 3, 0, -4, 0, -2, -2, 0, -5, -2, -1, 4, 3, 1, -13, -8, -8, -5, -3, 7, -2, 3, -2, -5, -3, -8, -2, -3, 8, 6, 1, -2, 5, 3, 1, 2, 0, -1, 2, 4, 3, -5, 1, -3, 0, 1, 7, 1, 2, 3, -1, -4, -4, -10, -7, 3, 0, 2, -5, -5, -4, -1, -7, -3, -3, 1, 3, 0, 0, -1, -6, 6, 1, 4, 1, 2, 5, 6, 4, -1, -4, -3, 1, 2, 5, 2, -1, 1, 3, -8, -1, -10, -2, -5, 0, -1, -6, -10, -7, 2, -2, 6, -1, -2, 1, 4, -1, -5, -1, -5, 4, 1, 4, 2, 1, 3, 4, 0, -2, 1, -1, 3, 8, 2, 1, -4, -3, -3, 3, -3, -1, -4, 0, -4, -6, -2, -8, 1, -2, 5, -6, -5, -6, 0, 3, 1, -6, -3, 1, 2, 4, 2, 4, -2, 3, 3, 3, 1, 5, 1, 2, 3, -2, -6, 6, -1, 6, -2, 1, -7, -5, -2, -3, -6, -6, -6, -4, 0, -2, -4, -4, -3, 0, -1, 1, -3, -1, 3, 1, 1, 0, 6, 4, 8, 10, 5, 0, -3, 1, -2, 5, 2, 1, 1, 1, -4, -6, -8, -8, -8, -5, -4, -5, -4, -5, 0, -5, -3, 0, -7, 0, 4, 1, -4, -1, -4, -2, 4, 4, 5, 6, 6, 7, 0, 0, -1, 0, 2, 9, 2, 1, -3, 0, 1, -3, 1, -9, -1, 3, -4, 3, -6, -7, -2, -1, -1, -1, 1, -9, 2, -5, 1, -8, -6, -6, 1, -1, 6, 0, 2, 5, 2, 0, 2, 1, 2, 6, 5, -2, -1, 0, 4, 1, 6, 0, -2, 1, 0, 3, -7, -1, -13, -4, -3, -3, -3, -2, -3, -5, -9, -11, -2, -3, 4, 7, -1, 2, 0, -2, 8, 5, 1, 4, 3, 2, 7, 3, -2, -4, 7, 2, 3, -2, 1, -1, 2, 0, -5, -4, -4, 0, -4, 0, -1, -10, -9, -3, -5, -8, 1, -5, 3, -3, 0, -7, 1, 0, 5, 4, 7, 1, 1, 0, 2, 2, -2, -1, 2, 1, 4, 6, -1, 4, 3, -1, 4, -2, -3, 3, -1, -2, -6, -6, -7, -3, -1, 0, -4, -6, -5, -6, 0, -3, 3, -5, 7, 0, -1, 1, -3, -1, 1, 6, 3, -3, 7, 1, 10, 1, 6, -1, -2, 5, 2, 1, 1, -4, -2, 0, -3, -7, -2, -4, 4, -8, -8, -4, -10, -2, 2, -4, 1, -5, -7, -1, 3, -1, 1, 1, 4, 6, 2, 2, 0, 4, 7, 0, 5, -2, 0, 3, 3, 3, -3, -1, -5, -2, 0, 3, -4, -6, 2, -1, 0, -2, -4, 0, -4, -3, -9, -3, -4, -4, 0, 3, -1, -4, 3, 1, 5, -2, 1, 2, 2, 4, 5, -3, 2, 1, 3, 7, 1, -5, 1, 0, 5, -3, -2, -3, -4, 0, -3, -2, -5, 0, -8, 3, -6, -4, -6, -2, 2, -4, -2, -3, -2, 1, 4, 2, 3, -2, 2, 4, 1, 4, -2, 3, 2, 1, 1, 7, -1, 2, 4, -4, 2, -4, -2, 5, -4, 3, -1, -3, -2, 3, -8, -4, -6, -3, -3, -1, 0, -6, -1, 0, 1, 1, -2, -10, -3, -1, 0, 2, -5, 1, 1, 2, 10, 8, 2, 8, -1, -2, 4, -5, 2, 2, 7, 6, -6, -1, -5, -4, -3, -6, -7, 0, -5, -5, -1, -2, -5, 0, -4, 6, -6, 0, 3, -3, 4, 0, -6, 2, 5, 5, 4, 10, 0, 2, -3, 3, -2, 0, 3, -3, 2, -3, -8, -8, -5, -1, -1, -1, 0, -5, -2, 0, -3, -4, -1, -5, -2, 5, 0, 5, -4, 4, -1, -1, 1, -3, 3, 9, 2, -1, 1, -6, -3, 7, 1, 3, -2, -4, 0, -1, 3, 1, -3, 4, 6, 0, 1, 2, -3, 0, 0, -5, -13, -4, -2, 1, 2, -3, -10, -4, -7, 1, -2, -2, -1, 0, 1, 1, -4, -1, 2, -2, 7, 1, -3, 0, 0, 4, 5, 2, 2, -1, 6, 9, 1, 3, 1, -5, 5, -6, -5, -2, -4, -2, 2, -7, -4, -11, -5, 3, -3, -6, -4, -6, 3, 3, -3, 2, 0, 1, -3, -1, -2, -4, 1, 10, 8, -2, 4, -3, 6, 6, 1, 0, -7, 2, -2, 1, 3, -4, -4, 4, 1, 0, -2, -5, 2, -2, 0, -7, -11, -5, -2, -2, 5, -1, -8, -1, -1, 1, 2, -2, -1, 1, 1, 5, 0, -3, 5, 1, 6, 1, -1, 3, 1, 6, -3, -1, -1, -3, 4, 12, -1, -1, 2, -4, -1, -6, -8, -7, -3, -2, 1, -9, -5, -6, -10, 5, 1, -2, -3, -2, 5, 4, 3, -1, -5, 4, 6, 3, 4, 6, -2, 7, 0, -4, -1, -1, 9, 8, 2, 2, -8, -3, -3, 0, -2, 0, -4, -2, 0, -6, -7, -14, -6, -5, -1, 3, -6, -2, 1, -3, 0, -4, -5, 1, 5, 9, 4, 0, 3, 0, 1, 12, 0, 4, 8, 5, 7, -1, -4, 0, -3, 5, 4, -4, 0, -3, -13, -2, -10, -14, -3, -5, 2, 1, -3, -4, -8, -8, -3, -2, -2, 3, 4, 8, 0, 2, 1, 2, 12, 5, 3, 8, 2, 6, 3, -4, -4, -2, -8, 8, -5, -2, -6, -10, -2, -6, -4, 0, -4, 2, 5, 1, 0, -4, -4, -1, -1, -3, 4, -7, 4, 3, -3, 4, -4, -3, 8, 4, 7, 0, 0, 2, -1, -2, -1, -2, -7, 11, -1, 5, -4, 2, -2, 0, 2, -2, -4, -2, 1, -5, 3, -6, -9, -3, -3, -2, -5, -5, -2, -6, -2, -7, -8, 1, 3, 5, 9, 4, 4, 0, 5, 8, 1, 3, 7, 5, 10, 11, -7, 3, 0, -3, 1, -1, -7, -7, -3, -2, -6, -9, -6, -12, -4, -1, 0, -8, -5, -3, -3, -2, 3, 1, 1, 9, 4, 2, 5, -1, 2, 6, 2, 0, -3, 2, 2, 5, 2, -1, -4, 4, 1, 1, 2, -5, -8, -1, -3, -1, -9, -4, 1, -4, 5, -6, -4, 0, 3, -9, 3, -3, -5, 1, 4, 4, 1, -4, 1, -4, 4, 1, -6, 0, 5, 7, 8, 1, 6, 0, 3, 4, 2, -3, 1, -3, -3, 3, -9, -6, -7, -2, -1, -3, -5, -6, -5, -5, -6, -5, 4, -3, 5, 5, -2, -1, -1, -3, 6, -2, 5, 6, 2, 11, 8, -1, 3, -6, -2, 5, 4, -3, -3, -5, -3, -7, -5, 0, -5, 2, 1, 0, 1, -7, 0, -3, -2, -1, -2, -5, 7, -4, -2, -3, -2, -3, 4, 4, 9, 0, 1, 1, -5, -3, -4, -4, 4, 3, 6, 0, -2, -2, -6, 4, 1, 1, -3, 3, -1, 2, 0, -7, 0, 0, -1, -3, -2, -1, -5, -2, -3, -8, -5, -5, -1, 5, 5, 2, 2, -3, 4, 3, 3, 6, 3, -1, 10, -4, -3, -2, -3, 0, -4, 0, -2, -2, 0, 1, -4, -2, -5, -9, 8, -2, -1, -1, -3, -3, -2, -6, 2, 1, 2, 9, 0, 1, 3, -4, 2, 4, -6, -1, 2, -1, 6, 3, 0, -5, -3, -1, 0, 3, -3, 0, -6, -2, -3, -4, -2, 0, 3, 2, 2, 0, -10, 1, -6, -5, -1, -2, 5, 3, 6, -2, -6, -1, -3, 2, -1, 0, 0, -1, 0, 0, 0, 1, -2, 2, -2, -5, -1, -2, 16, 12, -18, -10, 3, -14, -10, 16, -1, -3, -16, 28, 3, -1, -1, 12, -5, -6, 6, 7, -7, -18, -28, 11, 0, 6, -2, 26, -21, -10, -1, 24, -3, 20, -19, 15, -14, -3, -3, 15, -35, -2, 6, -14, 30, 6, -36, -8, 17, 0, -27, 26, 16, -38, 8, -14, 57, 3, -31, -14, 34, -20, 33, 2, -6, -7, -28, 20, -24, 8, 13, 8, -39, 17, 40, -42, -11, 13, -46, 1, 28, -22, 11, -3, -14, 5, 20, -12, -4, 49, -22, -24, 39, -11, -1, -9, 37, -30, 13, 34, 4, -11, -25, 18, -22, 1, 29, -17, -3, -26, -16, -21, 12, -18, 7, -17, -6, 51, 0, -21, 10, 24, -45, 8, 14, 31, -10, -37, 6, 0, 24, 3, -18, -13, 14, 11, 0, 7, -1, -38, -29, -21, 32, -30, 22, -26, 14, -40, 55, -36, 30, -12, 8, 31, -16, 19, -15, 23, -48, 36, 1, 63, 3, 24, 0, -3, 14, 26, -21, 15, 47, -21, -80, 14, -4, -25, -33, 11, 25, -35, -44, 13, -2, -48, -11, -23, -7, 27, -4, -15, -22, 5, 26, -36, 50, 23, 11, -23, -14, 19, 32, 14, 38, -66, 56, -11, 26, 18, -12, 17, -30, -6, -54, 22, 77, -62, -12, -16, 34, -25, 2, 14, -62, 12, 20, -22, -50, 58, -29, -58, 4, 28, 30, 13, 25, -78, 38, 45, -19, -7, 52, -61, 27, 17, -21, -4, 6, 37, -24, -38, 73, 8, -16, 21, -2, -15, -19, -19, 18, 3, 7, -48, -10, -10, 10, 4, 13, -13, -4, 0, 46, -12, 6, -18, -25, 4, 14, 27, -22, -37, 14, -6, -17, 55, 40, -111, 63, 9, -38, -16, 46, -35, 4, 0, -10, -8, -12, 58, -69, 1, 66, -38, 21, -33, -6, 10, 0, 10, -11, 18, -16, 32, -7, -10, -25, 65, -42, 42, -62, 18, -3, -2, -8, 21, 4, -71, 13, 40, -3, 18, -19, -29, 15, -66, 60, -50, -6, 67, -80, 17, 66, -21, -20, -15, 68, -16, 72, -4, -23, 4, 53, -8, 8, -4, 0, 27, -26, -22, 25, -31, 7, -39, -18, 27, -43, -25, -33, -6, 17, -16, 0, -55, 6, 26, -3, -67, 7, 60, -83, 25, 15, 45, -8, 51, -55, 28, 42, 42, -17, 37, -6, 17, 8, 11, -1, 59, -7, -45, 14, -41, 107, -49, -50, -25, 63, -58, -27, -57, 19, 13, -13, -27, 19, -42, 63, -113, -1, 44, 8, 1, -10, -33, 0, 55, -41, 15, 0, 76, -17, -39, 60, -20, 28, 54, -93, 15, 83, -30, 4, -56, 49, -58, 30, -28, 2, 54, -64, 83, -128, 86, 24, -40, -27, -66, 51, 11, -51, 59, 6, 20, -58, -24, 78, -7, -23, -27, 1, -3, -24, 10, -6, -16, 34, 39, -37, -17, 26, 52, -69, -7, 11, 24, -62, 38, -13, 41, 5, -2, -5, -12, 15, 77, -49, -10, 74, -12, -11, -38, 32, -24, 25, -6, 19, -24, -2, -38, 63, -91, 64, -27, -11, -56, -43, 27, -41, -55, -15, 1, -4, 27, 8, 37, -57, 3, 28, -11, -4, 46, -39, 3, 12, 100, -33, 39, 17, 6, 49, 5, 38, -12, 10, 21, -35, 23, -6, -36, 10, -9, 3, -1, 13, -65, -40, 36, -25, -28, 5, -37, -20, -14, 31, -16, -32, -16, 4, 15, -11, 26, -16, 29, -42, 46, 7, 39, -1, -5, -9, 33, -31, 35, -33, -7, 17, 56, -24, 22, 14, -22, -34, 44, 16, 11, -46, 43, -48, -27, 43, 36, -45, 21, 11, 0, -98, -22, 87, -126, 52, -45, 34, -28, -17, -31, 23, -38, 23, 25, -11, 25, -63, 21, 13, 19, 47, 28, -23, 20, 21, -5, -14, 112, -30, -67, 37, 43, -12, -57, 34, -9, -29, 52, -19, 14, -51, 0, 26, -69, 3, -18, -24, -34, 31, -15, -33, -36, 10, -20, -38, 63, 0, 44, -50, 72, 25, -16, -6, 6, 15, 23, 31, 3, -20, -9, 19, 63, 17, -18, -5, -12, -87, 31, 26, -37, -29, 49, -42, -15, 14, 11, -16, -31, 46, -19, -13, -37, 59, -91, 47, 4, -11, -26, 39, -29, -24, 48, 10, 39, -11, 45, -51, -1, -24, 47, -19, 39, -34, -29, -17, 1, 56, -25, -16, -13, 0, 48, -71, 49, 2, -2, -45, -10, 59, -17, -25, 9, 9, 44, 42, -32, -23, -49, 46, -11, -50, 76, -43, -45, -1, 41, -8, 2, 71, -36, -61, 35, 21, -13, -36, 44, -45, 26, -45, -21, 28, -37, 39, -29, 15, 4, -5, 24, -7, 7, 3, 68, -80, 26, 24, -22, 8, 26, 28, 10, -26, -3, 16, -51, 85, -8, -14, -54, 39, -28, -9, -25, 46, -39, -20, 34, 11, -25, -7, -12, -41, 12, -17, -5, -43, -8, 0, 18, 13, 9, 28, -40, 34, 0, 13, 40, -20, 5, 22, -25, -13, 51, 9, -34, 43, -16, -18, 2, 35, -4, -28, 14, -37, 6, -8, 31, -49, 9, -31, 61, -55, 35, -46, -37, -12, 32, 74, -59, -30, -21, 5, 38, 3, 48, -35, -42, 2, 29, 81, -8, -37, 24, 42, -31, 18, -11, -21, -67, 98, -18, 11, -26, -14, -76, 11, 71, -70, 30, -52, 37, -45, 61, 6, -33, -44, 58, 24, -16, -51, 49, -28, 51, -6, -15, 46, 10, -24, 36, -4, 6, -30, 46, -66, 54, 27, -16, -34, -23, 90, -61, -49, 22, -3, -22, 17, -35, -11, -59, 23, 2, -25, 69, -24, -26, -28, 37, 12, 11, -63, 27, 18, 3, 34, -25, 9, -14, 29, 4, 24, 21, -77, 12, 14, 37, 1, 45, -63, 1, 49, -14, -23, -7, -4, -42, 48, -57, 18, -36, 17, 15, -37, 47, 1, -41, -14, 11, 49, -32, 32, -36, -19, 21, -11, 39, -31, 43, 0, -24, 15, 6, 9, -46, 5, 21, -23, 2, -28, -15, 59, -13, -29, 50, -7, -45, -12, 23, -1, 27, 6, -17, 7, -4, -3, -3, 53, -10, 17, -52, 19, 24, -8, -7, 19, -51, -30, 55, -22, -22, 29, -38, -25, 39, 3, 34, -84, 26, -37, 42, 15, 4, -4, -16, -33, 29, 17, 43, -93, 24, -6, -20, -14, 107, -29, -36, 69, -21, 10, -7, 74, -67, 38, -23, -8, 27, -35, -49, 29, -8, -4, 7, -8, 5, -38, -28, -33, 22, 70, -37, -10, -56, 26, 5, 7, 59, -21, -58, 10, -2, 6, 49, -16, -9, -38, 60, 13, 43, -43, 23, -14, -9, 38, 17, -38, -15, 29, 6, -5, -11, -3, -4, -65, 45, -13, 26, -13, -4, -5, -38, 48, 0, 4, -40, 40, -48, 23, 21, 23, -42, 5, -17, 13, -9, 12, -3, 5, -25, 34, -24, -3, -18, 16, -44, 13, 27, -30, 44, -54, 6, -18, -3, 4, 21, -25, -13, 22, -20, -12, 37, -10, -10, 5, 24, -17, 23, 9, 0, 4, 3, 12, 26, -27, 17, 9, -41, 69, -1, 15, -37, 15, -6, 0, -1, 3, -13, -23, -18, 27, -5, 21, -16, -41, -2, 20, 13, -27, 6, -21, 8, 6, 0, 6, -5, -21, -22, 73, -40, 4, 6, 21, -8, -5, 29, -47, -1, 1, 19, 3, -10, -1, 2, -48, -11, 45, -27, 11, -33, -21, 21, 7, 12, -22, 21, -40, 13, 27, -20, 37, 5, -18, -18, 35, 40, -11, 20, -25, 10, -4, 33, 12, -29, 9, -20, -30, 34, 24, -9, -10, -24, -16, 8, 22, 6, -58, -5, -13, 18, 5, -43, 10, -16, -25, 13, 70, -25, -7, -25, -19, 16, 58, -46, -5, 6, -5, 40, -24, 22, 50, -73, -7, 7, 32, 39, -27, -23, -23, 56, -35, 21, 17, -40, 40, -52, 4, 0, 49, -29, -42, 24, 9, 31, 2, -46, 0, -9, -5, 9, -31, 64, -5, -45, -26, 42, -4, -34, -8, -3, 32, -15, -8, 22, -24, 13, -31, -2, 31, 10, -10, -18, 8, 24, 20, -29, 2, 14, 23, 25, -4, -19, 20, -25, -5, -3, 23, -8, 52, -42, -17, -7, 29, -26, 2, -19, 55, -50, -28, 1, -10, -7, 7, -41, 16, 21, 1, -20, 0, 16, -19, 14, -39, 86, -17, -34, -64, 73, 0, 20, -28, 30, -22, 9, 58, -4, -8, -18, -20, 31, -21, 1, 26, -49, 5, 41, -25, -13, -6, -7, 6, 10, 42, -30, -26, -43, 11, 44, -54, 31, -10, -11, -17, 25, 32, -43, 64, -23, 3, -37, 33, -30, -4, -35, 47, -29, 9, 23, -34, -5, 64, -37, 32, -11, -44, 21, 25, -19, 8, 6, -25, 34, 2, -18, -23, 38, 20, 7, 21, 1, -32, -37, 50, -9, -25, 34, -61, 55, -32, 7, -48, 20, 13, 0, -35, 17, 9, -42, -28, 14, 42, -33, -25, -5, 21, 41, -60, 32, -7, 38, -9, -3, 20, -4, 29, -69, 62, -16, 35, -64, 45, 10, 5, -1, -18, -18, -1, 5, 32, 0, -21, -12, -23, 29, -15, 13, -39, -3, -3, 6, 35, -24, -23, -7, -2, 44, -10, -37, 25, 25, -25, -23, 7, 40, 4, -40, -18, 21, -2, -3, 1, -16, 45, -26, -2, -16, 18, 41, -64, 8, -26, 40, 5, -32, 8, 18, -1, 15, -1, 9, 2, 2, -13, -12, 35, -9, 13, -62, -29, 72, 18, 7, -30, 26, -7, -29, 39, -38, 31, -56, -25, -3, 17, 2, -3, -46, 35, 6, 27, -39, -3, 3, 31, -25, -19, -2, 38, 26, -77, 22, 18, 40, 3, -22, 65, -48, 33, -16, -37, 78, -34, 1, -52, 23, 16, 1, -37, 17, 12, 1, -4, 8, -27, -1, -11, -18, 27, -23, -10, -11, -19, -6, -7, 51, -74, 16, 20, 17, -14, 7, 7, -13, -8, -5, -11, 39, 21, -5, -44, 31, 64, -38, -18, 20, 40, -4, -10, 10, -23, 23, -6, -20, 11, 9, 10, 6, -23, -11, 1, 17, -56, 56, -40, 0, -17, -60, 84, -80, 16, -13, 4, -25, 12, 17, -42, -26, 54, -29, 12, -5, 37, 16, -62, 94, -5, -2, -2, -2, -9, 5, 51, -25, -5, -11, 5, 16, -14, -9, 43, -44, -8, 27, 2, -1, 9, -18, -6, 5, 23, -46, -9, 13, 16, -10, -10, -23, 59, -47, -14, 23, 29, -15, -14, -30, 21, -21, 0, 14, -3, 25, -16, -35, -2, -8, 32, -19, 22, -23, -37, 30, -33, -19, 11, 12, -32, 47, -4, 27, 11, 9, -35, 39, 29, -18, -2, -11, 27, -2, 13, 0, 18, -26, 15, -25, 26, -4, 21, -29, -33, 18, -8, -31, -5, 21, -1, -38, -28, 41, -18, -4, -22, 47, -12, -44, 55, -79, -5, 19, -10, 25, 4, 21, 15, -28, 13, -6, 45, -24, 25, 10, -26, 4, 2, 31, 3, -7, 3, 5, -23, 51, -9, -32, -5, 35, -32, -21, -20, 35, -40, -10, 20, -8, 7, -5, -38, -1, -24, 39, -26, 20, -16, -9, -27, 25, 34, -32, 1, 12, -13, 3, 37, 13, 3, -31, 27, 30, 5, -15, -21, 2, 10, -13, 16, 36, -9, -59, 41, -10, 61, -60, -35, -11, 7, 5, -28, 30, 5, -23, -66, 34, 50, -26, -19, -10, 11, 8, 8, -35, -5, -11, 56, -24, 10, 35, 16, -10, -19, 30, 4, -11, 23, 0, -6, 6, 36, -15, 0, 15, -14, -26, -8, -5, 15, -31, -45, 42, -30, 0, -9, 6, -22, 9, -22, 7, -8, 15, -19, -3, -13, 29, -14, 9, -16, 3, -5, -10, 63, 0, 4, 4, 20, 16, -21, 18, 31, -24, -19, 31, 54, -39, -7, -16, 5, -3, 0, -29, 16, 6, -29, -25, -52, 49, -9, -66, -3, 50, -3, -2, -14, 4, -8, 33, -40, 2, 15, -6, -17, -4, 10, 48, -16, 14, -9, 27, 10, 2, 2, 40, -35, 5, -10, 7, 28, 1, 4, -30, -4, 0, 1, -14, -13, -11, 26, -17, 13, -44, -9, -6, -23, 17, 11, 11, -21, -11, 0, 9, 8, 8, -30, 29, 10, -26, -12, 15, 17, 4, -26, 14, 19, 20, -9, -24, 39, 23, -10, -35, 8, -6, 18, -25, 15, -17, 41, -48, -31, -5, 47, -14, -20, -4, -7, 5, -19, 3, 21, 12, -23, 15, -24, 8, 3, -25, 2, 28, 14, 21, 25, -72, 15, 26, -6, 45, -27, 29, -30, -17, 23, 6, -2, 27, -46, 13, 9, 15, -57, 27, 1, -18, 1, -11, -2, -20, -16, -23, 24, 18, -21, -5, -15, -14, 26, -12, 30, -48, 37, -24, -3, 23, 9, -5, 9, 8, -43, 23, 26, 6, 28, -29, 30, -8, -12, 25, -18, 33, -48, -4, 29, 1, -8, -4, -20, 41, -22, 1, 12, -33, 0, -17, -16, 29, -3, -2, -36, 6, -1, -11, 4, -24, 40, -24, -5, 26, -2, -28, 13, -11, 35, -9, -2, -3, -6, 13, 10, 1, 11, -22, 22, -27, -5, 20, 11, -1, 8, -23, 8, 7, -7, 17, -6, 16, -9, -10, 3, 13, -3, -17, 19, -21, 6, -13, -15, -7, 22, -15, -7, 11, -20, -19, -6, 0, 28, -10, -7, -13, 9, 7, 1, -11, -6, 21, -33, -4, 52, -11, -1, -2, -2, -4, 32, 17, -31, 7, 12, 2, -5, 11, -1, -6, 1, 3, -11, 5, 4, -15, -8, 10, 5, -18, 5, -26, -11, 22, -15, -23, 22, 19, -30, 3, 1, -5, 10, -17, 10, -2, 10, 7, -17, -5, 36, -12, -24, 27, 22, -3, -11, -6, -7, 20, 5, -21, 0, 23, -31, -27, 14, 2, 8, 7, -15, 0, 13, -7, -3, -21, 33, -4, -26, 7, 5, -7, -7, 1, 3, 4, 11, -24, 6, 11, -7, 14, -9, -11, -1, 34, -22, 11, 1, -18, 17, 4, -19, 28, -15, -7, -11, 12, 1, -7, -9, -12, 17, -20, 6, 5, 2, -10, 12, -23, -3, 26, -1, 4, 6, -25, 12, -3, -26, 2, 15, 14, -18, -6, -17, 14, 4, -10, 21, -13, 5, -15, -20, 27, 6, 8, -11, 18, 15, -34, 17, -2, -13, 41, -9, -10, -6, -2, 7, -11, -4, 28, -26, -6, 25, 17, -36, -2, 33, -39, -15, 11, -2, 26, -32, -31, 21, 26, -11, -24, 12, -17, 4, -33, 24, 14, -10, 12, -19, -3, 28, 11, -8, 0, 26, -17, -7, 8, -6, 20, 26, -29, -27, 25, -14, -2, 10, -16, 39, -24, -17, -4, -13, 24, -10, -3, -20, 25, -1, -24, 24, -20, -5, 21, -26, 7, 21, -26, 15, 17, 6, -34, 5, 11, -27, 20, 17, -13, -8, -16, 9, 33, -36, 19, 5, 4, -2, -33, -12, 38, -17, -10, -4, 19, 14, -4, -32, -41, 64, 5, -38, 28, 6, -2, -11, -22, 11, 17, 17, -24, 23, -7, 9, 10, -38, 0, 25, -9, -6, -27, 20, 2, -27, 34, -23, 17, -22, 4, 12, -43, 29, -8, 25, -19, 13, -17, -11, 27, -8, 14, -19, 12, 9, -22, -6, 11, -10, 17, -4, 2, -3, 15, -47, 32, -18, 11, 14, 0, 8, -33, -14, -12, 23, 17, -12, -4, 13, -27, 10, -17, 20, -2, -11, -11, 27, 18, -21, -6, 26, -18, 9, -7, 27, -12, 3, -9, -9, 22, 7, -38, -2, 14, -16, 12, -21, -10, 22, 1, -28, 20, 31, -11, -49, 9, 16, -4, -7, -4, -5, 46, -39, 9, -18, 16, 22, -24, -13, 14, 29, -10, 3, -23, 4, 11, -33, 30, 18, -9, 5, -11, 4, -20, 30, -9, -14, -7, -9, 4, 0, 4, -15, -11, 23, 5, -24, 26, -6, -8, -17, 21, 0, 3, 13, -10, -13, 19, -16, -10, -5, 10, 8, 22, -19, 4, -8, 0, -24, 38, 12, -33, 10, -9, 5, -13, 11, 3, 7, -18, -12, 11, -4, 8, -17, -7, 16, -9, -2, -9, 0, 10, -2, -1, -1, 12, -6, 13, -18, 18, -6, 10, 1, -3, 9, -2, -30, 23, -9, 29, -11, -31, 10, 6, -21, -19, 54, -30, 18, -12, -26, 23, -10, -31, 23, -5, 49, -34, 4, -18, 3, 11, -24, 27, 12, -24, 3, -13, 3, 16, -6, -7, 1, 19, -8, -3, -11, 13, -14, 19, 10, 17, -21, 14, -40, 12, 13, -5, -3, 21, -14, -29, 16, -24, 1, 10, -1, -3, 6, -15, -16, 16, -4, 2, 23, -32, -1, 7, -5, 13, 4, -15, 33, 1, -7, -7, -12, 13, 6, -8, 2, 21, 2, -21, 17, -14, -19, 36, -2, -16, -4, 3, 9, 15, -39, 3, 9, -10, -3, -12, -7, 28, -19, 8, -18, 22, -18, -11, -2, 17, 23, -15, -24, 11, 13, -14, -10, 9, 4, 14, -10, -13, 13, -3, -12, 25, 6, -12, 12, -19, -3, 19, -10, -13, 19, 10, 18, -31, -15, 19, -9, -14, -6, 25, -18, 2, 17, -41, 11, 16, -20, 3, -10, 16, 9, 14, -27, -1, -3, 9, -19, 36, -6, -4, -4, -16, 5, -7, 24, -1, -30, 13, -8, -4, -9, 47, -37, 3, 21, -24, 1, 3, 11, 5, -10, -8, 20, -31, 16, 10, -1, 0, -9, -1, -6, 14, -6, 6, -17, 20, 3, -23, 10, -14, 17, -16, -2, 26, 7, -20, -10, 9, -18, 31, -35, 3, 14, -8, 13, -27, -4, -4, 26, -20, -9, 14, 22, -27, -4, 18, 9, 9, 3, -13, -20, 15, -13, 6, 12, -5, -6, -12, 0, 4, -10, 18, -7, -8, -15, 1, -11, 17, 5, -11, 14, -6, -11, 4, 10, -5, 13, 0, -7, 15, -2, -16, 2, -3, 9, -6, 2, 34, -11, -17, -8, 21, 13, -21, -4, 14, -7, -7, -19, 13, -7, 4, -25, 7, 16, -14, -40, -11, 36, 3, -10, 4, -10, 7, -1, -1, 4, 14, 6, -14, -14, 17, 23, -13, -2, -1, -12, 9, 8, 1, -7, 22, -29, 7, 7, 0, -24, 13, -10, 18, -1, -3, 13, -24, 30, -32, -5, 18, -2, -6, -8, 11, -18, -12, 17, -11, 0, 5, -4, -14, 31, -15, -16, 13, 12, -4, 4, -4, -1, -11, -15, 26, -18, 29, -15, -3, -8, 6, 6, -34, 22, 0, 11, -18, 16, 20, -19, -21, -5, 11, 21, 10, 10, -27, -5, 3, 2, -5, 9, -9, -1, 1, -11, -3, 8, 4, 1, -1, -11, 19, -1, -21, -5, -2, 11, -2, -8, 10, -7, -1, 2, -18, 3, 0, 7, 2, 7, 1, 1, -28, -14, 10, 19, 12, -21, 7, -19, 20, -2, -3, -1, 17, -11, -13, -16, 32, 4, -5, -3, 4, -4, 18, -2, -17, -6, 16, -3, 4, -12, 4, -2, 2, 6, -18, 20, -24, 17, -10, 19, -16, -17, 8, -7, -5, 16, -12, -18, 11, 9, 2, -8, 17, -9, -3, -13, 7, -6, 30, -15, -11, 5, 14, -2, -15, -5, 14, 13, -12, -24, -10, 22, -2, -8, -1, 21, -5, -19, -16, 8, 42, -6, -27, -12, 23, 10, -17, -14, 16, 14, -16, -2, 9, -2, 16, -9, -31, 22, 0, -2, 3, 4, -5, 20, -24, -5, 13, -1, -5, -10, -6, 8, -11, 2, 8, -8, -5, -9, 1, -6, 16, -1, -18, 4, 9, -3, 6, -4, 6, 9, -7, -9, -1, 10, -7, 4, 3, -3, 4, -8, -5, 3, -4, 10, 6, -15, 2, 3, -5, -2, -3, -12, 18, 2, -16, 7, 13, 0, -19, -8, 11, -6, -1, -9, 5, 13, -8, -6, 6, 7, 11, -11, -6, 13, -2, -5, -1, 9, -2, -7, -15, 10, 5, -1, -13, 8, 0, -6, -2, -2, 18, -16, -7, 2, 3, -4, 6, -11, 4, 6, 1, -5, 22, -11, -5, -6, -3, 11, -1, -1, 4, 1, -4, -13, -4, 11, -9, 1, 9, -1, -8, 1, -5, -7, 5, -14, 18, -1, -12, 11, -12, 16, -5, -11, 11, -2, 15, -7, -18, -10, 0, 18, -12, 8, 3, 6, -16, -3, 3, 6, 0, -1, -3, 4, 9, 3, -17, -7, 11, 11, -19, 5, 15, -12, -3, -12, 4, 11, -19, 0, 0, -14, 21, -15, 2, 8, 3, 8, -8, 5, -18, 9, -2, -8, 23, -5, -16, 5, 3, -20, 13, 11, -6, -15, 5, 4, -12, 2, 10, -5, -12, 5, -14, -2, 18, 11, -14, 0, 28, -10, -20, 4, 7, 9, -13, -6, 15, 11, -9, -6, 14, -8, 10, 4, -12, 11, -18, 13, -17, -9, 16, -4, -14, -7, 17, -24, -5, 4, 6, -6, 14, 2, -24, -22, 11, 13, 8, -16, 6, 13, -28, 10, -2, 11, 8, -1, -8, -14, 22, 3, -5, -13, 18, 7, -26, 15, 20, -6, -10, 4, 11, 5, -8, -3, -5, 0, -1, -6, 0, 4, 4, -14, -1, 1, 8, -14, -10, -4, 6, 4, -8, 3, -9, 0, 11, -4, -7, 5, 4, 6, -29, 18, 22, -19, -16, -11, 17, 7, -4, 3, -23, 20, 8, -19, 3, 13, 13, -16, -18, 15, -6, 0, 3, 17, -7, -4, 2, -22, 21, -1, -2, -1, -15, 13, 3, -7, 4, 0, -7, 8, -7, 11, 3, -2, -8, 10, -15, 0, 9, -14, -8, 8, -2, -9, 10, -13, 9, 7, -6, 2, -12, -4, 6, -12, 8, 12, 3, -10, 6, 7, 1, -2, -11, -1, 7, -7, 8, -13, -10, 11, -9, -10, -8, 20, 9, -11, 8, -5, -4, 6, -3, 5, 13, -13, -7, -7, 6, 19, 0, -9, 9, -1, -3, 4, -7, 0, -2, -4, -5, 5, 0, -5, 14, -19, -14, 18, -1, -5, 3, -12, 18, -19, 4, -15, -10, 10, 10, -17, -4, 19, -6, -2, 5, 11, -4, -3, 9, -22, 28, -6, -5, 0, -1, 11, -11, -13, 22, 3, -8, -9, 1, 3, 0, 1, 2, 7, -5, -25, 10, 6, 6, 2, -11, 8, -16, 15, -20, 5, 9, -6, -13, -5, 14, 6, -21, 22, -7, -14, 4, 26, -8, -13, 8, 1, -10, -13, 11, 10, -10, 2, -13, -9, 15, 0, 10, -30, 14, 7, -13, -5, -12, 8, 10, -4, 10, 12, -15, -7, 5, 2, 2, 10, -13, -3, 0, 21, -2, -16, 9, 3, -1, 6, 15, -3, -21, 10, -8, 5, 1, 1, 2, -19, 10, -7, -3, -1, 8, 6, -26, -10, 18, -28, -3, -3, 4, 0, -7, 6, -10, -2, 25, -19, 5, -11, -2, 14, 4, -5, -3, 4, -5, 6, -2, -3, 11, -1, 13, -12, 5, 20, -15, -3, 17, 4, -14, -5, 11, 3, 1, 6, 11, -20, 10, -4, -4, -4, -4, -18, -7, 5, 10, -25, 7, -9, -15, 1, -4, 4, 4, -4, -1, -18, 9, -6, 4, 7, -19, 10, 0, 3, -6, 12, 18, -5, 2, 4, -4, 11, 2, 5, 2, 1, 3, -4, 3, 4, -3, -2, -8, 11, 5, -10, -12, 12, -6, 6, -9, -6, 4, 9, 0, -9, 4, 3, -7, -5, -12, 19, 2, -28, 1, 0, 9, -10, -6, 3, 3, -11, -4, 6, 7, -7, -3, 5, -12, 9, 10, -12, 7, 5, 5, -6, -9, 16, 6, -16, 3, 8, -17, 12, -5, 2, 1, 21, -25, -10, 5, -2, 15, -6, 1, 3, 5, -16, -2, -16, 32, -17, 7, -13, 6, -1, -4, 0, -4, 10, -2, -17, -7, 29, 0, -13, -1, -1, 2, 12, -4, 3, -2, 4, -19, -1, 18, 2, -3, -15, -2, 10, -4, 1, -2, -5, 20, -5, -6, -7, 9, 0, -2, -24, 5, 15, -2, -11, 1, 0, -2, -14, -2, -4, 7, 4, -4, -9, 2, 4, -8, 8, -1, 2, 10, -13, 4, 10, -4, 27, -22, 17, -18, -2, 5, 8, -1, 4, -6, 2, -1, 9, 1, -3, 16, -21, -18, 2, 10, -14, 9, 3, -14, -9, 0, -16, 9, -10, 11, -12, -3, 1, -10, 3, -2, 2, -13, 13, 10, -1, 4, 4, 1, -3, 9, 0, 4, 8, -14, 10, -4, 0, 8, 11, -2, 2, -11, 3, -13, -8, 11, 4, 1, -7, 4, -21, 0, 1, -4, -22, 17, -8, -16, 10, 4, -2, 0, -4, 2, -2, 2, -6, 10, 3, 3, 5, -1, 6, 5, 2, -6, -3, -2, 7, -4, -4, 12, 1, -30, 12, -7, 3, 4, -6, -7, -9, 9, -1, 7, -10, 12, -16, 2, -8, 23, -5, -5, -1, -8, 10, 3, -14, -12, 25, 7, -13, -6, 4, 15, -3, -23, 9, 12, -9, -13, 18, -9, 5, 1, -17, -4, 13, -10, 11, -10, -1, 6, 0, -7, -2, 9, -4, 9, -24, 7, 6, -5, 4, 15, -15, 11, -5, -24, 9, 11, -16, 2, 0, -9, -2, 10, 7, -12, 8, -12, -6, 10, 6, 10, -14, -5, 20, -16, 7, 8, -1, -19, 24, 2, -10, 15, 6, -6, -21, 3, -3, 15, -9, -3, 3, -2, -4, -3, -9, 5, 0, -5, -3, -15, -4, -1, 1, -14, 33, -12, -18, 9, -2, -10, 9, 9, -1, -1, -5, 10, -3, 2, 4, 2, -9, -1, 25, -2, -3, 15, -17, -7, 8, -7, 0, 10, -13, 9, -11, 0, -3, 18, -15, -11, 5, 0, -12, -2, 7, -6, -4, -9, 11, -6, 8, 1, -14, 3, 16, -10, -3, 2, 6, 4, 9, -9, -2, 0, 2, -3, 15, 3, -10, -4, -8, -1, 10, -13, -9, 16, -9, -3, -2, 5, -6, -6, -9, 10, 8, -4, 14, -7, -19, 12, 1, 2, 1, 4, -1, -6, -3, -3, 5, 7, -2, 0, 0, -5, 0, -6, 1, 6, -5, -4, 5, -6, 5, -4, -8, 15, -5, -7, 0, 3, -8, 0, 3, -8, -4, 6, -4, -4, 15, -5, -8, -7, 4, 7, -10, -6, 15, -4, -13, 7, 2, 2, 1, -4, 5, 0, 0, 1, 4, -7, 4, 4, -2, 4, 5, 1, -18, 12, 4, -3, -6, 11, 0, -13, -1, 1, -12, 3, 13, -9, -15, 7, 0, -4, -8, 0, 5, 0, -9, 1, 1, -3, 0, 3, 5, -10, 6, -1, -4, 4, 15, -15, -5, -9, 18, -2, 0, 15, -11, -9, 0, 6, -2, 8, 1, -8, -9, 7, 3, -7, -3, 6, 1, -5, 0, -5, -5, 0, -3, 11, 1, -3, -8, -4, -4, 5, 9, -6, -7, 4, 15, -13, 5, -4, 2, -6, -2, 0, 5, 4, -4, 0, -6, 8, 3, -2, -4, -4, -11, 4, 10, -1, -4, -2, -1, -3, 1, -4, -2, 3, 1, -4, -11, 12, -4, 5, -2, 7, -12, -2, 4, -4, 5, 8, 1, -8, 14, -11, -1, 1, 4, 0, 5, -5, 2, -7, -7, 10, 3, 1, -13, 0, -4, 5, -9, -1, 1, -11, -5, 5, 2, -6, 5, -5, -8, 12, -2, 7, -1, -10, -5, -7, 14, 9, 3, -5, -2, 5, 4, -2, 0, -5, 2, 3, 3, -12, 6, 3, 2, -9, -1, 24, -13, -9, -1, -2, 0, 7, -6, -17, 14, -12, -5, 10, 1, -4, -1, -1, 1, -3, 2, -2, -11, 1, -1, -1, 1, 10, -3, 2, 1, 5, -7, 1, -1, -5, 7, 1, 7, -4, 5, -11, -8, -8, 7, 8, 6, 0, -15, -1, 7, 0, -6, -3, 7, -4, -3, -2, 1, 5, 8, -6, -4, 11, 3, -14, -6, -3, -6, 9, -5, 4, -5, 2, 3, -13, -3, 1, -4, -3, 11, -1, 0, 7, -16, -6, 11, 5, 0, 4, 5, -2, -3, -2, 8, 7, -16, 1, 2, 6, 3, -17, 11, -2, -2, -9, 6, 0, -7, 6, -22, -2, 14, 3, -11, 0, -6, -2, -7, -7, 1, 4, 14, -1, -6, 0, 7, 3, -14, 4, 15, -4, -9, -2, 12, 14, -10, 5, 9, -11, -2, -9, 2, -9, 11, 2, -21, 7, 6, -11, -1, 0, 0, 1, -9, 4, 0, -10, 1, 3, -3, -7, 12, -9, -2, 4, 6, 3, -8, 0, 1, -2, -14, 12, 11, -5, 10, -3, -1, 3, -6, 1, 0, -3, 8, -1, -18, 12, 5, -13, -4, 17, -1, -6, 1, -11, 0, -6, 2, -2, -2, 5, 3, -17, 2, -5, 11, -4, 8, 8, -19, -6, 14, -6, -6, 0, 5, 0, -8, 7, 13, -6, -5, 6, -2, -9, -1, 8, 3, -4, -4, 10, -10, -9, 7, 2, -6, 14, 0, -15, 3, 5, -4, -10, 8, 0, -6, -11, 3, 10, -9, 1, 8, -7, 2, -1, -6, -8, 6, 2, -8, -2, 16, -3, -3, -1, 5, -3, -8, 6, 9, -6, 1, -1, -1, 2, -6, 6, -1, -9, 3, 9, -10, 1, 5, -4, -14, 2, 1, 7, -5, 3, -2, -13, 5, 10, -9, -8, 14, -6, -19, -3, 19, -3, -3, 6, -4, -10, 3, -1, -4, 5, 5, 1, 0, -1, 11, 4, -10, 3, -5, 4, -7, 1, 8, -3, 1, 2, 0, -10, 2, 5, -15, -3, 8, -8, -6, 5, -2, -5, -5, 11, 0, -12, -7, 5, 2, -5, 2, -1, -4, 2, 7, -12, 5, 6, -3, 5, -1, 12, 7, -13, -3, 0, 3, 0, 13, -1, -4, 0, -9, 5, -6, 5, -2, -10, -6, -2, 9, -8, 5, -6, -10, 5, 4, -6, -2, 1, 1, 6, -14, 10, -3, -4, -5, 1, 8, -16, 7, 7, -1, 0, 3, -5, 2, -1, -3, 11, -11, 9, 8, -18, 3, 8, 13, -4, -5, -9, 4, -2, -4, 9, 5, -6, -5, -15, -3, 17, -6, 2, -8, 4, 4, -4, -12, -3, -2, -2, -4, 5, -4, 1, 7, -12, -6, 8, 6, -2, 1, -3, 3, 10, -3, 7, -11, 12, 4, -1, -1, 1, 0, -11, 11, 4, 0, -2, -9, -2, -2, -8, -1, 5, -4, -5, -5, 1, 10, -8, -11, -5, -4, 5, -1, 1, 6, -2, -5, -5, 3, 6, -2, 6, -3, 0, 4, 5, 2, 4, -2, 1, 5, -2, -6, 11, -1, -5, 8, -14, 6, -2, -6, -11, 4, 2, -14, 6, -9, 5, -4, -3, 4, -12, -2, 2, -5, 4, 7, -5, 3, 6, -1, -3, -6, 0, 7, 0, 1, 6, 9, 4, -2, -7, -4, 7, 4, 4, -5, -5, 0, 3, -6, -1, 7, -2, -18, -1, 3, -15, 5, -2, -2, 0, 4, -10, -4, 3, 4, -10, 4, -1, 5, 4, -7, 8, -7, 0, 3, 2, -7, 13, 0, -2, -6, -6, 5, 10, -10, 4, -1, 2, -1, -5, 7, 5, -3, -7, 1, -5, 10, 1, -11, 7, 6, -10, -15, 12, 2, -4, 1, 0, -5, 3, 0, -2, 6, -5, -4, -13, -2, 3, 1, 4, 3, 3, -10, -7, -7, 11, -2, 2, 2, -7, 4, -1, 6, 2, 0, 8, 3, 0, -7, 8, 3, 5, -8, -3, -2, 2, 3, -12, -4, -3, 12, -12, -4, 7, -3, -10, -10, -4, 6, -2, -8, 9, 1, 1, 1, -3, -6, 12, -5, -6, -1, 11, -7, 5, 6, 2, 9, -11, 6, -2, 8, 1, -6, 4, 3, -6, -3, 5, -4, 4, 1, -19, -1, 3, 4, 0, 0, -10, -1, -3, -5, -3, 0, 11, -1, -12, -2, 6, 0, -3, 3, 4, -1, -7, 1, -2, -1, 2, -1, 0, 2, -2, 4, -5, -4, 11, -4, -5, -3, 7, 5, -8, 3, 6, -9, 0, 9, -5, -2, 5, -4, -6, 0, 7, -1, -2, 0, -1, -6, -9, -6, -1, 8, 4, -1, -9, -5, 13, 2, -11, -5, 9, 0, -8, -1, 5, -2, -5, -3, -2, 7, 5, -4, -13, 3, 11, -8, 3, 0, 2, 5, -12, -6, 6, 3, -4, -1, 8, 1, -5, -7, -6, 2, 8, 5, -2, -9, 7, -6, -2, 13, -7, 2, 1, -1, -5, 3, 7, -1, -11, 9, -6, -4, -2, -5, -1, 2, -1, 3, 8, -7, -1, -9, 0, 0, -1, 2, 5, -2, 1, -2, -3, 6, 6, -3, -6, -5, 4, -1, 1, 5, 1, -1, -2, -3, -4, 4, 3, 1, -7, 5, -1, 0, -8, -6, 1, 7, -3, -6, -2, 3, -1, -3, 2, 2, 0, -9, 1, -2, 4, 4, -5, 1, -1, 1, 6, -2, 2, -5, -4, -1, 14, -3, 2, -9, 1, -2, -4, 1, -1, 7, -9, 5, 2, -3, 2, -2, -9, -2, 4, -1, 2, -2, -2, 0, -1, -1, -2, 3, 1, -1, -3, -6, 3, 7, -5, -3, 9, -5, -4, -5, 8, -4, 2, 2, 8, -10, -1, 8, -14, 0, 6, -7, -1, 2, -3, 2, -4, 5, 2, -5, -4, 5, 1, -6, 3, 6, -4, -1, -3, 3, -7, 0, 1, 0, -4, 7, 6, -13, -3, 3, 2, -15, 8, 3, -3, -6, 9, -4, -1, 9, 1, -6, -6, 7, 1, 1, -2, 6, -1, -4, -1, -1, -7, 5, 3, 0, -5, -2, 8, -2, -8, 6, 7, -16, -5, 6, -6, -1, 1, 7, -4, -3, -6, 3, -10, -3, 8, -9, -1, 5, -1, -7, 5, 2, -1, 1, 5, 1, 2, -4, -5, 1, 1, 3, 1, -5, -2, 3, 2, -7, -1, 7, 5, -5, -7, 5, 0, 3, -1, -4, -4, 4, 0, -4, 1, 6, -3, -7, 0, -3, -3, -1, 0, -2, -4, 2, 1, -2, 3, -1, 0, -1, -6, 9, -5, 4, -1, -1, 4, -2, 5, -8, 2, -3, -2, 2, -3, 10, 2, -3, -5, 2, -4, -1, -3, -7, 9, 1, 0, 0, -5, 1, -2, -12, 6, 8, -18, 4, -1, 4, -1, 5, -5, -3, 3, -1, 4, -5, 9, -5, -4, -5, 2, 5, -1, -4, 0, -3, -2, 8, -5, 2, 1, -13, 3, 1, 4, 5, -8, 2, 8, 1, -1, 1, -9, 1, -2, -4, 1, 4, -3, 4, -4, -5, 6, 5, -6, -3, -3, 1, 1, -7, 1, 2, 1, -5, -4, -2, 2, -6, 6, 3, 7, -10, -9, 4, 1, -5, 6, 9, 3, 1, -2, -4, 3, 4, -1, -6, 3, 1, -2, -9, 4, 4, -5, 4, -10, 2, -4, -5, -1, 1, 2, 0, 2, -8, 1, 3, -4, -13, 0, 10, -1, -4, 5, 0, -4, 5, -3, 2, -5, 2, 1, 2, 4, 2, 2, -10, 5, 3, -11, -2, 3, 3, 0, -6, -2, 1, 1, 2, -1, -8, -1, -5, -4, -3, 5, 8, -4, -4, 2, 0, -2, -2, 1, -5, 0, 13, -8, -6, 4, 8, -6, -1, 6, -2, 4, -5, 3, 5, -7, -8, -2, -3, 7, 8, -8, -3, 1, 5, -5, -5, 9, -4, -7, -5, 4, 3, -6, 5, 1, -1, 3, 0, -6, -9, 0, -6, 1, 4, 10, 5, -13, 0, 6, -2, -4, 2, -2, 6, -1, -4, 0, -11, 6, 3, -1, -3, 14, -1, -15, 1, 2, 3, -1, 4, -3, -6, 0, 3, 0, -6, 10, -3, -14, -2, 10, -3, -9, -4, 0, 6, -1, 7, -3, -5, -6, 1, 0, -5, 11, -2, 1, -2, 5, -1, -4, -1, -3, -4, 2, 11, 2, -4, 1, 2, -12, 7, 3, -1, -11, 3, 15, -8, -11, 0, 0, 2, -7, 1, -3, -4, -3, -5, -4, 6, 11, -7, -8, -1, 6, -5, -3, 6, 8, 3, -6, 1, -1, -1, -1, -5, -3, 8, 7, 4, -9, 1, -2, -4, -6, 9, -4, 3, -8, 0, 6, -2, -4, -2, -2, -6, 8, -7, 3, 1, 3, -1, -3, 2, 1, -6, -9, 3, -5, 8, 5, -10, 7, 5, -3, -2, -1, -3, -1, -4, -7, 6, 6, 3, -7, 0, 0, 1, 0, -7, 3, -1, 0, 1, 2, 2, 2, -11, -8, 9, 6, 2, -6, -1, 1, -3, 3, 1, -6, 2, -3, -2, -1, 2, -4, 0, -4, -2, 0, -3, -2, -6, 5, 2, 0, -1, -3, -1, 3, 1, -2, 0, 2, 2, 0, 1, 7, 1, -4, -2, -6, 4, 3, -1, -4, -1, 3, 3, -9, -2, 0, -2, -1, -5, 6, 1, -5, 1, -5, 9, -10, -4, 0, -4, 6, 1, -3, -5, 9, -2, -5, 2, 0, 6, -6, 2, 5, 10, -8, -3, -2, -1, 4, -3, -1, -4, 0, -1, 1, -4, 0, 5, -8, -1, -5, -1, -1, 3, 3, 3, 2, -14, -5, 1, 2, 3, 1, -1, 2, 5, -2, 2, -5, 2, 3, -2, -2, -3, 4, 4, 4, -6, 3, 1, -10, 1, -6, 6, -2, -3, 0, -3, 1, -3, 1, -1, -4, -5, -4, 7, -2, -2, -3, 6, -5, -5, 2, -6, 1, 4, 3, -8, 11, 4, -4, -1, 2, 3, -5, -2, 1, 7, -4, 2, 4, -10, 7, -7, -1, 0, -3, 5, -4, -1, -4, 5, -7, 3, 3, -11, -2, -1, 5, 1, -1, 0, 6, -11, 0, 1, -2, 1, 0, -1, -4, 2, 9, -2, -9, -4, 2, 0, 2, -1, 1, 1, -7, 5, -3, 4, -1, -3, -8, 5, 7, -1, -1, -3, 3, -7, 0, 4, -3, -3, 1, 6, 0, -1, 0, -5, -1, 0, -4, 0, 0, -3, 1, -4, 1, 7, -3, -13, -2, -2, -1, 3, 5, 2, -6, 1, 6, -2, -6, 8, -1, -6, 0, 4, 6, -2, 0, -2, -4, 3, 5, -4, -7, 2, 5, -3, -3, 3, 1, -10, -7, 3, 1, -3, 2, 4, -7, -3, 0, 2, -5, -3, 3, -2, 0, 3, 5, -6, -1, 4, -2, 0, 5, 1, -2, -2, 3, 2, -1, -3, -3, -7, 7, 3, -1, -2, 0, 0, 1, -2, 1, 0, -15, -1, 3, 2, -3, 4, 0, -7, 0, -1, -1, -4, -3, 2, -1, -1, 11, -3, -1, -5, -1, 2, 2, 0, 1, 2, 3, 4, -6, -3, -2, 1, 0, -4, 2, 1, -1, -5, 1, -1, -7, 2, -2, -5, 0, 2, -2, 3, 5, 0, -2, -6, 6, -7, 3, -4, -6, 1, 6, 3, 1, -2, -3, -4, -6, -1, 7, -2, 0, -3, 0, 9, -3, -5, -1, 3, 0, -1, -3, 6, 1, -6, -3, 3, 6, 0, -6, -4, 2, 1, -1, 2, -5, 4, 1, -2, -5, 0, 7, -9, 3, -1, 1, -6, 0, -5, -1, 1, -1, 0, -4, 2, -2, -2, 1, 6, -1, -5, 0, 0, 0, 1, 3, 2, 2, -1, -3, 0, 1, 5, 1, -5, -7, 2, 6, -3, -3, -3, 2, -7, -5, 5, 0, 0, -3, -4, -1, 3, -4, -5, 1, 5, -1, -2, -4, 0, 5, 2, 0, 2, 2, -1, -1, -5, 5, 3, -1, -4, 1, 0, -1, -2, -1, 2, 2, -4, -4, 2, -2, -3, -4, -3, 0, 3, -3, -2, -2, 4, 1, -2, -2, 1, 2, -6, -1, 2, 6, 1, -2, 0, 4, -3, -1, -2, -1, 5, 1, -11, 4, 3, -1, -6, 2, -2, 3, -4, -8, -2, -1, 4, 0, 3, -2, -1, -2, -2, 1, 3, 3, -7, 0, 2, 10, 0, -4, 3, -3, 0, 0, 3, -4, 6, -4, -8, 2, 1, 3, -14, 1, -1, -2, 0, 0, -5, -1, 2, -6, -1, 3, 0, -5, -3, 3, 1, 6, -2, 0, 6, 2, -7, 1, 3, -5, 5, 8, 0, -1, 1, -4, -6, -2, 6, 4, -4, -1, 1, -10, 0, -4, 0, -3, 2, 0, -8, 3, -3, 0, 2, -1, 1, -8, -1, -1, -3, -1, 4, 1, 6, 1, 0, 0, -2, 0, -2, 7, -4, 3, -1, 2, 0, -2, -2, -8, 3, 2, -1, -4, 3, 0, -3, -5, 2, -3, -3, -2, 5, 2, 1, 1, -4, 1, -1, 4, 6, -4, 0, -6, -4, 1, 3, 3, -1, -2, -7, -1, -3, 6, -6, 2, 1, 5, -8, -5, -1, 2, -1, -3, -1, -1, 5, -7, 3, 3, 1, 4, -4, -3, -3, 8, 1, -2, 4, 4, -2, -8, 2, 1, 0, 2, 0, -6, 3, -2, -8, -2, 5, -1, -6, 0, 2, -1, -5, -2, -2, 6, 0, -5, -2, 3, 0, -5, -1, 6, 7, 2, -8, -4, 6, 2, -6, -4, 12, 2, -5, -2, -6, 1, 1, -3, -7, -3, 11, -3, -6, -1, 3, -2, -4, -4, 4, -3, 4, -2, -3, 1, 7, 0, -8, 7, 1, -2, -4, -6, 13, 0, -3, 1, 2, -1, -4, -3, 1, 3, -2, -3, -1, 0, 3, -1, -10, -1, 2, -8, -3, 3, 2, 1, 4, -6, -2, 1, -3, -1, -4, 6, 5, -1, -5, -1, 9, -2, 0, -4, 0, 1, -3, 4, -5, 1, 3, -4, -6, 0, 4, -2, -6, 9, -1, -3, 2, -4, 0, 4, -7, -4, -1, 1, 4, 0, -1, 6, -2, -2, 4, -3, -1, -6, -2, 2, 3, 1, -3, 8, -10, -10, 7, 0, -2, -1, -4, 3, -6, 0, -5, -5, 5, 3, -6, 1, 5, 0, -1, 1, -1, 0, 0, 0, -5, 7, -2, -1, 2, -1, 3, 0, -6, 4, -3, -2, -3, -2, 1, 3, 3, 0, -2, -1, -9, 2, 2, -1, 4, -4, 4, -10, 7, -8, 2, 1, -1, 0, -1, 4, 2, -7, 7, -6, -4, 3, 11, -5, -6, 1, 3, -4, -6, 2, 2, -2, -3, -7, -4, 6, 0, 7, -13, 6, 2, -9, -2, -5, 3, 8, 0, 0, 5, -5, -4, 3, 0, 2, 4, -7, 0, -1, 10, -3, -6, 7, 2, -1, 0, 6, -2, -7, 4, -2, -1, -2, 1, -3, -9, 6, 0, -4, 0, 3, 3, -11, -4, 7, -16, -2, 0, 2, 1, -2, 2, -5, -1, 12, -6, 2, -7, 2, 6, 0, -4, -1, 1, -3, 2, -1, 0, 7, -2, 2, -6, 2, 7, -9, -4, 8, 2, -9, -3, 8, 1, -1, 4, 5, -11, 2, 1, -1, 0, 0, -6, -2, 2, 6, -13, 2, -3, -8, 1, 1, 3, -2, -3, -2, -7, 4, -6, -2, 3, -10, 5, -2, 1, -3, 5, 8, -4, -1, 2, -1, 6, 2, 3, 2, -2, 0, -1, 0, 4, 1, -1, -2, 7, 1, -7, -5, 7, -5, 2, -5, -4, 0, 3, 3, -2, 0, -1, -9, -4, -9, 10, 1, -14, 0, -1, 6, -8, -3, 3, -1, -6, -1, 5, 3, -5, -1, 3, -6, 5, 7, -10, 5, 5, 2, -4, -3, 9, 4, -11, 0, 5, -11, 7, -6, 2, 2, 12, -15, -8, 2, -3, 7, -5, 3, 3, 1, -10, 0, -9, 17, -11, 7, -6, 2, 1, -3, 0, -1, 5, -2, -10, -4, 16, -1, -7, -1, -3, 1, 11, -3, 1, -3, 2, -12, -2, 12, 3, -1, -10, -2, 6, -3, 1, -1, -4, 12, -1, -2, -7, 6, -1, -1, -16, 5, 11, -3, -7, 1, -1, -2, -6, -4, -5, 3, 4, -3, -8, -1, 3, -5, 3, 1, 2, 6, -10, 1, 7, 0, 21, -15, 11, -12, 0, 1, 4, 1, 4, -4, -1, 3, 7, 0, -5, 10, -15, -14, 2, 6, -11, 5, 3, -10, -6, -1, -11, 4, -9, 6, -9, -2, 2, -8, 3, 0, 2, -9, 7, 7, 2, 2, 0, 3, 1, 6, 0, 3, 6, -10, 6, -4, 1, 7, 9, -1, 0, -7, 1, -11, -8, 9, 4, 0, -6, 2, -16, 0, 1, -2, -16, 10, -7, -12, 7, 4, -1, -1, -4, 2, -1, 2, -5, 8, 3, 3, 4, -2, 4, 3, 2, -4, -2, -1, 5, -5, -3, 9, 2, -22, 8, -6, 1, 3, -5, -4, -6, 7, 0, 5, -8, 9, -13, 0, -6, 18, -3, -3, -1, -6, 7, 3, -11, -9, 19, 6, -10, -6, 3, 12, -2, -18, 7, 8, -7, -10, 14, -8, 5, 1, -15, -4, 11, -6, 9, -8, -1, 5, 1, -6, -2, 7, -3, 7, -20, 6, 5, -4, 3, 12, -12, 11, -4, -22, 7, 9, -13, 1, 0, -8, -1, 9, 6, -10, 5, -9, -5, 8, 5, 8, -12, -4, 16, -14, 7, 6, -1, -16, 21, 2, -9, 13, 5, -4, -19, 2, -3, 12, -7, -2, 3, -2, -4, -3, -8, 4, 1, -4, -4, -14, -3, -1, 1, -11, 30, -11, -16, 8, -2, -9, 8, 8, -1, -1, -5, 10, -4, 1, 4, 3, -8, -1, 23, -2, -2, 14, -15, -7, 7, -7, 0, 9, -12, 8, -10, 0, -3, 16, -13, -11, 5, -1, -10, -2, 6, -5, -4, -9, 10, -6, 7, 1, -13, 2, 14, -9, -3, 2, 6, 4, 8, -8, -2, 0, 2, -3, 14, 3, -10, -4, -8, -1, 10, -13, -8, 15, -9, -3, -2, 5, -5, -6, -9, 9, 7, -4, 14, -7, -18, 12, 1, 2, 1, 4, -2, -6, -3, -2, 5, 7, -2, 0, 0, -4, 0, -6, 1, 5, -5, -4, 5, -6, 5, -4, -8, 15, -5, -6, 0, 3, -8, 0, 3, 0, -1, 0, -4, 6, -16, 22, -7, 3, -5, 2, 2, 1, -3, 4, -8, 4, 4, 0, -5, -9, 4, -5, -4, 3, 2, 1, 3, -4, 6, -15, -1, 4, 1, -9, 3, 1, -8, 3, -6, 11, -5, 6, -11, 17, -15, -2, -19, -11, 1, -4, 8, 0, 5, 18, -11, 0, 13, -4, 6, -13, 4, -11, -1, -7, -7, 11, 10, -9, 17, -11, 20, -6, 7, -14, 23, -7, -2, -2, 7, -10, 2, 0, 2, 5, 6, -8, 5, -4, -10, 9, -4, 6, 0, -7, 8, -7, 1, -20, -4, -1, -3, 6, -10, -6, -15, -11, 10, -5, 19, 3, 1, -19, -11, -1, -9, 9, 22, 24, 10, -5, -18, -8, -23, 14, 11, 0, 31, 43, -9, 0, -7, -15, -28, -35, -30, 3, 5, -5, 11, 52, 55, 7, -5, -10, -12, -25, -43, -12, 4, -37, -47, -21, -5, 4, -11, 1, 31, 27, 34, 46, 48, 61, 10, 16, 8, 7, -14, -40, -47, -36, -51, -42, -15, 4, 12, -32, -42, -10, -4, 10, 1, 15, 50, 31, 5, 15, 38, 37, 29, 15, 22, 11, -4, -35, 10, 3, -18, 1, -14, -33, -5, -47, -25, -13, -2, 15, -6, 5, -29, -17, -19, -1, 3, 7, 2, 17, 28, -8, -23, 7, 7, 36, 15, 2, 1, -2, -9, 1, 6, 20, 6, 14, -3, 21, -11, -12, -35, 11, -20, -18, -36, -23, -27, -19, 1, 10, 14, 27, 6, 44, 14, -9, 3, 20, 27, 45, -8, -13, 16, -16, 24, -10, -9, -3, -38, -19, -14, -38, -38, -41, 13, 40, -37, 5, -7, -7, -4, 4, -31, 32, 22, 15, 9, 13, 10, 10, -17, 22, 30, 9, -6, 27, 66, 47, -17, -21, -20, -9, -36, -73, -3, 22, -35, -12, 6, 7, 4, -17, -45, 22, 17, -17, 3, -9, -4, 11, -10, 13, -4, 8, 38, 3, 20, 42, -22, 9, 23, -28, -21, 3, 10, 1, 26, -28, -18, -9, 7, -30, -41, -24, -9, 10, -6, 31, -5, 2, 29, -9, 1, -27, -24, 7, -19, -5, 10, -13, 21, 21, 3, 30, -11, -17, 34, -11, 8, 7, -8, 1, 11, -1, 7, -13, 1, -3, 23, -12, 8, -19, -3, 20, -78, 42, -23, 4, -29, -16, -5, 38, -49, 30, -26, 26, 16, 8, -33, 53, 19, -20, 12, 5, 23, -11, 4, -6, 42, -111, 67, -40, 29, -32, -20, -77, 113, -46, -12, 8, -5, -14, 35, -52, 94, -5, -61, 58, -36, 41, -83, 21, -19, 61, -68, 37, -37, 12, 66, -69, -16, 100, -88, 48, 21, -39, 73, -24, -2, 45, 65, -59, 53, -103, 95, -97, 1, -14, -4, -41, 9, -13, -18, 16, -26, 9, 26, -15, 25, -16, 6, 8, 26, -52, 35, -21, 4, -2, -11, -4, 22, 0, 21, -40, 65, -6, -13, -11, -7, 32, -46, -48, 16, -26, -3, 0, -42, 87, -68, 34, 17, -14, 43, 23, -15, 30, 20, 47, -19, -33, -12, 15, 1, -37, 15, -12, -11, -7, 15, -75, 36, -41, 27, -8, -7, -12, 10, -4, 49, -6, 42, -32, 4, 20, 33, -65, 24, -52, 10, 13, -17, -15, 60, -14, -55, 35, -16, 50, -83, -3, 29, 58, -75, 71, -46, 47, -32, 44, -57, 10, -43, 33, 22, -48, 51, -41, 6, 7, 39, -3, -41, 7, -9, 37, -66, 22, 26, -13, 74, -87, 127, -39, -16, -29, -11, -8, -57, -15, -45, 52, -74, -5, -2, 103, -126, 85, 20, 28, -7, 53, -38, 58, -10, -11, 33, -70, 20, 1, 40, -36, 26, -58, 58, -23, 61, -71, -7, -39, 43, 22, -18, -1, -61, 90, -37, 35, -58, 30, -62, 27, -45, 47, -59, -6, -35, 70, -49, 9, -30, 92, -15, 21, 1, 26, 6, -19, 90, -43, 49, -46, 10, 6, 15, -90, 67, -51, -11, 4, 28, -36, 24, 41, -68, 24, -34, 63, -40, 17, -30, 18, -39, 14, -38, 15, 9, -54, 54, -20, 36, -21, -14, -13, 11, 23, 11, -54, 56, -25, 37, -46, 49, -74, 81, -40, 51, -44, 57, -69, 51, -50, 61, 27, -112, 111, -114, 106, -85, 49, -61, 75, -18, 26, -68, 32, -15, -25, 21, -15, 38, -46, 80, -119, 126, -85, 41, -40, 77, -65, 28, -6, -39, 45, -87, 39, -63, 81, -32, 4, -32, 44, -25, 42, -12, -15, 21, -1, -56, 21, 23, -30, 33, -28, -3, 32, 4, -36, 60, -20, 13, -3, 22, -43, 101, -88, 59, -53, 18, 8, 22, -33, -52, 34, -32, 35, -90, 112, -107, 56, -59, 43, -60, -18, -4, -21, 45, 11, -48, 11, 38, -27, 58, -49, 65, 19, 54, -38, 35, -37, 24, -11, 44, -62, 41, -16, -48, -8, 31, -68, 17, -3, -5, 52, -51, -10, 16, -26, 18, -29, 56, -41, 3, 5, -10, -37, 61, -14, -10, -9, 20, -8, 8, -2, -16, 44, -17, 14, -33, 30, -2, -27, 16, 3, 0, 51, -42, 32, -20, 8, -11, -24, 10, 12, -15, 6, -32, 10, 21, -38, -11, -12, 23, 13, -64, 19, 34, -23, -23, 16, 10, 39, 2, -36, 55, -31, 0, -29, 18, 8, 12, -61, 73, -28, 54, -34, 21, 9, 7, 53, -34, -29, 19, -7, -44, 7, 15, -16, -18, -31, 10, -29, 36, -69, 7, 4, 33, -72, 45, 14, 0, -8, 35, -13, 26, 16, -28, -3, -32, 45, -4, 8, -20, 65, -24, 2, -24, 40, -16, -16, 20, 8, 2, -3, -2, 23, -15, -11, -30, 19, -51, -19, -5, -36, 18, 24, -4, -1, 46, -90, 60, 4, 23, -17, 16, 60, -24, 0, 18, 0, 5, -6, -24, 27, -34, -28, -7, -4, 22, -30, -11, -3, -1, -44, 36, -38, -6, -9, 55, -34, 16, 27, 28, -65, 62, 22, -32, 36, 7, 2, 27, -19, 50, -71, 44, -19, -67, 13, -3, -14, -30, 33, 5, -12, -48, 60, -47, -28, 9, -6, 24, -11, -1, 13, 62, -53, 26, 7, -9, 6, 58, -38, -10, 0, 5, -23, 23, 8, -14, -19, 21, -9, 35, -17, -28, 14, 27, -17, -14, -29, 24, 6, -85, 74, -16, -18, -2, -19, 47, -29, -18, -15, 52, 0, 7, -10, -23, 45, 13, -11, 12, -28, 27, -26, 19, -69, 74, -55, 35, -21, 41, -24, -11, 39, -19, 7, 0, 7, -31, 10, 7, -45, -17, 25, -12, 9, -19, 3, 28, -53, 76, -19, -25, 49, -2, 6, -11, 24, -12, -23, 17, -1, -15, -10, -36, 26, -25, 0, -44, 59, -67, 45, -31, 5, 15, 56, -12, -14, 12, 10, 24, -52, 37, 5, -35, 52, 23, -55, -6, 24, -49, 26, 31, -24, 10, -33, 33, -11, 1, -49, 8, 7, 6, -78, 12, -22, 10, -11, 13, 13, -18, 38, 50, -18, -5, 64, -52, 59, 33, 3, -9, -6, -6, 26, -64, 18, -38, -47, 18, -33, 4, -39, 40, -31, -1, -23, 48, -30, 18, 17, 32, -20, 32, 19, 24, -58, 49, -38, -9, 15, -28, 16, -3, -2, -28, 33, -22, 23, -1, -34, 33, -48, 67, -55, 21, 51, -66, -2, 21, -5, -17, 24, -63, 53, 8, -19, 9, -11, 36, -37, -35, 43, -35, -3, -44, 68, -43, 53, -24, -5, 45, -16, -7, 14, 49, 3, -16, 22, -10, 2, -28, -9, -6, -5, 32, -76, -22, 35, -26, -35, -12, 0, 3, 13, 6, 36, 7, -32, 69, -15, 45, -20, -21, 35, 35, 1, -25, 11, 34, -24, -33, -9, 5, -25, -49, 31, -41, 15, -42, 25, -30, 42, -80, 32, 2, -18, 33, -12, -9, 43, -1, 4, -12, 54, -51, 22, -1, 18, 28, -29, 18, 7, 10, -19, 8, -1, 12, -21, -6, -11, 4, 4, -28, -8, 22, -27, -5, 9, -25, 20, -19, -36, 41, -8, 20, -32, 16, -29, 29, -13, 13, 4, 1, 17, 8, 0, 9, 22, -1, -3, 28, -11, -39, 36, -31, 5, -11, -27, 22, -39, 7, 15, -24, 19, 8, -37, 75, -52, 54, -65, 22, -13, 23, -26, 32, -19, 10, -8, -3, 12, 16, -44, 25, -23, 14, 9, -46, 20, 2, -4, -8, -6, 18, 4, -2, -3, -15, 4, 16, -9, -5, 34, -29, 27, -54, 98, -65, 11, -18, 16, -13, 0, -2, 0, 22, -43, 31, -46, 58, 2, -25, -2, 16, -2, -29, 17, 18, -26, 21, -17, 5, -4, -9, 0, -34, 50, -27, -3, 4, 31, -3, -47, 32, -25, 36, 6, -47, 33, -28, 39, -36, 42, -28, 5, -3, -2, 25, 27, -47, 20, 22, -5, -15, 1, -9, 16, -25, -10, -43, 40, -12, -19, 22, -24, -5, 14, -44, 42, -32, 32, -45, 40, 41, -17, 27, -44, 38, -16, 15, -36, 39, -13, -19, -4, 34, 1, -9, 9, -16, -2, -29, 31, -31, -4, 35, -21, -52, 63, -41, 2, -7, 30, -35, 13, 9, 15, -4, 14, -36, 18, -14, 55, -50, -6, 22, -23, -11, -5, 12, 17, -13, -43, 44, -33, 41, -42, 45, 3, -12, 26, 11, -11, 35, -76, 39, 2, 0, 3, -4, 15, -19, -6, -33, 11, 5, 16, -25, -2, 19, -7, -43, 30, 20, -27, -18, 12, 14, 33, -50, 14, -15, 23, 8, 2, -10, -4, 53, -86, 24, -9, 41, -34, -21, 22, 24, -54, 27, 13, 2, -9, 14, -29, 21, 40, -43, -9, -3, 27, -3, -22, 18, 10, -23, -15, 1, 14, -12, 3, -30, 30, -22, -28, 36, -15, 39, -57, 21, 3, -3, 33, -13, -2, 6, 20, -6, 4, -13, -5, -18, 13, -7, 7, 26, -26, 16, 7, -64, 37, -7, 10, -20, 12, -11, 7, -34, 37, -12, -24, 34, -18, -18, 39, 9, -42, -24, 43, 2, -16, 25, 12, -16, 8, 12, -44, 32, -9, 23, 1, -37, 40, -23, -17, 18, -42, 23, -12, -7, 10, -6, 6, -13, -13, 30, -23, 36, -4, 7, 17, -18, 18, -3, 8, 5, -1, -13, -15, 2, -5, -16, 7, -52, 23, -38, 30, -30, 16, -26, 21, -22, 24, 3, 20, -28, 22, 22, -31, 42, -16, -11, 32, -26, 0, 31, -14, 11, -15, 14, -17, -9, 10, 11, 27, -38, -4, 14, -18, 36, -44, 0, -11, 16, -14, -2, 16, -34, -23, 22, 4, -24, 14, -13, 16, 31, -28, -10, -6, 51, -27, 13, -49, 3, 68, -38, 1, 8, -27, 26, -16, 0, 15, -36, 7, -6, 38, -11, 0, -14, 10, -4, 22, -48, 31, -1, 23, -38, 1, 15, -7, 10, -1, -3, 4, -1, 10, -2, -12, 3, -22, 5, 9, 8, 4, -14, 12, -3, -7, 22, -20, 3, -6, 13, -15, -8, -7, 16, -14, -1, -3, 6, -17, 12, 22, -44, 68, -67, 50, 13, -20, -11, -4, -20, -3, 22, -13, -20, 28, -7, 2, 11, -9, -23, 5, 5, -26, 24, -31, 2, 20, 15, 2, -7, 4, 19, -6, 41, -51, -3, 24, 27, -30, 25, -37, 1, -7, -2, -4, -26, -1, 12, 5, -12, 9, -30, 5, 11, 26, -18, -32, 42, 7, 0, -23, 10, 10, -20, 53, -49, 6, -39, 18, 3, -27, 41, -21, 16, 28, 14, -24, -15, 19, 5, 16, -31, -1, 45, -25, -6, -16, -4, -19, 37, -47, 21, 2, -14, -7, 30, -35, 13, -30, 14, 21, 11, -18, -28, 37, 12, -18, 9, 5, -1, 33, -41, 3, -7, -19, 8, -14, 12, 15, -18, -4, 44, -25, 22, -46, 19, 40, -25, -12, -5, 17, 7, -53, 25, 4, -10, 14, 16, -31, 40, -27, -11, -4, 28, -40, -5, -9, -3, 34, -47, 33, -5, 11, -33, 33, 0, -14, 35, -18, -27, 11, 14, -37, 35, -20, 7, 15, 2, 27, -17, 15, -31, -1, 11, -27, 24, -26, 14, 13, -35, 20, -13, -2, 16, 16, -6, 2, 15, -7, -22, 51, -36, -2, 20, -19, 23, -20, -19, -9, -14, 8, -4, -13, 35, -66, 36, -37, 3, 19, -1, 15, 32, -45, 71, -15, -5, 12, 34, -33, 24, -5, 20, -43, 42, -59, 13, -12, -69, 66, -29, -34, 17, 7, -28, 24, 5, -27, 51, -40, -9, 46, 3, -17, 36, -56, 63, -7, -31, -19, 53, -12, -10, 4, 19, -47, 35, 0, -40, 17, -14, 13, -11, 11, 3, -39, 22, 5, 21, -19, -11, 25, -4, -5, 20, -13, 25, -6, -16, -16, 29, -61, 25, -33, 12, -17, 7, -19, 34, -27, 15, -19, 32, -26, 54, -46, 6, 9, 14, -6, -6, 23, -32, 58, -19, -5, 15, 46, -42, 39, -7, -23, -7, -14, -22, 42, -66, 0, 4, -8, -11, -4, -3, -7, 7, -23, 30, -14, 19, 8, -9, 20, 36, 5, -24, 25, 12, -20, 16, -53, 60, -49, -26, 24, -87, 67, -49, 13, -7, 5, -14, 5, 11, 38, -3, -15, 27, 26, -36, 20, 30, -47, 29, -5, 9, -10, 38, -65, 47, -49, -4, -10, -6, 1, -1, -28, 16, -14, 3, -14, 27, -8, 1, 2, 23, 21, -53, 40, 24, -16, -12, -2, 11, 17, -8, -18, 8, -25, 28, -10, -12, 13, -51, 10, 35, -10, -8, -9, 8, 10, 14, -20, 4, -9, 37, -5, -2, 2, 4, -9, -5, 16, -16, -23, 13, 7, -9, 14, -49, 13, 8, -3, -13, -9, 22, -8, 12, -13, 36, -36, 35, -17, 23, -12, 0, -37, 50, -31, -8, -31, 43, -4, -11, 0, 3, -7, -19, 16, -16, -28, 46, -28, 27, -13, 33, -21, -1, 39, -13, 3, -4, 4, -39, 74, -30, -17, 33, -3, -20, -12, 24, -94, 75, -63, 54, -62, 23, 4, 12, -33, 22, -35, 16, 12, -28, 34, 2, -12, -3, 22, 23, -31, -6, 26, 4, -41, 8, 37, -15, 21, -7, 18, -51, 42, -27, 35, -45, 35, -30, 18, 9, -20, 1, 18, -12, -51, 61, -61, 24, -20, 1, 11, -5, -2, -12, 11, 20, -35, -2, 37, -21, 23, -15, -2, 19, -51, 82, -50, 20, 29, -26, -34, 49, -2, -16, 11, -17, -4, 6, 15, -35, 13, -15, -10, -17, 15, 4, -42, 43, -31, 34, -30, 53, -43, 40, -22, 9, 9, -24, 64, -41, 29, -17, 8, -15, 8, 2, -27, 7, 10, -28, 0, 30, -50, 6, -13, -14, -21, 11, 9, 13, -47, 35, -11, 32, 28, -28, 1, 32, 2, -19, 28, -24, 9, 0, 19, -6, 16, -33, 6, -23, 33, -31, -1, -4, 26, -22, -22, -10, -11, 18, -26, 19, -8, -4, 21, -14, 36, -2, 12, -48, 49, -1, -13, -5, 8, -3, 9, -4, -18, 15, 28, -50, 10, 4, -7, 4, -39, 37, -39, 11, 2, -20, 13, 4, -6, 0, 35, -17, -9, 6, 38, -21, -1, -1, 12, -2, -16, 15, 7, -22, 18, -23, 11, 3, -9, -39, 29, -31, 44, -41, 0, 5, 21, -9, -25, 25, -6, 38, -55, 38, -14, 6, -26, 38, -24, 39, -39, -15, 17, 16, -20, -27, 17, 24, -20, -20, 33, 8, -31, 2, 2, 27, 11, -4, -7, 31, -20, -9, 4, -4, 17, -32, 2, -18, 31, -35, 38, -52, 42, -1, -28, -26, 25, 3, -51, 42, -35, 35, -39, 44, -38, 20, 20, -51, 34, 45, -10, -7, 27, -19, 33, -49, 22, 2, -7, -5, -27, 59, -24, -20, 21, -8, -15, 24, -51, 3, 9, -23, 24, -30, 2, 29, -26, -2, 4, 10, 0, -18, 50, 3, 9, -14, 17, -18, 24, -13, -33, 7, 25, -50, 2, -2, 30, -58, 31, -8, 23, -11, -1, -24, 21, 1, -41, 47, -30, 28, -39, 56, -16, -20, 51, -45, 33, 6, 23, -12, -19, -2, 7, 1, -14, -5, -11, -20, 25, -17, 7, -22, 21, -19, 34, -47, -2, 1, 33, -30, 14, 20, 6, -9, 17, 13, -22, 19, -58, 23, 26, -15, -52, 2, 18, 10, -13, 46, -5, -8, -6, 4, -14, 5, 11, -13, -7, 42, -25, 8, -37, 35, -10, 6, -25, 16, 15, -15, -9, -20, 18, -23, 26, -34, 35, -22, -10, 9, 14, -6, -21, 27, -8, 4, 1, 3, -19, 28, 2, -7, 30, -8, -13, 11, -9, -9, -19, 12, 0, -23, -1, -23, -6, 27, -31, 41, -28, 13, 5, 9, -21, 6, 2, -2, 18, -16, 31, -25, 40, -38, 39, -13, 8, 14, -3, 9, -30, 6, -12, -7, -15, 30, -64, 6, -22, 13, -8, 14, -40, 9, 32, -35, 14, -1, 12, -25, 63, -25, 35, -2, 19, -5, -3, 20, -29, -1, 35, -37, 53, -46, 4, -14, 22, -27, 23, -64, 8, 5, -25, 41, -18, 14, -42, 53, -56, 35, -42, 71, -63, 45, -38, 29, -12, 33, -22, 0, 24, -13, 3, 13, 1, -10, -19, 11, 19, -38, 5, -2, -18, -21, 33, -54, 41, 9, 4, -1, -21, 3, 3, 37, -31, 34, -40, 34, -19, 30, -26, 23, -53, 55, -8, -13, -16, 7, -13, 46, -38, 2, -3, 17, -1, -26, 18, -57, 68, -27, 23, -19, 32, -39, 2, 2, -18, 12, -16, 4, -23, 38, -65, 40, -5, 13, 19, -26, -13, 60, -25, 7, 1, 10, 22, -24, 23, -20, -16, -17, 14, -32, 26, -4, 17, -15, 9, -29, 4, -29, 11, 36, -18, -19, -2, 5, 28, -23, 31, 6, 4, 18, -14, 4, -7, 0, -45, 61, -31, 5, -15, -23, -21, 52, -62, 4, 22, 1, -9, 15, -24, -27, 60, -49, 38, 0, -6, 1, 13, 7, 4, 19, 6, 0, 27, -28, -14, -21, 17, -1, -30, 23, 10, -36, 18, -19, 2, -18, 0, 6, -1, 7, -1, -37, 26, 15, -35, 41, -24, 10, 10, -9, -12, 12, 7, 3, 10, -11, 11, -14, 27, -49, 71, -55, 25, 8, -11, 11, -5, -22, 7, 15, -17, -11, 18, 4, -54, 43, -38, 27, -1, 7, -13, 19, 10, -41, 50, -41, 13, 9, 10, -41, 38, -13, 13, -2, -2, -4, 9, -36, -5, 22, -31, -18, 8, 21, -22, 21, -24, 12, 3, 16, -24, 25, -16, 22, -35, 14, 3, 11, 12, -22, 40, -11, -25, 14, 0, 14, -2, 2, -10, -12, 14, -51, 11, -21, 55, -27, 9, 3, 38, 7, -25, 5, -19, 6, -14, 0, -10, 21, -57, 35, 18, -21, 21, -40, -13, 24, -24, -12, 10, -1, 11, 10, -12, -5, 38, -45, 23, 26, -13, -9, 32, 6, -3, 30, -28, -28, 27, 3, -10, -11, -10, 16, -28, 21, -12, -3, -1, -33, 14, -30, 12, -20, 40, -15, 7, 19, -18, -1, -1, 9, 4, -23, 32, 17, -19, 12, 16, -45, 4, -6, 18, -28, 36, -44, 44, -29, 10, 4, 14, -8, -13, 9, -30, 39, -17, -5, 10, -10, 5, -1, -16, 17, -7, -9, -10, 15, -21, 9, 10, 8, -10, -6, 3, -21, 34, -3, 6, -4, 15, 3, -2, 4, 26, -44, 30, -43, 2, 9, -5, -7, -18, 16, -28, 0, 5, -7, 0, 7, 0, -7, 21, -14, 17, 15, 2, -40, 7, 44, -30, 55, -33, -19, 40, -30, 17, -1, -20, -20, -20, 5, 14, 1, -7, -32, 26, -11, -11, 24, -23, 17, 17, 8, -19, 18, 11, -6, 17, -4, -13, 14, -9, 21, 9, -16, -8, 2, -16, 3, -9, -32, 6, -36, -4, 0, 10, -36, 26, -11, 3, 31, -20, 1, 7, 4, 45, -35, 39, 0, 4, 28, -21, 29, -39, 27, 15, -6, -14, 17, -25, -33, 16, -15, 18, -43, 28, -61, 33, 1, -27, 13, -19, -20, 26, 11, -27, 16, -21, 33, -13, 43, -44, 13, 24, -10, 35, -39, 36, 20, -39, 68, -68, 23, -16, -7, 0, 36, -30, -13, -27, 42, -21, -4, -23, -2, 23, 0, -3, -3, 2, 4, -15, -5, 28, -10, -20, 24, -7, 27, -58, 31, -7, -29, 39, -40, 41, -35, 8, -25, 30, 31, -17, -9, 3, 36, -8, -18, -11, 29, -2, 6, -25, 21, -5, -8, -17, -24, 20, -26, 20, -23, 46, -26, -13, 8, 13, 2, -15, 4, -9, 28, -25, -19, 49, 18, -50, 45, -11, -17, 5, -61, 15, 4, -22, -1, 22, 23, 33, -55, 46, -25, 37, 18, 2, -9, 11, -47, 23, -8, -25, 37, -32, 2, 5, 12, -18, -5, 19, -27, -7, 20, -40, 32, -44, -21, -29, 58, 8, -9, 57, -28, 29, -32, 14, -14, 4, 23, -33, 16, -4, -16, 21, 38, -37, 23, 10, -32, 17, 17, -12, -59, 9, -3, -12, 22, -13, -8, -26, 16, 1, 33, -9, -17, 16, -7, 21, -44, 26, 5, 35, -36, -1, 13, 36, -36, 39, -36, 17, -13, 2, -33, 20, -13, -51, -2, 9, -2, 35, -21, 19, -20, 18, -19, -5, 30, -39, 30, 22, -35, 74, -52, 33, -15, 17, -21, -13, 11, 6, -25, 25, -31, 29, -18, 18, -52, 40, -11, -17, -26, 56, -56, 69, -53, -14, 32, -10, -8, -2, 18, -14, 20, -18, 20, 22, -27, 0, -25, 56, -46, 16, -28, 52, -5, -33, 76, -75, 36, -1, -42, 42, -46, 13, -13, 25, -7, 35, -55, 5, 63, -56, 11, -24, 13, -8, -10, -27, 15, -15, 44, -66, 52, -3, -6, 0, 23, -33, 79, -55, 30, -27, 37, -18, -6, -2, -19, 52, -22, -50, 60, -32, 28, -56, 44, -28, 15, -37, -9, -28, 63, -75, 9, 39, 28, -21, 5, -17, 15, 2, -13, 30, 13, -14, 10, -12, 30, -22, -10, 4, -8, -9, 14, 6, -39, 34, -6, 4, 1, -5, 0, 33, -73, 34, -12, 23, -9, 53, -47, 17, 3, -18, -6, 2, -19, -12, -7, -45, 72, -9, -71, 55, -58, 50, -18, -36, 37, 19, -11, 13, -35, 32, 6, 5, 18, -6, 19, -26, 32, 16, 20, -43, 20, -10, -7, 16, -7, -68, 21, -36, 7, 19, -22, 19, -3, -35, -37, 25, 21, -57, 67, -9, 9, 32, -11, 28, -18, 35, -41, 60, -19, 29, 0, -38, 29, -6, -35, 0, 25, -37, -1, -31, -42, 30, -19, -21, 36, -66, 53, -33, 15, 16, -13, 20, -35, 73, -4, 18, 39, 4, 1, 3, 21, -2, -12, -18, -51, 44, -17, -50, 48, -30, -16, -13, -35, -7, 25, -33, -14, 14, 0, 8, -30, 45, -13, 50, -53, 28, 60, -33, 23, -7, -2, 15, 36, -11, 9, 19, -44, 4, -21, 19, -5, -27, -45, 48, 9, -47, -23, 12, 3, -25, -8, -21, 63, 1, -29, 31, -18, 19, 16, -24, -17, 50, -65, 65, -56, 93, -45, -17, -25, 45, -18, 23, -53, 50, -15, -12, -39, 51, -11, 11, 13, -31, 54, -14, -29, 22, -11, 10, -41, -19, 52, 10, -51, -60, 72, -13, 12, -38, 19, -2, 31, -56, 37, -4, -10, 22, -14, -33, 48, -40, 38, -14, 27, -24, 19, 29, 17, -31, -2, -41, 34, -17, 2, 5, 5, -13, -30, 14, 9, -9, 7, -11, 15, 5, -28, -2, 0, 45, -30, -25, 1, 10, 29, -55, -24, 52, -5, 5, 20, -25, 20, -15, 14, -64, 95, -53, 32, 13, -26, 31, -8, -27, 18, 48, -57, -3, -10, 25, -24, -32, -9, 18, 18, -33, -15, 27, -22, 14, -5, 10, 51, -21, -25, 19, 5, -15, -29, 16, 1, 33, -39, -12, 56, 14, -63, 36, -2, -17, 52, -11, -37, 5, 19, -52, 38, -23, -60, 93, -75, 52, -30, -2, -11, 49, -11, -25, 1, 42, -35, 26, -35, -9, 24, -1, 10, -6, -12, 7, 4, 22, -10, 41, -25, -8, -4, -2, 28, -43, 19, -32, 4, -27, 9, -47, 51, -16, 12, -52, 49, 8, 7, -37, 27, -33, 80, -44, 6, 5, 28, -15, 16, 15, 2, -12, 50, -77, 38, -38, -45, 30, 8, -37, -13, -8, -18, 50, 3, -54, 29, 29, -20, 4, 52, -57, 62, -52, -2, -9, 62, -64, -5, 24, 23, 0, -7, -23, 48, 25, -78, -9, 38, 18, -46, 30, -51, 39, 4, -48, 22, 15, 13, -39, 8, 10, 31, -20, -22, 21, -17, 17, -23, 22, 22, -24, -36, 11, 31, -16, -28, 34, -4, 0, -20, 6, -2, 35, -13, -60, 36, 24, -45, 21, -2, 36, 0, -73, 66, -37, 39, -66, -18, 22, 17, -17, -25, 24, 36, -47, 3, 25, 7, 8, 0, 1, 14, 20, -21, 4, 21, 12, -77, 17, -4, -12, 31, -57, 38, -11, -4, -31, -6, 29, -34, 11, 13, -20, 82, -36, -36, 40, -28, 77, -68, 12, 2, 34, -23, 5, -31, 11, -5, 44, -105, 79, -31, -29, -16, 37, 8, 18, -14, -9, 32, -10, -11, -7, 0, 41, 34, -56, 7, 13, -2, -31, 33, -67, 42, -31, -2, 22, -49, 18, -34, -11, 38, -40, 56, -16, 14, -2, 24, 0, 0, 41, -21, -8, 6, -11, 11, 11, -45, 26, 4, -17, -7, -26, -30, 7, -21, -29, 56, -29, 37, -3, 2, -8, -3, 22, 11, 40, -13, 58, -6, -38, 48, -23, 15, -52, -14, -6, 49, -66, -20, -11, 34, -32, -44, 41, 4, 20, -59, -24, 77, 23, -24, -17, 42, 19, -3, -19, -34, 54, 17, -22, -17, 46, -24, -9, 3, -22, 40, -47, -49, 72, 4, -18, -48, -33, 55, -4, -41, -51, 105, -26, -3, -22, 64, 28, -51, 31, 2, 15, 27, -62, 18, 21, 6, -15, -54, 52, -14, -46, 7, -30, 32, -1, 6, -37, 39, -3, -23, -20, 24, 23, 17, -25, -6, 67, -36, -11, -37, 56, -79, 3, 30, 45, -39, -17, -2, 21, 2, -4, -3, 3, 1, 16, -16, 9, 30, -37, 8, -6, 46, -65, 3, 14, -59, 104, -60, 2, 46, -29, -30, -2, -10, 24, -52, 63, -31, 81, -85, 18, 35, 16, -32, -18, -24, 45, -16, -15, -13, 37, -15, -20, -42, 91, -45, -15, -9, -16, 64, -11, -23, 31, -18, 38, -42, 3, 12, 1, 5, -5, 22, -44, 69, -31, -18, 15, 21, -64, -13, 34, -37, 30, -26, -15, 6, -3, 44, -28, 11, -3, -1, 16, -18, 25, -14, -26, 69, -56, -5, 31, -51, 24, 3, -36, 9, 52, -34, 31, 21, -11, -68, 31, -24, 53, -25, -29, 31, 23, -20, 9, -15, -11, 19, 12, -47, 84, -60, -16, -11, 17, -4, -15, 30, -45, 32, 34, -63, -7, 68, 0, -35, 17, 7, 33, -31, -8, 7, -32, 43, -13, -18, 15, 31, -32, -34, 5, 8, -16, 20, -26, -29, 32, -9, -20, 17, 33, -31, -13, -5, 86, -52, 23, -19, 2, 13, 14, -7, -20, 36, -16, -3, 8, 0, 14, -69, 76, -77, 25, -14, -17, 3, 39, -14, -46, 31, -2, -7, 37, -45, -6, 24, 28, -37, 22, 13, -35, 4, 8, 23, 7, -43, 53, -59, 23, 16, 4, -25, -15, 23, -9, -20, 26, -18, -1, 25, -3, -48, 53, 2, -43, 7, 14, -34, 15, 28, -33, 53, -2, -59, 31, -34, 40, 19, -27, 20, -2, 8, 2, 3, -8, -8, 4, -57, 62, 24, -72, -4, 17, -17, -3, -10, -26, 42, -30, 12, -29, 31, -10, 3, 24, 2, 21, -1, -36, 52, -7, 21, 14, -32, -18, 73, -45, -6, 8, -12, -66, 21, 25, -17, -6, -35, -14, 27, 26, -47, 40, -51, 56, -19, -24, 31, 6, 4, 11, -3, 37, -47, 41, -32, 50, 0, -72, 25, 16, -19, -1, -2, -4, -41, 20, 6, 9, -3, -44, 32, -54, 83, -30, -26, -8, 46, -47, 29, 5, -19, 37, -9, -20, 65, -14, -21, -4, 10, 28, -28, 18, -29, 35, -25, 3, -17, -31, 4, -4, 0, -9, 41, -42, -34, 40, -15, 8, -24, -8, 36, 22, -18, -27, 70, -39, 39, 1, -5, 57, -54, 12, 36, 3, -13, -1, -32, 69, 6, -64, -50, 13, -13, -34, 22, -13, 0, -10, -38, 41, -11, -22, -3, 11, 4, 38, 22, -10, 24, 32, -23, 23, -6, 8, -4, 21, -61, 66, -35, -41, 7, 5, -29, -19, -45, 23, -2, 46, -84, 78, -59, 40, -10, -18, 79, -35, -5, -1, 36, 16, 13, -21, -31, 52, 2, -50, 34, -5, -36, -37, 65, -42, 1, 16, -42, 35, -8, -50, -6, 41, -16, 27, -41, 22, 64, -50, -11, 31, -18, -17, 5, -3, 34, 34, -40, -41, 66, -37, 20, -11, -20, 29, -5, -14, -15, 45, -33, -37, -11, 36, -25, 18, -8, 20, 1, -23, 60, -32, 0, 34, -24, -32, 64, -39, -35, 48, -7, -13, 4, -39, 32, 0, 1, -31, 2, -12, 43, -38, -8, 26, 0, -57, 53, 19, -22, -10, 17, -30, 57, 6, -31, 33, 10, 0, -48, 29, -4, -23, 6, -7, 31, -39, 15, -41, 38, -19, 5, -37, 23, 11, -28, -14, 59, -48, 8, 22, -20, 50, 15, -34, -26, 67, -8, -15, -21, 53, -27, -9, 13, -24, -35, -10, 9, -15, -13, 18, -38, 28, 22, -14, 2, -22, 42, -20, 22, 12, -20, 45, -16, 17, -16, 22, 34, -27, -13, -7, 1, -21, -1, 13, -44, 36, -51, -8, 16, -7, -30, -46, 90, -54, 35, 1, 11, 9, 5, 1, -19, 20, 11, 21, -1, -49, 41, -6, 0, 37, -74, 9, 20, -12, -47, 65, -68, 28, -5, -26, 15, 14, -3, -23, 8, 18, -22, 13, 3, 31, -21, -5, 8, 24, -21, 48, -20, -21, 41, -43, 4, 18, 21, -60, 9, -27, 1, 13, -15, -33, 15, 23, -48, -8, 53, -50, 1, 6, -40, 90, -10, -15, 51, -52, 53, 29, -68, 50, 52, -30, -21, 7, -1, -8, -29, 11, -47, 6, 18, -12, -25, 53, -34, -23, -6, 19, -7, -13, 7, 5, -2, 14, 11, -15, 51, -29, 6, 12, 20, -27, 29, -12, 4, -18, -5, 2, -17, 10, -19, 2, -8, -5, 56, -82, 49, 0, -42, 48, -25, 19, 6, -41, 17, 35, -18, -17, -29, 26, 10, 4, -24, 26, -35, 47, -36, 2, 2, -23, 27, -42, 55, 0, -21, 19, 21, -8, 1, -3, -15, 7, 12, -23, -29, 47, -12, 4, -28, 17, 16, -7, -31, -8, 25, -6, 0, 13, -20, 6, 3, -7, 19, -21, -37, 27, 41, 7, -14, 12, -59, 57, 6, -49, -2, -8, 0, 19, 13, -20, -5, 16, 23, 4, -15, -33, 14, 2, 15, -26, -28, 10, 45, -17, -24, 14, 17, -39, 22, -8, 48, -51, -1, -16, 52, -34, -21, 11, 13, 18, -57, 26, 15, 27, -36, -12, 40, -7, -14, 15, -86, 91, -20, -13, -7, 53, -43, 33, -25, 13, 3, -38, -19, 28, 28, -18, -74, 58, -3, 40, -27, -34, 30, 28, -1, -22, 2, 9, -8, -12, 12, 21, -35, -2, -17, 17, 2, -27, 22, -36, 38, -11, 2, -20, 7, 20, -29, 39, 11, -3, 9, -24, 47, -36, 28, -14, -16, 38, -37, 12, -15, 18, -69, 56, -31, 17, -16, -18, -13, 21, -6, -9, -25, 37, 6, -1, -2, 5, -1, -26, 39, 6, -3, -10, 0, 12, 30, -12, -31, 24, 13, -14, 9, -23, 31, -43, -17, -2, 13, -23, -14, -21, 21, 19, -22, -12, 24, 41, -26, 10, 12, 19, -3, 9, -12, 26, 12, -52, -4, 16, -3, 0, -43, 7, 5, -14, -9, 12, -28, 15, -23, -2, 35, -12, -8, -10, 24, 57, -55, 26, -18, 19, 44, -30, 0, -5, 50, -56, -1, 8, -5, -39, 9, 19, -39, 38, -73, 30, -1, 2, 16, -24, 6, 29, -71, 70, -18, -6, 8, 31, 4, -13, 23, -11, 31, -56, 57, -25, 10, 15, -44, -10, 16, -17, -44, 18, -28, 10, 8, -21, -4, -9, 28, 20, -16, 17, -17, -6, 30, 0, 11, -21, 25, 25, -1, 31, -56, 31, 14, -32, 2, -19, 4, -17, -26, -13, 42, -59, 15, -29, 53, -4, 1, -23, 13, 31, 5, -22, 3, 30, -28, 2, -24, 37, 1, -3, -18, 18, 41, -40, 3, -40, 48, -31, -5, -20, 5, 9, 0, -30, -1, 26, -15, -5, -6, 51, -25, -27, 7, 44, -11, 10, -32, 14, 46, -31, 6, -11, 37, -33, -14, 19, -4, 22, -50, 26, -45, 21, 1, -23, 10, -15, 17, -63, 53, -14, -18, 56, -49, 21, 25, -7, 4, -21, 52, -33, 19, 3, 11, -9, -7, 0, -49, 22, -17, 25, -10, -11, 5, -19, 35, -26, 20, -7, -21, 37, -25, 29, -23, 3, 6, 17, -26, 27, 5, -16, 10, -9, -24, 11, -4, -17, 9, -5, -13, 1, -2, 10, 5, -13, 21, 0, 8, 9, -22, 12, 13, -24, -3, -22, 42, -18, 3, -4, -15, 1, -2, 8, -17, -13, -2, 1, 23, 10, -2, -31, 23, 17, -15, -9, -24, 31, 2, 19, -24, 4, -22, 28, -5, -20, 34, -57, 26, 71, -51, 28, -24, -12, 28, 10, -35, -4, -6, 7, -7, 8, -52, 61, -52, 7, -9, -21, 9, 18, -19, 3, 34, -53, 56, -29, 20, -11, 22, 4, -1, 23, 2, 1, 24, -15, 3, -32, 13, 21, -37, 6, -11, -25, 22, 7, -2, -41, 4, 10, -30, 39, -24, -7, 8, 12, 9, -1, -35, 13, 3, 9, -18, 21, 26, -14, 41, -8, -35, 31, -29, 17, -20, -12, 20, -30, 27, -26, 21, -9, -6, 5, -14, 3, -11, 15, 2, 8, -14, -5, 20, 4, 0, -31, 9, 4, 25, -24, 5, -5, -13, 27, -7, -32, 1, -5, -10, 28, 7, -4, 11, 10, 22, -3, -22, -15, 6, -3, -3, -27, -25, 5, 8, -10, -17, 18, -18, 12, 32, -18, 1, 25, -25, 50, 7, 2, 0, -3, -3, 16, -20, 9, -14, -15, 21, -27, -3, -17, 23, -31, -4, -18, 31, -21, 6, 0, 18, -16, 27, 3, -7, -17, 17, -15, -11, 19, -16, 6, 1, 12, -18, 5, -6, 24, 0, -19, 22, -23, 43, -35, 18, 22, -40, 1, 12, -4, -18, 26, -53, 34, 1, -10, 1, -18, 27, -25, -24, 33, -31, 9, -43, 53, -29, 33, -17, 5, 23, -7, 2, 23, 29, 1, -8, 20, -10, -1, -22, -3, -17, 4, 22, -61, -23, 31, -26, -29, -12, 2, -3, 12, 10, 26, 5, -29, 61, -9, 32, -18, -14, 29, 31, 2, -19, 9, 31, -20, -31, -7, 5, -22, -47, 31, -40, 15, -39, 22, -27, 40, -78, 31, 4, -19, 33, -13, -8, 41, -1, 5, -12, 53, -51, 22, -1, 18, 28, -29, -1, 0, 0, 11, 13, -2, -7, -5, -3, -3, 1, 2, -6, 0, 3, 8, 9, 5, 0, 14, -5, -28, -39, -39, -36, -37, -27, -43, -49, -13, 4, 6, -7, 0, -1, 3, 23, 39, 29, 35, 41, 21, 35, 0, 0, 21, 59, 67, 31, 21, 13, -3, 18, 34, 28, 5, 3, 13, 3, 0, 12, -7, -33, -27, -39, -14, -34, -50, -30, -37, -35, -53, -74, -70, -61, -62, -62, -50, -44, -61, -36, -3, -23, -15, -12, -17, -20, -6, 11, -6, -12, -6, -17, 7, 46, 71, 87, 79, 70, 77, 104, 109, 66, 37, 34, 27, 31, 40, 43, 31, 23, 17, 2, 10, 24, 32, 66, 56, 17, -13, -55, -54, -21, 19, -19, -56, -77, -37, -27, -10, -6, -38, -36, -37, -3, 23, 25, 25, 19, 35, 34, -7, -5, 28, 60, 66, 65, 51, 34, 22, 53, 51, 15, 20, 11, 21, 21, 16, 24, -2, -23, -36, -35, -21, -29, -51, -51, -47, -57, -85, -80, -70, -100, -97, -82, -78, -76, -64, -51, -56, -54, -49, -70, -62, -53, -54, -60, -57, -65, -78, -76, -62, -39, 0, 31, 13, 6, 31, 54, 55, 43, 30, 13, 9, 31, 23, 43, 28, 24, 36, 36, 24, 30, 54, 70, 113, 103, 75, 4, -3, 40, 55, 50, 23, 9, 25, 29, 48, 41, 29, 14, 6, 40, 63, 49, 39, 71, 80, 64, 21, 12, 17, 29, 68, 71, 52, 36, 24, 37, 24, 1, 5, 3, -6, -4, 1, 13, -3, -22, -35, -31, -27, -58, -59, -43, -55, -71, -76, -71, -88, -103, -95, -98, -85, -77, -68, -71, -58, -50, -47, -52, -46, -40, -47, -44, -48, -56, -60, -91, -96, -68, -15, -6, -16, 9, 3, 29, 31, 29, 8, 10, -6, 5, 10, -6, -4, -6, 15, 7, -2, 2, -5, 30, 91, 107, 74, 8, -3, 14, 27, 32, 26, 17, 21, 18, 34, 49, 20, -3, 2, 30, 42, 20, 36, 68, 79, 81, 52, 27, 22, 37, 80, 95, 77, 77, 72, 74, 57, 55, 56, 41, 35, 22, 40, 58, 32, 23, 24, 26, 0, -7, 6, -2, -16, -26, -31, -45, -46, -64, -77, -79, -73, -72, -75, -59, -49, -56, -35, -48, -44, -50, -43, -59, -58, -40, -78, -119, -123, -95, -73, -40, -52, -45, -29, -18, -3, -1, -11, -21, -28, -12, -24, -29, -21, -29, -16, -3, -5, -30, -40, 1, 69, 96, 78, 31, 14, 23, 17, 19, 33, 20, 9, 9, 45, 50, 14, 3, 12, 13, 16, 7, 14, 35, 54, 75, 56, 24, 1, 18, 47, 47, 60, 62, 66, 69, 46, 54, 53, 38, 11, 18, 44, 41, 28, 33, 37, 22, 14, 15, 13, 13, 1, -1, -13, -6, -11, -38, -33, -47, -40, -46, -31, -29, -22, -9, -5, -9, 9, 4, -23, -14, -4, -3, -26, -69, -87, -74, -60, -42, -49, -33, -28, -16, 9, 2, -16, -22, -25, -25, -33, -32, -44, -58, -41, -11, -19, -51, -77, -43, 24, 47, 49, 34, 21, 5, -9, 5, 18, -10, -14, 2, 23, 26, -3, -7, -4, 2, -3, -10, -4, -6, 38, 64, 50, 25, 1, 11, 17, 21, 36, 58, 62, 46, 46, 61, 56, 27, 11, 20, 18, 27, 15, 31, 26, 23, 17, 7, 16, 0, -9, -10, -3, -8, -14, -25, -36, -56, -41, -39, -50, -30, -12, -23, -8, 10, 23, 17, -2, 3, 14, 26, 7, -33, -48, -53, -52, -35, -30, -30, -23, 3, 21, 17, 8, 7, -8, -1, 0, -6, -29, -50, -26, 10, 5, -38, -64, -41, 5, 22, 49, 63, 38, 20, 13, 26, 15, -7, -9, -1, 28, 9, 1, -4, -12, -1, -5, -20, -38, -32, 6, 38, 36, 16, 10, 0, -8, -13, 15, 41, 25, 30, 30, 52, 35, 17, 8, 3, -5, -5, -6, 4, 7, 4, 4, 3, 3, -20, -25, -23, -28, -22, -18, -47, -50, -54, -62, -67, -62, -48, -43, -44, -31, -10, 17, 10, -8, 1, 22, 24, 17, -1, -21, -40, -39, -26, -38, -32, -21, 2, 17, 26, 29, 18, 5, 15, 35, 19, -11, -37, -9, 33, 17, -6, -30, -23, -10, 22, 65, 73, 71, 47, 57, 66, 38, 15, 16, 23, 34, 35, 27, 10, 11, 21, 32, -4, -26, -29, 4, 29, 28, 38, 32, 17, -6, -6, 17, 32, 21, 31, 39, 49, 36, 27, 25, 13, -1, -11, -8, -1, -15, -11, 4, -7, -9, -14, -38, -46, -35, -31, -43, -53, -54, -72, -84, -88, -86, -79, -73, -86, -69, -40, -16, -23, -28, -13, -9, 5, 5, -10, -34, -45, -48, -52, -61, -59, -42, -38, -9, 13, 19, 8, -14, 18, 42, 28, -18, -31, -3, 11, 21, 13, -9, -17, -22, 9, 57, 71, 62, 68, 83, 82, 65, 38, 38, 31, 52, 57, 45, 23, 25, 51, 56, 21, -2, -8, 7, 21, 28, 55, 55, 37, 15, 17, 30, 30, 30, 48, 55, 65, 55, 54, 61, 42, 24, 22, 13, 6, 6, 4, 4, 17, 19, 1, -20, -23, -25, -27, -26, -44, -44, -62, -79, -91, -83, -76, -99, -104, -87, -63, -51, -40, -42, -40, -29, -16, -6, -31, -40, -47, -63, -68, -81, -76, -81, -75, -49, -15, -5, -34, -38, 2, 15, 8, -29, -43, -33, -18, -11, 8, -9, -42, -45, -14, 25, 33, 41, 54, 67, 75, 71, 46, 30, 23, 52, 55, 38, 20, 25, 53, 59, 35, 17, 6, 3, 5, 27, 64, 61, 49, 40, 40, 45, 36, 38, 63, 69, 69, 77, 85, 78, 76, 63, 48, 38, 42, 28, 15, 30, 35, 41, 27, 14, 0, -4, -2, -14, -16, -15, -35, -65, -63, -56, -64, -80, -94, -77, -71, -46, -34, -42, -37, -21, -6, -5, -16, -20, -35, -44, -62, -66, -66, -96, -94, -58, -26, -32, -44, -50, -14, 2, -9, -26, -41, -53, -49, -27, -5, -28, -59, -65, -47, -20, -11, 7, 15, 28, 51, 57, 32, 7, 2, 30, 32, 15, 0, 7, 30, 30, 24, 21, -2, -19, -20, 6, 37, 40, 31, 40, 45, 30, 29, 35, 49, 52, 69, 74, 78, 89, 79, 72, 62, 60, 51, 37, 29, 29, 42, 51, 46, 30, 32, 18, 2, 8, 13, 15, -13, -35, -35, -38, -40, -53, -71, -70, -58, -34, -38, -32, -28, -9, 10, 10, 7, 11, -7, -28, -21, -26, -47, -80, -84, -49, -18, -28, -38, -32, -8, -4, 4, 3, -23, -46, -44, -19, -5, -22, -42, -55, -56, -35, -25, -12, -8, 11, 43, 51, 33, 1, 0, 24, 18, 1, -5, 0, 1, 9, 15, 21, -2, -38, -36, -19, 2, 2, 19, 26, 19, 20, 10, 11, 20, 31, 37, 49, 62, 64, 61, 60, 61, 50, 51, 32, 10, 16, 27, 31, 33, 33, 36, 7, -6, 3, 14, 12, -10, -21, -40, -34, -33, -47, -65, -67, -60, -40, -40, -44, -25, -10, -4, 14, 26, 22, 4, -7, 8, 8, -22, -67, -65, -33, -19, -24, -20, -18, -8, 1, 26, 30, -2, -22, -25, -6, 5, -1, -13, -38, -43, -31, -21, -16, -16, 9, 47, 61, 35, 22, 22, 31, 24, 10, 13, 5, -2, 0, 28, 34, 1, -21, -30, -28, -18, -5, 5, 18, 20, 14, 6, 6, 12, 9, 20, 33, 39, 51, 51, 42, 51, 51, 48, 20, 9, 7, 5, 7, 15, 28, 19, -1, -16, -15, -4, 4, -16, -30, -41, -45, -41, -50, -79, -77, -69, -65, -64, -56, -45, -40, -28, -4, 21, 17, -8, -9, 21, 16, -18, -56, -58, -44, -39, -24, -22, -28, -22, -4, 29, 31, 13, -9, -16, -3, 11, 13, 1, -18, -33, -15, -11, -23, -22, 11, 52, 58, 50, 46, 50, 49, 36, 40, 40, 17, 6, 20, 37, 45, 29, 9, -7, -12, -11, -6, 9, 30, 25, 26, 26, 17, 19, 15, 21, 24, 46, 55, 47, 43, 56, 64, 52, 33, 25, 13, -3, 2, 10, 21, 26, 4, -15, -16, -13, -2, -11, -32, -43, -37, -44, -61, -77, -78, -82, -82, -80, -71, -61, -72, -59, -21, 5, -2, -27, -10, 15, 7, -14, -44, -59, -67, -55, -37, -38, -50, -45, -23, 5, 23, 9, -6, -19, -15, 5, 14, 2, -22, -22, -10, -17, -35, -38, -3, 35, 38, 43, 57, 51, 44, 49, 57, 46, 25, 14, 24, 35, 54, 41, 31, 22, 1, -7, -4, 12, 23, 34, 37, 35, 35, 36, 26, 24, 33, 55, 62, 53, 58, 70, 70, 73, 62, 51, 38, 14, 6, 20, 31, 32, 27, 4, -9, -1, 9, -8, -21, -22, -27, -33, -53, -64, -67, -82, -86, -83, -67, -75, -97, -77, -36, -15, -27, -32, -18, -1, -1, -6, -31, -62, -73, -68, -52, -52, -68, -69, -50, -21, -2, 4, -10, -33, -29, -4, 2, -10, -29, -22, -8, -27, -55, -49, -27, -6, 12, 31, 43, 31, 38, 44, 54, 48, 25, 11, 19, 30, 36, 41, 41, 29, 11, -1, -9, 0, 15, 27, 34, 36, 46, 46, 26, 27, 39, 51, 59, 62, 62, 73, 76, 77, 85, 78, 58, 35, 23, 21, 37, 53, 37, 22, 15, 16, 20, 3, 0, -2, -2, -14, -33, -35, -45, -69, -77, -59, -53, -76, -96, -74, -41, -30, -25, -26, -19, -4, 7, 11, -8, -40, -62, -62, -51, -55, -69, -74, -71, -44, -15, -2, -14, -36, -38, -8, -7, -27, -33, -17, -12, -38, -51, -57, -58, -41, -14, 8, 19, 15, 15, 31, 46, 40, 21, 9, 7, 10, 20, 25, 33, 28, 16, 1, -18, -13, 0, 6, 12, 30, 39, 39, 26, 20, 32, 41, 45, 53, 64, 63, 62, 80, 84, 87, 81, 51, 29, 21, 44, 52, 41, 33, 29, 31, 27, 12, 8, 16, 10, -4, -7, -7, -29, -62, -57, -37, -44, -68, -81, -70, -48, -33, -23, -22, -17, -5, 16, 31, 14, -15, -33, -42, -41, -37, -53, -65, -74, -54, -16, 2, -12, -33, -19, -1, -10, -22, -17, -8, -8, -18, -33, -48, -62, -57, -31, -1, 7, 0, 9, 22, 40, 40, 27, 14, 4, 3, 10, 14, 21, 31, 20, 0, -13, -19, -17, -15, -7, 12, 29, 28, 13, 20, 18, 18, 31, 38, 47, 49, 51, 56, 67, 87, 84, 56, 30, 20, 31, 41, 31, 24, 32, 33, 20, 7, 14, 15, -2, -1, 13, 4, -28, -53, -45, -34, -38, -59, -75, -72, -58, -44, -26, -26, -29, -8, 14, 34, 28, 10, -9, -22, -26, -24, -30, -54, -78, -56, -13, -4, -17, -16, -5, 1, -6, -9, -8, -1, 3, -2, -4, -28, -53, -58, -37, -10, 1, -1, 6, 20, 34, 46, 40, 25, 19, 11, 7, 10, 23, 33, 28, 16, -3, -3, -17, -31, -14, 4, 15, 20, 20, 16, 10, 14, 19, 23, 37, 45, 35, 37, 53, 76, 83, 62, 34, 20, 27, 28, 13, 17, 29, 21, 7, 9, 13, -4, -17, -4, 13, 2, -27, -53, -47, -39, -46, -56, -77, -87, -77, -58, -45, -46, -47, -33, -6, 17, 22, 16, 1, -20, -25, -10, -21, -57, -79, -57, -32, -24, -23, -18, -3, -1, -6, -4, -4, -5, 3, 13, 14, -6, -38, -51, -39, -22, -4, -1, 3, 14, 32, 45, 46, 46, 33, 25, 15, 9, 28, 38, 32, 28, 26, 14, -9, -21, -15, -5, 10, 24, 22, 22, 21, 15, 15, 23, 36, 42, 35, 31, 41, 72, 87, 68, 46, 42, 34, 19, 14, 25, 25, 11, 14, 18, 14, -7, -24, -7, 12, 4, -19, -41, -47, -44, -41, -52, -74, -92, -88, -72, -59, -63, -68, -53, -34, -11, 12, 19, -7, -27, -15, -5, -22, -54, -76, -66, -52, -47, -41, -29, -17, -12, -12, -10, -11, -19, -7, 12, 19, 3, -23, -42, -48, -31, -19, -14, -6, 1, 20, 35, 39, 50, 51, 33, 16, 17, 30, 31, 32, 41, 39, 28, 14, -7, -14, -5, 8, 18, 27, 34, 29, 22, 21, 26, 38, 51, 39, 27, 43, 75, 84, 73, 75, 68, 46, 32, 31, 35, 27, 15, 23, 36, 26, 0, -13, -4, 12, 14, 1, -23, -36, -36, -32, -36, -60, -83, -84, -70, -67, -70, -66, -67, -62, -27, 8, 13, -11, -22, -7, 4, -16, -44, -63, -67, -63, -63, -53, -42, -33, -25, -15, -10, -22, -27, -18, -1, 16, 9, -13, -32, -46, -42, -31, -30, -24, -8, 5, 11, 25, 49, 50, 33, 25, 20, 21, 24, 29, 34, 41, 41, 26, 5, -5, -7, -4, 12, 23, 33, 37, 29, 19, 24, 49, 53, 33, 33, 49, 65, 73, 80, 89, 85, 63, 48, 50, 46, 30, 20, 35, 46, 39, 17, 0, 2, 15, 23, 18, -2, -20, -24, -12, -19, -45, -60, -66, -70, -66, -56, -61, -74, -74, -38, 0, 6, -8, -15, 3, 13, -1, -24, -42, -52, -65, -64, -54, -54, -47, -31, -19, -12, -21, -32, -27, -12, 7, 13, -2, -24, -36, -37, -44, -47, -32, -20, -18, -9, 12, 30, 38, 35, 26, 18, 17, 16, 13, 25, 36, 37, 32, 18, 2, -11, -10, -5, 3, 28, 38, 20, 8, 25, 42, 40, 28, 30, 40, 46, 54, 70, 87, 82, 66, 61, 59, 48, 28, 20, 32, 43, 43, 24, 8, 1, 7, 23, 25, 3, -13, -9, -8, -15, -28, -40, -58, -71, -60, -49, -58, -80, -82, -50, -17, -5, -13, -12, 6, 13, 8, -3, -24, -42, -54, -59, -57, -60, -59, -43, -24, -15, -20, -30, -35, -25, 1, 11, -2, -12, -18, -33, -48, -49, -41, -37, -32, -21, -8, 13, 27, 27, 27, 23, 16, 8, 7, 15, 22, 32, 35, 22, 9, 0, -18, -26, -8, 20, 25, 11, 4, 18, 32, 29, 22, 29, 30, 27, 38, 60, 75, 70, 68, 69, 67, 52, 30, 19, 27, 36, 40, 34, 10, -2, 6, 21, 20, 4, -2, -4, -7, -9, -12, -25, -52, -66, -53, -42, -53, -79, -86, -58, -33, -23, -16, -12, 0, 12, 17, 13, -5, -24, -38, -44, -50, -59, -61, -51, -33, -15, -11, -28, -36, -23, -4, 5, 5, 7, -3, -17, -31, -40, -38, -37, -36, -29, -14, 4, 15, 25, 34, 30, 24, 19, 9, 8, 22, 33, 31, 30, 31, 16, -14, -26, -13, 14, 17, 7, 8, 18, 24, 23, 28, 31, 23, 18, 30, 50, 62, 61, 63, 75, 73, 59, 40, 23, 20, 30, 43, 35, 11, 0, 8, 15, 12, 6, 3, -6, -10, -3, -1, -15, -46, -62, -47, -38, -54, -77, -84, -70, -53, -40, -30, -21, -12, 1, 16, 20, 5, -12, -21, -33, -44, -52, -64, -64, -44, -17, -15, -27, -30, -26, -15, -3, 6, 12, 9, -2, -17, -26, -29, -36, -41, -32, -21, -10, 6, 18, 27, 34, 37, 25, 11, 14, 21, 26, 27, 37, 48, 33, -1, -19, -8, 7, 8, 8, 16, 16, 17, 25, 34, 36, 23, 16, 28, 44, 53, 54, 61, 74, 79, 75, 56, 30, 19, 31, 45, 35, 15, 9, 9, 9, 11, 9, 5, -8, -14, 0, 9, -10, -40, -53, -44, -38, -51, -72, -84, -80, -69, -58, -45, -38, -30, -13, 5, 13, 8, 0, -14, -25, -30, -46, -67, -72, -55, -34, -26, -28, -31, -31, -26, -17, -4, 9, 11, 2, -4, -12, -22, -33, -38, -40, -34, -18, -7, 2, 17, 33, 38, 29, 19, 20, 22, 17, 19, 38, 57, 43, 15, 2, -1, 1, 3, 10, 18, 15, 14, 25, 38, 40, 27, 21, 28, 38, 46, 50, 55, 66, 81, 90, 71, 40, 30, 37, 44, 39, 26, 18, 12, 8, 14, 19, 8, -11, -13, 5, 15, -2, -28, -42, -36, -34, -45, -60, -76, -83, -77, -65, -59, -55, -43, -28, -13, 5, 11, 2, -9, -11, -17, -37, -61, -71, -65, -49, -38, -36, -34, -35, -36, -32, -16, -2, 1, 3, 0, -7, -13, -25, -39, -46, -42, -30, -22, -15, 2, 21, 30, 24, 22, 28, 19, 5, 11, 33, 50, 45, 31, 17, 6, -1, 0, 8, 16, 12, 11, 23, 37, 40, 33, 29, 29, 33, 45, 48, 46, 58, 83, 97, 84, 59, 45, 46, 47, 46, 42, 31, 16, 12, 23, 29, 16, -5, -9, 10, 21, 10, -12, -24, -25, -25, -29, -42, -64, -73, -70, -66, -63, -58, -52, -42, -22, 0, 8, 4, 1, 3, -1, -19, -44, -61, -63, -57, -50, -39, -33, -37, -39, -36, -27, -14, -4, 0, 0, 0, -1, -13, -30, -42, -43, -37, -36, -30, -10, 8, 12, 15, 26, 31, 16, 1, 4, 21, 37, 41, 38, 29, 13, 0, -1, 6, 8, 3, 7, 17, 26, 34, 35, 27, 24, 32, 40, 37, 32, 45, 72, 89, 86, 70, 57, 48, 45, 49, 50, 37, 16, 11, 25, 34, 20, -3, -7, 7, 18, 15, 2, -14, -20, -15, -17, -32, -49, -61, -67, -65, -60, -61, -63, -54, -33, -12, -1, 1, 2, 10, 12, -3, -26, -43, -57, -60, -54, -45, -38, -38, -39, -39, -35, -23, -13, -6, -3, 2, 7, -2, -20, -30, -34, -42, -47, -38, -19, -9, -5, 7, 24, 31, 19, 3, 0, 10, 23, 33, 40, 36, 18, 5, 4, 4, 0, 0, 0, 5, 16, 29, 30, 22, 22, 31, 36, 27, 21, 32, 54, 74, 81, 77, 65, 49, 44, 50, 55, 40, 16, 10, 24, 31, 20, 3, -6, -1, 11, 16, 5, -9, -13, -12, -14, -22, -36, -53, -63, -62, -59, -63, -69, -67, -48, -25, -14, -10, -1, 10, 16, 10, -6, -26, -45, -54, -55, -50, -42, -39, -39, -40, -39, -29, -19, -15, -8, 4, 11, 3, -6, -11, -21, -38, -48, -40, -26, -21, -16, -3, 18, 30, 24, 12, 6, 4, 11, 29, 41, 39, 28, 18, 11, 8, 5, 1, -4, -2, 11, 25, 25, 19, 23, 33, 35, 25, 17, 23, 39, 57, 74, 81, 72, 53, 47, 56, 60, 44, 23, 16, 22, 29, 25, 10, -4, -3, 7, 11, 6, -3, -9, -11, -9, -12, -26, -42, -56, -59, -55, -61, -73, -75, -60, -42, -32, -23, -12, 0, 12, 15, 7, -10, -30, -46, -53, -53, -46, -41, -43, -45, -41, -32, -30, -26, -14, -1, 5, 2, 3, 3, -9, -30, -43, -40, -31, -31, -28, -12, 8, 20, 25, 22, 9, 0, 6, 21, 34, 39, 35, 26, 18, 16, 14, 4, -7, -5, 9, 21, 19, 16, 23, 35, 37, 28, 20, 20, 26, 43, 67, 82, 74, 57, 54, 62, 63, 52, 33, 21, 23, 30, 28, 14, 1, -1, 3, 8, 7, -1, -7, -9, -6, -5, -15, -34, -49, -51, -51, -60, -72, -76, -70, -57, -46, -37, -25, -13, 3, 14, 14, 3, -15, -33, -48, -52, -47, -45, -49, -49, -41, -37, -39, -35, -21, -10, -5, -2, 6, 12, 1, -19, -32, -34, -36, -39, -34, -23, -9, 9, 23, 25, 14, 3, 2, 12, 25, 36, 37, 30, 24, 25, 24, 10, -5, -4, 9, 18, 15, 14, 23, 34, 38, 36, 30, 19, 15, 32, 61, 78, 75, 63, 60, 67, 71, 62, 42, 29, 30, 33, 32, 20, 8, 4, 6, 8, 8, 3, -5, -9, -2, 3, -7, -25, -37, -42, -45, -54, -66, -74, -74, -67, -58, -49, -40, -27, -9, 5, 13, 13, 0, -21, -39, -45, -44, -49, -54, -50, -44, -44, -47, -42, -29, -21, -19, -11, 5, 12, 4, -8, -18, -28, -36, -40, -40, -36, -24, -4, 14, 21, 17, 7, 0, 3, 17, 32, 34, 29, 28, 34, 33, 17, 0, 0, 9, 13, 12, 14, 20, 27, 38, 46, 39, 21, 11, 24, 51, 71, 74, 66, 64, 73, 78, 71, 54, 40, 38, 41, 38, 28, 17, 11, 9, 12, 14, 7, -3, -5, 3, 9, 2, -12, -23, -28, -35, -45, -55, -65, -71, -68, -62, -57, -50, -37, -22, -7, 10, 20, 12, -8, -24, -32, -39, -48, -52, -49, -45, -49, -52, -44, -34, -33, -30, -18, -3, 5, 5, 1, -8, -19, -29, -37, -43, -45, -37, -18, 0, 13, 18, 10, -1, -3, 10, 24, 26, 23, 29, 38, 37, 21, 8, 5, 6, 8, 10, 12, 11, 16, 34, 49, 46, 27, 10, 15, 38, 59, 67, 63, 63, 72, 81, 77, 61, 48, 45, 45, 42, 35, 23, 13, 11, 17, 18, 9, -3, -5, 3, 10, 6, -3, -12, -19, -24, -34, -46, -57, -64, -65, -66, -63, -56, -48, -39, -22, 1, 17, 16, 3, -8, -17, -30, -44, -47, -44, -47, -53, -52, -44, -41, -41, -38, -28, -14, -3, 3, 3, -2, -9, -17, -28, -42, -49, -46, -34, -17, 3, 14, 9, -3, -6, 5, 15, 13, 15, 26, 36, 35, 25, 16, 8, 2, 4, 9, 6, 1, 4, 22, 43, 48, 31, 11, 7, 24, 45, 55, 54, 55, 68, 79, 77, 66, 54, 48, 47, 47, 41, 27, 14, 11, 18, 20, 10, -2, -6, 0, 7, 8, 2, -6, -12, -14, -23, -38, -49, -55, -62, -66, -63, -60, -59, -53, -37, -12, 8, 13, 10, 7, -4, -21, -35, -37, -39, -47, -53, -51, -45, -44, -44, -42, -36, -24, -10, 0, 2, 1, 1, -3, -15, -30, -42, -49, -45, -30, -6, 10, 7, -2, -3, 5, 9, 6, 11, 23, 32, 35, 33, 25, 14, 6, 9, 12, 8, -2, -4, 13, 36, 48, 39, 18, 7, 17, 34, 43, 45, 50, 62, 74, 78, 71, 59, 51, 49, 52, 48, 32, 16, 12, 19, 21, 13, 1, -6, -5, 2, 6, 2, -4, -6, -9, -18, -29, -40, -51, -60, -65, -63, -63, -68, -68, -53, -30, -12, 0, 10, 13, 3, -14, -25, -29, -35, -45, -52, -52, -49, -47, -47, -47, -46, -35, -20, -10, -5, -1, 4, 4, -4, -15, -30, -47, -54, -41, -15, 1, 0, -2, 2, 6, 4, 3, 7, 16, 26, 35, 38, 32, 20, 12, 14, 18, 12, -1, -8, 3, 27, 46, 44, 26, 14, 17, 28, 35, 38, 44, 55, 69, 78, 77, 66, 55, 54, 60, 58, 41, 24, 17, 19, 23, 20, 7, -4, -4, 0, 2, 1, 0, -2, -4, -10, -17, -28, -42, -55, -59, -56, -61, -72, -74, -63, -47, -32, -14, 5, 13, 7, -4, -12, -19, -28, -38, -46, -51, -50, -46, -47, -51, -52, -43, -30, -20, -13, -5, 0, 4, 4, 2, -13, -40, -55, -47, -25, -12, -8, -3, 3, 5, 4, 2, 3, 7, 18, 32, 41, 36, 25, 18, 21, 25, 21, 5, -9, -3, 19, 41, 45, 34, 24, 23, 27, 30, 33, 38, 47, 62, 78, 82, 72, 61, 61, 67, 66, 54, 37, 24, 23, 28, 25, 15, 5, 0, 0, 0, 1, 2, 2, -1, -4, -5, -15, -34, -47, -49, -49, -58, -69, -73, -70, -63, -51, -30, -8, 5, 7, 3, -4, -11, -20, -29, -41, -49, -50, -46, -49, -54, -56, -50, -42, -33, -22, -13, -10, -6, 5, 12, -1, -30, -50, -50, -38, -27, -18, -10, -3, 1, 2, 2, -2, -4, 6, 24, 36, 36, 27, 19, 22, 30, 28, 10, -8, -10, 9, 30, 39, 35, 30, 26, 26, 28, 29, 29, 35, 53, 73, 80, 74, 65, 63, 69, 72, 64, 47, 33, 28, 29, 28, 21, 12, 6, 2, -2, 1, 4, 1, -2, 2, 6, -4, -23, -35, -38, -42, -51, -60, -66, -70, -71, -63, -45, -23, -5, 4, 6, 3, -2, -7, -18, -32, -42, -43, -43, -47, -52, -54, -53, -51, -42, -27, -20, -21, -14, 4, 17, 10, -13, -35, -45, -44, -37, -26, -17, -11, -3, 3, 3, -3, -9, -4, 13, 31, 35, 27, 19, 23, 34, 36, 19, -3, -10, 2, 19, 31, 35, 33, 29, 30, 32, 28, 22, 26, 43, 63, 76, 75, 67, 65, 71, 75, 70, 57, 43, 36, 34, 30, 26, 21, 14, 5, 1, 4, 3, -2, -2, 6, 11, 3, -11, -22, -29, -36, -43, -50, -57, -67, -74, -72, -60, -40, -19, -5, 2, 4, 6, 3, -8, -23, -32, -35, -40, -45, -47, -51, -57, -58, -47, -33, -30, -32, -24, -5, 13, 14, 1, -18, -36, -45, -42, -35, -27, -20, -11, 0, 3, -3, -12, -12, 1, 21, 31, 25, 16, 20, 34, 40, 26, 5, -7, -6, 7, 21, 27, 26, 27, 31, 33, 27, 17, 15, 28, 50, 65, 68, 64, 62, 68, 74, 72, 61, 51, 44, 35, 29, 28, 25, 15, 7, 5, 5, -1, -8, -5, 3, 8, 4, -4, -12, -22, -32, -38, -42, -50, -61, -72, -77, -73, -57, -36, -20, -11, -2, 7, 8, -3, -14, -22, -30, -38, -41, -42, -49, -60, -62, -52, -41, -40, -41, -34, -18, 0, 11, 10, -3, -23, -38, -42, -40, -36, -31, -20, -6, 2, -1, -13, -19, -9, 12, 25, 20, 12, 17, 30, 39, 34, 17, -2, -8, 1, 13, 19, 21, 23, 31, 37, 32, 18, 10, 18, 36, 55, 62, 60, 60, 67, 73, 72, 68, 61, 51, 41, 35, 34, 28, 18, 12, 11, 8, -2, -9, -7, 0, 4, 5, 3, -3, -14, -24, -31, -36, -41, -50, -64, -77, -80, -68, -51, -37, -26, -11, 3, 6, 2, -3, -13, -24, -32, -33, -34, -46, -60, -62, -54, -47, -46, -47, -43, -31, -13, 4, 12, 6, -9, -23, -34, -39, -40, -38, -29, -14, 0, 2, -11, -22, -15, 4, 17, 16, 11, 13, 25, 39, 41, 28, 9, -3, 0, 9, 15, 15, 19, 30, 40, 39, 26, 12, 11, 28, 45, 54, 56, 60, 66, 70, 73, 74, 69, 58, 49, 45, 42, 32, 22, 18, 19, 14, 3, -6, -7, -4, 0, 5, 6, 3, -5, -14, -24, -30, -32, -38, -53, -71, -78, -72, -63, -54, -39, -22, -8, 1, 6, 6, -4, -18, -25, -23, -25, -39, -54, -58, -54, -49, -49, -50, -49, -42, -26, -7, 7, 9, 2, -9, -20, -30, -38, -43, -39, -22, -2, 3, -9, -20, -16, -2, 11, 14, 10, 10, 20, 36, 46, 40, 22, 8, 6, 11, 13, 12, 15, 26, 41, 46, 36, 20, 14, 24, 38, 47, 54, 60, 64, 69, 76, 81, 76, 66, 60, 58, 53, 40, 30, 27, 27, 22, 12, 3, -3, -4, -1, 4, 8, 8, 5, -4, -15, -21, -21, -25, -41, -58, -69, -71, -70, -64, -51, -35, -23, -9, 5, 10, 1, -13, -17, -15, -19, -32, -46, -54, -54, -51, -50, -52, -55, -53, -40, -22, -6, 3, 4, -2, -10, -19, -32, -47, -49, -32, -11, -3, -10, -20, -20, -10, 2, 7, 5, 2, 10, 28, 42, 41, 29, 16, 10, 11, 11, 7, 6, 17, 35, 45, 39, 26, 18, 19, 26, 37, 47, 53, 56, 61, 73, 81, 76, 68, 65, 65, 59, 46, 36, 31, 28, 25, 19, 9, -1, -6, -4, -1, 2, 8, 9, 0, -10, -15, -14, -18, -32, -46, -57, -68, -74, -71, -61, -51, -41, -23, -2, 8, 2, -8, -11, -10, -13, -23, -37, -48, -53, -51, -49, -53, -59, -60, -53, -37, -19, -7, -3, -2, -1, -6, -22, -43, -52, -42, -21, -9, -12, -20, -23, -16, -4, 3, -1, -6, 0, 18, 34, 40, 33, 22, 16, 16, 13, 5, 0, 9, 27, 39, 40, 32, 24, 18, 19, 29, 40, 44, 46, 55, 69, 77, 75, 71, 70, 70, 65, 55, 45, 37, 32, 30, 26, 17, 7, 0, -5, -6, -1, 8, 11, 4, -5, -7, -7, -13, -21, -30, -44, -59, -69, -69, -65, -63, -56, -36, -13, 1, 1, -4, -6, -5, -6, -12, -25, -40, -47, -47, -46, -50, -56, -62, -61, -48, -30, -18, -12, -6, 4, 6, -7, -32, -49, -46, -30, -16, -12, -19, -25, -20, -7, 0, -3, -9, -7, 8, 26, 36, 34, 27, 24, 24, 19, 7, -2, 4, 18, 31, 38, 38, 30, 20, 18, 26, 34, 35, 38, 48, 62, 71, 73, 72, 73, 72, 70, 64, 53, 43, 38, 35, 30, 23, 16, 7, -4, -10, -4, 6, 8, 3, -1, -2, -4, -9, -12, -19, -33, -51, -61, -65, -69, -73, -70, -52, -30, -13, -6, -5, -7, -5, -2, -5, -17, -31, -41, -45, -44, -45, -53, -64, -67, -58, -43, -31, -26, -17, -1, 10, 3, -19, -41, -48, -39, -23, -16, -21, -27, -24, -12, -3, -5, -13, -15, -3, 16, 28, 29, 26, 28, 31, 24, 10, 0, 0, 8, 20, 33, 38, 32, 22, 19, 24, 28, 28, 30, 40, 52, 61, 68, 71, 72, 73, 73, 69, 59, 51, 45, 39, 32, 28, 26, 15, 0, -9, -5, 2, 4, 2, 1, -1, -4, -6, -5, -10, -24, -41, -50, -56, -66, -76, -77, -66, -47, -27, -15, -11, -10, -5, 0, -1, -8, -20, -33, -40, -40, -40, -48, -62, -70, -64, -51, -43, -39, -29, -11, 7, 10, -5, -28, -43, -41, -28, -20, -22, -29, -28, -17, -6, -5, -14, -20, -12, 6, 19, 22, 23, 30, 35, 31, 20, 8, 0, 1, 13, 29, 37, 33, 26, 25, 27, 27, 25, 26, 33, 43, 54, 63, 67, 70, 74, 76, 72, 66, 61, 54, 44, 37, 36, 34, 24, 8, -3, -4, -2, 0, 2, 3, -1, -5, -3, 2, -2, -16, -29, -36, -44, -57, -70, -79, -76, -60, -41, -27, -19, -14, -8, -1, 3, 0, -10, -24, -33, -33, -32, -40, -55, -65, -63, -56, -51, -48, -40, -23, -1, 12, 7, -13, -32, -37, -29, -21, -21, -28, -29, -19, -6, -2, -12, -20, -14, 0, 11, 16, 22, 30, 37, 38, 33, 21, 7, 0, 9, 26, 36, 35, 32, 32, 32, 31, 28, 27, 30, 38, 50, 58, 63, 70, 78, 79, 76, 74, 72, 64, 53, 46, 45, 44, 34, 20, 9, 3, -1, 1, 7, 7, 0, -4, 2, 8, 5, -5, -15, -23, -30, -41, -58, -73, -77, -68, -53, -38, -28, -21, -14, -5, 4, 7, -1, -15, -25, -25, -24, -32, -48, -59, -61, -59, -57, -57, -54, -39, -16, 4, 8, -5, -24, -33, -30, -24, -24, -32, -35, -26, -11, -6, -14, -20, -19, -10, -2, 5, 13, 21, 29, 37, 40, 30, 11, 0, 4, 17, 27, 30, 31, 31, 32, 32, 29, 23, 23, 31, 40, 45, 52, 63, 72, 74, 73, 75, 75, 67, 56, 51, 50, 46, 38, 29, 18, 6, -3, -1, 5, 3, -4, -7, -2, 4, 5, -2, -11, -17, -21, -30, -47, -66, -78, -77, -66, -53, -42, -34, -27, -16, -3, 6, 1, -12, -21, -21, -21, -28, -42, -54, -60, -60, -61, -65, -67, -57, -35, -11, 1, -3, -18, -30, -30, -25, -27, -36, -41, -32, -19, -13, -17, -22, -22, -19, -14, -6, 2, 7, 17, 31, 41, 34, 17, 3, 1, 8, 17, 23, 25, 26, 30, 32, 28, 22, 21, 25, 30, 34, 42, 54, 63, 66, 70, 77, 77, 69, 61, 57, 55, 49, 44, 39, 28, 11, 2, 2, 5, 3, -3, -8, -4, 3, 6, 2, -4, -9, -11, -16, -31, -52, -68, -75, -71, -61, -50, -43, -38, -26, -8, 5, 4, -6, -13, -14, -13, -19, -31, -44, -51, -52, -55, -64, -71, -67, -49, -24, -4, -1, -12, -22, -21, -18, -22, -33, -39, -33, -22, -16, -16, -17, -19, -20, -16, -9, -4, -2, 5, 18, 31, 37, 32, 21, 11, 9, 12, 17, 20, 24, 28, 32, 31, 28, 26, 26, 26, 28, 34, 43, 51, 57, 65, 74, 77, 75, 72, 68, 63, 59, 56, 53, 44, 31, 19, 12, 11, 8, 3, -2, -3, 0, 4, 5, 2, 0, -1, -3, -11, -25, -42, -58, -66, -65, -59, -54, -51, -42, -27, -11, -2, -3, -6, -7, -7, -9, -16, -27, -36, -40, -44, -52, -63, -70, -66, -49, -28, -15, -13, -16, -16, -13, -16, -24, -31, -33, -29, -24, -19, -17, -19, -20, -18, -14, -13, -12, -6, 7, 22, 33, 35, 28, 18, 12, 12, 14, 17, 21, 27, 31, 31, 30, 30, 28, 25, 25, 30, 36, 42, 49, 58, 67, 74, 76, 75, 71, 66, 62, 60, 59, 53, 41, 29, 19, 14, 11, 7, 1, -3, -2, 1, 3, 3, 1, 0, 0, -3, -11, -26, -44, -59, -65, -63, -60, -57, -52, -41, -25, -11, -4, -4, -6, -6, -6, -9, -17, -27, -35, -39, -44, -53, -65, -71, -65, -47, -28, -16, -15, -16, -15, -14, -17, -25, -32, -33, -29, -24, -19, -17, -19, -20, -18, -14, -13, -12, -6, -2, 1, 6, 5, 21, 46, 42, 15, 0, 5, 34, 48, 29, -4, -31, -33, -17, 26, 49, 32, 0, -21, -15, 14, 24, 24, 16, 0, 3, 11, 11, 11, 5, 9, 9, 8, 11, 30, 27, 22, 7, -3, -3, 10, 2, -2, -4, -13, -4, -4, -2, -2, -3, -7, -6, -14, -15, -14, -14, -13, -3, -14, -16, -18, -13, -15, -16, -22, -20, -14, -3, -6, -4, -14, -11, -6, -10, -15, -15, -16, -9, -10, -19, -3, -5, -17, -15, -18, -16, -14, -14, -12, -15, -7, -22, -19, -17, -20, -11, -17, -14, -11, -8, -10, -13, -12, -11, -6, -6, -9, 1, 1, -3, 0, 6, -2, -9, 7, -8, 8, 4, 3, 1, -6, -2, -2, 2, -5, -7, -4, -7, -8, -9, -6, -6, 0, -8, -12, -12, -13, -8, -4, -7, -3, -11, -6, -15, -7, -9, -9, -3, -10, -8, -9, -15, -10, -2, 2, -7, -16, -17, -15, -13, -9, -6, -5, -7, -9, -15, -17, -12, -19, -12, -8, -8, -4, -6, -3, 0, -4, -11, -13, -7, -6, -2, 4, 4, 8, 10, 4, 3, 3, 4, 7, 12, 11, 14, 15, 20, 20, 18, 16, 17, 15, 14, 15, 22, 23, 28, 34, 29, 28, 17, 22, 24, 23, 25, 28, 28, 30, 24, 19, 16, 13, 18, 20, 15, 8, 2, 3, 0, 2, 0, -3, -2, -9, -20, -23, -25, -24, -23, -27, -33, -38, -39, -44, -36, -42, -44, -48, -53, -54, -56, -52, -50, -40, -35, -44, -43, -44, -39, -28, -24, -23, -22, -15, -9, 2, 11, 19, 28, 31, 31, 32, 35, 43, 61, 70, 78, 81, 73, 78, 78, 78, 85, 82, 85, 88, 87, 84, 83, 83, 79, 74, 62, 49, 45, 42, 43, 44, 38, 30, 18, 6, -5, -15, -17, -15, -22, -28, -38, -46, -48, -50, -58, -59, -72, -80, -83, -89, -88, -89, -87, -81, -84, -93, -105, -110, -109, -110, -102, -96, -82, -65, -62, -60, -60, -60, -51, -43, -37, -28, -16, 1, 15, 28, 35, 41, 46, 53, 56, 60, 66, 77, 91, 101, 102, 101, 99, 104, 103, 97, 91, 86, 90, 91, 86, 85, 79, 75, 71, 59, 48, 39, 35, 33, 32, 28, 22, 15, 13, 7, 3, -7, -15, -16, -18, -19, -23, -28, -29, -33, -37, -47, -52, -56, -63, -61, -70, -67, -70, -72, -72, -80, -93, -91, -99, -103, -96, -108, -105, -109, -112, -94, -81, -73, -67, -71, -77, -69, -63, -57, -38, -27, -15, 0, 4, 6, 19, 26, 41, 53, 49, 56, 58, 69, 84, 91, 95, 101, 103, 98, 93, 85, 87, 102, 102, 103, 95, 81, 78, 78, 71, 66, 60, 51, 50, 44, 39, 34, 34, 32, 27, 15, 0, -6, -8, -3, -3, -11, -10, -18, -21, -26, -35, -39, -38, -44, -48, -53, -63, -61, -61, -71, -63, -86, -89, -86, -107, -99, -109, -108, -109, -108, -121, -128, -105, -102, -83, -67, -88, -82, -76, -78, -62, -47, -41, -19, -6, 1, 7, 13, 33, 44, 64, 61, 59, 68, 73, 93, 98, 107, 114, 109, 123, 107, 100, 105, 100, 111, 117, 100, 93, 92, 86, 85, 80, 70, 59, 58, 47, 38, 41, 33, 40, 38, 25, 16, 1, -2, -3, -3, -4, -10, -16, -12, -21, -28, -28, -36, -38, -39, -52, -61, -61, -67, -63, -65, -76, -77, -86, -95, -95, -107, -109, -112, -112, -121, -121, -122, -105, -79, -80, -71, -80, -84, -73, -70, -56, -43, -28, -10, 6, 11, 17, 31, 43, 63, 69, 69, 65, 77, 88, 101, 113, 112, 127, 122, 122, 115, 104, 112, 116, 122, 117, 106, 99, 97, 96, 94, 86, 75, 70, 61, 53, 44, 41, 46, 47, 45, 28, 19, 9, 5, 9, 1, -8, -14, -20, -24, -26, -28, -29, -36, -39, -42, -45, -41, -42, -45, -46, -49, -47, -50, -55, -53, -61, -63, -67, -83, -78, -89, -91, -88, -100, -93, -108, -110, -110, -115, -90, -100, -91, -80, -91, -73, -62, -60, -41, -33, -36, -25, -16, -9, 8, 18, 35, 40, 57, 61, 66, 95, 94, 106, 114, 105, 117, 111, 117, 118, 115, 120, 111, 109, 111, 104, 102, 106, 93, 88, 76, 66, 63, 52, 53, 31, 27, 25, 5, 12, 1, -5, 0, -15, -17, -23, -27, -27, -31, -31, -37, -44, -41, -43, -43, -35, -45, -43, -41, -50, -49, -51, -57, -58, -62, -72, -76, -79, -81, -82, -86, -92, -94, -100, -109, -110, -102, -99, -96, -83, -96, -83, -67, -73, -45, -41, -42, -27, -27, -19, -5, 7, 14, 30, 44, 46, 57, 75, 84, 98, 108, 102, 112, 114, 110, 120, 115, 116, 117, 108, 112, 107, 104, 108, 99, 96, 90, 73, 69, 66, 57, 48, 36, 26, 18, 13, 6, -3, 3, -8, -14, -15, -26, -25, -26, -33, -33, -40, -45, -45, -45, -42, -43, -44, -45, -48, -46, -55, -57, -58, -62, -67, -73, -78, -80, -81, -82, -89, -93, -99, -106, -108, -115, -100, -95, -103, -77, -91, -85, -59, -63, -48, -32, -36, -33, -18, -14, -6, 11, 21, 27, 47, 55, 56, 81, 92, 96, 114, 106, 111, 116, 110, 121, 113, 115, 115, 105, 111, 106, 101, 103, 100, 92, 84, 74, 66, 60, 58, 43, 29, 29, 13, 9, 10, -6, -2, -6, -16, -18, -22, -27, -30, -30, -35, -44, -43, -46, -46, -42, -44, -48, -45, -46, -50, -54, -51, -61, -63, -61, -85, -76, -80, -94, -75, -98, -97, -93, -111, -103, -106, -97, -97, -90, -79, -93, -73, -64, -67, -39, -38, -41, -20, -20, -12, 11, 10, 30, 40, 48, 62, 62, 85, 91, 99, 111, 101, 112, 111, 113, 120, 112, 119, 111, 108, 114, 101, 102, 104, 89, 91, 79, 63, 67, 56, 52, 41, 29, 26, 12, 14, 3, -5, 1, -14, -15, -19, -27, -24, -30, -31, -34, -43, -43, -45, -48, -40, -48, -48, -45, -51, -49, -53, -56, -57, -63, -69, -76, -86, -80, -86, -90, -87, -98, -101, -101, -108, -103, -88, -96, -88, -77, -89, -70, -60, -56, -39, -34, -30, -26, -11, -4, 6, 26, 27, 42, 54, 57, 72, 86, 95, 105, 107, 108, 112, 109, 116, 118, 112, 117, 108, 109, 107, 104, 103, 99, 97, 83, 77, 71, 57, 60, 49, 35, 30, 21, 11, 11, 4, -2, -3, -13, -17, -22, -24, -28, -29, -29, -39, -39, -44, -44, -41, -45, -44, -50, -49, -49, -56, -50, -60, -62, -55, -82, -70, -82, -90, -80, -95, -95, -100, -105, -112, -112, -93, -102, -91, -81, -91, -77, -60, -65, -45, -33, -40, -25, -21, -14, 5, 10, 30, 35, 49, 61, 61, 87, 94, 102, 109, 109, 112, 112, 116, 117, 116, 118, 116, 106, 113, 108, 101, 110, 96, 91, 84, 69, 66, 58, 54, 38, 29, 26, 12, 11, 6, -2, -2, -8, -16, -20, -23, -27, -28, -33, -34, -44, -43, -43, -47, -39, -44, -47, -43, -47, -49, -50, -52, -57, -58, -68, -75, -76, -83, -86, -86, -91, -97, -98, -103, -109, -102, -91, -99, -84, -81, -93, -65, -66, -60, -37, -42, -33, -25, -18, -9, 6, 16, 28, 41, 49, 57, 68, 84, 93, 102, 106, 106, 110, 107, 116, 114, 111, 119, 106, 111, 108, 101, 104, 99, 94, 85, 76, 68, 61, 56, 49, 34, 28, 21, 10, 10, 2, -3, -3, -13, -15, -24, -26, -28, -34, -31, -42, -45, -43, -48, -44, -43, -47, -47, -47, -48, -51, -57, -57, -63, -70, -72, -80, -86, -81, -92, -88, -96, -103, -100, -113, -110, -96, -101, -96, -79, -91, -82, -59, -68, -47, -34, -39, -29, -18, -13, -5, 18, 22, 32, 54, 52, 64, 83, 90, 100, 108, 109, 110, 113, 113, 116, 113, 117, 113, 106, 111, 103, 100, 101, 98, 86, 82, 73, 59, 61, 53, 36, 34, 24, 12, 10, 5, -5, -3, -8, -17, -18, -24, -27, -29, -30, -35, -40, -41, -45, -43, -43, -42, -45, -46, -44, -50, -49, -55, -58, -55, -71, -70, -79, -87, -77, -92, -88, -95, -104, -100, -115, -107, -91, -105, -85, -83, -97, -67, -68, -65, -37, -43, -33, -29, -21, -9, 0, 18, 23, 35, 55, 48, 69, 87, 86, 108, 107, 103, 117, 106, 117, 118, 113, 122, 109, 111, 111, 102, 110, 101, 98, 92, 77, 73, 62, 59, 54, 34, 34, 21, 11, 15, 2, 2, 2, -14, -12, -23, -26, -26, -33, -30, -40, -44, -42, -49, -41, -41, -44, -43, -46, -49, -51, -59, -54, -63, -67, -64, -84, -79, -76, -91, -82, -87, -100, -100, -101, -118, -101, -89, -107, -81, -82, -93, -65, -57, -57, -36, -26, -39, -17, -9, -13, 14, 21, 26, 45, 53, 54, 76, 88, 95, 111, 106, 111, 114, 109, 120, 115, 115, 116, 110, 105, 109, 104, 98, 105, 94, 83, 81, 68, 60, 62, 49, 32, 33, 18, 9, 12, 0, -3, -3, -13, -18, -20, -24, -27, -26, -31, -37, -40, -42, -42, -43, -42, -44, -48, -48, -47, -51, -54, -52, -56, -64, -68, -75, -84, -79, -89, -91, -93, -104, -105, -110, -114, -97, -97, -96, -78, -89, -81, -58, -66, -47, -34, -40, -31, -23, -14, -6, 14, 22, 31, 54, 55, 63, 87, 91, 103, 113, 105, 111, 113, 109, 119, 112, 117, 114, 106, 113, 106, 105, 105, 99, 93, 81, 74, 61, 58, 55, 36, 30, 25, 10, 11, 6, -5, 1, -8, -16, -19, -25, -27, -32, -32, -37, -44, -41, -47, -43, -39, -43, -44, -45, -46, -46, -56, -53, -55, -72, -64, -74, -91, -72, -88, -97, -80, -100, -105, -100, -111, -111, -88, -100, -99, -74, -97, -79, -54, -68, -43, -32, -41, -26, -10, -16, 6, 22, 19, 41, 51, 49, 69, 86, 88, 103, 107, 100, 119, 110, 111, 125, 110, 115, 115, 104, 108, 106, 99, 98, 98, 82, 76, 71, 60, 60, 52, 34, 30, 25, 9, 11, 3, -6, 0, -15, -18, -21, -27, -27, -30, -31, -38, -39, -43, -43, -39, -43, -44, -46, -47, -47, -54, -53, -59, -58, -65, -71, -75, -81, -75, -90, -83, -90, -100, -95, -111, -109, -101, -97, -100, -84, -86, -89, -62, -64, -50, -34, -37, -30, -21, -11, -8, 10, 19, 26, 47, 49, 59, 76, 89, 99, 107, 109, 110, 115, 113, 119, 115, 114, 115, 106, 111, 103, 103, 101, 98, 94, 81, 78, 65, 63, 59, 43, 34, 25, 17, 10, 7, -4, -3, -6, -14, -16, -23, -24, -28, -29, -33, -41, -41, -46, -43, -40, -44, -44, -46, -46, -47, -50, -54, -56, -58, -69, -70, -76, -83, -75, -87, -87, -91, -100, -100, -109, -108, -97, -98, -93, -83, -88, -76, -61, -59, -43, -36, -33, -28, -18, -11, -4, 14, 21, 31, 52, 51, 63, 84, 90, 101, 111, 104, 113, 113, 111, 118, 112, 114, 109, 108, 109, 102, 106, 101, 98, 94, 79, 74, 66, 58, 55, 39, 29, 24, 13, 11, 5, -4, 0, -10, -15, -17, -24, -25, -28, -29, -34, -41, -41, -47, -42, -44, -46, -45, -50, -45, -50, -55, -48, -60, -60, -65, -76, -77, -83, -84, -91, -92, -94, -106, -103, -109, -106, -89, -101, -82, -81, -88, -63, -66, -54, -36, -40, -31, -25, -16, -7, 6, 17, 30, 41, 55, 56, 73, 89, 92, 109, 104, 106, 114, 104, 117, 113, 110, 116, 105, 108, 106, 100, 102, 98, 94, 85, 74, 67, 59, 55, 48, 31, 28, 19, 10, 12, 0, 2, -2, -11, -11, -21, -21, -26, -30, -30, -40, -43, -43, -44, -40, -39, -41, -43, -42, -46, -52, -52, -58, -63, -65, -75, -79, -83, -80, -89, -85, -88, -101, -94, -104, -114, -93, -97, -104, -78, -92, -89, -60, -68, -48, -36, -36, -26, -21, -8, -5, 12, 23, 26, 47, 50, 54, 77, 85, 96, 109, 102, 114, 112, 109, 125, 112, 114, 118, 102, 110, 103, 99, 101, 96, 92, 79, 76, 66, 59, 61, 43, 32, 31, 14, 10, 9, -5, -2, -9, -17, -18, -28, -25, -31, -31, -31, -42, -38, -43, -41, -39, -43, -44, -47, -45, -48, -51, -53, -54, -61, -64, -67, -77, -76, -82, -81, -89, -93, -97, -106, -108, -105, -96, -99, -88, -82, -92, -67, -64, -60, -38, -38, -36, -24, -20, -16, 4, 11, 21, 36, 46, 53, 66, 85, 88, 103, 108, 102, 115, 107, 112, 115, 109, 114, 104, 106, 106, 99, 102, 101, 92, 89, 81, 67, 66, 58, 47, 39, 28, 21, 11, 12, 2, -2, 2, -12, -12, -17, -25, -24, -29, -30, -36, -39, -41, -41, -41, -39, -41, -44, -44, -47, -51, -52, -54, -59, -63, -65, -75, -79, -75, -90, -81, -89, -99, -92, -109, -109, -105, -99, -97, -92, -80, -90, -71, -58, -60, -37, -32, -37, -19, -15, -14, 9, 14, 23, 42, 46, 56, 67, 83, 96, 100, 111, 106, 111, 114, 111, 117, 111, 112, 109, 103, 107, 100, 99, 103, 92, 88, 82, 65, 66, 59, 48, 39, 27, 22, 12, 9, 5, -5, 0, -12, -16, -17, -26, -25, -26, -31, -34, -40, -41, -41, -41, -40, -42, -47, -43, -46, -46, -52, -50, -52, -61, -59, -74, -75, -77, -83, -84, -91, -92, -105, -100, -106, -109, -81, -103, -86, -73, -96, -64, -62, -59, -38, -39, -36, -28, -15, -11, 3, 18, 25, 37, 53, 53, 67, 89, 85, 106, 103, 98, 115, 99, 114, 115, 103, 116, 103, 104, 109, 98, 101, 98, 91, 84, 75, 67, 60, 55, 50, 31, 28, 20, 7, 15, 0, -3, 2, -15, -12, -19, -25, -24, -32, -32, -38, -44, -44, -45, -42, -41, -44, -43, -46, -44, -44, -58, -48, -63, -67, -63, -87, -75, -83, -90, -81, -94, -95, -95, -107, -109, -99, -95, -99, -85, -85, -90, -68, -62, -60, -36, -34, -39, -15, -13, -9, 14, 15, 29, 42, 50, 55, 68, 87, 91, 101, 107, 106, 110, 113, 114, 115, 114, 112, 108, 105, 106, 98, 98, 100, 88, 84, 75, 63, 63, 57, 46, 34, 28, 18, 10, 8, 0, -5, -5, -15, -19, -20, -26, -26, -26, -31, -36, -40, -42, -43, -42, -39, -44, -44, -42, -44, -47, -51, -52, -54, -65, -63, -76, -81, -68, -93, -84, -85, -104, -92, -105, -109, -95, -95, -96, -84, -82, -84, -64, -64, -52, -39, -37, -33, -23, -11, -9, 10, 20, 25, 49, 46, 60, 76, 82, 98, 101, 104, 110, 108, 108, 116, 111, 111, 113, 104, 108, 106, 101, 98, 99, 92, 80, 79, 63, 61, 59, 41, 35, 27, 18, 13, 9, 2, 0, -5, -12, -15, -20, -22, -26, -27, -30, -38, -39, -42, -40, -39, -40, -40, -45, -43, -47, -49, -54, -53, -57, -70, -59, -80, -77, -72, -93, -75, -91, -99, -93, -105, -108, -97, -92, -99, -80, -84, -84, -61, -59, -49, -35, -28, -34, -14, -9, -10, 19, 17, 27, 47, 47, 61, 72, 87, 95, 105, 104, 110, 111, 109, 117, 109, 111, 109, 103, 103, 102, 97, 95, 100, 85, 81, 77, 61, 64, 55, 42, 34, 26, 17, 10, 9, -3, -2, -5, -13, -15, -20, -23, -27, -27, -32, -37, -38, -41, -40, -41, -39, -43, -43, -40, -48, -47, -49, -55, -61, -59, -70, -80, -69, -87, -83, -79, -97, -89, -98, -101, -107, -96, -93, -101, -77, -90, -84, -62, -63, -49, -36, -34, -30, -15, -12, -2, 11, 20, 32, 39, 53, 56, 71, 87, 89, 103, 101, 109, 109, 109, 118, 106, 114, 111, 101, 107, 102, 93, 99, 94, 84, 85, 71, 65, 62, 54, 45, 32, 30, 16, 12, 8, -5, -2, -9, -14, -16, -24, -22, -27, -29, -31, -38, -41, -38, -44, -42, -41, -47, -45, -44, -48, -50, -50, -52, -62, -57, -69, -79, -69, -83, -88, -78, -99, -97, -92, -109, -106, -91, -100, -93, -76, -91, -80, -60, -66, -48, -37, -38, -32, -18, -15, -4, 11, 14, 31, 42, 48, 60, 69, 85, 94, 96, 102, 107, 103, 109, 115, 104, 112, 109, 100, 106, 103, 95, 97, 96, 84, 82, 73, 60, 62, 54, 41, 33, 27, 17, 14, 7, 0, 0, -8, -11, -16, -23, -23, -29, -29, -32, -39, -40, -40, -40, -41, -40, -46, -48, -45, -50, -51, -54, -56, -64, -63, -71, -78, -73, -84, -82, -87, -95, -93, -102, -102, -108, -95, -96, -95, -76, -90, -77, -57, -61, -42, -33, -35, -26, -13, -14, 3, 15, 17, 36, 45, 54, 60, 80, 89, 96, 108, 101, 111, 110, 109, 118, 107, 110, 109, 102, 103, 103, 95, 97, 96, 83, 82, 70, 60, 61, 51, 38, 28, 23, 11, 8, 4, -7, -3, -10, -16, -17, -22, -25, -27, -29, -35, -38, -43, -42, -41, -40, -39, -43, -42, -44, -45, -46, -53, -51, -55, -68, -65, -75, -79, -77, -88, -83, -94, -93, -101, -105, -96, -96, -92, -85, -85, -83, -71, -64, -57, -41, -41, -31, -27, -17, -7, 2, 18, 23, 38, 48, 51, 68, 78, 91, 98, 102, 106, 108, 110, 112, 115, 110, 115, 107, 107, 108, 99, 102, 97, 94, 87, 76, 70, 63, 60, 49, 39, 30, 22, 16, 8, 4, 0, -4, -10, -14, -20, -24, -25, -31, -30, -37, -41, -40, -41, -38, -39, -40, -42, -41, -43, -48, -44, -55, -58, -57, -71, -71, -73, -78, -79, -80, -88, -89, -95, -99, -103, -101, -88, -98, -85, -79, -90, -62, -60, -54, -35, -35, -27, -21, -9, -3, 7, 22, 26, 38, 52, 54, 67, 87, 89, 101, 105, 103, 114, 107, 117, 112, 107, 116, 100, 105, 103, 94, 98, 93, 87, 80, 73, 65, 59, 56, 45, 31, 28, 19, 6, 10, -3, -5, -4, -17, -16, -22, -24, -25, -30, -28, -39, -37, -40, -44, -40, -44, -46, -46, -47, -51, -50, -55, -55, -60, -67, -65, -81, -75, -78, -93, -78, -97, -101, -94, -113, -104, -92, -96, -91, -79, -86, -79, -58, -58, -49, -34, -34, -33, -14, -12, -5, 20, 19, 34, 49, 49, 66, 76, 91, 98, 98, 105, 104, 107, 111, 110, 109, 108, 108, 103, 101, 102, 97, 95, 96, 80, 75, 71, 56, 58, 49, 33, 28, 20, 13, 7, 4, -4, -7, -9, -18, -22, -22, -28, -30, -30, -38, -41, -41, -43, -40, -41, -40, -44, -43, -45, -48, -49, -55, -55, -59, -67, -66, -82, -70, -81, -86, -78, -101, -92, -98, -111, -98, -95, -95, -89, -76, -91, -70, -56, -61, -38, -34, -33, -25, -12, -10, 1, 21, 15, 39, 47, 48, 68, 75, 90, 97, 101, 103, 106, 106, 110, 111, 104, 111, 101, 99, 103, 96, 94, 95, 92, 75, 79, 64, 55, 64, 43, 36, 30, 17, 13, 9, 3, -4, -3, -12, -16, -18, -23, -25, -26, -29, -35, -38, -42, -40, -39, -41, -38, -48, -42, -45, -50, -49, -52, -57, -63, -57, -78, -76, -67, -94, -75, -88, -100, -92, -103, -106, -97, -88, -96, -81, -77, -85, -60, -55, -51, -35, -30, -33, -19, -9, -10, 17, 16, 30, 46, 48, 64, 72, 86, 96, 101, 104, 105, 111, 104, 116, 109, 107, 110, 104, 101, 104, 100, 93, 100, 86, 77, 78, 59, 60, 54, 40, 32, 23, 18, 9, 9, 0, -5, -6, -14, -17, -20, -23, -25, -26, -31, -35, -39, -40, -36, -40, -37, -40, -45, -42, -45, -48, -51, -50, -57, -64, -62, -76, -78, -71, -90, -84, -88, -101, -97, -105, -108, -94, -97, -92, -81, -87, -76, -63, -58, -42, -36, -33, -27, -15, -10, -2, 18, 19, 34, 49, 47, 66, 78, 86, 102, 104, 104, 111, 109, 112, 115, 112, 110, 108, 106, 101, 102, 98, 96, 97, 86, 79, 72, 62, 61, 51, 39, 32, 20, 15, 10, 2, 1, -4, -9, -13, -18, -22, -24, -25, -29, -33, -37, -41, -39, -37, -39, -39, -43, -46, -46, -49, -49, -56, -54, -57, -68, -66, -73, -77, -79, -83, -90, -96, -95, -107, -110, -98, -97, -98, -76, -87, -83, -56, -68, -49, -34, -43, -28, -26, -18, -8, 3, 14, 22, 39, 47, 54, 70, 83, 90, 101, 100, 104, 107, 102, 113, 103, 106, 109, 95, 106, 99, 95, 101, 92, 93, 83, 74, 66, 60, 56, 44, 33, 26, 17, 12, 8, 1, 2, -4, -11, -10, -21, -19, -25, -29, -28, -39, -38, -41, -41, -37, -40, -42, -43, -42, -45, -47, -48, -56, -52, -59, -69, -67, -78, -78, -79, -88, -86, -95, -100, -99, -112, -95, -92, -101, -77, -86, -86, -62, -65, -51, -39, -35, -31, -26, -8, -11, 7, 26, 21, 45, 53, 50, 76, 86, 90, 105, 102, 105, 109, 108, 115, 107, 112, 110, 100, 108, 100, 96, 100, 93, 89, 79, 72, 64, 58, 56, 42, 31, 28, 14, 10, 9, -5, -2, -6, -14, -15, -22, -22, -27, -28, -31, -41, -37, -41, -42, -37, -41, -45, -43, -45, -47, -48, -49, -58, -53, -64, -71, -68, -82, -75, -83, -91, -87, -103, -97, -104, -111, -90, -98, -95, -77, -91, -76, -61, -63, -43, -41, -35, -29, -23, -7, -7, 13, 22, 24, 50, 50, 59, 82, 82, 99, 102, 100, 110, 105, 111, 113, 104, 114, 103, 104, 107, 96, 102, 97, 92, 90, 77, 73, 64, 58, 53, 38, 31, 23, 13, 12, 3, 0, -2, -11, -10, -17, -21, -20, -29, -27, -33, -40, -38, -44, -39, -39, -43, -41, -42, -42, -46, -42, -53, -53, -52, -71, -67, -73, -83, -80, -81, -89, -93, -91, -100, -106, -97, -96, -93, -88, -81, -85, -79, -59, -58, -48, -30, -36, -28, -11, -9, -2, 21, 22, 32, 50, 52, 58, 79, 89, 90, 104, 104, 100, 113, 111, 109, 114, 109, 107, 103, 104, 99, 94, 97, 91, 78, 79, 65, 58, 61, 47, 37, 30, 23, 14, 10, 7, -7, -4, -8, -21, -17, -23, -30, -26, -30, -36, -37, -39, -38, -38, -36, -38, -45, -41, -45, -49, -51, -56, -57, -63, -64, -69, -78, -70, -80, -84, -84, -91, -100, -98, -106, -108, -90, -103, -90, -80, -93, -65, -64, -52, -38, -37, -27, -26, -12, -6, 3, 18, 22, 36, 48, 54, 69, 84, 89, 105, 103, 106, 117, 105, 117, 113, 106, 113, 101, 105, 101, 99, 98, 93, 94, 83, 75, 70, 60, 55, 49, 33, 27, 19, 10, 8, -2, -2, -7, -13, -12, -22, -20, -23, -28, -28, -35, -39, -40, -41, -40, -42, -40, -43, -42, -42, -44, -46, -49, -52, -59, -60, -70, -74, -71, -84, -82, -88, -96, -98, -100, -105, -102, -88, -95, -83, -79, -87, -62, -62, -52, -40, -39, -31, -27, -14, -10, 7, 17, 25, 42, 49, 59, 72, 85, 92, 103, 103, 102, 111, 104, 113, 110, 104, 112, 102, 107, 103, 101, 99, 97, 92, 81, 76, 64, 61, 54, 42, 33, 24, 17, 11, 8, -2, -2, -5, -13, -12, -22, -23, -26, -31, -32, -38, -40, -43, -39, -40, -41, -40, -44, -41, -44, -47, -51, -49, -62, -55, -68, -78, -68, -89, -79, -81, -96, -85, -101, -100, -103, -98, -91, -97, -79, -83, -87, -61, -64, -55, -31, -41, -29, -15, -19, 3, 9, 18, 33, 36, 56, 54, 71, 87, 87, 103, 103, 103, 110, 107, 113, 112, 108, 111, 101, 104, 103, 92, 101, 92, 84, 84, 66, 65, 59, 51, 45, 31, 27, 16, 10, 6, -3, -3, -9, -15, -16, -22, -24, -25, -30, -28, -36, -40, -36, -42, -38, -41, -45, -44, -47, -47, -49, -51, -52, -54, -62, -68, -73, -78, -81, -84, -83, -97, -94, -101, -113, -100, -99, -96, -87, -83, -85, -75, -60, -60, -43, -36, -38, -27, -20, -15, 0, 14, 19, 33, 47, 49, 67, 78, 90, 100, 103, 105, 107, 108, 110, 112, 109, 109, 107, 102, 105, 100, 99, 98, 95, 84, 80, 69, 59, 60, 48, 36, 31, 18, 14, 9, 3, -2, -5, -10, -15, -19, -24, -25, -28, -31, -34, -39, -41, -40, -38, -40, -38, -43, -43, -42, -48, -47, -53, -54, -58, -67, -63, -79, -73, -78, -90, -80, -98, -97, -101, -109, -105, -93, -98, -90, -76, -93, -66, -60, -59, -33, -42, -32, -26, -18, -9, 0, 17, 21, 38, 48, 53, 69, 82, 93, 101, 107, 102, 112, 108, 111, 115, 105, 112, 103, 105, 104, 96, 103, 95, 95, 85, 76, 68, 63, 59, 47, 38, 26, 19, 13, 7, 1, -3, -4, -14, -12, -19, -23, -21, -29, -29, -35, -40, -41, -42, -39, -43, -42, -46, -43, -47, -45, -48, -54, -47, -66, -61, -68, -85, -66, -90, -84, -84, -103, -91, -106, -105, -96, -90, -92, -81, -79, -86, -59, -59, -53, -34, -36, -33, -19, -10, -10, 17, 20, 26, 52, 48, 60, 75, 85, 95, 102, 104, 102, 111, 107, 113, 110, 109, 111, 103, 107, 102, 97, 96, 95, 85, 77, 73, 56, 60, 52, 37, 33, 22, 16, 11, 7, -3, -4, -6, -16, -14, -21, -24, -24, -28, -32, -37, -38, -42, -36, -37, -39, -39, -43, -40, -42, -48, -50, -50, -64, -57, -70, -84, -63, -90, -81, -77, -101, -85, -99, -105, -102, -100, -92, -99, -79, -89, -86, -58, -65, -49, -29, -41, -26, -11, -19, 6, 12, 14, 39, 37, 52, 60, 68, 90, 90, 104, 102, 106, 111, 108, 118, 109, 109, 111, 98, 106, 101, 90, 101, 90, 82, 86, 63, 65, 63, 48, 47, 29, 25, 16, 10, 6, -6, -3, -13, -18, -16, -26, -25, -25, -32, -30, -39, -43, -37, -43, -39, -39, -48, -44, -46, -53, -50, -56, -59, -59, -67, -72, -77, -76, -84, -83, -84, -100, -95, -103, -115, -98, -93, -103, -82, -82, -91, -60, -62, -54, -34, -35, -31, -23, -13, -11, 7, 19, 21, 43, 48, 55, 73, 85, 94, 104, 102, 109, 110, 105, 118, 107, 109, 113, 98, 106, 103, 96, 99, 98, 90, 82, 79, 62, 62, 58, 41, 34, 26, 14, 10, 8, -3, -2, -5, -14, -13, -20, -20, -24, -26, -28, -38, -39, -42, -42, -41, -41, -42, -48, -41, -43, -50, -41, -49, -59, -50, -68, -74, -67, -82, -80, -89, -87, -101, -101, -93, -121, -85, -90, -105, -65, -93, -82, -55, -69, -49, -38, -46, -32, -27, -19, -5, 3, 19, 26, 41, 53, 52, 81, 81, 95, 104, 90, 113, 101, 105, 118, 99, 113, 109, 100, 109, 104, 98, 104, 96, 89, 83, 71, 66, 57, 56, 38, 28, 29, 8, 17, 6, -2, 3, -24, -13, -79, -103, -120, -116, -104, -87, -76, -63, 63, 82, 97, 108, 119, 99, 70, 69, 80, 91, 92, 98, 115, 124, 127, 113, 82, 42, 4, -44, -70, -82, -100, -87, -62, -58, -71, -65, -79, -60, -102, -113, -62, -44, -31, -31, -22, -18, -3, 4, 11, 20, 28, 11, 15, 18, 27, 18, 7, 13, 26, 11, -19, -69, -108, -84, -51, -21, -3, -6, -18, -17, -31, -33, -18, 2, 4, 26, 47, 48, 77, 117, 127, 127, 127, 121, 110, 86, 72, 62, 46, 11, 17, -2, -7, -13, -44, -60, -61, -61, -63, -72, -79, -99, -116, -127, -128, -128, -124, -81, -51, -4, 5, -6, 7, 8, 9, 31, 31, 16, 34, 28, 34, 34, 46, 78, 84, 93, 69, 47, 40, 64, 44, 27, 22, 0, -29, -8, 15, -6, -36, -66, -68, -42, 0, 6, 1, 13, 24, 41, 64, 58, 50, 40, 4, 0, 3, -24, -3, 21, 28, 26, 9, -30, -42, -61, -85, -92, -91, -96, -87, -74, -31, -20, -38, -14, -44, -17, 18, -25, -9, 7, 1, 11, -2, -19, 12, 47, 76, 72, 58, 68, 69, 82, 86, 76, 58, 9, -23, -12, -7, -22, -2, 0, -9, -2, -15, -10, -3, -22, -17, -38, -44, -33, -24, -27, -16, 0, -15, 20, 19, 18, 1, 10, 41, -1, -25, -25, -11, 30, 37, 9, 45, 37, -30, -30, 21, 5, -26, -43, -56, -42, -48, -48, -29, -62, -76, -42, -23, -12, -14, 8, 45, 36, 40, 25, 14, 11, 40, 46, 55, 65, 30, 17, 30, 36, 33, 18, 13, 16, 15, 46, 37, 2, -1, -26, -36, -19, -21, -36, -62, -51, -48, -20, -2, 3, -12, -12, -10, -35, -37, -49, -22, 14, 61, 40, 60, 75, 33, 41, 48, 38, 29, -32, -45, -56, -64, -61, -30, -20, 30, 10, -46, -37, -35, -30, -24, -12, -23, -34, -29, -22, -20, -14, 4, 44, 77, 49, 10, 8, 24, 20, 28, 31, 27, 40, 35, 69, 39, 54, 38, 26, 22, 43, 36, 7, 14, 2, -25, -50, -51, -56, -42, -55, -46, -36, -44, -36, -35, 1, 23, 11, -3, -34, -66, -33, -12, -31, -27, -13, -1, 21, 31, 23, 0, -11, -3, -2, 9, 27, 5, -8, -2, -17, -13, 10, 9, 3, 35, 32, 43, 24, 15, 2, -15, -9, -5, 2, 5, 27, 25, 42, 76, 61, 17, 25, 14, -5, -17, -24, -6, 11, 23, 7, -8, 5, -11, -23, -27, -48, -30, -12, -26, -36, -37, -39, -46, -61, -55, -23, -20, -22, -14, -10, -16, -16, -22, -11, -3, -14, -34, -16, 9, 28, 25, 50, 63, 52, 56, 46, 50, 54, 56, 45, 54, 29, 20, 21, 0, 0, 6, 16, 28, 14, -1, -9, -10, -4, -9, -13, -7, -21, -27, -29, -40, -41, -35, -42, -64, -11, 9, 2, -12, -24, -37, -40, -34, -29, -34, -12, -26, -20, -6, -4, 5, 5, 27, 1, -17, 2, 21, 12, 8, 9, 15, 23, 24, 1, 5, 22, 25, 28, 57, 55, 41, 33, 36, 27, 5, 1, 15, 34, 23, 4, 20, 18, -1, -21, -22, -15, -17, -8, -6, -6, -12, -15, -26, 1, 29, -8, -40, -52, -55, -19, -21, -36, -48, -56, -29, -15, -29, -39, -46, -35, -14, -11, -16, 1, 27, 22, -10, -14, -7, -12, -12, 23, 55, 48, 65, 42, 20, 46, 45, 49, 42, 38, 34, 25, 33, 21, 10, 38, 40, 26, 22, 37, 33, 12, 4, 7, -14, -49, -41, -36, -53, -40, -35, -44, -31, -22, -19, -50, -78, -80, -78, -48, -31, -18, -27, -28, -7, -17, -11, 5, 32, 39, 19, 14, 22, 34, 37, 23, 20, 40, 40, 27, 14, 11, 7, 29, 34, 19, 32, 7, -15, -12, -24, -12, 8, 6, 21, 34, 29, -6, -22, -15, 1, -1, 24, 27, 20, 36, 42, 45, 27, -14, -50, -34, -14, -26, -25, -10, 10, -4, -28, -30, -34, -69, -91, -85, -74, -51, -38, -24, -19, -9, -7, -30, -35, -30, -36, -12, 25, 32, 44, 50, 45, 51, 68, 94, 90, 74, 60, 52, 64, 48, 30, 11, 11, 11, 2, 14, 24, 16, 13, -7, -17, -9, -12, -20, -32, -45, -54, -58, -35, -23, -46, -51, -33, -28, -29, -24, -36, -30, -24, -22, -20, -13, -9, -14, -7, 10, 26, 22, 9, 9, 10, -2, -9, -15, -11, -1, 19, 27, 33, 28, 5, 3, 5, 6, 10, 14, 24, 32, 36, 40, 41, 37, 19, 11, 3, -7, -10, -7, 6, 27, 38, 28, 23, 16, 18, 15, -7, -33, -20, -13, -24, -25, -19, -15, -26, -52, -56, -48, -41, -36, -30, -32, -30, -15, -38, -49, -47, -32, -17, -17, -11, -3, 3, 8, 24, 28, 16, 6, 1, 7, 28, 41, 42, 69, 87, 78, 73, 62, 30, 14, 9, 7, 15, 32, 20, 10, -8, -20, 2, 9, -2, 5, 12, -4, -12, -19, -32, -37, -29, -24, -28, -39, -43, -40, -44, -28, -25, -33, -39, -37, -34, -29, -28, -25, -19, -1, -5, -22, -12, 2, 6, 38, 46, 25, 30, 41, 47, 37, 21, 7, -7, -8, 11, 39, 48, 43, 35, 27, 25, 22, -1, -22, -11, 13, -4, -13, -3, -8, -7, -11, -17, -5, 5, 9, 8, 15, 25, 16, 22, 20, 5, -16, -27, -29, -30, -9, 9, 9, 3, -14, -50, -56, -56, -79, -92, -80, -57, -24, 12, 10, 11, 4, -22, -21, -13, -2, 4, 10, 15, 8, 35, 72, 53, 44, 25, 25, 48, 56, 69, 53, 50, 75, 85, 71, 33, 12, -16, -32, -25, -14, -5, -16, -23, -19, -22, -39, -41, -47, -45, -33, -35, -39, -38, -35, -34, -29, -28, -28, -23, -10, -7, -9, -11, -18, -5, 13, 1, -13, -8, -5, 6, 27, 46, 43, 25, 8, 11, 16, 18, 23, 30, 12, 5, 10, 7, 5, -6, -4, -5, 1, 10, 9, 15, 21, 17, 10, -8, -16, 10, 33, 34, 23, 13, 17, 17, 9, 11, 7, -4, -8, -8, -22, -27, -26, -19, -7, -18, -16, -16, -47, -62, -55, -36, -16, -25, -33, -30, -34, -42, -49, -41, -43, -31, -20, -3, 28, 48, 66, 64, 36, 20, 26, 21, 22, 39, 51, 45, 39, 40, 53, 56, 39, 24, 16, 12, 16, 24, 27, 16, 13, 7, -18, -33, -50, -47, -33, -24, -20, -26, -32, -31, -46, -53, -58, -56, -29, -13, -11, -2, 8, -11, -24, -11, -9, -6, -2, -6, 1, 4, 5, 11, 6, 7, 16, 30, 28, 19, 15, 7, 4, 11, 27, 22, 6, 9, 11, 3, 4, 17, 27, 18, 11, 12, 5, 2, -2, -6, -7, -2, 10, 12, 9, 1, -2, 3, 4, 11, 21, 30, 28, 6, -9, -18, -22, -22, -38, -41, -27, -18, -18, -27, -27, -23, -32, -35, -32, -34, -30, -25, -24, -18, -9, -5, 5, -5, -26, -19, -11, -4, 11, 37, 48, 46, 50, 53, 50, 45, 45, 37, 18, 24, 44, 38, 43, 47, 29, 15, 11, 10, 12, 4, -8, -6, -4, -17, -27, -28, -36, -34, -37, -53, -53, -46, -38, -38, -37, -28, -24, -23, -37, -42, -30, 0, 20, 18, 12, 14, 9, 2, 6, 15, 13, 10, 14, 12, 2, 12, 29, 21, 1, 7, 21, 19, 14, 15, 15, 4, -1, 5, -1, -4, 0, -2, 3, 6, 6, 13, 21, 15, 7, 3, 5, 2, -3, 3, 3, 5, 8, 10, 16, 14, -1, -7, 2, 11, 12, -10, -35, -42, -26, -21, -37, -44, -44, -47, -42, -27, -27, -23, -15, -16, -20, -21, -14, -12, -9, -7, -6, 0, 13, 30, 32, 37, 38, 31, 24, 25, 43, 54, 49, 46, 44, 40, 41, 30, 9, -1, 6, 22, 31, 22, 9, 0, -14, -23, -29, -29, -28, -35, -39, -39, -39, -33, -25, -30, -44, -49, -45, -45, -35, -19, 2, 16, 16, 9, 0, 0, 6, 2, -1, 11, 27, 40, 32, 16, -2, -2, 1, 3, 1, 7, 12, 6, 8, 11, 5, -1, -2, -1, 1, 8, 10, 5, 4, 14, 17, 6, -1, 0, 4, 4, 17, 23, 19, 25, 20, 5, -8, -9, -2, -1, -6, -3, 13, 16, 1, -13, -19, -21, -26, -34, -37, -23, -13, -13, -24, -40, -42, -40, -39, -29, -22, -21, -18, -12, -2, 18, 24, 10, 0, -6, -4, 15, 33, 34, 34, 44, 41, 31, 33, 44, 43, 31, 22, 20, 17, 16, 23, 22, 19, 21, 10, -5, -6, -9, -8, -2, -5, -16, -28, -36, -47, -53, -39, -23, -21, -24, -32, -43, -39, -34, -24, -18, -14, -11, -12, -6, 10, 29, 41, 40, 27, 14, 10, 4, 1, 3, 2, 9, 19, 21, 9, -10, -16, -10, 8, 18, 20, 13, -3, -8, -4, -1, 2, 5, 5, -1, 3, 9, 12, 16, 16, 14, 9, 3, 5, 10, 4, -6, 1, 6, 5, 13, 20, 11, 1, -7, -21, -30, -25, -12, -9, -13, -19, -24, -29, -34, -30, -32, -39, -33, -24, -20, -22, -24, -13, 3, 6, 2, 1, 3, 5, 16, 30, 35, 35, 24, 16, 15, 19, 31, 37, 33, 28, 29, 29, 30, 26, 20, 15, 13, 10, 10, 12, 9, 7, -3, -21, -39, -44, -43, -42, -34, -26, -23, -18, -12, -18, -32, -36, -31, -27, -20, -10, -7, -9, -11, -5, 2, 12, 19, 19, 25, 24, 11, 3, 15, 29, 30, 20, 9, 1, -1, 1, 5, 2, -3, -2, 0, -6, -18, -27, -20, -3, 8, 13, 15, 11, 7, 10, 18, 16, 10, 6, 3, -1, 1, 11, 19, 19, 15, 14, 5, -2, -2, -7, -12, -15, -20, -16, -10, -5, 2, 1, -13, -29, -33, -24, -10, -6, -13, -18, -23, -31, -32, -26, -22, -18, -13, -3, 2, 3, 7, 8, 10, 19, 27, 32, 33, 33, 35, 38, 43, 41, 29, 9, -4, -9, 2, 16, 17, 13, 15, 17, 13, 10, 5, -1, -8, -18, -29, -32, -27, -21, -22, -30, -31, -31, -33, -31, -27, -18, -7, -6, -15, -16, -8, -1, 4, 12, 18, 22, 20, 16, 11, 10, 14, 18, 16, 15, 14, 9, 6, 4, 3, 3, 0, -5, -13, -18, -15, -13, -9, -7, -8, -5, -2, -5, -1, 5, 8, 10, 11, 12, 17, 19, 16, 10, 4, 4, 8, 8, 8, 13, 14, 9, 3, 0, -1, 0, 0, -7, -19, -24, -20, -15, -12, -15, -21, -23, -24, -26, -28, -29, -28, -21, -10, -1, 5, 6, -3, -12, -14, -11, -1, 12, 16, 17, 28, 36, 28, 20, 25, 27, 24, 25, 28, 21, 15, 11, 3, 4, 12, 11, 0, -7, -5, -1, -1, -5, -8, -11, -17, -23, -22, -19, -21, -20, -20, -22, -24, -22, -17, -20, -24, -20, -10, 2, 10, 13, 14, 14, 11, 8, 8, 12, 17, 18, 20, 20, 14, 4, -1, -2, -1, 3, 11, 12, 6, 0, -9, -20, -25, -18, -9, -8, -13, -18, -19, -14, -6, 0, 4, 11, 19, 22, 20, 19, 15, 13, 14, 18, 17, 12, 7, 9, 14, 9, -1, -4, -1, -5, -10, -12, -16, -23, -19, -7, -5, -10, -10, -11, -19, -27, -24, -14, -6, -3, -10, -21, -24, -15, -6, 0, 9, 15, 12, 8, 6, 9, 9, 11, 20, 26, 31, 35, 30, 21, 16, 16, 13, 6, 2, 4, 5, 3, -2, -10, -13, -11, -8, -9, -13, -16, -18, -18, -19, -22, -18, -8, -3, -1, 0, -5, -11, -10, -9, -11, -9, -2, 2, 4, 10, 15, 18, 19, 21, 21, 22, 22, 15, 4, -4, -8, -7, -6, -10, -14, -18, -23, -20, -15, -8, -1, 0, -4, -7, -9, -9, -6, -2, 2, 6, 7, 4, 1, 0, 7, 13, 11, 14, 22, 22, 15, 8, 2, 4, 10, 16, 17, 13, 10, 9, 6, -3, -13, -23, -26, -21, -17, -14, -12, -13, -16, -14, -9, -8, -8, -11, -18, -18, -12, -4, 0, 2, 6, 6, -1, -6, 0, 8, 11, 13, 11, 6, 6, 9, 13, 16, 16, 15, 10, 7, 10, 10, 4, 0, -2, -3, -1, 2, 2, -1, -5, -13, -21, -27, -30, -26, -16, -4, 5, 8, 6, 2, -3, -5, -1, 4, 8, 9, 11, 11, 6, 0, 0, 7, 12, 13, 11, 7, 1, -4, -3, 0, 5, 6, 5, -2, -10, -13, -13, -10, -5, -4, -9, -18, -28, -31, -24, -14, -10, -4, 2, 5, 4, 2, 4, 13, 20, 21, 19, 14, 11, 11, 12, 13, 14, 15, 17, 18, 18, 14, 5, -3, -5, -8, -11, -11, -12, -15, -15, -13, -13, -15, -13, -12, -15, -16, -11, -7, -6, -4, -1, 4, 6, -1, -10, -11, -7, -4, -1, 4, 9, 11, 12, 9, 7, 8, 8, 7, 9, 13, 15, 12, 4, 1, 1, -2, -9, -10, -7, -1, 3, 3, -1, -9, -12, -9, -5, 1, 3, -2, -10, -10, -7, -4, 2, 8, 6, 4, 6, 5, -1, -1, 7, 17, 20, 17, 16, 19, 16, 7, -3, -8, -9, -9, -11, -15, -24, -27, -20, -15, -12, -11, -7, -3, -4, -6, -7, -6, -8, -14, -18, -18, -15, -10, -5, 3, 12, 18, 20, 17, 11, 10, 16, 21, 22, 23, 23, 22, 17, 9, 0, -3, 2, 10, 15, 16, 11, 2, -9, -19, -23, -22, -15, -10, -8, -11, -13, -15, -17, -19, -18, -15, -10, -3, 1, -2, -6, -3, 0, -3, -3, 0, 6, 10, 9, 7, 4, -1, -4, 0, 10, 17, 16, 11, 5, 0, -1, 2, 5, 1, -6, -10, -10, -8, -6, -4, -2, -4, -7, -9, -9, -6, 2, 12, 17, 16, 11, 8, 7, 6, 5, 7, 9, 12, 14, 14, 9, 3, -1, -3, -5, -4, 0, 4, -1, -10, -18, -24, -29, -28, -20, -14, -13, -12, -8, -5, -5, -9, -13, -14, -11, -10, -9, -4, 1, 3, 2, 3, 8, 16, 20, 18, 13, 10, 14, 24, 29, 29, 27, 23, 17, 14, 16, 17, 15, 9, -1, -7, -10, -14, -18, -16, -11, -8, -7, -8, -12, -18, -26, -29, -26, -19, -11, -5, -3, -3, -2, 0, 2, 0, -3, -3, -2, -3, -4, -2, -1, 3, 7, 9, 8, 7, 3, 1, 4, 5, 2, 3, 5, 5, 0, -7, -9, -6, -1, 5, 9, 8, 3, -2, -6, -5, 3, 9, 12, 11, 8, 4, 3, 4, 6, 11, 13, 8, 1, 0, 4, 9, 13, 12, 5, 2, 3, 3, 0, -6, -16, -26, -30, -28, -26, -22, -18, -17, -19, -22, -24, -19, -12, -7, -2, 1, 0, -2, -4, -5, -2, 4, 10, 14, 15, 15, 16, 16, 17, 19, 22, 26, 25, 19, 13, 10, 7, 9, 11, 10, 7, 4, 1, -5, -8, -8, -4, 0, 1, -4, -11, -16, -17, -16, -14, -12, -10, -11, -14, -15, -16, -13, -9, -3, 1, 2, 1, 0, 0, -3, -9, -13, -10, -8, -7, -4, 0, 3, 6, 9, 9, 5, 3, 3, 5, 8, 12, 12, 6, -1, -2, 2, 8, 8, 4, -2, -5, -1, 4, 10, 13, 14, 13, 13, 14, 14, 12, 10, 8, 8, 8, 6, 6, 9, 6, -1, -9, -15, -19, -22, -24, -23, -25, -25, -23, -20, -19, -19, -21, -20, -20, -21, -19, -11, -2, 2, 1, 0, 3, 9, 13, 15, 16, 14, 10, 5, 3, 8, 14, 16, 18, 20, 22, 24, 21, 15, 9, 6, 8, 14, 18, 15, 9, 4, 1, 0, -2, -4, -4, -3, -3, -4, -7, -11, -13, -12, -11, -15, -19, -22, -25, -25, -21, -14, -11, -15, -19, -18, -14, -7, -1, 4, 2, -3, -6, -4, 0, 5, 10, 16, 17, 12, 7, 2, -1, -3, 0, 3, 6, 10, 14, 12, 6, 2, 5, 10, 15, 18, 18, 16, 14, 11, 6, 4, 3, 1, 1, 2, 6, 9, 9, 3, -2, -3, -4, -6, -8, -10, -15, -19, -20, -19, -18, -17, -15, -16, -17, -18, -20, -22, -21, -16, -11, -4, 1, 0, -4, -4, -1, 1, 2, 4, 4, 3, 3, 4, 7, 11, 16, 21, 20, 15, 11, 9, 12, 16, 21, 24, 23, 21, 17, 13, 11, 9, 4, 0, 0, 1, 3, 4, 0, -4, -7, -7, -9, -13, -17, -20, -22, -23, -21, -16, -12, -12, -15, -17, -17, -15, -12, -10, -10, -11, -12, -15, -15, -10, -4, 0, -1, -1, 1, 4, 7, 13, 19, 22, 23, 21, 19, 18, 17, 11, 5, 2, 5, 10, 13, 15, 15, 14, 13, 10, 5, 1, 0, 2, 5, 8, 10, 9, 6, 4, 2, -1, -5, -7, -8, -7, -8, -11, -13, -14, -16, -19, -21, -22, -22, -24, -23, -20, -17, -16, -16, -15, -16, -16, -15, -13, -11, -9, -5, 0, 6, 12, 15, 18, 18, 17, 17, 19, 20, 19, 19, 20, 23, 25, 25, 23, 20, 17, 13, 11, 9, 9, 8, 6, 3, 1, -2, -5, -5, -2, -1, -3, -7, -6, -3, 0, -2, -9, -21, -29, -32, -32, -30, -27, -27, -29, -30, -28, -24, -23, -21, -16, -7, 0, 1, 2, 2, 4, 7, 10, 14, 16, 14, 12, 13, 15, 18, 20, 22, 23, 20, 15, 8, 3, 2, 7, 13, 15, 13, 7, 2, 0, 0, -1, -2, -1, 1, 2, 1, 0, 2, 3, 4, 4, 6, 7, 5, 0, -10, -21, -30, -36, -36, -33, -28, -23, -18, -15, -14, -17, -19, -19, -17, -12, -5, -2, -2, -3, -1, 2, 6, 10, 12, 14, 13, 12, 13, 18, 25, 29, 28, 24, 19, 14, 10, 6, 6, 9, 12, 13, 15, 17, 18, 18, 14, 7, 0, -1, 1, 1, -2, -6, -8, -10, -11, -13, -17, -19, -18, -17, -16, -14, -14, -15, -17, -19, -22, -26, -26, -24, -20, -17, -14, -13, -12, -10, -7, -4, 1, 5, 7, 9, 10, 13, 15, 17, 18, 21, 24, 22, 21, 19, 17, 15, 13, 14, 14, 16, 17, 18, 16, 12, 10, 8, 6, 5, 3, 0, -3, -6, -7, -5, -4, -4, -5, -5, -4, -4, -4, -8, -13, -19, -24, -27, -28, -27, -25, -25, -27, -27, -25, -19, -14, -8, -3, 1, 6, 9, 8, 3, -3, -6, -4, -1, 4, 9, 14, 18, 20, 22, 22, 23, 23, 22, 21, 20, 20, 21, 21, 19, 15, 9, 3, -2, -4, -3, 0, 2, 2, 2, 3, 3, 1, -4, -10, -15, -19, -19, -16, -11, -7, -7, -9, -13, -17, -23, -28, -30, -29, -24, -20, -18, -19, -20, -19, -18, -19, -18, -13, -5, 1, 6, 9, 11, 13, 16, 21, 26, 29, 30, 29, 29, 28, 26, 23, 20, 20, 21, 21, 20, 18, 15, 9, 2, -4, -6, -5, -3, -3, -4, -6, -7, -9, -10, -10, -10, -10, -11, -13, -12, -11, -8, -6, -6, -10, -17, -26, -32, -35, -35, -34, -32, -27, -19, -9, -3, -1, -2, -5, -7, -6, -1, 7, 14, 18, 21, 23, 25, 26, 26, 23, 20, 20, 23, 24, 24, 21, 19, 14, 8, 2, -1, 0, 1, 2, 3, 6, 8, 8, 5, 2, -2, -5, -5, -4, -1, 1, 1, -1, -6, -9, -11, -13, -17, -20, -24, -26, -27, -26, -23, -21, -20, -23, -26, -27, -26, -24, -20, -15, -9, -2, 4, 8, 10, 13, 16, 19, 21, 23, 25, 28, 33, 36, 38, 38, 35, 32, 29, 24, 16, 11, 6, 2, -2, -6, -6, -5, -4, -4, -7, -11, -14, -13, -10, -8, -8, -8, -9, -11, -12, -12, -11, -11, -12, -14, -17, -19, -19, -18, -18, -20, -22, -23, -21, -18, -14, -11, -8, -4, -1, 5, 11, 13, 11, 8, 6, 7, 9, 11, 13, 15, 19, 22, 23, 25, 27, 27, 22, 17, 11, 6, 4, 5, 9, 13, 15, 15, 11, 6, 0, -4, -7, -8, -6, -3, -2, -3, -6, -9, -13, -18, -22, -23, -20, -15, -11, -10, -11, -14, -19, -24, -27, -28, -28, -27, -26, -23, -19, -15, -10, -6, -1, 4, 8, 10, 11, 11, 13, 15, 17, 20, 23, 24, 24, 26, 28, 28, 28, 27, 26, 24, 22, 20, 16, 13, 10, 8, 6, 3, -3, -9, -15, -17, -16, -15, -13, -13, -14, -17, -19, -20, -20, -17, -14, -12, -13, -14, -13, -13, -14, -15, -14, -13, -12, -12, -12, -10, -8, -7, -8, -9, -9, -7, -4, 0, 3, 6, 8, 10, 12, 14, 18, 22, 25, 26, 27, 28, 28, 27, 24, 20, 16, 13, 11, 9, 6, 3, 0, -3, -3, -2, 1, 3, 5, 3, 0, -4, -8, -12, -17, -21, -22, -20, -17, -15, -14, -14, -13, -15, -19, -22, -21, -18, -14, -13, -15, -16, -17, -17, -19, -19, -16, -11, -4, 1, 6, 10, 13, 17, 20, 23, 24, 24, 24, 25, 28, 33, 37, 38, 35, 30, 24, 20, 16, 13, 9, 2, -4, -8, -8, -8, -7, -7, -9, -12, -16, -18, -18, -16, -15, -16, -16, -16, -13, -10, -10, -11, -13, -15, -15, -15, -15, -16, -17, -16, -14, -13, -13, -13, -13, -12, -9, -5, -2, 1, 3, 6, 12, 18, 22, 22, 21, 18, 16, 16, 19, 23, 29, 32, 30, 24, 18, 13, 9, 6, 3, 0, -2, -4, -6, -8, -10, -11, -10, -6, -3, -2, -3, -5, -5, -6, -6, -7, -6, -5, -4, -5, -8, -10, -11, -12, -14, -16, -18, -20, -21, -21, -22, -23, -24, -24, -22, -18, -11, -4, 1, 4, 5, 6, 8, 11, 15, 20, 24, 26, 27, 28, 31, 32, 31, 30, 28, 27, 24, 20, 17, 14, 12, 9, 3, -3, -9, -12, -15, -16, -17, -15, -13, -10, -10, -11, -13, -14, -15, -17, -19, -21, -23, -24, -22, -18, -13, -9, -8, -8, -8, -9, -9, -9, -7, -4, 0, 2, 3, 5, 5, 3, 3, 4, 5, 6, 7, 10, 14, 17, 20, 20, 20, 21, 22, 20, 18, 16, 15, 14, 12, 9, 7, 6, 4, 2, -2, -5, -7, -9, -9, -8, -5, -2, 0, 0, -1, -3, -7, -12, -16, -16, -15, -13, -12, -13, -13, -12, -11, -11, -12, -15, -19, -23, -24, -22, -19, -16, -13, -10, -5, -1, 3, 6, 7, 8, 8, 10, 13, 17, 21, 25, 27, 28, 28, 26, 24, 24, 25, 27, 28, 29, 28, 25, 19, 12, 4, -3, -10, -15, -19, -22, -24, -25, -26, -25, -23, -21, -20, -18, -17, -16, -14, -12, -11, -12, -14, -14, -13, -13, -15, -16, -16, -16, -15, -11, -4, 0, -2, 0, 0, 3, 14, 34, 24, -3, -14, -12, 6, 6, -11, -23, -5, 15, 20, 15, -19, -12, 3, 19, 11, -5, 1, 4, 7, -13, -3, 5, -13, 0, -2, 8, 0, -6, 16, 23, 13, 6, 2, 14, 25, 2, 11, 3, -7, -8, -24, -6, -4, -18, 6, 30, 14, 9, 0, 0, 13, -7, 0, -3, 9, 8, -6, -14, -15, -23, -19, -7, 0, -3, 1, -8, -10, -10, -17, -12, -7, -10, 1, -12, -13, 0, -15, -20, -25, -16, -6, -7, -6, -6, -2, -4, -13, -12, -6, -6, -5, 2, 8, -5, -13, -3, -4, -11, -16, -3, 12, -2, -8, -4, -4, 4, -15, -17, -6, -2, 5, -4, 3, -2, -10, -4, -5, -7, -8, 4, 17, 1, -3, -14, -4, -2, -7, -4, -6, 10, 5, -6, -7, -8, 10, -5, -3, 3, -8, 11, 7, -5, -3, -13, -7, 0, -6, 4, 0, -7, 12, -9, -17, -7, 5, 2, -3, -4, -7, 7, -2, -13, -5, -2, 5, 4, 0, 7, -3, 4, 1, -2, -4, 6, 8, 8, 0, -2, 2, 3, 2, 1, -2, 5, 12, 6, 3, 2, -3, 2, 3, 1, 8, 6, 7, 2, -5, -3, 1, 5, 2, 0, -3, 2, 7, 2, 0, -9, 0, 5, 1, 3, 1, 4, 6, -5, -3, -2, 2, 6, 4, 6, 1, 2, 4, 4, -2, 2, 5, 5, 7, 7, 2, 6, 0, 3, 0, -3, 8, 4, 4, 9, -3, 2, 1, 1, 2, 1, 5, 5, 4, 6, 1, -6, -2, 3, 5, 6, 4, 3, 4, 1, 2, -4, 0, 6, 2, 2, 4, 3, 5, -3, -2, -5, -3, 5, 2, 1, 3, 1, -2, -3, -4, -6, 3, 5, 1, -2, 1, 2, -2, -2, -2, -3, 3, 5, 3, 4, 2, 2, 1, 0, 1, 4, 9, 9, 5, 2, 1, 6, 4, 4, 5, 5, 7, 8, 4, 5, 1, 2, 3, 1, 1, 4, 2, 3, 0, -4, -7, -5, 0, -3, -3, -3, -5, 0, -8, -7, -8, -5, -3, -6, -3, -4, -5, 0, -7, -4, -5, -3, 1, 1, -2, 1, -2, 2, 0, 0, -2, 3, 5, 4, 5, 4, 2, 4, 2, 4, 5, 6, 5, 6, 4, 4, 4, 4, 3, 4, 2, 4, 4, 2, -2, -2, 0, -3, -3, -3, -4, -2, -7, -6, -7, -9, -7, -10, -9, -10, -10, -8, -11, -9, -9, -12, -10, -13, -12, -7, -8, -6, -6, -9, -6, -5, -3, 0, 0, 1, 1, 4, 3, 4, 8, 6, 8, 7, 6, 10, 9, 12, 12, 11, 12, 8, 13, 10, 11, 10, 8, 9, 8, 6, 9, 4, 5, 0, -3, -5, -5, -6, -7, -9, -12, -15, -17, -21, -18, -22, -21, -23, -25, -24, -27, -27, -26, -30, -27, -27, -28, -20, -22, -19, -14, -15, -12, -10, -10, -2, 3, 4, 12, 12, 14, 20, 17, 25, 27, 29, 33, 35, 35, 40, 38, 41, 39, 36, 38, 36, 36, 38, 31, 33, 25, 21, 14, 8, 1, 2, 0, -3, -5, -15, -23, -28, -40, -39, -43, -46, -43, -52, -53, -59, -66, -62, -69, -63, -64, -64, -50, -56, -44, -45, -43, -38, -36, -31, -20, -8, 4, 12, 19, 18, 28, 31, 40, 52, 57, 68, 73, 73, 77, 73, 81, 79, 82, 82, 77, 82, 77, 75, 69, 59, 53, 42, 33, 24, 22, 17, 11, 1, -17, -25, -36, -42, -46, -55, -60, -64, -73, -77, -88, -90, -92, -97, -98, -100, -100, -92, -85, -79, -80, -76, -79, -69, -56, -50, -32, -24, -15, 0, -2, 11, 15, 29, 45, 55, 67, 72, 82, 88, 95, 101, 102, 109, 109, 112, 109, 110, 110, 106, 104, 91, 81, 77, 68, 66, 54, 42, 32, 14, 6, -6, -12, -20, -29, -43, -55, -65, -76, -76, -85, -89, -97, -105, -107, -114, -115, -117, -117, -113, -112, -104, -101, -91, -85, -84, -70, -72, -55, -42, -34, -14, -8, 5, 16, 22, 35, 44, 57, 69, 78, 89, 94, 101, 104, 109, 109, 119, 118, 117, 120, 110, 114, 114, 99, 102, 84, 74, 72, 57, 52, 43, 32, 22, 10, -7, -20, -28, -34, -47, -54, -60, -67, -71, -80, -87, -90, -105, -105, -110, -120, -115, -120, -123, -113, -111, -109, -97, -98, -92, -83, -82, -76, -63, -61, -48, -39, -30, -16, -3, 10, 22, 32, 42, 49, 61, 67, 76, 84, 91, 101, 105, 115, 116, 117, 125, 115, 119, 116, 106, 111, 102, 97, 92, 84, 79, 70, 64, 50, 45, 31, 19, 14, -2, -9, -19, -30, -35, -47, -54, -62, -67, -73, -82, -86, -96, -100, -105, -109, -116, -118, -120, -120, -117, -111, -110, -97, -96, -90, -84, -78, -73, -64, -55, -50, -39, -25, -20, 1, 11, 19, 37, 40, 51, 61, 68, 76, 85, 94, 97, 105, 114, 112, 120, 122, 119, 121, 117, 110, 106, 105, 92, 90, 84, 69, 71, 57, 48, 45, 29, 22, 14, -2, -9, -22, -31, -40, -47, -59, -62, -68, -76, -80, -87, -97, -96, -111, -111, -116, -124, -119, -123, -120, -109, -109, -98, -95, -93, -84, -81, -75, -66, -55, -51, -37, -28, -16, 1, 12, 23, 39, 40, 55, 59, 68, 77, 86, 94, 103, 104, 116, 117, 118, 125, 122, 117, 120, 107, 108, 104, 95, 92, 85, 72, 70, 60, 48, 43, 29, 18, 10, -7, -12, -22, -30, -38, -49, -58, -63, -72, -75, -84, -90, -93, -100, -110, -103, -121, -115, -115, -124, -110, -112, -111, -92, -98, -86, -81, -77, -69, -61, -53, -48, -34, -27, -13, 1, 9, 28, 37, 45, 58, 59, 76, 78, 85, 97, 98, 109, 114, 111, 123, 120, 119, 121, 116, 111, 110, 101, 93, 92, 79, 73, 68, 55, 52, 40, 30, 21, 10, 0, -13, -23, -29, -41, -47, -58, -64, -69, -75, -84, -89, -93, -103, -105, -110, -120, -115, -117, -128, -105, -114, -109, -88, -102, -86, -76, -84, -64, -63, -56, -43, -37, -25, -10, 4, 11, 31, 36, 46, 56, 58, 74, 78, 84, 100, 95, 110, 114, 110, 124, 120, 116, 121, 110, 105, 108, 97, 96, 91, 79, 75, 66, 57, 51, 38, 29, 17, 5, -3, -13, -20, -28, -40, -46, -55, -66, -68, -76, -85, -88, -97, -102, -106, -110, -117, -115, -120, -122, -108, -117, -103, -98, -96, -86, -79, -77, -66, -59, -54, -46, -33, -31, -10, -2, 11, 27, 36, 47, 58, 62, 74, 78, 86, 94, 96, 106, 109, 115, 120, 118, 121, 119, 112, 114, 104, 98, 94, 85, 77, 72, 63, 56, 49, 37, 31, 20, 6, -2, -15, -24, -33, -44, -50, -58, -63, -68, -76, -82, -89, -95, -105, -105, -116, -118, -117, -126, -114, -111, -118, -92, -105, -92, -83, -88, -72, -71, -65, -51, -50, -31, -25, -9, 2, 16, 29, 35, 50, 53, 67, 73, 75, 92, 88, 104, 112, 108, 122, 117, 119, 123, 114, 116, 110, 104, 98, 94, 86, 80, 75, 63, 59, 47, 36, 29, 13, 9, -5, -16, -21, -36, -40, -50, -61, -61, -73, -77, -85, -93, -95, -103, -108, -117, -120, -118, -125, -117, -108, -116, -96, -98, -97, -83, -82, -78, -66, -61, -54, -43, -32, -25, -2, 3, 16, 33, 36, 52, 56, 66, 75, 78, 94, 91, 103, 113, 108, 122, 119, 119, 121, 116, 112, 110, 106, 93, 96, 83, 76, 74, 59, 58, 47, 34, 28, 14, 6, -6, -17, -27, -36, -44, -54, -61, -63, -70, -76, -86, -90, -99, -102, -108, -117, -115, -121, -123, -111, -120, -102, -100, -101, -84, -91, -76, -74, -70, -54, -56, -41, -30, -20, -3, 8, 23, 31, 46, 47, 59, 70, 71, 83, 89, 90, 108, 108, 115, 120, 121, 122, 118, 118, 109, 110, 102, 93, 93, 82, 78, 72, 62, 57, 45, 37, 22, 15, 4, -10, -18, -30, -36, -42, -54, -57, -63, -68, -77, -86, -91, -102, -103, -108, -117, -114, -119, -117, -115, -110, -106, -100, -91, -99, -79, -81, -77, -59, -61, -50, -36, -33, -16, -4, 10, 16, 35, 39, 48, 62, 64, 76, 85, 89, 98, 105, 110, 113, 120, 119, 118, 123, 112, 111, 110, 100, 98, 93, 82, 78, 70, 58, 54, 45, 30, 24, 12, 0, -7, -20, -28, -36, -45, -55, -61, -66, -73, -79, -88, -93, -103, -105, -112, -119, -115, -124, -123, -109, -119, -103, -98, -102, -92, -84, -83, -75, -62, -59, -50, -34, -34, -12, 1, 7, 26, 33, 42, 50, 62, 67, 76, 88, 90, 101, 110, 108, 118, 121, 119, 122, 121, 111, 113, 110, 98, 98, 91, 80, 78, 66, 58, 53, 40, 29, 20, 8, -4, -11, -22, -33, -37, -49, -57, -61, -68, -77, -81, -90, -96, -101, -110, -112, -116, -120, -116, -121, -119, -104, -111, -96, -91, -96, -79, -79, -76, -59, -57, -46, -33, -25, -14, 5, 11, 26, 39, 42, 55, 61, 70, 81, 86, 94, 101, 105, 114, 116, 120, 121, 119, 119, 115, 111, 107, 102, 94, 90, 82, 73, 68, 59, 50, 41, 28, 20, 7, -4, -12, -22, -30, -41, -48, -56, -62, -69, -75, -83, -90, -98, -100, -107, -111, -119, -112, -124, -120, -107, -119, -101, -93, -104, -80, -85, -83, -61, -65, -55, -40, -38, -25, -7, -3, 13, 29, 34, 45, 57, 59, 74, 79, 87, 98, 98, 108, 111, 112, 122, 117, 119, 119, 111, 110, 107, 96, 96, 89, 76, 74, 63, 54, 51, 35, 27, 19, 5, -3, -12, -25, -29, -43, -52, -58, -64, -71, -78, -82, -92, -98, -101, -108, -110, -114, -120, -119, -118, -115, -110, -106, -95, -97, -82, -84, -76, -62, -63, -51, -42, -39, -20, -12, 2, 15, 29, 36, 47, 58, 62, 74, 80, 85, 95, 101, 106, 111, 116, 118, 117, 122, 113, 115, 111, 99, 103, 90, 85, 80, 68, 63, 56, 46, 36, 28, 17, 5, -5, -19, -25, -35, -43, -52, -58, -62, -72, -75, -83, -94, -94, -105, -105, -115, -115, -116, -122, -114, -112, -108, -98, -99, -89, -86, -82, -72, -69, -58, -52, -44, -31, -21, -6, 4, 17, 28, 39, 48, 53, 66, 72, 80, 88, 92, 104, 108, 113, 116, 119, 121, 116, 119, 112, 108, 107, 94, 94, 85, 79, 72, 62, 57, 48, 37, 25, 17, 8, -8, -15, -26, -35, -42, -55, -59, -65, -73, -75, -87, -89, -97, -104, -109, -116, -116, -121, -120, -120, -109, -108, -103, -90, -97, -78, -78, -77, -60, -64, -50, -41, -34, -16, -7, 9, 19, 33, 42, 52, 60, 65, 77, 79, 87, 96, 99, 109, 113, 118, 124, 117, 121, 117, 109, 110, 99, 94, 93, 83, 77, 73, 63, 55, 50, 32, 26, 18, 0, -6, -20, -29, -34, -49, -53, -57, -63, -71, -76, -83, -91, -97, -108, -112, -114, -122, -115, -124, -112, -105, -112, -89, -99, -90, -78, -89, -72, -66, -61, -49, -41, -28, -16, 2, 6, 25, 35, 36, 53, 54, 67, 77, 79, 93, 97, 105, 112, 111, 122, 118, 119, 117, 112, 109, 108, 99, 95, 92, 82, 76, 71, 59, 56, 43, 30, 24, 10, 0, -9, -18, -26, -36, -45, -55, -59, -68, -75, -81, -88, -94, -99, -106, -109, -110, -119, -117, -119, -116, -111, -105, -101, -91, -92, -83, -75, -75, -61, -52, -52, -35, -29, -18, 0, 9, 22, 36, 41, 51, 64, 68, 78, 88, 90, 101, 103, 109, 113, 115, 121, 117, 118, 116, 109, 109, 102, 94, 90, 80, 71, 67, 57, 47, 42, 30, 19, 14, -4, -9, -19, -31, -36, -50, -55, -61, -68, -74, -79, -87, -93, -101, -107, -107, -115, -118, -118, -123, -112, -110, -109, -92, -93, -94, -74, -83, -71, -57, -61, -45, -34, -31, -10, 0, 12, 27, 37, 42, 55, 61, 70, 77, 87, 95, 96, 106, 112, 113, 123, 122, 117, 122, 112, 109, 110, 96, 96, 92, 76, 74, 68, 55, 50, 40, 28, 20, 7, -6, -10, -23, -31, -42, -51, -59, -65, -70, -76, -82, -88, -92, -104, -104, -105, -122, -113, -122, -126, -106, -119, -103, -91, -99, -82, -80, -76, -66, -59, -54, -46, -34, -30, -9, 1, 13, 33, 34, 51, 57, 63, 76, 77, 91, 95, 95, 110, 108, 115, 122, 120, 120, 123, 112, 110, 110, 94, 95, 87, 70, 74, 62, 55, 50, 39, 29, 20, 7, -5, -13, -26, -35, -44, -56, -61, -65, -69, -75, -83, -86, -98, -104, -104, -121, -115, -119, -128, -110, -117, -116, -92, -100, -90, -78, -83, -75, -63, -64, -55, -41, -39, -20, -7, 1, 21, 31, 40, 51, 55, 67, 72, 77, 91, 93, 99, 110, 109, 118, 125, 118, 124, 119, 108, 114, 101, 93, 96, 81, 75, 73, 59, 57, 48, 35, 27, 15, 1, -7, -20, -29, -37, -49, -56, -61, -65, -69, -74, -83, -91, -98, -107, -113, -117, -120, -122, -118, -115, -111, -103, -101, -92, -89, -85, -80, -77, -65, -61, -51, -41, -33, -16, -4, 8, 21, 34, 40, 49, 57, 63, 73, 82, 89, 98, 104, 109, 117, 118, 123, 122, 119, 116, 110, 108, 100, 97, 93, 83, 80, 70, 64, 55, 45, 34, 22, 12, -2, -10, -20, -30, -35, -48, -55, -62, -67, -71, -78, -86, -91, -101, -104, -110, -117, -117, -120, -123, -111, -111, -110, -90, -99, -90, -76, -85, -71, -58, -63, -45, -37, -33, -14, 1, 4, 27, 34, 41, 53, 59, 66, 79, 84, 92, 100, 103, 110, 115, 116, 123, 118, 118, 117, 107, 110, 101, 95, 93, 79, 76, 68, 57, 52, 43, 30, 23, 11, -3, -8, -20, -30, -34, -48, -55, -60, -69, -74, -81, -89, -92, -101, -105, -108, -114, -117, -118, -122, -112, -113, -108, -95, -101, -87, -82, -83, -68, -60, -56, -45, -38, -28, -17, -2, 6, 23, 33, 40, 54, 60, 68, 80, 85, 94, 96, 103, 109, 110, 119, 118, 118, 121, 113, 112, 110, 100, 98, 90, 77, 73, 66, 55, 51, 41, 29, 25, 8, 1, -9, -23, -28, -42, -51, -59, -64, -67, -75, -79, -86, -94, -98, -105, -111, -115, -117, -121, -123, -111, -120, -102, -95, -100, -79, -84, -81, -61, -69, -55, -46, -42, -27, -14, -3, 11, 30, 35, 49, 57, 60, 76, 76, 86, 95, 95, 109, 108, 116, 122, 121, 123, 120, 116, 114, 106, 100, 94, 88, 78, 73, 65, 59, 52, 38, 33, 20, 10, -2, -15, -22, -32, -42, -51, -58, -62, -67, -77, -80, -86, -94, -100, -106, -113, -115, -119, -122, -118, -117, -107, -106, -98, -89, -89, -78, -76, -71, -57, -56, -46, -36, -25, -12, 0, 16, 26, 39, 49, 54, 67, 72, 80, 88, 94, 101, 104, 115, 113, 121, 125, 116, 123, 116, 110, 109, 98, 93, 88, 78, 69, 65, 56, 47, 42, 27, 20, 8, -6, -15, -27, -33, -43, -53, -58, -64, -68, -74, -86, -87, -96, -106, -103, -117, -116, -117, -123, -117, -106, -114, -97, -96, -96, -81, -81, -80, -62, -64, -49, -45, -34, -19, -8, 4, 17, 28, 40, 47, 54, 66, 73, 79, 93, 95, 102, 113, 110, 117, 123, 119, 121, 117, 113, 111, 106, 96, 95, 88, 78, 72, 63, 55, 47, 35, 26, 14, 4, -9, -19, -24, -35, -43, -51, -61, -65, -72, -79, -88, -88, -99, -107, -107, -120, -114, -120, -122, -113, -116, -102, -106, -95, -89, -95, -72, -80, -70, -50, -58, -37, -30, -20, -5, 6, 18, 29, 44, 45, 57, 72, 68, 89, 89, 97, 109, 104, 120, 113, 118, 124, 112, 120, 112, 107, 106, 96, 91, 87, 78, 66, 65, 52, 40, 39, 17, 17, 4, -13, -13, -30, -35, -44, -58, -59, -66, -72, -78, -85, -93, -97, -106, -114, -110, -120, -120, -118, -120, -109, -110, -98, -100, -89, -81, -87, -68, -68, -59, -44, -46, -29, -18, -5, 5, 22, 32, 39, 54, 56, 68, 79, 79, 94, 98, 102, 110, 112, 117, 119, 124, 117, 116, 116, 104, 106, 97, 89, 86, 74, 67, 60, 53, 41, 34, 24, 12, 4, -9, -19, -28, -38, -47, -58, -60, -68, -73, -77, -88, -93, -96, -111, -109, -115, -124, -118, -122, -120, -107, -109, -102, -91, -95, -82, -78, -78, -60, -59, -51, -36, -35, -14, -3, 6, 24, 34, 41, 56, 59, 67, 81, 82, 92, 103, 102, 112, 119, 114, 123, 123, 116, 121, 112, 106, 107, 93, 91, 84, 74, 69, 61, 52, 43, 32, 21, 13, -2, -10, -22, -31, -38, -51, -56, -59, -69, -71, -76, -87, -90, -100, -107, -110, -119, -118, -120, -123, -108, -118, -101, -92, -102, -77, -85, -83, -63, -71, -58, -45, -44, -27, -15, -2, 10, 30, 32, 46, 57, 56, 74, 73, 84, 93, 95, 109, 108, 117, 117, 124, 119, 119, 119, 112, 109, 100, 96, 90, 81, 75, 65, 59, 51, 41, 33, 22, 12, 0, -12, -23, -30, -40, -51, -57, -64, -71, -73, -83, -84, -95, -102, -102, -116, -117, -118, -128, -116, -114, -116, -102, -99, -95, -86, -80, -80, -71, -58, -61, -46, -38, -30, -10, -4, 12, 26, 37, 47, 54, 67, 68, 79, 89, 86, 104, 104, 111, 118, 118, 123, 121, 119, 116, 112, 109, 99, 96, 88, 80, 75, 66, 58, 49, 41, 29, 19, 10, -5, -10, -25, -35, -39, -53, -58, -64, -69, -75, -81, -87, -100, -99, -112, -116, -118, -126, -123, -115, -120, -111, -102, -100, -93, -86, -85, -76, -69, -64, -56, -47, -38, -25, -10, 4, 16, 31, 40, 46, 61, 65, 70, 83, 86, 93, 103, 105, 114, 125, 118, 124, 125, 112, 120, 111, 98, 103, 91, 86, 83, 71, 66, 61, 49, 38, 32, 16, 7, -4, -17, -26, -36, -44, -54, -60, -59, -71, -75, -79, -94, -95, -103, -117, -112, -120, -127, -120, -118, -117, -104, -102, -99, -88, -84, -86, -73, -70, -64, -51, -47, -37, -17, -10, 7, 19, 32, 40, 52, 56, 67, 73, 80, 87, 92, 103, 109, 110, 123, 119, 121, 126, 111, 113, 112, 98, 98, 91, 80, 80, 71, 60, 61, 47, 36, 30, 13, 5, -5, -19, -27, -35, -43, -52, -58, -62, -71, -76, -84, -96, -100, -105, -118, -115, -121, -123, -121, -114, -117, -110, -98, -105, -91, -83, -90, -71, -68, -64, -48, -43, -33, -17, -5, 3, 23, 32, 38, 54, 59, 66, 79, 82, 92, 100, 105, 108, 116, 119, 117, 126, 116, 115, 118, 106, 105, 99, 91, 85, 78, 67, 60, 54, 41, 33, 24, 11, 0, 3, 10, 14, -8, 46, 7, -20, -23, -28, 17, 9, 47, -7, -15, -35, -1, -26, 44, 34, -31, 31, -47, -32, 30, -2, 32, 15, -15, -17, -39, 16, -2, 26, 23, 3, -43, 11, -37, 14, 37, 7, 4, -21, -30, -9, 14, 18, 38, -13, -16, -21, -24, 8, 38, 3, 16, -29, -11, -26, 20, 15, 24, -9, 0, -34, -21, 32, -16, 41, -1, -20, -7, -7, -7, 27, 0, -2, -2, -11, -11, 19, -16, 32, -19, -4, 11, -40, 49, -13, -12, 12, -32, 12, 17, 1, 23, -34, -20, 14, -20, 33, 44, -51, 7, -21, -38, 46, 19, 37, -28, -29, -17, -40, 63, 36, -33, 42, -45, -57, 16, 37, -3, 54, 0, -64, -25, -7, 15, 37, 34, -2, -65, -12, -3, -7, 76, -2, -6, -28, -22, -30, 40, 11, 12, 21, -43, -6, -1, -31, 73, -35, 33, -1, -67, 29, -24, 16, 42, 4, -26, 17, -71, 32, 0, 0, 72, -56, 4, -2, -75, 76, -25, 39, 24, -42, -6, -20, -31, 56, 1, 3, 49, -63, -12, -16, -10, 49, 12, 29, -32, -59, 35, -39, 35, 45, -33, -21, 46, -68, 13, 16, 12, 0, 2, 32, -70, 12, 30, -62, 64, 5, -31, 22, -30, 11, -30, 43, 2, -8, 16, -3, -60, 39, -11, -13, 63, -32, 8, -6, -45, 39, -38, 30, 49, -89, 96, -84, 0, 43, -51, 52, -4, -6, 7, -31, -10, 12, -22, 62, 8, -57, 65, -101, 1, 69, -46, 76, -18, -34, -24, -33, 50, -6, 55, 16, -70, -19, 2, -33, 59, 61, -40, 7, -44, -33, -7, 61, 31, -15, 5, -32, -70, 47, 34, 8, 22, -16, -44, -47, 56, -6, 12, 56, -46, -32, -3, 7, -4, 42, 19, -41, -35, 41, -59, 43, 45, -44, 9, -9, -7, -19, 36, 2, -50, 49, -6, -34, 33, -1, -38, 17, 44, -33, 5, 28, -68, -13, 62, -25, 15, 45, -57, -32, 23, -14, 37, 11, 29, -56, -48, 46, -55, 48, 94, -74, 22, -40, -59, 36, 9, 75, -19, -31, 6, -104, 39, 80, -23, 59, -12, -104, 10, -12, 24, 59, 5, 9, -78, -12, 24, -47, 116, -6, -51, 34, -71, -26, 55, 3, 11, 38, -31, -9, -45, 21, -11, 4, 92, -79, 16, -16, -41, 29, 27, 19, -5, -19, -13, -35, 29, 22, -7, 20, -35, 6, -21, 30, -2, 6, -8, -20, -12, 30, -13, 8, 23, -52, 21, 8, -16, 40, -20, -7, -15, -38, 62, -33, 48, 5, -66, 28, -25, 15, 39, 5, -46, 8, -46, 32, 12, 37, -9, -49, 43, -78, 43, 46, -43, 39, -41, -36, 13, 19, 48, -21, 9, -37, -54, 45, 32, -14, 41, -32, -66, 42, -8, 37, 12, -10, -12, -74, 71, -30, 16, 65, -64, -1, -13, -12, 17, 24, 10, -16, -31, -1, -3, 1, 68, -47, -7, -8, -41, 74, -16, 32, -27, -42, 22, -49, 80, -11, 0, 23, -84, 34, -24, 31, 48, -37, 23, -55, -25, 22, 14, 22, 59, -78, -11, -1, -45, 90, -35, 32, 0, -75, 63, -65, 34, 52, -71, 70, -56, -14, 30, -22, 10, 55, -74, 41, -19, -47, 88, -62, 50, -11, -57, 44, -54, 59, 17, -23, 12, -40, -41, 60, 3, 15, 28, -71, -1, -17, 11, 61, -28, 47, -59, -48, 35, -18, 51, 27, -20, -35, -36, 14, 6, 44, 23, -30, -33, -17, -1, 14, 49, -2, -32, -12, -20, 5, 29, 34, -33, 9, -34, -26, 36, -2, 40, -28, 5, -26, -39, 65, -27, 19, 31, -54, 0, -8, 12, 2, 30, -5, -25, -22, 24, -29, 26, 52, -57, 7, 5, -56, 46, 1, 8, 4, -5, 1, -51, 28, 14, -21, 48, -17, -46, 4, 11, -6, 35, 7, -16, -31, -10, 25, -49, 95, -28, -29, 19, -46, -5, 32, 21, 8, -1, -24, -36, -17, 59, -7, 33, 10, -76, -14, 19, -1, 56, 16, -23, -64, -8, 7, 8, 85, 0, -57, -21, -35, -7, 72, 23, 28, -66, -16, -47, 2, 68, 24, 5, 0, -69, -26, 22, -7, 72, 0, -12, -20, -51, 15, -11, 44, 44, -46, 36, -59, -38, 32, 19, -3, 71, -45, -28, -29, -17, 36, 8, 79, -47, -53, 18, -65, 38, 75, -24, 20, -36, -34, -26, 38, 39, -7, -3, 7, -85, 44, 26, -17, 42, -20, -29, -26, 26, 18, -8, 36, -17, -73, 40, 4, -1, 52, -16, -47, -15, 14, 4, 29, 30, -41, -44, 15, -2, 16, 60, -26, -54, 17, -33, 22, 48, -5, -15, -20, -13, -15, 31, 37, -28, 6, -17, -22, -10, 64, -43, 16, 22, -71, 41, 3, -1, 6, -12, 12, -38, 11, 38, -49, 37, 24, -64, 27, 18, -73, 81, -33, 14, -3, -32, 43, -60, 53, 24, -76, 70, -29, -33, 50, -18, -34, 48, -38, 37, -15, -5, 25, -80, 70, -4, -45, 89, -72, -3, 13, -23, 28, 21, -9, -9, -25, -11, 24, -26, 62, -14, -49, 67, -97, 57, 12, -23, 46, -46, 9, -20, -4, 25, -1, 5, 18, -31, -25, 38, -43, 44, 17, -42, 37, -66, 37, -16, 26, 18, -16, -17, -4, -17, 7, 38, -11, 4, -3, -51, 32, -17, 38, 18, -34, 23, -58, 4, 25, 0, 26, 3, -35, -11, -10, 16, 24, 8, 4, -33, -30, 22, -2, 14, 52, -61, 10, -23, -4, 20, 10, 32, -44, -2, 1, -36, 37, 32, -25, 2, 0, -40, 14, 24, -5, 13, -28, 20, -51, 41, 15, -23, 25, -12, -41, 30, -2, -11, 40, -34, 14, -24, 3, 22, -31, 44, -22, -31, 57, -55, 28, 0, -9, 1, 11, -10, 8, -13, 3, -2, -23, 60, -49, 23, 10, -59, 36, -3, -3, 35, -23, 5, -42, 15, 7, -2, 35, 0, -45, 8, -4, -27, 63, -4, -14, 9, -39, 1, 1, 27, 19, -27, 24, -49, -6, 34, -5, 10, 19, -32, -20, 14, -12, 16, 26, -9, -19, -9, -8, 8, 7, 40, -29, -14, -4, -25, 7, 56, -15, 6, -20, -36, 3, 10, 33, 20, -23, -5, -42, -18, 54, -17, 63, -5, -59, 2, -44, 12, 57, 17, 15, -33, -44, -16, -17, 65, 40, -9, 10, -72, -51, 39, 10, 65, 19, -25, -47, -51, 17, 20, 53, 30, -35, -35, -34, -16, 36, 48, 12, -3, -35, -42, -9, 28, 34, 12, 15, -42, -39, 7, 8, 24, 28, 1, -31, -36, 9, -1, 28, 29, -14, -34, 14, -43, 23, 34, -7, 24, -44, 10, -28, -5, 53, -29, 29, -7, -33, 2, -1, 5, 19, 10, -17, 2, -33, 14, 1, 8, 32, -36, 17, -28, -18, 36, -22, 29, 2, -25, 5, -17, 13, 1, 16, -1, -10, -12, 3, -9, 10, 19, -22, 16, -3, -20, 24, -22, 15, -3, -14, 22, -30, 31, -14, -11, 12, -11, 8, 17, -9, -4, -13, -13, 7, 10, 19, -6, -7, -2, -32, 24, 8, 0, 17, -20, -10, -15, 13, 10, 11, 4, -1, -40, 19, -4, -6, 42, -31, -1, -5, -12, 19, 6, 7, -5, -26, 10, -12, 15, 20, -8, -19, 12, -40, 31, 15, -3, 16, -23, -27, 7, -5, 31, 6, 3, -6, -41, 14, -2, 7, 38, -10, -29, 11, -44, 17, 29, 6, 20, -26, 1, -45, 9, 31, -18, 40, -1, -47, 8, -10, -4, 29, 33, -25, 1, -31, -12, -9, 35, 30, -25, 31, -48, -28, 20, 17, 9, 30, -19, -39, -13, 6, 8, 38, 15, -10, -42, 0, -24, 15, 49, -9, -12, 5, -44, -5, 42, 4, 6, 8, -27, -29, 5, 24, -2, 10, 28, -56, 1, 23, -29, 29, 15, -19, -11, 1, -4, -8, 24, 6, -15, 2, 7, -27, 12, 21, -40, 36, -15, -12, 22, -16, 17, -17, 15, -6, -18, 23, -3, -26, 39, -27, -5, 26, -20, 8, 5, -11, 7, -21, 19, -11, -8, 35, -25, 2, 18, -35, 9, 16, -21, 29, -16, 1, -13, -13, 28, -18, 23, 13, -36, 6, -1, -23, 26, 12, -15, 17, -20, -2, -7, 3, 22, -22, 27, -11, -34, 36, -30, 11, 17, 2, -12, 13, -22, -11, 11, -5, 26, -17, 26, -25, -32, 44, -47, 39, 25, -31, 16, -35, -1, -4, 26, 16, 3, -16, -10, -23, -8, 55, -27, 26, 0, -63, 41, -26, 28, 22, -23, 14, -42, 5, 20, -13, 28, 3, -42, 20, -6, -17, 52, -32, 6, -2, -37, 42, -27, 29, 15, -51, 40, -38, 2, 33, -19, 6, 11, -43, 25, 0, -19, 57, -54, 31, -9, -43, 58, -52, 36, 11, -44, 50, -44, 8, 23, -24, 12, 6, -34, 25, -9, -15, 50, -55, 35, -7, -25, 49, -48, 32, -23, -18, 37, -30, 28, 8, -27, 7, -2, -19, 22, 10, -11, 10, -27, 4, -16, 18, 29, -19, 20, -22, -36, 16, -2, 18, 14, 3, -24, -15, -5, 12, 13, 20, 4, -40, 2, -23, 8, 29, 7, 9, -23, -10, -13, 5, 19, 9, -3, -14, -7, -19, 21, 6, 5, 10, -20, 0, -14, 12, 0, 2, 5, -13, 1, -3, 12, -12, 20, -13, -7, 6, -11, 5, 0, 5, -5, -4, 10, -10, 2, 6, -5, -12, 18, -13, -9, 19, -17, 11, -1, 8, -5, -22, 26, -26, 1, 29, -17, -7, 16, -22, -8, 23, -3, 4, -3, -2, -15, -20, 42, -21, 4, 40, -55, 8, 8, -22, 21, 20, -17, 2, -14, -7, -2, 10, 31, -25, 10, -3, -54, 40, 5, -12, 42, -17, -37, 13, -12, 7, 24, 10, -6, -36, 12, -9, -25, 74, -24, -19, 38, -64, 5, 25, 0, 16, 1, -9, -25, -23, 36, -8, 6, 50, -58, -12, 22, -53, 52, 18, -12, 16, -51, 15, -30, 25, 46, -37, 31, -26, -49, 30, 9, -1, 42, -19, -28, -13, -5, 16, 4, 42, -18, -40, 20, -30, 1, 49, -4, -15, 0, -21, -19, 21, 26, 0, -9, 9, -43, -1, 26, -5, 21, -7, -6, -32, 9, 12, -3, 34, -17, -12, -17, -4, 9, 7, 28, -19, -3, -13, -11, 7, 15, 15, -19, 15, -38, -5, 17, -1, 29, -20, 15, -39, -11, 41, -33, 45, -8, -21, -11, -3, 7, 0, 28, -7, -19, -8, 7, -20, 23, 24, -40, 24, -17, -16, 26, -9, 21, -27, 13, -11, -22, 29, -7, 0, 22, -22, -16, 14, -12, 12, 11, -5, -6, -17, 14, -15, 9, 30, -28, 5, 1, -26, 8, 18, -7, 1, 6, -12, -15, 9, 13, -13, 13, 13, -42, 14, 3, -16, 20, 7, -3, -22, 25, -26, 4, 16, -7, 3, -8, 17, -33, 14, 9, -21, 25, -3, -11, -1, 1, -13, 1, 23, -20, 26, -18, 0, -18, 3, 24, -25, 36, -15, -29, 22, -22, 3, 24, -5, -1, 0, -18, 2, -11, 20, 10, -17, 30, -37, -15, 29, -33, 39, 11, -23, 7, -34, 8, 0, 11, 36, -27, -12, 9, -47, 29, 31, -29, 40, -37, -14, 3, -17, 45, -11, 8, 12, -60, 20, -2, -2, 41, -12, -18, 3, -37, 27, 12, -4, 37, -56, 17, -21, -5, 44, -20, 14, -2, -40, 20, 0, 3, 22, -13, -10, -6, -16, 29, -12, 14, 15, -49, 24, -11, -7, 39, -18, 3, -20, -12, 19, -10, 32, 2, -34, 10, -13, -13, 37, 1, -7, 3, -33, 4, 2, 18, 25, -25, 8, -33, -13, 34, -7, 24, 4, -33, -10, -2, 2, 25, 12, -1, -25, -12, 3, -18, 34, 12, -15, 4, -9, -25, 10, 17, -3, 9, 2, -13, -23, 9, 8, -13, 37, -10, -15, 1, -13, -1, 0, 31, -15, 0, 5, -29, 6, 5, 15, -9, 16, -9, -29, 15, -10, 3, 15, 9, -11, -12, 11, -29, 17, 14, -7, 6, -6, -7, -24, 30, -11, 9, 18, -20, -8, -6, 6, -10, 22, 10, -29, 14, -13, -8, 13, 17, -13, 2, 1, -24, 5, 5, 12, -10, 15, -7, -28, 21, -2, -8, 22, -9, -14, -2, 6, -5, 5, 12, -7, -15, 14, -4, -16, 27, -10, -14, 13, -5, -9, 10, 5, -8, -5, 16, -20, 2, 13, -14, -3, 17, -18, 2, 10, -12, 9, -6, -2, -16, 13, 10, -15, 33, -24, -17, 10, -4, 15, 1, 9, -23, -9, 6, -5, 5, 21, -10, -13, 11, -21, -2, 19, -10, 23, -20, 10, -16, -21, 33, -17, 17, 18, -30, 1, -14, -1, 20, -2, 18, -15, -24, 6, -5, 6, 36, -26, 6, -18, -23, 34, -12, 25, 1, -30, -1, -11, 10, 22, -1, 4, -19, -28, 21, -11, 22, 25, -33, 4, -21, -7, 22, 7, 19, -23, -13, -3, -13, 21, 17, -11, 7, -19, -12, 12, -10, 30, -13, -5, 4, -30, 27, -9, 17, -3, -25, 13, -23, 13, 27, -15, -5, 3, -35, 17, 19, -8, 29, -37, 1, -15, -10, 48, -20, 26, -7, -49, 22, -23, 21, 33, -10, -8, -17, -34, 11, 19, 12, 40, -39, -14, -13, -36, 64, -4, 20, 9, -55, 3, -24, 21, 31, 10, -1, -22, -30, -7, 12, 18, 29, -10, -7, -28, -22, 22, 3, 26, 4, -13, -18, -16, 21, -9, 28, -1, -21, 0, -12, 5, 6, 5, 10, -20, 1, 3, -20, 21, 7, -23, 24, -25, -6, 21, -13, 25, -19, -8, 2, -14, 20, 13, -23, 25, -31, -7, 24, -16, 20, 6, -25, 8, -24, 12, 15, -10, 24, -25, -2, 0, -12, 14, 10, -13, 4, 1, -17, 9, 6, -9, 9, 0, -3, -8, 11, -10, -2, 7, -1, -6, 6, 1, -12, 1, 18, -31, 23, -2, -21, 21, -6, -8, 15, -14, 4, -6, -1, 17, -22, 20, -6, -35, 37, -17, -6, 47, -41, 6, -6, -16, 12, 16, 6, 1, -36, 18, -26, 4, 59, -36, -1, 16, -64, 30, 14, 1, 16, -13, 0, -35, 17, 13, -8, 12, 14, -45, 11, 12, -24, 27, 12, -27, 10, -6, -9, 1, 14, -7, -6, 8, -4, -8, 8, 8, -24, 13, 7, -27, 28, -1, -28, 27, -19, -2, 17, -5, 6, -10, -5, 4, -25, 32, 2, -22, 32, -28, -20, 35, -20, 16, 7, -18, 1, -22, 20, 0, 2, 20, -15, -25, 24, -25, 12, 25, -23, 10, -19, -5, 8, 2, 20, -6, -13, 0, -22, 12, 15, -3, 13, -13, -25, 12, -6, 18, 13, -3, -14, -22, 3, -2, 14, 25, -10, -16, -5, -13, 2, 22, 9, -2, -11, -12, -20, 15, 20, 1, 14, -19, -17, -9, 1, 19, 5, 0, 4, -35, 17, -7, 5, 20, -16, 2, -8, -11, 11, -2, 2, 7, -19, 15, -10, 2, 12, -14, -3, 2, -9, 17, -3, 2, -7, -16, 10, 2, 9, 10, -14, -9, -6, -11, 21, 5, 4, 6, -24, -5, -4, 6, 18, 0, 8, -21, -18, 8, -8, 21, 16, -11, -9, -12, -15, 15, 3, 27, -9, -16, 5, -30, 13, 23, -11, 21, -19, -15, -3, -9, 30, -9, 14, -6, -22, -5, 15, -11, 23, -1, -14, -4, -9, 8, 4, 1, 20, -34, 9, 1, -17, 24, -6, 1, -9, 1, -4, 3, 6, 8, -16, 0, 2, -13, 11, 21, -31, 24, -21, -4, 13, -2, 7, -9, -3, 0, -18, 29, -4, -9, 16, -19, -13, 25, -5, -1, 15, -24, 4, -15, 22, 4, -11, 20, -21, -25, 39, -23, 14, 14, -23, 1, -8, 3, 12, -9, 23, -19, -18, 24, -22, 5, 30, -32, 11, 2, -21, 18, -6, 5, 1, -9, 13, -22, 4, 19, -28, 26, 3, -28, 21, -4, -25, 32, -15, 5, 0, -2, -4, -9, 15, 0, -13, 21, -14, -20, 31, -19, 2, 17, -14, -9, 12, -6, 4, -1, 4, -17, -1, 12, -2, 0, 20, -31, -8, 12, -8, 17, 14, -13, -16, -9, -7, 20, 11, 18, -13, -28, -3, -12, 13, 40, -12, 4, -20, -32, 8, 17, 14, 21, -10, -28, -18, -2, 11, 22, 17, 0, -34, -6, -3, -17, 50, 1, -13, 4, -22, -21, 17, 16, 4, 7, 0, -27, -11, 4, 10, 2, 24, -6, -28, 7, -12, -2, 33, -3, -6, 2, -37, 3, 9, 7, 24, -4, -14, -6, -24, 25, -1, 11, 16, -36, -9, 12, -25, 45, 5, -20, 11, -36, 11, 7, 0, 30, -32, -1, 7, -33, 37, 0, -9, 15, -21, -10, 12, -15, 24, -8, 3, 4, -20, 7, 3, -15, 28, -14, -7, 13, -23, 2, 11, 0, 4, 7, -9, -16, 1, 7, -7, 19, -3, -12, -14, 15, -10, 7, 30, -26, -13, 15, -30, 15, 26, -12, -1, -8, -9, -5, 13, 22, -12, -12, 7, -36, 17, 31, -24, 27, -21, -24, 15, -10, 26, 4, -12, 4, -36, 13, 14, -5, 27, -14, -22, 7, -12, 6, 23, -13, 7, -19, -2, 7, -8, 25, -5, -17, 18, -25, 3, 14, -8, 4, 0, -1, -11, 4, 12, -18, 15, 2, -23, 12, -2, -7, 12, 1, -1, -15, 11, -3, -17, 41, -24, -7, 13, -25, 3, 22, -9, 15, -12, -9, 0, -17, 32, -5, -5, 19, -49, 19, 3, -11, 45, -30, 2, -4, -28, 29, 0, 7, 12, -34, 6, -10, 1, 33, -9, -6, 4, -41, 25, 2, 4, 29, -40, 8, -17, -9, 42, -16, 16, -10, -33, 11, -7, 22, 12, -6, -6, -25, -4, 18, -3, 25, -4, -29, 5, -17, 8, 22, 1, 4, -22, 1, -13, 2, 31, -19, 9, 2, -36, 17, 5, -7, 20, -11, -2, -13, 4, 9, -18, 24, -3, -30, 33, -19, -11, 31, -21, 6, 0, -5, 3, -10, 17, -7, -19, 30, -24, 0, 26, -23, 3, 7, -17, 9, -3, 9, -1, -17, 23, -25, -3, 34, -27, 10, 15, -34, 9, 1, 1, 7, -1, 12, -31, 4, 16, -27, 32, 10, -33, 10, -1, -27, 29, 9, -9, 0, -1, -16, -6, 24, 2, -17, 23, -20, -24, 33, -11, -2, 17, -7, -21, 13, 1, -7, 10, 1, -12, -9, 13, -1, -5, 20, -16, -15, 15, -8, 5, 13, -10, -7, -9, 5, 2, 10, 7, -7, -22, 12, -13, 6, 26, -14, -6, 0, -17, 3, 16, 6, 0, -11, 3, -26, 13, 15, -6, 7, 4, -29, 6, 7, -3, 13, 1, -11, -9, 2, -1, 3, 9, -3, -8, 1, -4, 0, 5, 0, 0, -2, 0, -1, 0, 0, -2, 11, 23, 22, 24, 25, 20, 21, 15, 40, -1, -24, -42, -5, -19, -11, -8, 4, -46, -31, -14, -33, -40, -44, -48, -89, -63, -47, -33, -27, -10, -6, 22, 25, 26, 28, 37, 11, 15, 51, 44, 54, 66, 66, 71, 111, 84, 70, 63, 47, 39, 22, 47, -28, -79, -111, -90, -91, -112, -81, -87, -49, -46, -5, -24, 26, 24, 47, 29, 23, 30, 30, 13, -1, 4, -14, 17, 35, 62, 31, 53, 59, 72, 64, 27, 26, 9, 9, -61, -44, -88, -74, -81, -83, -124, -96, -37, -78, -48, -56, -68, -60, 7, 44, 39, 54, 77, 102, 110, 108, 89, 101, 100, 105, 64, 22, -1, 44, 40, -19, -29, -35, -16, -27, -40, -77, -82, -113, -104, -93, -57, -72, -56, -3, 1, 7, -1, 49, 39, 30, 31, 23, 10, 31, 11, 7, -19, -2, -2, 28, 62, 92, 75, 33, 34, -20, -47, -61, -85, -105, -93, -119, -112, -54, -70, -67, -32, -1, 4, 4, 20, 29, 62, 70, 54, 62, 78, 115, 92, 85, 78, 52, 21, 19, 27, 2, -8, 13, 0, 5, 3, 9, 18, 0, -59, -61, -45, -57, -65, -76, -89, -102, -48, -24, 17, 6, 26, 33, 35, 26, 41, 63, 20, 12, 29, 34, 8, 7, 31, 21, 31, 39, 33, -5, -8, -55, -57, -98, -94, -88, -64, -82, -74, -39, -14, 3, 16, 22, 8, 2, 17, 5, 36, 76, 74, 71, 57, 73, 62, 47, 30, 32, 19, 4, 7, -14, -18, -2, 17, -5, 13, 22, 31, 10, 8, -13, -47, -80, -85, -86, -71, -73, -60, -35, -10, 9, 19, 49, 53, 47, 60, 73, 43, 33, 20, 13, -1, -7, -7, 7, 9, -2, 5, -14, -40, -69, -61, -66, -67, -84, -58, -58, -33, 2, -7, -5, 12, 32, 18, 25, 19, 24, 65, 59, 62, 64, 63, 55, 60, 52, 31, 19, -12, -26, -4, -7, -10, -3, 6, -22, -14, 12, 19, 4, -26, -38, -40, -56, -61, -66, -59, -65, -51, -20, 29, 40, 51, 52, 62, 61, 53, 26, 20, 6, 8, 6, 9, -14, -14, -15, -2, -11, -23, -36, -38, -60, -77, -69, -60, -51, -56, -44, -27, 10, -2, 14, 10, 22, 16, 41, 60, 39, 35, 60, 62, 43, 45, 63, 52, 17, 12, 15, -1, -2, 0, -38, -48, -32, -22, -7, 3, 13, 10, -2, -1, -8, -12, -25, -48, -46, -52, -49, -36, -17, 9, 17, 26, 48, 57, 55, 69, 60, 32, 6, 4, -6, -20, -24, -9, -21, -25, -14, -18, -38, -38, -32, -51, -52, -60, -34, -6, -6, -16, -11, -2, -1, 17, 19, 3, 11, 25, 31, 41, 39, 33, 33, 41, 34, 34, 23, 21, 15, 6, -13, -24, -28, -20, -8, -12, -19, -12, -5, 9, 14, 2, -12, -25, -28, -21, -28, -23, -22, -18, -26, -5, 24, 45, 46, 47, 39, 33, 36, 42, 29, 7, -5, -10, -21, -29, -39, -39, -31, -24, -29, -39, -51, -43, -27, -22, -18, -25, -26, -20, 9, 19, 18, 4, -2, 19, 30, 38, 25, 24, 28, 33, 41, 38, 34, 32, 38, 24, 8, 4, -8, -11, -15, -25, -31, -25, -20, -22, -15, -11, -9, -12, -17, -20, -20, -15, -6, -11, -8, 0, 11, 29, 19, 17, 17, 18, 28, 31, 25, 18, 23, 18, 10, 1, -7, -18, -26, -24, -30, -41, -38, -44, -32, -31, -31, -35, -25, -12, -2, -8, -11, -13, -13, -2, 8, 15, 19, 29, 35, 37, 39, 43, 42, 40, 35, 27, 25, 18, 15, 9, 4, -4, -15, -28, -28, -26, -28, -18, -15, -25, -23, -12, -11, -14, -10, -2, -4, -1, 8, 15, 19, 22, 25, 16, 16, 17, 5, 7, 13, 18, 13, 9, 6, 6, 4, -4, -21, -31, -28, -37, -39, -34, -38, -38, -32, -17, -6, -4, -14, -19, -9, 3, -2, 3, 4, 7, 8, 13, 23, 35, 38, 43, 42, 31, 25, 23, 17, 8, 3, 4, -7, -7, -10, -13, -20, -19, -28, -33, -30, -23, -18, -13, -17, -12, 3, 14, 23, 31, 27, 23, 21, 22, 19, 12, 4, 2, 2, -2, 0, 4, 11, 11, 6, 4, -2, -5, -14, -17, -30, -38, -44, -42, -28, -21, -23, -21, -15, -15, -4, 8, 11, 4, -7, -15, -7, 5, 10, 21, 26, 28, 27, 34, 37, 36, 28, 19, 10, 11, 8, -2, -18, -17, -19, -19, -22, -24, -21, -24, -18, -17, -13, -19, -13, -1, 12, 19, 22, 21, 19, 19, 30, 34, 24, 13, 7, 2, 1, 1, 2, -1, -2, -6, 0, 0, -2, -15, -21, -17, -21, -28, -32, -31, -31, -32, -27, -24, -17, -4, 1, -3, -1, 1, 4, 7, 8, 15, 16, 15, 15, 20, 32, 36, 38, 32, 19, 12, 3, 2, -2, -4, -11, -19, -17, -15, -11, -16, -20, -27, -30, -28, -22, -13, -6, -2, 2, 12, 23, 29, 45, 44, 36, 32, 21, 16, 14, 10, 1, -9, -8, -2, -1, -7, -13, -13, -12, -9, -11, -18, -24, -26, -28, -30, -24, -21, -21, -21, -11, -11, -10, 0, -2, 0, 4, 12, 13, 14, 12, 17, 22, 28, 30, 28, 20, 16, 13, 8, 2, -2, -6, -15, -14, -18, -15, -15, -16, -18, -18, -16, -19, -18, -17, -10, 0, -1, 4, 13, 22, 37, 39, 36, 27, 27, 32, 26, 15, 6, -1, -4, -5, -7, -11, -11, -9, -15, -15, -14, -18, -21, -19, -17, -21, -19, -15, -15, -10, -15, -14, -12, -11, -6, -2, 1, -2, 1, 5, 14, 22, 33, 35, 23, 18, 16, 13, 11, 6, 1, -9, -18, -11, -6, -7, -8, -9, -11, -11, -12, -13, -17, -21, -24, -24, -15, -4, 7, 12, 17, 25, 30, 28, 31, 32, 31, 27, 22, 15, 12, 3, -2, -8, -6, -3, -9, -13, -22, -24, -20, -18, -22, -24, -18, -14, -13, -10, -11, -9, -3, -2, -3, -5, -10, -10, -5, -1, 4, 11, 15, 19, 22, 27, 23, 20, 16, 14, 5, -3, -11, -15, -16, -12, -12, -11, -5, 1, -3, -10, -13, -15, -11, -10, -10, -11, -8, -3, 2, 7, 9, 15, 25, 30, 33, 31, 25, 21, 20, 16, 13, 7, -2, -8, -5, -4, -11, -20, -21, -22, -21, -17, -20, -21, -22, -19, -19, -11, -4, -2, -2, -2, 2, 5, 2, 0, 0, -3, 1, 8, 16, 13, 14, 17, 15, 13, 8, 5, -1, -6, -10, -13, -14, -14, -13, -10, -7, -8, -8, -6, -6, -3, -1, -1, -9, -12, -7, 3, 13, 17, 14, 13, 17, 22, 23, 24, 18, 15, 18, 18, 18, 15, 8, 0, -5, -8, -11, -15, -17, -21, -26, -26, -24, -26, -24, -13, -9, -6, -3, -2, 3, 4, 6, 7, 5, 2, 4, 2, -2, -4, -3, 5, 13, 17, 10, 3, -1, -2, -4, -5, -11, -14, -13, -11, -8, -8, -8, -6, -3, 0, -1, -5, -5, 0, 4, 3, 1, 2, 0, 0, 6, 13, 20, 17, 17, 18, 21, 18, 14, 13, 11, 11, 7, 9, 3, -5, -12, -14, -18, -21, -23, -26, -26, -13, -3, -6, -13, -14, -5, 5, 8, 3, 0, 1, 3, 6, 4, -1, -1, 1, 3, 7, 5, 3, 0, 1, -1, 3, 0, -3, -11, -11, -9, -10, -9, -8, -5, -7, -7, -10, -9, -6, -1, 4, 6, 4, 2, 5, 10, 13, 9, 12, 13, 14, 15, 16, 13, 12, 10, 13, 14, 13, 8, 2, -1, -4, -6, -9, -15, -20, -21, -19, -14, -16, -22, -21, -13, -5, -3, -3, -1, 3, 5, 10, 9, 9, 6, 8, 7, 7, 7, 3, -4, -6, -4, -1, -4, -8, -10, -11, -8, -4, -6, -10, -7, -8, -11, -11, -8, -5, -4, 0, 3, 3, 8, 10, 10, 12, 12, 11, 10, 13, 12, 10, 6, 8, 9, 9, 11, 13, 11, 9, 10, 7, 2, -3, -8, -9, -14, -16, -16, -19, -18, -14, -13, -11, -11, -10, -5, -1, 3, 5, 2, 2, 9, 14, 11, 9, 10, 7, 2, 0, 2, -2, -9, -13, -15, -18, -17, -15, -13, -10, -5, -5, -7, -7, -4, -1, 0, -2, -4, -2, 1, 4, 9, 10, 10, 11, 11, 13, 14, 10, 11, 9, 9, 4, 6, 5, 4, 5, 7, 8, 10, 9, 4, -4, -8, -9, -10, -11, -12, -14, -15, -17, -15, -9, -4, -1, -6, -5, 2, 8, 8, 6, 5, 3, 4, 5, 9, 10, 10, 5, -1, -5, -10, -12, -14, -16, -18, -17, -11, -10, -11, -8, -5, -2, -2, 0, 3, 4, 5, 3, 2, 3, 5, 9, 12, 12, 11, 10, 12, 14, 12, 8, 5, 0, -1, 1, 3, 0, 1, 3, 5, 6, 5, 0, -5, -11, -10, -13, -12, -13, -15, -14, -8, -4, -3, -3, -4, 0, 4, 5, 3, 6, 4, 4, 7, 10, 9, 9, 8, 5, 5, 2, -4, -10, -15, -17, -20, -22, -22, -19, -14, -11, -10, -8, -6, 0, 3, 5, 3, 4, 8, 11, 11, 12, 13, 12, 12, 15, 15, 16, 16, 13, 11, 6, 3, -2, -5, -5, -3, -2, -1, 2, 0, -3, -4, -5, -7, -10, -12, -11, -12, -11, -8, -4, -2, 0, 1, 2, 2, 2, 4, 3, 3, 4, 5, 9, 10, 6, 2, 1, 2, 0, -3, -7, -13, -18, -19, -18, -16, -18, -20, -19, -14, -8, -4, -1, 3, 3, 5, 7, 9, 9, 10, 12, 13, 13, 13, 13, 16, 15, 13, 9, 6, 3, 2, 1, 0, -3, -5, -6, -4, -2, -2, -4, -4, -5, -5, -3, -3, -4, -6, -6, -7, -4, 0, 2, 3, 2, 2, 1, 2, 2, 1, 4, 5, 4, 1, 0, 2, 2, 0, -2, -6, -8, -6, -7, -9, -11, -15, -18, -19, -18, -18, -17, -13, -9, -2, 2, 3, 5, 10, 12, 13, 14, 14, 15, 17, 17, 16, 16, 15, 13, 11, 7, 2, -6, -10, -8, -6, -8, -8, -7, -6, -6, -3, -4, -6, -5, -3, -2, -2, 0, 1, 0, 2, 2, 3, 2, 3, 2, 3, 3, 5, 2, 0, 4, 6, 5, -1, -4, -2, -1, -2, -6, -8, -9, -10, -12, -10, -14, -17, -22, -22, -21, -19, -15, -8, -3, 1, 7, 12, 12, 15, 19, 22, 21, 18, 16, 16, 16, 13, 12, 6, 3, 3, 2, -3, -6, -7, -12, -12, -11, -8, -9, -8, -7, -3, 0, 0, 0, 0, -2, -2, 0, 1, 2, 2, 4, 6, 6, 7, 5, 4, 3, 4, 5, 3, 0, -2, -2, -4, -6, -10, -8, -8, -10, -11, -12, -12, -12, -13, -16, -16, -16, -14, -11, -8, -4, -2, 1, 6, 12, 17, 19, 20, 20, 21, 21, 19, 13, 10, 9, 5, 0, -3, -4, -4, -5, -6, -6, -4, -7, -10, -12, -12, -12, -10, -7, -4, -2, 4, 6, 8, 7, 7, 7, 7, 8, 8, 7, 5, 6, 6, 4, 1, -1, -1, 0, -3, -7, -10, -10, -8, -11, -14, -14, -12, -11, -9, -6, -8, -8, -8, -11, -13, -12, -9, -8, -5, 0, 4, 8, 11, 14, 18, 18, 20, 23, 23, 20, 14, 9, 4, 0, -3, -6, -8, -8, -8, -8, -9, -10, -11, -10, -9, -8, -8, -7, -6, -3, 0, 3, 6, 12, 16, 16, 14, 10, 8, 9, 7, 4, 1, 0, 0, -2, -1, 0, 0, -3, -7, -10, -13, -13, -12, -13, -15, -14, -13, -9, -6, -5, -5, -7, -8, -9, -7, -6, -5, -7, -5, 1, 8, 13, 17, 19, 20, 21, 22, 22, 18, 12, 9, 5, -1, -5, -9, -11, -13, -12, -12, -11, -10, -8, -7, -7, -6, -7, -6, -3, 0, 1, 3, 7, 10, 11, 12, 15, 15, 14, 9, 6, 3, 1, 0, -2, -2, -2, -3, -6, -8, -10, -11, -13, -15, -15, -15, -13, -12, -12, -7, -5, -5, -5, -4, -3, -3, -4, -4, -1, -1, 1, 4, 7, 10, 12, 14, 17, 20, 22, 19, 14, 8, 5, 2, -2, -5, -10, -14, -13, -11, -10, -10, -10, -10, -8, -6, -3, -3, -3, -1, -1, 2, 6, 10, 13, 14, 15, 15, 15, 13, 11, 8, 5, 1, -1, -3, -3, -6, -10, -12, -12, -12, -12, -13, -15, -18, -19, -15, -11, -6, -4, -3, -4, -4, -2, 1, 4, 2, -1, -2, 1, 4, 6, 8, 7, 7, 11, 14, 15, 15, 15, 13, 10, 6, 1, -3, -6, -9, -13, -15, -15, -13, -11, -9, -9, -9, -7, -3, 0, 2, 2, 4, 7, 11, 15, 16, 14, 11, 12, 13, 15, 13, 9, 4, 1, -1, -4, -6, -8, -11, -15, -17, -17, -17, -17, -15, -13, -13, -12, -10, -7, -6, -4, 1, 2, 2, 3, 4, 5, 4, 4, 3, 5, 6, 6, 8, 7, 7, 9, 11, 10, 9, 8, 5, 2, 0, -2, -6, -10, -13, -13, -14, -14, -13, -11, -9, -4, -1, -1, -1, 2, 6, 8, 10, 11, 12, 14, 14, 14, 13, 11, 10, 7, 4, 2, 3, 1, -3, -6, -10, -14, -17, -18, -18, -19, -19, -17, -15, -13, -9, -5, -1, 1, 0, 1, 3, 5, 6, 6, 6, 7, 8, 9, 8, 4, 1, 0, 2, 4, 5, 6, 5, 4, 4, 4, 3, 1, -3, -7, -9, -11, -12, -12, -12, -11, -10, -7, -4, -2, 1, 4, 5, 8, 11, 13, 14, 14, 11, 11, 11, 10, 10, 9, 6, 5, 3, 1, -2, -5, -10, -14, -16, -17, -18, -19, -20, -19, -17, -14, -10, -5, -1, 1, 3, 5, 6, 6, 6, 6, 6, 6, 6, 6, 8, 7, 6, 4, 2, 0, -1, 0, 0, 1, 2, 1, 1, 2, 1, -2, -5, -8, -9, -10, -11, -12, -12, -10, -7, -4, -1, 2, 8, 11, 13, 15, 15, 13, 12, 11, 10, 9, 8, 6, 5, 4, 4, 3, 0, -3, -6, -10, -14, -18, -21, -22, -21, -18, -16, -13, -10, -6, -3, 0, 3, 5, 5, 5, 6, 7, 8, 8, 8, 7, 8, 7, 6, 5, 4, 1, 0, -2, -4, -4, -5, -4, -4, -3, -2, -1, -2, -3, -4, -7, -8, -9, -9, -9, -8, -5, -2, 2, 4, 8, 11, 14, 15, 15, 14, 12, 10, 7, 5, 4, 4, 2, 1, 1, 2, -1, -3, -7, -10, -15, -18, -18, -18, -18, -17, -15, -11, -7, -3, 1, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 9, 6, 4, 2, 0, -3, -4, -6, -7, -7, -6, -5, -3, -2, -2, -2, -2, -3, -4, -5, -6, -6, -6, -6, -5, -4, -1, 4, 7, 9, 11, 12, 12, 11, 10, 9, 8, 7, 5, 3, 3, 2, 1, 0, -1, -4, -7, -8, -10, -13, -14, -15, -15, -15, -14, -11, -9, -6, -3, 0, 2, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 6, 5, 3, 1, -3, -6, -8, -8, -7, -7, -7, -6, -4, -2, 0, -1, -2, -3, -3, -3, -3, -4, -3, -3, -1, 1, 3, 4, 6, 7, 8, 9, 10, 10, 9, 7, 6, 6, 4, 3, 2, 1, -1, -2, -4, -6, -9, -11, -12, -12, -12, -11, -11, -10, -9, -8, -7, -5, -4, -1, 1, 3, 5, 7, 9, 10, 11, 10, 9, 8, 7, 6, 2, -1, -3, -4, -6, -7, -7, -7, -7, -6, -5, -5, -4, -3, -3, -4, -4, -4, -3, -2, 0, 0, 1, 1, 2, 4, 6, 6, 7, 7, 8, 7, 7, 7, 7, 7, 6, 5, 2, 0, -2, -4, -5, -7, -8, -8, -8, -9, -10, -10, -9, -8, -7, -7, -7, -5, -3, -2, 0, 1, 2, 4, 6, 9, 10, 11, 12, 10, 8, 6, 3, 1, -2, -4, -6, -7, -7, -7, -7, -8, -7, -7, -6, -6, -5, -4, -3, -3, -2, -1, 1, 2, 2, 3, 4, 5, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 4, 3, 2, 1, -1, -3, -4, -6, -8, -9, -9, -8, -8, -6, -5, -5, -5, -6, -6, -6, -5, -4, -2, 0, 2, 4, 6, 7, 8, 9, 9, 9, 9, 6, 4, 1, -1, -3, -5, -6, -7, -7, -7, -6, -6, -6, -6, -6, -5, -4, -3, -3, -2, -1, 1, 3, 4, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 1, -1, -3, -4, -5, -6, -7, -7, -7, -7, -7, -6, -5, -4, -4, -3, -3, -3, -3, -2, -1, 0, 1, 3, 5, 7, 8, 8, 8, 7, 6, 4, 2, 0, -2, -3, -4, -5, -6, -7, -7, -7, -7, -6, -6, -5, -5, -5, -3, -2, 0, 1, 2, 3, 4, 5, 6, 6, 6, 5, 5, 4, 3, 3, 3, 3, 3, 3, 2, 1, 1, -1, -2, -3, -4, -5, -6, -6, -7, -6, -5, -4, -3, -3, -3, -3, -3, -2, -1, -1, 0, 1, 1, 1, 2, 3, 5, 6, 6, 6, 5, 4, 2, 1, 0, -2, -4, -5, -5, -6, -6, -6, -7, -7, -7, -6, -5, -4, -3, -2, -1, 0, 2, 3, 3, 4, 4, 5, 5, 5, 4, 4, 4, 4, 3, 3, 2, 1, 1, 0, 0, -1, -1, -2, -3, -4, -5, -5, -5, -5, -5, -4, -4, -3, -3, -2, -1, -1, -1, -1, 0, 0, 0, 1, 2, 3, 3, 4, 4, 4, 4, 4, 3, 1, 0, 0, -2, -3, -4, -5, -5, -6, -6, -6, -5, -4, -4, -4, -3, -2, -2, -1, 0, 2, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 0, -1, -1, -2, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -2, -2, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 0, 0, -1, -1, -2, -3, -3, -3, -4, -4, -4, -4, -3, -3, -2, -1, -1, -1, 0, 1, 1, 1, 2, 2, 2, 3, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -5, -41, -25, -37, -9, 28, 14, 6, 1, 19, 16, -83, -53, -35, -44, -29, 8, -23, -29, -6, -20, -22, -19, -40, -2, 14, 34, 78, 59, 73, 93, 73, 83, 124, 94, 87, 61, 98, 80, 29, 27, 6, 8, -9, -8, -26, -33, -35, -32, -25, -32, -28, -59, -46, -31, -19, -12, -12, 14, 14, -41, -59, -46, -33, -32, -52, -31, -29, -49, -51, -53, -85, -53, -60, -100, -85, -84, -66, -37, -26, -11, -8, 22, 41, 33, 39, 27, 29, 75, 59, 45, 52, 69, 66, 73, 90, 91, 103, 81, 46, 16, -21, -32, -13, -34, -22, -42, -51, -35, -53, -62, -45, -35, -34, -29, 25, 62, 61, 39, -8, -20, -5, -7, 2, 28, 1, -24, 8, 29, 11, -9, -54, -34, -35, -57, -41, -63, -50, -16, -18, 26, 23, -2, 38, 9, 17, 41, 39, 82, 64, 64, 103, 64, 43, 43, 51, 26, -3, 30, 1, 9, 14, -26, 20, -27, -50, -39, -47, -31, -23, -33, 25, 56, 51, 20, -19, -60, -41, -27, -10, 3, -36, -30, -22, -46, -5, -12, -7, -4, -54, 3, -25, -10, -1, -42, -75, -27, -84, -60, -88, -107, -73, -29, -67, -53, 9, -10, 17, -29, -33, 55, 12, 7, 121, 70, 42, 123, 96, 127, 74, 28, 51, 21, 60, 23, -10, 25, 103, 113, 65, 45, 15, -1, 10, 2, -26, 1, -16, 19, 27, -8, -8, -24, -20, -17, -35, -86, -87, -32, -51, -26, -60, -60, -50, -15, -31, -30, -50, -55, -19, 22, 14, 30, 49, 42, 15, -11, -57, -15, -29, -65, -37, -56, -29, 15, 70, 69, 36, 24, 19, 21, 19, 4, 60, 55, 18, -17, 0, -2, -21, 51, 49, -6, 22, 14, -24, -63, -5, 4, -53, -33, -1, -37, -34, 40, 30, 12, -6, -1, 12, 12, 23, 20, 43, 34, 11, -26, -40, 25, 56, -1, -41, -50, -37, -10, 20, -58, -65, -43, -26, 42, 57, 77, 57, 26, -4, -10, -57, -45, -23, -49, -1, -59, -41, -26, -27, 24, 52, -3, -12, 19, -44, -31, 33, 11, -14, 43, 31, 7, 58, 84, 45, 35, 18, -5, 6, -21, -6, -20, -7, 41, 53, 29, 25, 55, 68, 37, -29, -17, -41, -67, -76, -90, -112, -104, -60, -21, 25, 16, -23, -9, 30, 47, 17, 3, 19, 4, -2, 30, 24, 1, 26, 33, 34, 10, 14, 1, -5, 16, -2, -60, -32, -51, -48, -38, -34, -42, -20, 16, 17, -16, -32, -6, 4, -39, -18, 1, -20, -22, 55, 70, 34, 5, -1, 13, 2, 1, 28, 20, -31, -2, 51, 26, 24, 19, 11, -1, 2, 30, 13, 2, 70, 36, 15, 24, 5, 9, 14, 48, 43, 8, 2, -10, 18, 33, 22, -27, -19, -17, -22, 11, 19, -5, 0, -55, -60, -49, -63, -72, -45, -80, -55, -18, -8, 32, 52, 22, 0, -40, -42, -30, -68, -51, -9, -67, -52, -10, 7, 35, 12, 36, 64, 23, 13, 64, 39, 32, 73, 3, 6, -10, -6, 16, 18, 53, 51, 21, -20, -15, 13, -3, 2, -39, -30, -7, -3, 6, 10, -4, -25, -7, -10, -10, -18, -31, -23, -38, -48, -3, -26, -43, -7, 11, 31, 62, 41, -7, -34, -42, -24, 17, 12, 44, 25, 24, 18, 11, 32, 51, 46, 46, 51, 33, 24, 32, 30, 40, 8, -30, -39, -30, -44, -19, -33, -55, -41, -36, -70, -67, -64, -34, -37, -46, 1, 19, 27, 81, 23, 13, 10, -5, -18, -19, -51, -14, -48, -75, 11, 51, 43, 63, 37, 20, 19, 4, -23, 27, 47, 71, 29, 16, 15, -17, -11, 32, 40, 22, 6, 16, -7, 5, 34, 61, 12, -21, -24, -13, -38, -41, -36, -33, 2, 9, -45, -54, -36, 12, -18, -41, -25, -18, 19, 31, -11, -16, -22, -62, -65, -68, -42, -4, -48, -49, 4, 38, 65, 47, 12, -20, -20, -8, 3, 32, 69, 84, 44, 28, 31, 18, 36, 57, 74, 35, 19, 6, 24, 29, 36, 35, 6, -13, -25, -43, -45, -35, -33, -44, -23, -41, -57, -52, -41, -35, -21, -16, -22, -11, 33, 42, 14, 19, 16, 0, -6, -34, -17, -37, -25, -7, 6, 48, 47, 3, -14, -17, -19, -11, -9, -11, 42, 42, 16, 1, 6, 15, 51, 42, 33, 29, 20, -5, -3, 4, 54, 42, 8, -30, -19, -15, -15, -20, -6, -7, -24, -32, -24, -17, -1, -16, -18, -36, -55, -38, -2, 8, 16, 7, -21, -35, -56, -67, -17, -58, -67, -36, 21, 67, 48, 15, 8, 13, -9, -8, -1, 21, 107, 56, 40, 56, 32, 33, 71, 60, 36, 30, 3, 31, 15, 4, 21, 2, -2, -25, -30, -26, -13, -9, -26, -20, -34, -34, -51, -28, 6, -9, -24, -49, -67, -54, -54, -52, -41, -42, -58, -37, 16, 39, 31, 16, 19, 11, -4, -23, -5, 24, 1, 10, 24, 26, 15, 34, 70, 77, 56, 33, 43, 28, 17, 25, 12, 2, 0, -12, -15, -2, 10, -19, -28, -45, -41, -28, -17, -3, -2, -9, -3, -25, -45, -14, 23, 10, -5, -19, -32, -22, -10, -1, -15, -16, -6, 13, 48, 70, 55, 23, 23, 10, -8, -14, 6, 8, -12, -5, 13, 10, -14, 0, 33, 23, 18, 43, 21, 26, 33, 13, -14, -7, -3, -31, -29, -5, -5, -25, -27, -35, -56, -45, -21, -17, -40, -14, 2, -23, -38, -9, 8, -16, -16, -7, -13, -25, -4, -12, -21, -14, 3, 13, 44, 65, 60, 40, 15, 5, -20, -22, -3, 3, 20, 39, 39, 9, 6, 21, 48, 24, 25, 25, 11, 0, 4, -5, -31, -34, -22, -45, -40, -24, -24, -41, -38, -47, -54, -45, -16, -22, -32, -7, 16, -1, -11, 23, 31, -1, -10, -20, -19, -9, 15, -10, -28, -21, 4, 24, 45, 60, 56, 46, 30, 26, 23, 36, 48, 33, 46, 40, 34, 19, 12, 23, 43, 37, 41, 43, 22, 24, 11, -11, -2, -5, 8, -28, -33, -11, -5, -26, -30, -25, -45, -21, -8, -26, -35, -37, -39, -54, -56, -20, -23, -42, -52, -49, -63, -47, -31, -29, -16, -21, -7, 14, 26, 48, 32, 12, -10, -22, -24, -6, 0, 33, 44, 31, 25, 15, 10, 34, 48, 38, 14, 9, 16, 12, -23, -15, -15, -8, -9, -19, -22, -2, -8, -10, -32, -27, 4, 12, -5, 1, -1, 4, -5, -3, -5, 10, 37, 18, -8, -19, -3, 0, -10, -5, -31, -32, -29, -2, 18, 32, 33, 14, -12, -15, 6, 8, 36, 66, 48, 38, 37, 42, 29, 49, 50, 42, 28, 25, 33, 15, 2, 4, 2, 4, 2, -11, -1, 6, 3, 9, -14, -12, -5, -12, -33, -36, -29, -26, -38, -44, -42, -38, -38, -52, -67, -70, -50, -32, -27, -29, -38, -26, -27, 1, 21, 23, 16, -17, -34, -26, -18, -20, 2, 11, 13, 5, 10, 13, 12, 28, 33, 35, 14, 14, 14, -8, -24, -25, -8, -16, -23, -14, 12, 8, 21, 25, 13, 25, 29, 25, 6, 3, 36, 26, 34, 11, 30, 29, 34, 23, 0, 1, 7, 8, 1, -10, -9, -13, 5, 17, 30, 26, 25, 3, -11, -4, -4, 9, 13, 17, 6, 4, 17, -1, -4, 9, 16, 22, 3, -2, -4, -16, -28, -22, -13, -34, -37, -31, -9, -7, -12, -16, -26, -12, -14, -11, -23, -16, -24, -33, -24, -30, -17, -28, -34, -44, -51, -34, -24, -22, -25, -2, 14, 23, 38, 46, 43, 28, 10, -6, -11, 1, 0, 5, 18, 16, -3, 12, 27, 23, 32, 48, 42, 34, 21, 21, 10, -3, -10, -10, -20, -38, -34, -29, -22, -16, -15, -17, -9, 7, 6, 6, -6, 1, 7, 6, 3, 11, 30, 30, 15, 11, 11, 10, 17, 22, 23, 24, 9, 15, 5, -2, 4, 3, -17, -21, -4, -21, -6, 8, -9, -1, 0, 8, -7, -18, -16, -3, -14, -13, -8, -17, -10, -8, -26, -37, -28, -17, -35, -17, -10, 1, -6, 1, 25, 32, 26, 9, -18, -19, 1, -12, -20, 2, 12, 5, -4, 15, 14, 15, 15, 17, 14, 2, 6, 3, -18, -21, -9, -1, -15, -11, -15, -22, -1, 3, -7, 0, 14, 14, -4, -13, 4, 18, 12, 15, 19, 25, 28, 27, 12, 9, 9, -10, -17, -4, -5, -4, -20, -19, 11, 20, 13, 0, -19, -8, 6, -9, 6, 26, 18, 14, 17, 22, 24, 18, 21, 37, 20, 7, 11, -8, -11, -4, -3, -8, -22, -16, -18, -15, -4, -9, -21, -10, 5, -8, -7, -17, -7, -9, -20, -28, -35, -31, -23, -23, -29, -28, -28, -33, -28, -24, -6, 0, -4, 7, 29, 25, 15, -6, -19, 1, -2, -22, 4, 10, 1, 9, 10, 13, 4, 6, 21, 15, 5, 21, 11, -18, -21, -15, -3, -4, -15, -15, -19, 4, 19, 11, 2, 17, 16, 2, 14, 14, 17, 20, 22, 20, 10, 16, 27, 12, 8, 11, 5, -9, -10, -6, -1, -7, -12, -3, 3, 8, 9, -5, -3, 6, -5, -6, 23, 14, 11, 12, 21, 21, 4, 18, 30, 7, 12, 25, 3, -11, -16, -15, -10, -13, -8, -6, -21, 2, -2, -25, -18, -8, -22, -22, -17, -12, -7, -12, -15, -20, -41, -28, -24, -23, -12, -12, -15, -10, -7, 2, 1, 6, 18, 29, 23, 21, 20, 9, -3, -9, -9, -10, -15, -8, -11, -2, 6, 14, 7, 7, 11, 9, 14, 2, 3, 7, 6, 6, -21, -20, -10, -12, -15, -16, -18, -14, -11, -14, 0, 0, -5, 3, 14, 12, 9, 0, -11, 5, 5, 12, 11, -1, 5, 3, 1, 4, -1, -1, 13, 16, 8, 14, 9, -2, -7, -11, -17, -12, -5, -9, -10, -13, -4, 1, 0, 4, 5, 0, 2, 3, 5, 14, 18, 9, -3, 2, 15, 14, 6, 2, 1, -1, -5, -6, 0, 0, 0, 7, 20, 22, 23, 13, 13, 17, 20, 35, 25, 20, 20, 14, 17, 16, 3, 7, 18, 15, 13, 17, 6, -5, -6, -13, -23, -19, -19, -22, -22, -24, -17, -18, -22, -27, -31, -30, -29, -30, -33, -36, -34, -37, -47, -38, -24, -28, -27, -31, -30, -28, -26, -20, -14, -14, -9, 4, 17, 21, 15, 12, 25, 29, 33, 33, 30, 30, 31, 19, 20, 14, 4, 10, 17, 18, 21, 28, 19, 20, 20, 5, -2, -3, -7, -10, -2, 1, 4, 6, 4, 5, 3, 2, -1, -4, -7, -10, -3, -6, -16, -5, -1, -8, -7, -6, -9, -10, -11, -7, -6, -10, -11, 2, 11, 7, 1, 6, 12, 16, 18, 15, 11, 14, 16, 9, 11, 6, 5, 13, 14, 13, 11, 0, -11, -4, -4, -8, -7, -5, -6, -3, -1, 2, -1, -6, -7, -9, -9, -9, -15, -11, -14, -17, -16, -18, -17, -12, -7, -8, -7, -6, -2, -3, -12, -15, -15, -18, -13, -19, -23, -24, -21, -21, -13, -12, -7, -3, -7, -6, -4, 2, 1, 1, 3, 9, 23, 28, 23, 17, 24, 27, 22, 19, 16, 19, 10, 9, 10, 10, 19, 8, 11, 16, 15, 11, 13, 14, 7, 5, -3, -7, -12, -15, -16, -17, -10, -5, 4, -2, -2, -9, -13, -9, -8, -10, -10, -12, -5, 3, 7, 3, 9, 3, 4, -1, -2, 2, -4, -9, -4, 0, 4, 4, -6, -3, 12, 10, 15, 12, 7, 7, 1, -1, 8, 11, 9, 9, 13, 17, 17, 9, 11, 4, 0, -3, -6, -8, -9, -10, -17, -20, -24, -17, -19, -22, -20, -21, -15, -16, -19, -23, -21, -28, -26, -15, -14, -4, -1, -6, -3, -1, 4, 9, 2, 4, 7, 7, 11, 15, 6, 17, 24, 16, 15, 9, 6, 6, 3, 1, 3, 2, -2, 6, 6, 6, 3, -6, -3, -8, -7, -10, -13, -17, -18, -16, -19, -13, -9, -3, 4, 10, 7, 7, 12, 11, 13, 10, 6, 1, 2, 4, 4, 10, 10, 7, 4, 1, 4, -5, -12, -3, 1, 10, 7, 6, 4, 19, 22, 20, 23, 16, 15, 19, 17, 14, 9, 7, 4, 4, 2, 5, 3, 0, 0, -7, -7, -8, -7, -14, -15, -18, -25, -21, -21, -16, -13, -14, -17, -18, -23, -21, -23, -29, -32, -33, -30, -23, -13, -11, -10, -8, -7, -2, 1, -3, -1, 5, 13, 17, 13, 11, 13, 16, 14, 10, 11, 8, 16, 13, 4, 0, 7, 13, 14, 15, 15, 17, 17, 9, 8, 9, 9, 2, 5, 11, 14, 7, 4, 11, 10, 5, 7, 2, -1, -4, -9, -16, -15, -12, -9, -15, -23, -21, -22, -22, -20, -22, -22, -21, -22, -22, -13, -6, 4, 2, -2, 2, 7, 6, 10, 8, 9, 12, 21, 16, 11, 7, 11, 13, 11, 10, 11, 13, 9, 6, 6, 5, 4, -5, 1, 4, 5, -1, -2, 6, 3, 3, -3, -10, -14, -14, -14, -16, -8, -6, -1, -6, -7, -5, -7, -6, -9, -8, -8, -4, -5, -8, -6, 3, 12, 4, -2, 3, 1, 1, -1, -4, -4, 5, 6, 1, -4, -3, 5, 9, 8, 18, 20, 22, 15, 11, 11, 15, 12, 9, 11, 11, 11, 5, 10, 12, 5, 3, -2, -4, -9, -9, -16, -17, -14, -12, -14, -20, -15, -16, -17, -17, -19, -20, -19, -15, -17, -15, -13, -2, -3, -13, -8, 0, 4, 7, 6, 4, 11, 13, 14, 11, 5, 6, 3, -1, -2, 2, 3, -1, -2, -6, -4, -1, -3, 0, 3, 1, -2, -5, -5, -3, -6, -9, -7, -15, -13, -10, -8, -4, 1, 9, 7, 2, 8, 8, 9, 12, 14, 7, 12, 12, 12, 8, 14, 19, 11, 7, 10, 13, 10, 2, -2, -6, -1, 2, 6, 3, 1, 4, 2, 2, 5, 8, 8, 7, 7, 2, 0, -3, -6, -3, -1, -6, -12, -9, -6, -7, -9, -10, -14, -16, -12, -12, -11, -13, -16, -16, -20, -18, -14, -10, -8, -9, -13, -9, -8, -9, -7, -9, -8, -3, -4, -3, -6, 0, 2, 3, -3, 2, 5, 1, 6, 5, 5, 10, 11, 17, 15, 20, 25, 20, 15, 17, 13, 12, 11, 7, 4, -1, -2, 6, 7, 7, 9, 10, 7, 9, 7, 5, 5, 1, -6, -2, -5, -6, -3, -3, -1, -3, -5, -3, -6, -8, -7, -8, -11, -12, -16, -19, -19, -14, -14, -17, -17, -11, -12, -15, -6, -8, -12, -12, -9, -7, -6, 2, 9, 6, 8, 11, 13, 15, 14, 11, 7, 3, 3, 4, 7, 9, 10, 6, 6, 5, 7, 11, 11, 4, 1, 1, -3, -5, -1, -1, -1, -5, -2, -1, -1, 1, 1, -3, -7, -7, -9, -12, -11, -3, -3, -7, -6, -6, -5, -5, 0, -3, -4, -2, 2, -1, 0, 6, 7, 7, 4, 3, 5, -1, 0, -1, -7, -9, -8, -11, -5, 0, -1, 0, 2, 2, 5, 10, 10, 7, 7, 7, 8, 8, 9, 11, 9, 8, 9, 6, 4, 2, 0, -3, -5, -8, -8, -12, -8, -1, -4, -4, -5, -7, -9, -6, -5, -6, -8, -6, -3, -7, 0, 5, 6, 3, 1, 6, 6, 4, 3, 1, -2, -4, -6, -4, 3, 7, 3, 0, -1, -3, -2, -1, -2, -5, -8, -9, -7, -9, -8, -6, -9, -7, -9, -7, -6, -7, -6, -7, -7, -7, -7, -8, -2, 1, 2, 4, 3, 5, 6, 10, 11, 9, 10, 12, 9, 9, 11, 9, 10, 8, 7, 7, 6, 7, 5, 4, 5, 4, -1, -4, -3, -5, -1, -2, -4, -4, -4, -4, -2, -2, -3, -4, -2, -1, 0, 1, 8, 8, 4, 4, 4, 2, -2, -3, -5, -6, -9, -10, -8, -5, 2, 1, -2, -2, -2, -2, -2, -5, -5, -7, -7, -3, -4, -6, -4, -3, -5, -7, -5, -4, -7, -9, -6, -6, -9, -7, -6, -2, 3, 3, 4, 5, 3, 4, 5, 2, 0, 2, 3, 2, 5, 7, 10, 9, 7, 7, 6, 4, 1, -2, -5, -6, -10, -10, -8, 2, 8, 7, 6, 7, 5, 5, 7, 6, 3, 4, 3, 4, 1, 3, 2, 4, 2, 1, 1, -1, -3, -3, -4, -6, -9, -9, -9, -7, -6, -5, -5, -4, -5, -2, -1, -2, -3, -1, -1, -3, -2, 2, 2, 3, 4, 4, 2, 0, -1, -3, -4, -4, -5, -7, -2, 2, 2, -1, -3, -1, -4, -3, -2, -4, -4, -2, -1, -2, -4, -2, -2, -1, -2, -2, -2, -3, -2, 0, 2, 0, -2, -2, 0, 2, 3, 5, 4, 4, 4, 6, 3, 1, 0, 0, 0, 0, 5, 5, 4, 6, 4, 2, 0, -2, -3, -6, -9, -8, -10, -10, -2, 3, 4, 4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 2, 3, 2, 2, 2, 1, 1, 0, -2, -3, -3, -4, -6, -8, -7, -4, -6, -3, -3, -3, -2, 1, 0, -1, -2, -2, -1, -1, 0, 1, 0, 0, 1, 0, 0, 0, -1, -2, -3, -3, -4, -5, -4, -3, -3, -3, -3, -3, -3, -2, -1, 0, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 2, 3, 3, 2, 2, 0, -1, -1, -2, -3, -3, -4, -5, -4, 0, 3, 3, 3, 3, 2, 3, 4, 6, 4, 4, 3, 2, 1, 2, 1, 0, 0, -1, -2, -3, -3, -2, -2, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -3, -2, -3, -2, -2, 0, 0, 0, 0, 0, -1, -1, -2, -2, -3, -2, -4, -4, -3, 0, -1, 0, 0, 0, 0, 0, 1, 2, 1, 1, 1, 0, 0, 0, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, -2, -2, -2, -2, -2, -3, -3, -1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, -8, -33, -24, -25, -25, -26, -27, -32, -28, -36, -31, -36, -22, -34, 11, -74, -14, 94, 41, 28, 33, 30, 40, 34, 23, 41, 40, 60, 56, 59, 60, 44, 39, 54, 45, 52, 17, 44, 62, 34, 33, 19, 18, 43, 35, 22, 36, -15, -10, 32, -7, -12, -6, -8, -50, -47, -44, -4, -25, -48, -76, -58, -75, -96, -85, -118, -114, -63, -106, -103, -83, -110, -99, -84, -76, -58, -63, -61, -51, -53, -36, -32, -41, -27, -11, 11, 8, 27, 19, 30, 35, 28, 57, 53, 38, 71, 51, 68, 110, 78, 89, 109, 97, 82, 94, 115, 114, 79, 70, 79, 94, 85, 76, 84, 95, 83, 82, 55, 54, 54, 41, 41, 27, 20, 6, -11, -21, -16, -14, -33, -33, -52, -54, -59, -62, -71, -79, -88, -88, -78, -78, -72, -71, -94, -99, -93, -90, -78, -87, -105, -103, -79, -62, -71, -78, -63, -61, -66, -49, -23, -10, -11, -24, -20, -4, -22, 9, 8, 27, 43, 34, 38, 51, 83, 65, 58, 74, 75, 70, 73, 71, 65, 100, 89, 94, 65, 84, 49, 49, 61, 54, 43, 51, 58, 53, 35, 40, 36, 38, 34, 23, 14, -12, -10, -1, -1, -11, -12, -19, -33, -66, -52, -42, -37, -55, -42, -28, -32, -29, -35, -41, -28, -25, -46, -85, -64, -62, -55, -49, -68, -55, -53, -52, -47, -43, -26, -32, -41, -34, -35, -40, -26, -8, -1, -6, -11, 5, -2, 8, 3, 8, 6, 4, 20, 29, 43, 24, 33, 20, 30, 24, 39, 38, 40, 29, 37, 36, 39, 61, 58, 41, 51, 59, 51, 55, 58, 48, 32, 45, 40, 27, 30, 41, 44, 26, 19, 23, -3, 7, 0, -3, 2, 3, -6, -5, -14, -6, -10, -27, -45, -47, -41, -38, -50, -51, -46, -43, -45, -65, -65, -80, -95, -82, -74, -66, -69, -67, -33, -31, -53, -48, -51, -43, -18, -24, -24, -33, -26, -10, 0, -17, -6, 17, 31, 2, 23, 45, 46, 12, 75, 38, 63, 69, 31, 38, 80, 57, 48, 59, 81, 74, 32, 52, 72, 24, 60, 44, 55, 40, 28, 48, 33, 24, 10, -2, 21, 34, 13, 18, 7, -1, -12, -20, -18, -30, -9, -7, -30, -27, -26, -38, -20, -54, -55, -64, -53, -36, -62, -37, -71, -47, -42, -71, -45, -55, -50, -54, -56, -36, -37, -54, -36, -12, -38, -33, -26, -7, -22, -44, -10, 2, 3, 15, 8, 18, 6, 12, 8, 15, 28, 22, 50, 35, 55, 42, 36, 49, 52, 64, 48, 60, 49, 60, 62, 40, 47, 68, 52, 59, 61, 44, 53, 44, 35, 31, 31, 47, 22, 6, 4, -7, 5, -4, -21, -13, -9, -10, -27, -46, -32, -44, -46, -62, -44, -51, -67, -53, -59, -63, -74, -67, -61, -61, -65, -47, -58, -57, -45, -41, -46, -41, -38, -22, -25, -34, -16, -10, -18, 0, 1, -6, 5, 17, 15, 10, 23, 38, 28, 28, 54, 40, 19, 55, 55, 41, 46, 53, 40, 49, 51, 52, 41, 56, 39, 53, 38, 33, 35, 18, 15, 38, 30, 23, 27, 13, 11, 7, 16, -1, 0, 0, 13, -6, -10, -15, -10, -10, -24, -20, -16, -38, -36, -21, -40, -32, -42, -38, -52, -53, -41, -48, -58, -50, -47, -37, -41, -45, -29, -41, -6, -48, -24, -25, -15, -9, -10, -10, -10, -1, -17, 4, 3, 10, -4, 9, 15, 25, 24, 19, 23, 34, 28, 33, 37, 38, 26, 36, 47, 35, 46, 45, 28, 35, 32, 32, 24, 21, 26, 23, 19, 37, 20, 9, 29, -2, 26, 24, 8, 4, 14, 21, 11, -9, -8, 4, -9, -31, -11, -15, -21, -24, -29, -22, -33, -26, -29, -48, -32, -44, -28, -22, -35, -30, -38, -31, -46, -44, -36, -27, -23, -29, -24, -11, -20, -28, -13, -34, -19, -1, 7, -3, -1, 6, -3, 5, 4, 8, 17, 26, 19, 33, 27, 16, 35, 14, 36, 39, 22, 32, 31, 19, 32, 23, 29, 21, 30, 29, 23, 31, 13, 24, 17, 11, 26, 18, 12, 5, 23, 16, 9, 15, -10, 3, 18, -15, -4, -4, 6, -14, -15, -5, -34, -11, -20, -18, -8, -17, -29, -30, -29, -19, -34, -35, -20, -36, -20, -16, -21, -38, -16, -30, -24, -25, -19, -18, -15, -7, -5, -5, -10, -23, -3, -14, 0, -1, -12, -9, 7, 7, 2, 12, 5, 7, 19, 10, 21, 21, 27, 30, 22, 18, 34, 22, 11, 26, 24, 20, 21, 25, 29, 22, 27, 27, 20, 10, 20, 16, 22, 15, 16, 16, 5, 19, 10, 3, 22, -5, -5, -7, -16, -4, -11, -22, -7, -16, -11, -23, -16, -30, -24, -28, -20, -29, -24, -32, -22, -22, -30, -17, -23, -28, -22, -20, -21, -21, -17, -30, -15, -14, -20, -9, 3, 6, 5, -20, 10, 13, -2, 11, 8, -1, 7, 16, 5, 22, 23, 13, 22, 13, 22, 25, 15, 16, 11, 15, 13, 7, 12, 19, 18, 20, 12, 23, 11, 6, 10, 1, 11, 19, 5, 20, 0, 11, 11, 1, 14, 15, -3, -1, -7, 6, -6, -9, -9, 4, -3, -10, -20, -14, -9, -14, -7, -10, -5, -4, -29, -14, -12, -26, -21, -27, -18, -10, -19, -27, -18, -8, -25, -8, -13, -15, -14, -15, 5, -13, -7, -11, -4, -12, 0, 15, 5, 4, 1, 11, 6, 4, 3, 6, 21, 19, 8, 15, 13, 6, 14, 16, 18, 17, 20, 15, 11, 15, 24, 13, 11, 19, 7, 17, 14, 6, 17, 7, 7, 6, 6, 5, 11, 0, 6, 0, -6, 5, 1, -11, -6, -1, -8, -9, -15, -7, -4, -16, -17, -13, -13, -17, -14, -12, -12, -28, -13, -19, -25, -31, -24, -17, -17, -16, -7, -15, -12, -8, -15, -8, -16, -10, -4, -1, -2, 3, 5, 2, -2, 5, 3, 6, 10, 8, 11, 14, 14, 13, 15, 22, 16, 14, 18, 13, 17, 19, 16, 10, 17, 8, 17, 14, 3, 14, 7, 10, 10, 7, 6, 6, -1, 6, 1, 0, 12, -6, 6, 12, -4, -5, -4, -2, -2, -1, -2, -8, -11, -9, -11, -11, -18, -6, -5, -16, -9, -14, -10, -13, -10, -11, -15, -14, -14, -12, -17, -17, -17, -7, -11, -14, -15, -12, -6, -15, -5, -13, -9, 0, 12, -2, -2, 6, 2, -7, 4, 10, 2, 9, 8, 7, 4, 5, 11, 15, 11, 10, 18, 9, 13, 13, 13, 21, 11, 18, 19, 13, 14, 16, 6, 8, 1, 19, 11, 10, 11, 1, 3, -1, -1, 5, -11, 5, -1, -5, -3, -13, -10, -6, -7, -5, -15, -10, -11, -18, -8, -16, -20, -18, -9, -12, -17, -21, -21, -13, -21, -8, -10, -10, -5, -16, -7, 2, -6, -6, -9, -7, -2, -9, -5, 6, -7, 1, 3, -1, 2, 1, 2, 9, 8, 5, 15, 12, 1, 11, 9, 8, 10, 15, 14, 5, 13, 17, 14, 15, 10, 7, 16, 5, 5, 5, 8, 9, 10, 10, 7, 0, 4, 6, 9, -10, -4, 5, 2, -1, 0, -3, -4, -5, -10, -5, -8, -9, -10, -3, -13, -6, -9, -20, -15, -11, -18, -14, -10, -12, -20, -14, -14, -7, -12, -21, -14, -9, -8, -11, -5, -2, -7, -4, 4, -2, -3, -1, 0, -1, 8, 6, 9, 7, 10, 6, 3, 4, 7, 10, 11, 6, 9, 17, 11, 9, 7, -2, 16, 13, 12, 18, 5, 16, 9, 4, 9, 6, 8, 9, 4, 4, 3, -2, -3, 2, -6, -3, 1, -7, -6, -3, -6, -14, -8, -9, -4, -13, -9, -8, -16, -10, -12, -13, -11, -7, -8, -12, -9, -8, -7, -11, -4, -8, -7, -8, -3, -13, -10, -3, 6, -5, -5, 0, -5, -3, 6, -2, -2, 4, -2, 6, 2, -2, 5, 5, -2, 5, 15, 13, 4, 6, 6, 14, 9, 4, 8, 7, 3, 11, 12, 2, 10, 7, 10, 8, 4, 6, 2, 0, 3, 2, 4, 2, -6, -2, 2, -4, 3, -5, -6, -5, -5, -5, -4, -8, -7, -4, -4, -7, -8, -7, -13, -10, -10, -11, -9, -8, -8, -7, -11, -7, -3, -9, -6, -7, -3, -4, -5, 3, -3, -1, -2, -4, 1, 4, 0, 3, 0, 5, 2, 0, 5, 4, 1, 3, 1, 0, 1, 7, 3, 0, 4, 3, 6, 5, 0, 9, 5, 7, 6, 3, 6, 2, 3, 5, -4, 9, 0, 4, 10, 0, 5, 1, -2, 4, -3, -3, -2, 0, 2, -7, 3, -10, -1, -6, -9, -2, -4, -10, -3, -7, -6, -4, -10, -6, -6, -11, -6, 0, -6, -8, -4, -1, -9, -10, 0, -6, -7, -2, -7, 1, -5, -5, -1, 1, -6, 2, 0, -3, -1, 7, -4, 0, 7, 0, 8, 2, 3, 4, 4, 2, 5, -1, 6, 7, 5, 6, 4, 2, 4, 6, 8, 6, 3, 1, 8, 9, 2, -1, 4, 3, 4, 3, -3, 7, 4, 3, -2, 2, -4, -6, -2, -5, -2, -3, 0, -5, -6, -13, -5, -6, -11, -9, -10, -5, -4, -9, -9, -7, -7, -8, -8, -6, -5, -7, -5, -1, -3, -4, -2, -2, 2, -3, 1, 2, -3, 1, 2, 1, 0, 1, 5, 0, 2, 5, 2, 0, 4, 1, 7, 3, 2, 6, 0, 5, 7, 5, 5, 1, 3, 3, 5, 10, 3, 4, 8, 2, 7, 3, -2, 3, 0, -1, -1, 1, 0, 1, -3, -2, -5, -4, -3, -1, -7, -8, -4, -4, -10, -2, -8, -8, -8, -8, -9, -6, -8, -9, -4, -2, -7, -5, -2, -7, -6, -9, -2, 0, -4, 4, -6, -3, -4, -1, 2, 1, 2, 9, 0, 3, 0, 6, 4, 0, 5, 6, 2, 7, 7, 5, 7, 6, 8, 6, 6, 5, 5, 1, 6, 5, -1, 3, 4, -1, 4, 1, 4, 3, -5, 0, 4, 1, 4, -2, -3, -4, 0, -4, -8, -2, -5, -4, -8, -6, -5, -3, -3, -7, -9, -6, -10, -10, -6, -6, -5, -4, -7, -6, -4, -10, -3, -10, 0, -2, -2, -6, -1, 3, -3, -3, 1, 2, 1, 4, 3, 4, 3, 4, 1, 2, 6, 5, 5, 5, 7, 9, 1, 5, 4, 4, 7, 2, 9, 2, 4, 8, 2, 5, 6, 3, -2, -2, -1, -2, -1, 1, -2, -4, 1, -6, -2, -5, -3, -5, -5, -6, -4, -3, -4, -10, -4, -3, -8, -4, 0, -3, -5, -6, -6, -3, -1, -7, -3, 1, -1, -4, -2, 1, -2, 0, -1, -2, 0, 0, 5, -2, 0, 3, 3, 1, 5, 2, 4, 1, 4, 1, 2, 3, 3, 3, 4, 3, 3, 5, 1, 4, 2, 3, 1, 2, 0, 2, 1, -2, -2, -1, 0, -2, -1, -1, -3, -5, -2, 0, -5, -1, 0, -5, -2, -2, -2, -3, -3, -1, -4, -1, -2, -4, -2, -1, -2, -1, 0, -3, -1, -1, 0, 1, -1, -1, 3, -4, -2, -2, 4, -2, -1, -1, -1, 0, 0, -1, -1, -1, -1, 2, 0, -1, 2, -1, 0, -1, 2, 0, 3, 5, -2, 1, 2, 0, 5, 0, -3, 4, -3, 1, 2, 0, 4, -1, -2, 1, 0, 0, 0, -1, 1, -2, 0, 1, 1, 0, -5, 1, -2, -1, 0, -2, -3, -1, -3, 0, -2, -3, -4, 1, -2, -3, -2, -2, -1, -1, -2, -1, -4, -5, 2, -4, 0, 1, -1, 2, -2, -1, 0, 0, 1, -3, 3, 2, 0, -2, 2, 1, 2, -2, 5, 3, -2, -2, -1, 1, 0, 0, 1, 3, 2, 0, 0, -1, -2, 1, 1, 2, 1, 1, -1, 0, -1, -1, -1, -3, 1, 1, 2, -2, -1, 0, 0, -2, 0, -1, -1, 2, -2, 1, -1, 0, 0, -1, -1, -2, 0, -1, 1, -1, -1, 2, -2, 0, -1, -1, 2, -1, 0, -3, -1, 0, 0, 0, -3, -3, -2, 0, 0, -1, -1, 0, -4, 2, 0, -2, 0, 1, -3, -1, 2, 1, 0, -1, 0, 0, -1, 0, 2, -1, -1, 0, 0, -2, 1, 1, 0, 1, 0, 2, -3, -2, 2, -1, -1, 2, -2, 1, 1, 0, 0, 1, 1, 0, -4, 3, -1, 2, 0, 2, -1, -2, 0, 1, 1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, 1, 0, -5, 0, -1, -1, -1, 1, -1, 1, -1, 1, 0, -2, 0, -2, 1, -1, 1, 0, -1, -2, 0, -1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 2, 0, -1, 0, 0, 0, 2, -1, 1, 1, -1, -1, 0, 0, 1, 1, 0, 0, 0, 0, -1, 0, 0, -2, 0, 0, -1, 1, -2, -1, -1, -1, -2, -1, -2, 1, -1, 0, -2, -2, 1, -2, -1, 1, 0, 1, 1, -1, -1, 0, -1, 0, 0, 0, -2, 0, -1, 0, 0, -1, -2, -2, -2, 1, -1, 0, 0, -1, 1, 1, -2, -1, -2, -1, 1, -1, -1, -2, -2, 0, 0, 1, -1, -1, -1, -1, -2, 2, 0, 0, 1, 1, 1, -2, 0, -1, 0, -1, -1, 2, 0, -1, -1, -1, 1, -1, 2, 0, -1, 1, 1, 0, 1, 0, -1, -1, -1, -1, -3, 0, 0, -1, 1, 0, 0, -2, -2, -2, 0, -1, 0, 0, -1, 0, -1, -2, -1, -2, 0, -2, 0, 0, -1, -2, 1, -2, 0, -1, -2, 2, 0, -1, 2, -1, 1, -1, 0, 0, -1, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, -1, -1, 0, -2, -1, 0, 0, 1, 0, 0, 0, 0, -1, -1, 1, -1, -2, -1, 0, 0, -2, 0, -1, 0, 0, 0, 1, 0, 0, -1, 1, 0, -1, 0, 1, -1, 0, -1, -2, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, -1, -1, 0, -2, 0, 0, 0, -2, -2, 0, -2, -1, -1, -1, -2, 0, -1, -1, -1, 0, 0, -1, -1, 0, 1, -1, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, 0, -1, 0, 0, -1, -1, 0, -1, -1, 0, -1, 0, -1, -1, 0, -2, -1, 0, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, -1, 1, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, -1, 0, -2, 0, -1, -1, -1, 0, -1, -1, 0, -1, 0, 0, 0, -2, -1, 0, -1, -1, 0, 1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, -1, -1, 0, 0, -1, -1, 0, -1, 0, 0, 0, -1, 0, -1, -1, 0, -2, -1, -1, -1, 0, -1, 0, -1, -1, 0, 0, -1, 0, -1, 0, -1, -1, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, -1, 0, 1, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, 1, -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, 0, -1, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, -1, 0, 0, -1, 0, 0, 0, -1, -1, 0, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, -1, 0, 0, -1, -1, 0, 0, -1, 0, 0, -1, -1, -1, 0, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -4, 11, 6, 16, 10, -16, -48, -44, 2, 67, 42, -17, -51, 15, 71, 12, -22, -14, -44, -35, 11, 17, -18, 2, -15, 19, 12, -1, -44, -15, 50, 45, -25, -61, 17, 10, -10, 31, 18, -72, -27, 57, 26, -13, -17, -2, 6, -1, -23, -54, 17, 39, 8, 30, 28, -6, -71, -5, 33, 27, -5, 17, 10, -23, -6, 12, -26, -6, -7, -9, -14, 11, 37, 41, 8, -33, -14, 8, -31, -38, 13, 9, 15, 35, 33, 11, 17, -41, -48, -33, 29, 25, 16, -9, -9, -17, -19, -29, 43, 64, -2, -55, -42, -1, -21, -4, 29, 34, -25, -67, -29, 1, 51, 49, 25, -6, -15, -48, -76, -3, 60, 78, 33, 19, 13, -38, -35, -35, -2, 62, 19, -4, -12, -4, -4, -32, -30, 8, 68, -43, -66, -28, 55, 51, 20, -28, -29, -19, 20, -2, 8, 21, -15, -43, 24, 22, -7, -2, 35, 15, -2, -24, -12, 3, 31, 13, -15, -20, -17, -17, 26, -26, 24, -3, 7, 21, 26, -3, -17, -26, -50, -26, 33, 58, 49, -22, -67, -17, 24, 7, -57, 5, 42, -11, -3, 32, -3, 7, 13, -11, -9, 27, 17, 1, -5, -9, -18, -19, -3, -23, -5, 7, -8, 9, 13, 12, -5, 7, -37, 22, 26, 21, 24, -20, -35, 23, 24, -35, -15, 46, -38, -48, -14, -4, 0, -22, 3, 43, 38, -1, -14, -8, -5, -14, 1, 21, 23, 29, -19, -47, -42, -49, -10, 66, 77, 48, -29, -32, 1, -11, 8, 17, -17, 3, 43, 33, -22, -19, -41, 29, 22, -42, 9, 63, 28, -23, -59, -65, 7, 53, -22, -10, -27, -30, 36, 48, -4, -6, -22, -16, 10, 14, -7, 22, 50, -4, -25, -41, -55, -62, 23, 68, -16, -31, 49, 57, 21, -38, 14, 12, -43, -49, -16, 28, 7, -12, -50, -17, 49, 65, 18, 1, -8, 28, 2, -27, -13, 12, -11, -52, 4, 31, -32, -39, 15, 8, -19, 6, 25, -1, -23, 13, 34, 59, 36, -16, -5, -7, -28, -30, 1, -14, -42, 10, 43, 26, -25, -37, -61, 1, 63, 62, 1, -36, -24, 38, -7, -26, 27, 10, 4, 2, -19, -22, -27, -24, 0, 33, -8, -57, -12, 62, 77, 51, -10, -42, -27, -28, -31, -3, 5, 21, 10, 15, -27, -18, -18, -10, 3, 17, 19, 18, -16, -20, 25, -3, -19, -5, 32, 17, -3, -32, -8, 2, -11, -24, -17, -11, 3, 42, 15, -12, -2, 26, 9, -4, -30, -3, 16, 7, 13, 34, 40, 114, 11, -104, -71, 7, -14, -34, -26, 35, 45, 47, 7, -7, -16, 11, -6, -29, -32, 1, 24, 32, 10, 29, -10, -74, -80, -20, 18, 9, 18, 61, 38, -27, -44, 13, 16, -26, 20, 69, 14, -14, -46, -7, -6, -35, 0, 9, 5, 58, 71, -36, -78, -15, 43, 34, -61, -101, -27, 45, 26, -10, 23, 69, 69, 5, -72, -62, 19, 16, -37, -60, 37, 60, 10, -49, -10, -2, -1, 43, 44, 10, -50, -5, 19, 8, -43, -58, -17, 32, 28, 4, -1, -18, -10, 13, 8, 1, 1, 22, -3, -4, 9, -8, -9, 17, 3, -15, -8, 14, 11, -14, -11, -5, 13, -24, -34, -1, -16, -4, 32, 35, -32, 9, 22, 12, -27, -16, 14, 15, 0, -2, -12, -31, -24, 14, 48, 10, -14, -7, -22, 4, -8, -14, 19, 21, -21, -25, -12, 19, 24, 19, 27, -3, -15, -16, 10, 21, -14, 3, 8, 3, -11, -33, -16, 7, 5, -8, 2, -3, 12, 5, -34, -19, -6, 26, 19, 0, -4, -12, 5, 12, 20, 16, 19, 18, -13, -42, -26, -1, 0, -18, -16, 10, 27, 23, -5, -7, 9, -8, 7, 22, 10, -28, -51, -26, 13, 44, 17, 16, 25, 14, -32, -45, -36, -40, -3, 22, 41, 34, -12, -35, -31, 18, 3, 31, 28, 4, -21, 2, -14, -24, -23, 19, -6, -7, -10, -1, -13, -13, 21, 52, 28, 7, 1, -25, -36, 2, 34, 10, -37, -31, -13, 19, 11, -4, -20, 15, -5, -18, 40, -13, 15, -36, 14, 18, 17, -21, 6, -39, 21, 7, -26, 8, -33, 24, 30, 32, -11, -26, -47, -39, 62, 10, 11, 5, -17, -21, 10, 0, 18, 15, -22, 7, 13, 14, -8, -9, 30, 33, -34, -41, -32, 37, 24, -19, -15, 1, 2, 10, 10, -27, -46, -14, -9, 9, 47, 1, -22, -18, 5, 37, 29, -3, -19, -19, -18, 8, 17, 1, -11, -6, -20, 27, 37, -2, -28, -34, -3, 22, 54, 34, -31, -43, -28, -30, -33, 26, 49, 45, 43, -15, -58, -13, -2, -27, -7, 41, 11, 19, -50, -74, -28, 31, 75, 39, -45, -7, 99, 44, -83, -47, 45, -1, -30, 23, 29, -55, -30, 31, 28, -19, 2, -44, -46, -49, 30, 22, 58, 31, -50, -20, 9, -38, -53, 49, 37, -9, 13, -25, -18, 18, -27, -7, 17, 3, 24, 57, 26, -51, -52, -54, -43, 53, 85, 31, -36, -44, 7, 13, 19, -23, -33, 36, 47, -38, -11, 37, -19, -6, 18, 17, 2, 31, 54, -29, -72, -80, -1, 27, 52, 10, -29, -40, -48, -72, 24, 108, 66, -44, -76, -32, -24, 21, 69, 54, 24, -2, -8, -28, -44, -50, 34, 95, 45, -40, -72, -32, 6, 28, -1, 18, -7, 27, 1, -14, 21, -8, -51, -62, -24, 64, 56, 12, 19, -36, -22, 10, 20, -10, -1, -5, -51, 36, 72, -42, -51, 70, 45, -48, -27, 54, 19, -46, 8, 0, -46, 10, 37, 35, -21, -32, -22, -44, -82, -33, 59, 105, 48, -32, -36, -31, 18, 60, -12, -49, 10, 89, 28, 12, 8, -45, -21, -6, -16, -32, -17, -18, 3, 29, -3, 0, -20, -51, -31, 24, 52, 1, -17, -20, 1, 35, 15, 5, 35, 27, 18, -19, 8, -71, -74, -8, 88, 57, -45, -37, 17, 51, -1, -13, -4, 3, -13, -24, -7, 30, -7, -25, -1, 16, -8, -43, -70, 11, 85, 77, 12, -62, -57, 35, 53, -33, -96, 8, 82, 21, -38, 25, 39, -1, -27, -14, 18, -16, -45, -24, 42, 7, -9, 22, 32, -39, -5, -8, -49, -17, 60, 88, 21, -93, -20, 82, 31, -26, -63, -17, 52, -28, -25, 13, -2, -32, -46, 55, 56, -37, 6, -57, -33, 65, 63, 5, -25, -31, 69, 86, -32, -34, -56, -23, -47, 14, 44, -23, 19, 6, 60, -27, -69, -37, 20, -14, -5, 50, 44, 15, 13, -23, -60, -46, 23, 40, -5, -25, 6, 46, -4, -10, -27, -12, 28, 45, 10, -13, -33, -19, -39, 42, 32, -23, -25, 24, -17, 13, 25, 13, -32, 13, 48, 4, -93, -5, 40, -7, 37, -39, -37, 41, 1, -13, -33, 43, -53, 106, 8, -57, -93, 55, 40, 56, -24, -4, -19, 7, -23, -65, -18, 34, -30, 7, 66, 92, 3, -43, -37, -23, 12, -7, -17, 14, -15, -9, -18, 18, 51, -1, -57, -17, 23, 19, 15, -40, -1, 0, -8, 39, -13, -43, 72, 57, -1, -54, -17, 32, -19, 11, 0, 36, 25, -23, -86, 21, -3, 14, -17, 76, 37, 23, 2, -23, -54, -42, -80, 61, 60, 63, -12, -57, -44, 15, 35, 26, 11, -44, -22, 8, 33, -24, -17, 21, 38, -25, -39, 16, 43, -36, -28, 54, 10, -52, -18, -34, -14, 76, 60, 24, -32, -19, 16, -13, -68, -5, 30, -13, -23, -14, 61, 24, 35, 39, 4, -50, -58, -39, 0, 43, 43, 21, 24, -20, -46, -36, 38, 8, -67, -8, 61, 38, 10, -12, 5, -4, -16, -47, -5, -18, -20, 37, 41, 24, 4, 7, -19, 11, -52, 0, 17, 20, -30, -33, -16, 60, 34, -15, -46, -77, 14, 29, 26, 21, 25, 8, 7, 36, 23, -39, -16, 21, 11, -23, 11, -4, -6, -35, 13, -8, -49, -17, 44, 19, -25, -17, 9, -5, -5, -1, -31, 11, 15, 17, -8, -31, -51, 12, 54, 85, 32, 4, -58, -35, -31, 0, 10, 21, -20, -20, -29, 15, 26, -7, 8, 4, 0, 30, 2, -26, 2, 19, 15, -18, -13, -20, -19, 47, 33, -6, -51, -30, -12, 12, 30, 34, 31, 4, -45, -81, -7, -22, 1, 73, 98, 24, -67, -13, 19, -32, -86, 6, 94, 4, -47, 21, -11, -50, 22, -3, -2, 50, 20, -37, -59, 35, 28, -16, -36, -30, -11, 4, 69, 98, -65, -84, 73, 27, -90, -17, 84, 10, -51, -14, 40, -24, -11, 16, -34, -26, 38, -43, -34, 58, 85, -33, -51, 17, 7, 4, 52, 25, -35, 0, 44, -21, -47, 40, 44, -69, -65, 37, 35, -21, 4, 32, -60, -75, 21, 64, 60, -6, -11, 6, 2, -41, -34, 19, 31, 9, 7, -1, 11, 6, -11, -26, -23, 16, 35, -39, -68, 6, 56, -3, -42, 29, 28, 3, 28, 14, -37, -16, 11, -8, -18, 15, -1, -8, 43, -20, -67, -12, 34, 7, -12, -9, 5, -4, 7, -12, 27, -3, -68, 26, 96, 30, -33, -28, -25, 19, 27, -33, -48, -3, 37, -1, -35, -11, 5, 42, 36, 6, -48, -38, 26, 54, -23, -41, 52, 44, -32, -22, 28, -23, -32, 12, 41, -16, -6, -6, -17, -18, -14, -12, -5, 18, 52, 45, -10, -16, 29, 11, -36, -26, 7, 36, 12, -57, -48, 48, 70, 16, 21, -13, -46, -33, -62, -63, -21, 94, 94, 20, -110, -47, 41, 67, -16, -57, -40, 85, 71, 7, -39, 15, -29, -50, -41, 18, -40, -42, 38, 69, 21, -8, -58, -19, 23, 24, -20, -10, 11, 41, 7, -6, -30, -23, 2, 16, 57, 38, -11, -50, 36, -16, -51, -51, 81, 24, -68, -84, 39, 112, 62, -79, -104, 24, 102, 15, -38, 20, 22, -49, -91, 15, 51, 30, -1, -15, -30, -12, 17, 42, -17, -48, 0, 49, 35, 2, -19, -16, -30, 9, 17, -12, -4, -15, 5, 34, -1, -56, -64, 7, 48, 54, -16, -51, 20, 62, -17, -27, -9, -10, -29, -1, 35, 44, -20, -23, -2, -12, -4, 31, 24, -24, -14, 2, -28, -27, 49, 61, -54, -61, 6, 23, -20, 2, 41, 26, 2, 15, -5, 6, -16, -36, -16, 2, -54, -53, -18, 62, 64, 10, -3, 91, 39, -54, -103, -5, 16, -31, -28, 75, 105, -32, -114, -52, 68, 32, -52, -19, 25, 54, 61, 14, -40, 12, 1, -56, -31, 74, 40, -73, -66, 0, 49, 36, 24, -20, 0, 13, -40, -99, -11, 55, 31, -33, 39, 24, 3, -18, 7, 10, 4, -29, 17, 19, 27, -30, -41, 9, 33, -24, -25, 30, 28, -34, -57, 8, -7, -46, 5, 48, -22, -6, 57, 58, -31, -72, -2, 72, 44, -53, -42, 41, 1, -54, 30, 54, -6, -79, -14, 33, -6, -22, 14, 10, -5, -8, 13, 23, 21, -47, -74, 22, 24, -10, -7, 39, 2, 12, -7, -2, 4, 33, -20, -33, 18, 22, -88, -71, 26, 81, 14, -37, 3, -24, 6, -8, 11, 40, 18, -7, -17, 20, -8, -15, -41, -11, 27, 52, -27, -46, 33, 21, 46, -30, -13, 26, -91, -106, -47, 54, 109, 67, -87, -90, 38, 92, 31, -10, -69, -73, -27, -6, 24, -6, 20, 30, 45, 33, -13, -25, 10, 57, -16, -32, 0, -14, -55, -20, 4, 7, -4, 3, 18, -11, 34, 11, -45, -45, -125, -38, -2, 19, 72, 82, 99, 98, 35, -51, -81, -53, 3, -39, 23, -4, -58, -63, -24, 40, 84, 48, -7, -18, -2, -8, -20, -10, 3, 21, 17, -39, -66, -20, -2, 37, 30, 39, 34, -5, -41, -26, 33, 40, 18, -2, 11, 13, -20, -60, -21, 33, -25, -35, 30, 65, 22, 13, -15, 2, 16, 11, -68, -18, 74, 10, -74, -34, -39, -17, 8, 59, 39, -22, -38, -8, 9, 30, 23, 11, -3, -12, 10, -1, 59, 9, -28, -72, -27, 32, 68, -11, -3, 27, 4, -33, -39, 7, -1, -5, -7, 26, -14, -26, -40, -12, 5, 5, 1, -12, 64, 63, -41, -56, 10, 26, 40, -26, -44, -42, 25, -6, 3, -1, 10, 9, -1, 9, 1, -28, 10, 24, 26, -33, -36, 46, 20, -43, -52, -35, 22, 53, 30, -6, 18, -16, -49, -36, 45, 10, 21, 7, 9, -33, -50, 21, 73, 33, -42, -46, 42, -12, -18, 5, -50, -25, 68, 55, -31, -79, -7, 77, 25, -6, 29, 78, 24, -87, -41, -30, -41, -23, 75, 35, -32, -65, -7, -13, 3, 41, 34, -24, -33, 25, 14, -52, -28, 19, 76, 45, -45, -47, -5, 24, 9, -14, -41, -5, 49, 22, 10, -31, -35, -1, -6, 3, 10, -1, -12, -20, -51, 9, 79, 53, -36, -38, -13, -14, -15, 50, 50, -36, -33, 0, 5, 22, 23, 24, -51, -81, -27, 56, 42, -10, -16, 0, 0, -5, 16, 12, -19, 11, 10, -15, -1, -32, -17, 1, 11, 62, -16, -21, 9, 21, -29, -50, 16, 82, 17, -35, -4, 11, 3, 8, 8, -9, -13, 10, -39, -63, -19, 54, 58, -16, -25, 18, 38, -8, -50, -54, -17, 18, 47, 17, -33, -45, 0, 52, 57, -5, -34, -17, 32, 10, -28, -10, -21, -3, -9, -20, 20, 47, 22, 5, -4, -15, -37, -22, -28, 9, 37, -18, -13, 3, 15, -33, -47, 20, 73, 0, -36, 33, 60, -11, -77, -13, 42, 13, -20, 9, 47, 22, -27, 29, 6, -71, -78, -20, 21, 4, 27, 23, 19, 31, 45, -29, -54, -10, 37, -78, -46, -14, 67, 108, 57, 12, -62, -108, -15, 116, 56, -58, -110, -33, 33, 30, -39, -26, 11, 29, 22, 8, 52, 76, 31, 0, -31, -50, -10, 59, 54, -13, -84, -65, -60, 0, 35, 105, 61, -30, -117, -62, 35, 88, 57, 48, -38, -85, 41, 12, -21, -6, 7, 15, 73, -30, -72, -37, 25, 0, -5, 65, 76, -90, -78, 24, 47, 2, -14, 40, 83, 0, -32, -46, -62, -26, 50, 37, -4, -44, -40, 55, 31, -38, -13, -17, -30, -4, 7, 68, 39, 1, -23, -38, -30, 6, -35, 14, 52, -9, -62, -47, 45, 44, 11, -17, -9, 6, 16, 34, -3, -32, -21, -33, -3, 21, 26, -39, 11, 65, 33, 19, -1, -49, -85, -97, 66, 58, -93, -15, 15, 5, 81, 76, 29, -2, -52, -51, -30, 65, 38, -45, -14, 1, 28, 22, 43, 19, -59, -109, -29, 29, -14, -22, -41, 0, 54, 76, 16, 8, 23, 15, -47, -39, -8, 5, 36, -6, -3, -4, 13, 13, 21, -47, -53, -6, -9, -27, -44, 8, 86, 64, 12, -5, -32, -10, -20, -27, -23, 8, 30, 1, 16, 42, -35, -8, 4, -39, -11, -62, -29, 108, 87, -20, -104, -18, -55, 8, 47, -16, 29, 38, 4, -44, -39, -20, 38, -13, 23, 82, 30, -67, -93, 26, 79, 20, -79, -74, -23, 33, 59, 80, 39, -42, -100, 0, 19, 38, 9, -55, 9, -15, 22, 68, -17, -55, -23, 1, 87, 19, -56, -60, 32, 37, 38, -67, -33, -1, 31, 24, 15, -30, -5, -36, -29, -27, 8, 27, -9, 12, 29, 38, 33, 0, -39, -18, 6, 19, 18, 8, 1, -33, 9, -1, 2, -29, -66, 0, 41, 6, -50, -13, 9, 73, -28, -47, -21, 30, 68, 31, 32, 29, -46, -14, 13, -44, -75, -3, 62, 55, 9, -49, -1, 54, 19, -6, 7, 16, 38, 13, -26, -55, -76, -23, 16, 21, -33, -22, 16, 61, 25, -14, -35, 12, 23, -7, -17, -32, -10, -16, -1, 7, 18, -1, 19, -2, -1, 21, -14, 1, -44, -44, -23, -29, -1, 28, -28, 47, 64, 12, -4, -15, -37, -7, 24, 50, 6, -15, -26, -5, 20, 12, -25, -21, -2, -18, -23, 9, 16, 24, 36, -30, -35, -12, 32, 19, -13, 19, -6, 2, -2, -22, -11, 14, 50, 10, -21, -55, -14, 23, 6, 6, -6, -26, -25, -8, 25, 14, 24, 14, -13, 18, 11, 23, -34, -49, -45, 6, 39, 37, 3, 0, -29, 8, 26, -6, -7, -21, 2, -11, 6, 16, -1, -17, 6, 32, -4, -54, -9, 22, -14, 6, 27, -1, -2, 34, 33, 8, 1, -8, -14, -32, 23, -22, -23, -29, -12, 5, 25, 22, -4, 14, 5, 24, -39, -29, 17, -21, -80, -60, -9, 78, 99, 81, -41, -53, 22, 11, -69, -22, -2, 70, 80, 18, -56, -54, -79, -27, 56, 46, 28, -1, 12, -37, -76, 23, 64, -4, -5, 4, 0, -2, -5, 10, -4, -9, 5, 3, 3, -2, 6, -2, -1, 0, 2, 0, 1, -2, 2, -3, -2, 0, 1, -1, 0, 0, -1, -1, -1, 0, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -2, -3, -5, -6, -5, -5, -3, 0, -1, -3, -1, 7, 16, 20, 8, -8, -24, -35, -39, -36, -35, -42, -47, -35, -14, 0, 8, 17, 28, 45, 60, 65, 64, 66, 67, 60, 50, 39, 26, 14, 5, -14, -40, -54, -56, -56, -55, -47, -36, -20, 1, 13, 15, 16, 12, 2, -10, -20, -33, -43, -42, -38, -43, -40, -28, -17, -7, 6, 21, 34, 48, 60, 63, 64, 66, 61, 54, 51, 41, 23, 10, 1, -18, -37, -46, -54, -63, -60, -46, -30, -13, 5, 15, 16, 17, 11, -2, -11, -21, -34, -44, -45, -43, -42, -33, -21, -17, -10, 5, 23, 39, 54, 62, 61, 62, 63, 59, 53, 47, 38, 23, 10, -5, -23, -36, -42, -51, -61, -61, -48, -26, -2, 14, 16, 13, 13, 9, -1, -14, -27, -36, -42, -44, -48, -44, -31, -17, -10, -8, 1, 21, 47, 65, 67, 58, 54, 58, 61, 54, 41, 31, 23, 11, -9, -30, -41, -44, -45, -54, -61, -52, -21, 11, 25, 19, 8, 4, 7, 2, -15, -33, -39, -39, -44, -51, -48, -34, -12, -2, -4, -2, 19, 54, 74, 72, 58, 47, 51, 59, 54, 40, 26, 20, 7, -16, -37, -46, -44, -42, -51, -58, -47, -15, 19, 31, 25, 9, -1, -1, -4, -15, -30, -37, -41, -51, -55, -48, -28, -11, -4, -2, 6, 28, 58, 73, 74, 63, 50, 45, 46, 49, 42, 31, 19, -6, -30, -43, -44, -42, -51, -54, -49, -33, -3, 18, 30, 31, 17, 2, -13, -15, -15, -25, -31, -45, -62, -60, -45, -24, -16, -10, 6, 20, 40, 58, 68, 74, 69, 55, 41, 37, 44, 43, 34, 15, -17, -41, -48, -46, -51, -59, -51, -34, -16, 3, 17, 29, 33, 23, 2, -15, -18, -18, -22, -31, -50, -64, -61, -42, -30, -24, -8, 13, 35, 50, 57, 65, 70, 70, 58, 42, 40, 41, 40, 32, 6, -23, -45, -53, -55, -64, -60, -45, -24, -1, 10, 19, 27, 28, 23, 4, -9, -17, -22, -23, -36, -53, -61, -60, -47, -36, -22, -3, 19, 44, 56, 60, 65, 65, 65, 60, 52, 45, 39, 37, 23, -2, -26, -49, -63, -66, -63, -55, -42, -16, 3, 14, 25, 25, 22, 19, 11, -2, -17, -20, -29, -44, -50, -58, -64, -53, -32, -13, 0, 25, 45, 53, 65, 68, 61, 60, 63, 60, 47, 42, 33, 7, -10, -26, -56, -73, -68, -57, -53, -37, -12, -1, 14, 32, 26, 16, 17, 16, 1, -12, -19, -38, -52, -47, -55, -65, -50, -23, -9, 4, 27, 40, 48, 68, 72, 59, 58, 67, 64, 52, 42, 21, -5, -16, -31, -60, -73, -62, -54, -49, -34, -17, -4, 17, 32, 24, 13, 18, 20, 6, -11, -29, -46, -48, -46, -54, -59, -41, -17, -5, 6, 20, 35, 54, 71, 68, 55, 60, 74, 71, 53, 27, 5, -6, -16, -35, -62, -70, -57, -49, -45, -40, -25, 4, 25, 29, 15, 7, 23, 27, 10, -20, -46, -47, -41, -39, -47, -55, -34, -11, -1, 4, 11, 38, 67, 72, 62, 48, 61, 83, 76, 49, 9, -9, -7, -15, -31, -59, -70, -55, -48, -46, -43, -21, 16, 29, 22, 6, 1, 25, 32, 10, -28, -57, -47, -34, -30, -38, -49, -33, -12, -4, 3, 17, 50, 72, 68, 55, 44, 61, 86, 77, 41, -2, -16, -10, -13, -28, -56, -69, -58, -52, -47, -35, -7, 22, 25, 13, -4, -2, 25, 33, 7, -35, -58, -46, -29, -22, -32, -44, -34, -16, -5, 8, 30, 59, 72, 65, 46, 39, 62, 87, 76, 33, -8, -20, -13, -10, -28, -57, -70, -62, -51, -42, -24, 3, 23, 23, 4, -15, -4, 25, 34, 3, -38, -55, -45, -23, -17, -32, -43, -34, -15, -1, 14, 41, 64, 73, 59, 35, 35, 64, 89, 73, 26, -11, -23, -14, -11, -33, -60, -69, -59, -48, -39, -14, 11, 25, 17, -11, -24, -3, 30, 35, -3, -40, -54, -41, -18, -19, -36, -41, -28, -10, 0, 21, 51, 70, 71, 47, 24, 36, 72, 93, 65, 17, -14, -22, -13, -17, -43, -62, -63, -52, -48, -36, -5, 19, 26, 5, -26, -27, 5, 40, 31, -12, -42, -50, -34, -20, -28, -37, -33, -17, -8, -1, 29, 61, 75, 64, 31, 19, 44, 85, 93, 51, 9, -15, -18, -16, -30, -50, -57, -52, -48, -52, -32, 3, 25, 20, -10, -34, -21, 19, 42, 20, -17, -40, -43, -35, -30, -32, -32, -21, -12, -12, 3, 37, 67, 72, 50, 25, 24, 57, 92, 81, 42, 6, -12, -18, -25, -39, -53, -52, -44, -49, -51, -28, 6, 25, 13, -17, -32, -11, 29, 39, 8, -24, -38, -37, -33, -36, -39, -30, -10, -3, -9, 3, 38, 68, 71, 46, 23, 32, 68, 92, 71, 31, 5, -7, -16, -31, -50, -55, -45, -37, -49, -53, -27, 8, 23, 8, -20, -24, 3, 34, 28, -6, -28, -32, -30, -35, -46, -43, -23, 0, 0, -10, 5, 41, 67, 65, 42, 30, 47, 77, 83, 52, 23, 10, 2, -16, -43, -60, -55, -38, -36, -53, -53, -25, 8, 19, 3, -14, -8, 17, 29, 9, -17, -24, -22, -26, -43, -53, -42, -14, 4, -3, -9, 10, 44, 63, 58, 43, 43, 63, 77, 64, 38, 24, 20, 7, -23, -52, -62, -49, -38, -45, -57, -49, -19, 6, 11, 2, -1, 12, 22, 13, -7, -18, -15, -17, -32, -50, -52, -32, -11, -4, -8, -3, 21, 44, 55, 53, 52, 63, 70, 64, 49, 35, 34, 24, 0, -29, -53, -54, -50, -51, -56, -57, -37, -17, -2, 7, 9, 20, 21, 12, 1, -13, -11, -13, -24, -36, -49, -40, -30, -22, -12, -9, 10, 25, 38, 51, 57, 70, 71, 62, 57, 44, 42, 34, 15, -4, -30, -42, -53, -65, -61, -61, -49, -35, -22, -2, 10, 25, 27, 15, 11, -1, -8, -14, -22, -27, -37, -37, -37, -40, -26, -14, -2, 10, 24, 42, 54, 68, 73, 65, 65, 60, 49, 36, 27, 15, -7, -25, -43, -63, -69, -65, -61, -54, -36, -13, 3, 18, 26, 23, 20, 16, 1, -16, -21, -20, -31, -37, -38, -40, -38, -25, -15, -7, 11, 34, 48, 56, 66, 71, 72, 73, 61, 43, 34, 29, 11, -14, -31, -46, -63, -69, -72, -69, -53, -28, -7, 3, 16, 27, 30, 28, 15, -3, -14, -19, -25, -39, -42, -37, -38, -35, -30, -19, -2, 18, 39, 47, 56, 69, 75, 78, 71, 60, 49, 35, 22, -1, -20, -32, -50, -65, -76, -75, -63, -49, -27, -9, 6, 22, 28, 31, 27, 16, 6, -13, -26, -36, -43, -41, -42, -42, -36, -27, -10, 2, 18, 38, 52, 64, 70, 73, 79, 76, 70, 50, 27, 11, -5, -21, -41, -62, -69, -72, -68, -61, -50, -26, -4, 13, 21, 23, 32, 35, 27, 6, -21, -33, -37, -42, -48, -53, -45, -31, -19, -8, 3, 23, 45, 59, 65, 65, 73, 88, 88, 69, 40, 19, 10, -6, -30, -54, -69, -69, -68, -67, -59, -43, -18, 2, 10, 15, 22, 39, 46, 27, -3, -28, -34, -37, -48, -56, -60, -48, -29, -16, -1, 14, 35, 52, 58, 60, 64, 80, 96, 88, 64, 34, 16, 6, -11, -36, -62, -77, -75, -68, -58, -47, -33, -14, -1, 7, 15, 28, 43, 44, 24, -6, -30, -38, -40, -49, -63, -68, -56, -30, -5, 15, 27, 40, 51, 59, 63, 72, 84, 91, 83, 60, 32, 12, 1, -14, -45, -73, -84, -78, -62, -46, -36, -28, -17, 0, 11, 20, 31, 38, 35, 20, -6, -28, -40, -46, -58, -72, -71, -52, -26, 4, 26, 37, 45, 54, 64, 69, 74, 81, 80, 73, 59, 35, 13, -5, -28, -54, -75, -79, -74, -63, -43, -30, -21, -11, 0, 14, 23, 29, 33, 23, 14, -2, -25, -41, -58, -69, -71, -64, -43, -24, 3, 33, 47, 56, 60, 64, 73, 74, 75, 73, 62, 56, 38, 13, -12, -42, -57, -69, -77, -71, -63, -44, -25, -15, -3, 2, 13, 26, 23, 24, 19, 8, -2, -24, -44, -64, -74, -64, -60, -45, -16, 9, 34, 53, 63, 68, 66, 75, 73, 63, 66, 62, 49, 34, 11, -17, -43, -54, -66, -82, -72, -52, -43, -28, -10, 0, 4, 18, 27, 16, 13, 20, 8, -11, -26, -47, -66, -63, -59, -63, -47, -7, 20, 34, 56, 69, 65, 73, 81, 67, 54, 61, 63, 44, 25, 6, -23, -37, -44, -69, -85, -69, -48, -39, -26, -7, -4, 5, 27, 25, 9, 10, 15, 5, -17, -34, -52, -62, -54, -54, -60, -40, -5, 21, 41, 59, 67, 66, 78, 81, 64, 53, 58, 56, 39, 18, -3, -24, -34, -45, -64, -76, -67, -51, -37, -21, -8, -3, 11, 22, 20, 11, 9, 11, -4, -23, -38, -56, -57, -53, -50, -42, -31, -5, 21, 41, 63, 67, 72, 77, 69, 67, 58, 56, 49, 28, 16, -8, -28, -35, -50, -53, -62, -65, -53, -44, -20, -2, 2, 14, 10, 14, 17, 7, 5, -13, -27, -37, -60, -58, -55, -42, -22, -18, -2, 13, 36, 69, 73, 76, 71, 62, 70, 60, 53, 42, 23, 16, -13, -35, -45, -51, -40, -46, -58, -60, -52, -17, 4, 8, 11, 5, 14, 15, 4, -4, -20, -23, -37, -62, -67, -59, -27, -2, -3, -3, 3, 36, 70, 77, 75, 66, 67, 70, 57, 46, 32, 29, 19, -17, -49, -62, -46, -25, -33, -54, -68, -51, -15, 4, 8, 6, 11, 18, 8, -7, -19, -16, -12, -35, -68, -83, -56, -9, 13, 7, -7, 4, 40, 66, 73, 69, 73, 80, 69, 46, 27, 31, 42, 24, -23, -68, -69, -36, -14, -25, -57, -66, -43, -16, -3, -2, 11, 28, 23, -2, -31, -29, -4, -1, -34, -83, -89, -45, 3, 22, 6, -3, 16, 41, 56, 55, 68, 93, 93, 65, 23, 12, 38, 53, 27, -38, -80, -64, -29, -12, -31, -54, -49, -34, -22, -24, -11, 28, 47, 25, -24, -51, -27, 5, 5, -43, -90, -79, -34, 6, 11, 4, 17, 31, 39, 34, 38, 79, 114, 105, 50, 3, 12, 44, 56, 16, -49, -72, -54, -28, -29, -44, -37, -27, -28, -41, -45, -5, 46, 61, 17, -44, -53, -20, 7, -6, -53, -78, -62, -27, -7, -6, 14, 41, 45, 26, 11, 38, 93, 127, 101, 34, 1, 20, 48, 42, -1, -41, -53, -45, -40, -51, -44, -18, -9, -34, -61, -47, 7, 57, 58, 2, -46, -43, -14, -5, -27, -52, -58, -46, -31, -26, -12, 28, 59, 45, 10, 6, 50, 104, 124, 87, 30, 11, 30, 40, 19, -9, -26, -35, -44, -58, -62, -38, -4, -6, -46, -67, -37, 21, 56, 43, -4, -37, -30, -15, -25, -40, -44, -38, -38, -43, -38, -9, 40, 64, 37, 5, 14, 65, 106, 107, 75, 36, 26, 34, 24, 4, -8, -10, -24, -53, -70, -64, -30, 0, -16, -53, -61, -22, 28, 43, 29, -2, -21, -20, -26, -39, -43, -34, -26, -43, -54, -40, 0, 46, 56, 30, 12, 30, 75, 97, 90, 69, 47, 38, 29, 13, 2, 0, -1, -27, -61, -71, -55, -25, -14, -32, -50, -41, -6, 22, 25, 17, 4, -8, -19, -31, -38, -35, -28, -35, -53, -54, -29, 7, 31, 32, 23, 28, 51, 72, 78, 72, 65, 55, 42, 30, 19, 15, 11, -8, -36, -58, -58, -42, -35, -35, -43, -40, -18, 0, 12, 14, 11, 9, -4, -15, -25, -31, -28, -36, -49, -53, -45, -18, 1, 12, 19, 23, 43, 58, 64, 68, 64, 64, 57, 46, 40, 28, 22, 9, -17, -35, -48, -47, -44, -47, -45, -44, -31, -12, -2, 7, 10, 9, 7, -2, -8, -19, -28, -32, -44, -51, -48, -37, -21, -9, 5, 16, 26, 43, 55, 60, 64, 63, 61, 58, 55, 48, 34, 21, 6, -13, -27, -39, -49, -53, -50, -46, -41, -32, -16, -3, 5, 11, 9, 6, 5, -4, -17, -32, -40, -42, -44, -42, -40, -32, -12, 5, 17, 24, 35, 50, 58, 64, 64, 60, 65, 61, 50, 34, 18, 10, -2, -18, -38, -58, -56, -49, -45, -41, -38, -22, -4, 8, 14, 8, 11, 10, -5, -20, -38, -41, -36, -37, -40, -48, -37, -12, 4, 14, 19, 27, 46, 59, 66, 63, 62, 70, 64, 50, 34, 22, 17, 8, -11, -38, -59, -57, -50, -49, -47, -43, -28, -6, 10, 16, 10, 14, 8, 1, -5, -5, -4, -5, 5, 2, 2, 1, -1, 0, 1, 0, 2, 0, 0, -2, -1, -1, 2, 1, 1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 1, 0, 0, 0, 1, 0, 1, 0, -3, -10, -11, -8, -13, -25, -21, -10, 0, 2, 18, 41, 44, 42, 66, 62, 28, 10, 17, 17, -16, -10, 25, 28, 29, 34, 47, 34, -7, 7, 25, -12, -43, -44, -40, -61, -85, -78, -55, -42, -33, -10, 17, 31, 43, 59, 51, 25, 25, 40, 27, -1, 2, 25, 30, 15, 12, 27, 26, 13, 16, 9, -24, -43, -37, -49, -83, -92, -62, -40, -42, -36, 1, 33, 34, 45, 61, 46, 27, 32, 33, 10, -6, 15, 38, 26, 4, 15, 35, 19, 7, 17, 3, -26, -41, -50, -67, -91, -82, -48, -40, -46, -24, 18, 33, 32, 54, 62, 46, 30, 22, 20, 7, 4, 28, 33, 15, 10, 22, 25, 9, 13, 18, -2, -29, -54, -65, -74, -86, -68, -49, -46, -32, -8, 17, 29, 45, 65, 60, 43, 23, 13, 17, 12, 18, 28, 22, 19, 16, 13, 14, 16, 24, 13, -13, -40, -66, -72, -75, -74, -64, -55, -36, -20, -9, 15, 43, 63, 65, 51, 37, 17, 9, 19, 23, 21, 19, 24, 21, 3, 4, 24, 31, 18, -2, -20, -49, -77, -74, -65, -71, -69, -47, -27, -27, -10, 38, 66, 59, 52, 51, 34, 4, 11, 36, 26, 12, 22, 26, 2, -11, 25, 45, 18, 0, -1, -23, -72, -83, -55, -65, -83, -61, -34, -37, -36, 23, 71, 55, 43, 60, 55, 11, 1, 40, 37, 8, 16, 31, 6, -22, 14, 55, 27, -3, 8, 2, -52, -83, -57, -56, -89, -79, -43, -43, -55, -4, 66, 61, 35, 56, 68, 31, 4, 32, 46, 13, 7, 31, 16, -24, -4, 50, 42, 2, 7, 16, -25, -67, -60, -54, -86, -95, -55, -44, -63, -32, 40, 62, 40, 47, 67, 48, 22, 32, 42, 18, 4, 25, 25, -15, -16, 29, 44, 21, 11, 15, -5, -39, -49, -59, -85, -96, -72, -52, -62, -50, 7, 45, 49, 50, 56, 56, 43, 42, 39, 19, 9, 16, 21, 1, -16, 9, 32, 31, 24, 14, 5, -14, -34, -52, -81, -94, -85, -71, -62, -55, -21, 21, 41, 53, 55, 55, 57, 51, 44, 26, 13, 15, 11, 3, -3, 0, 19, 27, 29, 26, 11, 0, -16, -41, -70, -90, -88, -85, -80, -57, -34, -3, 26, 42, 57, 57, 60, 64, 50, 33, 20, 17, 9, -6, -1, 6, 10, 23, 26, 28, 22, 10, 1, -27, -60, -78, -87, -90, -94, -74, -42, -20, 10, 34, 44, 57, 65, 71, 58, 35, 30, 23, 8, -5, -7, 4, 7, 19, 33, 23, 19, 24, 17, -13, -53, -65, -75, -96, -98, -83, -61, -40, -7, 32, 38, 38, 66, 83, 65, 36, 36, 37, 8, -7, 1, 0, -5, 11, 39, 34, 10, 21, 36, 4, -45, -59, -59, -89, -106, -84, -67, -62, -32, 21, 41, 30, 47, 85, 80, 41, 34, 45, 20, -8, 0, 9, -7, -6, 31, 45, 21, 12, 32, 25, -27, -55, -52, -76, -104, -95, -70, -64, -57, -7, 33, 34, 38, 67, 84, 57, 35, 46, 29, -1, -4, 7, 7, -8, 12, 41, 31, 21, 24, 25, -5, -43, -45, -65, -98, -98, -82, -62, -58, -35, 13, 27, 38, 59, 70, 67, 45, 49, 39, 2, -3, 2, 9, 9, 6, 30, 30, 24, 31, 20, 3, -26, -37, -48, -91, -100, -88, -75, -53, -41, -9, 12, 23, 55, 65, 61, 54, 51, 51, 14, -6, 1, 1, 15, 18, 26, 29, 16, 30, 28, 4, -14, -29, -36, -71, -100, -93, -87, -64, -38, -16, 2, 6, 33, 61, 59, 56, 54, 55, 32, 1, -3, -4, 5, 25, 36, 36, 17, 14, 25, 14, -4, -19, -30, -53, -84, -94, -95, -82, -49, -16, 4, 2, 10, 37, 56, 61, 58, 54, 42, 19, 3, -9, -8, 14, 41, 53, 32, 10, 7, 10, 10, -7, -25, -43, -65, -81, -97, -99, -72, -29, 9, 11, 3, 10, 33, 61, 65, 55, 46, 30, 19, 0, -17, -5, 29, 62, 57, 24, -1, -6, 10, 8, -16, -35, -54, -64, -80, -105, -99, -57, -2, 26, 13, -2, 6, 42, 67, 60, 49, 36, 31, 22, -10, -24, 1, 49, 77, 53, 9, -14, -4, 10, -4, -26, -47, -56, -58, -89, -115, -93, -34, 23, 33, 6, -6, 16, 50, 62, 53, 39, 34, 40, 16, -24, -26, 15, 71, 82, 38, -5, -13, -1, 3, -13, -39, -53, -48, -61, -103, -119, -80, -6, 42, 27, -1, 2, 26, 51, 56, 43, 33, 43, 42, 4, -34, -23, 37, 87, 70, 20, -6, -10, -3, -5, -27, -49, -48, -44, -72, -115, -118, -56, 22, 43, 17, 3, 12, 33, 51, 45, 34, 38, 51, 38, -11, -42, -9, 59, 86, 53, 13, -5, -5, -3, -19, -42, -50, -43, -45, -85, -127, -105, -28, 34, 37, 15, 8, 23, 41, 42, 34, 33, 45, 55, 26, -27, -38, 12, 69, 77, 40, 9, 1, 0, -13, -33, -48, -49, -39, -55, -102, -124, -83, -8, 37, 31, 14, 19, 35, 39, 34, 30, 35, 51, 50, 9, -31, -25, 27, 72, 65, 30, 12, 9, -2, -23, -42, -52, -46, -43, -71, -109, -112, -63, 7, 36, 25, 20, 33, 42, 35, 29, 29, 40, 52, 35, -2, -28, -12, 40, 69, 51, 26, 18, 13, -8, -33, -48, -50, -46, -57, -84, -107, -98, -43, 14, 29, 24, 30, 44, 43, 30, 26, 34, 44, 40, 19, -8, -20, 4, 46, 59, 42, 29, 25, 10, -18, -40, -46, -47, -57, -73, -91, -100, -78, -30, 13, 25, 30, 44, 48, 39, 29, 31, 41, 35, 23, 9, -9, -5, 16, 43, 52, 40, 37, 25, 0, -23, -41, -43, -54, -74, -82, -93, -86, -60, -26, 12, 26, 41, 53, 44, 40, 33, 36, 38, 19, 12, 2, -3, 9, 18, 40, 48, 42, 41, 16, -6, -23, -41, -45, -68, -84, -86, -90, -71, -52, -22, 15, 32, 52, 54, 45, 45, 36, 36, 25, 6, 6, 0, 5, 15, 21, 41, 46, 46, 37, 10, -7, -24, -42, -57, -81, -88, -88, -83, -62, -43, -14, 16, 41, 59, 55, 48, 48, 40, 27, 10, 2, 2, 0, 8, 22, 30, 36, 45, 50, 32, 5, -9, -23, -48, -75, -86, -86, -88, -81, -54, -26, -11, 16, 52, 65, 55, 50, 53, 39, 9, -2, 4, 2, -4, 11, 36, 34, 27, 47, 51, 26, 0, -9, -23, -63, -91, -85, -81, -89, -79, -38, -13, -11, 23, 62, 67, 55, 52, 56, 29, -8, -7, 7, 0, -5, 19, 44, 30, 28, 49, 46, 21, -2, -10, -32, -79, -96, -83, -81, -87, -67, -27, -11, 0, 36, 65, 67, 58, 54, 48, 14, -15, -7, 3, 1, 6, 26, 35, 30, 38, 46, 37, 18, -2, -18, -48, -85, -96, -89, -81, -70, -52, -30, -8, 20, 48, 63, 66, 59, 50, 33, 6, -14, -15, -2, 13, 20, 21, 25, 36, 45, 42, 31, 12, -10, -31, -56, -84, -103, -96, -70, -50, -43, -31, 0, 35, 58, 68, 65, 51, 37, 26, 8, -19, -25, 2, 27, 27, 17, 20, 36, 45, 45, 29, 0, -27, -41, -55, -87, -111, -93, -57, -37, -33, -23, 5, 41, 70, 77, 59, 36, 26, 24, 4, -24, -22, 7, 31, 33, 19, 14, 29, 49, 50, 22, -16, -39, -48, -63, -92, -104, -86, -51, -25, -19, -16, 10, 53, 82, 74, 47, 26, 19, 16, -1, -18, -16, 7, 35, 37, 18, 10, 31, 55, 41, 4, -25, -45, -57, -73, -90, -95, -82, -42, -9, -8, -11, 20, 71, 84, 57, 39, 27, 13, 2, -6, -9, -12, 8, 45, 41, 8, 5, 42, 56, 20, -10, -24, -50, -73, -83, -83, -87, -76, -25, 10, -5, -9, 39, 84, 71, 44, 38, 26, 2, -9, -2, -4, -11, 17, 52, 36, 0, 11, 50, 43, 3, -19, -31, -57, -84, -84, -77, -82, -59, -9, 14, 1, 7, 55, 81, 61, 38, 29, 20, -2, -10, -1, -4, 0, 26, 42, 30, 8, 20, 41, 28, -4, -31, -46, -64, -84, -82, -79, -66, -37, -7, 15, 18, 30, 58, 68, 57, 33, 17, 9, 0, -3, -7, 0, 15, 23, 31, 29, 23, 24, 22, 14, -12, -43, -63, -72, -73, -83, -75, -47, -26, -2, 20, 37, 48, 50, 57, 52, 30, 6, -1, 11, 0, -9, 7, 16, 24, 28, 32, 33, 15, 7, 2, -21, -55, -79, -66, -67, -81, -63, -38, -12, 9, 29, 53, 48, 42, 51, 47, 22, -6, 5, 18, -4, -7, 6, 22, 28, 26, 39, 28, 2, -2, -8, -35, -73, -76, -56, -67, -77, -55, -20, 4, 16, 40, 54, 42, 41, 51, 37, 7, 0, 17, 13, -12, -9, 20, 31, 25, 29, 33, 15, -5, -8, -22, -57, -74, -62, -57, -74, -71, -33, 0, 11, 26, 44, 45, 41, 47, 45, 22, 3, 12, 19, 0, -15, 4, 30, 32, 27, 26, 17, 3, -4, -14, -44, -69, -66, -56, -63, -74, -52, -11, 12, 21, 29, 35, 41, 49, 51, 31, 9, 11, 19, 11, -8, -7, 20, 36, 34, 22, 10, 6, 5, -4, -33, -64, -66, -58, -58, -67, -63, -29, 4, 20, 21, 21, 35, 52, 57, 39, 12, 10, 18, 16, 3, -7, 8, 31, 39, 25, 5, 3, 10, 5, -22, -58, -67, -58, -56, -60, -64, -45, -11, 15, 19, 12, 24, 50, 62, 46, 17, 9, 18, 20, 12, 0, 2, 21, 37, 31, 7, 0, 11, 14, -12, -51, -66, -58, -53, -54, -59, -54, -29, 3, 16, 9, 17, 44, 62, 51, 22, 8, 17, 24, 21, 9, 1, 11, 30, 31, 14, 3, 11, 16, -4, -43, -65, -58, -49, -50, -53, -55, -43, -16, 5, 10, 16, 38, 59, 54, 26, 7, 18, 29, 24, 18, 8, 5, 16, 27, 23, 11, 14, 18, -1, -36, -63, -56, -43, -48, -47, -49, -52, -36, -12, 8, 17, 35, 55, 50, 28, 9, 17, 33, 25, 24, 20, 5, 4, 15, 27, 23, 20, 22, 0, -32, -58, -55, -40, -47, -44, -39, -52, -54, -34, -2, 19, 35, 53, 46, 27, 12, 18, 34, 26, 26, 33, 13, -6, 0, 22, 34, 32, 28, 3, -31, -53, -51, -39, -47, -45, -30, -45, -66, -56, -19, 15, 38, 52, 43, 22, 13, 22, 35, 26, 26, 41, 25, -7, -13, 10, 35, 46, 39, 10, -29, -50, -46, -37, -47, -46, -27, -35, -65, -72, -42, 2, 38, 55, 43, 19, 11, 24, 36, 27, 26, 43, 37, 2, -19, -6, 25, 53, 56, 20, -24, -46, -43, -36, -46, -48, -29, -28, -56, -77, -64, -22, 31, 61, 45, 16, 10, 23, 35, 30, 26, 41, 42, 16, -14, -21, 7, 51, 70, 36, -15, -38, -40, -35, -42, -49, -35, -29, -44, -71, -81, -49, 14, 60, 50, 18, 10, 21, 34, 34, 26, 37, 43, 30, 0, -27, -13, 37, 74, 54, 2, -29, -35, -32, -37, -49, -42, -32, -36, -57, -85, -73, -12, 46, 57, 27, 9, 17, 32, 38, 28, 30, 41, 39, 18, -20, -27, 15, 62, 68, 26, -17, -30, -28, -29, -45, -51, -40, -34, -45, -77, -86, -42, 18, 54, 43, 14, 12, 29, 42, 34, 25, 33, 41, 30, -2, -24, -5, 36, 65, 50, 3, -24, -24, -19, -33, -54, -52, -42, -45, -61, -75, -58, -15, 32, 48, 25, 10, 24, 45, 45, 27, 26, 32, 28, 13, -4, -6, 14, 44, 55, 24, -11, -18, -12, -20, -46, -57, -53, -54, -57, -63, -57, -33, 4, 35, 32, 16, 22, 40, 49, 36, 26, 28, 23, 17, 8, 1, 10, 27, 43, 33, 5, -6, -8, -14, -33, -53, -57, -61, -62, -61, -59, -38, -10, 15, 26, 20, 26, 40, 44, 41, 30, 27, 25, 18, 12, 3, 9, 26, 33, 28, 13, 5, 5, -8, -25, -45, -57, -60, -64, -66, -65, -49, -17, 6, 13, 16, 26, 43, 47, 39, 32, 27, 27, 25, 13, 3, 6, 22, 35, 26, 13, 10, 12, 5, -17, -40, -54, -58, -58, -68, -74, -61, -31, -1, 9, 10, 23, 40, 50, 45, 31, 24, 27, 31, 20, 3, 2, 17, 32, 31, 16, 12, 15, 12, -4, -31, -51, -55, -54, -62, -76, -73, -47, -17, 2, 8, 19, 37, 51, 50, 34, 24, 26, 31, 25, 9, 4, 13, 26, 34, 25, 9, 13, 20, -2, -33, -44, -43, -58, -78, -77, -59, -44, -33, -10, 17, 6, 12, -9, 32, 13, 4, -4, 6, -9, 27, 8, 2, -1, -3, -2, 3, -4, -3, 2, 0, -2, 1, -2, 1, -4, 2, 1, 0, -2, -1, -3, 2, 0, -1, -2, -2, -2, -1, -2, -2, -1, -2, -2, -2, -2, -1, -2, -1, 0, -1, -2, -2, -2, -1, 0, -2, -2, -2, -2, -1, -1, -2, -1, -2, -2, -2, -3, -1, -1, 0, 0, -1, -3, -2, 1, 3, 0, 0, -2, -8, -21, -17, -2, 12, 20, 19, 6, -13, -28, -73, -67, -64, -58, -39, -11, 19, 38, 60, 96, 80, 38, 12, 6, -20, -65, -83, -65, -61, -56, -17, 22, 35, 49, 74, 94, 55, 16, 20, -5, -52, -89, -81, -53, -65, -36, 21, 37, 48, 51, 85, 82, 25, 23, 9, -36, -80, -105, -58, -57, -54, 7, 36, 54, 44, 58, 97, 48, 26, 16, -21, -61, -115, -83, -45, -57, -12, 23, 57, 54, 36, 86, 77, 37, 21, -16, -40, -103, -110, -54, -46, -24, 6, 43, 68, 36, 62, 86, 60, 30, -12, -34, -80, -119, -76, -44, -24, -5, 24, 64, 51, 50, 76, 72, 48, 0, -34, -68, -106, -94, -56, -26, -7, 11, 45, 59, 58, 66, 71, 60, 23, -27, -68, -93, -93, -72, -37, -8, 10, 25, 50, 70, 68, 62, 62, 45, -10, -70, -88, -83, -79, -57, -15, 15, 13, 31, 73, 80, 59, 53, 61, 15, -67, -89, -73, -75, -75, -33, 21, 11, 10, 66, 92, 65, 42, 63, 42, -56, -92, -66, -66, -84, -57, 16, 19, -5, 50, 98, 76, 39, 56, 60, -35, -95, -64, -53, -84, -79, 0, 28, -8, 29, 96, 89, 42, 46, 69, -10, -90, -69, -41, -74, -95, -25, 28, -1, 13, 81, 101, 53, 37, 69, 11, -77, -75, -38, -53, -103, -55, 22, 8, 6, 61, 104, 75, 29, 59, 31, -61, -76, -43, -36, -91, -88, 6, 17, 1, 46, 96, 94, 34, 40, 48, -40, -80, -47, -27, -69, -107, -27, 26, 4, 29, 87, 105, 51, 24, 46, -10, -76, -58, -21, -49, -107, -62, 17, 16, 17, 70, 110, 67, 22, 38, 10, -60, -71, -24, -28, -97, -85, -6, 25, 18, 50, 106, 84, 28, 31, 16, -38, -71, -38, -17, -78, -94, -30, 15, 30, 41, 86, 92, 44, 31, 15, -25, -54, -53, -26, -57, -88, -51, -2, 33, 45, 68, 88, 59, 35, 17, -15, -42, -55, -41, -48, -73, -60, -19, 24, 50, 61, 74, 67, 46, 21, -8, -32, -48, -54, -53, -57, -57, -34, 9, 50, 63, 59, 65, 58, 29, -1, -24, -38, -62, -67, -48, -47, -40, -8, 43, 68, 48, 58, 66, 38, 6, -19, -26, -62, -85, -45, -35, -39, -21, 28, 72, 41, 47, 74, 45, 15, -14, -17, -53, -102, -50, -24, -36, -26, 10, 69, 42, 32, 81, 52, 21, -4, -15, -39, -109, -64, -12, -35, -26, -1, 54, 47, 21, 79, 65, 20, 7, -12, -33, -100, -82, -8, -27, -32, -2, 36, 47, 21, 66, 77, 25, 12, -2, -36, -88, -87, -18, -16, -36, -8, 27, 36, 30, 56, 77, 39, 12, 6, -33, -84, -79, -30, -11, -29, -20, 19, 27, 31, 58, 66, 50, 21, 5, -25, -81, -75, -32, -17, -17, -27, 2, 24, 28, 61, 61, 48, 35, 4, -22, -71, -77, -31, -19, -12, -23, -18, 16, 29, 59, 65, 45, 41, 10, -23, -59, -76, -37, -14, -11, -18, -29, -2, 29, 57, 68, 51, 37, 16, -21, -55, -67, -44, -12, -5, -21, -29, -19, 19, 59, 68, 61, 36, 14, -12, -55, -61, -44, -16, 3, -21, -29, -25, 0, 55, 72, 69, 43, 8, -6, -49, -63, -39, -18, 5, -15, -31, -26, -18, 39, 78, 75, 53, 8, -8, -40, -67, -37, -15, 2, -8, -30, -26, -29, 16, 79, 84, 59, 14, -11, -33, -66, -42, -9, -2, -6, -23, -26, -33, -7, 66, 94, 67, 22, -9, -32, -62, -48, -8, 0, -9, -16, -20, -35, -24, 46, 96, 78, 31, -2, -29, -59, -51, -13, 1, -10, -13, -9, -31, -35, 23, 86, 88, 42, 5, -22, -57, -53, -18, -3, -10, -13, 0, -19, -44, 2, 69, 90, 57, 12, -13, -50, -57, -21, -9, -13, -13, 1, -3, -41, -17, 51, 82, 69, 23, -9, -37, -57, -25, -12, -22, -15, 0, 10, -25, -32, 32, 69, 71, 37, -4, -25, -48, -30, -12, -32, -23, -3, 14, -2, -33, 11, 56, 63, 49, 3, -18, -32, -31, -13, -37, -38, -9, 11, 17, -16, -6, 41, 53, 51, 11, -17, -15, -23, -14, -35, -54, -22, 4, 26, 10, -10, 26, 43, 46, 19, -19, -6, -5, -10, -30, -65, -42, -9, 24, 35, 3, 12, 32, 37, 24, -20, -8, 14, 2, -23, -68, -62, -26, 10, 50, 28, 11, 22, 27, 24, -19, -19, 24, 21, -8, -63, -78, -45, -11, 47, 53, 23, 21, 19, 22, -17, -34, 21, 40, 15, -48, -89, -65, -34, 30, 68, 44, 27, 16, 16, -11, -47, 3, 49, 39, -22, -89, -82, -55, 3, 68, 61, 44, 21, 11, -6, -53, -21, 45, 56, 11, -74, -96, -72, -26, 52, 73, 60, 39, 10, -3, -48, -44, 27, 61, 42, -43, -101, -88, -52, 27, 73, 70, 59, 21, -1, -40, -60, 2, 52, 60, -4, -90, -100, -74, -2, 62, 72, 76, 42, 5, -30, -66, -22, 34, 63, 33, -62, -104, -92, -31, 44, 68, 84, 66, 21, -21, -64, -41, 13, 54, 55, -26, -94, -104, -57, 20, 56, 82, 84, 43, -6, -57, -54, -10, 36, 60, 7, -70, -107, -78, -6, 40, 73, 92, 66, 12, -45, -57, -27, 16, 52, 29, -41, -96, -90, -32, 20, 60, 91, 83, 34, -27, -52, -37, -3, 34, 36, -15, -77, -91, -52, -1, 43, 83, 93, 53, -5, -42, -40, -17, 14, 32, 1, -54, -81, -65, -21, 23, 71, 96, 67, 16, -25, -37, -24, -5, 21, 6, -36, -64, -69, -37, 3, 54, 93, 73, 35, -6, -28, -25, -19, 8, 4, -27, -46, -65, -46, -14, 34, 86, 73, 49, 15, -17, -19, -28, -4, -3, -28, -32, -56, -48, -24, 15, 74, 67, 55, 36, -2, -10, -28, -14, -9, -36, -25, -42, -50, -29, 1, 60, 59, 50, 55, 16, -3, -22, -20, -14, -46, -29, -28, -48, -33, -5, 47, 50, 40, 64, 40, 4, -14, -17, -19, -53, -40, -18, -40, -41, -6, 39, 39, 28, 61, 62, 17, -10, -7, -21, -59, -53, -20, -28, -47, -11, 38, 29, 15, 52, 77, 36, -6, 1, -12, -63, -66, -25, -20, -46, -19, 37, 28, 0, 38, 83, 54, 5, 5, -2, -57, -81, -34, -15, -44, -22, 29, 31, -4, 16, 85, 68, 17, 15, 1, -44, -87, -54, -8, -42, -27, 25, 24, 2, 0, 69, 88, 24, 25, 11, -42, -76, -75, -14, -25, -40, 23, 18, -3, 3, 42, 96, 45, 22, 29, -39, -70, -75, -40, -8, -39, 7, 24, -17, 8, 33, 79, 76, 22, 35, -21, -75, -64, -60, -15, -17, -14, 21, -21, -4, 40, 59, 88, 45, 24, -3, -71, -61, -59, -38, 1, -14, 0, -17, -18, 41, 54, 82, 74, 22, -3, -53, -61, -53, -54, -2, 3, -19, -25, -22, 30, 57, 73, 92, 38, -15, -40, -51, -50, -58, -17, 17, -23, -44, -22, 19, 55, 72, 97, 60, -22, -40, -35, -45, -55, -32, 14, -17, -60, -26, 11, 46, 75, 97, 78, -17, -46, -23, -38, -45, -37, -1, -14, -66, -31, 3, 34, 80, 98, 85, -4, -47, -19, -33, -33, -30, -20, -25, -63, -34, -4, 18, 79, 104, 84, 9, -38, -18, -29, -27, -14, -30, -46, -63, -32, -5, 3, 68, 111, 84, 18, -23, -12, -25, -28, -2, -25, -67, -75, -29, 1, -6, 46, 112, 91, 22, -11, 0, -18, -33, -1, -9, -76, -96, -34, 9, -8, 22, 101, 102, 27, -2, 14, -7, -36, -9, 4, -68, -114, -48, 13, -3, 5, 80, 109, 40, 4, 26, 6, -33, -18, 6, -52, -120, -67, 7, 4, -1, 55, 103, 58, 14, 31, 17, -21, -24, -4, -39, -110, -84, -10, 6, 2, 34, 87, 71, 29, 36, 25, -7, -23, -16, -33, -96, -90, -29, -1, 6, 22, 68, 75, 45, 45, 31, 4, -15, -24, -37, -84, -87, -43, -15, 3, 18, 53, 68, 57, 58, 38, 11, -7, -22, -45, -81, -79, -48, -29, -10, 17, 45, 57, 61, 71, 50, 17, 0, -15, -49, -85, -74, -45, -40, -25, 10, 42, 49, 55, 82, 65, 22, 7, -9, -43, -89, -80, -34, -47, -40, -1, 35, 52, 43, 85, 84, 25, 17, -4, -38, -85, -92, -28, -44, -55, -9, 21, 53, 42, 75, 100, 35, 22, 6, -38, -74, -99, -38, -34, -65, -18, 12, 42, 51, 63, 102, 52, 25, 21, -36, -70, -90, -56, -30, -64, -30, 7, 27, 55, 63, 90, 69, 33, 26, -26, -69, -79, -66, -43, -54, -37, -1, 17, 49, 69, 79, 72, 50, 30, -15, -61, -75, -68, -58, -52, -33, -12, 9, 42, 69, 78, 64, 60, 42, -9, -49, -71, -69, -68, -61, -25, -17, -1, 38, 64, 77, 59, 62, 58, -3, -37, -62, -72, -72, -73, -24, -12, -11, 35, 55, 73, 59, 58, 69, 8, -29, -48, -75, -76, -82, -31, -4, -14, 28, 49, 63, 61, 54, 73, 22, -21, -36, -71, -82, -88, -42, 0, -9, 21, 43, 53, 57, 56, 73, 33, -12, -25, -62, -89, -95, -49, -2, -2, 18, 37, 43, 49, 60, 75, 38, -2, -16, -49, -89, -105, -54, -7, 1, 19, 31, 37, 38, 59, 81, 39, 4, -7, -35, -83, -115, -62, -10, 0, 20, 27, 32, 30, 53, 87, 43, 4, 0, -24, -70, -118, -75, -12, -2, 19, 24, 27, 27, 45, 89, 52, 4, 1, -14, -55, -113, -87, -18, -3, 13, 20, 24, 28, 41, 85, 60, 7, -3, -9, -40, -100, -91, -28, -4, 7, 10, 21, 30, 43, 82, 62, 13, -8, -11, -26, -85, -87, -36, -10, 2, -4, 14, 35, 47, 81, 62, 18, -9, -21, -20, -65, -78, -38, -19, -4, -16, 0, 39, 54, 85, 65, 20, -7, -31, -24, -47, -62, -33, -26, -15, -25, -19, 35, 63, 90, 73, 22, -3, -39, -39, -35, -43, -20, -26, -30, -34, -36, 24, 71, 94, 85, 29, -3, -40, -58, -34, -24, -4, -16, -46, -47, -47, 6, 73, 100, 97, 42, -4, -39, -73, -45, -8, 12, 0, -51, -64, -56, -13, 66, 104, 106, 64, 2, -40, -82, -63, -3, 27, 18, -43, -82, -68, -28, 51, 104, 112, 86, 19, -42, -86, -81, -10, 40, 34, -26, -90, -86, -41, 31, 98, 116, 104, 46, -38, -92, -95, -25, 46, 48, -6, -84, -105, -55, 13, 84, 117, 114, 76, -20, -95, -105, -45, 41, 54, 8, -65, -112, -70, -1, 65, 109, 115, 100, 14, -85, -106, -62, 21, 50, 13, -44, -104, -84, -14, 45, 98, 112, 111, 53, -62, -105, -75, -3, 44, 12, -31, -85, -93, -27, 27, 82, 110, 110, 81, -27, -95, -81, -27, 31, 11, -31, -66, -90, -39, 12, 61, 106, 107, 94, 12, -73, -79, -48, 11, 13, -32, -57, -78, -46, -1, 38, 97, 109, 96, 43, -41, -69, -62, -13, 13, -30, -58, -68, -46, -11, 17, 81, 112, 97, 59, -7, -51, -67, -37, 6, -23, -62, -67, -42, -14, 2, 60, 110, 99, 65, 20, -24, -63, -56, -7, -15, -63, -75, -40, -12, -8, 39, 102, 103, 67, 35, 6, -48, -68, -25, -11, -56, -85, -46, -7, -10, 22, 86, 107, 72, 41, 29, -25, -70, -42, -14, -42, -91, -62, -5, -6, 9, 67, 105, 84, 40, 40, 3, -64, -56, -23, -30, -83, -85, -12, 3, 1, 50, 97, 96, 44, 36, 28, -45, -69, -33, -22, -67, -101, -34, 13, 2, 31, 88, 104, 56, 28, 37, -16, -71, -51, -18, -49, -103, -62, 9, 14, 18, 70, 109, 68, 26, 36, 6, -58, -68, -23, -28, -97, -84, -7, 23, 19, 50, 106, 84, 28, 31, -21, -26, -18, -30, -24, -77, -76, -48, -46, 31, 0, -1, 0, 0, 2, 0, 1, -2, 1, 0, -6, -7, -5, -3, 0, -3, -4, -2, 2, 0, -8, -11, -14, -10, -8, -4, 6, 13, 14, 9, 2, -6, -10, -9, -6, 9, 17, 15, 8, 0, 1, -4, -12, -19, -14, -8, -4, 3, 6, -2, -4, -6, -7, -10, -8, -12, -11, 3, 23, 27, 11, 4, -3, -5, 0, -9, -3, 6, 11, 19, 4, -8, -17, -20, -21, -3, 5, 8, 2, 3, 5, 2, -3, -3, -12, 4, 1, 3, -7, 0, 5, 6, 0, -7, -8, -5, -7, -5, -3, 4, 9, 5, -5, -5, -5, -17, -7, 3, 17, 15, 7, -2, -5, -3, 3, -8, -5, -3, 3, 8, 12, 5, -10, -27, -20, 1, 5, -4, -9, -17, 4, 10, 9, -2, -12, -16, -12, -2, 8, 16, 13, 11, 16, 19, 10, -2, -16, -21, -11, 14, 15, 21, 11, 6, -10, -8, -11, -24, -35, -31, -13, 9, 24, 17, -2, -11, -20, -11, -19, -7, 3, 8, 22, 21, 21, 2, -7, -10, 12, 24, 18, -3, -19, -6, 0, -5, -18, -17, 6, 12, 7, -16, -20, -22, -27, -19, -14, 12, 14, 3, 0, 2, 8, -3, -5, -3, 21, 29, 17, 6, -8, 3, 3, 10, 10, 3, 12, 4, -9, -18, -20, -20, -9, 6, 3, -9, -7, -14, -9, -8, -9, -23, -19, 7, 17, 20, 9, 8, 5, 9, 18, 9, 8, -10, -10, -4, 9, 25, -6, -19, -19, -5, -4, -7, -7, -17, -15, -7, -4, 0, 2, -2, -17, -4, 14, 23, 15, 2, -7, -5, 9, 11, 1, 0, -3, 0, 0, 15, 14, -4, -15, -20, -26, -22, -13, 0, 6, 12, 5, -10, 2, 8, -2, -18, -8, 6, 20, 28, 23, 0, -16, -7, 9, 7, 10, -12, -21, -19, 7, 12, 4, -17, -28, -24, -3, 14, 4, -19, -18, -9, 11, 22, 16, -13, -23, -15, 18, 32, 32, 17, -4, 1, 14, 11, 1, -20, -19, -3, 9, 13, -4, -13, -16, -18, -23, -12, -17, -16, -20, -15, -14, -4, 8, 12, 0, 8, 5, 12, 17, 26, 25, 14, 10, 11, 11, 18, 15, 4, -9, -13, -8, -9, -14, -20, -28, -32, -12, -9, -16, -17, -24, -18, -12, 5, 10, 4, 6, 8, 18, 35, 31, 17, 1, 12, 21, 33, 18, 6, -10, -11, -4, -9, -13, -19, -24, -24, -24, -18, -20, -18, -20, -13, -15, -10, -9, -5, 8, 10, 13, 23, 26, 29, 14, 13, 13, 13, 16, 25, 19, 17, 4, -15, -18, -15, -14, -17, -34, -23, -16, -12, -16, -26, -33, -23, -15, -4, 4, 10, 16, 19, 22, 29, 28, 7, 1, 2, 18, 26, 30, 21, 9, 3, -4, -10, -16, -29, -31, -27, -4, -9, -11, -28, -23, -17, -15, -13, -11, 4, 11, 9, 13, 16, 25, 18, 8, 10, 18, 17, 8, 18, 17, 11, -5, -19, -17, -12, -19, -38, -27, -8, 0, -3, -14, -19, -20, -14, -10, -13, -3, 6, 12, 26, 38, 34, 14, 2, -2, 11, 19, 14, 8, 5, 16, 9, -7, -19, -24, -29, -36, -26, -13, -12, -22, -28, -20, 5, -3, -10, -19, 7, 20, 18, 17, 24, 25, 14, 18, 19, 29, 21, 11, 10, 9, 13, -13, -29, -27, -20, -24, -30, -22, -12, -7, -15, -22, -21, -13, -14, -20, -8, 12, 26, 25, 21, 33, 27, 25, 16, 13, 16, 16, -2, 2, 11, 9, -2, -17, -18, -16, -25, -25, -26, -27, -30, -35, -30, -12, -6, -6, -6, -5, 19, 19, 11, 15, 17, 24, 23, 34, 28, 23, 13, 2, 9, 18, 16, -14, -18, -12, -7, -9, -31, -37, -33, -24, -14, -24, -20, -16, -21, -15, -7, 5, 9, 15, 20, 28, 38, 29, 21, 15, 22, 17, 4, 12, 6, 12, -4, -9, -15, -16, -19, -40, -38, -34, -23, -18, -17, -8, -10, -3, -7, 1, 3, 4, 11, 13, 36, 41, 36, 24, 9, 17, 20, 21, 14, -5, -9, -11, -8, -19, -14, -24, -30, -23, -18, -25, -30, -24, -17, -20, -9, -3, 6, 8, 22, 23, 20, 27, 18, 10, 10, 14, 18, 14, 23, 17, 6, 5, -4, -8, -26, -19, -24, -25, -24, -21, -27, -28, -15, -19, -16, -9, 0, 7, 9, 17, 14, 15, 24, 30, 29, 29, 32, 16, 10, 8, 0, -3, -10, -7, -17, -22, -25, -30, -36, -32, -25, -26, -22, -12, -16, -11, -3, 5, 7, 13, 21, 21, 26, 32, 28, 26, 28, 31, 17, 15, 15, 5, -4, -14, -18, -28, -25, -24, -28, -32, -33, -32, -29, -18, -17, -20, -10, -4, 6, 6, 18, 22, 22, 37, 38, 31, 27, 26, 23, 22, 23, 12, 4, -5, -2, -11, -19, -25, -35, -35, -36, -36, -43, -32, -24, -20, -12, -7, -3, -7, 3, 13, 23, 29, 35, 37, 35, 42, 33, 26, 22, 17, 12, 6, 4, -9, -23, -28, -34, -34, -33, -31, -40, -36, -27, -25, -22, -30, -20, -11, 2, 12, 22, 22, 26, 28, 35, 47, 44, 27, 29, 29, 29, 19, 2, 1, -9, -15, -21, -34, -35, -34, -40, -44, -42, -34, -31, -26, -21, -9, -12, -3, 10, 17, 29, 26, 27, 34, 48, 50, 34, 33, 25, 21, 16, 8, 3, -8, -11, -25, -30, -37, -37, -42, -51, -34, -28, -21, -26, -25, -19, -13, 4, 9, 17, 29, 41, 33, 33, 44, 45, 32, 31, 28, 22, 16, 5, -10, -13, -16, -23, -38, -39, -39, -45, -54, -40, -32, -24, -22, -17, -14, 0, 6, 9, 18, 41, 43, 34, 32, 40, 40, 31, 30, 27, 22, 19, 14, -2, -16, -21, -34, -48, -45, -41, -41, -41, -45, -38, -25, -21, -17, -20, -7, 11, 17, 19, 36, 40, 42, 44, 47, 46, 39, 33, 26, 15, 11, 8, -5, -19, -24, -29, -40, -44, -48, -44, -37, -37, -43, -43, -26, -19, -14, -2, 13, 23, 31, 36, 36, 43, 41, 47, 46, 44, 40, 24, 15, 14, 3, -12, -21, -23, -30, -36, -47, -51, -50, -47, -44, -46, -31, -19, -16, -11, 2, 16, 20, 25, 29, 40, 53, 51, 49, 45, 41, 35, 25, 18, 7, 5, -12, -18, -23, -34, -39, -56, -58, -54, -49, -50, -45, -35, -26, -12, -5, 6, 17, 29, 41, 42, 47, 50, 46, 49, 50, 50, 39, 30, 16, 2, -8, -15, -21, -30, -41, -49, -50, -46, -57, -63, -57, -41, -29, -24, -12, -3, 5, 12, 22, 33, 41, 50, 51, 53, 57, 55, 46, 36, 29, 16, 2, -4, -11, -21, -33, -40, -49, -47, -53, -60, -58, -51, -42, -34, -23, -13, -2, 5, 17, 27, 39, 49, 48, 51, 56, 54, 58, 44, 37, 28, 18, 4, -3, -15, -29, -39, -49, -49, -51, -62, -65, -64, -47, -42, -36, -26, -14, -5, 10, 24, 32, 45, 50, 49, 62, 65, 63, 47, 42, 41, 36, 23, 7, -7, -22, -31, -41, -53, -58, -62, -59, -62, -56, -54, -50, -44, -32, -16, 0, 11, 25, 35, 50, 54, 55, 56, 66, 65, 62, 54, 45, 36, 23, 14, -4, -22, -44, -55, -52, -62, -61, -66, -70, -68, -60, -54, -45, -29, -15, 4, 21, 34, 36, 44, 54, 62, 70, 73, 68, 67, 59, 50, 37, 21, -5, -12, -25, -39, -48, -53, -63, -76, -73, -71, -71, -67, -57, -45, -29, -12, 2, 13, 30, 42, 51, 61, 76, 71, 63, 66, 71, 60, 50, 40, 23, -2, -9, -20, -41, -54, -59, -72, -79, -71, -64, -73, -68, -60, -51, -36, -13, 2, 13, 27, 47, 54, 71, 78, 71, 60, 72, 74, 65, 54, 39, 28, 7, -6, -23, -50, -59, -64, -69, -75, -70, -78, -74, -73, -64, -52, -37, -13, 6, 18, 40, 51, 58, 64, 78, 79, 75, 68, 64, 68, 57, 45, 21, 4, -16, -34, -50, -65, -75, -83, -80, -71, -69, -68, -73, -63, -57, -36, -16, 6, 26, 45, 60, 70, 71, 79, 79, 81, 78, 80, 64, 55, 36, 16, -4, -23, -38, -54, -63, -69, -81, -85, -87, -76, -72, -66, -61, -52, -30, -12, 12, 24, 44, 55, 69, 78, 85, 84, 74, 70, 71, 71, 62, 41, 17, -11, -25, -42, -55, -66, -75, -87, -87, -81, -74, -76, -76, -63, -48, -32, -13, 7, 30, 51, 64, 76, 80, 82, 83, 81, 80, 82, 70, 61, 42, 19, 0, -28, -49, -61, -72, -78, -87, -90, -89, -88, -87, -82, -69, -54, -33, -13, 15, 36, 58, 68, 79, 90, 96, 90, 84, 86, 89, 79, 62, 38, 22, -3, -29, -55, -69, -81, -89, -94, -94, -94, -94, -89, -74, -62, -52, -35, -18, 14, 39, 54, 65, 76, 87, 98, 95, 94, 90, 82, 75, 69, 47, 26, -6, -33, -57, -72, -82, -88, -97, -90, -91, -88, -83, -80, -75, -59, -33, -9, 20, 42, 58, 68, 82, 90, 94, 93, 94, 88, 85, 77, 65, 43, 16, -10, -37, -60, -71, -84, -89, -95, -97, -102, -95, -84, -80, -72, -57, -26, -4, 19, 42, 62, 80, 89, 94, 97, 100, 99, 90, 83, 71, 65, 39, 14, -9, -43, -65, -83, -90, -95, -98, -96, -100, -96, -88, -76, -66, -51, -24, -12, 21, 45, 70, 85, 93, 95, 97, 101, 105, 92, 84, 69, 58, 35, 16, -14, -44, -68, -86, -88, -96, -101, -101, -102, -97, -90, -74, -69, -50, -19, 9, 35, 56, 76, 84, 92, 98, 96, 99, 97, 93, 84, 77, 59, 24, 2, -30, -52, -76, -87, -93, -98, -100, -102, -100, -96, -89, -81, -73, -46, -18, 12, 36, 62, 82, 88, 96, 104, 107, 105, 102, 92, 84, 77, 53, 26, -6, -35, -57, -75, -81, -92, -103, -114, -111, -108, -98, -88, -83, -67, -35, -7, 20, 39, 60, 70, 89, 106, 116, 107, 103, 99, 86, 90, 82, 53, 18, -13, -31, -52, -73, -92, -102, -106, -104, -97, -106, -99, -101, -92, -72, -42, -5, 16, 38, 66, 86, 101, 99, 101, 95, 112, 107, 99, 95, 81, 53, 16, -3, -29, -60, -81, -102, -98, -102, -102, -112, -114, -101, -104, -88, -69, -34, -8, 14, 41, 67, 92, 94, 99, 103, 104, 115, 109, 103, 90, 78, 52, 22, 0, -39, -65, -92, -95, -91, -103, -104, -118, -110, -102, -93, -84, -71, -36, -15, 19, 52, 81, 94, 89, 98, 103, 115, 117, 102, 92, 83, 80, 49, 23, -11, -43, -67, -90, -93, -102, -105, -110, -118, -104, -100, -89, -83, -64, -36, -7, 28, 50, 74, 88, 95, 104, 103, 115, 107, 106, 97, 87, 74, 50, 20, -17, -47, -75, -89, -93, -101, -102, -115, -117, -106, -97, -88, -90, -73, -38, 2, 36, 60, 75, 84, 96, 104, 115, 115, 102, 98, 96, 96, 84, 52, 10, -12, -32, -53, -71, -87, -101, -109, -112, -109, -106, -105, -102, -92, -74, -48, -19, 7, 33, 56, 76, 91, 101, 108, 111, 111, 108, 103, 96, 85, 63, 33, 1, -27, -51, -73, -90, -102, -109, -112, -110, -107, -103, -100, -93, -76, -50, -19, 10, 36, 58, 76, 91, 101, 108, 111, 111, 108, 103, 96, 85, 63, 33, 1, -27, -51, -73, -90, -102, -109, -112, -110, -107, -103, -100, -93, -76, -50, -19, 10, 36, 58, 76, -1, -2, -15, 21, -17, 23, -30, 1, 34, -34, 6, 5, -15, 19, 1, -25, 6, 20, -2, -28, 15, 10, -15, 0, -7, 10, 7, -5, -9, -6, 19, -3, -21, 3, 20, -4, -20, 1, 16, -3, -8, -2, 5, 1, -8, -6, 3, 9, 2, -13, -4, 15, -7, -9, 0, 3, 6, -7, -7, 5, 8, -8, -4, 0, 1, 1, -6, -4, 7, 2, -2, -7, 0, 4, -3, -4, 0, 2, 0, -2, -4, 1, 4, -2, -4, -3, 1, 3, -5, -4, 4, 3, -6, -5, 4, -1, -2, -3, 0, 3, -3, -1, -4, 3, 3, -5, -3, 1, 1, -2, -3, 1, 2, -2, -4, 0, 0, 0, -1, -3, 1, 1, -3, -2, 1, 0, -2, -2, 0, 0, -2, -1, 0, -1, 1, -2, -2, 1, 0, -2, 0, -1, 0, -1, -1, -1, 0, 0, -1, -3, 1, 1, -2, -2, 0, 1, -1, -2, -1, 0, 0, 0, -2, -1, 1, 0, -3, 0, 2, -1, -2, 0, 0, 0, -2, 0, -1, 0, -1, -1, 1, 0, -1, 0, -1, 1, 0, -13, 5, 7, -11, 24, -50, 41, 4, -29, 14, -11, 8, 11, -15, -12, 15, 18, -21, -14, 22, -2, -11, -3, -3, 18, -3, -5, -14, 9, 22, -24, -16, 23, 12, -23, -8, 9, 10, -4, -8, -3, 11, -4, -14, 0, 8, 8, -5, -14, 8, 10, -12, -4, -2, 10, 0, -11, -3, 11, 0, -7, -2, -1, 7, -6, -8, 3, 6, 0, -3, -8, 7, 2, -7, -2, 2, 1, -2, -4, -1, 3, 3, -4, -5, 1, 3, -3, -6, 2, 5, -1, -7, -1, 3, -1, -4, -3, 5, 0, -3, -2, -1, 4, -1, -5, -1, 3, -1, -4, -1, 3, 1, -4, -2, 1, 0, -2, -3, 0, 2, -1, -4, 1, 1, -1, -2, -2, 1, -1, -3, 0, 0, 0, -1, -2, 0, 0, -2, -1, 0, -1, 0, -2, -1, 0, -1, 0, -1, -2, 2, -1, -2, -1, 0, 1, -2, 0, -1, -1, 0, -1, -2, 0, 1, -1, -3, 0, 1, -1, -3, 0, 1, -2, -1, 0, 0, -1, -1, 0, -1, -1, -1, -1, 0, 0, -1, -1, 0, 0, -2, 0, 0, 0, 0, -2, 1, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, -1, 0, -1, 1, 0, 0, 0, 1, -1, -1, 0, 0, 0, 1, -2, 4, -3, 3, -40, 71, -73, 67, -27, -68, 127, -80, 3, 5, 1, 17, -14, 1, -30, 53, -3, -42, 15, 19, -9, -17, -1, 13, 16, -17, 4, -32, 43, 15, -68, 18, 54, -38, -7, -1, 11, 7, -3, -18, 5, 25, -27, -9, 9, 19, -6, -12, -8, 20, -1, -15, -1, 1, 17, -10, -16, 12, 12, -13, 0, -6, 10, 2, -16, -1, 14, -4, 4, -11, -2, 12, -6, -8, 4, 4, -2, -4, 1, -2, 4, 3, -7, -5, 8, 0, -10, 1, 4, 2, -4, -6, 4, 1, -1, -7, 1, 8, -9, 2, -5, 3, 3, -4, -3, 0, 3, -3, -5, 4, 3, -3, -4, 0, 2, 0, -3, -4, 5, 0, -5, -1, 2, 0, -3, 0, -1, 2, -2, -4, 3, 0, -1, -2, -1, 2, -2, -2, 1, -1, 0, -1, -3, 1, 1, -2, 1, -3, 1, 1, -3, -1, 1, 0, -1, -2, 1, -1, -1, 1, -2, 1, -1, -1, -1, -1, 0, 1, -3, 0, 0, 1, -4, 0, 1, -2, 0, -2, 0, 0, 0, -2, 1, -1, 0, -2, 0, 2, -2, -1, 0, -1, 2, -2, -1, 1, -2, 0, -1, 1, -1, -1, -1, 1, -2, 1, -1, -1, 2, -3, 0, 0, -1, 1, -1, 0, 1, 0, -2, 0, -1, 1, -2, 0, 0, -1, 1, 0, -2, 0, 1, -2, 1, 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 0, 0, 0, -1, 1, 0, -1, 1, 0, 0, 1, 0, -1, 1, 0, 3, -40, 58, -39, 12, 42, -117, 108, 1, -66, 22, 17, 0, -9, 10, -39, 42, 4, -23, -12, 28, 3, -34, 9, 17, 3, -9, 10, -29, 13, 53, -79, 3, 64, -26, -24, 16, -9, 14, 2, -8, -15, 31, -9, -30, 11, 29, -15, -7, 0, 3, 6, -4, -9, -6, 22, 1, -24, 9, 11, -8, 0, -2, 2, 8, -12, -6, 10, 2, 2, -9, -4, 11, -2, -10, 3, 2, 3, -5, -1, 1, -1, 6, -4, -8, 9, 2, -8, -3, 6, 3, -4, -3, -1, 6, -2, -8, 0, 9, -4, -3, -2, 2, 4, -4, -1, -1, 4, -2, -6, 4, 2, -1, -4, 0, 1, 2, -3, -5, 3, 3, -3, -4, 3, 0, -1, 0, -2, 2, 0, -3, 0, 3, 0, -3, -1, 2, 0, -3, 1, 0, -1, 2, -2, -2, 2, -1, 0, -1, -1, 1, -1, -2, 0, 0, 1, -3, 1, 0, -1, 1, -2, -1, 2, -2, -1, 0, -1, 2, -3, -1, 1, 1, -2, -2, 2, 1, -2, -1, 0, 0, 1, -3, 1, 0, 0, 0, -2, 3, 0, -2, 0, 0, 1, 0, -1, 1, -2, 0, 0, 0, -1, 1, 0, 0, 0, -1, 1, -1, 1, 0, -1, 1, -2, 0, 1, 1, 0, 1, -2, 1, 0, 1, 0, 0, 3, -1, 0, 1, 0, 0, 3, -29, 35, -12, -16, 56, -88, 39, 62, -79, 5, 29, 1, -13, 12, -29, 26, 17, -28, -3, 12, 5, -11, -19, 28, 1, -5, 9, -21, -7, 60, -56, -20, 57, -10, -27, 21, -21, 16, 12, -12, -21, 24, 6, -29, 4, 19, 2, -7, -5, -3, 7, 6, -11, -9, 11, 13, -18, -4, 13, 1, -3, -6, -1, 10, -8, -6, 5, 3, 5, -3, -11, 4, 9, -11, 0, 4, 3, -4, -1, 0, 0, 7, 0, -14, 7, 5, -7, -4, 4, 5, -1, -4, -4, 4, 1, -4, -4, 7, -1, -1, -3, 0, 5, -1, -4, -1, 2, 0, -3, 1, 1, 2, -2, -4, 1, 2, 0, -5, 2, 3, -2, -2, 1, 1, -2, 2, -3, 0, 0, -1, -1, 0, 1, 0, -3, 0, 0, -1, 1, -1, -2, 1, -1, 0, -2, 2, 1, -2, -1, 1, 0, -1, -1, 0, 1, -1, 0, -2, 1, 1, -1, 0, -1, -1, 0, 0, -1, -1, 0, -1, -1, 2, -2, -1, 1, 0, 0, -1, -1, 1, 0, -1, 1, -1, 0, 1, -3, 1, 1, -1, -1, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 2, -2, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, -1, -1, -7, -9, 35, -52, 59, -33, -32, 64, -15, -41, 19, 22, -20, 9, -11, -3, 33, -27, 2, 7, -9, 19, -37, 24, 7, -11, 11, -1, -30, 37, 8, -57, 36, 19, -33, 14, 0, -17, 26, 1, -20, -5, 26, -18, -13, 14, 7, -6, 4, -9, -4, 11, 3, -14, -7, 20, 0, -18, 10, 1, 4, -5, -7, 6, 0, -3, -2, -2, 8, 5, -11, -6, 10, -1, -10, 6, -2, -1, 1, -3, 0, 3, 5, -9, -5, 9, -3, -4, 1, 1, 3, -1, -4, -1, 2, -2, -5, 5, -3, 0, 1, -5, 4, 2, -3, -3, 0, 0, -2, 1, 0, -2, 3, -2, -5, 2, 2, -2, -4, 3, 0, -2, 1, -2, -2, 5, -2, -6, 1, 2, -1, -1, 0, 1, -1, -2, -1, -1, 2, 0, -4, 0, 1, 0, -3, 0, 2, 0, -3, 0, 0, 1, -1, -1, 1, 0, -1, -2, 1, 0, 0, -1, 0, -2, 1, 0, -1, 1, -1, 0, -2, 1, 1, -2, -1, 2, -2, 1, -3, 1, 1, -1, 0, 0, -1, 1, 0, -2, 2, -1, -1, 0, 0, 1, 0, 1, 0, -2, 1, 0, 0, -1, 1, 0, 0, 0, 0, -3, -20, 45, -56, 40, -5, -34, 27, 24, -42, -1, 29, -14, -4, 2, -7, 24, -20, -1, 18, -25, 25, -29, 9, 21, -26, 14, 4, -20, 7, 27, -42, 5, 31, -24, -2, 19, -30, 21, 8, -11, -17, 20, 1, -22, 11, 7, -7, 6, -5, -7, 3, 11, -6, -18, 11, 16, -20, 1, 5, 2, -3, -3, 0, -3, 4, -1, -7, 2, 10, -9, -8, 7, 2, -9, 5, -1, -5, 2, 1, -3, -2, 9, -5, -8, 4, 1, -5, 0, 1, 2, -1, 0, -5, 4, -1, -5, 4, -3, 1, 1, -5, 3, 0, 0, -3, 0, -1, -2, 1, 2, -5, 2, 1, -5, -2, 3, -1, -5, 2, 1, -4, 2, -1, -4, 2, 3, -7, -1, 2, 0, -2, 1, 0, -2, -1, 0, -3, 1, 2, -3, -2, 3, 0, -3, -1, 1, 0, -1, -2, -1, 1, 0, 0, -1, 0, 0, -2, 0, 0, 1, -2, 2, -3, 1, 0, 0, -2, 1, 0, -1, 0, 0, -1, -1, 2, -3, 0, 0, -1, 0, 0, -1, 1, 0, -4, -13, 32, -41, 31, -10, -10, 4, 22, -25, -8, 21, -3, -14, 5, 1, 12, -23, 8, 18, -31, 25, -26, 10, 17, -23, 8, 5, -9, 0, 16, -25, 2, 23, -22, -2, 22, -30, 15, 7, -6, -13, 12, 1, -17, 9, 5, -6, 4, -3, -7, 5, 7, -6, -13, 7, 10, -11, 0, 0, 4, -3, -3, 2, -7, 4, 2, -5, 0, 6, -3, -8, 4, 2, -8, 7, 0, -8, -1, 6, 0, -8, 6, 0, -5, 1, 0, -5, 3, 2, -3, -2, 4, -5, -1, -1, -2, 3, -4, 1, -1, -3, 3, -1, -2, -2, 1, -2, -2, 1, 1, -4, 1, 2, -5, -3, 5, -3, -4, 4, -1, -4, 2, -1, -4, 3, 1, -5, -2, 2, 0, -2, 2, -1, -4, 3, -1, -3, 0, 1, -2, -2, 1, -1, -1, -1, 0, 0, -1, -1, -1, 0, -1, 1, -1, -1, 0, -2, 1, 0, -1, -1, 0, -1, -1, -1, 2, -2, -1, 1, -1, -2, 1, -1, -1, 1, -2, 1, -7, -3, 15, -23, 20, -16, 9, -12, 16, -12, -8, 11, 5, -18, 6, 8, 0, -18, 16, 4, -19, 16, -17, 10, 5, -8, -2, 9, -5, -4, 10, -17, 5, 13, -18, 2, 12, -17, 10, 0, -2, -8, 7, -4, -7, 6, 1, -3, 1, 3, -9, -2, 10, -7, -8, 4, 6, -6, 1, 0, 0, -2, 1, -1, -8, 6, 1, -5, 2, 4, -2, -4, 1, 1, -7, 5, -1, -4, -2, 4, 0, -4, 4, -3, -4, 1, 0, -3, 0, 2, -1, -2, 2, -2, -1, -3, 0, 3, -4, 3, -3, 0, 2, 0, -3, -1, 1, -3, -1, 2, 0, -1, 0, 0, -3, 0, 1, -4, -1, 2, 0, -2, 0, 1, -3, 1, 1, -3, -2, 2, -1, -1, 2, -1, -2, 1, 0, -1, -1, -1, -3, -8, -16, -20, -7, 14, 20, 19, 18, 16, 11, 3, -9, -21, -36, -43, -39, -24, 6, 38, 57, 55, 26, 0, -7, -10, -13, -12, -11, -29, -56, -59, -37, 0, 43, 74, 87, 75, 37, -2, -31, -51, -59, -45, -15, -16, -34, -20, -10, -5, 29, 61, 72, 51, 18, -2, -21, -39, -35, -24, 1, 0, -31, -29, -23, -44, -13, 48, 82, 79, 46, 16, -4, -44, -58, -26, 3, 6, -38, -52, -24, -42, -35, 47, 95, 88, 55, 19, 12, -22, -72, -38, 4, 3, -31, -67, -29, -24, -60, 23, 112, 111, 72, 22, 7, -20, -90, -73, -1, 19, -4, -57, -36, 3, -54, -32, 98, 125, 71, 14, 14, 0, -82, -106, 0, 42, 10, -48, -32, -2, -54, -63, 72, 125, 82, 24, 14, -8, -57, -104, -22, 52, 34, -34, -46, -16, -35, -83, 32, 127, 99, 26, 19, 4, -55, -110, -48, 45, 36, -12, -26, -22, -41, -64, -7, 107, 113, 56, 6, 4, -41, -92, -74, 35, 57, 12, -41, -21, -39, -67, -40, 86, 114, 71, 10, 22, -31, -83, -83, 16, 46, 34, -28, -18, -42, -58, -60, 55, 108, 97, 3, 21, -8, -77, -102, 10, 45, 42, -26, -2, -27, -68, -73, 45, 83, 92, 29, 25, -8, -56, -104, -13, 35, 52, -6, -7, -22, -46, -91, 10, 80, 95, 35, 26, 8, -38, -106, -34, 34, 42, 5, 1, -23, -39, -73, -28, 61, 89, 60, 20, 2, -7, -73, -86, 24, 52, 26, -12, -11, -19, -58, -86, 46, 91, 62, 17, 22, -15, -39, -106, 8, 55, 45, -13, -6, -30, -21, -102, 4, 82, 87, 7, 28, -3, -9, -115, -32, 50, 63, -23, 8, -19, -18, -94, -28, 61, 96, 14, 39, -4, 1, -85, -60, 23, 79, -3, 2, -20, -10, -82, -65, 25, 108, 28, 31, 19, 9, -65, -74, -5, 78, 16, -3, -9, -14, -65, -76, -3, 93, 60, 29, 22, 13, -43, -90, -30, 61, 49, -9, -1, 4, -52, -98, -16, 68, 72, 21, 38, 15, -31, -94, -34, 32, 67, 5, 9, 0, -28, -111, -33, 40, 85, 24, 37, 23, -6, -104, -44, 13, 69, 9, 14, 8, -11, -110, -53, 20, 80, 32, 48, 30, 5, -87, -66, -7, 63, 33, 12, 2, 5, -86, -94, -2, 79, 46, 26, 44, 22, -59, -88, -19, 54, 48, 13, 14, 4, -51, -112, -37, 67, 71, 21, 38, 29, -29, -104, -50, 44, 63, 11, 10, 14, -24, -103, -67, 49, 88, 20, 27, 43, -10, -90, -79, 24, 69, 21, 7, 18, -8, -82, -103, 17, 94, 38, 10, 54, 12, -70, -97, 1, 68, 37, -4, 27, -6, -56, -104, -21, 82, 67, -3, 46, 23, -37, -108, -31, 57, 58, -13, 29, 11, -32, -106, -50, 53, 92, -6, 38, 38, -15, -105, -54, 34, 79, -12, 20, 22, -11, -98, -70, 22, 99, 4, 16, 48, 14, -99, -75, 15, 82, 2, 0, 44, 8, -93, -80, 0, 84, 29, -3, 57, 32, -79, -94, 1, 66, 27, -19, 49, 29, -73, -109, -7, 54, 52, -17, 62, 53, -46, -113, -4, 43, 51, -30, 46, 37, -42, -128, -23, 26, 69, -18, 51, 59, -2, -122, -30, 24, 66, -27, 31, 51, 1, -128, -48, 13, 71, -11, 33, 66, 22, -110, -57, 8, 68, -9, 12, 53, 28, -104, -87, -4, 67, 8, 8, 72, 53, -80, -91, -4, 59, 10, -13, 63, 44, -81, -109, -19, 46, 33, -6, 76, 57, -43, -104, -24, 36, 42, -26, 55, 51, -34, -126, -39, 19, 58, -21, 68, 71, -8, -114, -32, 2, 62, -24, 52, 54, -4, -120, -53, -22, 71, -8, 49, 62, 31, -102, -52, -25, 70, -5, 24, 55, 35, -109, -69, -40, 59, 16, 25, 65, 55, -80, -70, -37, 47, 23, 7, 48, 51, -73, -97, -48, 30, 46, 6, 57, 74, -37, -98, -34, 21, 48, -10, 44, 58, -34, -123, -46, -2, 61, 2, 50, 69, 10, -110, -40, -5, 59, -9, 31, 53, 19, -126, -59, -20, 62, 8, 32, 64, 49, -105, -59, -16, 58, 2, 17, 50, 45, -102, -83, -31, 46, 24, 15, 53, 69, -65, -86, -24, 42, 25, -4, 45, 64, -58, -112, -37, 30, 41, -6, 51, 75, -24, -105, -32, 26, 41, -19, 39, 62, -14, -117, -51, 7, 54, -13, 35, 78, 19, -105, -47, 9, 58, -19, 21, 69, 18, -113, -66, -10, 52, -10, 14, 75, 42, -83, -60, -5, 52, 0, -3, 69, 43, -83, -83, -21, 35, 17, -13, 72, 57, -54, -82, -10, 29, 28, -29, 65, 52, -45, -98, -21, 1, 40, -30, 64, 63, -7, -94, -9, 1, 51, -36, 51, 54, -8, -115, -23, -22, 47, -30, 48, 65, 24, -90, -13, -15, 46, -26, 30, 55, 21, -100, -37, -26, 31, -10, 24, 65, 41, -71, -35, -10, 25, -2, 4, 58, 32, -69, -61, -16, 2, 8, 1, 67, 42, -33, -56, -1, -1, 20, -13, 59, 33, -28, -82, -10, -20, 22, -15, 64, 40, -1, -70, 0, -17, 29, -22, 53, 33, 1, -84, -15, -29, 22, -19, 53, 43, 22, -64, -7, -19, 25, -18, 37, 38, 16, -73, -30, -33, 11, -14, 32, 50, 31, -45, -17, -15, 16, -4, 16, 43, 23, -49, -43, -30, -2, -1, 8, 52, 36, -25, -32, -13, -1, 11, -1, 42, 30, -25, -49, -25, -18, 10, -7, 44, 40, -2, -34, -11, -15, 21, -6, 29, 33, -5, -54, -29, -30, 13, -6, 29, 46, 15, -32, -10, -18, 16, -1, 13, 36, 9, -45, -30, -32, 0, 1, 12, 43, 28, -23, -16, -16, 6, 9, 2, 33, 22, -33, -34, -27, -11, 2, 1, 35, 36, -14, -16, -11, -5, 8, 3, 24, 32, -19, -30, -29, -17, -4, 1, 20, 43, -5, -14, -13, -4, 0, 7, 11, 39, -9, -23, -28, -17, -16, 1, 9, 44, 3, -7, -15, -4, -4, 7, 5, 38, 3, -20, -30, -19, -19, -8, 0, 40, 17, -6, -7, -3, -2, -1, 4, 32, 16, -20, -21, -26, -17, -18, -3, 28, 32, -7, -1, -9, 4, -9, 3, 22, 34, -19, -14, -27, -13, -27, -10, 16, 44, -8, 5, -6, 3, -12, 1, 13, 40, -12, -11, -25, -17, -27, -15, 5, 45, 4, 2, 0, 0, -9, -5, 6, 38, 2, -17, -14, -20, -24, -23, 0, 38, 19, -4, 11, -4, -7, -10, 4, 27, 20, -20, -9, -23, -22, -30, -6, 26, 35, -8, 12, 2, -4, -15, 2, 20, 32, -16, -7, -15, -22, -37, -14, 18, 39, -3, 5, 8, -5, -18, -2, 18, 34, -4, -14, -4, -21, -35, -25, 15, 36, 8, -4, 21, -5, -17, -14, 23, 26, 9, -22, 4, -25, -32, -40, 14, 27, 24, -12, 30, 1, -8, -26, 24, 21, 19, -28, 9, -20, -28, -51, 7, 23, 30, -15, 27, 9, -7, -32, 16, 25, 23, -21, 4, -8, -27, -50, -10, 25, 29, -9, 13, 24, -7, -28, -3, 34, 20, -12, -9, 10, -31, -43, -29, 30, 23, 2, -3, 38, -9, -19, -19, 39, 18, -1, -20, 25, -29, -36, -42, 26, 17, 12, -14, 43, -3, -15, -29, 35, 19, 6, -28, 27, -18, -36, -48, 16, 17, 15, -15, 39, 12, -13, -29, 24, 24, 9, -25, 19, -1, -39, -50, 1, 18, 11, -11, 25, 26, -14, -26, 12, 32, 10, -17, 6, 17, -33, -48, -14, 20, 6, -7, 11, 36, -9, -26, -1, 34, 11, -9, -4, 25, -25, -49, -26, 19, 4, -4, 5, 41, 3, -21, -8, 31, 12, -7, -11, 23, -13, -47, -37, 13, 6, -3, 1, 40, 14, -17, -14, 26, 16, -2, -12, 20, -3, -40, -44, 2, 6, -2, -4, 35, 24, -9, -19, 19, 17, 2, -13, 16, 5, -29, -48, -7, 4, 3, -7, 28, 28, 2, -21, 13, 14, 9, -14, 11, 9, -15, -49, -17, -3, 6, -11, 20, 30, 14, -23, 7, 12, 14, -11, 6, 10, -4, -46, -24, -10, 6, -8, 11, 29, 24, -15, 0, 11, 14, -4, -2, 11, 3, -37, -36, -13, -3, -2, 2, 28, 27, -2, -10, 14, 9, 7, -8, 13, 3, -21, -42, -14, -14, 4, -6, 24, 24, 13, -16, 12, 3, 14, -8, 12, 4, -7, -44, -18, -20, 5, -6, 18, 22, 23, -13, 6, 2, 13, -4, 5, 5, 1, -36, -26, -20, -1, -1, 10, 23, 25, -3, -4, 5, 9, 5, -2, 8, 1, -24, -36, -18, -10, 4, 1, 24, 23, 11, -9, 8, 4, 12, -7, 9, 1, -12, -40, -19, -16, 4, -4, 21, 21, 16, -9, 6, 2, 13, -4, 6, 6, -4, -33, -24, -18, -2, -2, 10, 21, 18, 0, -3, 3, 8, 6, -1, 8, 0, -18, -31, -19, -10, 1, 0, 19, 20, 13, -5, 4, 5, 12, -4, 5, 2, -7, -34, -24, -17, 1, -4, 13, 20, 21, -3, 2, 5, 14, 0, 2, 4, 0, -26, -28, -20, -6, -4, 4, 18, 23, 6, -3, 5, 9, 7, -1, 6, 3, -14, -33, -22, -14, -1, -1, 16, 22, 17, -4, 4, 4, 10, -2, 4, 3, -4, -30, -25, -19, -2, -2, 11, 20, 23, 0, 0, 2, 10, 3, 1, 4, 1, -23, -30, -22, -8, -1, 4, 19, 23, 10, -3, 4, 6, 8, -2, 5, 2, -13, -33, -23, -15, 0, -1, 16, 21, 16, -3, 3, 4, 11, 0, 5, 6, -3, -27, -25, -19, -4, -2, 9, 19, 19, 2, -3, 2, 8, 6, -1, 8, 0, 0, 2, 33, 42, 58, 71, 79, 85, 88, 91, 94, 79, 95, 82, 106, 86, 105, 47, 16, -6, 13, 44, 31, -15, -38, -36, 20, 70, 41, 48, 58, 24, -57, -127, -119, -102, -126, -128, -111, -78, -82, -88, -87, -60, -66, -98, -104, -99, -97, -99, -104, -101, -88, -87, -91, -61, -27, -34, -54, -55, -45, -24, -10, -5, -4, 5, 34, 63, 101, 94, 78, 52, 51, 52, 74, 81, 77, 59, 46, 17, 7, 39, 53, 47, 42, 66, 83, 73, 52, 28, 22, 11, 8, 11, 0, -15, -23, -15, -14, -6, 16, 46, 62, 71, 76, 90, 102, 103, 103, 101, 100, 90, 75, 63, 67, 49, 37, 28, 12, 5, 6, 15, 15, 8, -7, -12, -4, -10, -28, -24, -17, -25, -50, -64, -81, -103, -116, -116, -113, -95, -72, -54, -41, -47, -65, -65, -50, -33, -24, -7, 11, 8, -4, -13, -28, -51, -75, -90, -91, -90, -90, -87, -88, -83, -84, -82, -81, -81, -76, -65, -71, -85, -84, -79, -83, -81, -77, -72, -70, -65, -66, -66, -65, -66, -68, -61, -56, -51, -36, -13, -3, -5, -8, -12, -12, 3, 16, 21, 31, 50, 69, 77, 82, 90, 102, 110, 114, 116, 117, 118, 119, 116, 112, 109, 105, 98, 99, 103, 102, 91, 73, 64, 63, 61, 57, 51, 40, 24, 35, 57, 75, 84, 79, 65, 37, 4, -26, -45, -57, -54, -46, -45, -54, -67, -67, -48, -16, 15, 35, 44, 45, 44, 45, 46, 38, 23, 2, -15, -34, -52, -60, -70, -77, -80, -79, -74, -77, -84, -86, -80, -72, -68, -72, -80, -87, -92, -96, -101, -104, -104, -101, -93, -90, -89, -86, -85, -84, -83, -82, -81, -79, -77, -76, -73, -71, -66, -62, -55, -39, -31, -27, -25, -31, -37, -46, -51, -53, -54, -48, -45, -38, -20, 3, 24, 35, 39, 32, 16, 5, 3, 0, -6, -13, -13, -11, -2, 14, 28, 40, 50, 53, 50, 55, 64, 74, 90, 105, 108, 112, 106, 104, 109, 112, 123, 127, 127, 127, 127, 127, 127, 118, 113, 107, 110, 114, 111, 104, 101, 101, 102, 103, 99, 99, 89, 73, 53, 35, 20, 0, -22, -43, -63, -77, -82, -76, -65, -48, -36, -29, -24, -25, -29, -37, -40, -49, -59, -67, -73, -76, -78, -79, -75, -73, -74, -75, -68, -52, -44, -30, -19, -9, -6, -9, -13, -24, -33, -35, -31, -30, -35, -40, -44, -45, -51, -53, -54, -50, -50, -47, -42, -50, -55, -54, -56, -56, -54, -54, -49, -48, -41, -32, -28, -18, -13, -5, 6, 18, 33, 49, 60, 71, 78, 88, 95, 97, 93, 88, 91, 93, 97, 98, 97, 94, 91, 85, 81, 72, 70, 66, 61, 60, 64, 66, 74, 83, 92, 102, 108, 109, 107, 102, 97, 95, 91, 87, 80, 74, 67, 62, 61, 58, 61, 61, 57, 53, 43, 35, 27, 25, 24, 20, 20, 22, 27, 34, 36, 32, 21, 8, -3, -10, -16, -18, -16, -16, -19, -15, -11, -11, -12, -20, -34, -45, -59, -72, -80, -89, -94, -95, -102, -111, -114, -111, -111, -108, -106, -104, -101, -98, -93, -90, -86, -86, -83, -82, -81, -79, -76, -73, -70, -72, -78, -81, -79, -79, -72, -60, -43, -31, -25, -27, -34, -37, -40, -42, -41, -39, -36, -34, -25, -12, -4, 5, 12, 16, 17, 15, 13, 6, -4, -7, -8, -6, -1, 4, 7, 9, 12, 16, 19, 19, 22, 28, 29, 28, 29, 30, 34, 40, 49, 57, 71, 78, 85, 92, 96, 95, 89, 85, 86, 93, 99, 104, 102, 100, 94, 85, 77, 73, 69, 66, 63, 60, 60, 59, 57, 52, 47, 41, 31, 18, 6, -3, -7, -11, -12, -14, -18, -22, -23, -22, -24, -30, -37, -41, -44, -50, -56, -64, -67, -65, -62, -58, -58, -58, -59, -61, -62, -66, -72, -78, -79, -77, -73, -68, -64, -61, -56, -53, -54, -52, -52, -57, -63, -69, -70, -68, -65, -62, -59, -57, -56, -58, -60, -61, -63, -64, -62, -61, -60, -58, -54, -49, -45, -42, -39, -36, -32, -28, -22, -13, -7, -3, 2, 13, 28, 41, 52, 64, 71, 73, 73, 70, 64, 61, 60, 64, 66, 65, 66, 64, 61, 60, 62, 65, 64, 66, 67, 67, 68, 66, 64, 66, 68, 73, 76, 74, 72, 66, 58, 52, 46, 42, 38, 38, 41, 47, 52, 52, 48, 45, 42, 40, 38, 34, 29, 27, 26, 28, 29, 28, 29, 30, 31, 28, 24, 21, 19, 17, 14, 10, 6, 3, -4, -9, -15, -19, -26, -33, -40, -49, -55, -60, -65, -70, -73, -72, -72, -71, -70, -71, -75, -78, -81, -83, -86, -86, -85, -84, -82, -80, -77, -72, -69, -66, -63, -61, -61, -61, -61, -61, -60, -58, -53, -48, -42, -36, -30, -28, -30, -32, -33, -32, -31, -28, -22, -18, -10, -5, 0, 3, 6, 11, 16, 19, 22, 24, 26, 27, 29, 34, 40, 46, 48, 48, 48, 45, 40, 36, 33, 31, 33, 35, 40, 48, 55, 62, 68, 73, 76, 78, 78, 77, 79, 82, 85, 87, 87, 87, 86, 86, 86, 83, 78, 71, 63, 55, 48, 44, 39, 36, 36, 36, 35, 32, 28, 24, 18, 13, 9, 6, 4, 1, -2, -5, -11, -17, -20, -21, -20, -21, -24, -28, -32, -34, -33, -33, -35, -37, -40, -43, -47, -52, -58, -63, -69, -74, -77, -80, -81, -82, -81, -80, -77, -74, -69, -62, -54, -48, -48, -51, -54, -57, -57, -57, -56, -55, -55, -56, -57, -56, -55, -54, -54, -54, -54, -52, -49, -45, -41, -38, -34, -31, -29, -27, -24, -20, -17, -11, -7, -3, 0, 5, 10, 16, 22, 27, 31, 34, 38, 42, 44, 45, 48, 50, 52, 57, 61, 64, 64, 65, 65, 63, 60, 57, 55, 55, 58, 61, 63, 65, 67, 69, 71, 74, 77, 79, 79, 77, 74, 71, 68, 66, 63, 60, 57, 55, 51, 46, 40, 36, 30, 25, 20, 17, 16, 17, 16, 14, 12, 10, 7, 3, -1, -5, -11, -15, -17, -18, -18, -19, -21, -25, -29, -32, -33, -33, -36, -39, -43, -46, -50, -53, -56, -58, -59, -60, -61, -62, -63, -65, -66, -67, -68, -70, -72, -72, -70, -67, -63, -61, -60, -60, -58, -56, -54, -53, -52, -52, -52, -51, -50, -49, -47, -45, -43, -40, -37, -35, -34, -32, -29, -25, -21, -18, -14, -9, -4, 0, 4, 7, 11, 15, 18, 21, 25, 28, 33, 37, 41, 44, 46, 47, 47, 46, 46, 45, 43, 42, 42, 43, 46, 48, 49, 50, 52, 55, 59, 62, 65, 66, 67, 68, 69, 69, 70, 72, 74, 74, 73, 72, 71, 69, 65, 61, 57, 53, 50, 46, 43, 38, 35, 32, 28, 23, 19, 17, 17, 15, 13, 11, 9, 5, 1, -3, -6, -9, -12, -14, -17, -19, -23, -27, -31, -35, -38, -40, -43, -46, -48, -52, -55, -57, -61, -64, -66, -67, -68, -69, -70, -70, -70, -69, -69, -70, -71, -70, -66, -62, -59, -55, -52, -50, -46, -43, -41, -38, -36, -35, -35, -34, -33, -33, -33, -33, -31, -30, -28, -26, -25, -24, -21, -20, -20, -19, -19, -18, -17, -16, -15, -13, -11, -8, -3, 2, 9, 15, 21, 27, 33, 38, 41, 45, 48, 51, 53, 55, 56, 56, 56, 56, 56, 56, 56, 55, 57, 58, 60, 61, 62, 62, 64, 66, 68, 69, 71, 72, 73, 74, 72, 70, 67, 63, 60, 57, 54, 50, 46, 41, 36, 31, 27, 23, 19, 16, 14, 12, 11, 9, 8, 5, 2, -1, -4, -8, -10, -15, -18, -19, -20, -22, -22, -23, -23, -24, -26, -29, -31, -33, -35, -36, -37, -38, -41, -44, -46, -48, -50, -52, -54, -56, -59, -61, -63, -63, -64, -65, -64, -63, -62, -61, -60, -59, -58, -57, -58, -57, -57, -55, -53, -50, -49, -47, -46, -43, -40, -37, -33, -31, -28, -26, -23, -20, -16, -14, -12, -9, -5, -2, 1, 5, 9, 13, 17, 21, 24, 26, 29, 32, 35, 37, 37, 38, 39, 41, 43, 44, 45, 46, 48, 50, 51, 53, 52, 52, 50, 48, 47, 46, 46, 46, 46, 47, 48, 49, 51, 54, 56, 58, 60, 61, 62, 62, 62, 61, 59, 57, 55, 54, 53, 52, 51, 49, 46, 41, 36, 31, 27, 22, 18, 14, 11, 9, 6, 3, 0, -2, -5, -8, -11, -16, -20, -25, -28, -31, -34, -37, -39, -41, -41, -42, -42, -42, -43, -45, -46, -47, -49, -50, -52, -54, -56, -57, -58, -60, -61, -63, -64, -64, -64, -63, -63, -61, -59, -58, -57, -55, -54, -53, -52, -52, -51, -50, -49, -47, -46, -45, -44, -42, -40, -38, -35, -32, -30, -28, -25, -22, -19, -17, -15, -12, -9, -5, -1, 3, 7, 11, 15, 19, 23, 25, 27, 30, 34, 36, 37, 38, 39, 40, 42, 44, 45, 46, 47, 49, 50, 52, 53, 52, 51, 49, 47, 47, 46, 46, 46, 47, 47, 48, 50, 52, 55, 57, 59, 61, 62, 62, 62, 61, 60, 58, 56, 54, 54, 53, 51, 50, 47, 44, 39, 34, 29, 25, 20, 16, 13, 10, 7, 4, 2, -1, -3, -6, -9, -14, -18, -22, -26, -30, -33, -35, -38, -40, -41, -41, -42, -42, -43, -44, -46, -47, -48, -49, -51, -53, -55, -56, -57, -59, -60, -62, -63, -64, -64, -63, -63, -62, -60, -59, -57, -56, -55, -53, -52, -52, -51, -51, -50, -48, -46, -45, -44, -43, -41, -39, -36, -34, -31, -29, -26, -24, -21, -16, -1, -2, -1, -3, 1, -2, -2, -4, 2, 6, 2, -2, -2, 0, 7, 8, 4, -2, -2, 6, 5, 6, 0, -2, 5, 12, 10, 0, -5, -3, 5, 10, 9, -7, -8, -7, 5, 8, 3, -9, -13, -5, 3, 5, -5, -9, -4, 0, 6, 0, -4, -11, -7, 3, 4, 0, -5, 0, -1, 5, 1, 4, -6, -5, -3, 12, 9, -2, -10, 4, 11, 8, -4, -5, -9, -6, 1, 19, 13, -2, -22, 4, 9, 6, -26, -4, 3, 12, -9, 0, 2, 0, -15, 4, 8, -8, -20, 0, 15, 8, -13, -2, -4, -4, -2, 12, 3, -14, -18, 1, 21, 13, -9, -25, -8, 17, 15, 5, -14, -17, 5, 19, 13, -15, -17, -3, 10, 20, 10, -27, -19, 5, 11, 12, 3, -13, -17, -1, 6, -3, -2, 1, -1, -11, -17, 7, 7, -7, -7, -13, 9, 0, -5, 9, -5, -9, 6, 5, -2, -16, -5, 15, 17, -10, -20, 1, 11, 14, -1, 1, 10, -11, -8, -1, 18, 13, -2, -12, 1, -16, -2, 34, 27, -28, -42, -3, 42, 26, -14, -39, -19, 7, 26, 25, -16, -55, -26, 32, 57, 4, -69, -48, 6, 75, 29, -51, -67, -32, 51, 56, 7, -57, -75, 14, 63, 43, -29, -82, -27, 31, 56, 28, -43, -81, -31, 59, 85, 1, -100, -59, 8, 102, 41, -42, -92, -52, 72, 79, 29, -103, -85, -1, 117, 49, -54, -113, 7, 24, 94, -28, -39, -84, 39, 28, 61, -44, -28, -67, 61, 23, 35, -40, -23, -37, 6, 38, 69, -42, -61, -53, 58, 86, 2, -93, -24, 19, 72, 17, -19, -87, 45, 10, 64, -13, -45, -57, 38, 48, 36, -51, -35, -37, 46, 26, 37, -73, -28, -12, 44, 22, 27, -84, -22, 6, 70, 17, -24, -82, -7, 26, 79, 9, -63, -78, 6, 90, 68, -55, -118, -3, 92, 62, -10, -73, -50, 14, 110, 15, -5, -118, 5, 69, 53, 22, -81, -45, 29, 47, 80, -69, -28, -52, 58, 66, -1, -25, -59, -22, 107, 2, 43, -108, -13, 20, 59, 56, -58, -66, -7, 34, 114, -42, -63, -50, 42, 69, 44, -63, -37, -50, 114, 27, 18, -49, -81, 20, 74, 51, -14, -102, -4, 40, 70, 38, -64, -73, 11, 60, 76, -41, -30, -78, 42, 46, 68, -63, -48, -56, 89, 43, 28, -100, -53, 41, 60, 11, -6, -76, -16, 44, 52, 9, -67, -48, 10, 69, 30, -1, -84, -4, 36, 72, -23, -22, -27, -33, 55, 74, -11, -86, -1, 27, 36, 31, -7, -101, 49, 5, 66, -7, -46, -39, 9, 64, 44, -63, -33, -22, 55, 23, 43, -79, -24, 5, 29, 54, -14, -59, -53, 63, 32, 20, -34, -32, -36, 93, -2, 20, -35, -38, 18, 51, 61, -94, 15, -14, 17, 69, 5, -87, 16, 28, 34, 1, 34, -57, -53, 118, -22, 34, -10, -71, 23, 70, 25, -29, -7, -19, -3, 117, -33, -12, -21, -19, 43, 84, -38, -57, 33, 0, 32, 41, -7, -103, 85, 2, 2, 58, -14, -103, 103, 7, -17, 34, -32, -59, 71, 51, -78, 76, -65, -30, 63, 48, -66, 9, -11, -28, 52, 50, -72, -37, 73, -61, 75, 7, -51, -44, 73, -3, -11, 40, -78, 7, 63, -15, -16, 30, -53, 12, 38, 12, -42, 39, -63, 47, 23, 0, -23, -11, 8, -25, 60, -37, -15, -3, -9, 12, 27, -14, -40, 22, 12, 14, 15, -31, -14, 15, 23, -12, 14, -31, 19, 13, 32, -39, 27, -51, 43, 8, 0, 5, -26, 16, 4, 19, -24, 17, -18, 6, -2, 49, -67, 39, -1, -30, 46, -13, -16, -9, 21, -17, 27, 2, -34, 19, -3, 24, 8, -38, 13, -10, 22, 15, -34, 2, 4, -10, 18, 14, -15, -15, 26, -12, 28, -21, 0, -6, 0, 7, 0, -15, 6, -2, -18, 9, 8, -18, -15, 59, -94, 81, -40, -24, 14, -18, 25, -15, 4, -21, -9, 24, -20, 3, 3, -52, 56, -29, 4, 5, -51, 45, -50, 73, -75, 13, 17, -48, 38, -10, -16, 5, 4, -22, 3, 17, -27, -23, 42, -30, -5, 41, -53, 10, 23, -28, 1, 29, -47, 9, 13, -3, -18, 9, -13, -11, 18, 12, -53, 28, 1, -41, 41, 7, -61, 32, 0, -34, 16, 9, -74, 45, -23, -33, 22, 39, -104, 49, 23, -96, 83, 5, -46, 36, -4, -45, 54, -25, -26, 21, 2, -39, 51, -25, -25, 43, -22, -25, 30, -2, -32, 39, 14, -69, 42, 22, -78, 60, 23, -83, 33, 44, -74, 19, 69, -113, 43, 53, -88, 51, 17, -74, 42, 1, -38, 4, 39, -67, 12, 35, -39, -23, 73, -82, -5, 67, -71, -5, 42, -36, -48, 78, -64, -4, 40, -48, -7, 50, -80, 17, 31, -56, 9, 6, -18, -36, 43, -37, -29, 47, -47, -18, 33, -29, -27, 40, -30, -37, 51, -46, -25, 61, -66, 7, 28, -48, 30, -15, -8, -6, 17, -14, -9, 26, -23, 4, 9, -15, 12, -9, 16, -22, 7, 22, -51, 59, -29, -23, 54, -49, 6, 20, -19, -11, 17, -3, -30, 32, -27, -5, 16, -28, 4, 4, -27, 32, -46, 27, -18, -8, 11, -25, 18, -6, -17, 10, 1, -18, 24, -33, 10, 8, -12, -10, 21, -19, 0, 8, -18, 14, 11, -44, 39, -22, -4, -6, 11, -15, -13, 17, -17, -6, 13, -22, -1, 7, -5, -8, 0, 4, -24, 29, -23, 0, 20, -25, -8, 30, -34, 31, -29, 11, -9, 21, -15, -1, 10, -9, -11, 32, -23, -2, -14, 27, -19, 10, -4, -23, 14, 13, -45, 48, -44, 11, -4, -7, -3, 4, -2, -34, -8, 37, -41, 20, -24, -4, -10, 2, 4, 12, -28, -30, 9, 32, -16, 6, -46, -23, 60, 0, -22, -3, -23, -15, 48, 12, -34, -17, -18, 10, 46, -1, -56, -8, 12, 9, 18, 13, -72, -3, 26, 9, 28, -14, -89, 15, 67, -18, 1, -19, -52, 45, 26, -8, -5, -25, -25, 36, 38, -13, -36, -18, -6, 55, 23, -51, -14, 4, 6, 25, 24, -41, -44, 38, 19, 10, 10, -59, -14, 42, 1, 6, -8, -43, -1, 43, 10, -30, -10, -36, 18, 35, -20, -14, -11, -19, 9, 20, -5, -22, -9, -6, 13, 26, -30, -23, 4, 1, 20, 9, -20, -22, 3, -1, 17, 28, -26, -25, 16, -2, -4, 12, -10, -16, 24, -2, -18, 17, -27, -1, 36, -6, -7, -4, -26, 6, 29, -3, -17, -6, -4, 18, 18, -26, -10, -4, 6, 30, -1, -6, -24, 0, 24, 12, 2, -16, -25, 13, 32, -3, -4, -3, -24, 15, 16, -7, 8, -20, -13, 36, 9, -24, -11, -10, 10, 20, -1, -13, -10, -9, 20, 17, -12, -9, -15, 9, 20, -11, -14, -6, 5, 10, 6, 5, -7, -11, 7, 19, 1, 3, -11, -10, 24, 14, -16, 2, -9, 11, 14, 7, -1, -11, -4, 15, 24, 3, -24, -4, 4, 15, 13, -3, -15, 0, 15, 8, 2, 0, -19, 16, 12, -1, 7, -13, -2, 18, 3, -3, 5, -9, -10, 12, 9, -2, 8, -9, 4, 9, 6, 1, -8, 10, 4, -2, 11, -14, 3, 5, 1, 9, 4, -15, 0, 10, 1, 5, -4, -10, 3, 7, -1, 8, -13, 1, 4, 10, 6, -9, -3, 1, 6, 14, -3, -4, 4, -10, 10, 13, -1, -4, 5, -3, 10, 13, -13, 4, 7, 1, 8, -1, 1, 4, 5, 4, 11, -5, -2, 1, 8, 6, 1, 3, -1, -5, 11, 3, -3, 4, -5, -1, 17, -4, -2, 6, -10, 10, 10, -4, 2, 3, -10, 10, 5, -2, -2, -1, 4, 3, -1, -2, -4, 1, 6, -4, 6, -4, -10, 8, 2, -4, 6, -4, -4, 12, -2, 2, 6, -9, 3, 2, 0, 7, -5, -3, 3, 2, 4, -4, -2, 7, 3, 5, 9, -3, 1, 12, -3, 7, 6, -9, 4, 9, -4, 12, 1, -7, 9, 2, 1, 10, -3, 1, 0, 0, 8, 0, -1, 5, -2, 8, 1, -3, 10, 2, 0, 11, -4, -1, 6, -3, 2, 3, -5, 4, 0, -5, 5, -3, 1, 3, 0, 4, -3, -3, 4, -2, -2, 5, -2, -1, 6, -5, 2, 3, -4, 4, -2, -3, 11, -8, 0, 5, -1, 1, 0, -3, 4, 2, 2, 6, -2, 4, 5, -3, 4, 7, -4, 11, -1, 0, 3, 0, 3, 7, -2, 5, 1, 0, 6, 3, 2, 4, -1, 2, 6, 0, 3, 5, -4, 6, 0, 2, 7, -4, -1, 2, -2, 7, 1, -1, 1, -2, 2, 4, -5, 0, 4, -1, 2, -1, -2, 1, -2, 3, 2, -3, 3, -1, -4, 5, -2, -2, 3, 0, -1, 2, -5, 2, 1, -4, 0, 1, -3, 5, -2, 2, 2, -3, 1, 3, -2, 3, 1, -2, 4, 1, 2, 5, -2, 3, 1, 2, 5, 0, -1, 4, 0, 1, 4, 2, 4, 4, -2, 0, 2, 3, 5, 0, 0, 0, 1, 5, -2, -3, 4, 0, 1, 2, -2, -4, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -13, -14, -16, -18, -21, -25, -29, -34, -36, -38, -39, -40, -42, -44, -47, -50, -53, -56, -58, -59, -58, -55, -50, -44, -38, -31, -24, -18, -13, -9, -6, -3, 0, 3, 6, 9, 13, 17, 21, 27, 33, 42, 53, 63, 74, 83, 91, 98, 104, 108, 111, 113, 115, 118, 119, 121, 123, 125, 126, 127, 127, 127, 127, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 126, 125, 123, 121, 118, 114, 111, 107, 104, 101, 100, 99, 98, 98, 98, 98, 98, 99, 98, 98, 97, 95, 92, 88, 81, 73, 63, 54, 46, 39, 33, 29, 27, 25, 24, 22, 20, 18, 14, 10, 5, 0, -5, -8, -8, -7, -3, 2, 8, 14, 19, 23, 26, 28, 29, 30, 31, 32, 32, 31, 30, 28, 24, 20, 14, 9, 4, -1, -4, -7, -9, -10, -12, -13, -15, -17, -19, -22, -24, -25, -25, -23, -21, -19, -17, -15, -15, -14, -15, -15, -16, -17, -17, -17, -16, -16, -16, -17, -19, -22, -25, -30, -35, -39, -44, -47, -50, -53, -56, -58, -61, -63, -64, -65, -65, -63, -60, -55, -49, -43, -38, -34, -32, -31, -31, -32, -33, -35, -36, -37, -37, -36, -35, -34, -34, -34, -36, -39, -43, -49, -55, -61, -67, -72, -77, -81, -85, -88, -90, -92, -94, -94, -95, -94, -94, -94, -94, -95, -96, -98, -100, -102, -104, -105, -107, -108, -108, -109, -110, -110, -110, -109, -109, -109, -108, -108, -109, -109, -109, -109, -108, -108, -107, -106, -106, -105, -105, -105, -105, -105, -105, -104, -103, -101, -98, -93, -88, -82, -76, -70, -64, -58, -52, -47, -42, -38, -34, -31, -29, -27, -25, -22, -18, -13, -7, -1, 6, 13, 20, 26, 32, 37, 41, 45, 48, 51, 55, 58, 63, 68, 73, 77, 82, 85, 89, 91, 94, 96, 97, 98, 99, 99, 99, 100, 100, 100, 101, 101, 101, 101, 101, 101, 99, 97, 95, 93, 90, 87, 84, 81, 77, 73, 67, 60, 51, 40, 29, 17, 6, -5, -14, -23, -31, -38, -45, -52, -58, -65, -70, -75, -80, -84, -87, -90, -92, -94, -95, -96, -97, -98, -100, -101, -102, -102, -103, -103, -104, -104, -103, -102, -100, -97, -93, -89, -86, -82, -79, -77, -75, -72, -70, -67, -63, -59, -53, -47, -40, -33, -26, -20, -14, -9, -6, -3, 0, 3, 6, 9, 13, 17, 21, 26, 31, 37, 44, 51, 58, 64, 70, 75, 79, 83, 86, 88, 90, 92, 93, 95, 96, 97, 98, 100, 100, 101, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 102, 102, 102, 101, 100, 98, 96, 94, 92, 90, 89, 88, 88, 87, 87, 87, 87, 87, 86, 85, 84, 82, 79, 76, 72, 67, 61, 55, 49, 43, 39, 35, 32, 30, 29, 27, 25, 24, 21, 18, 15, 12, 8, 5, 3, 3, 4, 6, 9, 12, 15, 18, 21, 23, 25, 27, 28, 30, 31, 31, 31, 30, 28, 25, 22, 18, 14, 10, 7, 5, 3, 1, 0, -2, -4, -6, -9, -11, -14, -16, -17, -17, -16, -14, -12, -11, -9, -9, -9, -10, -11, -12, -13, -14, -15, -15, -16, -16, -17, -19, -22, -26, -30, -34, -38, -42, -45, -48, -50, -52, -53, -54, -55, -56, -56, -55, -53, -50, -46, -42, -38, -35, -32, -31, -30, -31, -31, -33, -34, -35, -36, -36, -36, -35, -35, -35, -36, -38, -41, -45, -49, -54, -59, -64, -68, -73, -76, -80, -83, -86, -88, -89, -90, -91, -91, -91, -92, -92, -93, -95, -96, -98, -100, -101, -102, -103, -104, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -104, -104, -103, -102, -102, -101, -100, -100, -100, -99, -99, -99, -98, -96, -94, -91, -86, -82, -76, -71, -65, -59, -53, -48, -42, -37, -32, -28, -25, -22, -19, -16, -13, -8, -3, 3, 9, 16, 22, 28, 35, 40, 45, 49, 53, 56, 60, 63, 67, 71, 76, 80, 85, 88, 92, 94, 97, 99, 100, 102, 103, 103, 104, 104, 104, 104, 105, 105, 105, 105, 105, 104, 103, 101, 99, 97, 94, 91, 87, 84, 80, 76, 71, 65, 57, 48, 39, 28, 18, 8, -2, -11, -19, -27, -34, -41, -47, -54, -60, -65, -70, -75, -79, -82, -85, -87, -89, -91, -92, -94, -95, -96, -97, -98, -99, -100, -100, -100, -100, -100, -98, -96, -94, -90, -87, -84, -81, -78, -76, -73, -71, -68, -65, -61, -57, -52, -46, -40, -33, -27, -21, -15, -11, -7, -4, 0, 3, 7, 11, 15, 20, 24, 29, 35, 41, 48, 54, 61, 67, 72, 77, 81, 85, 88, 90, 92, 94, 95, 97, 98, 99, 101, 102, 103, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 104, 104, 103, 101, 99, 98, 96, 95, 93, 93, 92, 92, 91, 91, 90, 90, 88, 87, 86, 84, 81, 78, 74, 69, 64, 59, 54, 49, 45, 42, 39, 37, 35, 33, 31, 29, 27, 24, 21, 18, 15, 13, 11, 11, 12, 13, 15, 17, 20, 22, 24, 25, 27, 28, 29, 30, 31, 31, 31, 30, 28, 26, 23, 20, 17, 14, 11, 9, 8, 6, 5, 3, 1, -1, -4, -6, -8, -10, -11, -11, -11, -10, -9, -8, -8, -8, -9, -10, -11, -13, -14, -15, -16, -17, -17, -18, -20, -22, -25, -28, -31, -35, -38, -41, -44, -46, -47, -49, -50, -51, -52, -52, -52, -51, -49, -47, -44, -40, -38, -35, -33, -33, -32, -33, -33, -34, -35, -36, -37, -38, -38, -38, -38, -39, -40, -42, -45, -49, -53, -57, -61, -65, -69, -73, -76, -79, -82, -85, -87, -88, -89, -90, -91, -91, -92, -93, -94, -95, -97, -98, -99, -100, -101, -102, -103, -103, -104, -104, -104, -104, -104, -104, -104, -104, -104, -103, -103, -103, -102, -102, -101, -100, -99, -99, -98, -97, -97, -96, -96, -95, -94, -92, -89, -86, -82, -77, -72, -67, -61, -56, -50, -45, -39, -34, -29, -25, -21, -18, -14, -11, -5, 4, 8, 14, 19, 25, 31, 37, 42, 47, 52, 57, 61, 65, 69, 72, 76, 79, 83, 86, 89, 92, 95, 97, 99, 101, 102, 104, 104, 105, 106, 106, 106, 106, 106, 106, 105, 104, 104, 103, 101, 99, 97, 95, 92, 89, 85, 81, 77, 73, 68, 62, 57, 50, 43, 35, 28, 19, 12, 4, -4, -11, -18, -25, -32, -38, -44, -50, -55, -61, -65, -69, -73, -77, -80, -82, -85, -87, -89, -91, -92, -93, -95, -95, -96, -97, -97, -97, -96, -96, -95, -93, -92, -90, -88, -86, -84, -82, -79, -77, -74, -71, -68, -64, -60, -55, -51, -46, -41, -36, -31, -26, -21, -16, -11, -7, -2, 3, 8, 14, 19, 25, 30, 36, 42, 47, 53, 58, 63, 68, 72, 76, 79, 82, 85, 87, 89, 91, 93, 95, 96, 98, 99, 101, 102, 103, 103, 104, 105, 105, 105, 106, 106, 106, 106, 106, 106, 106, 105, 105, 105, 104, 103, 103, 102, 101, 100, 99, 99, 98, 97, 96, 95, 93, 92, 91, 89, 87, 85, 82, 79, 76, 73, 70, 67, 63, 60, 58, 55, 53, 50, 48, 46, 44, 41, 39, 37, 34, 32, 31, 29, 28, 28, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 29, 29, 28, 27, 26, 25, 23, 22, 20, 19, 17, 16, 15, 13, 12, 10, 8, 6, 4, 2, 1, -1, -2, -4, -5, -6, -7, -9, -10, -12, -13, -15, -17, -19, -21, -22, -24, -26, -27, -29, -31, -32, -34, -36, -38, -40, -42, -43, -45, -46, -47, -47, -48, -48, -49, -49, -48, -48, -47, -46, -45, -44, -44, -43, -43, -43, -44, -44, -45, -46, -47, -48, -49, -50, -51, -52, -53, -55, -57, -59, -61, -64, -67, -70, -72, -75, -78, -80, -82, -84, -86, -88, -90, -91, -92, -94, -95, -96, -97, -98, -98, -99, -100, -101, -101, -101, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -101, -101, -100, -100, -99, -98, -97, -96, -95, -94, -93, -92, -91, -89, -88, -87, -85, -83, -81, -78, -75, -71, -67, -63, -58, -54, -49, -44, -39, -33, -28, -23, -18, -13, -8, -3, 2, 7, 13, 18, 23, 29, 35, 40, 45, 51, 55, 60, 64, 68, 71, 75, 78, 82, 85, 88, 91, 93, 96, 98, 100, 101, 103, 104, 105, 105, 106, 106, 106, 106, 105, 105, 104, 104, 103, 101, 100, 98, 95, 93, 90, 86, 83, 79, 75, 70, 65, 60, 54, 47, 40, 33, 25, 18, 10, 2, -5, -12, -19, -26, -32, -38, -44, -50, -55, -60, -65, -69, -73, -76, -79, -82, -84, -87, -89, -90, -92, -93, -94, -95, -96, -96, -96, -96, -96, -95, -94, -93, -91, -90, -88, -86, -84, -81, -79, -76, -74, -70, -67, -63, -59, -54, -49, -44, -39, -34, -29, -24, -19, -14, -10, -5, -2, -1, 3, -2, 1, -3, 4, -2, 0, 0, 8, 0, 10, -9, -7, -128, -72, 13, -44, -13, -18, 4, -4, 12, 3, 31, 4, 66, 74, 38, 38, 36, 30, 25, 22, 18, 13, 7, 5, 2, 1, -5, -7, -9, -9, -11, -14, -12, -14, -12, -16, -13, -16, -13, -14, -16, -11, -14, -10, -13, -11, -13, -8, -8, -6, -6, -5, 0, -6, -3, -3, 3, -4, 6, -13, 17, -5, -5, 15, -1, -23, 6, 23, 28, 35, 13, 41, -3, 24, 25, -4, 6, 30, 4, 18, 10, -32, -64, -120, -64, -91, -76, -33, -45, -58, 2, 1, -19, -14, 18, 48, 50, 59, 51, 53, 47, 46, 41, 37, 35, 26, 28, 19, 21, 10, 13, 9, 3, 5, -4, 2, -5, -3, -8, -5, -8, -8, -10, -9, -10, -10, -12, -7, -17, -8, -11, -14, -5, -15, -5, -4, -10, -13, 11, -22, 3, -3, -4, -5, -11, 13, 2, -16, -9, -5, -12, 27, 15, 17, 21, 20, 20, 8, 14, 13, 0, 10, 35, 10, -1, -12, -52, -89, -78, -58, -85, -74, -51, -25, -25, -28, -30, -14, 12, 29, 44, 44, 51, 46, 50, 49, 43, 38, 36, 32, 29, 23, 19, 17, 14, 10, 6, 6, 2, 4, -8, 3, -7, -3, -6, -7, -11, -4, -12, -7, -6, -20, 1, -15, -14, -8, -7, -10, -10, -10, 2, -14, -12, 7, -10, -8, -5, -6, 1, 6, -2, -12, -19, -3, 3, 2, 19, 19, 14, 19, 24, 13, 5, 12, 12, 13, 21, 29, 5, -18, -43, -48, -64, -82, -82, -71, -44, -37, -37, -40, -33, -23, 5, 20, 33, 38, 45, 48, 51, 46, 44, 41, 38, 36, 27, 26, 24, 19, 13, 16, 5, 11, 4, -1, 3, -4, -3, 1, -9, -7, -2, -9, -6, -13, -4, -6, -17, -8, -6, -15, -10, -5, -10, -8, -10, -5, -7, -5, -2, -14, -10, 3, 5, -4, -3, -10, -17, -10, 3, 4, 5, 18, 18, 18, 16, 16, 10, 5, 11, 23, 26, 22, 7, -9, -16, -37, -62, -80, -76, -65, -46, -43, -43, -51, -41, -24, -4, 11, 24, 32, 41, 47, 43, 49, 45, 41, 40, 33, 31, 31, 20, 23, 18, 11, 16, 9, 5, 3, 2, 5, -2, -7, 2, -4, -10, -3, -5, -8, -10, -7, -8, -14, -10, -8, -11, -9, -6, -14, -10, -2, -3, -12, -10, -7, -9, 0, 6, -1, -11, -12, -11, -10, -7, 4, 7, 12, 17, 20, 18, 13, 6, 8, 19, 22, 24, 17, 14, 5, -8, -29, -54, -77, -71, -55, -50, -44, -54, -57, -39, -32, -15, 3, 15, 31, 34, 39, 47, 45, 44, 44, 37, 37, 33, 28, 27, 18, 20, 21, 10, 7, 10, 7, 1, 2, 2, 0, -5, 0, -2, -7, -3, -5, -8, -8, -5, -13, -13, -5, -6, -14, -11, -8, -8, -5, -5, -9, -17, -10, -2, 0, -2, -1, -9, -12, -14, -12, -6, -1, 3, 11, 19, 19, 14, 7, 9, 13, 17, 23, 22, 19, 21, 12, 2, -21, -55, -65, -59, -52, -47, -56, -56, -50, -53, -38, -22, -7, 10, 18, 29, 36, 40, 45, 43, 38, 41, 40, 32, 27, 26, 26, 19, 17, 17, 12, 9, 9, 6, 2, 4, 4, -1, -2, 2, -3, -3, 0, -2, -8, -9, -7, -7, -7, -6, -8, -12, -6, -4, -7, -12, -13, -10, -5, -2, -2, -3, -8, -12, -15, -16, -14, -13, -7, 2, 8, 11, 8, 4, 5, 8, 13, 20, 22, 23, 24, 23, 19, 6, -13, -23, -29, -32, -37, -42, -46, -53, -57, -53, -49, -39, -25, -12, -1, 10, 21, 28, 32, 35, 36, 34, 34, 32, 28, 25, 24, 21, 18, 19, 16, 10, 7, 8, 9, 8, 6, 5, 2, 3, 6, 7, 5, 2, -2, -4, -3, -1, -3, -4, -3, -1, -3, -8, -13, -14, -11, -4, -1, -2, -4, -6, -11, -16, -19, -21, -21, -17, -9, -3, 0, 0, -3, -5, -2, 4, 11, 18, 23, 25, 26, 24, 17, 10, 5, -1, -7, -12, -20, -29, -37, -44, -51, -55, -54, -47, -39, -28, -16, -4, 9, 18, 23, 27, 31, 31, 30, 30, 28, 23, 20, 22, 23, 20, 14, 10, 9, 9, 10, 9, 6, 4, 4, 6, 9, 10, 7, 2, 0, 1, -1, -2, -2, -1, 1, 2, -2, -10, -14, -11, -8, -5, -2, -1, -3, -6, -9, -14, -20, -23, -23, -18, -11, -5, -3, -4, -6, -8, -4, 2, 7, 14, 21, 25, 25, 23, 19, 13, 8, 4, -1, -9, -15, -23, -31, -39, -48, -53, -51, -48, -44, -34, -20, -8, 3, 12, 20, 24, 27, 30, 31, 29, 24, 22, 22, 23, 22, 18, 13, 10, 10, 11, 11, 9, 5, 3, 5, 10, 11, 9, 7, 5, 4, 2, 0, -3, -1, 3, 5, 2, -3, -8, -11, -10, -7, -5, -3, -2, -2, -4, -7, -14, -20, -24, -24, -19, -12, -6, -6, -8, -8, -8, -7, -2, 5, 12, 19, 23, 24, 22, 20, 16, 12, 7, 1, -5, -10, -17, -27, -36, -42, -47, -52, -51, -45, -36, -26, -12, 0, 9, 15, 21, 27, 30, 29, 26, 23, 22, 23, 23, 21, 17, 12, 9, 10, 12, 10, 6, 3, 4, 7, 10, 11, 9, 8, 9, 7, 2, -1, 0, 2, 6, 6, 3, -2, -7, -9, -8, -6, -4, -3, -1, -1, -2, -6, -13, -21, -26, -24, -18, -13, -10, -9, -10, -11, -11, -10, -5, 3, 10, 17, 21, 22, 22, 21, 19, 14, 8, 5, 1, -7, -14, -21, -29, -38, -45, -49, -50, -48, -40, -28, -16, -6, 3, 11, 19, 26, 27, 26, 24, 22, 22, 24, 24, 20, 14, 11, 11, 12, 11, 8, 4, 3, 6, 8, 9, 9, 10, 11, 10, 6, 2, 0, 2, 5, 8, 7, 3, -2, -5, -6, -7, -6, -4, -3, -1, 1, 1, -5, -13, -21, -24, -23, -18, -14, -12, -11, -12, -13, -14, -13, -8, 0, 8, 14, 17, 21, 22, 21, 18, 15, 12, 8, 2, -3, -9, -16, -24, -32, -40, -47, -51, -49, -41, -30, -21, -12, -1, 9, 17, 23, 25, 24, 21, 21, 24, 24, 22, 17, 12, 11, 13, 12, 8, 4, 3, 4, 6, 7, 7, 9, 11, 12, 10, 6, 3, 3, 6, 9, 10, 8, 5, 1, -2, -3, -3, -2, -1, 1, 3, 3, 1, -5, -12, -18, -20, -20, -18, -16, -16, -16, -17, -19, -20, -17, -11, -5, 1, 8, 13, 17, 18, 18, 17, 16, 14, 11, 7, 2, -3, -8, -14, -22, -34, -43, -46, -42, -35, -28, -20, -11, -2, 7, 15, 19, 19, 19, 19, 20, 20, 17, 14, 11, 10, 9, 7, 1, -4, -6, -4, 0, 2, 4, 6, 7, 8, 9, 8, 7, 7, 10, 13, 15, 15, 13, 9, 6, 3, 2, 4, 7, 9, 11, 11, 7, 1, -5, -10, -13, -14, -14, -14, -16, -19, -23, -26, -28, -27, -23, -18, -13, -7, -1, 6, 11, 14, 15, 14, 14, 15, 15, 12, 7, 2, -1, -4, -11, -22, -34, -41, -40, -34, -26, -19, -12, -4, 4, 10, 14, 17, 17, 18, 19, 18, 15, 12, 10, 9, 8, 6, 0, -6, -11, -10, -6, -1, 3, 5, 6, 6, 6, 7, 7, 8, 10, 13, 16, 18, 17, 13, 9, 5, 3, 4, 7, 11, 13, 14, 11, 5, -2, -7, -11, -12, -12, -13, -14, -17, -22, -26, -28, -29, -27, -22, -17, -11, -5, 1, 7, 12, 14, 14, 13, 14, 15, 14, 11, 5, 0, -2, -6, -15, -27, -37, -42, -38, -31, -24, -17, -9, -1, 6, 12, 15, 17, 18, 19, 19, 17, 13, 11, 9, 9, 8, 4, -2, -8, -11, -9, -4, 1, 4, 5, 6, 6, 6, 7, 7, 9, 11, 14, 17, 18, 16, 12, 8, 4, 3, 5, 9, 12, 14, 13, 9, 2, -4, -9, -12, -13, -12, -13, -15, -19, -23, -27, -29, -28, -25, -20, -15, -9, -3, 3, 9, 13, 15, 14, 13, 15, 15, 13, 9, 3, -1, -3, -9, -19, -31, -40, -41, -36, -28, -21, -14, -6, 2, 9, 13, 16, 17, 18, 19, 18, 16, 12, 10, 9, 9, 7, 2, -4, -10, -11, -8, -2, 2, 5, 5, 6, 6, 7, 7, 8, 9, 12, 16, 18, 17, 14, 10, 6, 4, 4, 6, 10, 13, 14, 12, 7, 0, -6, -10, -12, -13, -13, -14, -16, -21, -25, -28, -29, -28, -24, -18, -13, -7, -1, 6, 11, 14, 15, 13, 14, 15, 15, 12, 7, 2, -1, -5, -12, -23, -35, -41, -40, -34, -26, -19, -12, -3, 4, 10, 14, 17, 18, 18, 19, 18, 14, 11, 9, 9, 8, 6, 0, -7, -11, -10, -6, 0, 2, -1, -2, -9, -24, 4, -3, 3, -3, 10, 7, 4, 13, -4, 1, 3, 3, 0, 2, 8, -9, -9, 2, 1, -1, 7, 17, 21, 37, 25, 13, 14, -2, 15, 20, 5, 0, -3, -7, -27, -14, -18, -19, -29, -20, -4, -18, -32, -30, -30, -29, -32, -22, -26, -19, -19, -1, -6, 4, 7, 5, 2, 0, -8, -16, -12, -13, -17, -17, 19, 20, 24, 16, 8, -4, 8, 0, 13, 28, 33, 16, 11, 5, -3, -1, 4, 12, 12, 40, 20, 11, 4, 5, 8, -1, 2, 5, 5, 22, 13, 21, 8, 9, 18, 20, 13, 20, 26, 11, 24, 17, 10, 27, 30, 22, 28, 30, 41, 47, 57, 36, 36, 20, -16, 4, 6, -19, -21, -41, -39, -33, -38, -41, -46, -42, -36, -18, -37, -65, -75, -77, -78, -62, -63, -62, -68, -63, -63, -44, -50, -30, -41, -43, -26, -34, -35, -36, -45, -49, -27, 1, -6, -4, -7, -20, -16, -20, -21, -13, 2, -6, -1, -12, 0, -1, 15, 19, 20, 26, 37, 40, 46, 37, 50, 35, 34, 41, 43, 51, 54, 55, 50, 56, 47, 59, 51, 51, 75, 67, 66, 71, 59, 60, 72, 75, 72, 80, 79, 82, 98, 99, 87, 93, 62, 49, 58, 41, 42, 28, 5, -6, -6, -18, -24, -23, -30, -25, -20, -38, -60, -75, -77, -80, -75, -71, -75, -70, -73, -69, -76, -60, -66, -71, -66, -57, -62, -61, -61, -87, -90, -69, -63, -46, -31, -35, -47, -42, -53, -63, -53, -45, -33, -36, -39, -37, -43, -39, -34, -30, -19, -9, 2, -9, -1, -3, 1, -3, 5, 7, 15, 24, 22, 23, 20, 32, 43, 33, 48, 63, 67, 70, 68, 52, 59, 73, 73, 77, 85, 73, 81, 103, 98, 116, 115, 87, 80, 76, 72, 69, 60, 37, 27, 29, 12, 19, 4, -12, 1, 3, -3, -31, -42, -57, -67, -67, -61, -61, -61, -48, -58, -51, -41, -46, -48, -40, -35, -33, -26, -36, -67, -68, -65, -59, -47, -28, -34, -37, -36, -52, -61, -61, -47, -34, -39, -39, -42, -42, -48, -36, -38, -37, -20, -19, -16, -16, -18, -20, -22, -26, -22, -16, -15, 1, -4, -6, 10, 12, 13, 22, 32, 41, 54, 52, 44, 54, 66, 61, 78, 81, 71, 87, 89, 99, 119, 107, 91, 77, 76, 69, 76, 68, 47, 49, 35, 33, 37, 22, 14, 24, 37, 26, 13, -10, -26, -41, -43, -34, -40, -34, -33, -43, -39, -25, -27, -27, -18, -25, -15, -1, -10, -29, -42, -39, -39, -19, -7, -10, -10, -11, -20, -35, -44, -33, -30, -28, -36, -34, -47, -41, -36, -46, -42, -34, -27, -29, -25, -34, -30, -32, -40, -36, -36, -31, -16, -25, -25, -15, -21, -14, -9, -11, 1, 17, 15, 9, 25, 20, 25, 46, 39, 46, 50, 51, 68, 85, 87, 72, 65, 52, 50, 59, 44, 42, 29, 23, 22, 23, 11, -5, 8, 14, 19, 8, -6, -23, -38, -43, -42, -48, -41, -34, -42, -38, -19, -23, -16, -15, -19, -10, 8, 8, -9, -18, -27, -30, -10, -4, 7, 6, 15, 8, -8, -17, -15, -8, -11, -3, -15, -17, -14, -16, -27, -30, -26, -22, -19, -21, -22, -19, -30, -27, -26, -36, -22, -9, -13, -10, -10, -8, -9, -6, -12, -1, 16, 6, 11, 16, 6, 19, 24, 27, 38, 38, 38, 48, 71, 72, 78, 66, 51, 54, 52, 49, 42, 32, 21, 25, 26, 13, 1, -1, 10, 15, 8, 1, -22, -38, -47, -56, -58, -46, -43, -46, -33, -25, -17, -11, -9, -19, -9, 16, 18, 12, 1, -17, -18, -9, 3, 9, 17, 24, 26, 9, -4, -1, -6, 2, 9, 0, -2, 2, -3, -13, -16, -15, -8, -8, -8, -1, -6, -17, -11, -22, -24, -16, -12, -9, -9, -9, -9, -6, -8, -16, 2, 6, 2, 13, 9, 7, 10, 17, 19, 30, 31, 22, 37, 49, 61, 70, 56, 43, 37, 36, 31, 32, 15, 4, 11, 9, 4, -14, -16, -7, -5, -1, -8, -28, -46, -56, -75, -74, -67, -70, -67, -62, -55, -47, -36, -32, -42, -28, -9, 1, 4, -4, -17, -30, -18, -12, -2, 4, 15, 21, 7, 1, -7, -6, -1, 7, 0, 0, 3, -3, -8, -15, -18, -6, -9, -6, 5, -2, -2, 0, -7, -12, -7, -3, 2, 7, 3, 4, 14, 2, 1, 12, 11, 17, 20, 19, 16, 19, 20, 24, 39, 36, 37, 42, 55, 71, 84, 76, 63, 56, 47, 49, 46, 29, 18, 14, 18, 11, -5, -11, -8, -3, 4, 4, -16, -27, -44, -60, -64, -59, -62, -62, -55, -55, -47, -28, -32, -35, -29, -15, -3, 4, 3, -15, -25, -24, -13, -11, -3, 10, 14, 12, 4, -5, -9, -1, 2, -1, 1, 1, -1, -7, -17, -16, -12, -17, -8, 0, -1, -1, -2, -8, -13, -9, -9, 0, 9, 1, 14, 16, 6, 7, 10, 12, 18, 26, 20, 22, 22, 16, 25, 32, 36, 34, 36, 43, 60, 75, 72, 67, 52, 44, 50, 45, 38, 17, 14, 17, 11, -2, -9, -14, -10, 0, -4, -12, -24, -41, -59, -67, -63, -70, -69, -62, -70, -55, -40, -38, -42, -38, -29, -16, -3, -3, -9, -29, -31, -25, -26, -20, -7, 0, 2, -1, -14, -18, -14, -14, -12, -10, -10, -4, -13, -21, -19, -22, -24, -16, -10, -6, -2, -2, -10, -12, -15, -17, -4, -4, -5, 7, 9, 3, 4, 7, 5, 18, 23, 22, 28, 25, 22, 27, 34, 39, 43, 38, 41, 62, 71, 79, 78, 62, 55, 55, 57, 49, 31, 23, 30, 21, 15, 7, -5, 1, 8, 9, 8, -3, -16, -39, -46, -50, -60, -55, -58, -62, -53, -36, -33, -34, -34, -29, -18, -6, 5, -2, -17, -23, -22, -24, -17, -8, 1, 9, 10, -4, -7, -8, -9, -6, -9, -6, 0, -11, -14, -14, -21, -24, -21, -16, -10, 1, -3, -3, -5, -14, -11, -7, -7, -5, 6, 9, 4, 8, 1, 3, 11, 16, 20, 26, 24, 20, 25, 29, 36, 41, 32, 40, 51, 64, 77, 78, 67, 55, 54, 57, 53, 33, 27, 25, 22, 20, 9, -3, -3, 3, 7, 6, 4, -16, -32, -42, -55, -60, -61, -64, -70, -62, -49, -39, -41, -40, -37, -33, -18, -5, -8, -16, -24, -29, -31, -28, -24, -15, -1, 1, -7, -11, -14, -13, -14, -18, -11, -8, -14, -16, -16, -25, -31, -29, -31, -20, -12, -13, -6, -11, -19, -19, -14, -17, -12, -1, 2, 6, 7, 2, 4, 8, 11, 18, 24, 21, 22, 19, 21, 33, 33, 32, 32, 40, 55, 71, 76, 72, 58, 55, 62, 56, 42, 34, 28, 29, 26, 17, 4, 2, 6, 4, 13, 12, -4, -18, -30, -45, -50, -51, -59, -63, -61, -47, -37, -33, -32, -34, -32, -19, -4, -3, -5, -13, -21, -23, -22, -24, -13, 1, 5, 5, -3, -6, -1, -7, -9, -2, 1, -2, -2, -4, -13, -16, -22, -22, -15, -10, -4, 2, -1, -11, -8, -7, -12, -6, 1, 6, 12, 11, 8, 9, 9, 9, 20, 23, 26, 25, 20, 24, 32, 34, 35, 33, 35, 49, 63, 74, 74, 58, 55, 60, 54, 45, 33, 27, 25, 26, 19, 6, 4, 1, 1, 9, 12, -1, -10, -26, -43, -50, -54, -61, -70, -69, -61, -50, -43, -40, -44, -44, -34, -18, -12, -9, -15, -24, -25, -28, -31, -22, -12, -2, 1, -8, -8, -5, -12, -14, -8, -8, -8, -5, -9, -11, -18, -27, -26, -22, -19, -12, -1, -4, -9, -8, -11, -14, -12, -8, 0, 7, 5, 5, 6, 0, 3, 8, 13, 20, 18, 13, 15, 22, 27, 29, 25, 26, 36, 51, 70, 71, 59, 56, 57, 55, 47, 37, 25, 24, 27, 17, 9, 3, -2, -2, 8, 9, 6, -2, -16, -34, -44, -47, -54, -63, -66, -63, -55, -44, -39, -42, -44, -35, -23, -11, -4, -10, -16, -17, -23, -25, -22, -13, 1, 6, 1, 1, 4, -2, -4, 1, -1, 4, 3, 2, 2, -3, -12, -15, -14, -15, -7, 3, 5, 3, 2, 1, -2, -4, -4, 3, 9, 10, 13, 11, 9, 8, 9, 15, 22, 22, 20, 19, 21, 27, 30, 28, 28, 28, 42, 61, 69, 65, 60, 60, 58, 55, 47, 35, 30, 30, 24, 18, 10, 0, -1, 2, 6, 7, 3, -8, -24, -36, -43, -50, -59, -65, -66, -62, -52, -43, -43, -44, -41, -35, -21, -12, -12, -13, -17, -23, -26, -30, -24, -12, -4, -5, -3, -2, -5, -6, -6, -5, -3, -2, -1, 2, 2, -5, -3, 2, 8, 17, 26, 32, 42, 50, 56, 68, 73, 64, 63, 65, 48, 56, 71, 48, 49, 50, 26, 30, 30, 16, 25, 21, -2, 0, -13, -15, -2, -19, -17, -16, -50, -49, -49, -81, -85, -88, -108, -112, -116, -127, -126, -113, -113, -106, -79, -65, -48, -17, 5, 20, 41, 58, 63, 69, 59, 28, 17, 0, -32, -41, -52, -69, -63, -61, -59, -41, -26, -19, 6, 28, 33, 52, 67, 70, 81, 87, 84, 90, 93, 84, 72, 69, 60, 45, 56, 57, 40, 46, 39, 25, 29, 25, 16, 21, 12, -1, -3, -11, -8, -5, -16, -12, -21, -41, -38, -48, -68, -70, -77, -91, -93, -98, -106, -103, -93, -92, -82, -60, -47, -30, -4, 13, 27, 44, 56, 60, 62, 47, 23, 13, -8, -32, -40, -54, -64, -59, -59, -53, -36, -26, -14, 12, 27, 36, 56, 66, 72, 84, 86, 86, 93, 92, 82, 73, 70, 57, 49, 59, 52, 43, 47, 37, 29, 30, 24, 18, 18, 7, -2, -6, -11, -7, -10, -16, -14, -29, -42, -42, -57, -71, -73, -83, -93, -96, -102, -107, -101, -93, -90, -75, -55, -41, -22, 3, 19, 33, 50, 59, 61, 60, 41, 21, 10, -14, -33, -43, -57, -63, -60, -61, -51, -36, -27, -9, 15, 26, 40, 59, 66, 74, 85, 85, 88, 94, 90, 80, 75, 69, 56, 54, 60, 50, 47, 46, 36, 31, 30, 23, 19, 15, 4, -3, -7, -10, -9, -14, -17, -19, -35, -44, -47, -63, -73, -77, -88, -96, -98, -104, -107, -99, -92, -86, -69, -50, -35, -14, 9, 24, 38, 54, 60, 61, 56, 36, 19, 4, -20, -35, -46, -60, -62, -61, -60, -48, -35, -25, -3, 17, 27, 45, 60, 66, 77, 85, 86, 91, 94, 88, 80, 75, 67, 56, 58, 59, 50, 49, 45, 36, 33, 30, 23, 19, 13, 2, -5, -8, -10, -11, -16, -18, -25, -40, -45, -53, -68, -76, -81, -91, -97, -100, -106, -106, -97, -90, -81, -63, -44, -28, -6, 15, 28, 44, 57, 61, 61, 52, 31, 16, -1, -24, -37, -50, -61, -62, -62, -59, -46, -35, -22, 1, 18, 30, 48, 61, 68, 79, 85, 87, 92, 93, 86, 80, 75, 66, 58, 60, 58, 51, 50, 44, 37, 33, 29, 23, 17, 10, 0, -6, -9, -10, -14, -18, -21, -31, -43, -48, -59, -72, -78, -85, -94, -99, -102, -107, -104, -95, -88, -76, -56, -39, -22, 2, 20, 33, 49, 59, 61, 60, 47, 27, 12, -7, -27, -40, -53, -62, -62, -63, -57, -44, -34, -18, 5, 19, 33, 51, 61, 70, 81, 85, 88, 94, 92, 85, 80, 74, 65, 60, 62, 57, 52, 50, 43, 37, 33, 28, 22, 15, 8, -2, -7, -10, -12, -16, -20, -24, -36, -46, -52, -64, -75, -81, -89, -97, -100, -104, -107, -102, -93, -85, -70, -50, -33, -14, 8, 25, 38, 53, 61, 61, 58, 42, 24, 8, -12, -30, -43, -56, -62, -63, -63, -54, -43, -32, -13, 7, 20, 37, 53, 62, 72, 82, 85, 89, 94, 90, 84, 80, 73, 64, 62, 62, 56, 53, 49, 43, 37, 33, 27, 20, 14, 5, -3, -8, -11, -13, -18, -22, -28, -40, -49, -57, -69, -78, -84, -92, -99, -102, -105, -106, -99, -90, -81, -64, -44, -27, -7, 14, 29, 43, 56, 61, 61, 54, 37, 20, 4, -17, -33, -46, -58, -62, -64, -62, -52, -42, -29, -9, 9, 23, 40, 55, 64, 74, 83, 86, 91, 93, 89, 84, 80, 72, 65, 64, 62, 56, 53, 49, 42, 37, 33, 26, 19, 12, 3, -5, -8, -12, -16, -20, -24, -33, -44, -52, -61, -73, -80, -87, -95, -100, -103, -106, -104, -96, -88, -76, -57, -38, -21, 0, 20, 33, 47, 59, 62, 60, 51, 33, 17, -1, -21, -36, -49, -59, -63, -64, -61, -51, -40, -25, -5, 11, 26, 43, 56, 65, 76, 83, 87, 92, 93, 88, 84, 79, 71, 65, 65, 61, 56, 53, 48, 42, 37, 32, 25, 17, 10, 1, -6, -10, -13, -18, -22, -27, -37, -48, -55, -65, -76, -83, -90, -97, -101, -104, -106, -102, -94, -84, -71, -51, -33, -15, 7, 24, 38, 51, 60, 62, 59, 46, 29, 13, -6, -25, -39, -52, -60, -63, -64, -59, -49, -38, -21, -1, 14, 29, 46, 57, 67, 78, 84, 88, 92, 92, 87, 83, 78, 70, 66, 65, 61, 57, 53, 48, 42, 37, 31, 23, 15, 7, -1, -7, -11, -15, -20, -24, -31, -41, -51, -59, -69, -79, -85, -93, -99, -102, -105, -106, -100, -91, -80, -65, -45, -27, -8, 13, 29, 42, 55, 61, 61, 56, 42, 25, 8, -11, -28, -42, -54, -61, -64, -64, -57, -47, -35, -17, 1, 16, 33, 48, 59, 69, 79, 84, 89, 93, 91, 87, 83, 77, 70, 67, 65, 60, 57, 53, 47, 41, 36, 29, 21, 14, 5, -3, -8, -12, -17, -22, -27, -35, -45, -54, -63, -73, -81, -88, -95, -100, -103, -105, -104, -97, -88, -76, -58, -39, -21, -1, 18, 33, 46, 58, 62, 61, 53, 38, 21, 4, -15, -31, -45, -56, -62, -65, -64, -56, -46, -32, -13, 4, 19, 36, 50, 61, 71, 80, 85, 90, 92, 90, 86, 82, 76, 70, 68, 65, 60, 57, 52, 46, 41, 35, 27, 19, 12, 3, -5, -9, -14, -19, -24, -29, -38, -48, -57, -66, -76, -84, -91, -97, -101, -104, -105, -102, -94, -84, -71, -52, -33, -15, 5, 23, 37, 50, 60, 62, 60, 50, 34, 17, -1, -19, -35, -48, -58, -63, -65, -62, -54, -43, -28, -10, 7, 22, 39, 52, 62, 73, 81, 86, 91, 92, 89, 86, 82, 75, 70, 68, 64, 60, 57, 52, 46, 40, 34, 26, 17, 9, 1, -6, -11, -15, -21, -26, -32, -42, -52, -60, -70, -79, -86, -93, -99, -102, -104, -105, -100, -91, -80, -65, -46, -27, -9, 11, 28, 42, 54, 61, 62, 58, 46, 30, 13, -6, -23, -38, -51, -60, -64, -65, -61, -52, -41, -25, -6, 9, 26, 42, 54, 64, 75, 82, 87, 91, 91, 89, 85, 81, 74, 71, 68, 64, 60, 56, 51, 45, 39, 32, 24, 16, 7, -1, -7, -12, -17, -23, -28, -36, -45, -55, -64, -73, -82, -88, -95, -100, -103, -105, -104, -97, -88, -76, -59, -40, -22, -2, 17, 32, 45, 57, 62, 62, 56, 42, 26, 9, -10, -27, -41, -53, -61, -65, -65, -60, -50, -38, -21, -3, 12, 29, 44, 55, 66, 76, 82, 88, 91, 91, 88, 85, 80, 74, 71, 68, 63, 60, 56, 50, 44, 38, 30, 22, 14, 5, -3, -9, -14, -19, -25, -31, -39, -49, -58, -67, -77, -84, -91, -97, -101, -103, -105, -102, -95, -84, -71, -53, -34, -16, 4, 22, 37, 49, 59, 63, 61, 53, 38, 22, 4, -14, -30, -44, -56, -62, -66, -65, -58, -48, -35, -17, -1, 15, 32, 46, 57, 68, 77, 83, 88, 91, 90, 88, 84, 79, 74, 71, 67, 63, 60, 55, 49, 43, 37, 28, 20, 12, 3, -5, -10, -15, -21, -27, -33, -43, -52, -61, -70, -79, -86, -93, -98, -102, -104, -104, -100, -92, -81, -66, -47, -28, -10, 10, 27, 40, 53, 61, 63, 59, 49, 34, 18, -1, -18, -34, -47, -58, -63, -66, -64, -56, -46, -31, -14, 2, 18, 35, 48, 59, 70, 78, 84, 89, 91, 90, 87, 83, 78, 74, 71, 67, 63, 59, 54, 49, 42, 35, 27, 18, 9, 1, -6, -12, -17, -23, -29, -36, -46, -55, -64, -73, -82, -89, -95, -100, -102, -104, -103, -97, -88, -76, -60, -41, -23, -4, 15, 31, 44, 55, 62, 62, 57, 46, 30, 13, -5, -22, -37, -50, -59, -64, -66, -62, -55, -43, -28, -11, 5, 22, 37, 50, 61, 71, 79, 85, 89, 91, 89, 87, 82, 77, 73, 70, 66, 63, 59, 53, 47, 41, 33, 24, 16, 7, -1, -8, -14, -19, -25, -32, -40, -49, -58, -67, -76, -84, -91, -96, -101, -103, -104, -102, -95, -85, -72, -55, -37, -18, 1, 19, 34, 47, 57, 62, 62, 56, 43, 28, 10, -8, -25, -39, -52, -60, -65, -66, -62, -53, -42, -25, -9, 8, 24, 39, 51, 62, 72, 80, 86, 90, 90, 89, 86, 82, 77, 73, 70, 66, 62, 58, 53, 47, 40, 33, 24, 15, 6, -2, -8, -14, -19, -25, -32, -40, -49, -58, -67, -72, -103, -18, -76, 0, 0, 0, 0, 1, 2, 3, 5, 6, 0, -7, -8, -15, -9, 10, 8, 17, 33, 14, 5, 38, 44, 31, 63, 70, 51, 73, 82, 68, 85, 100, 96, 97, 103, 115, 114, 112, 127, 122, 110, 116, 113, 109, 120, 120, 118, 113, 91, 93, 109, 97, 98, 115, 110, 109, 120, 112, 94, 75, 63, 69, 72, 64, 64, 59, 45, 39, 36, 35, 42, 42, 24, 5, 2, 3, 4, 7, 9, 11, 14, 17, 19, 14, -3, -20, -26, -30, -26, -24, -31, -32, -34, -40, -39, -33, -34, -45, -56, -60, -66, -64, -55, -60, -62, -56, -59, -58, -50, -56, -70, -73, -76, -86, -77, -70, -80, -76, -71, -77, -71, -66, -76, -85, -82, -90, -95, -80, -82, -92, -85, -86, -94, -85, -79, -86, -92, -90, -94, -101, -92, -85, -90, -84, -77, -78, -74, -73, -85, -86, -85, -95, -85, -77, -90, -88, -83, -94, -93, -83, -81, -81, -86, -89, -89, -94, -88, -77, -77, -71, -59, -58, -59, -63, -72, -74, -77, -73, -61, -67, -72, -67, -73, -80, -74, -68, -60, -56, -65, -70, -67, -72, -66, -52, -49, -40, -27, -27, -32, -39, -47, -50, -42, -30, -31, -34, -32, -38, -46, -46, -43, -35, -20, -16, -24, -30, -30, -31, -24, -13, -6, 4, 13, 11, 3, -5, -9, -2, 12, 15, 15, 16, 9, 3, -2, -5, -1, 12, 24, 30, 29, 20, 17, 22, 25, 30, 41, 47, 49, 46, 37, 32, 41, 52, 54, 60, 61, 52, 48, 45, 36, 35, 43, 51, 60, 67, 69, 60, 57, 63, 63, 64, 73, 75, 72, 69, 63, 67, 78, 78, 82, 89, 80, 73, 76, 67, 60, 64, 67, 73, 79, 83, 88, 82, 75, 80, 81, 77, 83, 83, 76, 74, 77, 83, 85, 86, 94, 89, 80, 82, 78, 69, 68, 68, 69, 78, 80, 81, 90, 83, 73, 79, 77, 70, 73, 70, 62, 65, 73, 75, 76, 84, 82, 70, 71, 69, 59, 57, 54, 48, 53, 63, 64, 68, 76, 66, 57, 58, 51, 42, 40, 33, 28, 37, 46, 49, 55, 56, 42, 37, 37, 27, 22, 20, 10, 4, 8, 15, 24, 30, 31, 24, 14, 8, -3, -14, -21, -26, -26, -15, -4, -1, -4, -13, -21, -26, -34, -39, -42, -50, -57, -63, -66, -60, -47, -43, -48, -51, -57, -66, -75, -82, -88, -91, -88, -78, -74, -81, -86, -85, -92, -101, -100, -102, -109, -109, -110, -112, -113, -115, -109, -106, -113, -113, -107, -110, -110, -106, -108, -112, -109, -110, -114, -111, -98, -95, -98, -93, -93, -98, -94, -89, -81, -69, -65, -71, -73, -73, -77, -73, -62, -56, -48, -40, -41, -45, -47, -47, -37, -20, -11, -4, 5, 4, 3, 6, 9, 16, 30, 39, 47, 51, 44, 40, 45, 47, 50, 59, 64, 66, 68, 65, 65, 75, 80, 78, 87, 95, 91, 93, 98, 96, 98, 104, 100, 96, 99, 104, 101, 100, 106, 107, 105, 108, 109, 109, 110, 111, 110, 101, 87, 82, 84, 81, 82, 88, 89, 90, 91, 85, 71, 57, 49, 48, 51, 52, 55, 59, 58, 58, 60, 61, 61, 57, 42, 24, 14, 7, 5, 9, 11, 15, 20, 21, 19, 11, -3, -18, -27, -33, -31, -25, -24, -21, -16, -16, -14, -11, -17, -29, -40, -49, -59, -61, -55, -54, -52, -45, -42, -41, -41, -48, -59, -65, -72, -81, -79, -72, -73, -69, -62, -61, -59, -60, -69, -76, -79, -87, -92, -84, -81, -82, -76, -72, -71, -67, -66, -72, -79, -81, -87, -94, -92, -87, -86, -82, -76, -75, -75, -78, -85, -87, -91, -96, -91, -82, -83, -80, -74, -74, -71, -64, -64, -68, -73, -77, -81, -87, -88, -82, -79, -76, -70, -69, -72, -76, -80, -84, -87, -82, -71, -67, -64, -58, -57, -55, -49, -43, -39, -40, -47, -54, -58, -64, -66, -61, -58, -54, -49, -50, -55, -59, -63, -65, -58, -45, -38, -32, -25, -24, -23, -18, -13, -5, 3, 4, -2, -11, -17, -23, -26, -23, -20, -18, -15, -18, -24, -28, -28, -21, -7, 3, 11, 18, 20, 19, 22, 24, 30, 40, 47, 51, 49, 40, 32, 28, 24, 23, 25, 25, 23, 20, 15, 15, 23, 34, 43, 51, 59, 59, 58, 59, 58, 60, 67, 73, 78, 84, 85, 78, 71, 68, 63, 60, 60, 57, 53, 50, 50, 56, 65, 70, 76, 84, 84, 81, 81, 79, 76, 79, 84, 87, 91, 96, 98, 94, 88, 85, 81, 76, 73, 70, 66, 66, 70, 76, 80, 84, 91, 92, 87, 86, 83, 78, 76, 78, 81, 85, 88, 91, 96, 93, 86, 83, 78, 71, 68, 64, 61, 64, 71, 74, 78, 84, 86, 80, 76, 72, 64, 59, 56, 55, 59, 66, 69, 74, 79, 76, 69, 64, 57, 48, 43, 39, 39, 45, 52, 56, 62, 63, 55, 47, 41, 31, 21, 15, 8, 5, 9, 16, 24, 31, 35, 33, 26, 19, 10, 0, -6, -9, -7, -7, -13, -17, -22, -26, -31, -34, -37, -40, -42, -44, -46, -48, -50, -51, -54, -56, -58, -61, -64, -67, -70, -74, -78, -82, -86, -90, -93, -97, -99, -102, -104, -106, -108, -109, -110, -111, -112, -113, -113, -114, -114, -115, -115, -115, -115, -115, -114, -113, -111, -109, -107, -104, -100, -97, -93, -90, -87, -84, -82, -80, -78, -76, -74, -73, -71, -69, -67, -65, -61, -58, -53, -48, -42, -35, -28, -21, -13, -6, 1, 8, 15, 21, 26, 31, 35, 38, 41, 44, 46, 48, 50, 52, 55, 58, 61, 64, 68, 72, 76, 80, 83, 87, 90, 92, 94, 96, 98, 99, 100, 101, 102, 102, 103, 103, 103, 103, 104, 103, 103, 103, 102, 101, 99, 97, 94, 92, 88, 85, 81, 78, 74, 71, 67, 64, 61, 58, 55, 53, 51, 49, 47, 46, 44, 42, 40, 37, 34, 30, 26, 22, 17, 12, 8, 3, -1, -5, -9, -13, -16, -20, -23, -26, -29, -31, -33, -35, -37, -38, -40, -42, -44, -46, -48, -51, -54, -56, -59, -61, -64, -65, -67, -69, -70, -72, -74, -75, -77, -78, -80, -81, -82, -83, -84, -85, -86, -86, -87, -88, -89, -90, -90, -91, -92, -92, -92, -92, -92, -92, -91, -91, -92, -92, -92, -93, -93, -94, -94, -94, -95, -95, -95, -95, -95, -95, -95, -95, -95, -94, -93, -92, -91, -90, -89, -87, -86, -85, -85, -85, -84, -84, -85, -85, -85, -85, -85, -85, -85, -85, -85, -84, -83, -82, -81, -79, -77, -75, -73, -70, -68, -65, -63, -62, -60, -59, -59, -59, -59, -59, -59, -59, -60, -59, -59, -59, -58, -57, -55, -53, -50, -47, -44, -40, -36, -32, -29, -25, -22, -20, -18, -17, -16, -15, -15, -16, -16, -16, -16, -16, -16, -15, -13, -11, -9, -6, -2, 2, 6, 10, 15, 19, 22, 26, 29, 31, 33, 35, 36, 36, 36, 36, 35, 35, 35, 35, 35, 36, 38, 40, 42, 45, 48, 52, 55, 58, 61, 64, 67, 70, 72, 73, 74, 75, 76, 76, 76, 75, 75, 74, 74, 74, 74, 74, 75, 77, 78, 80, 82, 83, 85, 87, 89, 90, 91, 92, 93, 94, 94, 94, 94, 94, 93, 93, 92, 91, 91, 90, 90, 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 92, 92, 91, 90, 89, 88, 87, 87, 86, 86, 85, 85, 85, 84, 84, 83, 83, 82, 81, 80, 79, 78, 77, 77, 76, 75, 74, 72, 71, 70, 68, 67, 65, 64, 63, 61, 60, 58, 57, 55, 53, 50, 48, 45, 43, 40, 38, 36, 34, 32, 30, 29, 27, 25, 23, 21, 19, 17, 14, 12, 9, 6, 3, 0, -4, -8, -12, -17, -21, -25, -29, -33, -36, -39, -42, -45, -47, -49, -51, -53, -55, -58, -60, -63, -65, -68, -71, -74, -77, -81, -84, -87, -91, -94, -97, -99, -102, -104, -105, -107, -108, -109, -110, -111, -111, -112, -112, -113, -113, -113, -113, -113, -113, -112, -111, -109, -107, -105, -102, -99, -96, -93, -90, -87, -84, -82, -79, -77, -75, -73, -70, -69, -66, -64, -60, -58, -53, -49, -44, -39, -32, -27, -19, -14, -8, -3, 3, 11, 22, 10, 8, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 7, 5, 7, 5, 6, 4, 6, 4, 4, 4, 4, 3, 3, 2, 3, 1, 3, -2, 2, 0, 0, 0, 0, -2, -1, -2, -3, -3, 0, -5, -1, -2, -2, -2, -1, 0, -3, -1, -1, 0, 1, -1, 0, -1, 0, 0, 1, 0, 0, 1, -1, 1, -1, 1, -2, -1, -3, 0, -2, -1, -2, -2, -2, -3, -2, -3, -4, -5, -6, -5, -9, -8, -9, -9, -9, -11, -10, -13, -14, -14, -15, -16, -15, -17, -19, -19, -21, -18, -21, -20, -22, -20, -24, -21, -22, -19, -20, -21, -17, -19, -16, -17, -15, -17, -13, -11, -10, -7, -5, -3, 2, 6, 4, 8, 9, 18, 14, 31, 25, 24, 25, 24, 21, 13, 15, 15, 11, 9, 1, 4, -20, -18, -38, -44, -57, -57, -55, -55, -52, -55, -46, -47, -40, -32, -26, -19, -16, -2, 3, 13, 19, 28, 30, 37, 40, 44, 39, 38, 35, 34, 37, 41, 48, 51, 53, 58, 61, 70, 74, 76, 76, 80, 81, 86, 83, 83, 78, 78, 73, 69, 65, 55, 47, 40, 36, 29, 23, 16, 14, 8, -2, -4, -11, -11, -19, -22, -26, -25, -34, -39, -40, -41, -45, -49, -51, -57, -56, -58, -59, -66, -70, -70, -72, -65, -64, -59, -53, -49, -45, -34, -29, -21, -15, -10, -6, -6, -3, -4, 2, 3, 3, 3, -1, -3, -11, -11, -13, -16, -22, -24, -27, -32, -34, -37, -35, -31, -30, -26, -25, -22, -21, -15, -13, -15, -10, -12, -12, -7, 2, 15, 22, 27, 24, 28, 22, 22, 21, 22, 17, 13, 14, 9, 5, 2, -8, -12, -16, -14, -17, -17, -17, -17, -14, -8, -3, -3, 0, 5, 3, 5, 6, 3, -2, -6, -9, -11, -13, -18, -19, -29, -42, -61, -72, -79, -81, -83, -82, -79, -76, -65, -54, -42, -33, -24, -14, 0, 18, 33, 48, 62, 75, 87, 93, 99, 100, 102, 102, 104, 102, 100, 100, 96, 93, 95, 96, 105, 109, 112, 111, 110, 106, 106, 104, 102, 97, 93, 85, 80, 71, 60, 48, 36, 26, 12, 0, -5, -13, -21, -28, -31, -36, -42, -49, -53, -56, -59, -61, -63, -64, -64, -63, -67, -70, -77, -75, -77, -78, -79, -80, -81, -80, -75, -69, -64, -57, -50, -43, -35, -26, -16, -6, 6, 13, 17, 22, 26, 25, 27, 27, 26, 23, 19, 11, 5, -5, -12, -19, -24, -31, -37, -42, -45, -50, -49, -48, -47, -43, -41, -38, -38, -37, -35, -35, -37, -42, -40, -33, -27, -20, -12, -11, -13, -10, -9, -10, -10, -10, -13, -11, -9, -8, -11, -13, -16, -18, -17, -15, -15, -14, -12, -8, -3, 3, 8, 16, 22, 25, 31, 34, 36, 36, 34, 31, 25, 23, 24, 26, 23, 13, -1, -16, -29, -38, -45, -51, -56, -57, -54, -48, -39, -34, -29, -20, -10, 0, 13, 27, 39, 54, 68, 79, 87, 92, 94, 96, 94, 92, 89, 87, 82, 76, 72, 71, 74, 76, 81, 83, 83, 84, 84, 85, 85, 82, 81, 82, 80, 75, 71, 66, 57, 46, 34, 24, 15, 5, -2, -8, -13, -19, -26, -31, -37, -41, -44, -48, -53, -54, -53, -54, -54, -57, -61, -64, -67, -70, -72, -75, -77, -79, -79, -76, -73, -70, -63, -58, -53, -47, -38, -29, -21, -13, -6, 0, 4, 7, 7, 8, 8, 6, 5, -1, -8, -15, -22, -30, -36, -41, -47, -51, -54, -56, -58, -59, -56, -50, -45, -42, -37, -31, -26, -23, -23, -23, -24, -21, -14, -6, 2, 8, 12, 15, 18, 21, 20, 20, 20, 20, 21, 23, 22, 18, 13, 10, 8, 6, 5, 4, 3, 2, 2, 4, 7, 10, 13, 18, 22, 24, 26, 28, 27, 21, 14, 8, 5, 4, 2, -3, -12, -24, -37, -50, -59, -67, -76, -80, -79, -75, -69, -61, -55, -47, -38, -27, -15, -2, 11, 27, 43, 58, 71, 82, 90, 94, 96, 98, 98, 98, 95, 89, 84, 81, 79, 81, 85, 88, 89, 91, 92, 92, 90, 89, 89, 88, 85, 82, 79, 75, 67, 58, 48, 37, 25, 14, 4, -4, -10, -17, -24, -31, -37, -42, -47, -51, -56, -59, -59, -59, -59, -61, -63, -65, -67, -70, -72, -74, -76, -78, -78, -78, -75, -70, -66, -61, -56, -50, -41, -33, -23, -14, -6, 2, 10, 16, 19, 21, 23, 24, 24, 22, 19, 13, 7, 0, -6, -14, -20, -25, -27, -32, -37, -39, -39, -38, -36, -33, -30, -27, -22, -19, -19, -20, -23, -24, -22, -18, -13, -8, -4, 0, 2, 5, 6, 5, 3, 2, 4, 6, 6, 5, 1, -2, -6, -8, -9, -10, -11, -13, -12, -12, -11, -9, -4, 0, 4, 8, 13, 18, 20, 19, 14, 10, 6, 4, 4, 4, 0, -8, -17, -28, -38, -49, -60, -68, -72, -72, -70, -65, -59, -54, -46, -37, -27, -17, -5, 8, 22, 37, 51, 66, 77, 84, 88, 91, 93, 94, 94, 91, 85, 79, 75, 74, 76, 77, 80, 83, 85, 85, 85, 86, 86, 85, 85, 85, 83, 81, 77, 70, 64, 55, 44, 32, 22, 13, 6, -1, -9, -16, -22, -27, -32, -38, -43, -46, -47, -47, -47, -48, -49, -49, -50, -52, -54, -56, -59, -62, -64, -66, -65, -64, -61, -59, -56, -53, -48, -41, -33, -25, -17, -10, -2, 4, 9, 13, 15, 16, 17, 17, 15, 11, 7, 1, -7, -15, -22, -27, -33, -38, -43, -47, -49, -50, -50, -49, -46, -42, -37, -31, -28, -28, -29, -30, -29, -26, -22, -17, -13, -8, -3, 2, 6, 7, 6, 5, 6, 8, 10, 12, 11, 8, 5, 3, 1, -1, -2, -3, -4, -6, -7, -6, -3, 0, 1, 5, 10, 16, 20, 21, 19, 15, 10, 8, 6, 6, 4, 0, -5, -12, -22, -33, -45, -57, -65, -70, -72, -70, -68, -64, -58, -51, -44, -36, -24, -13, -2, 11, 27, 43, 58, 70, 78, 83, 88, 92, 96, 97, 93, 89, 85, 81, 80, 81, 83, 86, 88, 90, 91, 91, 91, 91, 91, 91, 91, 89, 86, 83, 79, 72, 63, 52, 41, 30, 21, 13, 4, -5, -11, -17, -23, -31, -38, -44, -47, -49, -50, -52, -54, -55, -57, -57, -58, -60, -63, -66, -69, -72, -74, -73, -72, -70, -69, -67, -64, -59, -53, -45, -37, -30, -22, -14, -7, -2, 3, 8, 10, 12, 12, 13, 12, 8, 3, -4, -10, -16, -21, -27, -33, -37, -41, -44, -46, -48, -48, -45, -48, -43, -37, -33, -31, -32, -33, -32, -29, -26, -22, -18, -12, -5, 1, 6, 9, 9, 9, 9, 11, 14, 16, 16, 14, 12, 8, 5, 3, 2, 1, -1, -3, -4, -4, -2, -1, 2, 5, 11, 18, 24, 27, 27, 24, 20, 17, 15, 13, 11, 9, 5, -1, -10, -22, -35, -49, -61, -70, -75, -77, -76, -73, -69, -63, -56, -47, -36, -25, -13, 0, 16, 34, 52, 67, 79, 88, 95, 101, 106, 109, 108, 105, 100, 95, 92, 90, 91, 93, 96, 99, 100, 101, 101, 101, 101, 101, 101, 100, 97, 95, 91, 85, 78, 67, 55, 43, 31, 21, 11, 1, -7, -14, -21, -29, -37, -45, -51, -54, -56, -58, -60, -62, -64, -65, -66, -67, -69, -72, -76, -80, -82, -84, -83, -82, -80, -79, -77, -73, -67, -60, -51, -42, -34, -25, -16, -8, -2, 4, 9, 12, 13, 14, 14, 13, 9, 3, -5, -12, -18, -25, -31, -37, -42, -47, -50, -53, -54, -53, -48, -41, -36, -32, -31, -31, -32, -31, -28, -25, -22, -17, -12, -5, 1, 1, -2, -1, -9, -9, -6, 5, 6, -1, -10, 8, 24, 11, -2, -14, -9, -15, -13, 5, 14, 12, -6, -1, -12, 1, -9, 12, 12, 10, 5, -19, -11, -13, -2, 8, 5, 1, -2, -3, 9, -6, 6, 5, 6, -3, -17, -7, 3, 2, -1, 0, 7, -7, 5, 4, 6, -18, -24, 6, 20, -1, -4, -1, 10, 3, -10, 8, 7, -11, -17, -15, 5, 18, 4, 1, 8, -16, -4, 0, 11, 9, -10, -15, 0, -22, -12, 19, 34, 16, -9, -16, -7, -12, -10, 13, 23, -1, -10, -2, -3, -11, 13, 7, -6, -9, 3, 11, -10, -18, 12, 22, 7, -27, -29, -4, 20, 20, 10, 8, -16, -26, -6, 22, 21, 7, 15, 8, -50, -50, -7, 35, 22, -13, 32, 41, -33, -46, -10, 23, -7, -25, 23, 21, -38, -36, 14, 44, 2, 2, 34, -14, -51, -29, 11, 19, 7, 22, 13, -23, -21, -8, -9, 1, 14, 26, 26, -8, -34, -33, 4, 1, -6, -2, 16, -7, -23, 12, 27, 5, 6, 6, 0, -8, 0, -1, -17, -13, -12, 3, 9, 4, 11, 23, 36, 0, -43, -16, 4, -21, -26, 27, 16, -25, 3, 65, 4, -34, 24, -10, -38, -14, 13, 4, -15, 36, 44, -42, -51, 20, -5, -6, 68, 20, -18, -39, -11, 9, 17, 6, -33, -20, -13, 48, 30, 22, -4, -9, -53, -20, 32, 32, -16, 17, -11, -36, -8, -5, 39, 28, 33, 21, -64, -48, 3, -22, 15, 62, -26, 0, 3, 5, 73, -14, -48, -20, -59, 4, 70, 60, -7, -2, -88, -22, -17, 39, 17, 33, -3, 15, 28, -47, -80, -37, 5, 7, 104, 16, -99, -92, -36, 109, 78, 26, -15, -92, -21, 62, 48, -51, -81, -25, 55, 63, 35, 21, -115, -54, 101, 73, -41, -110, -66, 50, 107, 45, -8, -109, -38, 12, 102, 3, 17, -45, -2, -36, 39, 46, -12, -28, -27, -17, 17, -18, 82, -5, -3, -25, -5, -14, 15, 9, -3, -17, -6, 2, 7, -36, -13, 6, 21, -23, -20, 16, -18, 3, -2, 26, 0, 13, -23, -2, -19, -28, -18, 15, 12, 22, -4, 23, -17, -22, -9, -18, -4, 11, 13, 0, 34, -16, -20, 26, 23, 15, -4, -25, 7, 8, -9, 8, 44, 1, -40, 17, -32, 9, -30, -52, 52, 3, 2, -21, 83, 58, -14, -46, -61, -12, -67, -20, 64, 72, 57, -10, 5, 1, -77, 31, -47, -39, 12, 22, 57, 28, 0, 9, -76, 15, -74, 33, -12, 39, 114, -35, -36, -38, -23, 27, -21, 14, 56, 47, 6, -72, -61, -4, 18, -4, 19, 13, 45, 71, 48, -1, -125, -52, -56, -20, -18, -12, 51, 78, 68, -46, 32, -40, -29, -28, -81, -25, 75, 42, 58, -38, 1, -29, -34, 31, -36, -14, 10, 64, 37, 2, -31, -72, -17, -33, 30, -52, -54, 25, 43, 70, 81, -9, -73, 4, -65, 15, -28, 25, 0, 28, 19, 51, -26, 6, 0, -37, -15, -22, -20, -16, -5, 50, 56, 67, 25, 16, -35, -29, -14, -39, 19, -24, -52, -13, -32, -10, 39, 33, 59, 6, 37, 55, 11, -9, -35, -15, -57, -56, -36, -34, 19, 19, 6, 20, 17, -11, 5, 26, 19, 16, 7, -20, -26, -55, -62, -36, -18, 19, 37, 47, 25, -6, -14, 1, -4, -13, 12, 23, 34, 38, 41, 33, 31, -10, -56, -52, -49, -31, -40, -21, -12, 0, 5, 12, 22, 22, 21, 31, 12, 2, -8, -4, -18, -7, 3, 1, -1, 11, 12, 18, 17, 9, -2, -12, -13, -11, -1, 8, 3, 3, 2, 5, -5, -16, -15, -13, -8, -12, -9, -2, -1, 2, 7, 10, 7, 11, 14, 7, -1, -4, 5, -3, -2, 0, -6, -10, -1, -5, 3, 9, 0, -8, -9, -6, -6, 0, 6, 3, 6, 7, 10, 0, -8, -3, -5, -1, -8, -7, -4, -3, -3, 0, -1, -6, 2, 7, 7, 5, 4, 10, 5, 8, -1, -11, -15, -11, -15, -10, -1, -8, -12, -5, 1, 3, 6, 8, 11, 18, 22, 26, 10, -10, -1, -15, -3, -21, -16, -14, -12, -7, -8, -18, -20, -11, 9, 20, 27, 26, 11, 1, 21, 6, 3, -9, -15, -9, -20, 3, 5, 21, 14, 6, 11, -21, -22, -6, -21, -23, -18, 11, 6, 5, 21, 9, 23, 16, -3, -30, -7, -27, -4, 5, 18, 22, 16, 2, 7, -1, -2, -10, -14, -10, -17, -10, -15, -16, 3, 12, 30, 18, -1, -6, -15, -3, 5, 11, -18, -2, 8, 21, 11, -13, -4, -30, -7, 0, 12, 25, -3, 17, 14, -20, -6, -27, -41, -11, -12, 23, -8, 13, 24, 18, 27, -11, -8, -12, -2, 17, 23, 13, -20, -21, -2, -21, -34, -46, -23, 28, 48, 9, -10, 8, 29, 27, 5, -29, -12, 13, -5, -2, -35, 1, 3, 24, 13, 17, -18, -30, -21, 14, -1, 6, -8, 48, 45, -7, -34, -49, -32, -6, -26, 20, 29, 76, 30, -21, -66, -36, -15, 40, -5, 29, 3, 10, -39, -25, -2, 24, 19, 19, -4, -8, 3, -22, -23, -18, 13, 17, -3, -25, 23, 66, 26, -18, -27, -34, -30, -30, 36, 25, 28, -22, -17, -7, -22, 21, 18, 42, 8, -25, -28, -31, -10, 15, 18, 0, -1, -5, 16, -12, 13, 13, 12, -8, -37, -9, 13, -5, 8, -3, 13, -8, 4, 24, -16, -43, -18, 26, 26, -11, -9, 19, 9, -15, 9, 15, -12, -31, -27, 8, 29, 5, 7, 17, -33, -14, 14, 23, -1, -18, -18, -4, -35, -17, 47, 71, -16, -20, -11, -16, -25, 6, 37, 14, -18, 1, -8, -14, 10, 14, 2, -20, 0, 20, -10, -25, 14, 32, 7, -39, -38, -3, 34, 25, 13, 3, -24, -34, 5, 38, 18, 7, 29, -30, -74, -41, 36, 40, -12, 26, 55, -17, -59, -26, 28, -2, -31, 24, 25, -44, -39, 21, 44, -1, 10, 33, -34, -50, -12, 18, 13, 20, 17, -6, -31, -10, -6, -1, 7, 12, 14, 6, -16, -24, 6, 9, -16, -16, 6, 2, -10, 13, 12, -10, 0, 11, 11, 10, -3, -22, -22, -12, -7, 19, 17, -2, -12, 6, 16, 7, -11, -1, -20, -22, -8, 26, 16, -3, 12, 1, -33, 2, 30, -23, -5, 28, -17, -19, 21, 9, -28, -14, 25, -1, 4, 24, 0, -26, -9, 7, 2, -2, 20, -10, -11, 5, -3, -4, 8, -9, 14, 18, 25, -22, -15, -22, -3, -12, 27, 30, 15, -11, -26, -4, 15, -7, -14, 23, -23, -4, 34, -2, -38, 14, -11, -24, 16, 34, 11, -13, 3, -3, -19, -34, 0, -3, 24, 43, 1, -12, -38, -25, -11, 23, 35, 12, -28, -25, -16, 7, 22, 1, -10, 8, 8, -3, 6, -24, -20, -13, 9, 31, 12, -16, 7, -29, 5, 8, -28, 3, 4, 12, 26, -9, -15, -5, -20, 9, 21, 0, 1, -9, 0, 8, -3, -7, -9, -3, 22, 8, 3, -11, -9, -11, 3, 15, 9, -10, 1, -3, -3, -2, -5, 9, 0, 12, 7, -15, -7, 0, -8, 5, 9, -5, 7, -7, 10, 4, -11, -2, -8, -4, 9, 9, 0, -2, -11, -3, -4, 3, 4, 3, -2, 3, 3, -8, -9, -2, 0, 3, 5, -1, -10, -7, 2, 8, 3, 0, -5, -5, 2, 4, -2, -5, -3, 2, 3, 0, 2, -5, -3, 3, 2, -2, -4, -2, 1, 2, 1, 0, 0, 0, 0, -1, -7, -9, -5, 0, 2, 2, 5, 6, 0, -11, -13, -5, 3, 1, 0, 0, 1, -3, -9, -6, -1, 5, 3, -3, -5, -3, -1, -4, -3, -1, 2, -2, -9, -7, -2, -5, -18, -31, -36, -36, -41, -38, -29, -21, -27, -31, -26, -4, 37, 65, 67, 44, 22, 10, 2, -4, 8, 32, 44, 38, 24, 17, 9, 4, 3, 12, 26, 32, 32, 23, 16, 7, 1, -7, -13, -8, 1, -5, -39, -72, -79, -64, -49, -40, -24, -1, 12, 0, -25, -44, -43, -30, -14, 1, 13, 13, 4, 4, 16, 34, 46, 55, 65, 73, 67, 53, 54, 58, 62, 60, 51, 38, 33, 20, -7, -27, -40, -46, -55, -58, -41, -9, 7, 8, 2, -26, -49, -71, -92, -101, -93, -80, -70, -71, -73, -65, -67, -69, -61, -42, -15, 15, 18, -5, -33, -54, -54, -40, -18, 2, 21, 21, 3, -28, -52, -33, 9, 35, 33, 30, 34, 45, 46, 43, 54, 63, 65, 61, 56, 43, 45, 59, 77, 96, 104, 112, 115, 100, 78, 53, 22, -3, -6, 5, 24, 37, 38, 35, 25, 3, -19, -38, -51, -46, -33, -34, -42, -47, -48, -38, -27, -30, -40, -48, -45, -30, -24, -38, -44, -43, -47, -34, -13, 7, 27, 30, 9, -18, -38, -22, 19, 47, 70, 83, 68, 28, -13, -41, -41, -19, -1, 10, 8, 4, 4, -7, -12, 6, 32, 42, 31, 0, -39, -71, -99, -115, -111, -85, -56, -46, -61, -74, -66, -45, -22, 4, 21, 27, 25, 1, -30, -51, -37, 4, 37, 40, 26, 17, 12, 12, 5, 1, 2, 12, 29, 43, 44, 45, 54, 45, 28, 10, 13, 26, 32, 43, 59, 67, 62, 60, 66, 72, 61, 34, 11, 0, 1, -6, -18, -12, 19, 47, 51, 32, 9, -8, -22, -26, -27, -30, -29, -12, 7, 18, 13, -1, -11, -11, 5, 16, 14, 11, 5, -19, -47, -54, -29, 13, 37, 42, 33, 9, -17, -31, -21, 14, 61, 81, 68, 39, 4, -26, -46, -38, -17, -1, 1, -4, -14, -25, -23, -4, 24, 43, 49, 37, 4, -48, -97, -123, -116, -89, -66, -65, -73, -67, -64, -66, -69, -46, 3, 36, 27, -3, -25, -39, -38, -39, -36, -24, -9, 5, 13, 13, 4, -1, -13, -15, 0, 22, 47, 65, 76, 67, 35, 3, -4, 6, 27, 47, 58, 68, 72, 73, 72, 66, 59, 62, 61, 49, 28, -5, -30, -27, 9, 40, 51, 46, 40, 28, 1, -30, -56, -57, -41, -13, 5, 12, 7, -11, -38, -54, -40, -16, 12, 23, 13, -16, -49, -62, -55, -29, 4, 38, 45, 28, -5, -36, -36, -5, 39, 68, 77, 73, 55, 8, -35, -46, -29, -15, -15, -16, -12, -9, -23, -30, -18, 16, 48, 51, 24, -18, -45, -72, -96, -111, -101, -80, -67, -71, -79, -77, -70, -46, -22, -7, -4, -5, -4, -2, -15, -37, -43, -42, -27, -5, 9, 27, 38, 27, 4, -14, -15, 6, 30, 61, 93, 90, 52, 16, 2, 1, 5, 11, 34, 64, 79, 71, 48, 35, 43, 61, 59, 46, 27, 1, -22, -33, -25, -9, 15, 37, 56, 54, 28, -10, -44, -58, -49, -27, -8, 20, 29, 0, -42, -66, -60, -34, -7, 16, 30, 15, -20, -50, -64, -49, -11, 21, 34, 34, 17, -7, -31, -29, 3, 43, 69, 78, 73, 45, 10, -20, -32, -33, -26, -12, -6, -18, -41, -44, -27, -6, 10, 17, 19, 18, -4, -49, -87, -108, -100, -84, -87, -93, -83, -67, -54, -45, -45, -35, -23, -13, 6, 17, 14, 1, -22, -40, -35, -18, 2, 28, 57, 63, 33, -7, -21, -4, 23, 57, 89, 102, 94, 68, 37, 8, -4, 4, 37, 71, 88, 79, 54, 46, 55, 62, 55, 53, 54, 46, 20, -14, -40, -41, -16, 15, 44, 60, 59, 30, -21, -61, -70, -54, -26, 10, 29, 19, -16, -49, -63, -58, -33, 4, 29, 26, -1, -33, -49, -50, -34, -9, 16, 34, 34, 9, -20, -25, -9, 13, 29, 54, 87, 91, 56, 11, -12, -11, -12, -20, -22, -17, -11, -12, -22, -25, -15, 3, 19, 19, 9, -11, -38, -62, -76, -92, -107, -109, -95, -68, -53, -49, -49, -58, -63, -48, -25, -5, 12, 12, -7, -36, -56, -56, -32, 8, 50, 64, 36, 6, -10, -15, -11, 9, 47, 94, 118, 100, 58, 14, -3, 3, 19, 44, 72, 83, 78, 75, 66, 53, 45, 52, 66, 70, 52, 22, -8, -36, -36, -14, 21, 63, 84, 63, 14, -29, -55, -54, -42, -12, 28, 40, 14, -24, -52, -58, -42, -22, 6, 19, 16, -5, -34, -49, -43, -24, -12, 2, 14, 22, 10, -10, -20, -16, 3, 28, 60, 72, 61, 42, 25, 1, -26, -44, -46, -31, -25, -26, -32, -30, -24, -12, -12, -15, 0, 6, -3, -23, -47, -79, -112, -128, -115, -84, -61, -45, -42, -51, -64, -68, -61, -33, 9, 29, 12, -28, -54, -64, -56, -30, 9, 36, 41, 34, 10, -18, -38, -29, 13, 70, 105, 106, 79, 48, 31, 12, -1, 12, 51, 78, 89, 87, 75, 66, 49, 44, 56, 73, 79, 66, 23, -23, -42, -39, -9, 31, 65, 75, 52, 7, -32, -54, -57, -30, 3, 24, 19, 2, -18, -39, -50, -39, -10, 8, 10, -2, -12, -18, -21, -29, -33, -16, 11, 28, 17, 1, -4, 3, -3, -6, 13, 42, 64, 67, 56, 29, 2, -21, -36, -42, -40, -25, -15, -10, -7, -10, -27, -38, -24, 2, 19, 14, -6, -44, -86, -115, -121, -109, -81, -45, -27, -36, -58, -76, -81, -53, -13, 11, 8, -11, -24, -40, -58, -62, -30, 11, 42, 44, 17, -15, -36, -38, -22, 15, 53, 84, 88, 73, 52, 19, -6, -9, 13, 44, 71, 88, 93, 79, 54, 42, 46, 67, 82, 79, 54, 20, -10, -28, -27, 0, 46, 70, 61, 29, 2, -18, -38, -45, -23, 7, 16, 10, -8, -22, -26, -30, -32, -23, -13, -2, 6, -6, -15, -16, -18, -20, -9, 0, 2, 11, 19, 17, -2, -21, -12, 14, 33, 50, 65, 61, 43, 19, -17, -44, -50, -42, -21, 1, 11, 1, -31, -56, -45, -22, -1, 17, 18, -4, -44, -95, -126, -123, -95, -56, -36, -41, -51, -59, -68, -60, -38, -15, 5, 14, 7, -17, -47, -61, -37, 1, 27, 33, 24, 7, -13, -30, -43, -26, 13, 47, 70, 74, 68, 48, 12, -19, -14, 14, 46, 74, 81, 75, 64, 52, 48, 56, 67, 82, 78, 44, 9, -12, -20, -8, 18, 41, 57, 46, 23, 0, -23, -33, -21, -10, -10, -2, 3, 5, -2, -19, -33, -32, -24, -16, -11, -14, -6, 7, -2, -20, -25, -16, -6, 6, 17, 27, 22, 2, -10, -11, 0, 24, 51, 68, 79, 65, 25, -19, -49, -48, -30, -9, 8, 10, -12, -40, -57, -57, -34, -1, 25, 24, -7, -56, -95, -111, -102, -84, -69, -57, -44, -42, -59, -74, -71, -47, -17, 0, 3, -6, -21, -37, -38, -27, -6, 15, 23, 22, 12, -4, -23, -32, -26, 1, 36, 63, 82, 78, 46, 12, -1, 2, 20, 41, 64, 81, 79, 66, 59, 61, 67, 75, 76, 66, 49, 27, 5, -7, 2, 24, 41, 44, 38, 28, 13, -5, -19, -21, -17, -11, -2, 4, 4, -2, -14, -28, -32, -27, -21, -16, -13, -1, 6, -4, -21, -25, -17, -7, 6, 0, 0, -4, -4, -5, -8, -4, 3, 8, 6, 1, 1, 2, 3, 3, -2, -7, -11, -10, -5, -2, 4, 6, 0, -2, -5, -4, -4, -9, -9, -7, -11, -11, -10, -7, 4, 0, -4, -4, -1, 4, 0, -4, -3, -5, -6, -5, -4, 4, -1, 2, 11, 5, -13, -20, -30, -49, -50, -34, -22, -33, -27, -20, -17, 0, 34, 70, 73, 42, 3, -26, -37, -25, -1, 25, 48, 71, 75, 44, 22, 45, 69, 57, 44, 52, 58, 24, -23, -41, -50, -58, -67, -82, -66, -29, -29, -41, -34, -19, -4, -4, -1, 20, 50, 56, 35, 12, 4, -8, -15, 4, 28, 44, 46, 34, 17, 2, 0, 11, 28, 42, 22, -28, -51, -45, -34, -39, -37, -19, -17, -30, -32, -18, -4, 9, 19, 38, 35, 3, -24, -35, -40, -23, -11, -25, -47, -52, -51, -58, -61, -52, -47, -37, -17, -5, -5, -16, -31, -24, -11, -1, -3, -23, -40, -48, -40, -12, 15, 25, 17, -5, -2, 14, 21, 15, -12, -26, -18, -2, 28, 48, 55, 52, 42, 35, 35, 42, 38, 36, 40, 53, 55, 52, 44, 36, 49, 57, 56, 57, 55, 50, 39, 27, 31, 30, 15, 11, 12, 6, 4, 14, 28, 23, 1, -6, -17, -35, -44, -41, -33, -22, -9, -6, -12, -15, -13, -27, -29, -7, 14, -5, -55, -71, -49, -33, -37, -46, -33, -18, -43, -89, -96, -65, -23, 2, 8, 20, 24, -11, -50, -51, -12, 15, 4, 1, 20, 47, 53, 43, 52, 77, 98, 114, 110, 100, 88, 53, 10, -29, -55, -71, -83, -77, -58, -55, -57, -52, -48, -47, -46, -12, 34, 59, 52, 25, -10, -33, -21, 18, 49, 54, 46, 18, 13, 30, 41, 48, 54, 53, 44, 24, 1, -13, -25, -43, -38, -28, -35, -55, -71, -64, -40, -13, 10, 24, 38, 41, 21, -1, -11, 1, 15, 7, -6, -13, -39, -57, -64, -51, -20, -12, -24, -37, -30, -4, 17, 21, 12, -7, -16, -15, -7, 6, 1, -20, -34, -30, -1, 32, 44, 36, 22, 25, 21, 6, 1, -2, -13, -5, 19, 28, 24, 12, 11, 16, 19, 38, 54, 49, 38, 28, 28, 39, 52, 49, 32, 25, 33, 45, 49, 39, 40, 46, 20, -9, -6, 6, 1, -22, -29, 10, 48, 33, -17, -51, -55, -44, -49, -50, -36, -33, -57, -84, -71, -21, 11, 13, 4, -1, -8, -32, -45, -32, -10, 2, -13, -37, -39, -42, -57, -65, -63, -36, -11, 10, 33, 22, -12, -34, -28, -12, 2, 8, 6, -2, -4, 0, 10, 22, 36, 57, 82, 104, 122, 127, 109, 70, 17, -28, -45, -36, -20, -33, -68, -102, -114, -103, -76, -45, -20, -7, -11, -10, -2, 6, 0, -14, -5, 30, 48, 29, 3, -8, 10, 39, 67, 86, 83, 59, 32, 17, 32, 46, 40, 11, -29, -48, -57, -68, -69, -57, -43, -26, -13, -2, 1, 1, 3, 4, 8, 21, 20, 11, 3, -2, -6, -26, -39, -33, -34, -36, -28, -23, -27, -28, -17, -1, 0, -6, -10, -9, -7, -12, -26, -44, -54, -38, -16, 0, 18, 27, 17, -3, -18, -3, 19, 11, -9, -7, 10, 14, 5, 5, 18, 29, 29, 12, 16, 38, 43, 14, 2, 24, 55, 59, 33, 17, 24, 44, 65, 75, 77, 55, 15, -16, -20, 6, 31, 27, 17, 18, 19, 17, 7, 0, -5, -20, -22, -25, -49, -69, -73, -58, -45, -29, -4, 9, -1, -23, -51, -52, -24, -2, 11, 12, -16, -51, -75, -77, -67, -59, -59, -54, -35, -15, -9, -9, -9, -7, -8, -12, -1, 15, 22, 10, -14, -34, -28, -14, 11, 64, 113, 127, 117, 97, 87, 84, 68, 50, 37, 36, 24, -15, -58, -78, -84, -71, -40, -14, -12, -34, -48, -41, -14, 20, 37, 35, 16, -6, 1, 14, 15, 20, 23, 24, 38, 58, 69, 57, 40, 54, 73, 75, 65, 40, -3, -49, -68, -56, -42, -42, -53, -59, -44, -23, -9, -3, -11, -18, -13, -11, -5, 3, 13, 4, -25, -39, -22, -14, -16, -27, -38, -37, -42, -55, -51, -21, 8, 10, -8, -12, -4, -10, -39, -55, -38, -13, -4, -11, -15, -3, 15, 12, 2, 11, 28, 34, 15, -5, 3, 11, 6, 12, 25, 25, 13, 10, 15, 27, 48, 55, 38, 23, 17, 23, 32, 23, 32, 57, 75, 75, 52, 22, 10, 5, 12, 28, 33, 23, 2, -14, -4, 19, 30, 25, 15, 1, -27, -64, -78, -67, -49, -45, -48, -42, -31, -25, -40, -50, -39, -18, -4, 13, 19, 12, -10, -43, -59, -53, -47, -54, -61, -51, -20, -2, -12, -23, -25, -18, 5, 33, 51, 45, 16, -16, -46, -53, -38, -6, 33, 57, 74, 81, 75, 77, 89, 105, 114, 110, 83, 39, -6, -25, -28, -39, -48, -52, -55, -59, -67, -67, -57, -42, -23, -3, 10, 3, -19, -33, -30, -8, 20, 23, 2, -18, -17, 12, 40, 58, 65, 65, 66, 71, 64, 54, 38, 1, -41, -62, -47, -26, -31, -49, -55, -42, -21, -17, -19, -10, -2, -3, -10, -13, 2, 13, -10, -38, -27, 3, 8, -18, -46, -61, -65, -53, -36, -18, -5, -6, -14, -22, -18, -12, -19, -29, -28, -21, -10, -15, -24, -18, -4, 16, 23, 17, 14, 10, 9, 13, 15, 28, 35, 19, 4, 2, -2, 9, 34, 62, 66, 43, 13, -2, 15, 42, 50, 48, 51, 56, 56, 45, 44, 45, 48, 40, 33, 31, 27, 10, -10, -4, 16, 41, 52, 48, 31, -1, -36, -56, -50, -27, -14, -25, -43, -60, -67, -47, -31, -38, -47, -40, -17, 13, 32, 28, -10, -50, -68, -62, -40, -21, -20, -33, -58, -72, -63, -45, -28, -11, 18, 48, 42, 15, -14, -43, -54, -40, -15, 4, 2, -5, 0, 20, 55, 91, 113, 120, 109, 89, 77, 63, 43, 26, 20, 12, -13, -47, -69, -68, -53, -49, -49, -36, -28, -27, -27, -28, -12, 5, 1, -9, -2, 14, 10, -25, -39, -6, 21, 35, 41, 53, 73, 82, 74, 64, 54, 39, 9, -23, -37, -30, -22, -30, -52, -62, -54, -32, -9, 2, 5, -3, -17, -25, -17, -1, 13, 8, -7, -12, -7, -7, -21, -40, -51, -51, -38, -21, -16, -22, -29, -33, -23, -10, -2, -9, -24, -33, -33, -29, -21, -8, 3, 2, -10, -18, -11, 8, 26, 32, 27, 21, 14, 7, 1, 3, 12, 22, 35, 45, 43, 29, 13, 10, 20, 37, 54, 59, 45, 28, 28, 37, 48, 55, 60, 60, 43, 17, 0, -3, 9, 24, 31, 31, 28, 28, 26, 14, -5, -22, -31, -30, -21, -7, -8, -34, -63, -82, -80, -63, -45, -28, -14, -5, 3, 2, -11, -27, -39, -33, -11, 2, -8, -39, -73, -95, -91, -54, -8, 19, 16, 4, 5, 14, 14, 2, -8, -14, -19, -33, -45, -38, -19, 2, 21, 54, 93, 106, 90, 74, 80, 97, 98, 76, 52, 34, 10, -18, -37, -36, -27, -35, -52, -62, -56, -44, -39, -37, -29, -17, -8, -2, 3, 4, -4, -16, -27, -32, -19, 1, 19, 41, 60, 70, 71, 67, 64, 61, 53, 38, 14, -8, -21, -29, -34, -38, -39, -29, -15, 0, 5, -5, -19, -25, -16, 5, 19, 17, 6, -3, -7, 0, -1, 1, -2, -5, 0, 0, 2, 0, -3, -2, 0, 1, 0, -2, -2, -2, 0, 3, 3, -2, -5, -1, -1, -1, -4, 3, 9, 1, -1, -2, -11, -7, 1, 9, 11, 8, -4, -11, -12, -9, -4, 18, 15, 14, 1, -22, -29, -14, 3, 30, 29, 14, -2, -35, -43, -11, 13, 36, 42, 15, -16, -49, -44, -10, 28, 47, 38, 11, -25, -66, -39, 4, 36, 58, 33, -3, -44, -65, -29, 19, 52, 54, 23, -13, -59, -65, -15, 32, 69, 49, 8, -30, -74, -51, 3, 43, 71, 40, -5, -48, -77, -31, 16, 57, 67, 24, -15, -67, -72, -12, 36, 66, 59, 5, -31, -80, -51, 3, 49, 75, 37, -2, -59, -81, -28, 20, 67, 66, 22, -23, -76, -65, -10, 41, 78, 48, 4, -36, -85, -47, 6, 59, 80, 31, -8, -69, -82, -22, 29, 73, 63, 17, -31, -81, -63, -1, 47, 79, 47, 3, -56, -90, -40, 19, 75, 73, 28, -25, -86, -74, -10, 48, 85, 56, 6, -51, -93, -48, 11, 67, 86, 33, -11, -78, -87, -29, 36, 89, 66, 13, -38, -91, -60, 2, 50, 83, 48, 0, -56, -90, -41, 16, 71, 78, 30, -17, -80, -75, -20, 31, 82, 62, 15, -32, -85, -66, -7, 48, 84, 50, 4, -53, -87, -44, 8, 62, 78, 35, -8, -65, -83, -30, 23, 70, 71, 24, -20, -76, -75, -12, 32, 73, 62, 15, -30, -85, -62, -2, 41, 76, 51, 9, -39, -86, -52, 1, 45, 79, 46, 8, -49, -89, -46, 3, 54, 80, 43, 7, -55, -83, -50, 0, 53, 76, 54, 11, -52, -83, -55, 0, 40, 67, 58, 22, -32, -79, -67, -11, 28, 63, 52, 37, -9, -70, -63, -28, 10, 42, 49, 53, 8, -46, -64, -41, 1, 22, 38, 51, 39, -16, -63, -46, -23, 5, 33, 38, 48, 14, -42, -57, -29, -5, 22, 37, 40, 28, -23, -53, -39, -10, 14, 30, 40, 31, -1, -48, -40, -18, 11, 19, 31, 26, 14, -20, -50, -25, -5, 11, 31, 30, 14, 0, -35, -39, -4, -1, 19, 27, 17, 9, -10, -39, -21, -8, 9, 24, 26, 13, -5, -19, -30, -12, -1, 17, 25, 16, 3, -19, -26, -13, -6, 17, 22, 20, 5, -16, -32, -19, -1, 23, 27, 23, 4, -30, -33, -23, -1, 35, 35, 24, -2, -41, -45, -21, 9, 45, 41, 22, -12, -50, -46, -18, 28, 55, 45, 10, -27, -78, -42, 0, 53, 66, 32, -1, -61, -74, -28, 27, 64, 64, 24, -28, -80, -66, -15, 53, 84, 48, 5, -59, -94, -41, 17, 75, 80, 26, -21, -91, -79, -12, 48, 87, 55, 10, -58, -96, -46, 9, 80, 81, 30, -23, -84, -80, -15, 49, 90, 49, 9, -57, -95, -45, 17, 76, 79, 26, -20, -91, -75, -18, 52, 90, 52, 6, -59, -92, -41, 15, 68, 80, 31, -21, -87, -76, -13, 45, 87, 49, 11, -60, -94, -35, 14, 80, 68, 22, -23, -89, -66, -7, 47, 93, 44, -8, -61, -95, -31, 24, 86, 75, 10, -35, -96, -66, -1, 61, 100, 44, -12, -77, -105, -33, 32, 97, 92, 16, -44, -111, -90, -5, 65, 121, 65, -3, -80, -123, -59, 17, 98, 111, 46, -25, -112, -109, -33, 42, 112, 90, 30, -55, -115, -84, -17, 66, 105, 71, 13, -73, -113, -61, 0, 77, 96, 56, 4, -80, -108, -50, 8, 78, 93, 47, 3, -88, -98, -40, 7, 65, 76, 53, 18, -71, -90, -44, 0, 39, 57, 43, 34, -19, -69, -54, -19, 18, 32, 31, 34, 7, -40, -36, -21, -1, 12, 12, 25, 27, -9, -32, -14, -14, 2, 0, 1, 20, 19, -2, -13, -11, -18, -12, -2, 18, 24, 12, -2, -14, -19, -19, -12, 18, 24, 22, -2, -15, -32, -20, 3, 22, 26, 17, -13, -31, -27, -13, 17, 33, 32, 5, -29, -47, -29, 2, 33, 42, 32, -6, -53, -52, -24, 22, 51, 41, 27, -32, -74, -45, 0, 45, 59, 33, -1, -62, -66, -31, 26, 73, 49, 17, -42, -80, -42, -8, 63, 72, 28, -10, -75, -72, -23, 32, 88, 47, 13, -56, -93, -38, 10, 76, 69, 26, -20, -96, -66, -10, 48, 90, 47, 0, -69, -103, -29, 25, 87, 73, 18, -35, -104, -68, -2, 61, 93, 47, -5, -83, -98, -31, 30, 92, 68, 17, -39, -97, -63, -5, 64, 88, 35, -9, -74, -86, -22, 31, 85, 54, 13, -44, -93, -46, 9, 65, 75, 23, -17, -75, -78, -15, 39, 84, 54, 3, -52, -96, -46, 12, 71, 90, 29, -18, -89, -87, -26, 36, 86, 72, 26, -37, -106, -77, -12, 45, 99, 68, 22, -46, -108, -73, -10, 43, 87, 69, 19, -27, -92, -79, -12, 27, 63, 57, 26, 4, -53, -75, -35, 12, 33, 37, 31, 26, -9, -53, -39, -16, 6, 20, 23, 22, 13, -8, -22, -23, -18, -3, 9, 25, 19, 4, -8, -20, -17, -10, 6, 16, 17, 13, -8, -34, -21, -6, 17, 33, 23, 6, -32, -51, -23, 11, 36, 46, 31, -11, -46, -65, -31, 15, 59, 55, 28, -20, -73, -64, -26, 42, 78, 51, 14, -53, -85, -48, -4, 70, 80, 38, -16, -80, -76, -32, 39, 90, 58, 19, -59, -99, -50, 14, 71, 75, 36, -21, -94, -70, -23, 51, 88, 53, 9, -68, -97, -40, 16, 83, 73, 29, -33, -100, -61, -13, 58, 87, 41, 0, -74, -81, -35, 24, 87, 55, 20, -41, -88, -58, 0, 69, 73, 34, -5, -86, -75, -20, 38, 79, 49, 13, -48, -90, -39, 2, 71, 68, 31, -16, -84, -67, -15, 38, 79, 42, 12, -50, -85, -37, 2, 62, 71, 34, -5, -83, -75, -24, 27, 82, 51, 27, -30, -88, -54, -15, 44, 73, 50, 16, -49, -81, -47, -6, 38, 58, 50, 27, -31, -69, -52, -13, 15, 36, 45, 33, -5, -41, -44, -23, 2, 14, 27, 33, 10, -25, -20, -18, -6, 1, -1, 17, 22, 3, -13, -10, -17, -13, -6, 13, 24, 15, 1, -11, -19, -19, -16, 12, 24, 24, 3, -12, -29, -26, -1, 18, 27, 19, -4, -31, -28, -19, 11, 30, 35, 12, -21, -46, -35, -6, 28, 42, 36, 5, -46, -57, -31, 10, 50, 43, 33, -16, -71, -55, -9, 35, 62, 38, 10, -51, -71, -40, 11, 69, 58, 24, -26, -81, -50, -18, 48, 79, 37, 1, -62, -81, -32, 16, 84, 59, 20, -37, -96, -50, -2, 63, 78, 33, -4, -85, -80, -20, 33, 88, 59, 10, -50, -107, -47, 14, 75, 85, 27, -19, -95, -83, -15, 47, 94, 60, 8, -66, -105, -46, 15, 83, 81, 26, -23, -91, -76, -18, 48, 92, 47, 1, -59, -94, -36, 18, 78, 66, 19, -27, -91, -60, -3, 53, 80, 35, -8, -62, -86, -28, 27, 79, 66, 13, -38, -94, -62, 1, 56, 95, 42, -6, -75, -96, -39, 22, 80, 80, 36, -20, -97, -92, -24, 30, 93, 79, 32, -27, -102, -87, -22, 31, 81, 79, 29, -14, -81, -91, -25, 19, 56, 63, 31, 11, -39, -77, -47, 3, 31, 37, 33, 27, 3, -48, -46, -20, 0, 18, 22, 23, 16, -3, -20, -19, -15, -4, 2, 8, 5, 0, 0, 0, 0, 2, 2, 5, 9, 12, 14, 12, 7, 6, 4, 0, -1, -1, 1, -2, -2, -11, -17, -32, -41, -49, -55, -58, -61, -61, -65, -61, -57, -47, -37, -27, -22, -15, -5, 6, 12, 16, 21, 27, 28, 32, 33, 35, 41, 44, 45, 47, 50, 54, 57, 56, 53, 53, 54, 50, 50, 52, 54, 56, 52, 53, 54, 50, 49, 46, 43, 38, 33, 27, 19, 8, 2, -11, -20, -27, -29, -30, -32, -35, -42, -52, -57, -57, -59, -48, -40, -27, -13, 4, 13, 20, 18, 14, 11, 7, 3, -1, -3, -10, -11, -20, -28, -46, -60, -72, -82, -92, -97, -97, -97, -94, -90, -81, -71, -61, -55, -55, -53, -47, -38, -29, -23, -11, -6, -3, 1, 2, 5, 6, 3, 3, 5, 15, 24, 28, 30, 30, 35, 37, 36, 39, 39, 44, 47, 48, 56, 62, 73, 84, 91, 96, 95, 91, 85, 76, 72, 63, 55, 47, 44, 43, 41, 38, 31, 19, 7, 0, -9, -7, -4, 8, 22, 40, 54, 67, 71, 70, 64, 56, 45, 32, 24, 15, 12, 3, -3, -21, -42, -66, -84, -102, -117, -124, -128, -127, -124, -118, -107, -96, -86, -86, -88, -86, -80, -70, -63, -50, -40, -33, -25, -23, -20, -18, -18, -21, -25, -22, -14, -8, -3, -3, -1, 1, 0, 1, -3, -1, 2, 4, 13, 24, 35, 49, 59, 67, 70, 69, 68, 59, 54, 46, 40, 31, 29, 27, 25, 23, 20, 12, -1, -9, -19, -22, -21, -11, 3, 23, 41, 60, 71, 76, 73, 71, 65, 56, 50, 44, 42, 35, 33, 24, 9, -13, -31, -48, -65, -76, -83, -83, -82, -77, -69, -59, -46, -40, -40, -41, -38, -30, -24, -13, -2, 8, 17, 22, 24, 25, 23, 20, 13, 9, 11, 15, 19, 16, 12, 9, 4, 1, -6, -10, -11, -14, -12, -5, 3, 15, 26, 35, 40, 41, 41, 35, 28, 19, 12, 3, -2, -6, -7, -10, -13, -19, -31, -39, -50, -56, -58, -52, -41, -22, -3, 18, 34, 46, 48, 47, 45, 38, 32, 26, 24, 20, 19, 15, 5, -14, -32, -49, -65, -79, -88, -91, -91, -88, -82, -75, -63, -52, -47, -46, -46, -38, -31, -21, -8, 4, 17, 26, 31, 36, 39, 42, 40, 35, 36, 39, 47, 48, 45, 43, 38, 36, 30, 24, 22, 19, 18, 23, 29, 40, 50, 61, 68, 72, 74, 71, 66, 57, 50, 40, 32, 24, 21, 16, 12, 7, -3, -14, -26, -38, -45, -46, -43, -31, -16, 3, 18, 33, 39, 39, 36, 31, 22, 13, 8, 3, -1, -4, -9, -24, -42, -60, -77, -94, -107, -115, -119, -120, -116, -112, -103, -91, -81, -78, -80, -75, -69, -61, -51, -39, -25, -13, -5, 2, 8, 14, 17, 16, 15, 16, 24, 31, 32, 32, 29, 29, 27, 22, 21, 20, 19, 22, 26, 35, 46, 59, 70, 77, 83, 85, 84, 79, 74, 66, 59, 50, 46, 41, 38, 35, 29, 21, 11, 0, -9, -14, -16, -11, 0, 16, 30, 48, 58, 62, 61, 58, 51, 40, 31, 25, 19, 15, 13, 4, -11, -28, -44, -61, -76, -87, -95, -100, -100, -99, -95, -86, -75, -68, -69, -68, -67, -62, -56, -49, -38, -27, -19, -13, -9, -3, 2, 1, -1, -3, 0, 7, 10, 10, 6, 5, 4, 0, -4, -5, -7, -7, -7, -2, 5, 16, 27, 36, 44, 49, 52, 50, 46, 40, 35, 26, 22, 18, 15, 15, 13, 9, 4, -5, -14, -19, -23, -21, -14, 0, 15, 33, 49, 60, 63, 63, 61, 53, 44, 38, 32, 27, 27, 23, 14, 0, -14, -29, -44, -58, -67, -74, -76, -76, -73, -67, -55, -45, -41, -41, -41, -39, -35, -30, -23, -12, -3, 4, 9, 14, 20, 21, 20, 17, 15, 19, 24, 26, 24, 21, 20, 18, 12, 9, 6, 3, 0, 1, 4, 11, 21, 30, 38, 43, 47, 48, 45, 38, 32, 23, 15, 9, 5, 3, 1, -2, -5, -13, -22, -30, -37, -41, -40, -30, -18, -3, 15, 30, 38, 41, 41, 37, 27, 19, 12, 6, 3, 2, -2, -13, -25, -39, -53, -67, -78, -88, -92, -92, -91, -86, -77, -63, -54, -50, -48, -47, -43, -38, -32, -23, -11, -1, 6, 11, 19, 25, 27, 26, 24, 26, 31, 36, 38, 36, 37, 37, 34, 32, 29, 27, 24, 22, 23, 27, 35, 45, 53, 61, 67, 70, 71, 66, 60, 51, 42, 34, 28, 24, 21, 18, 16, 11, 2, -8, -16, -24, -28, -25, -17, -5, 10, 26, 39, 45, 47, 45, 37, 27, 18, 9, 3, 0, -2, -10, -22, -36, -51, -67, -81, -93, -102, -107, -108, -107, -102, -90, -78, -71, -67, -66, -63, -59, -56, -49, -39, -28, -19, -13, -6, 1, 7, 8, 6, 5, 8, 14, 19, 19, 19, 20, 20, 19, 16, 15, 13, 12, 11, 13, 20, 30, 39, 49, 57, 63, 68, 68, 65, 58, 51, 43, 37, 32, 29, 27, 26, 24, 19, 11, 2, -5, -12, -14, -9, 0, 13, 30, 46, 56, 62, 65, 61, 53, 44, 35, 26, 22, 20, 15, 6, -6, -20, -36, -51, -66, -78, -87, -91, -92, -92, -85, -74, -65, -58, -56, -55, -52, -50, -46, -40, -30, -20, -14, -8, -2, 5, 7, 6, 3, 2, 5, 10, 11, 10, 9, 9, 8, 5, 2, 0, -2, -5, -5, -3, 5, 14, 23, 32, 39, 46, 50, 49, 45, 38, 31, 24, 17, 14, 11, 10, 9, 7, 2, -5, -12, -20, -25, -25, -19, -8, 7, 24, 40, 50, 58, 60, 56, 49, 41, 31, 24, 22, 20, 15, 6, -5, -19, -34, -48, -61, -72, -79, -83, -85, -81, -72, -62, -52, -47, -44, -41, -39, -35, -31, -24, -13, -5, 1, 7, 14, 20, 22, 21, 19, 18, 22, 25, 25, 24, 23, 23, 20, 17, 15, 12, 10, 7, 5, 9, 16, 24, 33, 40, 47, 53, 56, 54, 48, 41, 33, 25, 20, 15, 11, 9, 8, 5, -2, -10, -19, -27, -32, -31, -25, -15, 0, 17, 30, 40, 46, 46, 42, 35, 25, 15, 10, 9, 5, -2, -11, -23, -37, -52, -65, -79, -89, -95, -99, -100, -95, -85, -74, -65, -60, -55, -52, -48, -44, -40, -29, -18, -10, -4, 4, 12, 18, 20, 19, 17, 20, 24, 27, 27, 26, 26, 25, 23, 21, 19, 17, 15, 12, 13, 17, 25, 34, 41, 49, 57, 62, 65, 63, 57, 51, 42, 35, 30, 25, 22, 21, 19, 15, 8, 0, -9, -17, -21, -20, -14, -3, 13, 26, 38, 48, 53, 52, 47, 39, 28, 19, 15, 13, 8, 0, -10, -22, -37, -51, -65, -79, -88, -95, -100, -99, -94, -84, -74, -67, -61, -58, -55, -51, -49, -43, -33, -23, -17, -10, -2, 6, 10, 11, 9, 9, 12, 15, 17, 16, 16, 16, 14, 12, 11, 9, 8, 5, 3, 4, 10, 18, 26, 34, 42, 50, 57, 59, 57, 52, 45, 38, 32, 27, 23, 21, 20, 19, 14, 8, 1, -9, 2, 5, 7, 8, -1, 6, 15, 1, 20, 28, 1, 37, 41, 31, 29, 27, 61, 40, -12, 38, 52, -16, -20, -1, -23, -48, -56, -63, -61, -77, -100, -88, -76, -103, -113, -98, -103, -118, -120, -108, -107, -104, -110, -118, -104, -109, -128, -107, -83, -106, -86, -94, -100, -77, -113, -88, -43, -77, -46, -44, -69, -34, -54, -39, 4, -30, 11, 18, -25, 20, 16, 10, 52, 35, 52, 74, 33, 55, 74, 59, 70, 81, 85, 91, 81, 72, 89, 94, 82, 80, 99, 100, 85, 86, 91, 100, 91, 81, 91, 102, 83, 74, 92, 95, 63, 62, 75, 71, 63, 39, 54, 74, 15, 1, 31, 6, -5, -13, -20, -8, -44, -59, -38, -69, -73, -67, -86, -90, -68, -73, -77, -49, -82, -70, -43, -76, -27, 0, -29, 22, 25, -5, 44, 45, 29, 66, 71, 49, 84, 92, 73, 92, 74, 72, 91, 37, 48, 99, 47, 31, 44, 36, 33, -5, -11, 26, 6, -33, -22, -6, -32, -55, -44, -45, -52, -63, -73, -55, -51, -77, -79, -61, -73, -91, -83, -70, -77, -74, -82, -85, -68, -88, -98, -57, -67, -77, -58, -75, -66, -64, -78, -33, -37, -50, -19, -47, -38, -23, -41, 3, 6, -7, 30, 0, -4, 24, 15, 31, 45, 44, 66, 44, 34, 58, 54, 59, 67, 71, 87, 78, 60, 73, 84, 78, 76, 86, 95, 89, 76, 85, 94, 89, 73, 82, 99, 85, 66, 75, 93, 75, 50, 56, 69, 59, 31, 31, 61, 29, -15, 15, 5, -15, -14, -36, -25, -29, -69, -55, -53, -82, -78, -76, -95, -88, -69, -80, -65, -63, -86, -58, -67, -59, -12, -28, -9, 29, -8, 13, 44, 22, 44, 68, 53, 62, 91, 74, 81, 89, 64, 84, 78, 35, 78, 86, 44, 43, 47, 45, 22, -5, 17, 21, -16, -24, -14, -14, -34, -50, -40, -36, -63, -71, -58, -60, -69, -78, -78, -67, -81, -98, -78, -71, -89, -85, -84, -86, -82, -99, -82, -60, -76, -75, -74, -76, -71, -86, -68, -37, -51, -34, -41, -57, -37, -51, -31, -7, -17, -3, 1, 7, 22, 31, 46, 57, 41, 43, 56, 63, 62, 68, 85, 86, 80, 84, 92, 96, 93, 93, 104, 105, 96, 99, 108, 106, 102, 98, 102, 111, 99, 87, 106, 110, 85, 80, 88, 89, 79, 68, 70, 81, 48, 25, 39, 32, 18, 9, 12, 0, -29, -31, -38, -60, -52, -63, -79, -71, -66, -62, -59, -62, -74, -72, -73, -81, -43, -21, -28, 8, 10, -10, 16, 28, 27, 42, 50, 47, 66, 76, 68, 81, 73, 67, 72, 39, 40, 67, 41, 23, 25, 22, 12, -16, -22, -5, -27, -51, -44, -45, -57, -68, -73, -71, -74, -91, -89, -84, -90, -97, -98, -98, -102, -105, -108, -103, -97, -105, -109, -101, -107, -113, -106, -92, -87, -90, -92, -92, -92, -100, -92, -57, -56, -54, -40, -59, -58, -54, -61, -23, -9, -12, 16, 0, -14, 4, 5, 17, 32, 41, 57, 55, 43, 54, 66, 67, 68, 84, 89, 87, 87, 91, 98, 100, 96, 104, 109, 105, 103, 108, 111, 109, 105, 105, 113, 111, 99, 102, 115, 104, 88, 90, 97, 93, 80, 75, 86, 75, 37, 40, 43, 33, 20, 20, -14, -26, -36, -53, -52, -65, -75, -75, -69, -69, -69, -74, -77, -76, -74, -59, -34, -26, -9, 9, 5, 13, 32, 39, 42, 53, 58, 61, 73, 77, 77, 73, 61, 57, 46, 29, 37, 37, 17, 6, 2, -10, -27, -38, -41, -46, -58, -68, -69, -75, -85, -89, -92, -97, -101, -103, -106, -107, -108, -112, -111, -112, -115, -115, -115, -113, -111, -116, -115, -112, -116, -117, -110, -101, -98, -101, -101, -98, -101, -101, -86, -69, -65, -59, -57, -62, -58, -54, -39, -19, -12, 1, 7, -1, 5, 16, 24, 36, 46, 58, 64, 61, 64, 74, 79, 81, 90, 96, 97, 100, 100, 104, 108, 107, 111, 114, 113, 115, 115, 115, 118, 117, 116, 118, 119, 116, 115, 116, 117, 111, 104, 105, 107, 99, 93, 95, 91, 71, 57, 53, 47, 38, 29, 23, 14, -11, -28, -38, -49, -58, -67, -73, -80, -84, -84, -83, -82, -80, -78, -74, -67, -56, -42, -29, -16, -4, 7, 18, 29, 40, 49, 57, 64, 70, 74, 78, 79, 77, 72, 67, 60, 53, 48, 42, 33, 23, 14, 4, -6, -16, -24, -32, -40, -48, -55, -61, -68, -74, -78, -83, -87, -91, -94, -96, -99, -101, -103, -104, -106, -107, -107, -107, -107, -107, -108, -107, -107, -107, -105, -101, -98, -96, -94, -93, -91, -87, -82, -74, -67, -62, -57, -54, -49, -43, -35, -25, -16, -7, -1, 4, 10, 17, 25, 33, 41, 49, 55, 59, 63, 69, 74, 78, 83, 88, 91, 93, 96, 98, 100, 102, 104, 106, 107, 107, 108, 108, 109, 109, 108, 108, 108, 107, 105, 104, 102, 99, 94, 91, 87, 83, 78, 73, 66, 56, 46, 37, 28, 19, 9, 0, -11, -23, -35, -45, -55, -64, -71, -78, -83, -85, -84, -83, -81, -79, -75, -70, -61, -49, -36, -23, -10, 2, 12, 24, 35, 45, 53, 61, 67, 72, 76, 79, 78, 75, 70, 65, 58, 52, 46, 39, 29, 20, 11, 1, -9, -18, -26, -34, -42, -50, -56, -63, -69, -74, -79, -83, -88, -91, -94, -96, -98, -101, -102, -104, -105, -106, -106, -106, -106, -106, -106, -106, -106, -105, -102, -98, -96, -94, -92, -90, -88, -84, -77, -70, -64, -59, -55, -51, -45, -38, -29, -20, -11, -4, 2, 7, 13, 21, 29, 37, 44, 51, 56, 60, 65, 70, 75, 80, 84, 88, 91, 93, 96, 98, 100, 102, 104, 105, 106, 107, 107, 108, 108, 107, 107, 107, 106, 104, 103, 101, 99, 95, 91, 87, 83, 78, 73, 67, 59, 49, 39, 30, 21, 12, 3, -8, -19, -31, -41, -51, -60, -68, -75, -81, -84, -85, -84, -82, -80, -77, -73, -65, -55, -42, -29, -16, -4, 7, 18, 29, 40, 49, 57, 64, 70, 74, 78, 79, 77, 73, 68, 62, 56, 50, 44, 36, 26, 17, 7, -3, -12, -20, -28, -36, -44, -51, -58, -64, -70, -75, -79, -84, -88, -91, -93, -96, -98, -100, -102, -103, -105, -105, -105, -105, -105, -105, -105, -105, -104, -102, -99, -96, -94, -92, -90, -88, -85, -79, -72, -66, -61, -56, -52, -47, -41, -33, -24, -15, -8, -1, 4, 10, 17, 24, 32, 40, 47, 53, 57, 62, 67, 72, 77, 81, 85, 89, 91, 94, 96, 98, 100, 102, 104, 105, 105, 106, 106, 107, 106, 106, 106, 105, 104, 102, 101, 99, 95, 91, 87, 83, 79, 74, 68, 61, 52, 42, 33, 24, 15, 5, -5, -15, -27, -38, -48, -57, -66, -72, -79, -83, -85, -85, -83, -81, -79, -75, -69, -60, -48, -35, -23, -10, 2, 13, 24, 35, 45, 54, 61, 67, 72, 77, 78, 79, 76, 72, 66, 60, 54, 49, 41, 32, 23, 12, 3, -4, -17, -15, 1, -1, 0, 0, 1, 3, 5, 9, 13, 18, 24, 32, 38, 32, 18, -9, -48, -73, -41, 2, -3, -24, -34, -44, -72, -111, -124, -62, 40, 40, -51, -35, 45, 46, -22, -79, 35, 78, -47, -98, -88, -69, -57, -44, -31, -17, -9, -3, 6, 41, 85, 43, -91, -128, -65, -25, -21, -19, -12, 2, 16, 29, 39, 49, 48, 10, -69, -47, 50, 8, -52, -44, 5, 21, -40, -42, 33, 79, 66, 38, 24, 25, 26, 18, 21, 70, 117, 98, 28, -1, 20, 22, 0, 1, 9, -10, -49, -33, 39, 68, 39, -5, -17, -58, -76, 78, 104, 17, 6, -23, -43, -13, 58, 85, 43, 21, 35, 46, 31, 22, 35, 14, -48, -74, -38, 6, 10, -8, -17, -24, -37, -60, -69, -41, 15, 27, -21, -26, 18, 28, -1, -41, 5, 51, -9, -51, -48, -38, -31, -24, -16, -8, -2, 1, 6, 23, 52, 41, -39, -83, -50, -19, -13, -12, -8, 1, 10, 20, 27, 34, 35, 15, -40, -46, 27, 16, -35, -38, -6, 19, -18, -35, 17, 61, 55, 33, 21, 22, 25, 21, 18, 52, 98, 92, 31, -5, 9, 17, -1, -2, 7, -7, -47, -43, 24, 62, 39, -3, -20, -48, -88, 46, 113, 25, 4, -20, -45, -25, 42, 82, 47, 19, 28, 42, 32, 18, 30, 19, -39, -77, -51, -4, 10, -6, -18, -25, -37, -57, -70, -50, 4, 26, -15, -33, 9, 27, 6, -38, -12, 50, 6, -47, -50, -40, -32, -25, -17, -10, -3, 0, 4, 17, 45, 47, -23, -82, -60, -24, -14, -13, -10, -2, 7, 16, 24, 30, 33, 18, -32, -56, 13, 23, -31, -41, -15, 19, -6, -35, 4, 52, 55, 35, 21, 22, 25, 22, 15, 41, 89, 94, 38, -5, 4, 16, 2, -2, 7, -4, -41, -48, 12, 58, 43, 2, -20, -38, -89, 14, 118, 38, 3, -15, -43, -32, 28, 78, 53, 19, 24, 40, 34, 18, 26, 23, -28, -75, -61, -14, 10, -2, -16, -24, -34, -53, -68, -55, -7, 25, -8, -36, 1, 27, 12, -31, -26, 45, 22, -39, -50, -41, -32, -25, -17, -10, -4, 0, 3, 13, 38, 51, -5, -77, -69, -31, -15, -14, -11, -4, 5, 13, 21, 27, 31, 20, -24, -61, -3, 28, -23, -43, -23, 15, 5, -32, -6, 43, 53, 36, 22, 21, 26, 24, 14, 32, 79, 95, 46, -3, 0, 15, 5, -1, 7, -1, -36, -52, 2, 53, 46, 7, -18, -30, -84, -15, 114, 55, 4, -10, -40, -37, 15, 72, 59, 22, 20, 36, 36, 19, 23, 26, -18, -70, -68, -25, 7, 2, -13, -22, -32, -49, -65, -59, -16, 22, -1, -36, -8, 25, 17, -22, -35, 34, 36, -29, -48, -42, -32, -25, -18, -10, -4, 0, 3, 10, 32, 52, 11, -67, -76, -38, -16, -13, -11, -6, 3, 11, 19, 25, 30, 22, -15, -62, -19, 30, -14, -43, -30, 9, 13, -25, -15, 33, 51, 37, 23, 21, 26, 26, 15, 24, 68, 94, 54, 0, -3, 13, 8, 1, 8, 2, -30, -53, -8, 47, 49, 13, -16, -25, -75, -41, 102, 73, 6, -5, -36, -40, 2, 65, 64, 25, 18, 33, 37, 21, 21, 27, -8, -63, -73, -36, 2, 5, -10, -21, -30, -45, -62, -61, -25, 17, 5, -35, -17, 21, 21, -13, -39, 20, 46, -16, -46, -42, -32, -25, -17, -10, -4, 0, 3, 8, 27, 50, 25, -54, -81, -46, -19, -13, -12, -7, 1, 9, 17, 23, 28, 23, -8, -59, -35, 27, -5, -42, -35, 2, 20, -16, -20, 24, 47, 38, 24, 21, 27, 28, 17, 18, 58, 91, 62, 5, -6, 10, 10, 3, 9, 5, -24, -52, -17, 40, 50, 18, -13, -22, -64, -60, 83, 90, 12, -3, -31, -41, -8, 55, 67, 30, 17, 30, 37, 24, 19, 27, 1, -54, -75, -46, -4, 7, -7, -18, -28, -41, -58, -61, -32, 11, 10, -31, -24, 17, 23, -4, -39, 5, 52, -2, -42, -42, -32, -25, -17, -10, -4, 0, 3, 6, 22, 47, 35, -38, -82, -55, -23, -13, -12, -8, -1, 7, 15, 21, 26, 23, -1, -53, -48, 20, 5, -39, -39, -6, 22, -5, -22, 14, 43, 38, 25, 21, 27, 29, 19, 15, 47, 86, 68, 12, -7, 7, 11, 4, 10, 7, -18, -50, -25, 33, 51, 24, -10, -20, -52, -72, 58, 103, 21, -1, -26, -41, -17, 44, 67, 35, 16, 27, 36, 26, 18, 25, 8, -45, -76, -55, -13, 7, -3, -16, -26, -38, -55, -61, -38, 4, 13, -26, -30, 11, 25, 4, -36, -10, 51, 14, -37, -42, -33, -24, -17, -10, -4, 1, 3, 6, 18, 42, 42, -22, -80, -63, -28, -14, -12, -9, -3, 5, 12, 19, 24, 23, 3, -46, -58, 9, 14, -34, -41, -14, 21, 6, -21, 4, 36, 38, 26, 21, 26, 30, 22, 13, 37, 78, 73, 20, -7, 4, 11, 6, 10, 10, -11, -45, -33, 22, 49, 29, -4, -18, -40, -75, 23, 108, 40, 1, -18, -39, -26, 28, 65, 42, 17, 22, 34, 29, 18, 23, 15, -30, -71, -65, -27, 3, 2, -11, -22, -34, -49, -58, -45, -7, 13, -16, -35, -1, 24, 13, -23, -26, 37, 36, -20, -39, -34, -24, -17, -10, -4, 1, 3, 5, 12, 33, 46, 6, -64, -75, -40, -17, -12, -10, -5, 2, 9, 15, 20, 22, 10, -30, -65, -18, 20, -19, -42, -27, 11, 21, -8, -8, 22, 34, 27, 22, 26, 31, 27, 14, 22, 60, 75, 34, -4, -2, 8, 8, 11, 14, -2, -36, -42, 6, 44, 36, 4, -15, -26, -66, -24, 95, 71, 8, -10, -33, -32, 7, 56, 51, 21, 17, 29, 32, 20, 19, 20, -12, -59, -72, -45, -8, 5, -5, -17, -28, -42, -54, -50, -21, 9, -5, -36, -16, 19, 21, -7, -34, 12, 51, 4, -33, -34, -25, -17, -10, -4, 1, 4, 5, 9, 23, 44, 29, -39, -79, -55, -24, -13, -10, -7, -1, 6, 12, 16, 20, 14, -15, -62, -46, 16, -2, -39, -36, -2, 29, 9, -12, 8, 28, 27, 23, 25, 31, 31, 17, 13, 43, 72, 46, 2, -5, 5, 8, 11, 16, 5, -26, -44, -8, 36, 40, 12, -12, -19, -52, -53, 67, 94, 20, -5, -27, -35, -7, 45, 55, 27, 15, 25, 32, 23, 17, 21, 0, -47, -73, -57, -19, 4, 0, -13, -24, -37, -50, -51, -29, 3, 1, -32, -26, 12, 23, 3, -32, -6, 52, 22, -26, -34, -25, -17, -10, -4, 1, 5, 6, 8, 18, 39, 38, -21, -76, -64, -30, -14, -10, -8, -2, 4, 10, 15, 18, 14, -9, -56, -57, 7, 7, -35, -39, -10, 27, 18, -10, 2, 23, 26, 23, 24, 31, 32, 20, 11, 35, 67, 51, 7, -6, 3, 8, 11, 17, 8, -20, -44, -15, 31, 41, 16, -9, -17, -43, -61, 44, 102, 31, -2, -23, -35, -15, 36, 56, 32, 0, -27, 1, -1, -1, 3, -4, -2, 1, -1, -2, 2, 3, -6, 1, 2, -6, 2, 2, -4, -1, 2, -5, 1, 4, -4, 0, -1, 0, -1, -2, 2, 2, -6, 0, 4, -3, -3, 4, -2, -3, -2, 0, 1, 1, -2, -2, 3, -8, 27, -42, 11, 21, -35, 34, -25, 12, 9, -24, 14, 13, -38, 53, -42, -3, 46, -73, 55, -16, -9, 28, -49, 38, -12, -21, 49, -51, 20, 32, -73, 64, -28, -7, 32, -50, 42, -11, -30, 49, -21, -31, 46, -25, -7, 20, -22, 18, -16, -10, 21, -23, 5, 28, -35, 8, 0, 8, -26, 19, 6, -11, -20, 64, -46, -18, 51, -73, 119, -117, 46, 36, -80, 67, -46, 22, 0, -24, 56, -59, 14, 26, -40, 24, -9, 20, -20, -15, 43, -26, -11, 9, 14, -3, -31, 6, 54, -62, 3, 67, -78, 20, 21, -25, 31, -41, 18, 27, -53, 32, 15, -48, 37, -11, 4, -12, -3, 31, -24, -21, 42, -10, -45, 55, -32, 34, -43, -14, 86, -78, 8, 39, -35, -2, 13, 2, 5, -11, -4, 7, 5, -31, 37, -4, -28, 28, -9, -11, 10, -1, 4, -18, 17, -9, -13, 24, -18, 20, -18, -30, 59, -25, -29, 48, -15, -29, 23, 4, -3, -18, 14, 6, -8, -19, 19, 8, -13, 0, 13, -18, 4, 1, 0, 0, 10, -14, -12, 39, -46, 23, 9, -22, 23, -20, -22, 63, -42, -28, 77, -66, 12, 38, -56, 31, 27, -77, 66, -11, -39, 59, -33, -41, 92, -54, -50, 96, -36, -46, 46, -17, 31, -43, -28, 98, -57, -50, 84, -22, -44, 39, -8, 17, -28, -13, 63, -67, 16, 10, 3, -15, -4, 36, -34, -1, 26, -27, -2, 13, 7, -22, 0, 27, -11, -19, 6, 26, -42, 14, 18, -7, -14, -10, 37, -14, -24, 25, -4, -5, -10, 3, 35, -39, -7, 31, -8, -23, 15, 4, -1, -25, 28, 7, -35, 34, -16, -1, 9, -35, 45, -22, -17, 48, -52, 24, 22, -65, 48, 7, -45, 47, -19, -33, 71, -70, 46, -7, -52, 68, -25, -35, 48, -13, -17, 14, 2, -12, 8, -10, 1, 22, -32, 4, 34, -26, -18, 29, -7, -19, 15, -7, 15, -8, -29, 50, -22, -35, 53, -19, -37, 47, -9, -40, 41, 1, -27, 7, 3, 0, 0, -7, 13, -7, -21, 26, 14, -44, 11, 40, -51, 10, 26, -28, 16, -13, -3, 31, -42, 11, 34, -52, 11, 34, -43, 10, 29, -19, -21, 27, -10, -5, 10, -14, 11, 3, -35, 43, 3, -52, 37, 22, -66, 49, -12, -19, 50, -58, 16, 42, -70, 50, -2, -42, 60, -69, 43, 11, -57, 54, -8, -31, 23, -8, -7, 24, -32, 11, 21, -51, 60, -44, -6, 68, -87, 33, 45, -79, 50, -7, -13, 21, -40, 31, 12, -41, 18, 24, -39, 15, 7, -17, 25, -20, -12, 43, -47, 17, 6, -16, 10, 4, -11, -1, 14, -10, -7, 6, 9, -23, 9, 3, 13, -30, 16, 16, -33, 17, 4, -17, 23, -29, 3, 54, -86, 50, 11, -41, 30, -23, 15, 18, -60, 56, 7, -65, 49, -4, -12, 1, -6, 19, -4, -33, 35, -10, -12, 13, -2, -2, -2, 2, -10, 16, -8, -11, 19, -6, -19, 24, -14, 9, 3, -24, 24, -6, -13, 19, -11, -6, 6, -9, 16, -8, -10, 14, -10, -1, -5, 16, -8, -25, 37, -11, -27, 37, -14, -13, 19, -17, 14, -5, -15, 26, -27, 10, 11, -23, 22, -5, -19, 25, -7, -28, 44, -35, 0, 25, -31, 31, -10, -26, 46, -41, 2, 33, -40, 24, 8, -43, 44, -12, -25, 37, -25, -6, 29, -27, 5, 24, -40, 24, -1, -25, 23, -1, -6, -2, -1, 14, -24, 8, 13, -11, 0, -13, 16, 15, -56, 43, 12, -35, 14, -9, 18, -10, -19, 28, -3, -27, 23, -2, -14, 27, -35, 10, 35, -68, 44, 7, -43, 46, -21, -25, 56, -35, -21, 51, -33, -8, 28, -27, 19, -2, -26, 36, -26, 3, 13, -12, 6, -10, 8, -14, 15, -12, 0, 13, -9, -16, 32, -27, 3, 23, -49, 49, -17, -31, 63, -64, 25, 36, -76, 61, -11, -47, 75, -54, -9, 69, -81, 32, 29, -63, 46, -7, -26, 39, -31, 6, 18, -26, 13, -5, 5, -5, -2, 5, -12, 17, -17, -2, 22, -25, 1, 20, -19, 3, 6, -6, 3, -9, 10, -6, -3, 7, -7, -3, 12, -5, -5, -11, 24, -7, -23, 24, 0, -14, 0, 12, -10, -2, 5, 0, 1, -10, 10, -2, -17, 26, -11, -16, 28, -22, 6, 4, -17, 30, -27, -7, 46, -54, 15, 29, -42, 25, -4, -15, 26, -29, 11, 15, -28, 19, -7, 1, 8, -20, 14, 1, -15, 11, -2, -2, 0, -10, 15, -5, -12, 15, -1, -15, 12, 4, -15, 9, -1, -9, 9, -5, -6, 13, -12, 1, 6, -6, -3, 6, -4, 0, -6, 11, -9, -2, 13, -12, -2, -1, 8, -11, 4, 2, -6, 4, -4, 4, 0, -13, 15, 0, -21, 23, -5, -15, 15, -2, -9, 6, -2, -4, 2, 3, -1, -7, 7, -2, -9, 6, 2, -9, 4, 5, -12, 10, -9, 4, 5, -16, 12, -2, -13, 20, -13, -4, 17, -23, 14, 2, -20, 22, -13, -3, 15, -22, 12, 4, -18, 17, -7, -7, 13, -14, 6, 4, -10, 9, -5, -6, 7, 0, -7, 8, -4, -1, 0, -6, 4, 7, -14, 2, 13, -16, 3, 10, -15, 7, -1, -10, 14, -10, -2, 11, -9, -4, 7, -6, 3, -3, -5, 9, -6, -3, 5, 1, -7, 3, -2, 0, -2, 0, 4, -3, -2, 4, -6, 4, -2, -2, 0, 1, 0, -7, 7, -2, -7, 9, -7, -4, 11, -15, 11, -2, -9, 9, -4, -3, 2, 3, -7, 5, 0, -5, 6, -7, 1, 7, -10, -2, 13, -9, -4, 8, -4, -2, -1, 1, 1, -7, 4, 5, -8, 0, 6, -6, 0, 3, -4, 0, 1, -2, 2, -4, -4, 8, -7, -1, 6, -9, 8, -3, -6, 12, -12, 1, 10, -11, 1, 5, -6, 3, -2, -3, 7, -10, 2, 7, -12, 5, 2, -5, 3, -5, 0, 6, -10, 3, 4, -8, 2, 2, -3, 3, -8, 8, 2, -14, 10, 3, -12, 8, 2, -11, 8, -2, -6, 9, -7, -4, 10, -9, -1, 7, -7, 1, 3, -8, 8, -2, -8, 10, -3, -5, 5, -6, 3, 1, -8, 10, -5, -5, 7, -4, -2, 2, -3, 1, -1, -3, 4, -3, 0, 0, 0, 0, -4, 3, -2, -3, 3, -5, 3, 0, -7, 5, 1, -8, 5, 1, -6, 6, -5, 0, 3, -7, 3, 2, -6, 3, 2, -6, 3, 1, -3, -2, 5, -4, -1, 3, -4, 0, 0, -3, 5, -5, -3, 7, -5, -3, 6, -4, 0, -1, -3, 3, -2, -1, 2, -1, -2, 1, -2, 1, -1, -7, 8, -1, 5, -7, 13, -22, 8, -7, 8, -110, -28, 24, 54, 36, 2, 60, -45, 57, 42, -43, 20, 41, -66, 24, -11, 18, -18, -38, -63, -36, 30, -11, 33, 25, 30, 18, 11, -18, -5, 5, -46, 40, 1, -13, -18, -20, -31, 20, 10, 29, -7, -18, 40, -29, -17, 42, -19, 6, -4, 6, -8, 10, -26, -5, 3, 1, -17, 6, 0, 19, -1, 8, 0, -6, -10, -1, -12, -1, 1, -3, 8, -7, 4, 11, 4, 14, -13, 16, -19, -4, -13, -13, -14, 6, 4, -1, 4, 11, -1, 11, -1, 1, -4, -1, -15, 6, -9, 1, -1, 0, 3, 1, -8, 3, -1, -1, 2, -2, 2, -2, 1, -5, -7, 3, -3, 6, -3, 4, -1, 0, -4, 2, -7, 3, -6, -1, -1, 4, 0, 3, -2, 2, -5, 5, -8, -3, -3, 2, -5, 7, -1, 4, -2, 4, -10, 6, -6, -1, -4, 5, -13, 7, -6, 5, -8, 17, -20, 14, -6, 9, -40, 71, -127, 9, -73, 127, 76, -28, 74, -32, 8, -62, -49, -38, 40, -68, 22, -12, 68, 10, 39, -10, 0, 35, -23, 0, -59, -15, -7, -3, -23, 1, -20, 37, 27, 2, 30, -2, 17, 2, -5, -7, -27, -29, 16, -3, -11, 1, -16, -5, -8, -10, 7, 32, 9, 5, -4, 16, 5, -8, -17, -16, 5, -13, 8, 11, 15, -10, -9, 0, -1, 2, 7, -3, -23, 9, 2, 3, 1, -13, -1, -6, 11, -6, 8, 1, 12, -12, 9, -14, 8, -1, 0, -3, -13, 4, -7, -4, 8, 5, -5, -7, 4, -2, -3, 2, 3, -6, 8, -3, 1, -3, -2, 2, -6, 2, -4, -3, -4, 3, 1, 0, 0, 1, -1, -1, 2, -2, 0, -4, -2, 1, 2, 0, -3, 1, -3, 0, -1, -3, -6, 2, -2, 3, -4, 10, -8, 9, -5, 12, -19, 46, 37, -128, 60, -90, 102, -65, 40, -57, 39, -6, 23, -8, 19, 24, 15, -17, -47, -27, -36, -16, 21, 3, 23, 14, 50, -8, 19, 25, 7, -9, -28, -63, -37, 0, -42, 54, -17, 68, -3, 30, -12, -4, 11, -15, 9, -25, -15, -2, -27, -25, 38, -8, -13, 33, 24, 12, -38, 39, -12, -3, -17, -44, 38, 2, 27, 3, -5, -4, -13, -30, -56, -4, 11, 1, 9, 17, 46, 25, -14, 6, -3, -7, -21, 2, 16, -5, -22, 2, -2, 6, -12, -25, -15, 10, 9, 8, 11, 43, 8, -5, -22, -16, 14, -31, 16, 7, -7, -26, -20, -2, 9, 11, 26, 7, 6, -20, -13, 0, 4, 17, -17, -18, 10, 2, -10, 27, -8, 24, -23, -14, 1, 0, 13, -19, 14, 10, -16, 16, -4, -20, 20, -33, 2, 2, 24, 21, -3, -26, -24, -18, -18, 10, 10, 24, 18, 2, 9, -24, 16, -14, -8, 9, -5, -14, 8, -5, 30, -11, 11, -13, -15, -12, 7, 4, -13, -13, 13, -13, 12, 23, 9, 0, 14, -10, -9, -35, -2, -21, 12, -1, 17, 19, 11, -4, 0, -18, -24, 11, -10, 1, 11, 12, -13, -16, 10, -23, 21, 9, -9, 3, 12, -6, 3, -5, 12, 0, -2, 0, -19, -9, 5, -11, -7, 10, 1, -3, 9, 18, -6, 0, -1, 1, -13, 2, 1, -3, -8, 17, -4, -9, 18, -15, 8, -1, -11, -5, -14, 11, -5, -7, 12, 16, -7, 7, -3, -11, -5, -6, 1, 4, -3, -3, 15, 5, 0, 3, 6, -16, 4, -14, -6, -9, -4, 2, 11, 11, 7, -2, 4, -12, -7, -14, -6, -7, 9, 4, 7, -2, 6, 5, 6, -4, -3, -4, 7, -7, -11, -9, 0, -3, 7, -2, -2, 3, 13, -4, -6, -15, 9, -7, -1, 4, 6, 5, 8, -6, -8, 0, -11, -4, 6, -8, 4, 3, 5, 13, -4, -9, -3, 4, -3, -3, 4, -1, -12, 6, -14, 2, 3, 15, 2, 6, -7, -8, 3, 1, -2, 3, -3, -12, -6, -14, 7, -2, 13, 6, 10, 6, 0, -2, -10, -12, -8, -6, -7, -6, 6, 4, -2, 5, 2, 0, -1, 3, -11, 4, 0, 20, -8, -2, 0, -1, -3, 7, -3, -4, -2, -6, -10, -10, -8, 1, 2, 5, 8, 2, 5, 8, 3, 4, 3, -2, -15, 0, -1, -7, -2, -5, -10, 10, -1, 5, 3, 5, -1, -2, -8, -5, -9, 1, -8, 6, 5, 4, 1, 1, 2, 3, -2, 4, -7, 1, -7, -9, -2, 0, 2, 3, 6, -8, 8, 3, 0, -2, -9, -3, -2, 0, 3, -1, -2, -3, 7, -3, 10, -8, 1, -12, 3, -7, 2, -3, 7, 4, 4, 0, 0, -6, -1, -5, -3, -4, -7, 0, 5, 7, 0, 2, -3, 10, -1, 3, -7, -5, -4, -9, -3, -7, 5, -4, 9, 2, 1, 4, 5, 0, -5, 1, -8, 4, -9, 5, -5, 0, 3, -2, -1, 1, 1, -7, 7, 0, 3, -5, 0, -3, -1, -1, -5, -1, 1, -1, 1, -1, 0, 2, 0, 2, -7, -7, 4, -1, 0, 3, 4, -1, -3, -4, -6, 3, -2, 4, -1, 5, -2, -1, -5, -2, -4, 1, 3, 2, 2, 0, -3, 1, 1, -3, -3, -1, 1, -3, -2, -1, -2, -3, -1, 0, 4, 3, 5, 2, 1, -4, -9, -3, -7, 1, -2, 7, -2, 3, 3, 3, 1, 0, -1, -6, -7, -6, -4, -1, 1, 0, 5, 2, -2, 2, -3, -1, 3, -1, 1, -4, -4, -5, 0, -7, 2, -4, 3, 4, 1, 2, -1, -1, -2, -2, 0, -1, 1, -1, -1, -3, 1, 1, 3, -3, -1, 1, 1, -2, -3, -8, -5, 0, -1, 5, 2, 3, 1, -2, -1, -1, -3, 1, 1, -2, -3, -3, -1, 0, -1, 1, 2, 2, 5, 0, -1, -2, -1, -2, 0, -4, 0, -5, -1, -1, 0, 1, 5, 4, -2, -1, -2, 0, -6, -1, 0, 1, -1, -2, 1, 0, 0, 3, 1, -2, 1, -2, -4, -1, 0, -1, -1, -4, -2, -4, 2, -1, 1, 0, 3, 2, 0, 4, -1, 4, -6, 2, -4, -3, -5, -4, -3, 0, 2, 0, 1, 4, 2, 2, -2, -2, -5, -6, -5, -3, -2, 1, -1, 0, 0, 2, 2, 2, 0, 4, -2, 3, 2, -1, -2, -3, -3, -3, -5, -5, -5, -1, -1, 0, 2, 2, 4, 1, 2, 1, 2, -1, -1, -3, -4, -5, -3, -2, -2, -1, 1, 4, 2, 2, 2, 1, -1, -2, -6, -2, -3, 2, -1, 1, -2, 0, 2, 1, 2, -2, 1, 0, -2, -2, -3, 0, -2, -1, -1, 0, -2, -2, 1, 0, 2, -1, 1, -1, 0, -1, -1, 0, -1, 0, -2, 2, 0, 2, 2, 5, 3, 6, 8, 12, 13, -6, -110, -7, 51, -99, -128, 10, -28, -39, 25, -33, -27, 41, 34, -5, 17, 23, 25, 24, 23, 20, 24, 25, 24, 21, 20, 23, 23, 16, 20, 9, 20, 18, 10, 14, 5, 14, 11, 7, 5, 3, 10, 2, 7, -4, 0, 3, 0, -3, -5, -6, -1, -12, -4, -17, -10, 9, -42, -40, 65, 40, -58, 29, 72, 39, 50, 31, -1, 30, 25, -7, -4, -33, -47, -29, -49, -74, -69, -71, -79, -61, -51, -57, -53, -34, -20, -22, -16, -10, -6, -2, 1, 3, 4, 8, 8, 12, 10, 9, 14, 13, 12, 12, 13, 12, 12, 14, 12, 12, 12, 12, 13, 12, 9, 11, 11, 11, 7, 8, 7, 8, 9, 2, 5, 8, -6, 2, 17, -17, -20, 18, 5, -15, 15, 27, 21, 37, 44, 41, 46, 38, 26, 32, 26, -4, -15, -6, -20, -44, -50, -54, -60, -59, -58, -58, -54, -46, -38, -32, -26, -19, -14, -9, -5, -1, 2, 5, 7, 8, 10, 11, 12, 13, 13, 14, 14, 14, 13, 13, 14, 15, 14, 11, 13, 14, 13, 12, 10, 12, 12, 10, 10, 8, 6, 11, 9, -1, 5, 11, -1, -6, 1, -1, -4, 0, -1, 0, 14, 25, 24, 28, 37, 38, 38, 38, 31, 22, 14, 4, -5, -15, -26, -38, -47, -52, -54, -56, -57, -55, -51, -45, -39, -34, -28, -22, -17, -13, -8, -3, -1, 2, 5, 7, 8, 10, 11, 12, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 12, 13, 13, 12, 11, 12, 11, 9, 11, 9, 6, 7, 8, 5, 3, 2, 0, 0, 0, -2, -3, 0, 3, 6, 11, 18, 23, 27, 31, 34, 35, 32, 27, 21, 14, 5, -5, -15, -26, -35, -43, -48, -52, -53, -53, -52, -49, -44, -40, -35, -29, -24, -19, -14, -10, -6, -3, 1, 3, 5, 7, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 12, 11, 13, 11, 10, 10, 9, 9, 8, 7, 7, 5, 4, 3, 2, 0, -1, -1, 0, 2, 4, 8, 12, 17, 22, 25, 28, 30, 30, 28, 24, 19, 12, 3, -5, -14, -23, -31, -37, -43, -46, -46, -48, -47, -43, -41, -38, -33, -29, -25, -21, -16, -12, -8, -5, -2, 0, 3, 5, 7, 9, 10, 11, 12, 12, 13, 14, 13, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 9, 9, 8, 7, 7, 6, 5, 4, 4, 3, 3, 3, 3, 5, 6, 8, 10, 12, 14, 17, 18, 19, 20, 19, 17, 14, 10, 5, 0, -6, -11, -17, -22, -26, -29, -32, -34, -34, -35, -34, -32, -31, -28, -26, -23, -20, -17, -14, -11, -8, -5, -3, 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 5, 5, 5, 4, 4, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 12, 10, 8, 5, 2, -2, -6, -10, -14, -18, -21, -24, -26, -28, -29, -29, -30, -29, -28, -27, -25, -23, -20, -18, -15, -12, -10, -7, -4, -2, 0, 2, 4, 6, 7, 9, 10, 10, 11, 11, 12, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 5, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 13, 13, 12, 11, 10, 8, 5, 2, -1, -5, -9, -13, -16, -19, -22, -24, -26, -27, -28, -28, -28, -27, -26, -24, -22, -20, -18, -15, -13, -10, -7, -5, -2, 0, 2, 4, 5, 7, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 6, 5, 5, 5, 5, 6, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 12, 11, 10, 9, 7, 5, 2, -1, -5, -8, -12, -15, -18, -21, -23, -25, -26, -27, -27, -27, -26, -25, -24, -22, -20, -18, -16, -13, -11, -8, -6, -3, -1, 1, 3, 4, 6, 7, 8, 9, 10, 10, 10, 11, 11, 11, 10, 10, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 6, 5, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 10, 9, 7, 4, 2, -1, -4, -7, -11, -14, -17, -19, -21, -23, -24, -25, -26, -26, -25, -24, -23, -22, -20, -18, -16, -13, -11, -9, -6, -4, -2, 0, 2, 4, 5, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 10, 10, 10, 9, 9, 8, 8, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 10, 10, 8, 7, 5, 2, -1, -3, -7, -10, -13, -15, -18, -20, -22, -23, -24, -25, -25, -24, -24, -23, -21, -20, -18, -16, -14, -11, -9, -7, -5, -2, 0, 1, 3, 5, 6, 7, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 9, 9, 8, 8, 8, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 9, 9, 8, 7, 6, 4, 2, 0, -2, -5, -7, -10, -12, -15, -17, -18, -20, -21, -21, -22, -22, -21, -21, -20, -18, -17, -15, -13, -12, -10, -8, -6, -4, -2, 0, 1, 3, 4, 5, 6, 7, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 7, 6, 5, 4, 3, 1, -1, -3, -5, -7, -9, -10, -12, -14, -15, -16, -17, -18, -18, -18, -18, -17, -17, -16, -15, -13, -12, -11, -9, -7, -6, -4, -3, -1, 0, 1, 3, 4, 5, 5, 6, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 0, -1, -3, -5, -7, -9, -10, -12, -13, -15, -16, -17, -17, -18, -18, -18, -17, -17, -16, -15, -14, -12, -11, -9, -8, -6, -5, -3, -2, -1, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 4, 3, 2, 0, -1, -3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 10, 11, 12, 12, 13, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 29, 29, 29, 28, 28, 28, 29, 30, 31, 31, 31, 31, 28, 19, -8, -41, -53, -57, -59, -60, -62, -62, -63, -64, -65, -65, -66, -67, -69, -69, -69, -72, -74, -73, -74, -76, -78, -79, -81, -82, -82, -83, -81, -83, -85, -81, -81, -88, -90, -80, -64, -47, -32, -23, -18, -15, -13, -12, -12, -12, -13, -13, -13, -13, -13, -12, -12, -11, -9, -7, -6, -4, -2, -1, 0, 1, 2, 4, 5, 7, 10, 12, 14, 16, 18, 19, 18, 19, 21, 19, 20, 22, 22, 22, 25, 27, 28, 29, 29, 29, 29, 29, 30, 31, 31, 31, 33, 34, 34, 35, 34, 33, 31, 30, 29, 26, 25, 26, 25, 22, 22, 21, 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 17, 16, 16, 16, 15, 13, 13, 14, 14, 15, 13, 12, 13, 13, 11, 12, 14, 14, 16, 17, 15, 16, 19, 19, 19, 19, 21, 19, 17, 18, 19, 18, 15, 15, 17, 18, 18, 13, 11, 14, 15, 14, 11, 6, 5, 10, 13, 17, 18, 11, 2, -2, -2, -3, 2, 14, 24, 30, 37, 47, 52, 52, 56, 63, 65, 65, 63, 65, 72, 75, 73, 71, 73, 77, 82, 82, 77, 77, 82, 90, 99, 104, 99, 89, 84, 86, 94, 106, 119, 127, 126, 117, 104, 87, 64, 42, 24, 10, -2, -15, -22, -25, -27, -30, -35, -37, -36, -34, -33, -36, -40, -42, -44, -43, -44, -48, -53, -57, -59, -57, -53, -52, -53, -57, -62, -68, -73, -75, -75, -71, -63, -56, -48, -40, -34, -29, -26, -23, -22, -21, -19, -19, -20, -21, -22, -22, -22, -22, -22, -21, -21, -21, -20, -19, -19, -18, -18, -17, -17, -16, -14, -14, -13, -11, -9, -9, -9, -9, -9, -8, -8, -8, -8, -8, -7, -6, -7, -6, -4, -3, -2, -2, -3, -4, -3, -3, -2, -1, 0, 0, -1, -1, 0, -1, -1, -1, -3, -5, -5, -8, -10, -10, -9, -9, -10, -11, -11, -11, -11, -11, -10, -9, -10, -10, -10, -11, -12, -12, -13, -12, -11, -12, -14, -14, -11, -10, -12, -11, -11, -12, -12, -11, -11, -13, -12, -9, -6, -6, -7, -7, -6, -5, -4, -4, -5, -8, -12, -11, -8, -4, -3, -5, -6, -7, -9, -12, -13, -8, -3, -2, -4, -8, -11, -14, -15, -17, -19, -19, -15, -8, -1, 2, 4, 8, 12, 17, 23, 26, 25, 24, 25, 30, 36, 40, 39, 36, 33, 32, 33, 37, 43, 49, 53, 53, 49, 45, 43, 43, 46, 52, 60, 67, 76, 82, 82, 78, 69, 58, 47, 37, 26, 14, 2, -9, -16, -21, -24, -28, -32, -35, -37, -38, -37, -36, -36, -36, -39, -43, -46, -49, -51, -49, -47, -46, -45, -45, -48, -52, -58, -62, -65, -66, -65, -62, -58, -54, -50, -45, -39, -34, -30, -28, -25, -23, -21, -20, -20, -20, -20, -19, -18, -19, -20, -18, -17, -18, -17, -17, -18, -17, -16, -15, -15, -13, -12, -10, -10, -10, -9, -8, -7, -6, -4, -4, -5, -6, -5, -4, -4, -3, -2, -2, -1, -1, -1, 0, 2, 3, 2, 2, 3, 2, 1, 2, 4, 5, 5, 4, 4, 4, 3, 2, 2, 1, 0, 0, -1, -4, -5, -4, -2, -2, -3, -3, -3, -2, -1, -2, -3, -2, -3, -4, -4, -3, -4, -6, -7, -4, 0, 0, -2, -4, -4, -3, -2, -2, -3, -4, -4, -3, -2, -1, 3, 6, 8, 6, 3, 0, 0, 2, 4, 5, 4, 3, 2, 2, 2, 1, 0, -1, 2, 7, 11, 9, 6, 2, -1, -3, -3, -5, -7, -8, -6, -3, 2, 8, 13, 17, 18, 18, 19, 23, 28, 34, 40, 42, 42, 40, 39, 39, 40, 42, 46, 50, 55, 59, 59, 55, 51, 48, 48, 51, 57, 63, 70, 76, 82, 86, 88, 89, 86, 80, 71, 61, 51, 43, 34, 25, 18, 10, 2, -5, -9, -12, -13, -12, -12, -13, -14, -17, -22, -26, -29, -28, -27, -25, -24, -24, -25, -27, -31, -35, -40, -43, -46, -47, -49, -49, -46, -43, -40, -36, -32, -28, -24, -21, -18, -16, -14, -13, -13, -12, -11, -11, -12, -11, -10, -9, -11, -11, -11, -12, -12, -12, -10, -10, -10, -10, -9, -8, -7, -6, -5, -4, -4, -4, -4, -4, -3, -2, -2, -1, -2, -3, -2, -1, 0, 0, 1, 2, 3, 2, 1, 1, 2, 3, 3, 4, 5, 4, 4, 5, 6, 7, 6, 4, 3, 3, 3, 2, -1, -3, -3, -1, -1, -2, -3, -3, -2, -1, 1, 0, -1, -1, -2, -5, -6, -5, -4, -4, -4, -4, -6, -6, -4, -1, 0, -2, -6, -9, -10, -8, -5, -4, -3, -3, -1, 1, 1, -1, -3, -4, -2, 0, 2, 2, 0, -3, -6, -7, -6, -4, -3, -2, -1, -1, -1, 0, 1, 0, -3, -9, -14, -18, -18, -15, -12, -9, -8, -7, -5, -3, -2, 0, 5, 11, 17, 22, 25, 24, 23, 21, 20, 22, 27, 32, 37, 40, 41, 40, 39, 37, 35, 34, 34, 35, 39, 45, 52, 59, 66, 71, 73, 75, 74, 71, 65, 60, 55, 48, 39, 28, 17, 7, -1, -7, -11, -13, -13, -14, -17, -21, -24, -28, -31, -32, -32, -32, -32, -31, -29, -29, -30, -33, -36, -40, -44, -47, -50, -52, -54, -55, -54, -52, -49, -47, -43, -39, -35, -31, -28, -26, -24, -22, -21, -19, -18, -17, -17, -16, -15, -16, -18, -17, -16, -16, -17, -18, -18, -17, -16, -16, -14, -13, -13, -12, -12, -12, -11, -10, -10, -9, -7, -8, -9, -10, -10, -8, -6, -5, -6, -6, -5, -3, -3, -4, -4, -4, -3, -2, -2, -1, -1, -1, 0, 2, 3, 3, 3, 2, 1, 0, -1, -1, -1, -2, -3, -5, -5, -4, -2, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 3, 2, 0, -1, 1, 2, 1, -1, -1, 2, 2, 0, 1, 2, 2, -1, -4, -10, -21, -30, -36, -41, -44, -40, -30, -18, -10, -8, -11, -13, -8, 3, 18, 32, 41, 44, 45, 48, 49, 43, 32, 23, 14, 7, 8, 16, 27, 35, 37, 30, 18, 9, 5, 3, 2, 1, 1, -1, -6, -11, -12, -6, -2, -5, -11, -18, -28, -39, -47, -55, -69, -86, -99, -102, -92, -70, -46, -28, -15, -3, 7, 17, 26, 28, 24, 23, 30, 42, 53, 57, 50, 36, 21, 5, -5, -4, 6, 20, 31, 35, 34, 29, 26, 27, 37, 56, 76, 85, 80, 71, 63, 55, 47, 34, 13, -13, -32, -39, -40, -46, -65, -93, -117, -128, -128, -126, -120, -110, -96, -78, -58, -36, -14, 3, 10, 20, 41, 60, 68, 63, 54, 45, 39, 36, 32, 28, 29, 35, 41, 47, 46, 41, 39, 43, 53, 68, 80, 78, 64, 46, 28, 13, 3, -9, -35, -64, -80, -82, -74, -66, -71, -91, -111, -121, -118, -105, -86, -68, -57, -49, -37, -22, -7, 5, 14, 26, 42, 55, 56, 46, 35, 25, 14, 6, 2, 1, 3, 11, 22, 32, 40, 43, 42, 46, 60, 77, 88, 90, 78, 54, 30, 14, 2, -15, -37, -62, -82, -90, -89, -86, -90, -99, -107, -109, -101, -81, -54, -29, -14, -5, 7, 24, 40, 49, 56, 68, 83, 92, 92, 87, 74, 54, 32, 12, -5, -19, -25, -24, -18, -7, 1, -1, -6, -4, 13, 41, 69, 84, 80, 63, 44, 32, 29, 25, 11, -10, -25, -31, -35, -40, -48, -65, -87, -104, -109, -102, -87, -69, -58, -54, -42, -21, 0, 13, 29, 51, 71, 84, 89, 86, 75, 54, 33, 14, -3, -19, -29, -27, -22, -18, -11, -8, -16, -26, -19, 2, 24, 40, 48, 42, 27, 21, 29, 34, 24, 7, -5, -14, -23, -28, -32, -45, -67, -82, -85, -78, -63, -46, -34, -29, -24, -13, 0, 12, 25, 44, 65, 79, 85, 86, 78, 60, 41, 27, 12, -5, -15, -15, -14, -13, -8, -7, -17, -27, -23, -3, 23, 44, 51, 43, 25, 12, 11, 14, 8, -3, -10, -15, -22, -28, -30, -36, -55, -73, -78, -74, -71, -63, -51, -43, -39, -34, -25, -18, -9, 8, 28, 46, 56, 61, 62, 58, 47, 36, 28, 20, 12, 11, 16, 19, 20, 21, 15, 0, -6, 10, 37, 57, 63, 55, 36, 15, 2, -3, -9, -19, -27, -34, -43, -49, -49, -52, -66, -82, -86, -81, -77, -71, -61, -51, -47, -43, -35, -22, -12, 2, 24, 47, 58, 63, 67, 66, 58, 51, 45, 34, 18, 9, 7, 7, 7, 8, 1, -14, -24, -12, 18, 47, 64, 68, 63, 53, 42, 37, 38, 36, 29, 21, 16, 11, 5, -2, -17, -36, -49, -52, -56, -62, -63, -61, -61, -63, -60, -56, -49, -37, -19, 2, 17, 25, 30, 34, 37, 37, 37, 34, 25, 15, 11, 13, 14, 14, 8, -7, -21, -16, 9, 37, 53, 60, 61, 53, 40, 33, 34, 32, 22, 14, 12, 10, 6, -2, -15, -32, -48, -57, -60, -63, -67, -66, -63, -63, -65, -64, -58, -49, -34, -13, 6, 16, 21, 28, 34, 38, 41, 43, 36, 25, 19, 21, 26, 27, 20, 4, -11, -11, 7, 31, 53, 66, 70, 66, 57, 49, 47, 44, 33, 21, 17, 16, 10, 1, -9, -26, -46, -60, -67, -76, -84, -84, -80, -78, -79, -78, -73, -65, -52, -32, -11, 4, 10, 17, 25, 32, 36, 40, 37, 24, 13, 15, 23, 23, 11, -5, -19, -25, -16, 9, 38, 59, 70, 72, 67, 63, 63, 60, 50, 39, 32, 28, 22, 14, 3, -14, -34, -53, -65, -76, -87, -94, -93, -91, -94, -96, -93, -86, -76, -56, -30, -9, 4, 16, 29, 40, 51, 63, 65, 52, 39, 39, 45, 42, 29, 11, -7, -22, -24, -8, 19, 42, 54, 60, 63, 61, 58, 57, 53, 43, 36, 36, 34, 28, 21, 11, -5, -24, -39, -52, -65, -75, -77, -75, -75, -78, -80, -78, -73, -61, -43, -23, -9, 1, 10, 23, 39, 52, 56, 47, 36, 35, 41, 42, 33, 17, -2, -24, -35, -26, -3, 18, 32, 42, 50, 52, 53, 52, 47, 38, 31, 30, 31, 29, 26, 22, 14, -1, -18, -33, -46, -58, -65, -65, -65, -71, -79, -81, -79, -75, -62, -42, -27, -21, -14, 1, 19, 34, 40, 36, 29, 27, 31, 38, 39, 29, 9, -12, -27, -28, -14, 8, 25, 37, 50, 62, 67, 66, 62, 53, 42, 36, 37, 36, 32, 30, 25, 12, -7, -24, -39, -54, -65, -67, -67, -72, -78, -81, -82, -81, -70, -51, -35, -29, -23, -7, 15, 30, 37, 40, 35, 25, 25, 36, 41, 33, 15, -6, -26, -36, -27, -9, 7, 20, 35, 50, 58, 59, 58, 52, 43, 37, 37, 37, 36, 34, 31, 24, 8, -11, -29, -44, -57, -67, -70, -73, -79, -86, -92, -93, -87, -72, -59, -53, -46, -29, -9, 7, 20, 28, 26, 19, 17, 27, 38, 38, 26, 7, -12, -25, -26, -15, 1, 14, 28, 47, 61, 67, 68, 68, 63, 54, 51, 53, 51, 49, 49, 47, 34, 14, -5, -22, -39, -56, -65, -67, -73, -86, -96, -97, -92, -86, -77, -69, -61, -49, -28, -6, 10, 22, 27, 25, 24, 33, 49, 56, 48, 32, 13, -5, -15, -12, -2, 7, 18, 35, 50, 59, 63, 65, 61, 53, 48, 46, 44, 43, 46, 49, 43, 27, 10, -6, -25, -45, -53, -53, -60, -75, -87, -90, -90, -88, -81, -75, -72, -65, -48, -25, -6, 5, 10, 13, 18, 31, 49, 60, 58, 44, 28, 12, -1, -7, -7, -1, 8, 23, 41, 54, 61, 65, 66, 63, 56, 48, 43, 41, 42, 44, 43, 37, 25, 8, -12, -32, -44, -49, -53, -64, -80, -91, -95, -93, -89, -85, -82, -78, -68, -50, -27, -6, 0, -1, 0, 0, 0, 1, 2, 3, 6, 9, 13, 17, 19, 13, -4, -15, -10, 4, 19, 26, 15, -9, -16, 6, -2, -18, 38, 64, 21, -48, 30, 82, -23, -63, -50, -26, -7, 12, 26, 47, 83, 100, 3, -108, -87, -30, -6, 5, 18, 33, 46, 47, 21, -52, -46, 48, 3, -54, -32, 22, 25, -7, 12, 9, -18, -33, -24, 2, 44, 88, 92, 10, -28, -1, 1, 20, 42, 1, -17, 53, 72, 12, -16, -74, -31, 127, 52, 1, -35, -46, 13, 39, -13, -13, 13, 12, 11, 8, -57, -80, -44, -5, 14, 18, 6, -13, -26, -11, -8, -24, 3, 30, 14, -28, -12, 41, -2, -37, -35, -23, -12, -1, 6, 17, 34, 53, 19, -55, -67, -32, -13, -5, 2, 12, 19, 24, 14, -24, -47, 12, 11, -36, -35, -1, 18, -3, 0, 5, -13, -25, -22, -5, 19, 53, 69, 21, -28, -10, -5, 6, 28, 8, -25, 23, 57, 17, -17, -49, -63, 84, 70, 3, -23, -50, -6, 36, -2, -20, 8, 14, 9, 13, -37, -82, -58, -19, 8, 17, 10, -9, -26, -19, -7, -24, -9, 25, 22, -17, -28, 33, 16, -32, -37, -27, -15, -4, 4, 13, 27, 48, 35, -35, -72, -43, -17, -7, -1, 9, 16, 23, 17, -12, -51, -7, 21, -27, -40, -12, 19, 6, -3, 5, -9, -22, -23, -8, 11, 42, 68, 38, -23, -16, -6, 3, 25, 19, -24, 8, 54, 31, -13, -33, -76, 46, 95, 13, -13, -48, -20, 32, 13, -22, 2, 15, 10, 15, -17, -77, -67, -31, 3, 17, 15, -3, -21, -23, -7, -20, -18, 18, 27, -4, -34, 17, 33, -21, -36, -29, -16, -6, 4, 11, 23, 42, 47, -12, -69, -54, -22, -8, -2, 7, 15, 22, 20, -2, -46, -27, 23, -13, -41, -22, 15, 16, -2, 4, -5, -18, -21, -10, 5, 32, 64, 53, -12, -21, -6, 0, 21, 27, -16, -6, 48, 42, -6, -22, -71, 2, 106, 31, -6, -41, -32, 22, 25, -18, -4, 15, 12, 14, -1, -64, -74, -42, -5, 16, 19, 4, -16, -25, -10, -14, -23, 9, 29, 9, -31, -2, 42, -5, -33, -30, -18, -8, 3, 9, 19, 36, 51, 10, -58, -63, -29, -11, -2, 4, 13, 20, 21, 6, -35, -44, 16, 1, -38, -30, 7, 23, 3, 2, -2, -16, -20, -12, 2, 23, 56, 62, 3, -24, -7, -2, 17, 30, -5, -17, 37, 49, 4, -17, -57, -37, 99, 55, 0, -31, -41, 9, 33, -10, -11, 13, 14, 12, 9, -47, -78, -53, -15, 12, 20, 9, -10, -24, -14, -11, -25, -2, 27, 18, -21, -20, 39, 13, -29, -31, -20, -9, 1, 8, 17, 30, 49, 29, -41, -70, -39, -15, -4, 2, 11, 17, 21, 11, -22, -52, 0, 14, -31, -36, -4, 25, 11, 1, -1, -13, -19, -13, 0, 15, 45, 65, 20, -24, -10, -4, 12, 30, 8, -22, 24, 52, 17, -14, -39, -61, 71, 81, 8, -21, -44, -5, 34, 2, -16, 9, 16, 11, 14, -29, -76, -62, -27, 6, 20, 15, -4, -21, -19, -9, -23, -12, 22, 25, -8, -30, 26, 30, -20, -31, -23, -11, -1, 8, 14, 25, 44, 42, -19, -69, -50, -20, -6, 1, 9, 15, 20, 15, -11, -51, -19, 20, -20, -39, -15, 23, 20, 2, 0, -11, -17, -14, -2, 9, 35, 63, 37, -19, -14, -5, 8, 28, 18, -22, 9, 50, 28, -11, -26, -68, 32, 100, 22, -13, -43, -18, 30, 15, -17, 4, 16, 12, 15, -12, -69, -69, -39, -2, 18, 19, 2, -17, -22, -10, -19, -20, 15, 27, 4, -31, 7, 41, -7, -30, -25, -13, -3, 6, 12, 22, 38, 48, 3, -61, -60, -27, -9, 0, 7, 13, 19, 17, -2, -44, -37, 18, -7, -39, -24, 15, 28, 7, 0, -9, -16, -14, -3, 6, 25, 57, 49, -9, -18, -7, 3, 25, 26, -15, -4, 45, 38, -5, -18, -61, -8, 103, 42, -6, -37, -30, 21, 25, -13, -3, 16, 13, 14, 2, -56, -73, -49, -12, 15, 21, 8, -11, -23, -13, -15, -24, 4, 28, 14, -25, -12, 42, 9, -26, -26, -15, -5, 5, 11, 19, 32, 48, 22, -46, -67, -36, -12, -2, 4, 12, 17, 18, 4, -33, -50, 6, 6, -35, -31, 4, 31, 14, 0, -8, -15, -14, -4, 4, 17, 48, 57, 4, -21, -8, -1, 21, 30, -5, -15, 36, 44, 5, -14, -46, -40, 88, 67, 2, -29, -37, 9, 31, -6, -9, 14, 15, 13, 11, -40, -74, -58, -24, 9, 22, 13, -6, -21, -17, -13, -25, -6, 25, 21, -13, -25, 33, 26, -19, -27, -18, -6, 3, 10, 16, 27, 45, 36, -26, -69, -46, -17, -4, 2, 10, 15, 18, 9, -22, -55, -11, 15, -26, -36, -8, 30, 23, 2, -6, -14, -14, -6, 4, 11, 37, 59, 19, -20, -10, -4, 16, 31, 7, -20, 23, 47, 15, -13, -32, -58, 58, 88, 13, -21, -40, -5, 32, 4, -13, 10, 17, 12, 14, -23, -70, -65, -35, 1, 20, 17, 0, -18, -20, -12, -23, -16, 19, 25, -1, -30, 16, 39, -8, -26, -20, -8, 1, 9, 14, 23, 39, 44, -5, -63, -57, -24, -7, 1, 8, 13, 17, 12, -12, -52, -30, 17, -15, -38, -18, 23, 32, 7, -6, -13, -14, -7, 3, 8, 27, 55, 33, -16, -13, -6, 10, 30, 17, -20, 10, 46, 25, -9, -21, -60, 19, 100, 31, -13, -39, -17, 27, 15, -13, 4, 17, 13, 15, -8, -61, -69, -46, -10, 17, 21, 6, -13, -22, -13, -20, -22, 10, 27, 9, -27, -4, 44, 6, -24, -22, -11, -1, 8, 13, 20, 33, 46, 14, -50, -65, -33, -11, 0, 5, 12, 15, 14, -4, -43, -46, 10, -2, -36, -27, 13, 36, 15, -4, -13, -14, -8, 3, 7, 18, 49, 43, -7, -16, -7, 5, 27, 24, -14, -3, 42, 33, -3, -16, -51, -17, 97, 51, -3, -38, -5, -13, 1, -7, 5, -22, -32, -35, -32, -43, -35, -55, -42, -66, -48, -80, -57, -17, -128, -59, -76, 0, -26, 1, -33, 21, 3, 16, 15, 26, 43, 28, 66, 6, 97, 40, 103, 67, 101, 102, 98, 94, 21, 98, 90, 57, 78, 89, 81, 61, -6, 54, 4, 62, 19, 27, 34, 12, 16, 14, -17, 19, -5, -2, -13, -38, -24, -3, -33, -14, -11, -16, 0, -13, 7, -26, -13, -16, 6, -57, -23, -28, -13, -9, -34, -32, -20, -87, -62, -28, -38, -75, -37, -27, -41, -71, -48, -30, -44, -83, -67, -52, -48, -45, -46, -45, -63, -47, -40, -32, -45, -24, -32, -43, -21, -17, 0, 21, 26, 43, 51, 62, 47, 41, 55, 57, 68, 34, 53, 63, 62, 71, 60, 61, 56, 53, 56, 54, 38, 50, 58, 50, 40, 28, 54, 39, 41, 38, 22, 32, 20, -3, 19, -1, -7, -6, -16, -16, -14, -27, -29, -46, -66, -61, -51, -54, -61, -41, -50, -47, -52, -55, -45, -44, -28, -58, -56, -31, -37, -36, -32, -18, -16, -34, -29, -9, -21, -20, -30, -22, -17, -19, -8, -12, -14, -6, -14, -6, -11, -2, 4, -6, 9, 8, 17, 23, 13, 31, 13, 24, 30, 28, 29, 30, 43, 34, 37, 52, 42, 44, 50, 67, 59, 49, 54, 48, 43, 51, 45, 42, 62, 47, 39, 37, 36, 24, 28, 13, 3, 9, -11, -3, -9, -14, -18, -34, -27, -29, -39, -42, -38, -46, -37, -46, -43, -41, -35, -38, -31, -38, -34, -39, -39, -34, -48, -44, -47, -49, -54, -52, -44, -53, -37, -47, -38, -31, -38, -27, -19, -19, -15, -16, 0, 0, 2, 7, 13, 29, 22, 32, 32, 39, 47, 41, 40, 55, 48, 41, 44, 57, 43, 36, 47, 43, 42, 37, 32, 32, 27, 33, 36, 30, 23, 25, 25, 22, 18, 22, 20, 16, 8, 6, 12, 7, 0, 1, 3, -5, -14, -9, -7, -8, -19, -15, -16, -23, -21, -21, -32, -31, -29, -26, -27, -29, -33, -26, -29, -30, -39, -28, -41, -43, -35, -34, -32, -29, -28, -28, -25, -27, -24, -27, -27, -27, -22, -23, -17, -9, -10, -14, -10, -8, -4, -2, -1, -3, 5, 4, 10, 11, 7, 13, 11, 14, 27, 22, 22, 22, 27, 36, 34, 36, 37, 45, 44, 47, 48, 51, 49, 52, 51, 52, 48, 50, 47, 48, 42, 40, 29, 33, 24, 22, 12, 5, 0, -3, -5, -9, -21, -21, -25, -19, -28, -28, -30, -33, -39, -42, -42, -46, -46, -45, -42, -43, -47, -47, -36, -32, -30, -34, -31, -22, -29, -29, -30, -26, -28, -30, -21, -26, -27, -21, -19, -16, -11, -12, -8, -2, 1, -4, 1, 0, 1, 9, 8, 7, 12, 10, 13, 20, 17, 18, 21, 26, 29, 30, 30, 29, 34, 33, 34, 33, 30, 32, 33, 28, 33, 29, 35, 32, 31, 30, 31, 30, 25, 27, 24, 21, 21, 20, 16, 17, 12, 6, 4, -3, 1, -6, -7, -11, -13, -11, -10, -8, -13, -12, -9, -17, -14, -19, -24, -22, -24, -30, -32, -30, -33, -37, -39, -40, -42, -39, -41, -39, -40, -41, -35, -35, -35, -37, -36, -33, -30, -25, -25, -19, -16, -16, -10, -6, -7, -4, -2, 1, 3, 6, 10, 9, 15, 17, 18, 17, 13, 19, 18, 17, 19, 20, 24, 24, 27, 27, 29, 30, 26, 28, 28, 27, 28, 26, 25, 24, 25, 20, 19, 17, 18, 15, 12, 13, 10, 6, 8, 6, 3, 4, 3, 0, -3, 0, -1, -2, -5, -4, -5, -4, -5, -6, -8, -9, -9, -12, -11, -16, -16, -15, -15, -13, -17, -16, -17, -17, -21, -20, -25, -24, -24, -24, -26, -30, -30, -27, -30, -26, -26, -27, -27, -25, -24, -19, -20, -17, -13, -12, -8, -8, -8, -6, -5, -2, -1, 0, 3, 8, 10, 12, 16, 18, 24, 25, 25, 28, 30, 28, 32, 33, 31, 32, 31, 35, 33, 31, 31, 27, 28, 26, 23, 23, 20, 22, 18, 16, 13, 11, 9, 5, 4, -2, -2, -3, -8, -9, -11, -12, -13, -15, -15, -15, -15, -15, -14, -12, -12, -13, -13, -8, -11, -10, -12, -10, -12, -12, -8, -8, -9, -9, -9, -8, -9, -10, -11, -11, -10, -13, -14, -13, -16, -16, -17, -17, -18, -19, -18, -17, -16, -16, -15, -15, -13, -12, -10, -12, -10, -9, -8, -6, -6, -3, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 14, 13, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -1, -2, -3, -4, -5, -5, -6, -7, -7, -8, -9, -9, -10, -11, -11, -12, -12, -13, -13, -13, -13, -14, -14, -14, -15, -15, -15, -15, -15, -15, -16, -16, -16, -15, -15, -15, -14, -13, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 16, 16, 15, 15, 14, 14, 13, 12, 11, 10, 9, 7, 6, 5, 3, 1, 0, -2, -4, -5, -7, -9, -10, -11, -13, -14, -15, -15, -16, -17, -17, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -17, -17, -16, -16, -15, -14, -14, -13, -12, -11, -10, -9, -8, -7, -6, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 12, 12, 11, 10, 9, 8, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, 0, 0, -1, 2, 1, 0, 1, 4, 2, 2, 2, 5, 2, 5, 5, 8, 4, 13, 15, 19, -62, -65, 56, -18, -128, -39, 15, -57, -10, 19, -22, -11, 36, 30, 5, 19, 25, 17, 21, 21, 16, 21, 18, 17, 17, 15, 14, 13, 12, 10, 6, 8, 6, 6, -1, 1, -4, 7, -10, -36, 35, 64, -25, -18, 83, 50, 22, 39, 21, 19, -4, -20, 28, 0, -88, -55, -5, -55, -83, -64, -58, -77, -61, -22, -39, -57, -15, 2, -14, -9, -1, 1, 1, 2, 9, 5, 6, 11, 9, 9, 10, 11, 12, 12, 10, 9, 9, 13, 7, 3, 14, 4, -3, 2, 2, 17, 40, 12, 14, 55, 58, 44, 39, 38, 37, 6, 4, 31, -6, -50, -25, -15, -49, -52, -41, -60, -68, -32, -25, -47, -36, -9, -5, -7, -3, 3, 4, 6, 8, 11, 9, 10, 14, 14, 11, 13, 15, 14, 13, 14, 12, 11, 12, 12, 8, 8, 3, 4, 5, -1, 8, 32, 21, 14, 43, 50, 39, 47, 39, 20, 23, 16, 5, -9, -23, -26, -34, -48, -37, -48, -71, -56, -34, -43, -49, -36, -20, -14, -13, -9, -4, -1, 1, 3, 6, 6, 6, 9, 10, 8, 10, 11, 11, 11, 11, 10, 10, 10, 10, 6, 6, 4, 3, 6, -3, 2, 25, 23, 16, 34, 38, 43, 51, 31, 19, 38, 22, -10, -7, 0, -25, -45, -34, -32, -54, -62, -47, -39, -45, -47, -36, -24, -19, -16, -11, -6, -3, 0, 2, 4, 6, 7, 8, 10, 11, 9, 11, 12, 11, 11, 12, 11, 10, 10, 8, 7, 6, 3, 5, 4, 0, 13, 28, 23, 19, 36, 50, 42, 30, 31, 39, 24, -6, -2, 7, -21, -40, -27, -34, -51, -51, -44, -42, -45, -45, -37, -27, -22, -18, -13, -9, -6, -2, 1, 2, 5, 7, 7, 9, 11, 10, 10, 12, 12, 11, 12, 11, 10, 10, 9, 7, 7, 4, 5, 7, 1, 7, 27, 24, 15, 34, 47, 37, 32, 36, 36, 26, 4, -1, 4, -13, -30, -27, -34, -47, -46, -42, -43, -45, -44, -38, -31, -25, -21, -17, -12, -8, -5, -1, 1, 3, 5, 6, 8, 9, 10, 10, 10, 11, 11, 11, 11, 11, 10, 9, 7, 7, 6, 3, 6, 5, 6, 17, 23, 19, 29, 40, 35, 33, 36, 34, 26, 14, 3, 0, -6, -18, -26, -32, -39, -40, -38, -39, -41, -40, -36, -31, -27, -23, -19, -15, -12, -8, -4, -2, 0, 3, 4, 5, 7, 8, 9, 9, 9, 10, 10, 10, 10, 10, 9, 8, 8, 8, 7, 8, 10, 11, 14, 19, 22, 25, 28, 29, 29, 29, 27, 21, 14, 7, -1, -5, -11, -19, -26, -29, -31, -32, -33, -34, -33, -32, -29, -26, -24, -21, -18, -15, -12, -9, -6, -4, -2, 0, 2, 3, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 11, 12, 14, 16, 18, 20, 22, 23, 24, 24, 23, 20, 17, 12, 7, 2, -3, -8, -13, -17, -21, -23, -25, -26, -27, -27, -27, -26, -25, -23, -21, -19, -17, -14, -12, -9, -7, -5, -3, -1, 1, 2, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, 15, 16, 18, 19, 21, 22, 22, 22, 21, 19, 17, 13, 9, 4, 0, -5, -10, -14, -18, -21, -23, -25, -26, -26, -26, -26, -25, -23, -22, -20, -18, -15, -13, -11, -9, -6, -4, -2, 0, 1, 3, 4, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 11, 12, 13, 14, 15, 17, 18, 20, 21, 21, 21, 21, 19, 17, 14, 11, 7, 2, -3, -7, -11, -15, -19, -21, -23, -25, -25, -26, -25, -25, -24, -22, -21, -19, -17, -15, -12, -10, -8, -6, -4, -2, 0, 1, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, 15, 16, 17, 19, 20, 20, 21, 20, 19, 18, 15, 12, 8, 4, 0, -4, -9, -13, -16, -19, -21, -23, -24, -25, -25, -25, -24, -23, -21, -20, -18, -16, -14, -12, -9, -7, -5, -3, -2, 0, 1, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 20, 20, 19, 18, 16, 13, 10, 6, 2, -2, -6, -10, -13, -16, -19, -21, -23, -24, -24, -24, -24, -23, -22, -20, -19, -17, -15, -13, -11, -8, -6, -5, -3, -1, 0, 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 19, 18, 16, 14, 11, 8, 4, 0, -3, -7, -11, -14, -17, -19, -21, -22, -23, -23, -23, -23, -22, -21, -19, -18, -16, -14, -12, -10, -8, -6, -4, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19, 18, 17, 15, 12, 9, 6, 3, -1, -5, -9, -12, -15, -17, -19, -21, -22, -23, -23, -23, -22, -21, -20, -18, -17, -15, -13, -11, -9, -7, -6, -4, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 17, 16, 14, 12, 10, 7, 4, 0, -3, -6, -9, -12, -15, -17, -18, -20, -20, -21, -21, -21, -20, -19, -18, -17, -15, -14, -12, -10, -9, -7, -5, -4, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 15, 14, 12, 11, 8, 6, 3, 0, -3, -6, -9, -12, 1, -1, 2, -1, 4, 2, 8, 5, 10, -5, 0, 5, 17, -11, 0, 19, -17, 26, 65, 15, 29, 3, 35, 67, 50, 88, 59, 117, 28, -6, -16, 29, 63, 62, -40, 59, 22, -95, -49, -55, 19, 36, -15, 26, -117, 60, 8, -101, -115, 23, 60, -32, -106, -84, -88, -127, -99, -117, -110, -56, -42, -53, -79, -44, 43, 10, -11, 72, 22, 61, 10, -92, -106, -111, -35, -68, -128, -67, -36, -118, -97, -96, -4, 75, 70, 113, 36, 73, 115, 37, 6, 79, 97, 89, -8, -38, -8, -72, -8, -29, -35, 73, 98, 66, 12, 40, 113, 106, 87, 126, 112, 127, 87, -3, -21, -23, 40, 14, -68, -20, 21, -57, -67, -67, -4, 69, 53, 90, 17, 36, 78, -7, -54, -2, 32, 21, -71, -109, -89, -124, -103, -114, -113, -37, -4, -30, -88, -83, 15, 13, -35, 42, 28, 33, 14, -90, -92, -104, -37, -34, -115, -73, -9, -75, -89, -85, -29, 67, 51, 97, 55, 47, 115, 46, -9, 42, 90, 96, 26, -36, 11, -43, -25, -6, -37, 59, 104, 88, 31, 22, 96, 116, 69, 110, 119, 119, 109, 11, -15, -26, 18, 37, -45, -32, 34, -13, -62, -62, -30, 61, 47, 75, 46, 14, 72, 14, -58, -35, 16, 30, -38, -109, -78, -109, -116, -102, -123, -57, -2, -11, -58, -95, -18, 22, -41, -3, 36, 20, 31, -69, -94, -100, -72, -21, -91, -92, -9, -33, -82, -81, -57, 48, 52, 70, 81, 35, 97, 69, -10, 8, 66, 94, 55, -27, 4, -5, -40, -1, -33, 30, 102, 101, 61, 19, 70, 121, 72, 77, 123, 112, 121, 36, -13, -21, -10, 38, -18, -43, 27, 25, -40, -59, -45, 40, 54, 52, 68, 15, 56, 35, -48, -58, -12, 25, -10, -98, -84, -83, -122, -101, -123, -81, -8, -3, -28, -85, -47, 20, -28, -39, 23, 18, 31, -38, -99, -92, -97, -35, -66, -102, -26, -3, -60, -77, -69, 18, 59, 47, 87, 46, 73, 86, 3, -13, 34, 80, 70, -8, -12, 19, -32, -12, -21, 3, 91, 105, 87, 34, 51, 114, 89, 53, 106, 115, 119, 65, -10, -13, -25, 20, 4, -45, 9, 44, -8, -49, -51, 14, 61, 39, 68, 34, 39, 51, -30, -67, -41, 7, 5, -76, -96, -65, -111, -110, -115, -103, -20, -1, -9, -58, -65, 8, -9, -55, -6, 17, 24, -11, -94, -89, -102, -64, -50, -101, -51, 6, -30, -66, -71, -12, 59, 40, 72, 67, 58, 91, 24, -21, 6, 56, 74, 14, -22, 23, -8, -24, -14, -13, 71, 106, 101, 62, 42, 101, 105, 49, 76, 114, 114, 87, 3, -12, -23, -6, 13, -37, -11, 45, 24, -29, -49, -8, 57, 40, 53, 54, 32, 56, -6, -65, -61, -21, 6, -52, -101, -65, -85, -115, -109, -116, -42, 0, -1, -27, -65, -12, 7, -51, -37, 7, 17, 6, -76, -95, -94, -91, -52, -90, -76, -2, -4, -46, -66, -35, 46, 46, 49, 78, 57, 85, 50, -17, -13, 26, 64, 34, -22, 9, 18, -22, -14, -18, 42, 103, 105, 88, 50, 83, 114, 63, 49, 96, 110, 99, 26, -14, -15, -23, 6, -24, -29, 33, 45, 0, -38, -23, 44, 50, 37, 60, 38, 52, 21, -54, -70, -48, -7, -31, -95, -78, -63, -104, -108, -117, -69, -4, -1, -5, -47, -30, 13, -33, -58, -14, 8, 11, -50, -99, -87, -101, -70, -77, -92, -22, 10, -22, -52, -46, 23, 55, 36, 70, 66, 74, 69, -2, -23, 1, 43, 43, -11, -8, 29, -4, -17, -16, 18, 91, 105, 102, 71, 72, 112, 83, 40, 70, 101, 102, 50, -10, -10, -24, -10, -13, -36, 14, 52, 27, -18, -28, 26, 58, 33, 51, 49, 46, 40, -34, -70, -66, -31, -22, -81, -92, -56, -83, -105, -112, -91, -17, 0, 2, -22, -37, 7, -12, -61, -39, -5, 7, -27, -93, -90, -96, -90, -72, -95, -48, 9, -1, -33, -46, 0, 55, 37, 50, 72, 68, 77, 20, -25, -15, 17, 40, 3, -20, 22, 19, -12, -14, 2, 70, 105, 106, 92, 72, 104, 100, 48, 46, 83, 98, 70, 3, -12, -16, -23, -11, -34, -8, 46, 47, 11, -21, 8, 57, 41, 36, 53, 45, 48, -6, -64, -72, -57, -28, -61, -98, -65, -60, -94, -105, -103, -41, 1, 0, -1, -29, -6, 5, -48, -60, -26, -3, -12, -74, -97, -86, -100, -80, -89, -74, -6, 13, -10, -35, -18, 41, 48, 33, 64, 68, 75, 46, -15, -25, -7, 24, 16, -20, 4, 33, 5, -11, -5, 43, 98, 105, 105, 85, 93, 110, 67, 35, 59, 87, 81, 25, -13, -9, -23, -18, -27, -25, 30, 55, 37, -1, -3, 46, 53, 29, 44, 47, 48, 20, -48, -72, -72, -47, -48, -93, -82, -51, -73, -96, -102, -66, -6, 0, 5, -10, -16, 10, -26, -66, -49, -20, -10, -51, -98, -86, -93, -93, -85, -88, -32, 14, 8, -16, -23, 22, 54, 32, 45, 67, 70, 61, 4, -27, -21, 2, 17, -13, -13, 29, 26, -1, -5, 23, 83, 104, 106, 100, 90, 110, 87, 40, 38, 68, 80, 45, -6, -9, -14, -24, -23, -32, 8, 52, 53, 25, 1, 31, 60, 35, 30, 45, 45, 36, -24, -68, -76, -67, -49, -80, -94, -57, -54, -81, -95, -82, -23, 2, 1, 4, -12, 4, -5, -57, -65, -40, -20, -36, -87, -94, -83, -97, -87, -90, -57, 2, 18, 2, -12, 8, 10, -20, 30, 25, 21, 14, 4, 15, -48, -33, 11, -70, 54, -5, -21, -8, -3, 73, -52, 65, -55, 80, -28, -67, -3, -13, 21, -49, -2, 11, 36, 59, -60, 34, -28, 21, -25, -45, 54, 5, 0, -19, -12, 20, 54, -51, -23, 22, 36, -59, -20, 8, 28, -9, -54, 127, -44, 69, -128, 5, 69, -8, -98, 45, 69, 20, -97, 23, -7, 121, -81, -2, -21, 51, -67, -14, -24, 127, -60, 45, -116, 127, -29, -93, -23, 107, -5, -21, -62, 37, 41, 29, -74, -63, 103, 24, -59, -44, 62, 43, -28, -46, 7, 72, 19, -70, -47, 42, 53, -68, -13, 37, 59, -38, -60, 39, 66, 27, -128, 36, 77, 15, -74, -15, 75, 38, -49, -11, -39, 16, -8, -30, 35, 41, -1, -2, 17, -68, 99, -97, 60, -49, 32, -44, -29, 82, -26, 39, -35, 10, 38, -20, -21, -92, 83, -24, 13, 31, -33, 22, 45, -31, -24, 9, -24, -32, 42, -17, 34, 7, -27, 6, 61, -9, -34, -5, -8, -17, -6, -34, 17, 43, -9, 35, -34, 16, 27, -24, -17, -17, 5, -17, 42, -31, 22, 17, -26, -22, 32, 41, -27, -25, -10, -5, 16, -2, 13, -1, 48, -33, -27, 6, 16, 13, -37, -11, 18, 25, -42, -11, 46, -7, -15, 9, 15, 4, -3, -36, -24, 31, -8, 14, 12, 27, -19, -17, -14, -7, 42, -5, -15, 5, 1, -15, 14, 43, -19, 1, -25, -35, 16, 16, 29, -12, 8, -14, 1, 21, -8, -12, -22, -4, 24, 26, -16, -22, 37, 3, -41, 7, 4, 3, 30, 4, -27, 11, -6, -26, 33, 23, -23, -14, -20, -7, -4, 36, 0, 18, 10, -27, 1, 1, 16, -1, -4, -44, -5, 17, 9, 13, -4, -3, 31, 24, -14, -26, 9, -27, -28, 19, 22, 32, -11, -15, 5, 15, -23, -21, 16, 14, 18, -11, -26, 13, 10, -12, -12, 11, 14, -6, -13, -3, 6, -6, 3, 12, 32, 14, -22, -45, -10, 37, 11, -50, -11, 50, 22, -13, -4, -4, 15, -16, -33, 7, 34, -9, -14, -1, 21, 15, -14, -12, -6, 7, 8, 2, 0, -5, 6, 15, 4, -9, 13, 3, -51, -18, 27, 10, 5, -11, 6, -1, 5, 22, 2, -14, -39, -12, 19, 17, 4, 11, 5, -25, 2, 23, 8, 2, -3, -39, -22, 4, 18, 6, 14, 25, 20, -17, -20, 17, 7, -43, -38, -18, 17, 24, -6, 30, 44, 6, -36, -20, 7, 24, 1, -69, -25, 47, 15, -4, 35, 19, -18, -22, -12, 20, 39, -36, -49, 9, 28, -16, 9, 34, 36, -22, -69, -16, 39, 7, -28, -3, 33, -18, -7, 18, 53, 24, -37, -61, -10, 38, 2, -24, -11, 12, 17, 0, 28, 50, -5, -59, -57, 22, 14, -15, -5, 22, 9, -20, 19, 33, 31, -33, -62, -13, -2, 45, -9, -4, -3, 19, 8, -8, 40, 8, -16, -44, -19, 16, 3, 23, -32, 22, 5, -9, 5, 26, 21, -27, -18, -45, 3, 15, 0, 7, 7, 7, 13, 18, -10, 3, -5, -30, -30, -3, 9, 31, 17, -10, 19, 28, -33, -20, 31, 14, -67, -27, 13, 20, 29, 1, -2, 24, -3, -26, -12, 32, -7, -31, -17, 5, 22, 11, -6, 6, 7, 2, 7, 5, -12, -22, -17, -24, 22, 47, 1, 2, 10, 5, -29, -5, 13, 1, -30, -28, -5, 23, 25, 6, 5, 1, 7, 0, 5, 3, -33, -37, -6, 19, 20, 26, -1, -15, 21, 9, -14, -13, 0, -11, -24, -9, 9, 23, 1, 1, 32, 11, -25, -18, 5, -5, -6, -9, -10, 2, 18, 4, 12, 6, -2, -8, 2, 2, -7, 2, -22, -5, 17, 25, 15, -5, -1, -24, -8, -10, -5, 12, 7, -4, -10, 4, 8, 22, 11, -1, -12, -31, -17, 6, 12, 11, 5, -3, -1, 22, 0, -4, 3, -18, -17, -3, 16, 9, 2, -5, 0, 4, -9, 18, 17, -22, -19, -8, -6, 21, 11, -6, -16, 33, 13, -15, -3, -15, 1, -3, -10, -7, 8, 17, -11, 9, 19, 0, 5, 0, -18, -13, 2, -20, 10, 29, -11, -13, 5, 11, 16, 4, -25, -21, 13, -5, 1, 3, -1, 6, 13, -7, -1, 17, -6, -6, -9, -6, -3, -1, 1, 18, 11, -22, 2, 18, -2, -15, 1, 5, -12, -10, -7, 9, 26, 10, -11, 5, 0, -7, -3, -11, -9, -3, 2, -10, 19, 28, -3, -3, -4, 9, -14, -5, -7, 8, -3, -27, 5, 37, 11, -2, 3, -27, -15, 12, -2, 14, 2, -8, -16, 22, 11, -1, 10, -17, -8, -5, -23, 2, 29, 8, -21, 8, 12, 6, 8, -17, 3, -2, -12, -27, 16, 25, -5, -7, 2, 19, 1, -15, 7, 2, -5, -34, 2, 18, 17, -10, 2, 18, -1, -12, -10, 5, 1, -16, -9, 12, 21, 4, -10, 2, 12, 1, -19, -11, 20, 5, -14, -21, 5, 17, -5, 3, 17, 4, -25, -5, 5, 4, 0, -5, 2, 2, -1, 1, 13, 0, -11, -8, 3, 2, -1, -3, -3, 11, 8, -6, 2, 7, 4, -5, -23, -2, 14, -1, -15, -2, 15, 10, 1, -4, 16, 1, -24, -12, 8, 8, -20, -2, 14, 13, 10, 2, 2, -9, -6, -9, -3, 5, 7, -3, -9, 0, 2, 8, 3, -1, 2, -4, 0, -1, -1, -1, -2, -8, -14, -19, -28, -51, -53, -49, -48, -49, -44, -37, -30, -23, -14, -8, -11, -5, 3, 11, 2, 0, 8, 19, 10, 1, 6, 18, 15, 4, 4, 17, 19, 13, 9, 20, 27, 26, 26, 33, 42, 45, 53, 59, 68, 69, 83, 89, 92, 85, 88, 91, 80, 56, 37, 29, 9, -25, -54, -65, -74, -94, -113, -112, -103, -101, -103, -93, -79, -66, -62, -50, -41, -33, -27, -17, -11, -12, -8, 0, 7, -1, -2, 5, 15, 8, -1, 3, 15, 13, 2, 2, 12, 17, 12, 8, 15, 23, 24, 25, 29, 38, 42, 50, 56, 65, 68, 78, 87, 91, 87, 87, 91, 84, 64, 43, 33, 16, -14, -44, -60, -70, -87, -107, -111, -105, -101, -103, -96, -84, -70, -64, -55, -45, -36, -30, -22, -14, -14, -11, -4, 4, 0, -3, 1, 11, 8, -1, 0, 10, 12, 3, 0, 9, 15, 11, 7, 14, 22, 23, 24, 28, 37, 42, 49, 55, 64, 67, 78, 87, 91, 88, 88, 93, 86, 67, 47, 36, 20, -10, -40, -56, -67, -84, -104, -109, -105, -101, -103, -96, -85, -71, -65, -56, -46, -38, -31, -23, -16, -15, -12, -6, 2, -1, -5, 0, 9, 6, -1, -1, 8, 11, 3, 0, 8, 14, 11, 7, 13, 21, 23, 23, 27, 37, 41, 48, 54, 63, 67, 77, 86, 91, 89, 89, 93, 87, 70, 51, 39, 23, -6, -36, -53, -64, -81, -101, -107, -103, -100, -102, -96, -85, -72, -66, -57, -47, -39, -32, -25, -17, -16, -13, -7, 0, -3, -5, -1, 7, 6, -2, -2, 7, 9, 2, -1, 7, 13, 10, 7, 12, 20, 22, 23, 27, 36, 41, 48, 54, 63, 68, 77, 87, 91, 91, 91, 95, 89, 73, 54, 43, 27, -1, -31, -49, -61, -78, -98, -105, -102, -99, -101, -96, -85, -73, -66, -58, -48, -40, -33, -26, -19, -17, -14, -9, -2, -4, -6, -3, 5, 4, -3, -3, 5, 8, 1, -1, 6, 12, 10, 7, 11, 20, 22, 23, 27, 35, 41, 47, 54, 62, 68, 76, 86, 91, 91, 92, 96, 91, 76, 58, 46, 30, 3, -27, -45, -57, -75, -94, -103, -100, -98, -100, -96, -85, -74, -67, -59, -49, -41, -34, -28, -20, -19, -15, -10, -3, -5, -7, -4, 3, 3, -4, -4, 4, 7, 1, -2, 5, 11, 9, 6, 11, 19, 21, 22, 26, 35, 40, 46, 53, 61, 67, 76, 86, 91, 92, 93, 97, 93, 78, 61, 49, 33, 7, -22, -41, -54, -72, -91, -100, -99, -97, -100, -96, -86, -74, -67, -60, -51, -42, -35, -29, -22, -20, -17, -11, -5, -6, -8, -5, 2, 1, -5, -5, 2, 5, 0, -3, 3, 10, 8, 5, 10, 18, 21, 21, 25, 34, 39, 45, 52, 61, 67, 75, 85, 91, 92, 94, 97, 94, 81, 64, 52, 37, 11, -18, -37, -51, -69, -88, -98, -98, -96, -99, -95, -86, -75, -68, -61, -52, -44, -36, -30, -23, -21, -17, -13, -6, -7, -9, -6, 0, 0, -5, -5, 1, 4, -1, -3, 2, 8, 8, 5, 10, 17, 20, 21, 25, 33, 39, 45, 51, 60, 66, 75, 85, 91, 93, 94, 98, 95, 83, 67, 55, 40, 15, -14, -33, -48, -66, -85, -96, -96, -95, -98, -95, -86, -75, -69, -62, -53, -45, -38, -32, -25, -22, -19, -14, -8, -9, -10, -8, -2, -1, -6, -7, -1, 2, -2, -4, 1, 7, 6, 5, 8, 16, 19, 20, 24, 32, 38, 44, 50, 59, 66, 74, 84, 91, 93, 95, 99, 97, 85, 70, 58, 43, 18, -10, -30, -45, -63, -82, -93, -95, -94, -97, -95, -87, -76, -70, -63, -54, -46, -39, -33, -26, -23, -20, -16, -10, -10, -12, -9, -3, -3, -7, -8, -2, 1, -2, -5, 0, 6, 6, 4, 8, 15, 18, 20, 23, 31, 37, 43, 50, 58, 65, 74, 83, 91, 93, 96, 100, 98, 87, 72, 61, 46, 22, -6, -27, -42, -60, -79, -91, -94, -93, -97, -95, -87, -77, -70, -64, -55, -47, -40, -34, -28, -25, -22, -17, -12, -11, -13, -11, -5, -4, -8, -9, -3, 0, -4, -6, -1, 5, 5, 3, 7, 14, 18, 19, 23, 30, 36, 42, 49, 57, 65, 73, 83, 90, 94, 96, 100, 99, 89, 75, 63, 49, 25, -2, -23, -38, -56, -76, -88, -92, -92, -95, -94, -87, -77, -71, -65, -57, -48, -41, -36, -29, -26, -23, -19, -13, -12, -14, -12, -7, -6, -9, -10, -5, -1, -4, -7, -2, 2, 5, 4, 6, 12, 18, 20, 24, 30, 38, 45, 52, 61, 70, 79, 89, 99, 106, 109, 113, 115, 109, 96, 81, 66, 44, 16, -12, -32, -52, -74, -92, -101, -104, -107, -108, -103, -94, -85, -78, -70, -60, -52, -45, -38, -33, -29, -25, -19, -16, -17, -16, -12, -9, -10, -12, -9, -5, -5, -7, -5, 0, 3, 3, 5, 11, 17, 20, 23, 29, 37, 44, 51, 59, 69, 78, 88, 98, 105, 110, 114, 116, 110, 98, 84, 69, 48, 20, -7, -29, -49, -71, -89, -99, -102, -105, -107, -103, -94, -86, -79, -71, -62, -54, -47, -40, -34, -30, -26, -21, -18, -18, -17, -14, -10, -12, -14, -11, -5, -10, 43, -94, 44, -13, 27, -98, 1, 9, 77, 63, 4, 8, -128, 63, -73, 78, -116, 127, -14, 111, -87, -67, -43, -45, 38, 53, 99, -37, 14, -51, -58, -23, -32, 34, 27, 75, 9, 51, -104, -71, -33, 27, 67, 0, -1, 25, 0, -35, 1, -70, 28, -4, 109, 3, 5, -42, -7, 42, -15, 37, -62, 67, -14, 48, -85, -46, -94, 37, 35, 23, 15, -79, 35, -50, 91, -64, 40, -69, 46, 20, 43, -21, -51, 8, -1, 95, -47, 69, -104, 98, -44, 74, -61, -14, -19, 7, 52, -40, 8, -89, 58, -53, 106, -106, 42, -82, 61, -1, -8, -10, -59, 53, -18, 85, -83, 63, -73, 89, -32, 50, -62, 10, 13, 20, 62, -81, 41, -84, 88, -32, 41, -78, 27, -30, 51, -6, -42, 6, -49, 74, -41, 41, -89, 27, -33, 57, 0, -16, -8, -4, 45, 8, 20, -63, 36, -29, 75, -23, -17, -23, -14, 45, -7, 17, -56, 20, -12, 45, -16, -13, -31, 6, 31, -7, 17, -81, 40, -35, 73, -34, 0, -31, 10, 35, -4, 19, -60, 44, -30, 83, -66, 41, -87, 59, -6, 23, -4, -59, 34, -33, 77, -70, 49, -89, 88, -45, 63, -62, 4, -20, 18, 46, -49, 45, -101, 91, -56, 78, -79, 35, -51, 67, -12, -2, -14, -49, 66, -35, 72, -87, 51, -74, 83, -38, 29, -36, -10, 23, 3, 30, -59, 27, -59, 91, -44, 41, -63, 12, 2, 23, 8, -36, 14, -35, 66, -38, 32, -59, 25, -11, 40, -6, -25, -2, -24, 55, -25, 29, -58, 30, -17, 41, -18, -17, -3, -13, 50, -25, 26, -63, 35, -23, 50, -22, -5, -18, 0, 33, -19, 22, -67, 57, -39, 63, -45, 6, -27, 13, 23, -6, 15, -55, 44, -42, 70, -59, 36, -60, 56, -13, 15, -9, -50, 49, -38, 72, -63, 37, -65, 67, -48, 55, -51, 10, 2, -5, 45, -61, 46, -83, 91, -58, 72, -69, 23, -27, 35, -8, -3, -2, -33, 66, -61, 79, -100, 67, -60, 66, -26, 13, -21, -13, 23, -11, 29, -49, 40, -53, 80, -67, 52, -63, 28, 6, -1, 23, -45, 25, -30, 42, -25, 22, -42, 33, -26, 39, -26, -9, 10, -28, 61, -50, 33, -43, 18, 2, 6, 4, -18, 4, -8, 24, -21, 22, -49, 50, -40, 52, -35, -10, 17, -34, 64, -53, 38, -47, 37, -28, 40, -47, 33, -32, 28, 3, -20, 30, -69, 79, -75, 88, -72, 39, -34, 22, -7, 9, -18, 1, 19, -27, 58, -89, 81, -90, 89, -58, 42, -27, -5, 16, -21, 29, -34, 28, -37, 59, -65, 72, -90, 69, -45, 31, 6, -36, 40, -53, 56, -47, 39, -42, 40, -38, 50, -52, 34, -31, 7, 32, -47, 62, -79, 66, -51, 41, -27, 12, -10, 12, -5, 3, -5, -18, 33, -44, 70, -75, 60, -52, 27, 4, -19, 22, -29, 27, -15, 18, -31, 26, -36, 50, -41, 35, -31, 3, 19, -37, 55, -62, 51, -38, 25, -11, 1, -13, 12, -7, 13, 4, -33, 38, -56, 72, -64, 52, -43, 20, 6, -20, 25, -40, 34, -25, 38, -41, 43, -68, 68, -59, 53, -28, -7, 27, -45, 63, -70, 56, -60, 59, -41, 48, -56, 39, -43, 35, -3, -19, 40, -70, 85, -81, 76, -75, 48, -36, 41, -20, 12, -23, 0, 16, -23, 51, -76, 78, -82, 80, -57, 29, -23, 3, 14, -2, 9, -29, 17, -31, 55, -51, 53, -66, 49, -27, 17, 3, -35, 36, -33, 44, -27, 11, -30, 24, -18, 37, -29, 4, -3, -15, 45, -47, 42, -57, 46, -19, 18, -11, -20, 10, -3, 24, -18, 14, -46, 52, -50, 64, -57, 25, -14, 1, 33, -42, 30, -52, 50, -28, 47, -54, 32, -49, 53, -25, 14, -4, -34, 57, -54, 69, -78, 46, -45, 52, -21, 21, -37, 7, 1, 3, 29, -57, 56, -74, 90, -66, 47, -51, 16, 6, 10, 10, -29, 9, -32, 58, -47, 59, -84, 65, -49, 52, -24, -18, 14, -30, 61, -39, 31, -57, 39, -38, 67, -56, 37, -46, 26, 10, -15, 18, -49, 45, -27, 42, -37, 11, -24, 30, -15, 21, -34, 15, -5, 11, 5, -24, 11, -16, 30, -16, 6, -20, 7, 3, 11, -9, -5, -6, 4, 16, -15, 9, -29, 22, -6, 14, -6, -16, 9, -12, 28, -22, 15, -27, 22, -11, 21, -23, 5, -10, 8, 17, -22, 19, -42, 41, -31, 39, -37, 20, -20, 19, -3, -7, 2, -17, 27, -20, 30, -43, 30, -34, 38, -24, 13, -13, -1, 16, -16, 19, -36, 28, -21, 30, -22, 7, -17, 11, 2, 1, 1, -19, 22, -21, 32, -34, 18, -21, 17, 6, -8, 5, -25, 21, -13, 24, -24, 12, -22, 24, -11, 10, -14, -7, 15, -11, 28, -36, 21, -30, 30, -10, 10, -13, -5, 6, -2, 14, -22, 15, -25, 33, -22, 23, -31, 11, -6, 8, 11, -21, 14, -28, 32, -23, 25, -31, 19, -15, 19, -7, -7, 1, -13, 26, -19, 24, -37, 25, -24, 30, -18, 6, -9, -2, 17, -16, 17, -34, 27, -19, 28, -21, 6, -15, 10, 4, 0, 2, -20, 22, -19, -21, 0, -3, -3, 2, 1, -1, 2, -2, -1, 4, 3, -3, -15, -21, -20, -23, -42, -45, -31, -27, -17, -8, 9, 29, 41, 44, 33, 20, 13, 6, 12, 16, 25, 43, 44, 33, 33, 35, 15, -5, -3, 8, 16, 8, -10, -6, 8, 4, -4, 1, -18, -38, -43, -51, -54, -55, -71, -85, -68, -58, -61, -50, -33, -27, -15, -5, 22, 67, 100, 109, 114, 110, 91, 69, 50, 37, 35, 46, 48, 37, 36, 14, -24, -38, -42, -38, -38, -59, -91, -86, -57, -44, -32, -15, -26, -44, -30, -30, -30, -16, -31, -50, -34, -43, -59, -49, -44, -52, -62, -69, -50, -4, 47, 83, 105, 120, 111, 88, 72, 55, 57, 76, 69, 59, 55, 41, 10, -18, -32, -28, -19, -36, -68, -76, -72, -71, -46, -35, -47, -43, -43, -61, -48, -28, -25, -22, -19, -23, -15, -7, 3, 4, -8, -28, -37, -5, 42, 72, 107, 127, 122, 117, 90, 48, 37, 48, 51, 54, 56, 43, 24, -8, -37, -33, -11, -28, -55, -61, -75, -75, -51, -58, -55, -33, -33, -41, -35, -30, -21, -16, -17, -24, -26, -20, -18, -17, -12, -36, -72, -65, -45, -6, 53, 88, 106, 119, 107, 71, 52, 50, 59, 75, 87, 85, 76, 43, -1, -7, 9, -1, -13, -34, -69, -80, -74, -80, -73, -65, -67, -65, -56, -44, -33, -23, -18, -24, -25, -16, -20, -9, -1, -21, -38, -55, -64, -40, 3, 39, 82, 113, 114, 95, 71, 54, 56, 68, 76, 87, 94, 57, 10, -9, -17, -17, -15, -35, -60, -75, -89, -92, -85, -76, -71, -74, -70, -53, -41, -20, -9, -9, 4, 4, 10, 33, 38, 25, 15, -17, -43, -33, -15, 3, 40, 77, 94, 91, 69, 37, 31, 33, 37, 68, 96, 82, 53, 25, 8, 22, 28, 9, -9, -27, -46, -56, -65, -62, -61, -60, -51, -51, -39, -25, -23, -11, -3, -15, -10, 5, 12, 20, 18, -11, -41, -52, -47, -34, -2, 33, 65, 82, 70, 51, 45, 28, 21, 49, 74, 86, 74, 33, 5, 10, 14, 7, -10, -28, -45, -67, -68, -73, -76, -66, -66, -65, -46, -39, -31, -9, -3, -6, 1, 8, 22, 41, 49, 33, 8, -16, -34, -30, -17, 7, 49, 73, 64, 63, 50, 19, 5, 13, 32, 62, 65, 37, 8, -5, 4, -1, -8, -15, -36, -50, -57, -71, -65, -53, -58, -49, -37, -40, -28, -10, -3, 0, 2, -2, 5, 30, 41, 36, 22, -7, -33, -39, -46, -30, 15, 44, 56, 72, 65, 44, 21, 2, 15, 42, 59, 49, 18, 2, -3, -4, 0, -10, -25, -34, -52, -65, -59, -56, -50, -37, -33, -33, -25, -12, -2, 10, 12, 3, 6, 27, 42, 52, 43, 16, -3, -24, -48, -41, -11, 16, 48, 67, 78, 75, 49, 21, 13, 36, 64, 63, 47, 25, -1, -2, 2, -12, -18, -28, -53, -65, -71, -76, -70, -55, -53, -49, -41, -35, -24, -1, 5, 1, 4, 8, 28, 51, 43, 26, 18, -14, -42, -51, -49, -23, 5, 31, 55, 67, 58, 26, -2, 11, 35, 49, 55, 35, 8, 3, -2, -5, -6, -13, -30, -38, -49, -61, -56, -45, -43, -36, -31, -37, -25, -7, 1, 6, 1, -10, 11, 33, 29, 27, 17, -6, -34, -58, -67, -57, -34, -4, 21, 50, 63, 37, 11, 8, 17, 45, 63, 55, 39, 26, 12, 11, 10, -1, -11, -19, -35, -51, -52, -52, -45, -35, -36, -41, -31, -24, -9, 9, -3, -12, 2, 19, 33, 40, 37, 25, -3, -30, -51, -59, -42, -24, -3, 38, 58, 51, 32, 8, 2, 25, 45, 50, 49, 35, 18, 16, 19, 10, 9, 4, -13, -27, -36, -45, -36, -24, -32, -29, -31, -33, -10, 6, 1, -4, -6, 4, 19, 30, 37, 30, 12, -13, -48, -59, -57, -56, -35, 2, 31, 48, 41, 12, -2, 7, 25, 41, 52, 44, 29, 25, 22, 18, 20, 15, 1, -6, -26, -38, -28, -26, -21, -17, -31, -33, -19, -4, 0, -8, -16, -15, -11, 9, 19, 22, 24, -2, -34, -49, -61, -70, -57, -32, 4, 38, 46, 26, 5, -1, 7, 29, 45, 44, 38, 32, 23, 27, 30, 23, 24, 14, -8, -16, -24, -24, -12, -10, -19, -27, -26, -9, -2, -4, -6, -16, -14, -2, 8, 23, 34, 17, -6, -26, -47, -61, -62, -50, -18, 26, 50, 48, 31, 12, 6, 24, 40, 44, 51, 40, 29, 34, 28, 27, 32, 20, 7, -5, -23, -26, -19, -9, -12, -25, -25, -17, -8, 1, -4, -13, -12, -16, -9, 13, 26, 23, 8, -13, -37, -55, -71, -78, -59, -18, 16, 35, 34, 8, -3, 4, 13, 31, 40, 34, 34, 29, 23, 30, 31, 27, 21, 7, -6, -21, -21, -10, -10, -19, -24, -28, -17, -6, -8, -9, -9, -19, -21, -5, 12, 23, 22, 5, -16, -34, -55, -80, -78, -56, -22, 18, 33, 24, 14, 3, 7, 25, 31, 37, 41, 33, 29, 29, 32, 33, 30, 24, 7, -16, -22, -18, -15, -14, -24, -31, -22, -13, -12, -8, -6, -18, -27, -22, -6, -5, -1, -1, -1, 1, 2, 7, 13, 19, 10, -12, -31, -13, 17, 29, -4, -29, 24, 53, 18, 92, 15, -15, 23, 13, -35, -52, 127, 9, 3, -9, 31, -63, -64, -5, -50, 14, 33, -29, -42, 0, 43, 39, -15, -59, -45, 3, 33, 12, -35, -10, 51, 18, 49, 55, -28, 16, 4, 3, -64, 54, 53, -12, 0, 5, -4, -72, -7, -31, -14, 26, -2, -37, -14, 17, 35, 4, -33, -45, -12, 15, 21, -16, -23, 22, 28, 12, 55, -7, -2, 7, 7, -34, -10, 65, -4, 1, -5, 14, -46, -28, -9, -29, 13, 13, -23, -23, 4, 27, 18, -17, -39, -25, 5, 20, 0, -26, 1, 34, 7, 41, 24, -20, 11, 1, -6, -45, 53, 22, -6, -4, 9, -17, -52, -4, -30, -6, 20, -9, -29, -8, 18, 27, -2, -33, -36, -6, 16, 13, -20, -16, 27, 19, 18, 49, -17, 3, 2, 6, -42, 9, 55, -9, 1, -3, 9, -54, -19, -16, -24, 16, 7, -27, -19, 8, 28, 12, -22, -40, -20, 8, 19, -7, -25, 9, 31, 7, 48, 9, -14, 9, 2, -17, -35, 62, 9, -2, -6, 13, -30, -44, -4, -31, 2, 18, -15, -27, -3, 22, 24, -8, -36, -32, -2, 17, 8, -23, -9, 31, 13, 28, 40, -21, 8, 1, 3, -47, 29, 43, -9, 0, 1, 1, -57, -11, -22, -17, 19, 2, -28, -14, 12, 29, 7, -27, -39, -14, 11, 17, -13, -22, 17, 27, 10, 51, -4, -7, 7, 5, -27, -19, 64, -1, 1, -6, 14, -41, -34, -8, -30, 8, 15, -20, -24, 2, 25, 20, -14, -38, -27, 2, 18, 2, -25, -1, 33, 9, 37, 29, -21, 11, 0, -3, -46, 46, 29, -7, -2, 7, -9, -54, -6, -27, -10, 20, -4, -28, -9, 16, 28, 1, -30, -37, -8, 14, 14, -18, -17, 25, 22, 16, 50, -13, 1, 4, 5, -37, 0, 59, -7, 2, -4, 12, -49, -24, -13, -26, 13, 11, -23, -19, 6, 27, 15, -19, -39, -21, 6, 18, -4, -24, 7, 32, 8, 45, 15, -16, 10, 2, -12, -39, 58, 16, -3, -5, 11, -22, -48, -4, -30, -2, 19, -10, -26, -4, 20, 25, -5, -34, -33, -4, 16, 10, -21, -11, 30, 16, 25, 43, -19, 7, 1, 4, -44, 20, 49, -8, 1, -1, 6, -54, -15, -19, -20, 17, 6, -26, -15, 10, 29, 9, -23, -39, -16, 9, 17, -10, -22, 15, 29, 10, 50, 2, -10, 8, 3, -22, -26, 63, 5, 0, -6, 14, -34, -39, -6, -30, 4, 17, -15, -24, 0, 24, 22, -11, -36, -28, 1, 17, 5, -23, -3, 32, 12, 34, 33, -21, 10, 0, 0, -46, 39, 36, -7, -1, 4, -3, -54, -9, -24, -14, 19, 0, -26, -10, 14, 28, 4, -27, -37, -11, 12, 15, -15, -18, 22, 24, 14, 50, -9, -2, 5, 5, -32, -8, 61, -3, 2, -5, 14, -44, -29, -10, -27, 10, 13, -20, -20, 4, 26, 17, -16, -37, -23, 4, 18, -1, -23, 5, 32, 9, 42, 20, -18, 11, 1, -7, -41, 53, 22, -4, -3, 9, -14, -50, -6, -27, -7, 19, -6, -26, -5, 18, 26, -2, -31, -34, -6, 14, 11, -19, -12, 28, 19, 22, 45, -17, 4, 2, 5, -40, 11, 54, -6, 2, -3, 10, -51, -20, -16, -23, 14, 9, -23, -15, 8, 28, 12, -20, -38, -18, 7, 17, -7, -22, 13, 30, 10, 47, 7, -12, 9, 2, -17, -31, 61, 10, 0, -5, 13, -26, -43, -6, -29, 0, 18, -11, -23, -1, 22, 23, -8, -34, -30, -1, 15, 7, -22, -5, 31, 14, 30, 37, -20, 9, 0, 2, -44, 30, 42, -7, 1, 2, 2, -53, -12, -21, -17, 17, 4, -25, -11, 12, 28, 6, -25, -37, -13, 10, 15, -13, -18, 20, 26, 13, 49, -5, -5, 6, 4, -27, -16, 62, 1, 2, -5, 14, -38, -34, -9, -28, 6, 15, -16, -20, 3, 25, 19, -13, -36, -25, 2, 16, 1, -23, 3, 32, 11, 38, 25, -19, 11, 0, -4, -43, 46, 29, -4, -2, 7, -8, -51, -8, -25, -10, 18, -2, -25, -7, 16, 27, 0, -28, -35, -8, 12, 12, -17, -13, 26, 21, 19, 46, -14, 2, 3, 4, -36, 2, 57, -4, 3, -4, 12, -46, -25, -13, -25, 11, 12, -20, -16, 7, 27, 14, -18, -37, -20, 5, 16, -5, -21, 10, 31, 10, 45, 12, -14, 10, 1, -12, -36, 57, 16, -1, -4, 11, -20, -46, -6, -28, -4, 18, -8, -23, -3, 20, 24, -5, -32, -31, -4, 13, 8, -20, -6, 29, 17, 27, 39, -19, 7, 0, 3, -42, 21, 47, -6, 2, 0, 7, -51, -17, -18, -20, 15, 7, -23, -12, 10, 28, 8, -22, -37, -15, 8, 15, -10, -19, 18, 27, 13, 47, 0, -8, 8, 3, -24, -20, 52, -36, -2, 0, -2, 3, 5, -4, -28, 22, -43, 36, -13, -127, -43, 2, -18, 126, 78, -127, -48, 68, -74, -67, 33, 62, 83, 42, -32, -46, -70, -26, 115, 21, -66, 72, 52, -27, 44, 50, 50, 61, 28, -12, 3, -59, 49, 3, -19, 39, 94, 16, 31, 6, 29, 3, -100, -1, -4, -60, 19, 7, -29, -28, -38, -3, -47, -20, -21, -1, 5, -55, -12, -55, -39, 26, 47, -22, -9, -41, -21, -19, -37, 0, 45, -56, 24, 75, -50, -9, 31, 28, 26, 13, -3, -15, -27, 1, 1, -31, -10, 38, -1, 7, 43, 19, 21, 41, 33, 9, -17, -3, -42, -76, -30, -8, -9, -1, 21, 22, 38, 32, 22, 0, -18, -32, -58, -12, 5, -48, -13, 64, 29, -2, 2, 19, 43, 25, -19, -39, -69, -92, -15, 23, 30, 30, 51, 37, 35, 37, 30, -27, -63, 5, -30, -56, -16, 26, 52, 20, 14, 59, 27, -9, 22, -4, -20, -37, -17, -34, -34, -1, 35, 26, 31, 5, -16, 4, 33, 22, 8, 5, -28, -41, -20, -10, -6, -2, -16, 12, 31, -23, 7, -2, -39, -28, -13, 8, 5, 16, -4, -6, -18, -24, -27, -50, -6, 5, 12, 0, -2, -14, -23, 5, -28, -10, 2, 28, 15, 2, 22, 27, 41, 31, 2, 12, 31, 5, 12, -6, 15, 40, 34, 18, 26, 26, 12, 34, 23, 34, 30, 22, 10, -26, -22, 1, 0, -1, 12, -4, -21, -5, -5, -20, -31, -25, -24, -42, -44, -41, -41, -37, -29, -28, -29, -40, -17, -21, -38, -42, -38, -40, -36, -13, -14, -8, -15, -7, -6, 5, 12, -1, -17, -1, 9, 2, 16, 30, 27, 37, 36, 38, 36, 36, 19, 45, 45, 33, 26, 33, 28, 36, 31, 17, 12, 22, 11, 11, 17, 5, -13, 6, 10, 2, -6, 2, 9, 15, -6, -8, -23, -44, -3, -11, -35, -25, -35, -23, -21, 0, -11, -21, -17, 11, -6, -11, -17, -33, -16, -16, -4, -7, -7, -9, -4, 1, 1, -3, 6, 7, 4, -17, -11, -6, -4, 1, 3, 6, 4, 5, -4, 17, 7, 3, 9, -20, 0, -7, -3, -5, 4, 9, 16, 2, 3, 8, 15, 15, 1, -3, 8, -1, 5, 14, 7, 4, 8, -8, 2, -3, 5, 11, 5, 3, -4, 10, 17, 13, -11, -5, 1, -3, 0, -6, -12, 2, -3, 13, -5, -25, -15, -7, 4, 1, -8, -4, -12, -16, 3, 9, -6, 3, -21, -4, 4, -14, 1, -1, -2, 3, -8, -5, 0, 7, -2, -3, -1, 3, -9, 5, -4, -17, -1, 9, 3, 7, 1, -4, -3, 5, 2, -7, -9, 12, -6, -14, -16, 2, -1, 16, 2, 2, 7, -6, -26, 3, -2, -4, -2, 10, 3, -7, 3, 8, 9, 5, 4, 1, -5, -5, 11, 8, 7, 11, 12, -1, -5, -16, 13, 7, 2, 11, 4, -4, 9, -8, -8, 14, 11, -8, 0, -1, -5, -2, -1, -10, -5, -9, -9, -16, -12, -8, -16, 5, -10, -4, -11, -3, 1, 0, -3, -5, -13, -9, -2, -8, 5, -9, -7, -2, 2, -11, -7, 13, 8, -3, 2, 7, -2, -1, 5, 0, 11, 6, 13, 15, 1, -4, 9, 5, 3, 8, -3, -4, 16, 4, 11, 9, 0, 8, 1, -6, -5, -18, 3, 7, -18, -4, 0, -3, -3, -6, -4, -5, -5, -10, -2, -9, -5, -2, -4, -11, -2, 1, -5, -2, 11, -6, -9, 1, 4, -6, -1, -5, 1, 2, 9, 5, 0, 4, 4, -2, 7, 0, -10, 5, 2, -3, 0, -6, 7, -4, -3, 6, -1, -6, -1, -1, 2, -2, -6, -3, 0, 8, -6, 4, -1, -5, -3, 3, 1, -5, -6, -2, -3, 5, 6, 0, 7, -3, 3, -1, 0, -2, 9, 1, 1, -3, 4, 5, -5, 2, -2, 2, -11, -2, -4, 11, 4, 5, 0, -5, -12, -6, -5, -5, 3, -2, -2, 2, 2, 1, 0, -1, -8, -5, -5, -3, 2, -1, 3, -1, 3, 0, -1, 0, -1, 1, 1, -4, -4, 2, -2, 1, -6, 1, 2, 4, 2, 2, -5, -1, 6, -3, -1, -4, 11, 3, -9, -2, -6, -3, 2, 4, 2, 1, 2, 4, 3, -6, -4, -3, -2, 0, 2, -2, 5, 2, -1, 3, -9, -3, -3, -4, -4, -1, 0, -2, 7, 3, 1, 1, -2, -4, -2, -3, -2, -4, 2, 4, -1, 2, 3, 0, 3, -1, 0, -2, -2, -3, 1, -1, -4, 5, -1, 5, 0, -3, -2, -1, -4, 3, -1, -3, -2, -2, -1, 0, 0, 1, -1, 0, -2, -2, 0, -3, -1, 0, 0, 1, 1, -2, -1, 1, -3, 1, 2, 0, -1, 0, -1, 1, 5, -2, 1, -3, -3, -1, -3, 0, 1, 3, 2, -1, -1, -2, -2, -1, 1, 0, -1, -2, -2, -2, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -1, 0, 1, 1, -2, -2, 0, 0, 2, -3, -16, -22, -20, -28, -35, -31, -17, 19, 33, 36, 33, 34, 40, 36, 25, 18, 20, 18, 14, 17, 12, 14, 10, -24, -36, -27, -38, -55, -69, -66, -47, -33, -13, 3, 5, 10, 22, 25, 15, 28, 43, 41, 51, 56, 58, 58, 31, -18, -52, -64, -71, -92, -105, -98, -77, -50, -17, 23, 59, 85, 99, 94, 76, 55, 14, -9, -5, -7, -18, -17, -35, -53, -53, -33, -23, -33, -36, -15, 17, 32, 24, 12, 19, 37, 54, 49, 38, 21, -14, -44, -30, -22, -15, 5, 8, -1, -26, -42, -46, -49, -51, -37, -17, 1, -4, -19, -4, 45, 84, 91, 79, 57, 3, -30, -29, -35, -25, -8, -6, -26, -61, -75, -73, -77, -72, -54, -19, 9, 6, -10, 3, 47, 85, 92, 103, 92, 45, 21, 6, 4, 16, 27, 27, -1, -48, -69, -78, -80, -84, -72, -33, -10, -24, -41, -20, 40, 82, 99, 123, 102, 69, 49, 30, 27, 34, 42, 41, -2, -58, -96, -108, -103, -106, -83, -37, -10, -18, -38, -18, 40, 65, 92, 110, 84, 44, 1, -26, -23, -7, 21, 32, 7, -39, -78, -84, -79, -82, -61, -19, 5, -14, -52, -25, 25, 59, 102, 127, 116, 86, 40, 13, 4, 9, 27, 29, 4, -47, -88, -94, -87, -83, -56, -18, 15, -13, -49, -30, -2, 29, 69, 87, 80, 50, 9, -15, -27, -10, 18, 44, 36, -9, -45, -53, -53, -46, -33, 6, 31, -8, -36, -28, -11, 21, 54, 76, 76, 44, 4, -33, -53, -45, -18, 13, 10, -35, -62, -70, -61, -44, -19, 38, 63, 30, 9, 4, 9, 35, 60, 81, 75, 51, 14, -25, -44, -37, -9, 29, 24, -11, -41, -59, -51, -54, -33, 23, 35, 6, -13, -28, -18, 8, 43, 73, 76, 63, 33, -1, -21, -22, 10, 43, 35, 5, -32, -47, -51, -68, -44, 6, 14, 0, -21, -34, -25, 0, 37, 65, 73, 64, 35, 5, -22, -25, 11, 40, 39, 13, -20, -28, -42, -64, -32, 6, 15, -1, -25, -39, -39, -16, 19, 44, 58, 53, 27, -2, -39, -38, -2, 30, 40, 13, -16, -19, -45, -60, -29, 6, 17, 1, -21, -40, -44, -24, 9, 38, 58, 51, 38, 8, -31, -29, 0, 34, 44, 9, -11, -23, -58, -69, -42, -6, 9, 0, -16, -33, -36, -12, 19, 55, 72, 68, 58, 18, -22, -25, -6, 29, 31, 2, -5, -23, -57, -69, -45, -8, 12, 10, 0, -22, -24, -7, 20, 52, 61, 65, 59, 21, -15, -28, -11, 26, 20, 2, -2, -22, -56, -71, -49, -14, 3, 8, -5, -26, -28, -19, 14, 42, 54, 71, 67, 38, 8, -11, 16, 47, 37, 26, 18, -10, -51, -74, -59, -35, -19, -12, -24, -37, -44, -34, 0, 24, 44, 67, 64, 43, 3, -18, 11, 35, 28, 22, 18, -4, -47, -68, -55, -34, -11, -7, -15, -27, -43, -32, -1, 18, 42, 58, 60, 43, -8, -29, -6, 11, 7, 4, 4, -17, -59, -75, -66, -41, -13, -3, 1, -11, -29, -19, 1, 19, 42, 53, 64, 45, -8, -28, -9, 7, 4, 4, 9, -13, -51, -71, -69, -43, -19, -7, 3, -11, -25, -17, -2, 23, 43, 60, 78, 55, 1, -19, -5, 8, 3, 7, 13, -8, -41, -66, -67, -40, -19, 3, 16, 1, -7, -5, 10, 34, 46, 67, 87, 62, 11, -13, -1, 8, 4, 15, 20, 1, -33, -64, -65, -48, -30, -2, 6, -5, -14, -18, 1, 21, 32, 62, 86, 66, 20, -3, 6, 7, 5, 16, 20, 7, -29, -62, -65, -59, -39, -13, -5, -8, -22, -27, -6, 7, 17, 49, 74, 58, 14, -5, -2, -4, -3, 7, 14, 6, -32, -59, -66, -63, -40, -16, -2, -2, -19, -20, -1, 6, 18, 49, 77, 62, 21, 3, -1, -5, -2, 5, 18, 10, -26, -50, -65, -64, -43, -24, -5, -6, -24, -23, -8, -2, 10, 45, 75, 60, 25, 6, -4, -4, -5, 3, 20, 8, -20, -43, -60, -58, -45, -24, 1, -1, -15, -12, -1, 3, 16, 53, 83, 70, 42, 19, 9, 7, 3, 16, 29, 17, -7, -35, -55, -56, -49, -24, 2, -1, -11, -7, 3, 4, 16, 55, 83, 75, 50, 25, 15, 6, 0, 13, 21, 13, -9, -40, -58, -66, -62, -35, -11, -11, -18, -13, -3, -7, 9, 49, 75, 74, 51, 28, 19, 5, 1, 13, 20, 16, -3, -28, -48, -62, -61, -37, -16, -13, -20, -15, -12, -19, -5, 21, 50, 61, 47, 28, 15, -1, -6, 0, 9, 14, 1, -19, -37, -55, -56, -38, -16, -11, -13, -9, -9, -16, -8, 18, 48, 59, 44, 28, 9, 15, -3, 2, -5, 3, 3, 4, 1, 7, -2, 7, -4, 2, -124, -37, 33, -48, 7, -27, 8, -14, 77, 26, -9, 26, 7, 20, 10, 13, 8, 9, 7, 4, 5, 2, 3, 2, 1, -1, 0, -3, -2, -5, 1, -10, 11, 70, -6, 21, 5, 27, -2, 41, -15, -61, -66, -128, 0, -48, -21, -46, -6, -55, 23, 53, -6, 11, 2, 14, 11, 10, 11, 8, 9, 9, 8, 5, 8, 5, 6, 5, 6, 2, 7, -4, 6, 5, -23, 62, 29, 24, 8, 33, 4, 32, 36, -30, -16, -124, -58, -39, -18, -51, -3, -43, -40, 53, 19, 12, 4, 9, 12, 13, 10, 11, 9, 8, 11, 6, 5, 8, 6, 3, 9, 1, 7, 2, -5, 22, -33, 20, 37, 35, 7, 29, 14, 8, 52, -5, 17, -64, -84, -70, -15, -55, -23, -12, -72, 1, 28, 16, 8, 6, 7, 12, 10, 8, 11, 6, 8, 10, 5, 4, 10, 1, 8, 4, 2, 10, -15, 26, -16, -9, 14, 42, 17, 19, 29, -3, 42, 14, 28, -8, -45, -92, -37, -41, -54, 0, -53, -48, 2, 18, 10, 8, 4, 8, 12, 8, 10, 10, 6, 9, 10, 2, 10, 5, 3, 9, -2, 18, -16, 17, 3, -9, -12, 26, 28, 13, 35, 3, 27, 19, 31, 17, 4, -60, -67, -33, -66, -22, -22, -58, -38, 2, 11, 9, 7, 4, 9, 10, 8, 10, 9, 5, 12, 5, 5, 9, 2, 11, -5, 21, -8, 4, 10, 5, -17, -1, 28, 11, 34, 13, 20, 17, 28, 24, 27, -6, -61, -41, -57, -51, -17, -36, -56, -32, -1, 7, 8, 5, 6, 8, 10, 8, 12, 6, 9, 9, 5, 9, 1, 15, -7, 15, 5, -2, 4, 14, -3, -18, 15, 8, 28, 21, 20, 16, 23, 23, 29, 30, -20, -38, -45, -63, -38, -23, -43, -53, -29, -5, 5, 5, 5, 5, 9, 7, 11, 8, 8, 10, 5, 12, -2, 16, -1, 4, 11, 4, -3, 8, 15, -16, 0, 1, 16, 23, 23, 17, 20, 21, 21, 39, 19, -14, -28, -52, -58, -33, -28, -47, -50, -30, -6, 2, 5, 4, 6, 6, 9, 10, 7, 12, 3, 15, 0, 10, 8, 1, 6, 11, 2, -4, 20, -1, -6, -5, 4, 15, 24, 20, 18, 23, 15, 30, 38, 13, -6, -27, -56, -52, -30, -34, -48, -50, -28, -8, 2, 3, 5, 5, 6, 11, 5, 13, 3, 12, 6, 5, 10, 5, 2, 7, 13, -8, 10, 11, 0, -6, -4, 3, 17, 23, 16, 24, 18, 17, 36, 32, 13, -1, -30, -57, -45, -31, -36, -51, -49, -28, -7, -1, 3, 6, 2, 11, 5, 12, 6, 9, 10, 5, 8, 8, 5, -1, 16, 1, -1, 11, 9, -1, -5, -5, 4, 20, 17, 20, 24, 14, 23, 37, 29, 16, 2, -33, -53, -42, -30, -39, -52, -49, -27, -9, -3, 5, 0, 8, 5, 10, 8, 6, 10, 6, 7, 6, 11, -3, 8, 11, 0, 2, 11, 8, -1, -5, -7, 9, 18, 16, 24, 20, 14, 27, 35, 27, 21, 1, -33, -50, -38, -32, -42, -53, -48, -25, -14, -1, -2, 4, 3, 6, 9, 5, 9, 7, 7, 4, 12, 4, 1, 10, 6, 2, 6, 10, 4, 0, -6, -2, 11, 14, 18, 22, 17, 20, 32, 34, 28, 20, 0, -26, -36, -34, -37, -45, -54, -44, -30, -13, -8, -3, 1, 2, 6, 4, 7, 8, 8, 2, 8, 10, 1, 4, 6, 5, 5, 9, 6, 1, -3, -5, 3, 10, 14, 18, 18, 17, 26, 35, 35, 29, 17, -1, -17, -24, -32, -41, -50, -51, -44, -28, -18, -12, -5, -2, 2, 3, 3, 6, 9, 4, 3, 9, 6, 2, 2, 4, 5, 9, 10, 4, -2, -5, -1, 5, 10, 14, 16, 15, 19, 30, 38, 37, 29, 15, 1, -5, -14, -31, -43, -50, -52, -42, -29, -22, -16, -9, -3, 0, 0, 2, 6, 6, 2, 4, 7, 6, 2, 1, 2, 6, 11, 10, 2, -5, -4, 0, 5, 10, 14, 15, 14, 21, 32, 39, 38, 29, 14, 4, 0, -3, -19, -32, -40, -43, -41, -36, -31, -25, -19, -12, -9, -8, -6, -1, 2, 2, 0, -3, -4, -1, 3, 6, 6, 2, -3, -6, -2, 2, 2, 1, 2, 7, 16, 25, 32, 35, 35, 36, 36, 33, 24, 11, -3, -18, -32, -40, -42, -40, -36, -30, -25, -18, -12, -9, -8, -5, -1, 2, 2, 0, -3, -4, -1, 3, 7, 6, 2, -4, -5, -2, 2, 2, 1, 2, 8, 17, 25, 32, 35, 36, 36, 36, 32, 23, 10, -4, -20, -33, -41, -42, -40, -35, -30, -24, -18, -12, -9, -8, -5, -1, 3, 2, -1, -4, -4, -1, 4, 7, 6, 1, -4, -5, -2, -1, 3, 1, 3, 5, 3, -3, -1, -1, 1, -15, 1, 1, -5, -7, 7, -2, -4, 3, -2, -5, -1, -3, -3, -1, 6, 3, 2, 3, -26, -117, 35, -8, -19, 24, 58, -7, -6, 25, -9, 7, 4, 10, 2, 7, 6, 6, 0, 6, -2, -1, -3, -3, 8, 71, 0, 17, 27, 20, -102, -115, 39, -32, -18, -5, 58, -15, -12, 13, -10, -4, 1, 2, 1, 0, 6, 2, 1, 2, 0, -4, 0, -5, 2, 67, 9, 14, 28, 29, -72, -126, 27, -25, -19, -14, 58, -6, -11, 13, -5, -3, 3, 3, 4, 1, 8, 3, 3, 3, 3, -2, 2, -3, -3, 62, 17, 14, 27, 35, -45, -128, 11, -19, -20, -22, 53, 1, -12, 11, -3, -4, 2, 3, 4, 1, 7, 3, 3, 3, 3, -2, 2, -2, -9, 57, 22, 14, 25, 37, -23, -125, -8, -15, -20, -30, 46, 9, -12, 10, -2, -3, 0, 3, 3, 1, 6, 4, 2, 3, 2, -2, 1, 0, -16, 50, 26, 13, 22, 37, -2, -117, -27, -13, -18, -36, 36, 16, -13, 9, -2, -2, -2, 3, 2, 2, 4, 5, 1, 4, 2, -1, 0, 4, -20, 43, 29, 15, 20, 36, 14, -102, -43, -15, -16, -40, 26, 22, -12, 8, -2, -2, -3, 3, 1, 3, 2, 6, 1, 5, 1, 0, -1, 7, -23, 35, 31, 18, 18, 33, 27, -83, -57, -20, -14, -42, 14, 26, -9, 7, -2, 0, -5, 3, 1, 4, 1, 7, 0, 5, 1, 1, -2, 10, -24, 26, 31, 20, 17, 30, 36, -62, -65, -27, -12, -43, 2, 28, -7, 6, -2, 0, -5, 3, 0, 4, 0, 7, 0, 5, 1, 2, -4, 11, -23, 17, 32, 22, 16, 27, 42, -44, -67, -36, -9, -42, -8, 28, -3, 5, -1, 1, -5, 2, 0, 4, 1, 7, 1, 5, 1, 3, -5, 13, -22, 10, 31, 23, 17, 22, 45, -25, -66, -45, -8, -40, -18, 27, 0, 5, -1, 1, -5, 1, 0, 4, 0, 6, 2, 4, 2, 3, -6, 14, -19, 2, 29, 25, 19, 19, 47, -10, -60, -54, -10, -37, -27, 24, 4, 4, 0, 1, -5, 0, 0, 3, 1, 5, 2, 4, 2, 4, -7, 15, -16, -4, 27, 25, 21, 15, 48, 4, -51, -61, -12, -33, -34, 19, 7, 4, 1, 0, -4, -1, 0, 3, 2, 5, 3, 3, 3, 5, -8, 15, -11, -10, 24, 25, 23, 12, 45, 15, -39, -66, -18, -28, -40, 12, 10, 4, 2, 1, -3, -2, 0, 2, 2, 4, 3, 3, 3, 5, -8, 13, -6, -14, 19, 25, 25, 10, 43, 24, -25, -67, -25, -24, -45, 4, 11, 5, 3, 0, -2, -3, -1, 1, 2, 3, 3, 3, 2, 6, -9, 11, -2, -17, 15, 24, 27, 9, 39, 31, -13, -66, -33, -19, -48, -3, 11, 5, 3, 1, -2, -3, -1, 1, 2, 4, 3, 3, 2, 8, -9, 9, 3, -18, 10, 22, 29, 9, 35, 35, 0, -61, -41, -17, -49, -11, 10, 6, 3, 2, -2, -3, -2, 1, 1, 4, 3, 5, 1, 9, -9, 7, 6, -18, 5, 20, 29, 10, 32, 38, 11, -47, -45, -18, -47, -20, 5, 6, 4, 2, -1, -3, -2, 0, 1, 5, 1, 6, 1, 7, -7, 6, 6, -16, 1, 16, 27, 11, 29, 40, 20, -30, -43, -23, -46, -28, -2, 4, 4, 2, -1, -3, -2, -1, 0, 6, -1, 7, 2, 5, -6, 5, 6, -15, -3, 13, 25, 12, 26, 41, 26, -14, -36, -26, -44, -35, -11, 1, 4, 2, 0, -4, -3, -3, -1, 7, -2, 7, 4, 4, -6, 4, 7, -13, -6, 10, 23, 12, 24, 42, 31, 0, -24, -28, -42, -40, -19, -4, 4, 2, 1, -4, -3, -4, -3, 8, -3, 6, 6, 3, -6, 4, 7, -11, -8, 7, 20, 12, 21, 41, 34, -2, -31, -34, -29, -21, -12, -3, -4, -10, -7, -5, -6, -4, 5, 8, -3, -1, 7, -1, -11, -7, 0, 1, 6, 16, 28, 33, 33, 30, 13, -1, -26, -35, -30, -24, -14, -5, -4, -11, -7, -5, -6, -6, 3, 8, -2, -2, 7, 1, -11, -9, -1, 0, 4, 14, 26, 32, 33, 32, 17, 3, -22, -34, -31, -25, -16, -6, -3, -10, -8, -5, -6, -7, 2, 9, 0, -3, 6, 3, -9, -10, -2, 0, 3, 12, 24, 32, -1, 0, -3, -1, -8, -5, -16, -5, -14, -4, -13, -5, -1, -7, 16, -17, 28, -16, 47, 1, 70, 35, 97, 71, 98, 66, 32, -5, -71, -69, -122, -69, -105, -33, -67, -6, -35, 2, -12, -2, 4, -12, 16, -19, 29, -16, 44, 2, 66, 37, 92, 76, 95, 74, 33, 5, -69, -63, -122, -69, -106, -36, -66, -11, -33, -3, -9, -7, 7, -16, 18, -22, 29, -17, 42, 3, 61, 40, 86, 81, 91, 82, 34, 15, -67, -57, -122, -69, -105, -40, -64, -17, -29, -9, -6, -12, 10, -20, 20, -23, 28, -17, 39, 4, 56, 42, 80, 85, 88, 89, 35, 24, -63, -53, -119, -70, -104, -45, -62, -22, -26, -14, -2, -16, 12, -23, 20, -25, 27, -16, 35, 7, 51, 45, 74, 89, 85, 96, 38, 32, -58, -49, -116, -72, -102, -50, -60, -27, -24, -19, 0, -20, 14, -24, 20, -24, 24, -14, 31, 10, 45, 48, 69, 92, 82, 102, 40, 39, -53, -45, -112, -74, -100, -55, -57, -33, -21, -24, 3, -24, 15, -26, 19, -24, 22, -12, 27, 12, 40, 50, 63, 95, 80, 106, 43, 45, -47, -42, -107, -76, -97, -60, -55, -38, -18, -28, 4, -26, 15, -27, 18, -23, 19, -10, 23, 15, 35, 53, 59, 97, 78, 110, 47, 50, -39, -39, -102, -79, -94, -65, -52, -43, -16, -32, 5, -28, 14, -27, 16, -21, 15, -7, 18, 18, 30, 55, 54, 98, 76, 113, 51, 55, -32, -37, -96, -81, -91, -70, -50, -48, -15, -35, 6, -30, 13, -26, 13, -19, 11, -5, 13, 20, 25, 56, 50, 99, 75, 115, 56, 59, -24, -35, -90, -83, -88, -75, -48, -52, -14, -38, 5, -30, 11, -25, 10, -17, 7, -2, 9, 22, 21, 57, 47, 99, 75, 116, 61, 62, -15, -33, -82, -86, -84, -80, -47, -56, -14, -39, 4, -30, 9, -24, 6, -15, 3, 1, 5, 24, 17, 57, 44, 98, 75, 116, 66, 65, -6, -31, -75, -88, -81, -83, -46, -59, -14, -41, 3, -30, 6, -22, 3, -12, -1, 3, 1, 26, 13, 57, 41, 96, 75, 115, 72, 68, 2, -29, -69, -89, -78, -87, -45, -62, -15, -42, 0, -29, 3, -20, -1, -10, -5, 5, -2, 26, 11, 56, 40, 94, 76, 114, 77, 69, 12, -28, -61, -91, -75, -89, -45, -64, -16, -42, -2, -28, 0, -18, -5, -8, -9, 7, -6, 27, 8, 55, 38, 91, 77, 112, 82, 71, 20, -25, -55, -91, -73, -91, -46, -65, -18, -42, -5, -26, -4, -15, -10, -5, -13, 9, -9, 27, 7, 53, 37, 88, 78, 110, 87, 72, 29, -23, -48, -90, -71, -93, -47, -66, -21, -41, -9, -24, -8, -13, -13, -3, -16, 9, -11, 27, 5, 51, 37, 84, 79, 108, 93, 74, 37, -20, -42, -90, -70, -94, -49, -66, -24, -40, -12, -23, -12, -12, -16, -2, -18, 10, -12, 25, 5, 48, 37, 80, 81, 105, 98, 75, 45, -16, -36, -88, -68, -94, -51, -66, -28, -39, -16, -21, -15, -10, -19, -1, -21, 10, -13, 24, 4, 45, 37, 76, 82, 102, 102, 76, 52, -13, -30, -85, -67, -94, -54, -66, -31, -38, -20, -19, -19, -9, -22, 0, -22, 9, -14, 22, 4, 41, 37, 71, 83, 99, 105, 77, 59, -8, -25, -82, -67, -93, -56, -65, -35, -37, -23, -18, -22, -7, -25, 0, -24, 8, -14, 20, 5, 37, 38, 67, 84, 96, 108, 79, 65, -3, -20, -79, -66, -92, -59, -65, -39, -36, -27, -17, -25, -7, -27, -1, -24, 6, -14, 17, 6, 34, 39, 63, 84, 93, 111, 80, 71, 1, -15, -75, -66, -90, -62, -64, -43, -35, -31, -16, -28, -6, -28, -1, -25, 5, -14, 14, 6, 30, 39, 58, 85, 90, 113, 82, 76, 7, -11, -70, -66, -88, -66, -62, -46, -34, -34, -15, -30, -7, -30, -2, -25, 2, -13, 11, 7, 26, 40, 53, 84, 87, 115, 84, 81, 13, -7, -65, -66, -85, -68, -61, -50, -33, -37, -15, -32, -7, -30, -4, -25, 0, -12, 7, 9, 19, 37, 52, 80, 97, 118, 113, 98, 54, 7, -41, -72, -87, -87, -75, -65, -47, -42, -29, -30, -22, -24, -19, -19, -14, -9, -2, 8, 17, 36, 50, 77, 95, 117, 115, 101, 60, 13, -35, -69, -85, -88, -75, -66, -49, -44, -31, -31, -23, -25, -20, -20, -15, -9, -2, -1, 0, 0, 0, 0, -1, -1, -1, 3, 9, 14, 14, 10, -3, -17, -13, 1, 1, 23, 33, -14, -55, -59, -80, -75, -35, -7, 51, 40, -29, -35, -53, -128, -31, 111, 72, 46, 55, -19, -73, -23, 14, 64, 104, 87, 105, 68, -54, -76, -1, -18, 12, 92, 23, -79, -93, -105, -119, -64, -20, 39, 70, 2, -45, -52, -107, -82, 73, 106, 56, 53, 12, -57, -37, 14, 52, 105, 101, 94, 85, -5, -75, -25, -1, -8, 59, 52, -45, -89, -94, -117, -90, -42, 1, 53, 29, -29, -45, -79, -104, 3, 99, 78, 63, 42, -25, -49, -7, 30, 83, 112, 103, 99, 40, -54, -58, -11, -7, 36, 68, -4, -80, -98, -114, -106, -57, -15, 33, 42, -10, -46, -66, -97, -45, 68, 90, 67, 53, 4, -40, -20, 18, 60, 103, 107, 100, 69, -15, -62, -31, -9, 15, 60, 31, -50, -90, -108, -115, -79, -33, 11, 42, 15, -33, -58, -87, -75, 21, 87, 79, 63, 27, -26, -33, 1, 40, 88, 111, 105, 85, 20, -50, -49, -17, 5, 46, 49, -17, -77, -102, -115, -95, -49, -7, 31, 28, -15, -50, -76, -84, -21, 64, 84, 71, 45, -4, -32, -13, 22, 66, 103, 108, 95, 50, -23, -56, -32, -5, 30, 55, 14, -53, -92, -111, -107, -68, -24, 16, 34, 4, -37, -66, -85, -53, 32, 81, 77, 58, 17, -25, -24, 6, 46, 89, 108, 101, 71, 6, -49, -45, -16, 15, 49, 36, -26, -77, -103, -110, -85, -41, 0, 30, 20, -21, -55, -79, -72, -5, 65, 81, 67, 36, -10, -28, -8, 27, 71, 102, 104, 85, 34, -31, -51, -29, 1, 37, 48, 2, -57, -93, -109, -97, -58, -16, 20, 28, -4, -42, -70, -79, -36, 39, 78, 74, 51, 9, -24, -18, 11, 51, 91, 105, 94, 57, -6, -48, -41, -12, 22, 48, 26, -33, -79, -103, -104, -74, -32, 6, 28, 12, -27, -60, -78, -59, 8, 66, 78, 62, 27, -13, -24, -3, 33, 74, 100, 99, 74, 20, -35, -48, -25, 8, 40, 40, -7, -61, -94, -106, -88, -49, -9, 21, 21, -11, -47, -72, -71, -22, 45, 76, 71, 43, 2, -22, -13, 16, 56, 91, 101, 85, 43, -15, -47, -36, -6, 28, 45, 16, -38, -80, -102, -97, -65, -24, 11, 25, 4, -33, -63, -75, -46, 18, 66, 75, 56, 19, -15, -20, 2, 38, 77, 98, 93, 62, 8, -38, -44, -20, 14, 41, 32, -15, -64, -94, -101, -79, -40, -2, 22, 15, -17, -52, -72, -61, -9, 49, 74, 66, 36, -2, -21, -9, 22, 61, 91, 96, 76, 31, -22, -45, -32, 0, 32, 40, 7, -43, -82, -99, -89, -56, -17, 14, 21, -2, -38, -65, -69, -33, 26, 66, 71, 50, 13, -16, -16, 7, 43, 79, 95, 85, 50, -2, -40, -40, -14, 20, 40, 24, -22, -66, -93, -95, -70, -32, 3, 21, 9, -23, -55, -70, -51, 1, 52, 71, 60, 28, -6, -19, -4, 27, 64, 90, 91, 66, 19, -27, -43, -26, 6, 34, 35, -1, -48, -83, -96, -81, -47, -10, 16, 17, -9, -43, -66, -62, -22, 33, 66, 67, 43, 7, -16, -13, 12, 48, 80, 91, 77, 39, -10, -40, -36, -8, 24, 38, 17, -28, -69, -92, -89, -62, -25, 7, 19, 4, -29, -58, -67, -42, 10, 55, 70, 55, 22, -9, -17, 0, 33, 68, 90, 86, 57, 10, -31, -41, -21, 12, 36, 30, -8, -53, -85, -94, -75, -41, -5, 17, 13, -15, -48, -67, -57, -13, 39, 68, 64, 37, 3, -16, -9, 18, 54, 84, 91, 72, 30, -17, -41, -33, -2, 28, 37, 10, -35, -74, -94, -86, -56, -19, 10, 17, -2, -36, -63, -66, -34, 19, 60, 70, 51, 17, -11, -15, 5, 39, 74, 92, 83, 49, 1, -36, -40, -16, 18, 37, 24, -17, -61, -90, -93, -70, -34, 1, 18, 8, -22, -55, -69, -50, -2, 47, 70, 61, 31, -3, -17, -5, 26, 62, 88, 90, 65, 19, -25, -42, -27, 5, 33, 33, 1, -45, -81, -95, -81, -48, -11, 14, 15, -10, -43, -66, -61, -22, 31, 65, 68, 43, 9, -14, -11, 12, 49, 80, 92, 76, 38, -10, -39, -36, -8, 24, 38, 16, -27, -70, -92, -89, -61, -25, 7, 17, 3, -31, -59, -68, -39, 8, 55, 55, 19, 0, -9, -10, -14, -13, -21, -30, -32, -44, -49, -57, -65, -72, -83, -98, -104, -117, -123, -128, -127, -128, -128, -128, -128, -127, -128, -120, -117, -109, -100, -90, -83, -72, -66, -55, -50, -33, -42, -18, -29, -18, 15, -6, 11, 7, 19, 3, 38, 5, 48, 44, 64, 57, 97, 82, 111, 104, 110, 107, 120, 116, 125, 126, 126, 126, 126, 127, 117, 125, 123, 100, 127, 101, 124, 102, 121, 109, 126, 96, 125, 116, 127, 90, 119, 87, 127, 90, 118, 95, 123, 93, 106, 90, 100, 104, 74, 84, 73, 97, 72, 71, 57, 66, 80, 36, 59, 38, 55, 35, 57, -6, 64, 10, 25, 19, 19, -22, 65, -26, 14, 2, -17, -12, 22, -40, -3, -31, -24, -38, -1, -56, -6, -48, -36, -54, -19, -56, -33, -49, -69, -49, -52, -53, -60, -61, -84, -76, -85, -96, -95, -95, -114, -93, -117, -104, -93, -101, -98, -100, -101, -96, -78, -95, -71, -70, -72, -52, -63, -70, -43, -77, -41, -48, -65, -53, -53, -59, -42, -56, -37, -64, -54, -52, -50, -54, -56, -54, -55, -62, -51, -47, -44, -67, -60, -63, -56, -64, -53, -48, -61, -53, -58, -38, -48, -32, -38, -34, -28, -26, -23, -25, -22, -6, -7, -12, -1, 5, 6, 6, -7, 22, -4, 27, 15, 18, 24, 37, 30, 47, 24, 53, 29, 63, 29, 46, 46, 51, 52, 53, 36, 54, 65, 55, 33, 64, 36, 69, 54, 26, 62, 66, 36, 68, 30, 47, 54, 58, 20, 55, 31, 40, 50, 35, 19, 56, 33, 25, 46, 18, 22, 42, 21, 25, 32, 19, 19, 26, 18, 23, 29, 24, 7, 27, 6, 33, 8, 17, -2, 14, 3, 23, 14, 7, 5, -9, -13, -10, -23, -12, -16, -27, -8, -18, -15, -3, -18, -24, -5, -23, -9, 0, -11, 4, -1, 4, 2, 5, -2, 3, -1, -7, 4, -11, 1, -12, -4, -7, -10, -11, -11, -16, -23, -15, -20, -22, -23, -20, -30, -23, -31, -25, -32, -35, -41, -34, -44, -39, -34, -49, -33, -30, -36, -29, -33, -14, -24, -32, -18, -15, -7, -9, -11, 5, -14, 27, -11, 16, -10, 13, -9, 23, -10, 19, 10, 18, 11, 29, 1, 47, 27, -4, 45, 3, 43, 40, 14, 13, 57, 16, 34, 27, 22, 30, 32, 14, 24, 27, 20, 20, 17, 4, 20, 20, 8, 8, 0, 10, -3, 17, -8, -1, -4, 1, 0, 6, -7, -3, -3, -13, -5, -6, -18, -5, -28, -12, -13, -5, -11, -5, -28, -7, -15, -10, -6, -28, -16, -12, -17, -8, -10, -19, -10, -24, -30, -32, -26, -31, -36, -32, -33, -27, -25, -26, -26, -25, -25, -23, -16, -22, -10, -11, -7, -7, 4, -10, 10, -9, 11, -8, 4, -6, 4, -8, 3, -4, 2, -3, -5, -3, -11, -8, -6, -12, -11, -7, -24, -4, -17, -9, -18, -28, -16, -29, -23, -38, -24, -34, -22, -38, -18, -27, -10, -22, -19, -21, -2, -23, 10, -19, 0, 4, 16, 7, 0, 3, 17, 14, 26, 8, 25, 27, 30, 25, 38, 31, 49, 37, 42, 45, 48, 55, 63, 46, 54, 54, 56, 59, 56, 47, 50, 53, 47, 50, 44, 42, 35, 40, 31, 37, 35, 27, 20, 23, 19, 26, 24, 18, 11, 14, 18, 24, 18, 12, 10, 3, 12, 2, 9, 4, 0, 0, 3, -4, 11, 1, 1, -1, -5, -7, 1, -6, -1, 2, -4, 1, -1, -7, -9, -11, -21, -19, -20, -28, -27, -22, -29, -24, -26, -32, -22, -25, -31, -24, -19, -22, -11, -19, -15, -4, -5, -4, 0, -6, -6, 2, -9, -5, -5, -9, -10, -7, -18, -8, -14, -14, -19, -29, -25, -16, -25, -30, -30, -30, -21, -29, -38, -37, -36, -41, -44, -53, -48, -43, -44, -55, -46, -40, -33, -36, -40, -40, -28, -25, -24, -23, -17, -15, 1, -3, -1, 5, 2, 9, 1, 4, 12, 13, 14, 15, 9, 21, 26, 32, 31, 28, 28, 41, 38, 49, 45, 46, 53, 56, 57, 57, 57, 58, 55, 48, 56, 56, 56, 45, 39, 41, 41, 44, 42, 25, 28, 27, 24, 28, 21, 14, 17, 8, 15, 22, 13, 15, 16, 3, 11, 10, 4, 6, 4, -8, 0, -2, -2, -3, -2, 1, 3, -3, -3, -6, -8, -5, 4, 3, 2, -4, -2, -1, 5, 3, -2, -2, -2, 3, 7, -2, -26, -37, -34, -30, -13, -14, -21, -24, -27, -24, -13, -7, -15, 6, 3, -30, -50, -48, -47, -41, -26, -8, 28, 43, 38, 57, 63, 56, 75, 118, 127, 117, 99, 86, 85, 66, 46, 59, 80, 69, 43, 27, -6, -47, -74, -80, -71, -57, -40, -44, -56, -78, -88, -78, -59, -52, -51, -56, -57, -47, -36, -36, -39, -39, -32, -17, 6, 24, 33, 10, -14, -14, -2, -11, -20, -15, -24, -28, -28, -25, -28, -54, -73, -65, -43, -18, 6, 27, 21, 23, 17, 22, 18, 16, 31, 50, 45, 25, 22, 8, -20, -17, 8, 29, 10, -22, -41, -45, -51, -53, -31, -18, -23, -7, 37, 54, 38, 36, 60, 100, 119, 120, 122, 125, 110, 88, 94, 99, 90, 85, 82, 54, 26, -5, -49, -83, -85, -67, -36, -14, -30, -55, -76, -86, -65, -41, -45, -60, -53, -43, -35, -34, -41, -43, -45, -35, 10, 40, 32, 3, -3, -14, -30, -38, -33, -23, -29, -26, -18, -10, -17, -37, -46, -58, -61, -45, -17, -4, -2, 19, 31, 27, 13, 22, 38, 49, 59, 69, 60, 23, -13, -11, 13, 24, 19, 24, 8, -30, -58, -58, -66, -85, -90, -61, -19, -1, -11, -5, 25, 42, 61, 92, 109, 106, 110, 104, 93, 93, 89, 82, 86, 81, 71, 51, 13, -40, -74, -87, -73, -35, -24, -50, -71, -73, -53, -50, -58, -68, -60, -61, -54, -30, -25, -40, -52, -25, 13, 32, 45, 49, 44, 28, 22, 29, 32, 20, 3, 7, 6, 0, -1, -4, -30, -63, -69, -62, -57, -49, -25, 2, 17, 24, 27, 30, 10, 4, 38, 77, 66, 32, 13, 7, 0, 9, 31, 43, 23, -11, -25, -23, -46, -83, -87, -63, -42, -19, -6, -3, 6, 27, 49, 81, 108, 121, 123, 124, 115, 110, 98, 80, 78, 77, 77, 69, 54, 8, -56, -99, -92, -53, -46, -64, -75, -73, -70, -75, -62, -67, -86, -88, -54, -28, -33, -46, -50, -40, -24, -3, 29, 51, 48, 34, 44, 44, 30, 18, 13, -3, -15, -7, -1, -10, -36, -56, -65, -79, -100, -91, -64, -52, -40, -5, 20, 9, -14, -9, 21, 49, 59, 58, 49, 25, -1, 11, 39, 39, 22, 19, 20, 8, -19, -49, -72, -69, -58, -43, -27, -24, -13, -5, 12, 38, 74, 97, 110, 124, 126, 126, 114, 105, 100, 87, 91, 108, 115, 73, 5, -41, -49, -49, -53, -45, -49, -69, -77, -60, -51, -71, -94, -96, -68, -49, -46, -44, -45, -60, -60, -27, 0, 11, 26, 37, 37, 37, 40, 42, 34, 8, -1, 14, 15, -5, -12, -18, -44, -75, -85, -88, -98, -99, -76, -36, -12, -19, -24, -11, -9, 1, 36, 71, 58, 29, 13, 17, 33, 33, 30, 35, 44, 44, 27, -3, -39, -51, -61, -55, -41, -31, -25, -29, -21, -1, 23, 46, 76, 102, 109, 110, 116, 118, 92, 61, 76, 112, 120, 93, 57, 14, -28, -54, -50, -46, -60, -83, -82, -64, -62, -82, -89, -93, -101, -88, -59, -52, -64, -75, -76, -63, -50, -30, -1, 9, 8, 11, 32, 44, 36, 29, 32, 27, 20, 22, 28, 24, 0, -21, -30, -45, -78, -97, -83, -66, -50, -32, -17, -16, -23, -20, 4, 38, 51, 47, 37, 28, 29, 27, 27, 31, 42, 54, 55, 43, 20, -5, -29, -40, -37, -30, -27, -23, -15, -12, -11, 8, 43, 67, 78, 100, 122, 126, 107, 84, 81, 92, 106, 115, 110, 79, 31, -3, -13, -26, -47, -56, -56, -58, -58, -56, -59, -72, -86, -84, -66, -57, -56, -56, -60, -74, -74, -51, -32, -24, -14, 3, 14, 15, 19, 28, 33, 19, 11, 22, 29, 18, 8, 9, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -3, -2, -1, 0, 2, -4, -13, -21, -23, -19, -8, 7, 17, 23, 26, 33, 38, 32, 17, -5, -17, -24, -20, -6, -3, -16, -29, -26, -17, -5, -1, 2, 7, 11, 17, 15, 9, 9, 3, 10, 15, 9, -14, -33, -27, -18, -6, -7, -10, -6, 0, 12, 15, 29, 38, 36, 32, 11, 0, -30, -45, -50, -39, -23, -27, -24, -15, 6, 25, 37, 51, 46, 40, 0, -19, -22, -34, -30, -40, -45, -51, -34, -1, 25, 48, 40, 43, 51, 64, 58, 5, -22, -49, -63, -69, -68, -58, -54, -16, 13, 44, 66, 61, 68, 72, 86, 47, -17, -56, -82, -88, -93, -72, -58, -40, 4, 45, 94, 98, 84, 65, 68, 71, 15, -46, -88, -90, -88, -85, -62, -56, -34, -4, 41, 80, 82, 74, 54, 70, 66, 25, -29, -70, -74, -90, -87, -79, -73, -46, -10, 54, 90, 103, 88, 76, 90, 69, 25, -38, -76, -96, -119, -111, -103, -81, -57, -12, 50, 90, 113, 98, 100, 112, 103, 60, -11, -54, -95, -121, -124, -119, -95, -71, -10, 53, 103, 116, 93, 91, 89, 80, 31, -28, -67, -108, -122, -128, -110, -87, -53, 8, 60, 107, 107, 89, 83, 83, 76, 27, -14, -52, -84, -99, -103, -82, -72, -40, 4, 53, 92, 92, 88, 85, 97, 87, 42, 3, -45, -74, -106, -111, -105, -101, -70, -30, 27, 65, 77, 83, 87, 106, 90, 58, 16, -30, -67, -101, -100, -101, -93, -68, -27, 29, 60, 77, 79, 93, 111, 96, 71, 24, -21, -73, -109, -118, -127, -118, -98, -50, 6, 43, 65, 70, 99, 115, 108, 82, 40, -1, -53, -80, -94, -105, -101, -82, -31, 18, 56, 66, 72, 95, 103, 97, 64, 29, -15, -63, -85, -102, -105, -104, -81, -35, 13, 53, 58, 69, 86, 97, 94, 67, 39, -12, -54, -80, -97, -102, -103, -77, -38, 9, 40, 45, 60, 77, 95, 88, 70, 41, -8, -46, -74, -87, -99, -100, -78, -42, 10, 37, 50, 66, 89, 110, 103, 91, 57, 9, -33, -68, -86, -105, -105, -89, -51, -2, 23, 40, 53, 80, 99, 98, 89, 53, 8, -37, -68, -90, -107, -106, -94, -51, -5, 25, 43, 58, 86, 95, 98, 86, 52, 9, -36, -64, -92, -105, -108, -95, -53, -11, 22, 37, 57, 81, 90, 96, 82, 52, 6, -34, -64, -92, -104, -113, -97, -59, -18, 15, 31, 58, 79, 92, 98, 87, 57, 9, -29, -63, -87, -100, -109, -91, -58, -13, 16, 36, 62, 78, 93, 96, 88, 56, 12, -25, -62, -83, -101, -106, -89, -57, -15, 6, 30, 52, 71, 87, 94, 89, 55, 18, -21, -55, -76, -96, -100, -88, -53, -16, 6, 31, 53, 76, 93, 105, 98, 64, 26, -18, -52, -78, -99, -105, -95, -59, -26, 0, 24, 45, 66, 81, 97, 88, 62, 28, -12, -40, -67, -84, -95, -83, -50, -21, 4, 24, 47, 64, 81, 96, 85, 63, 26, -11, -41, -69, -88, -102, -91, -64, -36, -12, 10, 34, 51, 74, 87, 81, 62, 26, -7, -40, -63, -83, -95, -83, -58, -31, -10, 14, 34, 51, 75, 85, 82, 61, 30, -3, -34, -57, -81, -92, -83, -60, -36, -15, 11, 27, 47, 69, 80, 79, 59, 30, -5, -33, -57, -82, -93, -84, -61, -38, -15, 10, 25, 48, 68, 80, 77, 58, 29, -4, -30, -56, -80, -89, -78, -54, -34, -8, 10, 0, 0, 1, 0, -2, -2, -5, -8, -3, 3, -4, -10, 2, 8, 3, 4, 5, -3, -9, 10, 26, 26, 12, -4, -40, -64, -50, 1, 55, 69, 28, -23, -65, -83, -52, 13, 67, 67, 39, 16, -15, -48, -38, 10, 53, 44, 5, -5, -14, -43, -35, 16, 54, 37, -1, -26, -53, -82, -37, 35, 67, 44, 2, -10, -20, -39, -19, 27, 55, 42, 3, -26, -67, -107, -62, 43, 110, 102, 43, -18, -63, -91, -35, 73, 120, 77, -6, -72, -113, -109, -36, 53, 78, 50, 0, -46, -72, -71, -20, 67, 112, 100, 44, -24, -88, -123, -84, 5, 71, 97, 66, 7, -53, -100, -80, -1, 83, 127, 108, 38, -57, -121, -119, -57, 24, 84, 97, 62, -4, -77, -97, -46, 32, 101, 108, 56, -20, -103, -119, -69, 18, 105, 126, 90, 6, -92, -126, -90, -3, 85, 108, 75, 0, -86, -117, -85, -6, 76, 115, 101, 30, -68, -118, -105, -33, 57, 105, 102, 41, -46, -104, -112, -59, 25, 95, 121, 81, -5, -88, -126, -94, -12, 63, 101, 76, 7, -67, -107, -73, 11, 94, 127, 102, 21, -74, -124, -95, -21, 57, 101, 82, 21, -48, -89, -59, 6, 67, 95, 60, -11, -82, -115, -81, -13, 52, 84, 52, -9, -68, -96, -56, 9, 66, 93, 63, 10, -52, -86, -54, 1, 60, 96, 70, 19, -44, -80, -51, 0, 55, 94, 69, 20, -42, -88, -76, -40, 24, 79, 72, 34, -28, -75, -63, -23, 35, 71, 48, 4, -57, -95, -67, -10, 62, 103, 75, 18, -61, -110, -86, -22, 61, 110, 90, 37, -45, -100, -87, -39, 34, 81, 70, 33, -39, -88, -76, -24, 54, 94, 76, 32, -46, -100, -92, -42, 35, 73, 62, 26, -46, -97, -93, -44, 36, 81, 75, 35, -38, -87, -81, -26, 58, 99, 85, 37, -44, -101, -103, -46, 47, 98, 97, 56, -27, -90, -99, -49, 37, 88, 95, 62, -12, -74, -93, -51, 27, 69, 71, 35, -30, -78, -87, -38, 41, 84, 90, 57, -11, -71, -96, -56, 21, 69, 86, 60, -4, -67, -97, -61, 12, 65, 88, 65, 3, -61, -94, -60, 14, 71, 96, 68, 3, -66, -104, -70, 3, 59, 84, 59, -1, -67, -107, -76, -3, 59, 89, 64, 3, -67, -111, -82, -9, 57, 92, 76, 26, -43, -93, -71, -9, 50, 80, 64, 16, -51, -100, -79, -17, 49, 88, 77, 30, -41, -95, -79, -17, 49, 87, 77, 34, -36, -92, -78, -19, 44, 82, 73, 33, -37, -95, -84, -23, 47, 89, 83, 43, -30, -92, -83, -28, 39, 79, 74, 40, -28, -87, -82, -31, 34, 71, 67, 35, -31, -88, -85, -36, 28, 68, 69, 44, -20, -79, -83, -43, 19, 59, 64, 41, -25, -89, -100, -61, 9, 60, 76, 57, -10, -75, -90, -51, 22, 74, 88, 66, 1, -61, -78, -42, 25, 71, 84, 63, -1, -67, -90, -59, 8, 59, 81, 68, 8, -56, -85, -62, 1, 50, 74, 63, 7, -53, -84, -60, 5, 55, 80, 70, 17, -43, -76, -55, 4, 49, 73, 65, 17, -41, -77, -62, -9, 38, 68, 64, 17, -43, -84, -73, -22, 23, 56, 57, 18, -36, -77, -68, -23, 20, 51, 52, 16, -36, -77, -70, -26, 18, 54, 59, 28, -22, -64, -59, -20, 21, 56, 63, 36, -12, -55, -52, -16, 25, 58, 63, 35, -14, -59, -57, -22, 18, 51, 57, 31, -16, -58, -58, -27, 10, 43, 51, 30, -16, -59, -60, -28, 12, 48, 57, 35, -13, -59, -64, -35, 7, 47, 63, 47, 1, -46, -55, -32, 7, 47, 0, 0, -1, -1, -4, 1, -1, -3, -13, -8, -14, -3, -2, -2, 1, 8, 5, 7, -21, -13, -2, -6, -8, -22, -6, 5, 11, 34, 41, 33, 13, 28, 33, 48, 35, 21, -3, -26, -18, -10, 3, 7, 22, 21, 63, 40, 41, 43, 4, -8, -43, -63, -77, -77, -59, -18, 3, 2, -21, -46, -74, -90, -108, -101, -94, -89, -84, -85, -77, -59, -50, -33, -7, 18, 37, 47, 64, 101, 127, 125, 127, 126, 126, 126, 122, 100, 87, 62, 37, 28, 27, 25, 27, 34, 25, -4, -45, -85, -123, -128, -126, -128, -127, -123, -92, -73, -55, -45, -37, -33, -32, -33, -43, -53, -55, -43, -20, 3, 20, 34, 42, 49, 55, 63, 74, 84, 93, 101, 107, 112, 117, 109, 92, 63, 33, 8, -13, -25, -29, -30, -27, -27, -32, -46, -63, -82, -98, -109, -116, -121, -118, -104, -80, -49, -12, 21, 45, 58, 64, 66, 66, 61, 51, 44, 37, 32, 32, 33, 33, 28, 23, 15, 8, 3, 2, 9, 16, 20, 24, 23, 14, -1, -20, -37, -48, -53, -52, -47, -38, -26, -13, -5, -1, -4, -10, -22, -34, -43, -48, -46, -34, -16, 5, 25, 45, 65, 78, 84, 83, 71, 55, 39, 24, 9, -3, -12, -23, -34, -45, -57, -65, -71, -71, -63, -49, -34, -21, -11, -2, 2, 8, 11, 12, 14, 14, 20, 28, 38, 50, 58, 63, 61, 56, 46, 33, 17, -1, -19, -34, -45, -48, -44, -32, -19, -5, 5, 7, 4, -2, -7, -11, -15, -18, -21, -23, -26, -28, -30, -31, -29, -26, -20, -12, -1, 11, 21, 32, 42, 51, 55, 55, 52, 46, 41, 37, 32, 30, 28, 27, 24, 19, 12, -1, -21, -45, -67, -89, -103, -107, -101, -90, -70, -51, -33, -18, -2, 11, 23, 33, 39, 44, 49, 52, 57, 59, 59, 56, 52, 48, 41, 35, 28, 20, 15, 11, 4, 0, -5, -11, -18, -25, -34, -42, -47, -48, -46, -40, -33, -27, -24, -21, -24, -32, -42, -51, -56, -58, -56, -47, -35, -18, 2, 24, 48, 70, 88, 99, 104, 102, 97, 89, 79, 69, 59, 49, 37, 27, 14, 0, -14, -29, -44, -58, -71, -81, -87, -88, -88, -85, -81, -77, -72, -63, -51, -37, -21, -5, 12, 29, 43, 53, 59, 61, 57, 48, 36, 24, 13, 8, 8, 15, 25, 38, 48, 54, 54, 50, 43, 33, 22, 11, 3, -6, -15, -25, -35, -46, -54, -61, -65, -68, -69, -69, -68, -64, -59, -52, -43, -32, -20, -7, 6, 19, 31, 42, 51, 58, 62, 64, 62, 58, 52, 44, 35, 26, 17, 9, 1, -5, -10, -15, -18, -19, -20, -19, -18, -16, -15, -14, -14, -15, -16, -17, -18, -19, -19, -19, -19, -18, -16, -14, -11, -9, -6, -3, 0, 3, 6, 10, 14, 18, 22, 27, 32, 35, 37, 37, 35, 30, 23, 14, 4, -6, -15, -24, -31, -36, -39, -40, -39, -37, -32, -26, -19, -10, -1, 8, 17, 24, 29, 32, 33, 32, 29, 25, 20, 15, 11, 7, 3, -1, -5, -9, -14, -19, -24, -28, -31, -32, -31, -27, -23, -16, -10, -3, 2, 7, 10, 12, 13, 13, 13, 12, 10, 8, 7, 5, 5, 5, 5, 6, 8, 10, 13, 17, 20, 23, 25, 26, 25, 21, 16, 9, 1, -7, -16, -24, -31, -37, -42, -47, -49, -51, -52, -51, -48, -43, -37, -30, -20, -7, 6, 19, -1, -4, -4, 0, -1, -4, -3, 4, 4, -2, -3, 2, 1, -4, 0, 5, 0, -4, 2, -10, -26, -29, -34, -49, -61, -44, -21, -8, -3, -3, 1, 20, 32, 38, 32, 12, -4, 1, 14, 28, 51, 68, 78, 80, 72, 38, 1, -6, 16, 23, 2, -14, -15, -20, -33, -62, -65, -37, -18, -27, -29, -26, -45, -38, 8, 52, 55, 31, 26, 16, 17, 45, 80, 87, 77, 62, 54, 24, -23, -50, -43, -28, -47, -72, -86, -86, -87, -61, -35, -38, -57, -69, -55, -27, 1, 4, 22, 45, 54, 31, 0, -7, -5, -3, 0, -9, -21, -20, -15, -27, -31, -10, 5, 9, 3, -21, -67, -83, -46, -3, 8, 18, 22, 4, -3, 5, 35, 52, 67, 72, 83, 89, 71, 37, 19, 25, 8, -11, -37, -58, -80, -85, -68, -33, -24, -57, -60, -34, -16, -14, 17, 73, 96, 77, 48, 17, -7, -9, 4, -1, -3, 6, 3, -12, -10, 19, 33, 33, 41, 35, -29, -70, -64, -38, -18, 3, 17, -5, -26, -35, -5, 31, 63, 73, 86, 94, 80, 64, 50, 46, 37, 28, -2, -32, -65, -91, -84, -63, -59, -82, -97, -80, -66, -65, -43, 8, 49, 60, 61, 42, 27, 23, 23, 14, 15, 18, 10, -12, -17, -9, -13, 8, 35, 42, 2, -41, -76, -87, -67, -46, -31, -32, -45, -72, -53, -5, 32, 46, 72, 92, 96, 92, 77, 75, 73, 61, 44, 12, -32, -68, -72, -54, -58, -75, -85, -67, -57, -61, -60, -46, -11, 24, 35, 22, 15, 6, -1, -13, 8, 23, 8, -1, -1, -6, -8, 35, 71, 86, 79, 50, -11, -46, -38, -31, -29, -21, -30, -64, -68, -43, -12, 10, 28, 62, 89, 88, 84, 85, 90, 89, 95, 83, 28, -32, -53, -36, -44, -62, -64, -55, -59, -54, -52, -48, -23, 19, 48, 37, 39, 42, 31, 12, 19, 20, 5, 4, 1, -23, -40, -14, 14, 42, 68, 64, 14, -33, -53, -52, -32, -18, -24, -43, -67, -62, -36, -18, -1, 25, 54, 57, 58, 56, 54, 50, 66, 80, 44, -21, -50, -40, -52, -69, -77, -60, -56, -54, -53, -62, -49, -9, 28, 41, 58, 58, 47, 43, 49, 41, 34, 37, 18, -19, -44, -47, -36, 1, 35, 38, 19, -20, -62, -71, -59, -36, -34, -47, -63, -63, -50, -38, -17, 7, 37, 56, 74, 80, 73, 61, 87, 116, 99, 47, -7, -26, -22, -20, -32, -57, -72, -76, -76, -71, -47, -9, 13, 24, 29, 29, 25, 27, 52, 68, 62, 9, -38, -67, -66, -39, -11, -4, -24, -37, -47, -51, -49, -44, -55, -39, -6, -17, -52, -54, -19, 1, 15, 24, 31, 41, 55, 71, 79, 89, 111, 115, 88, 54, 22, -2, -8, -5, -7, -27, -49, -57, -69, -72, -64, -30, -3, 17, 31, 37, 29, 14, 39, 67, 73, 47, 10, -40, -72, -58, -23, -12, -19, -19, -39, -49, -42, -46, -62, -44, -8, -11, -36, -51, -39, -15, 0, 13, 21, 25, 40, 55, 63, 73, 95, 115, 115, 85, 53, 20, 2, -1, -2, -10, -32, -48, -64, -73, -77, -62, -33, -9, 16, 33, 31, 18, 17, 44, 67, 70, 49, 6, -45, -69, -53, -24, -13, -19, -24, -40, -47, -45, -50, -62, -43, -10, -13, -37, -51, -39, -15, 0, -3, -1, 1, -1, -6, -6, -4, -1, -2, -6, -8, -7, -4, -5, -10, -14, -16, -16, -16, -17, -18, -18, -17, -15, -15, -16, -15, -13, -10, -9, -9, -11, -13, -14, -11, -9, -8, -9, -7, -3, -2, -5, -8, -6, 1, 5, 4, 1, 0, 1, 4, 4, 4, 5, 7, 9, 9, 8, 8, 9, 10, 9, 5, 2, 3, 5, 7, 7, 9, 11, 11, 12, 14, 14, 12, 8, 7, 8, 5, 1, 3, 8, 9, 9, 10, 14, 16, 15, 14, 12, 11, 9, 7, 3, -2, -3, 3, 5, 0, -5, -1, -1, -6, -10, -16, -23, -28, -29, -32, -39, -36, -23, -16, -19, -19, -10, -7, -12, -11, -5, -6, -11, -13, -11, -9, -8, -2, 6, 8, 8, 9, 6, 2, 4, 8, 9, 4, 4, 12, 18, 17, 14, 17, 20, 20, 16, 9, 7, 7, 5, 3, 4, 1, -2, 0, 3, 2, -1, 1, 3, 3, 1, 2, 2, 0, 3, 6, 9, 8, 0, -5, -3, 7, 12, 8, -2, -2, 9, 10, 2, -3, 2, 5, 1, -3, -5, -6, -2, -3, -11, -20, -26, -28, -30, -32, -37, -43, -45, -43, -40, -42, -41, -31, -22, -20, -18, -16, -16, -19, -15, -8, -3, -3, 3, 17, 26, 22, 16, 18, 23, 27, 26, 23, 17, 15, 21, 25, 24, 25, 31, 36, 32, 29, 23, 17, 15, 11, 5, 1, 4, 6, 8, 6, 7, 8, 10, 14, 18, 22, 20, 17, 14, 15, 13, 10, 15, 15, 12, 9, 10, 15, 14, 9, 3, 6, 10, 5, -3, -9, -16, -16, -10, -11, -20, -24, -18, -20, -32, -42, -48, -55, -70, -84, -95, -100, -92, -75, -65, -68, -67, -56, -55, -51, -41, -33, -37, -42, -38, -33, -31, -26, -6, 19, 30, 25, 25, 28, 30, 27, 19, 16, 18, 31, 44, 46, 48, 56, 71, 77, 74, 66, 54, 47, 37, 19, 3, 2, 3, 3, 4, 13, 20, 21, 25, 24, 25, 19, 18, 19, 19, 14, 6, 17, 14, 1, 3, 12, 27, 29, 25, 13, 14, 24, 22, 6, -7, -7, 0, 11, 12, 1, 0, 10, 8, -13, -32, -46, -52, -57, -70, -88, -106, -101, -81, -74, -82, -75, -49, -37, -42, -44, -42, -46, -51, -47, -40, -32, -27, -6, 3, 16, 32, 29, 25, 24, 30, 54, 69, 74, 78, 90, 108, 118, 124, 117, 107, 102, 93, 76, 61, 50, 41, 35, 31, 26, 13, 4, 0, -1, 0, -6, -12, -10, -8, -4, 0, -3, -20, -31, -27, -18, -16, -22, -29, -28, -9, 0, -3, -1, 2, 11, 20, 24, 18, 22, 34, 32, 16, -1, -18, -34, -46, -55, -67, -91, -102, -91, -72, -73, -81, -68, -55, -55, -65, -74, -79, -87, -87, -83, -81, -77, -60, -25, 4, 4, -3, 0, 13, 29, 29, 24, 23, 29, 51, 67, 72, 77, 88, 105, 114, 122, 116, 106, 100, 93, 77, 63, 51, 42, 36, 31, 27, 15, 5, 0, -1, 0, -4, -10, -9, -7, -3, 2, -1, -16, -28, -26, -16, -13, -18, -25, -25, -8, 2, 1, 2, 5, 13, 21, 26, 20, 23, 35, 35, 20, 3, -14, -32, -45, -54, -67, -91, -102, -90, -72, -75, -82, -68, -56, -56, -66, -75, -81, -88, -88, -83, -82, -77, -59, -22, 4, 1, -1, -2, -3, -3, -1, -1, -6, -8, -9, -12, -5, 6, 15, 21, 22, 21, 9, -8, -16, -23, -32, -22, 4, 27, 32, 17, -2, -21, -34, -37, -30, -24, -3, 24, 47, 58, 50, 23, -12, -41, -52, -47, -33, -2, 28, 48, 45, 28, 0, -36, -58, -53, -34, -4, 26, 52, 75, 73, 45, -5, -66, -101, -90, -61, -14, 23, 59, 87, 89, 63, 10, -46, -79, -80, -55, -23, -3, 27, 58, 62, 41, -6, -66, -92, -77, -29, 19, 41, 65, 74, 69, 42, -9, -73, -109, -107, -67, -17, 23, 70, 104, 111, 83, 21, -56, -104, -109, -62, -21, 4, 34, 68, 89, 75, 19, -46, -89, -85, -38, -1, 23, 45, 64, 74, 62, 8, -53, -98, -93, -47, -9, 16, 36, 62, 86, 78, 13, -67, -121, -109, -56, -9, 25, 58, 89, 109, 81, 8, -70, -119, -106, -56, -7, 32, 63, 90, 108, 74, -3, -89, -128, -118, -70, -22, 23, 62, 101, 126, 98, 26, -64, -117, -110, -72, -32, 6, 44, 93, 124, 100, 28, -63, -116, -110, -71, -26, 16, 54, 101, 121, 92, 13, -86, -128, -120, -79, -28, 15, 60, 111, 127, 95, 11, -83, -127, -116, -80, -29, 15, 67, 117, 127, 100, 17, -75, -118, -108, -75, -31, 7, 60, 109, 123, 87, 3, -83, -118, -106, -67, -23, 13, 62, 106, 119, 85, 3, -77, -106, -95, -61, -27, 2, 52, 103, 124, 97, 19, -61, -95, -92, -63, -34, -4, 45, 94, 116, 87, 8, -63, -91, -85, -58, -36, -9, 36, 81, 104, 76, 2, -60, -87, -77, -52, -32, -2, 48, 97, 119, 86, 7, -59, -90, -85, -65, -50, -22, 26, 78, 107, 79, 11, -49, -78, -73, -58, -46, -18, 31, 85, 112, 75, 1, -59, -84, -73, -55, -40, -12, 30, 80, 106, 74, 10, -46, -70, -62, -49, -39, -13, 31, 86, 110, 74, 8, -49, -70, -59, -46, -33, -6, 38, 92, 111, 76, 13, -42, -62, -56, -51, -44, -23, 19, 75, 97, 67, 8, -44, -63, -58, -56, -48, -26, 19, 75, 94, 64, 8, -40, -55, -50, -49, -42, -25, 18, 69, 85, 57, 4, -41, -54, -51, -50, -45, -28, 18, 71, 88, 60, 8, -35, -46, -47, -48, -46, -30, 16, 66, 84, 59, 9, -30, -41, -43, -42, -40, -22, 25, 73, 88, 60, 8, -30, -42, -46, -45, -42, -21, 28, 74, 83, 52, -1, -36, -46, -45, -40, -37, -17, 26, 66, 73, 41, -10, -42, -54, -53, -48, -43, -19, 27, 68, 76, 44, -4, -34, -44, -41, -37, -33, -10, 34, 71, 75, 40, -7, -36, -47, -43, -39, -35, -9, 35, 72, 75, 39, -7, -38, -49, -45, -43, -38, -11, 33, 68, 70, 36, -4, -31, -39, -36, -35, -31, -5, 36, 69, 69, 35, -4, -31, -38, -35, -37, -33, -8, 31, 64, 63, 31, -7, -34, -42, -40, -43, -38, -12, 28, 61, 59, 27, -10, -34, -40, -38, -41, -35, -9, 31, 63, 60, 29, -6, -31, -37, -38, -42, -35, -10, 29, 60, 56, 27, -8, -30, -33, -34, -38, -32, -10, 28, 56, 51, 23, -9, -29, -32, -34, -38, -33, -10, 29, 55, 50, 23, -9, -28, -30, -33, -37, -32, -8, 32, 56, 52, 23, 23, 0, -2, 0, -2, -6, -6, -6, -5, -2, -1, 5, 15, 20, 11, 12, 12, 6, 0, -8, -19, -12, -4, -19, -19, -4, 4, -7, -3, 5, 8, 11, 14, 9, 9, 8, -4, -11, -6, -8, -16, -14, -7, -1, -3, 1, 10, 13, 24, 28, 12, 10, 14, 11, -14, -29, -19, -12, -21, -25, -16, 2, 0, -11, -7, 7, 10, 0, 0, 5, 11, 6, 10, 21, 13, 7, 14, 4, -4, -9, -5, -11, -16, -7, -3, 3, 15, -2, 2, 17, 6, -19, -16, 3, 3, -14, -10, 7, 7, 4, 8, 11, 4, -5, -12, -9, -6, -14, -13, -17, -13, -8, 5, 9, 3, 10, 12, 24, 28, 26, 35, 20, -3, 24, 23, -19, -31, -23, -23, -38, -34, -18, -10, -8, -6, -4, -1, 5, -4, -8, 2, 15, 12, 26, 56, 37, 10, 25, 25, -4, -21, -24, -23, -26, -30, -27, -8, 10, -5, 3, 30, 6, -26, -7, 13, -2, -19, -2, 11, 3, 14, 21, 8, 12, 5, -19, -26, -12, 9, 1, -8, -8, 20, 27, 17, 16, 15, 0, 23, 39, 11, -4, -13, -21, -21, -32, -36, -27, -20, -24, -10, -4, 5, 14, 4, -11, -10, 7, -8, -7, 7, 7, 2, 15, 29, 55, 26, 4, 22, 37, 32, 14, 10, 18, 7, -1, -28, -49, -24, -14, -41, -53, -37, -28, -27, -15, 1, 2, 14, 14, 13, 3, 0, 1, 18, 9, 7, 11, 23, 23, 25, 16, -7, 1, 13, 26, 26, 9, 13, 28, 28, 1, -29, -29, -26, -27, -43, -43, -31, -12, -26, -15, 6, 16, 6, 22, 11, -4, 0, 3, 0, -4, -20, -9, 15, 23, 19, 7, 25, 19, 42, 63, 40, 13, 22, 24, 1, -41, -60, -55, -63, -69, -61, -31, -7, 10, 8, 0, 7, 4, 4, 20, 5, -4, 9, 27, 31, 27, 23, 13, 19, 12, 2, 4, 15, 20, 35, 19, 16, 26, 3, -30, -48, -31, -40, -60, -59, -47, -13, -3, 12, 22, 11, 7, 9, 8, 3, -10, -34, -5, 6, 24, 38, 19, 13, 21, 40, 15, 2, 27, 26, 16, 44, 47, -7, -43, -41, -29, -44, -80, -81, -58, -26, -17, 3, 16, 30, 19, 10, 25, 16, 6, -12, -3, 13, 30, 38, 20, 17, 22, 25, 18, 13, 16, -3, 1, 32, 44, -11, -48, -51, -34, -38, -49, -64, -70, -23, -10, -14, -1, 20, 18, 20, 21, 11, 3, -8, -3, 13, 14, 22, 18, 32, 37, 30, 25, 16, 27, 27, 18, 37, 52, 12, -26, -56, -57, -46, -71, -92, -86, -50, -21, -10, 8, 15, 15, 18, 28, 17, 1, 1, 2, 13, 13, 23, 23, 21, 29, 31, 29, 15, 20, 33, 32, 29, 46, 21, -31, -49, -53, -51, -66, -82, -76, -54, -32, -10, 12, 19, 29, 18, 3, 0, 16, 20, 29, 31, 20, 25, 31, 43, 41, 34, 44, 27, 29, 65, 54, -15, -70, -79, -63, -86, -114, -114, -79, -26, -2, 6, 18, 19, 10, 19, 26, 15, 5, 0, 16, 23, 29, 30, 21, 25, 28, 37, 37, 38, 44, 32, 29, 66, 65, -7, -67, -74, -59, -82, -114, -117, -85, -31, -2, 11, 20, 18, 9, 20, 30, 15, 5, 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 7, 7, 7, 7, 7, 6, 4, 3, 2, 0, -1, -2, -3, -5, -6, -8, -9, -9, -11, -12, -14, -15, -17, -17, -17, -18, -19, -19, -19, -18, -17, -16, -15, -13, -11, -8, -7, -6, -5, -3, -1, 0, 0, 1, 3, 5, 8, 10, 12, 14, 17, 19, 21, 23, 26, 27, 28, 28, 28, 26, 25, 24, 23, 23, 21, 19, 18, 16, 15, 14, 13, 12, 11, 11, 11, 10, 8, 6, 5, 5, 4, 2, 0, -2, -4, -5, -7, -10, -11, -12, -13, -14, -15, -15, -15, -15, -15, -16, -17, -18, -18, -19, -21, -23, -25, -27, -28, -29, -29, -30, -30, -29, -27, -25, -23, -22, -20, -18, -16, -14, -13, -12, -11, -11, -10, -9, -8, -6, -5, -4, -3, -1, 1, 3, 4, 6, 7, 8, 8, 9, 10, 11, 12, 13, 13, 13, 13, 15, 18, 21, 23, 24, 25, 25, 28, 31, 33, 34, 34, 32, 31, 31, 31, 30, 27, 22, 16, 12, 10, 9, 7, 3, -5, -13, -19, -22, -22, -23, -25, -28, -31, -33, -33, -32, -32, -31, -32, -33, -32, -29, -25, -21, -19, -19, -19, -19, -18, -15, -9, -3, 2, 6, 9, 12, 16, 21, 27, 32, 37, 39, 40, 40, 39, 39, 40, 41, 40, 38, 35, 34, 34, 33, 29, 22, 16, 11, 10, 11, 12, 12, 10, 8, 7, 5, 3, 2, 0, -6, -12, -19, -23, -23, -22, -23, -26, -30, -33, -33, -33, -34, -35, -37, -40, -45, -50, -53, -52, -48, -42, -37, -32, -27, -22, -20, -18, -16, -16, -18, -21, -26, -30, -33, -34, -35, -36, -38, -40, -41, -41, -38, -36, -36, -38, -41, -40, -38, -34, -30, -27, -25, -22, -20, -16, -15, -16, -17, -18, -16, -13, -10, -7, -4, -2, 1, 6, 11, 16, 21, 24, 25, 26, 24, 22, 19, 18, 19, 22, 24, 26, 30, 33, 38, 44, 50, 56, 61, 63, 68, 72, 74, 73, 68, 64, 57, 50, 47, 46, 44, 37, 21, 3, -11, -20, -23, -25, -30, -33, -36, -36, -34, -31, -27, -22, -21, -22, -21, -18, -21, -24, -27, -31, -33, -32, -27, -21, -14, -13, -17, -17, -10, 0, 10, 15, 16, 14, 8, 6, 10, 16, 25, 34, 39, 43, 47, 53, 62, 72, 82, 89, 92, 90, 84, 79, 77, 77, 76, 67, 54, 42, 33, 26, 18, 5, -11, -27, -41, -53, -65, -73, -77, -79, -81, -86, -93, -102, -110, -116, -118, -120, -124, -127, -128, -128, -126, -122, -116, -107, -96, -85, -78, -72, -64, -54, -45, -39, -40, -46, -49, -49, -47, -45, -44, -45, -45, -44, -42, -38, -33, -29, -26, -23, -20, -18, -14, -11, -8, -5, -2, 2, 7, 11, 10, 8, 7, 9, 16, 22, 26, 28, 31, 34, 39, 44, 49, 53, 57, 60, 62, 63, 63, 65, 66, 63, 57, 51, 46, 46, 50, 53, 54, 55, 54, 55, 57, 63, 69, 73, 75, 73, 69, 66, 64, 65, 63, 55, 43, 30, 18, 11, 3, -6, -15, -23, -29, -32, -32, -28, -22, -16, -13, -16, -16, -11, -2, 9, 15, 1, 0, 0, 0, -1, 0, -3, 0, -1, 0, -18, 21, -22, 23, -41, 20, 84, -39, 50, -61, 26, -126, -19, -37, 15, 2, 70, -33, 127, -55, 117, -73, 15, -45, -50, 8, -11, 23, 33, 1, 26, -67, 26, -25, 14, -45, 57, -124, 12, -4, -23, 107, -54, 127, -49, 43, 27, -59, -30, 15, -128, 5, -128, 86, -39, 82, 12, 62, 9, 51, -59, 53, -95, 67, -92, 68, -28, 94, 21, 47, -11, -1, -41, 0, -25, -9, 18, -68, 15, -27, 49, -27, 103, -4, 3, -36, 58, -98, 56, -116, -31, -123, 25, -58, 89, -21, 110, -25, 73, -28, 39, -21, 35, -40, 37, -20, 50, 55, 51, 6, 1, -47, -11, -32, -23, 38, -67, 3, -54, 34, -55, 79, 1, 32, -61, 89, -86, 53, -67, -10, -128, -6, -68, 51, -4, 82, 15, 83, -16, 63, -24, 55, -29, 8, 0, 6, 11, 54, 14, 16, -39, -9, -12, -47, 37, -40, -22, -60, 21, -76, 51, -17, 74, -63, 98, -36, 44, -33, 24, -113, -37, -89, 20, -30, 67, 18, 87, 0, 67, -6, 38, 1, -2, -18, -5, -20, 32, 17, 21, -8, -30, 15, -47, 11, -17, 11, -97, 43, -87, 27, -36, 91, -41, 66, 3, 44, -28, 55, -74, -37, -92, -21, -37, 33, -1, 75, 22, 36, 14, 26, 8, 8, -12, -7, -21, -1, 27, 11, 21, -30, 21, -37, -3, -13, 23, -27, -32, -10, -23, -44, 56, -1, 43, -12, 76, -29, 48, -9, -25, -71, -70, -48, -20, 2, 9, 56, 8, 56, -10, 52, -12, 31, -29, 27, -60, 62, -42, 83, -45, 30, -24, 4, -26, 33, -23, 5, -18, -25, -53, -7, -6, -6, 19, 16, 31, 3, 58, -14, 0, -64, -33, -58, -8, -43, 42, -18, 57, -9, 54, 1, 47, -3, 36, -18, 3, 4, 6, 2, -17, 8, -14, -27, 35, 2, -3, 1, -8, -43, -34, -1, -22, 12, 2, 37, -6, 53, 14, 16, -43, -22, -75, -2, -67, 23, -24, 39, -3, 39, 6, 44, 9, 37, 5, 1, 3, 5, 12, -18, 0, 0, -31, 5, 23, 1, -3, 10, -20, -48, -6, -30, 7, -18, 35, -4, 32, 21, 39, -26, -1, -75, -9, -65, -3, -28, 20, -5, 32, 5, 36, 20, 30, 30, 3, 10, -1, 16, -10, -7, -1, -17, -23, 18, 14, -3, 8, 9, -45, -14, -35, -1, -27, 18, -2, 29, 1, 61, -14, 20, -56, -19, -51, -22, -38, 9, -14, 22, 5, 24, 27, 23, 41, 13, 20, -7, 23, -2, -8, -2, -9, -26, -6, 14, 11, -11, 37, -33, -12, -38, -6, -33, 7, -14, 30, -12, 55, 4, 33, -32, -14, -45, -22, -43, -7, -15, 18, 18, 33, 17, 41, 22, 15, 14, 8, -24, -16, -18, -16, -7, 6, 16, -2, 8, -14, -6, -23, 0, -22, 1, -23, 21, 4, 24, -1, 9, -9, -11, -14, -13, -16, -14, -15, -12, -16, -5, 8, 28, 25, 28, 34, 27, 15, 16, 2, -20, -22, -20, -15, -8, 10, 11, 7, -3, -5, -16, -10, -13, -5, -16, -5, 4, 17, 13, 6, 1, -9, -1, -2, -3, -4, -4, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -6, -6, -6, -6, -6, -5, -3, -3, -5, -5, -5, -7, -8, -5, 4, 5, 13, 12, -12, -5, 10, 5, 4, 0, 3, 26, 33, 10, -15, -69, -89, -25, 25, 58, 70, 22, -41, -62, -31, 18, 17, -17, -12, -9, 20, 99, 96, 0, -88, -123, -69, 61, 116, 54, -11, -45, -28, 40, 38, -42, -59, -53, -31, 63, 78, -9, -65, -83, -59, 48, 110, 50, -11, -51, -54, 41, 96, 9, -87, -119, -77, 42, 118, 67, -18, -57, -46, 24, 89, 81, 22, -43, -77, -65, -41, -23, -3, 4, 8, -13, -54, -52, -21, 30, 89, 86, 8, -49, -76, -56, 30, 55, 52, 47, -7, -45, -49, -48, -10, 68, 74, 43, 22, -27, -25, 12, 20, -5, -43, -69, -46, 21, 53, 51, 38, -8, -32, 6, 20, -1, -19, -56, -67, -26, 27, 76, 95, 23, -64, -60, -15, 33, 39, -8, -37, -24, -7, 7, 4, -25, -23, -10, -14, -7, -5, -12, 2, 28, 31, 37, 21, -18, -16, -4, -22, -37, -46, -56, -8, 58, 64, 53, 31, -9, -9, -2, -57, -85, -52, -13, 59, 92, 21, -42, -47, -33, 27, 75, 27, -22, -38, -44, 18, 77, 32, -21, -46, -50, 34, 89, 22, -37, -60, -56, 31, 95, 36, -27, -57, -82, -15, 53, 15, -13, -25, -44, 14, 66, 14, -32, -53, -62, 25, 96, 50, 3, -32, -56, 25, 98, 51, -9, -56, -78, 7, 92, 71, 28, -31, -92, -42, 28, 20, 24, 8, -34, 22, 70, 18, -17, -53, -88, -20, 39, 7, -2, -8, -28, 35, 80, 19, -23, -55, -93, -22, 63, 54, 47, 19, -52, -35, 2, -36, -32, -18, -49, -9, 41, 15, 26, 34, -22, -6, 31, 1, 8, 9, -43, -15, 30, -3, -1, -7, -73, -48, 6, -14, 5, 13, -47, -30, 12, -13, 6, 18, -37, -13, 39, 27, 45, 38, -37, -32, 12, 3, 32, 46, -10, 6, 48, 16, 15, 15, -32, -2, 47, 24, 26, 18, -51, -51, -15, -29, -1, 19, -28, -15, 21, 2, 18, 22, -34, -24, 13, -3, 15, 14, -45, -34, 7, 10, 38, 31, -34, -30, 4, 5, 43, 61, 13, 4, 6, -22, 4, 24, -13, -13, -10, -34, 0, 23, -16, -16, -13, -42, -18, -4, -36, -17, 5, -10, 14, 22, -21, -22, -16, -37, -6, 20, -2, 17, 36, 19, 43, 43, -9, -15, -12, -29, 6, 31, 6, 10, 7, -23, -2, 9, -23, -15, -10, -26, 3, 20, -5, 1, 0, -22, 5, 22, -6, -8, -16, -37, -5, 20, 2, 11, 6, -19, 11, 33, 12, 20, 16, -7, 20, 35, 11, 11, -3, -28, 2, 19, -1, 3, -6, -29, -5, 2, -25, -17, -12, -16, 22, 34, 3, -4, -21, -36, 4, 26, 8, -1, -30, -54, -23, -3, -11, 0, -12, -27, 7, 24, 13, 19, -1, -21, 10, 27, 14, 17, 0, -14, 18, 33, 19, 14, -17, -41, -10, 9, 2, 7, -14, -30, 4, 20, 9, 9, -15, -35, -3, 16, 9, 0, -1, -2, -3, 4, 7, 4, -2, -3, 0, 3, -1, -1, 4, 5, -2, -13, -9, 1, 4, 2, 1, 2, 2, -2, -8, -4, 0, 4, 4, -3, -4, -3, 1, 2, -1, 3, 14, 1, -7, -12, -4, -2, 1, 1, 9, 5, -6, -5, -2, -1, -1, 1, 14, 6, -6, -7, 3, 8, -2, -4, 13, 12, -10, -17, -10, -5, -4, 2, 3, 7, -6, -6, -1, -1, -4, 1, 11, 6, -6, -9, 10, 11, 3, 1, 14, 15, -12, -20, -12, -9, -15, -1, 7, 2, -16, -7, 6, 0, -2, 10, 26, 17, -6, -11, 24, 21, 1, 0, 18, 15, -17, -31, -28, -23, -14, 0, -4, 0, -16, -8, 8, -4, -3, 7, 15, 5, -3, -3, 26, 25, 12, 8, 28, 17, -15, -28, -18, -17, -18, -7, -3, -7, -20, 0, 7, 1, -9, 6, 9, -4, -9, 2, 15, 24, 34, 31, 10, -4, -15, -29, -17, -21, -41, -40, -5, 19, -20, 3, 11, 33, 28, 21, 18, 15, 16, 3, -1, 18, 17, 15, 1, -15, -10, -5, -14, -42, -48, -43, -26, 4, -29, -14, -9, 32, 20, 12, 15, 21, 39, 24, 8, 26, 33, 6, -3, 0, 1, -7, -16, -41, -44, -51, -34, -3, -6, -6, -19, 26, 10, 15, 35, 46, 32, 20, 16, 23, 38, 15, -4, -10, 17, -6, -41, -48, -53, -70, -52, -9, -9, -22, -15, 19, 24, 22, 30, 49, 34, 10, 1, 15, 33, 15, 1, 17, 46, 12, -38, -59, -50, -57, -46, -13, -16, -30, -24, 26, 37, 33, 30, 45, 40, 2, -11, 17, 41, 24, -4, 16, 48, 15, -38, -67, -64, -65, -46, -18, -18, -35, -32, 35, 39, 37, 21, 45, 42, -2, -19, 14, 37, 22, 7, 24, 40, 13, -42, -68, -63, -63, -38, -6, -12, -34, -25, 39, 43, 39, 17, 47, 45, 3, -19, 21, 45, 25, 2, 21, 31, 0, -45, -71, -78, -83, -48, 2, 7, -27, -32, 34, 45, 49, 23, 44, 36, 5, -5, 38, 60, 27, -13, 21, 42, -13, -69, -81, -86, -79, -38, -9, -11, -41, -36, 38, 56, 45, 10, 43, 43, 10, -6, 36, 57, 41, 10, 36, 46, -16, -67, -66, -71, -80, -44, -8, -5, -29, -27, 30, 43, 46, 20, 52, 39, -9, -21, 40, 68, 42, -1, 20, 32, -14, -70, -86, -94, -90, -45, -2, 0, -31, -17, 36, 47, 46, 18, 44, 29, -2, -11, 46, 74, 51, 14, 36, 46, -15, -78, -87, -91, -89, -46, -12, -11, -28, -5, 41, 46, 40, 17, 51, 33, -6, -13, 49, 75, 52, 15, 30, 34, -21, -79, -88, -93, -88, -42, -9, -4, -25, -3, 36, 40, 34, 16, 44, 23, -8, -10, 52, 83, 55, 17, 38, 31, -31, -82, -91, -93, -82, -39, -16, -10, -25, 5, 33, 42, 32, 20, 54, 25, -9, -3, 59, 85, 63, 24, 37, 24, -39, -86, -92, -97, -80, -34, -17, -15, -24, 10, 35, 45, 32, 16, 45, 12, -23, -2, 62, 78, 53, 21, 37, 26, -39, -91, -95, -96, -77, -29, -16, -16, -25, 10, -1, 0, 3, 21, -26, 18, -30, 32, -19, -15, -27, 2, 0, 103, -84, -53, -52, 79, 51, 36, -69, -31, 48, 71, 33, -74, -64, 10, 51, 49, -68, -91, -16, 30, 33, -31, -58, -42, 14, 24, -25, 23, -71, 79, -22, 123, -74, 28, 28, 115, 99, -7, 9, -15, 72, 1, 16, -47, -5, -71, -18, -75, -26, -71, -28, -56, -24, -57, -19, -33, -5, 7, -3, 14, -8, 82, 100, 23, -32, -15, 80, 98, 68, -30, -21, 24, 71, 28, -41, -96, -22, 32, 37, -57, -110, -67, 28, 35, -22, -112, -79, 13, 70, 27, -55, -63, 31, 95, 86, -4, -40, 29, 110, 110, 28, -50, -12, 66, 80, 14, -87, -81, -7, 36, -5, -95, -118, -42, 26, 8, -69, -121, -48, 37, 60, -6, -68, -29, 67, 104, 61, -24, -17, 70, 123, 92, -5, -43, 23, 82, 67, -28, -96, -54, 18, 30, -39, -115, -96, -7, 25, -13, -99, -101, -13, 52, 42, -35, -62, 9, 88, 93, 28, -32, 15, 97, 118, 58, -29, -24, 51, 82, 39, -61, -88, -26, 28, 9, -70, -117, -63, 7, 14, -46, -109, -71, 15, 55, 16, -51, -42, 43, 94, 75, 2, -21, 48, 107, 101, 23, -36, 4, 65, 70, 1, -81, -69, -3, 26, -19, -94, -106, -32, 14, -3, -74, -103, -37, 34, 46, -10, -56, -12, 66, 91, 49, -15, 1, 74, 111, 76, -4, -28, 31, 72, 50, -33, -85, -43, 11, 15, -46, -106, -80, -11, 13, -26, -92, -84, -8, 44, 29, -30, -48, 19, 80, 81, 26, -18, 27, 91, 103, 49, -22, -10, 48, 68, 22, -60, -75, -22, 17, -5, -71, -105, -54, 3, 3, -49, -98, -58, 14, 44, 11, -44, -27, 45, 85, 65, 5, -8, 53, 100, 87, 21, -26, 11, 60, 56, -6, -74, -58, -4, 13, -25, -90, -91, -29, 7, -12, -72, -90, -29, 32, 37, -10, -46, -2, 66, 83, 47, -8, 10, 74, 101, 68, -3, -19, 31, 62, 38, -36, -77, -40, 6, 4, -49, -100, -72, -12, 3, -31, -86, -73, -4, 37, 25, -28, -36, 25, 75, 74, 25, -9, 34, 88, 94, 43, -16, -4, 47, 58, 15, -57, -69, -22, 6, -12, -73, -96, -50, -4, -7, -53, -89, -49, 13, 36, 5, -37, -17, 47, 77, 59, 9, 2, 58, 92, 79, 19, -17, 16, 54, 45, -13, -69, -52, -8, 3, -33, -85, -82, -29, -2, -20, -68, -79, -23, 24, 29, -11, -34, 7, 61, 73, 41, 0, 22, 73, 90, 58, 1, -9, 32, 52, 26, -36, -69, -35, -3, -7, -53, -90, -63, -16, -7, -36, -78, -60, -4, 29, 16, -22, -23, 29, 68, 64, 26, 2, 42, 80, 81, 38, -8, 5, 42, 44, 4, -53, -57, -21, -2, -22, -69, -83, -43, -10, -15, -51, -77, -38, 11, 27, 3, -27, -5, 46, 68, 52, 13, 15, 58, 83, 68, 19, -8, 21, 46, 32, -16, -60, -44, -12, -6, -36, -76, -74, -34, -10, -20, -57, -73, -33, 12, 27, 3, -1, -6, -11, -3, 4, 0, -7, -8, 1, 21, 14, 28, 33, 25, -1, 7, 4, -13, -21, -44, -29, -17, -31, -32, 2, 0, -20, 4, 3, 4, 0, -2, -5, -4, -14, 3, 14, 9, 28, 34, 54, 43, 54, 39, 19, 17, -1, 5, -23, -31, -25, -35, -46, -60, -29, -29, -13, -37, -22, -16, -20, -27, -21, -6, -16, 8, -5, 15, 26, 69, 65, 74, 85, 81, 76, 51, 22, -10, -10, -19, -3, -39, -73, -55, -36, -18, -45, -49, -45, -52, -47, -74, -73, -56, -31, -15, -16, -5, 18, 65, 86, 108, 94, 97, 90, 79, 54, 30, 19, 10, 25, -16, -34, -37, -9, -16, -35, -44, -60, -60, -50, -62, -70, -66, -44, -34, -34, -29, -10, 23, 61, 85, 79, 75, 70, 61, 41, 31, 7, 8, 3, -22, -42, -28, 0, -13, -29, -39, -52, -56, -55, -58, -60, -57, -41, -35, -37, -19, 5, 35, 71, 87, 85, 97, 112, 97, 71, 56, 52, 53, 43, 18, -7, -3, 10, 0, -17, -39, -55, -58, -64, -80, -106, -121, -112, -110, -113, -105, -82, -51, -8, 16, 20, 45, 66, 66, 49, 46, 59, 75, 78, 63, 62, 74, 80, 80, 69, 51, 27, 11, 0, -14, -40, -53, -48, -55, -68, -71, -56, -34, -1, 14, 24, 49, 62, 59, 42, 34, 43, 47, 43, 26, 30, 33, 38, 26, 4, -17, -41, -66, -81, -92, -112, -120, -115, -116, -128, -125, -103, -71, -36, -11, 9, 33, 56, 59, 54, 61, 67, 77, 77, 77, 79, 74, 75, 73, 55, 30, 10, -21, -38, -46, -61, -70, -67, -70, -81, -77, -64, -45, -23, -4, 10, 30, 44, 44, 39, 42, 48, 51, 50, 51, 58, 58, 65, 65, 47, 29, 12, -14, -31, -41, -53, -63, -60, -62, -64, -58, -44, -26, -11, 1, 10, 20, 22, 17, 9, 5, 6, 6, 2, 4, 10, 10, 17, 19, 9, 7, -1, -14, -18, -13, -14, -9, 1, 7, 12, 17, 23, 31, 35, 36, 35, 38, 31, 21, 16, 3, 0, -8, -11, -11, -13, -19, -20, -23, -34, -39, -51, -69, -78, -81, -83, -83, -78, -70, -60, -47, -34, -19, 2, 20, 39, 57, 60, 66, 67, 63, 61, 53, 50, 51, 47, 37, 32, 23, 13, 6, -3, -17, -23, -28, -34, -37, -35, -27, -15, -2, 4, 12, 23, 30, 44, 47, 43, 41, 35, 29, 22, 15, 13, 14, 7, -1, -5, -11, -19, -20, -25, -37, -43, -41, -43, -47, -47, -40, -29, -17, -7, 5, 13, 23, 38, 44, 37, 34, 31, 23, 17, 6, 1, -2, -10, -20, -25, -35, -45, -50, -54, -64, -68, -65, -66, -65, -59, -47, -30, -19, -7, 5, 14, 28, 48, 62, 66, 72, 75, 78, 76, 67, 60, 56, 46, 32, 20, 9, -2, -10, -21, -35, -43, -44, -49, -56, -57, -51, -38, -25, -13, -2, 9, 25, 42, 56, 59, 64, 65, 67, 65, 57, 52, 49, 41, 28, 18, 8, -2, -10, 0, 8, 13, 21, 20, 20, 17, 10, 8, -2, -6, -17, -21, -29, -23, -25, -14, -7, -2, 7, 10, 20, 21, 22, 23, 19, 14, 9, -2, -6, -18, -20, -28, -25, -23, -18, -10, -3, 5, 9, 22, 17, 28, 22, 21, 17, 11, 2, -8, -18, -23, -27, -26, -24, -19, -13, -6, 3, 9, 17, 20, 28, 24, 25, 21, 13, 6, -5, -14, -21, -29, -29, -30, -23, -19, -7, -1, 10, 18, 25, 29, 27, 28, 20, 17, 5, -7, -13, -26, -29, -30, -30, -27, -20, -12, 0, 11, 19, 25, 27, 30, 26, 28, 19, 11, -2, -12, -24, -30, -35, -34, -30, -24, -14, -2, 9, 18, 23, 28, 26, 33, 31, 29, 24, 12, 5, -12, -23, -30, -37, -36, -36, -26, -19, -5, 5, 19, 22, 32, 32, 36, 35, 26, 21, 3, -6, -22, -34, -41, -44, -38, -31, -18, -6, 6, 15, 23, 32, 33, 39, 34, 31, 23, 10, -2, -21, -32, -44, -47, -45, -37, -23, -12, 6, 13, 28, 30, 38, 40, 40, 38, 23, 17, -6, -15, -35, -42, -50, -49, -41, -31, -14, 0, 14, 26, 35, 42, 45, 45, 40, 27, 18, -4, -14, -33, -42, -54, -52, -47, -36, -21, -5, 13, 24, 39, 43, 52, 47, 42, 36, 20, 7, -15, -32, -45, -55, -56, -54, -43, -27, -8, 12, 26, 38, 45, 50, 51, 48, 40, 27, 9, -11, -30, -46, -58, -62, -58, -49, -31, -11, 9, 24, 41, 45, 54, 53, 54, 45, 30, 14, -10, -27, -48, -58, -67, -64, -56, -35, -15, 6, 24, 37, 45, 54, 56, 56, 49, 39, 18, 0, -26, -45, -60, -74, -70, -63, -41, -23, 4, 21, 39, 48, 53, 61, 58, 59, 43, 29, 3, -20, -46, -64, -77, -77, -69, -50, -27, 0, 20, 36, 49, 56, 64, 64, 63, 51, 34, 6, -17, -46, -65, -79, -83, -76, -58, -33, -6, 17, 38, 49, 60, 67, 68, 66, 53, 37, 13, -13, -38, -65, -79, -90, -82, -68, -41, -15, 14, 36, 52, 63, 70, 73, 69, 62, 44, 19, -8, -38, -63, -83, -93, -90, -77, -49, -20, 12, 34, 54, 65, 72, 75, 76, 65, 51, 26, -1, -33, -62, -86, -98, -96, -86, -58, -29, 6, 32, 54, 66, 73, 79, 76, 73, 58, 36, 4, -27, -60, -85, -101, -104, -92, -70, -36, -1, 31, 53, 70, 75, 81, 80, 78, 65, 41, 15, -24, -56, -84, -105, -109, -101, -79, -46, -7, 25, 56, 65, 77, 82, 85, 83, 69, 51, 19, -14, -50, -83, -103, -115, -107, -88, -55, -17, 21, 50, 67, 81, 86, 89, 85, 79, 55, 28, -8, -46, -77, -103, -116, -117, -97, -67, -25, 1, 39, 66, 81, 92, 96, 97, 90, 73, 45, 11, -27, -64, -97, -120, -128, -117, -89, -49, -5, 35, 65, 81, 93, 98, 99, 91, 75, 46, 12, -27, 28, -9, -42, -57, -50, -18, 33, 77, 77, 17, -64, -96, -55, 22, 73, 68, 17, -43, -77, -67, -15, 59, 102, 79, 12, -48, -71, -57, -28, -3, 11, 10, -3, -17, -4, 44, 88, 79, 10, -69, -103, -74, -6, 54, 75, 53, -4, -63, -80, -38, 32, 73, 59, 7, -43, -67, -57, -18, 33, 71, 71, 24, -31, -47, -17, 20, 23, -14, -58, -73, -47, 10, 73, 110, 93, 20, -62, -97, -68, -6, 43, 54, 28, -13, -51, -65, -35, 26, 74, 69, 12, -50, -68, -37, 9, 37, 37, 16, -12, -26, -7, 36, 65, 45, -19, -87, -112, -75, -7, 58, 97, 92, 41, -30, -75, -62, -3, 49, 52, 7, -44, -63, -45, -6, 37, 60, 42, -5, -42, -41, -3, 38, 41, 8, -33, -51, -38, 3, 54, 90, 79, 12, -76, -127, -106, -29, 47, 78, 63, 23, -19, -36, -16, 24, 50, 35, -15, -59, -64, -27, 17, 40, 35, 11, -20, -39, -26, 19, 63, 67, 14, -61, -97, -72, -5, 64, 101, 87, 26, -49, -96, -86, -32, 24, 40, 17, -11, -17, -3, 24, 51, 55, 29, -20, -66, -69, -23, 35, 55, 25, -26, -59, -55, -14, 44, 86, 80, 23, -56, -105, -87, -19, 48, 79, 67, 27, -18, -46, -43, -14, 17, 16, -20, -54, -47, 3, 59, 83, 66, 18, -35, -64, -54, -8, 44, 59, 18, -48, -87, -72, -16, 49, 88, 84, 37, -31, -81, -79, -26, 33, 52, 29, -5, -19, -6, 20, 34, 27, -5, -51, -84, -71, -9, 62, 95, 71, 12, -40, -58, -37, 8, 52, 63, 22, -53, -103, -88, -23, 47, 80, 64, 24, -14, -33, -28, -3, 21, 18, -15, -45, -39, 5, 57, 78, 54, -1, -60, -97, -89, -29, 50, 92, 67, 0, -53, -57, -13, 38, 64, 52, 10, -44, -82, -76, -26, 28, 49, 32, 1, -14, -1, 24, 40, 38, 9, -43, -87, -79, -13, 69, 110, 80, 4, -65, -90, -69, -21, 32, 58, 39, -9, -48, -45, 0, 52, 69, 46, 5, -34, -57, -50, -14, 23, 28, -8, -48, -48, 4, 71, 99, 69, 3, -63, -99, -88, -30, 46, 92, 78, 16, -45, -66, -44, -6, 25, 34, 16, -24, -55, -43, 10, 67, 80, 37, -22, -48, -29, 7, 30, 27, -5, -51, -84, -73, -11, 71, 116, 95, 27, -43, -84, -84, -43, 18, 63, 60, 10, -44, -53, -9, 41, 49, 14, -31, -57, -50, -15, 29, 61, 57, 14, -37, -51, -14, 38, 63, 47, -1, -61, -106, -105, -47, 44, 115, 113, 42, -36, -64, -42, -2, 23, 20, -3, -28, -39, -21, 24, 64, 59, 7, -48, -67, -47, -7, 36, 59, 47, 2, -55, -77, -31, 55, 111, 89, 7, -75, -113, -96, -42, 21, 62, 64, 28, -13, -18, 17, 45, 28, -2, -7, -6, -7, -7, -8, -8, -8, -8, -7, -6, -5, -4, -3, -3, -2, -2, -1, 0, 1, 2, 4, 5, 6, 8, 9, 10, 11, 12, 13, 13, 14, 15, 16, 17, 17, 17, 17, 17, 16, 16, 15, 15, 14, 14, 13, 12, 10, 10, 9, 8, 7, 6, 5, 5, 4, 3, 2, 1, 0, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -13, -14, -14, -14, -14, -14, -15, -15, -15, -15, -16, -16, -14, -14, -12, -10, -13, -10, -13, -7, -3, -5, -1, -1, -5, -5, 8, 13, 10, 10, 15, 16, 17, 30, 34, 19, 17, 22, 29, 27, 22, 16, 1, -3, 8, 18, 11, 6, 8, 8, 1, 6, 18, 5, -8, -4, 4, 5, 3, 5, -3, -6, 12, 30, 23, 9, 5, 6, 9, 15, 27, 20, 2, 0, 10, 17, 8, -1, -4, -8, -8, -3, -7, -19, -28, -24, -22, -31, -42, -47, -50, -50, -42, -35, -35, -43, -41, -31, -27, -23, -17, -9, -7, 3, 26, 37, 38, 37, 41, 39, 39, 49, 55, 50, 46, 53, 58, 51, 44, 36, 24, 9, 5, 2, -12, -25, -28, -26, -33, -42, -44, -55, -66, -69, -62, -60, -65, -57, -42, -33, -26, -15, -5, -6, 0, 15, 29, 34, 41, 55, 61, 62, 68, 71, 62, 49, 49, 49, 39, 29, 24, 14, -2, -10, -16, -34, -56, -67, -70, -77, -83, -85, -88, -93, -92, -79, -74, -78, -74, -61, -49, -41, -23, -9, -2, 11, 35, 54, 56, 58, 64, 69, 73, 81, 91, 86, 77, 78, 77, 67, 50, 39, 24, 6, -4, -10, -22, -41, -49, -52, -62, -73, -81, -87, -98, -97, -83, -74, -70, -63, -46, -33, -23, -6, 9, 18, 26, 48, 69, 77, 85, 97, 106, 107, 111, 114, 104, 89, 83, 84, 75, 60, 50, 34, 13, -5, -16, -34, -59, -74, -80, -86, -95, -97, -96, -104, -104, -95, -86, -86, -82, -66, -49, -32, -11, 12, 26, 36, 55, 73, 81, 84, 94, 104, 107, 114, 120, 116, 102, 92, 88, 73, 54, 37, 21, 0, -16, -23, -37, -58, -76, -85, -94, -108, -114, -116, -120, -119, -106, -89, -84, -78, -64, -49, -37, -21, 1, 13, 25, 46, 71, 88, 95, 105, 113, 112, 113, 116, 112, 97, 91, 91, 83, 68, 51, 35, 11, -10, -23, -38, -60, -80, -86, -93, -102, -107, -110, -116, -121, -114, -102, -98, -93, -77, -55, -38, -18, 1, 13, 25, 46, 71, 88, 95, 105, 113, 112, 113, 116, 112, 97, 91, 91, 83, 68, 51, 35, 11, -10, -23, -38, -60, -80, -86, -93, -102, -107, -110, -116, -121, -114, -102, -98, -93, -77, -55, -38, -18, 1, -3, -7, -8, -3, 1, 0, 3, -5, -9, -14, -15, -4, 0, 7, 12, 12, 11, 18, 16, 14, 14, 11, 20, 14, 19, 7, 12, 8, 13, 8, 7, 9, 0, 9, -7, -4, -5, -8, -7, -9, -7, -2, -7, -4, 1, 1, 0, -2, 3, 2, 1, 2, 1, -2, -3, -7, -2, -2, -2, -5, -4, -4, -4, 3, 6, 8, 3, 0, -3, -2, 3, 4, 3, 2, 2, -2, 1, 0, 2, 3, 9, 8, 2, -3, -4, -2, 1, 4, 0, -2, 3, 1, 7, 1, -4, 0, 2, 3, 1, 1, 2, -5, 3, -3, -4, -3, -8, 2, -7, 1, -3, -2, -5, -8, -7, -8, -7, -5, -7, -4, -8, -10, -7, -8, -7, -5, 0, -2, 0, -2, -3, -3, -2, 0, 1, 0, 1, 0, -3, -3, -5, -5, -9, -9, -13, -16, -21, -26, -25, -25, -16, -16, -12, -13, -15, -9, 3, 25, 44, 66, 68, 66, 49, 17, 13, 18, 41, 51, 40, 35, 25, 23, -2, -16, -28, -8, -4, -12, -18, -34, -29, -31, -28, -18, -4, 2, 16, 13, 20, 9, 4, 2, -3, -4, -9, -9, -9, -8, -9, -10, -13, -14, -15, -13, -4, 7, 13, 19, 18, 16, 9, 7, 4, 6, 8, 7, 7, 3, -3, -15, -19, -24, -21, -16, -9, 0, 3, 7, 4, 4, -3, -2, 6, 13, 20, 14, 16, 14, 11, 7, 0, -4, -3, -3, -7, -12, -12, -9, -5, -5, -7, -9, -4, -2, -2, -2, -4, -9, -10, -13, -13, -14, -15, -13, -9, -8, -9, -9, -7, -4, 2, 2, 6, 9, 8, 11, 9, 11, 9, 8, 6, 0, -7, -13, -21, -29, -36, -45, -53, -63, -72, -73, -61, -41, 0, 52, 98, 109, 81, 64, 54, 78, 77, 45, 39, 44, 25, 19, 6, -8, 25, 30, 44, 62, 46, -20, -85, -89, -88, -47, -29, -30, 2, 11, 8, 12, 24, 33, 29, 25, 22, 1, -15, -34, -37, -36, -41, -36, -28, -15, 2, 9, 11, 14, 12, 8, 12, 17, 18, 19, 23, 20, 20, 20, 8, -5, -14, -15, -15, -13, -13, -18, -19, -24, -29, -32, -31, -23, -12, -2, 12, 20, 23, 24, 25, 20, 22, 18, 16, 14, 9, 7, 2, 1, -9, -10, -19, -15, -12, -13, -8, -5, -4, -4, -7, -10, -12, -12, -16, -14, -8, -9, -13, -14, -18, -15, -10, -5, -3, 3, 4, 6, 11, 13, 13, 16, 16, 16, 12, 6, -3, -10, -16, -21, -28, -37, -48, -61, -77, -88, -87, -68, -34, 28, 92, 127, 99, 64, 50, 72, 92, 55, 43, 51, 41, 32, 4, -8, -7, -17, -23, -31, -33, -35, -32, -28, -23, -18, -12, -8, -4, -2, 0, 1, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 6, 7, 7, 7, 8, 9, 9, 8, 8, 9, 11, 14, 18, 22, 27, 32, 33, 30, 21, 6, -12, -30, -45, -54, -56, -51, -41, -29, -17, -9, -3, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 2, 3, 4, 5, 8, 9, 10, 9, 8, 7, 7, 8, 10, 15, 20, 25, 30, 35, 39, 39, 32, 19, 0, -22, -42, -56, -62, -61, -53, -40, -27, -15, -7, -3, -1, 0, 0, 0, 0, 2, 3, 4, 5, 5, 5, 4, 2, 0, -1, 0, 2, 5, 8, 9, 10, 10, 9, 9, 8, 9, 10, 14, 19, 24, 28, 32, 34, 38, 36, 29, 17, -5, -28, -49, -61, -65, -61, -52, -39, -25, -14, -7, -3, -2, -1, -2, -1, 0, 2, 4, 6, 7, 7, 5, 3, 0, -1, -1, 0, 3, 7, 11, 13, 14, 13, 12, 10, 8, 8, 9, 12, 17, 22, 26, 29, 31, 33, 31, 26, 18, 3, -16, -35, -50, -59, -61, -56, -46, -35, -23, -14, -6, -2, 0, 1, 2, 3, 4, 4, 5, 5, 5, 4, 2, 1, -1, -1, 0, 2, 5, 9, 12, 13, 13, 12, 11, 9, 7, 7, 8, 11, 15, 20, 24, 29, 33, 35, 34, 30, 21, 4, -16, -37, -55, -66, -68, -63, -50, -35, -21, -9, -1, 4, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 1, 0, -1, -1, 1, 6, 10, 13, 15, 15, 13, 11, 8, 5, 4, 4, 7, 11, 17, 22, 27, 32, 36, 39, 39, 36, 24, 6, -20, -48, -70, -81, -79, -67, -48, -29, -12, -1, 5, 7, 7, 4, 2, 1, 1, 2, 2, 3, 2, 2, -1, -2, -3, -3, -1, 3, 8, 13, 16, 17, 16, 12, 8, 3, -1, -3, -2, 2, 11, 21, 29, 36, 38, 39, 42, 48, 57, 52, 23, -27, -76, -107, -113, -98, -71, -42, -18, -1, 8, 12, 13, 10, 7, 3, 1, 1, 2, 3, 2, 1, 0, -2, -3, -3, -1, 2, 8, 13, 17, 18, 17, 12, 7, 1, -3, -4, -3, 20, 30, 38, 41, 39, 38, 46, 65, 75, 45, -23, -89, -126, -127, -101, -64, -31, -7, 5, 11, 13, 14, 13, 9, 4, 1, 0, 1, 2, 1, -1, -3, -4, -4, -2, 2, 6, 10, 14, 18, 18, 15, 9, 1, -6, -10, -13, -10, -4, 7, 20, 0, 14, 19, 23, 26, 28, 28, 26, 23, 18, 11, 3, -4, -10, -16, -21, -23, -24, -22, -20, -16, -12, -8, -3, 3, 8, 13, 19, 23, 26, 27, 26, 23, 17, 10, 4, -3, -9, -15, -20, -24, -25, -25, -22, -17, -11, -3, 3, 9, 14, 18, 20, 22, 23, 23, 21, 17, 13, 6, 1, -6, -11, -15, -18, -20, -19, -19, -17, -16, -13, -11, -8, -5, -1, 2, 5, 7, 9, 9, 8, 6, 3, 0, -3, -7, -10, -14, -17, -19, -19, -18, -16, -12, -7, -2, 3, 8, 13, 16, 18, 19, 17, 14, 8, -1, -11, -21, -31, -38, -41, -40, -34, -25, -12, 2, 17, 32, 45, 56, 62, 65, 63, 58, 49, 38, 25, 10, -6, -18, -28, -37, -44, -51, -59, -64, -64, -56, -40, -17, 7, 29, 46, 56, 58, 59, 56, 51, 45, 33, 19, 4, -13, -26, -39, -49, -56, -59, -55, -46, -34, -19, -4, 10, 21, 30, 40, 46, 51, 52, 49, 43, 31, 18, 5, -8, -16, -21, -23, -26, -29, -35, -39, -42, -40, -34, -22, -11, 2, 11, 18, 21, 24, 23, 22, 19, 14, 7, -3, -13, -21, -30, -39, -46, -50, -52, -49, -42, -31, -17, -3, 12, 26, 39, 49, 57, 60, 58, 51, 39, 22, 1, -23, -47, -68, -82, -89, -88, -77, -60, -37, -11, 16, 43, 65, 83, 94, 100, 101, 96, 87, 71, 51, 29, 4, -18, -38, -58, -75, -91, -104, -109, -105, -87, -61, -27, 8, 39, 67, 87, 97, 97, 88, 71, 54, 36, 16, -2, -23, -42, -57, -70, -75, -75, -71, -60, -43, -23, -1, 18, 31, 47, 57, 66, 71, 68, 61, 49, 32, 17, 1, -11, -22, -33, -41, -47, -54, -59, -63, -62, -57, -46, -30, -12, 1, 17, 30, 41, 49, 50, 47, 40, 29, 17, 3, -14, -30, -46, -60, -70, -76, -77, -73, -63, -48, -28, -4, 20, 44, 65, 81, 91, 93, 88, 77, 60, 37, 11, -19, -49, -76, -97, -109, -110, -100, -81, -56, -25, 7, 38, 67, 91, 109, 121, 127, 126, 116, 96, 68, 38, 8, -18, -43, -68, -90, -110, -124, -127, -116, -91, -59, -22, 14, 47, 77, 98, 107, 105, 93, 74, 54, 33, 13, -6, -26, -45, -60, -71, -78, -79, -74, -61, -42, -21, 1, 18, 33, 49, 60, 68, 73, 70, 62, 48, 32, 15, 0, -13, -24, -34, -42, -48, -55, -61, -65, -65, -60, -48, -32, -15, 2, 19, 32, 43, 50, 51, 47, 40, 28, 16, 1, -14, 2, -2, 2, -5, -3, -1, 0, -4, -4, -6, -4, -6, -4, -4, -7, -6, -7, -6, -1, 0, 3, 13, 14, 16, 12, 13, 2, 1, 0, -1, -1, -1, -2, -2, -2, -3, -3, -4, -8, -4, -4, -5, -5, -5, -7, -9, -12, -8, -14, -11, -14, -18, -8, 1, 31, 71, 68, 24, -5, -11, -7, -5, -5, -5, -3, -2, -5, -5, -9, -8, -7, -7, -9, -12, -11, -17, -14, -16, -15, -20, -26, -30, -27, -15, 16, 51, 87, 101, 70, 8, -18, -11, -14, -7, -7, -1, -2, -5, -7, -12, -14, -10, -10, -13, -14, -13, -16, -16, -17, -18, -35, -31, -30, -34, -9, 16, 56, 84, 89, 60, 30, 5, -7, -5, -8, -3, -4, -4, -6, -12, -14, -13, -10, -12, -12, -9, -10, -8, -12, -13, -15, -19, -23, -26, -33, -29, -28, -9, 12, 43, 71, 88, 72, 48, 29, -2, -16, -19, -12, -12, -12, -7, -11, -10, -10, -10, -11, -13, -15, -18, -19, -17, -16, -15, -13, -12, -13, -9, -13, -17, -21, -18, 2, 34, 59, 87, 92, 98, 38, -30, -24, -27, -18, -16, -11, -11, -13, -15, -12, -14, -15, -18, -17, -20, -18, -15, -10, -7, -3, -1, 2, -8, -11, -22, -22, -20, 7, 31, 61, 97, 106, 43, -23, -28, -25, -20, -12, -7, -5, -7, -10, -13, -13, -13, -11, -14, -15, -15, -12, -8, -7, -4, -2, -4, -10, -15, -19, -26, -10, 12, 42, 72, 101, 90, 20, -25, -27, -22, -18, -10, -6, -9, -11, -16, -17, -16, -14, -10, -8, -9, -9, -9, -9, -9, -8, -5, -3, -6, -10, -17, -24, -21, 4, 30, 61, 84, 96, 79, -16, -38, -27, -26, -17, -12, -8, -12, -13, -14, -14, -11, -8, -4, -4, -7, -9, -8, -10, -12, -8, -5, -4, -7, -10, -18, -24, -11, 14, 42, 70, 79, 93, 36, -32, -26, -28, -19, -15, -9, -9, -13, -16, -14, -12, -8, -5, -3, -7, -9, -9, -9, -11, -8, -5, -1, -6, -9, -15, -24, -23, 6, 28, 63, 86, 127, 37, -45, -27, -28, -26, -19, -4, -5, -8, -11, -12, -14, -12, -8, -4, -8, -8, -10, -8, -13, -8, -8, -3, -8, -8, -16, -23, -17, 7, 34, 69, 83, 113, 37, -50, -28, -25, -22, -16, 0, -3, -8, -12, -12, -14, -14, -10, -5, -7, -6, -9, -9, -13, -9, -10, -7, -9, -9, -15, -20, -14, 8, 33, 64, 81, 90, 57, -29, -28, 0, -4, 10, 10, 11, -15, 4, -1, 3, -11, 11, 2, -12, 3, 18, -10, -62, 89, -16, -95, 118, -128, 122, -128, 112, -100, 109, -121, 120, -104, 58, 10, -88, 127, -102, 6, 98, -126, 35, 89, -111, -7, 112, -53, -94, 92, 64, -106, -53, 109, 52, -100, -75, 86, 95, -45, -119, -12, 111, 74, -58, -118, -27, 97, 100, -4, -107, -95, 17, 109, 92, -4, -99, -109, -26, 78, 115, 66, -27, -104, -109, -41, 55, 112, 98, 32, -53, -109, -105, -44, 41, 102, 109, 67, -4, -74, -112, -102, -47, 27, 88, 112, 93, 45, -19, -78, -110, -105, -65, -4, 59, 101, 110, 87, 43, -13, -67, -103, -111, -89, -44, 13, 65, 100, 109, 93, 59, 14, -36, -78, -104, -108, -90, -53, -6, 43, 83, 104, 106, 88, 57, 17, -27, -66, -95, -108, -102, -80, -44, -2, 41, 77, 99, 106, 98, 77, 46, 10, -29, -64, -91, -105, -105, -91, -64, -29, 10, 48, 78, 98, 105, 100, 84, 59, 30, -3, -36, -65, -88, -101, -105, -99, -83, -60, -32, -1, 30, 58, 80, 96, 103, 102, 94, 80, 62, 40, 16, -10, -35, -58, -78, -92, -101, -104, -100, -91, -77, -58, -36, -13, 12, 36, 57, 75, 89, 98, 102, 102, 97, 88, 76, 61, 44, 25, 5, -15, -35, -54, -70, -84, -94, -101, -104, -103, -98, -89, -77, -63, -46, -27, -8, 12, 31, 49, 65, 79, 90, 97, 102, 104, 102, 97, 90, 81, 70, 57, 42, 27, 10, -7, -24, -40, -56, -70, -81, -91, -99, -103, -105, -105, -101, -95, -87, -76, -63, -49, -34, -18, -1, 16, 32, 48, 62, 74, 85, 93, 100, 104, 105, 105, 102, 97, 90, 82, 72, 61, 48, 35, 21, 6, -9, -24, -38, -52, -65, -76, -86, -94, -101, -105, -108, -108, -106, -102, -96, -87, -78, -66, -54, -40, -26, -11, 4, 19, 34, 48, 61, 73, 83, 92, 99, 104, 107, 108, 108, 105, 101, 96, 89, 80, 70, 60, 48, 36, 22, 9, -5, -19, -33, -46, -58, -69, -80, -89, -96, -102, -107, -109, -110, -110, -107, -102, -97, -89, -80, -70, -59, -47, -33, -20, -6, 7, 19, 30, 41, 50, 58, 65, 71, 75, 78, 79, 80, 79, 77, 74, 70, 65, 60, 54, 48, 42, 36, 29, 22, 16, 10, 4, -2, -7, -12, -16, -19, -22, -24, -26, -27, -27, -27, -26, -25, -23, -22, -19, -17, -14, -12, -10, -1, -1, -4, -9, -9, -7, -6, -7, -3, 4, 8, 10, 11, 13, 10, 4, -3, -10, -15, -13, -9, -10, -11, -5, 4, 12, 14, 12, 13, 14, 9, 1, -8, -15, -21, -23, -22, -13, -3, 7, 17, 24, 27, 19, 11, 16, 15, -5, -24, -29, -23, -27, -32, -21, 5, 18, 20, 21, 24, 24, 15, 11, 8, -6, -30, -31, -19, -17, -24, -14, 2, 17, 15, 12, 17, 16, 19, 8, -5, -2, -1, -17, -17, -3, 6, 5, -4, 0, 1, -12, -9, 9, 11, -4, -14, -8, 9, -2, -21, -14, 4, 9, 9, 11, 18, 21, 10, 8, 16, 10, 26, 35, 6, -14, -28, -25, -24, -55, -65, -33, -17, 1, -6, -6, 8, 23, 33, 49, 37, 19, 16, 11, 24, 42, 17, -37, -36, 3, 7, -23, -36, -9, 9, -12, -20, -8, -2, -4, -23, -17, -6, 0, 10, 24, 24, 40, 46, 33, 39, 26, 5, 6, 9, -12, -26, -33, -42, -61, -52, -43, -37, -21, -4, 7, 13, 28, 36, 31, 24, 1, -1, 20, 24, 23, 21, 26, 27, 8, -32, -44, -3, 28, -1, -36, -30, -6, 13, -12, -34, -18, -6, 9, 21, 25, 16, 10, 38, 62, 46, 17, -11, -7, 10, -8, -44, -53, -33, -35, -38, -29, -27, -16, 0, 1, 9, 37, 50, 36, 2, -20, -12, 15, 21, 24, 32, 29, 20, 23, 12, -8, -3, 4, -10, -5, 2, -19, -63, -70, -21, 20, 41, 23, 33, 57, 61, 42, 21, 15, 10, -45, -82, -60, -29, -44, -77, -50, -7, 4, -4, 10, 32, 56, 42, 1, -10, -18, 2, 22, 28, 33, 42, 47, 43, 47, 11, -23, 0, 10, -40, -81, -70, -28, -29, -68, -29, 19, 6, 7, 21, 40, 41, 32, 22, 28, 47, 69, 66, 35, 21, 15, -3, -20, -34, -24, -6, -19, -59, -47, -42, -35, -28, 15, 45, 51, 66, 78, 83, 37, 1, 13, 7, -51, -81, -92, -83, -87, -74, -58, -73, -51, 12, 35, 26, 35, 47, 69, 70, 63, 65, 49, 47, 68, 73, 52, 33, 15, -12, -30, -50, -51, -46, -45, -60, -50, -50, -50, -54, -24, 38, 78, 90, 106, 99, 40, -6, -11, -46, -110, -127, -107, -76, -67, -53, -41, -41, -23, 14, 33, 27, 34, 49, 70, 71, 66, 65, 51, 51, 69, 72, 52, 32, 10, -12, 0, -5, -2, -5, 2, -29, 22, 0, -27, 67, -59, 45, -13, -37, 28, 65, -4, 6, 60, 5, 58, 44, 60, 27, 43, 96, 71, 81, 48, 96, 70, 23, 90, 66, 80, 88, 40, 20, 61, 64, 12, 36, 24, 4, 7, 5, -27, -38, -26, -33, -49, -50, -70, -69, -93, -92, -94, -104, -104, -101, -110, -107, -111, -111, -126, -87, -119, -100, -94, -112, -93, -93, -80, -81, -76, -58, -56, -70, -30, -21, -42, -13, -3, 2, 8, 20, 28, 41, 45, 59, 62, 69, 84, 85, 90, 103, 109, 111, 118, 121, 121, 123, 121, 122, 121, 122, 121, 122, 121, 121, 120, 121, 120, 121, 120, 121, 120, 120, 119, 120, 119, 120, 118, 105, 106, 110, 83, 89, 92, 75, 67, 61, 57, 47, 40, 33, 24, 17, 10, 3, -2, -10, -20, -31, -31, -37, -49, -50, -63, -66, -69, -74, -79, -91, -89, -92, -95, -102, -106, -104, -107, -113, -113, -110, -113, -116, -114, -115, -114, -115, -114, -113, -114, -113, -114, -113, -112, -113, -109, -105, -111, -106, -107, -103, -100, -103, -99, -97, -98, -99, -92, -92, -93, -92, -92, -90, -88, -90, -88, -86, -89, -85, -85, -87, -85, -85, -82, -83, -82, -80, -78, -79, -76, -74, -73, -73, -69, -68, -66, -64, -65, -62, -58, -56, -56, -52, -50, -47, -43, -42, -39, -35, -33, -31, -27, -23, -21, -16, -16, -8, -7, -3, 1, 0, 10, 15, 15, 19, 26, 29, 30, 38, 41, 42, 47, 54, 54, 57, 63, 68, 69, 72, 77, 78, 80, 85, 84, 86, 87, 86, 87, 86, 85, 86, 85, 84, 85, 84, 83, 84, 83, 82, 82, 83, 82, 81, 82, 81, 80, 81, 80, 79, 80, 79, 79, 78, 79, 78, 78, 77, 74, 70, 66, 64, 61, 55, 52, 49, 45, 40, 35, 32, 29, 24, 19, 15, 12, 8, 4, 0, -4, -8, -11, -15, -17, -20, -25, -26, -29, -32, -34, -37, -39, -41, -43, -45, -46, -48, -49, -50, -50, -52, -52, -53, -52, -53, -54, -53, -53, -52, -52, -51, -50, -50, -49, -48, -48, -46, -45, -44, -42, -41, -40, -39, -37, -35, -34, -32, -30, -28, -27, -24, -23, -22, -20, -19, -17, -15, -14, -13, -12, -10, -9, -8, -8, -6, -6, -5, -4, -4, -3, -3, -2, -2, -1, -2, -1, -2, -1, -1, 0, -1, -1, 1, 0, 0, -3, -1, 1, -4, -4, -3, -2, -5, -3, 0, -1, -1, -3, -1, 0, 2, 0, -2, -5, 5, 4, 1, 7, 2, 2, 1, 8, 1, 6, 2, -4, 2, 1, -4, 6, -8, -3, -7, -2, -6, -1, -9, 1, -2, -4, 1, 2, 1, -2, 8, 2, 0, 14, 9, 10, 5, 3, 5, 6, 4, 3, -8, -2, -4, -10, -1, -5, -3, -4, -6, -13, -5, -4, -4, -3, 2, -13, -6, 3, 6, 6, 7, 1, 1, 6, 6, 16, 13, 9, 10, 9, 2, 7, 10, 4, -4, -3, -17, -7, -6, -6, -10, -17, -17, -10, -11, -9, -5, -6, -8, 2, 1, 8, 19, 15, 18, 24, 19, 16, 17, 19, 11, 7, 1, -5, -8, -9, -15, -8, -9, -14, -20, -19, -9, -18, -10, -13, -23, -13, -12, -7, 0, -1, 5, 16, 12, 28, 30, 32, 34, 34, 19, 24, 23, 16, 11, 5, -7, -19, -17, -16, -21, -26, -23, -32, -31, -30, -25, -26, -24, -19, -13, -9, -1, 0, 4, 6, 13, 15, 19, 17, 13, 8, 8, 8, 7, 0, -4, -8, -10, -7, -5, -6, -6, -9, -12, -8, -10, -9, -9, -11, -13, -12, -9, -4, -1, 4, 9, 19, 27, 31, 26, 16, 14, 16, 16, 12, 1, -8, -14, -11, -9, -6, -11, -11, -12, -14, -10, -11, -13, -15, -19, -23, -19, -14, -8, -5, -1, 8, 34, 62, 59, 12, 14, 32, 22, 6, 20, 6, -9, -54, -16, -1, -19, 7, -15, -13, -12, -14, -15, -14, -22, -24, -30, -30, -20, -12, -6, 3, 26, 66, 88, 39, 0, 47, 36, -2, 26, -23, 21, 13, -6, -60, -42, 6, -22, 4, -18, -16, -4, -16, -19, -24, -39, -31, -25, -32, -26, -11, 12, 55, 104, 75, 10, 35, 62, 9, 26, -16, -8, 19, 3, -9, -61, -46, 2, -26, -7, -16, -10, 2, -7, -22, -23, -38, -40, -37, -44, -33, -8, 37, 101, 124, 36, -5, 89, 20, 38, 5, -26, 3, 1, 5, -28, -65, -21, 1, -22, -12, -26, 1, -7, -10, -24, -26, -33, -37, -48, -50, -36, 5, 63, 122, 109, 7, 35, 84, 5, 59, -36, -4, -11, -1, -5, -40, -55, -4, -15, -21, -16, -22, 5, -10, -17, -20, -27, -23, -44, -54, -62, -23, 29, 114, 127, 51, 7, -2, -4, -2, 4, 11, 14, 10, 2, -7, -9, -9, -15, -16, -7, 3, 2, -10, -21, -17, 6, 10, -8, -28, -11, 45, 66, 64, 47, 36, 49, 49, 27, 9, -12, -18, -25, -30, -11, 0, -5, 0, -1, -18, -36, -33, -18, -10, -13, -31, -26, -25, -17, 4, 28, 70, 89, 48, 9, -32, -58, -56, -70, -57, -17, -38, -48, -35, -32, -7, 35, 38, 53, 62, 44, 33, 27, -6, -35, -52, -65, -54, -40, -43, -30, -25, 2, 63, 54, 34, 17, 34, 70, 60, 8, -15, -3, 0, 39, 55, 35, 39, 60, 75, 36, 20, -7, -25, -66, -110, -89, -89, -71, -36, -12, 9, 31, 41, 54, 46, 45, 59, 41, 22, 3, -69, -110, -126, -116, -64, -15, 9, 29, 33, 30, 56, 42, 12, 23, 6, -27, -36, -21, -22, -32, -21, -30, -29, -5, 9, 16, 22, -9, -12, 31, 24, -17, -41, -23, 32, 32, 26, 34, 64, 66, 109, 104, 51, 5, 12, 16, -36, -58, -59, -66, -63, -82, -64, -23, -9, 11, 16, 20, 19, 13, 12, 33, 37, 41, 46, 28, 7, -58, -93, -79, -64, -33, -1, 22, -4, 2, 19, 4, -7, -3, -3, 5, 1, -10, -3, 12, -6, -38, -29, -17, -5, 11, 2, -33, -20, 44, 42, 20, -30, -24, 9, 44, 38, 20, 36, 71, 61, 86, 72, 25, -8, 10, 17, -35, -54, -63, -67, -70, -78, -58, -16, -7, 19, 22, 20, 21, 29, 21, 16, 35, 36, 16, -8, -27, -61, -58, -67, -43, 3, 35, 38, -2, -2, 10, -9, -29, -14, -5, -1, -5, 2, 12, -6, -32, -23, -22, -16, -5, 3, -9, -29, 27, 56, 39, 11, -27, -28, 23, 34, 28, 18, 20, 62, 82, 71, 74, 24, -4, 16, 18, -39, -54, -65, -61, -52, -64, -49, -11, -4, 12, 17, 16, 25, 24, 6, 23, 36, 18, 18, -1, -42, -50, -90, -43, 3, 35, 38, -2, -2, 10, -9, -29, -14, -5, -1, -5, 2, 12, -6, -32, -23, -22, -16, -5, 3, -9, -29, 27, 56, 39, 11, -27, -28, 23, 34, 28, 18, 20, 62, 82, 71, 74, 24, -4, 16, 18, -39, -54, -65, -61, -52, -64, -49, -11, -4, 12, 17, 16, 25, 24, 6, 23, 36, 18, 18, -1, -42, -50, -90, -43, 0, 1, 6, -11, 19, -25, 24, -15, 11, -6, 1, 9, -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0, -5, 18, -23, 24, -28, 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40, 22, -6, -3, 14, -16, 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20, -4, -11, 19, -20, 21, -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32, -11, -7, 4, -4, 13, -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34, -21, 14, -9, 4, -13, 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6, -5, 13, -17, 9, -4, -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13, 5, -12, 6, -10, 18, -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30, -19, 5, -6, 7, -9, -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0, -17, 33, -48, 38, -16, -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9, -7, 15, -17, 9, 4, -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29, -8, -1, 1, 14, -58, 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61, 70, -99, 122, -120, 56, 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38, -3, 20, -31, 29, -37, 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25, 1, 1, -1, -3, 3, -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42, 13, -4, -14, 14, -29, 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25, -37, 43, -50, 32, -20, -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11, -21, 34, -40, 24, -7, -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47, -63, 62, -64, 32, 2, -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11, -1, -10, 6, -10, -7, 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24, 8, -7, -2, 3, -24, 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2, -12, 5, 1, -7, 7, -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13, 12, -3, -9, -6, 8, -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49, 48, -38, 8, 16, -40, 47, -52, 34, -12, -4, 2, -13, 0, 1, 6, -11, 19, -25, 24, -15, 11, -6, 1, 9, -6, -3, 11, -18, 28, -23, 8, 6, -2, -1, 0, -5, 18, -23, 24, -28, 27, -12, -1, -2, 6, 4, -14, 19, -29, 42, -40, 22, -6, -3, 14, -16, 4, 8, -9, 13, -22, 17, 5, -24, 37, -34, 20, -4, -11, 19, -20, 21, -16, 1, 17, -17, 5, -9, 25, -31, 31, -40, 32, -11, -7, 4, -4, 13, -23, 29, -40, 51, -49, 20, 3, -20, 38, -47, 34, -21, 14, -9, 4, -13, 20, -29, 37, -57, 59, -48, 23, -5, -7, 5, -6, -5, 13, -17, 9, -4, -12, 22, -19, -8, 10, -5, -7, 8, -18, 19, -13, 5, -12, 6, -10, 18, -40, 66, -91, 82, -56, 17, 19, -51, 56, -45, 30, -19, 5, -6, 7, -9, -4, -2, -5, 13, -19, 1, 20, -28, 13, -6, 0, -17, 33, -48, 38, -16, -20, 53, -75, 75, -61, 30, -12, -9, 2, 5, -9, -7, 15, -17, 9, 4, -46, 70, -85, 86, -67, 29, 18, -60, 76, -70, 29, -8, -1, 1, 14, -58, 93, -118, 127, -125, 85, -36, -2, 17, -39, 46, -61, 70, -99, 122, -120, 56, 15, -85, 116, -101, 30, 43, -108, 127, -122, 72, -38, -3, 20, -31, 29, -37, 42, -50, 63, -72, 40, -7, -46, 66, -82, 53, -25, 1, 1, -1, -3, 3, -24, 24, -34, 27, -24, 36, -49, 37, -38, 35, -42, 13, -4, -14, 14, -29, 42, -58, 58, -60, 41, -39, 27, -35, 27, -32, 25, -37, 43, -50, 32, -20, -4, 4, -14, 16, -43, 66, -93, 79, -58, 27, -11, -21, 34, -40, 24, -7, -25, 31, -29, 19, -18, -2, 1, -6, 4, -31, 47, -63, 62, -64, 32, 2, -29, 23, -21, 19, -41, 59, -76, 62, -52, 26, -11, -1, -10, 6, -10, -7, 17, -42, 34, -12, -34, 73, -106, 92, -61, 26, -24, 8, -7, -2, 3, -24, 31, -44, 27, -9, -22, 38, -43, 15, -4, -3, -2, -12, 5, 1, -7, 7, -25, 17, -17, 4, -15, 27, -40, 34, -18, 6, -13, 12, -3, -9, -6, 8, -18, 18, -36, 54, -55, 30, -25, 26, -41, 38, -49, 48, -38, 8, 16, -40, 47, -52, 34, -12, -4, 2, -13, -1, -2, -1, -4, -3, -25, -41, 8, 16, 27, 2, 16, 1, 13, 21, -8, -6, -29, 17, 8, 8, 20, -13, 5, 4, 25, 17, 30, 22, 14, 15, 19, 7, 51, -16, -15, -32, -13, 12, -8, -17, -49, -27, -29, -29, -52, -66, -55, -32, -20, -41, -21, -36, -11, -16, 22, 3, 19, 0, -6, -10, 0, -38, -17, -35, -19, -27, 0, -35, -27, -9, -17, -14, -2, 20, 50, 63, 57, 49, 70, 70, 97, 81, 68, 52, 78, 93, 98, 102, 56, 34, 20, 53, 60, 45, 24, -18, 21, -10, 0, -38, -79, -38, -37, -13, -27, -41, -50, -51, 14, 10, 16, -21, -13, -22, -20, -48, -53, -55, -66, -76, -65, -91, -105, -92, -87, -101, -79, -56, -34, -7, -4, 7, 20, 15, 26, 29, 32, -8, 36, 47, 50, 66, 29, 18, -33, -11, -4, -10, -24, -42, -31, -22, 2, -23, -75, -34, -36, 5, 1, 1, -17, -47, 20, 43, 68, 28, 30, 9, 29, 7, -9, -5, -32, -46, -36, -15, -40, -35, -15, -26, -21, 2, 21, 49, 62, 83, 87, 106, 77, 97, 94, 67, 60, 85, 79, 110, 80, 61, 1, 8, 16, 50, 36, 2, -22, 4, -2, 21, -35, -33, -19, 4, 24, 19, 10, -58, -23, 18, 45, 34, 8, -12, -6, -5, -48, -51, -75, -72, -77, -37, -65, -80, -57, -66, -68, -38, -38, 2, 10, 38, 31, 58, 22, 39, 37, 27, -9, 23, 9, 35, 18, 15, -31, -50, -44, -5, 6, -10, -63, -41, -56, -15, -41, -71, -45, -37, 7, -6, 5, -56, -71, -6, 21, 41, 8, -13, -14, -40, -30, -41, -40, -56, -31, -31, -9, -15, -5, 10, 42, 27, 73, 82, 73, 73, 79, 70, 38, 28, 31, 23, 45, 42, 44, 30, -40, 8, 28, 52, 30, -18, -29, -40, -14, -45, -50, -55, -68, -39, -6, -29, -45, -59, -32, 4, 31, 23, 16, 20, 11, -1, 1, -28, -45, -53, -56, -67, -60, -55, -40, -31, -25, -16, 11, 20, 36, 67, 70, 75, 77, 81, 65, 46, 38, 34, 39, 51, 44, 57, 7, -4, 13, 37, 46, 19, -8, -29, -1, -9, -21, -32, -43, -55, -58, -40, -8, 15, 29, 38, 44, 59, 63, 51, 20, -20, -47, -61, -58, -48, -42, -43, -35, -15, 15, 41, 55, 61, 62, 70, 67, 45, 11, -31, -62, -80, -78, -71, -62, -54, -39, -15, 18, 50, 68, 79, 83, 92, 88, 57, 16, -31, -71, -94, -95, -90, -83, -71, -55, -28, 7, 49, 77, 93, 100, 109, 107, 78, 36, -20, -71, -99, -104, -100, -92, -83, -69, -43, -5, 42, 79, 100, 108, 114, 112, 90, 51, -9, -65, -100, -110, -105, -95, -87, -76, -52, -11, 35, 75, 100, 107, 111, 106, 90, 52, -4, -60, -97, -109, -99, -87, -80, -65, -35, 5, 43, 75, 91, 95, 93, 87, 71, 31, -19, -64, -93, -99, -88, -76, -66, -44, -9, 28, 59, 79, 84, 80, 71, 59, 35, -5, -45, -76, -96, -95, -77, -59, -39, -9, 28, 61, 86, 98, 93, 74, 52, 28, -6, -43, -72, -94, -108, -99, -77, -52, -20, 19, 56, 84, 106, 115, 106, 79, 45, 3, -40, -74, -93, -108, -112, -100, -79, -46, -1, 45, 78, 100, 113, 118, 108, 81, 39, -19, -67, -93, -103, -108, -104, -94, -74, -32, 19, 61, 88, 102, 108, 109, 100, 73, 21, -44, -87, -102, -104, -97, -90, -78, -49, 0, 46, 78, 90, 92, 89, 87, 77, 43, -15, -72, -101, -104, -93, -79, -69, -47, -3, 47, 84, 96, 89, 74, 65, 58, 37, -7, -61, -99, -110, -101, -82, -62, -38, 2, 49, 92, 112, 106, 82, 59, 41, 18, -19, -61, -95, -111, -110, -98, -74, -39, 6, 54, 99, 122, 123, 104, 79, 50, 12, -32, -72, -100, -111, -110, -106, -90, -54, -4, 49, 99, 123, 126, 113, 95, 69, 24, -27, -72, -102, -114, -109, -104, -94, -64, -16, 36, 87, 116, 121, 111, 97, 76, 36, -15, -61, -94, -110, -108, -98, -86, -60, -19, 29, 77, 104, 109, 99, 86, 67, 35, -7, -47, -82, -98, -101, -92, -77, -48, -14, 25, 67, 92, 95, 83, 66, 45, 18, -9, -37, -62, -77, -81, -78, -54, -16, 0, 0, 0, 12, -10, 16, -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37, 31, -1, -25, -16, -47, -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33, -62, -54, -59, -32, -13, 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42, -46, 17, 55, 78, 86, 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78, 92, 105, 70, 13, -15, -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39, -4, -63, -103, -99, -107, -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104, -108, -83, -13, 29, 69, 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1, 47, 96, 90, 85, 52, 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86, 65, 35, -15, -41, -80, -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23, -59, -75, -74, -60, -22, 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61, -40, -9, 30, 52, 57, 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30, 49, 60, 47, 28, 6, -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34, 18, -3, -35, -39, -52, -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28, -43, -49, -31, -13, 2, 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26, -12, 19, 30, 34, 36, 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26, 35, 28, 12, 3, -17, -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8, -9, -18, -22, -28, -25, -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24, -21, -13, -3, 8, 11, 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3, 8, 20, 17, 7, 7, -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8, 6, 3, -9, -11, -9, -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4, -4, -10, -6, -3, -4, 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3, -3, 2, 3, 0, 6, 4, 0, -1, -2, -2, 0, 0, 0, 12, -10, 16, -14, -18, 17, -31, -2, 3, -19, -8, 17, 28, 37, 31, -1, -25, -16, -47, -13, -43, -22, 6, 34, 41, 49, 41, 27, 6, -33, -62, -54, -59, -32, -13, 29, 53, 73, 60, 54, 16, -19, -58, -77, -89, -42, -46, 17, 55, 78, 86, 81, 33, -3, -35, -84, -110, -75, -70, 0, 39, 78, 92, 105, 70, 13, -15, -82, -107, -103, -84, -41, 20, 81, 85, 127, 86, 39, -4, -63, -103, -99, -107, -69, 2, 68, 82, 127, 84, 58, 28, -44, -88, -104, -108, -83, -13, 29, 69, 116, 87, 77, 40, -16, -65, -89, -104, -89, -40, -1, 47, 96, 90, 85, 52, 9, -38, -62, -96, -95, -62, -22, 21, 73, 78, 86, 65, 35, -15, -41, -80, -92, -69, -48, 1, 43, 65, 80, 73, 49, 8, -23, -59, -75, -74, -60, -22, 17, 49, 69, 65, 60, 25, -1, -36, -59, -70, -61, -40, -9, 30, 52, 57, 63, 37, 17, -12, -41, -61, -57, -50, -30, 9, 30, 49, 60, 47, 28, 6, -20, -49, -51, -53, -42, -11, 13, 34, 53, 50, 34, 18, -3, -35, -39, -52, -49, -23, 0, 18, 41, 47, 36, 31, 10, -21, -28, -43, -49, -31, -13, 2, 28, 39, 35, 38, 19, -7, -18, -33, -42, -36, -26, -12, 19, 30, 34, 36, 22, 6, -5, -25, -38, -36, -29, -17, 8, 19, 26, 35, 28, 12, 3, -17, -30, -29, -29, -22, -3, 9, 19, 33, 26, 14, 8, -9, -18, -22, -28, -25, -9, 3, 15, 22, 20, 18, 12, 1, -11, -22, -24, -21, -13, -3, 8, 11, 20, 21, 12, 5, -6, -19, -16, -17, -17, -7, 3, 8, 20, 17, 7, 7, -2, -11, -13, -16, -17, -5, 2, 5, 12, 13, 8, 6, 3, -9, -11, -9, -14, -5, 1, -3, 6, 11, 6, 7, 2, -6, -4, -4, -10, -6, -3, -4, 5, 8, 2, 5, 4, -2, 0, -3, -9, -4, -3, -3, 2, 3, 0, 6, 4, 0, -1, -2, -2, 0, -1, -1, -3, -7, -14, -23, -32, -45, -55, -66, -74, -83, -88, -80, -77, -71, -64, -54, -46, -37, -31, -25, -19, -12, -6, -1, 4, 8, 12, 17, 21, 23, 25, 25, 27, 29, 32, 35, 36, 34, 32, 31, 32, 35, 37, 37, 35, 31, 29, 29, 31, 33, 34, 32, 29, 26, 25, 27, 30, 32, 31, 29, 27, 27, 29, 31, 34, 35, 35, 35, 36, 38, 41, 43, 45, 47, 49, 52, 55, 57, 59, 61, 63, 66, 69, 70, 70, 68, 66, 63, 61, 58, 54, 47, 36, 24, 11, 1, -9, -20, -33, -48, -64, -78, -89, -97, -103, -110, -116, -123, -128, -128, -126, -121, -116, -112, -107, -102, -95, -88, -78, -69, -61, -54, -47, -41, -34, -27, -21, -16, -12, -7, -2, 2, 5, 6, 8, 10, 13, 16, 19, 19, 19, 17, 18, 19, 22, 24, 24, 22, 19, 18, 19, 21, 23, 24, 22, 19, 17, 18, 20, 22, 24, 24, 22, 21, 22, 24, 27, 29, 30, 30, 31, 32, 35, 37, 40, 42, 45, 47, 50, 53, 56, 58, 60, 62, 66, 68, 70, 69, 68, 65, 63, 61, 59, 54, 46, 36, 24, 13, -1, -14, -28, -43, -57, -68, -78, -86, -94, -102, -109, -114, -117, -117, -115, -112, -109, -106, -101, -96, -89, -81, -73, -67, -59, -53, -46, -40, -34, -28, -23, -18, -13, -9, -5, -2, 0, 2, 5, 7, 10, 12, 14, 15, 15, 15, 16, 18, 19, 20, 20, 19, 18, 18, 19, 21, 22, 22, 21, 20, 19, 21, 23, 24, 25, 25, 25, 25, 26, 29, 31, 33, 34, 35, 36, 38, 40, 43, 46, 48, 51, 53, 56, 59, 62, 65, 68, 71, 74, 77, 78, 79, 78, 77, 76, 74, 71, 66, 58, 49, 39, 28, 17, 6, -6, -20, -35, -50, -64, -75, -85, -94, -102, -110, -117, -122, -124, -123, -121, -118, -114, -110, -106, -99, -92, -84, -76, -69, -61, -55, -48, -41, -34, -29, -23, -18, -13, -9, -5, -2, 0, -1, -1, 0, 2, 0, 3, 2, 2, 4, 5, 4, 4, 4, 4, 5, 3, 4, 3, 1, 2, 0, 0, -1, -3, -4, -2, -3, -5, -3, -4, -5, -5, -4, -3, -3, -6, -5, -4, -2, -5, -5, -2, -3, -3, -3, 1, 4, 4, 8, 8, 8, 13, 12, 13, 14, 12, 9, 8, 6, 6, 3, -2, -2, -5, -5, -4, -5, -11, -16, -12, -7, -3, -5, -10, -11, -6, -2, -2, -1, -4, -6, -6, -7, -8, -5, -2, 2, 5, 6, 8, 8, 9, 13, 16, 16, 14, 11, 7, 5, 4, 2, 0, -2, -3, -3, 0, -3, -13, -28, -11, 7, -1, -15, -1, -5, -18, -10, 6, 11, -11, -1, -10, -14, -13, -13, -4, 4, 6, 14, 13, 10, 10, 15, 17, 24, 24, 13, 12, 10, 1, 0, 2, -4, 0, -6, 2, 7, -22, -68, 2, 35, -40, 14, -24, -3, -10, -9, -20, -3, 28, 2, -9, -12, -28, -19, -4, -1, 15, 17, 17, 16, 12, 16, 22, 25, 28, 6, 17, 9, -1, -2, -3, 2, 12, -6, 6, -5, -35, -89, 32, 28, -39, 20, -36, 9, -20, -9, -34, 3, 34, 8, -16, -11, -37, -15, -3, 0, 26, 18, 13, 15, 13, 25, 27, 29, 20, 3, 21, 2, -2, 0, -8, 11, 16, -1, 8, -21, -76, -81, 87, -25, 4, -4, -23, 6, -26, -20, -35, 23, 28, 0, -18, -16, -43, 2, -9, 17, 25, 15, 9, 18, 17, 37, 28, 35, 3, 14, 12, -5, -1, -1, -5, 27, 0, 16, -11, -49, -128, 36, 40, -36, 35, -41, 21, -27, -14, -45, 4, 24, 20, -23, -6, -41, -9, -1, 6, 23, 19, 5, 15, 14, 33, 35, 40, 16, 5, 16, -3, -5, 4, -12, 24, 10, 18, 1, -38, -128, -21, 72, -50, 42, -38, 19, -16, -16, -43, -10, 21, 24, -22, -11, -30, -15, 6, 4, 22, 18, 6, 11, 13, 27, 39, 42, 22, 4, -3, -2, -2, -5, -3, -5, -3, -2, -6, -5, -5, -6, -5, -3, -5, -3, -5, -4, -6, -3, -1, -2, -1, 0, -2, 1, 2, 1, 4, 4, 5, 5, 5, 8, 10, 11, 9, 10, 11, 8, 5, 10, 7, 5, 5, 0, -3, 1, 0, -5, -2, -8, -9, -7, -7, -5, -9, -11, -9, -8, -8, -7, -9, -7, -6, -7, -5, -6, -5, -3, -3, -3, -4, -4, -2, 0, 1, 2, 5, 9, 12, 16, 19, 22, 22, 24, 22, 22, 19, 13, 11, 7, 7, 4, -2, -7, -9, -9, -8, -10, -14, -14, -15, -15, -13, -14, -17, -18, -14, -12, -12, -8, -9, -7, -6, -6, -6, -8, -9, -9, -11, -13, -11, -6, -1, 3, 9, 20, 27, 33, 37, 46, 46, 42, 37, 28, 21, 14, 11, 10, 14, 20, -2, -40, -47, -22, -5, -4, -1, 4, -15, -53, -56, -7, -33, -14, -2, -19, -7, -8, -15, -6, -9, -8, -3, -9, -15, -18, -26, -19, -6, -5, -6, 0, 12, 22, 29, 30, 28, 32, 29, 21, 15, 13, 5, 5, 3, 19, 30, 3, -68, -26, 2, -17, 17, -12, 15, -1, -12, -48, -43, -19, -1, 3, 6, -8, -4, -10, -10, -4, 0, -6, -1, -7, -9, -17, -12, -6, -9, -14, -5, 14, 33, 33, 41, 32, 41, 35, 20, 10, 8, 4, 10, -2, 36, 40, 3, -110, -8, -7, -6, 16, -18, 27, -2, -4, -56, -57, -33, 16, -2, 12, -11, -5, -17, -9, -5, 10, -6, 0, -12, -11, -20, -10, -8, -12, -17, -3, 17, 38, 34, 45, 36, 51, 37, 18, 4, -3, 3, 8, 8, 54, 48, -34, -128, 28, -33, 28, -13, 1, 21, 3, -20, -59, -65, -10, 17, -1, 7, -17, -10, -19, -8, 5, 11, -4, -2, -16, -17, -20, -9, -11, -18, -11, 3, 31, 36, 41, 41, 44, 53, 30, 10, 1, -13, 12, -5, 42, 63, 43, -127, -55, 19, -27, 28, -1, 0, 3, 5, 8, 12, 14, 15, 15, 14, 12, 8, 5, 1, -3, -9, -14, -17, -19, -18, -16, -12, -8, -5, -4, -2, -1, -1, -2, -3, -4, -3, -2, -1, -1, 0, 0, 0, 2, 8, 12, 16, 19, 23, 26, 34, 40, 39, 28, 11, -8, -26, -36, -40, -39, -35, -27, -19, -10, -5, -6, -10, -12, -15, -14, -12, -9, -5, -3, -1, 1, 6, 8, 7, 7, 7, 8, 13, 20, 28, 35, 43, 48, 55, 57, 51, 32, 3, -29, -56, -68, -67, -60, -46, -31, -17, -7, -4, -7, -11, -15, -16, -15, -10, -5, -1, 1, 3, 5, 7, 9, 11, 12, 12, 10, 13, 19, 26, 36, 43, 51, 58, 65, 61, 40, 6, -30, -60, -75, -73, -64, -49, -32, -16, -5, -1, -4, -11, -18, -23, -23, -19, -12, -5, 2, 8, 12, 13, 11, 9, 8, 8, 10, 15, 21, 27, 32, 37, 42, 49, 55, 63, 55, 32, -3, -39, -66, -79, -73, -56, -39, -24, -12, -7, -7, -12, -19, -24, -24, -21, -14, -6, 3, 8, 11, 12, 11, 10, 10, 10, 11, 14, 17, 21, 27, 33, 41, 49, 56, 63, 66, 49, 15, -27, -61, -82, -85, -73, -52, -33, -18, -9, -5, -7, -12, -18, -21, -20, -15, -9, -1, 4, 8, 12, 15, 15, 14, 11, 8, 7, 10, 15, 22, 32, 45, 59, 72, 86, 95, 75, 22, -40, -93, -119, -120, -97, -64, -32, -9, 5, 9, 5, -3, -14, -21, -23, -20, -13, -5, 4, 12, 17, 18, 15, 10, 7, 4, 3, 6, 9, 15, 21, 30, 40, 56, 77, 99, 99, 54, -19, -86, -123, -127, -103, -66, -27, 1, 16, 18, 11, -1, -12, -21, -23, -21, -16, -8, 1, 9, 16, 19, 16, 11, 8, 5, 5, 7, 9, 14, 19, 27, 35, 49, 68, 90, 101, 73, 6, -66, -114, -128, -113, -78, -39, -6, 13, 19, 11, -1, 0, 10, 30, 35, 40, 39, 37, 28, 18, 6, -9, -20, -30, -35, -33, -30, -28, -23, -24, -23, -19, -20, -15, -11, -8, -3, 0, 1, 0, -2, -4, -1, 0, 10, 15, 21, 27, 25, 25, 22, 13, 10, -5, -9, -15, -19, -17, -17, -12, -7, 0, 4, 10, 8, 5, -5, -13, -23, -31, -30, -24, -13, 11, 36, 62, 81, 83, 78, 54, 35, 19, -11, -29, -49, -57, -47, -35, -20, -19, -26, -27, -33, -30, -26, -22, -11, -8, 3, 11, 6, 0, -16, -23, -23, -11, 9, 23, 35, 45, 51, 46, 49, 26, 12, -13, -26, -37, -45, -31, -35, -17, -4, 8, 23, 24, 23, 9, -10, -22, -37, -40, -38, -33, -12, 22, 67, 100, 119, 111, 79, 50, 10, -12, -32, -52, -69, -62, -38, -14, -9, -21, -42, -60, -50, -39, -19, -4, -1, 3, 15, 19, 2, -16, -43, -57, -48, -21, 19, 38, 63, 66, 69, 74, 59, 39, 4, -33, -52, -67, -58, -39, -25, 2, 10, 32, 35, 36, 18, -7, -25, -37, -31, -28, -23, -10, 11, 53, 101, 121, 123, 92, 48, 11, -24, -42, -60, -66, -67, -48, -20, 2, -16, -41, -67, -87, -62, -44, -10, 8, 19, 30, 34, 35, 4, -36, -66, -78, -75, -27, 22, 49, 83, 91, 97, 90, 69, 39, -18, -61, -104, -98, -75, -32, 19, 47, 68, 70, 56, 16, -33, -77, -89, -76, -47, 7, 35, 64, 100, 123, 125, 107, 60, 5, -39, -76, -94, -101, -93, -69, -36, -3, 17, 10, -15, -56, -80, -86, -69, -40, -7, 25, 49, 66, 72, 54, 19, -19, -55, -77, -67, -40, 4, 45, 76, 96, 100, 92, 67, 32, -11, -56, -88, -91, -73, -33, 9, 41, 61, 65, 52, 17, -28, -67, -80, -68, -36, 6, 47, 82, 114, 126, 114, 74, 18, -32, -73, -93, -101, -93, -70, -36, -3, 17, 10, -15, 0, -1, -2, -2, 0, 2, 3, 6, 7, 6, 6, 3, 2, -1, -4, -8, -12, -14, -13, -13, -11, -5, -1, 5, 10, 14, 17, 19, 18, 15, 12, 7, 3, 1, -2, -4, -4, -7, -11, -13, -16, -16, -12, -9, -6, -3, -1, -1, -1, -4, -8, -11, -15, -16, -15, -10, -2, 7, 18, 25, 28, 28, 24, 16, 10, 4, -2, -5, -5, -4, -4, -1, 0, 0, 1, 1, 0, -1, -3, -6, -11, -11, -14, -16, -17, -19, -19, -16, -10, -2, 8, 19, 27, 33, 35, 32, 26, 21, 14, 7, 0, -6, -11, -18, -25, -31, -32, -27, -19, -9, 1, 10, 15, 14, 10, 0, -13, -28, -38, -42, -40, -26, -4, 17, 40, 58, 66, 62, 51, 35, 17, 3, -8, -16, -18, -18, -15, -13, -15, -17, -17, -15, -13, -11, -12, -3, -2, 1, -3, -15, -28, -36, -42, -40, -28, -11, 14, 45, 63, 70, 69, 56, 44, 36, 21, 3, -12, -18, -26, -37, -47, -58, -55, -41, -20, 4, 22, 34, 43, 37, 22, -7, -43, -71, -88, -86, -64, -31, 7, 56, 99, 115, 106, 85, 48, 17, 1, -14, -28, -33, -20, -11, -12, -18, -37, -44, -41, -29, -23, -7, 15, 31, 40, 33, 8, -27, -56, -73, -74, -63, -33, 4, 50, 93, 101, 91, 79, 56, 43, 24, 5, -17, -32, -31, -43, -56, -63, -72, -57, -32, 3, 26, 46, 62, 63, 45, 9, -39, -85, -112, -106, -84, -49, 6, 60, 104, 127, 115, 83, 46, 16, -1, -16, -21, -26, -16, -2, -8, -25, -47, -67, -62, -49, -26, 2, 34, 60, 74, 65, 33, -21, -71, -98, -92, -77, -36, 21, 69, 106, 112, 88, 58, 29, 9, -8, -18, -24, -17, -4, -10, -26, -47, -67, -62, -49, -26, 2, 34, 60, 74, 65, 33, 17, 16, -38, 9, 40, -58, 27, 43, -80, 52, -2, -54, 64, -27, -17, 32, 4, -49, 53, -22, -47, 90, -73, 17, 42, -45, 8, 23, -41, -1, 58, -74, 40, 25, -66, 56, -19, -45, 58, -9, -39, 45, 3, -48, 55, -41, -27, 78, -66, 13, 40, -38, 0, 29, -51, 12, 57, -79, 38, 31, -64, 40, -4, -47, 63, -16, -40, 55, -16, -32, 45, -31, -29, 76, -64, 0, 58, -49, 4, 31, -52, 31, 5, -35, 45, -21, 4, -5, 3, -17, -7, 55, -72, 43, 35, -88, 80, -57, 3, 45, -62, 53, -14, -2, -17, 46, -77, 42, 23, -61, 75, -54, 39, -40, 31, -42, 25, 11, -48, 93, -97, 62, -27, -13, 7, 0, 30, -59, 82, -74, 28, 10, -53, 65, -47, 46, -41, 40, -48, 7, 45, -95, 127, -99, 43, -9, -25, 40, -58, 84, -84, 78, -66, 11, 50, -96, 111, -85, 51, -26, -14, 36, -60, 91, -84, 58, -26, -22, 56, -87, 98, -71, 47, -25, -11, 44, -84, 103, -92, 69, -32, -3, 25, -59, 87, -90, 70, -45, 17, 16, -57, 81, -73, 50, -33, 14, 0, -35, 75, -84, 69, -42, 8, 11, -46, 74, -69, 57, -47, 36, -26, -20, 69, -89, 83, -58, 37, -24, -7, 41, -58, 54, -53, 53, -42, 14, 28, -54, 52, -55, 46, -41, 22, 30, -57, 58, -64, 56, -54, 26, 31, -55, 63, -73, 66, -68, 49, -3, -38, 61, -71, 75, -87, 69, -15, -27, 37, -55, 74, -84, 73, -34, -5, 26, -59, 74, -85, 84, -33, -12, 30, -57, 65, -85, 86, -40, 9, 15, -50, 69, -94, 93, -53, 15, 11, -38, 58, -86, 96, -64, 11, 21, -30, 17, -3, -3, 0, 0, -3, -4, -4, -3, -4, -4, -5, -6, -6, -8, -5, -6, -3, 0, 2, 4, 7, 8, 12, 12, 14, 13, 13, 12, 8, 7, 2, 2, -4, -6, -10, -11, -12, -12, -14, -10, -9, -3, -3, 2, 3, 3, 2, 1, 1, -3, -3, -4, -3, -3, -3, -4, 0, -3, -3, -3, 0, -3, 0, -3, 0, 1, 0, 0, 0, 0, 0, -3, 1, -3, 1, -3, 2, 1, 0, 0, -3, -4, -5, -9, -10, -15, -16, -17, -17, -14, -10, -3, 4, 9, 14, 19, 24, 25, 26, 28, 30, 34, 42, 31, 9, -31, -39, -23, -15, -17, -23, -30, -23, -12, -10, 4, 9, 19, 13, 14, 6, 0, -9, -11, -12, -9, -8, 0, 0, 2, 1, 1, -3, -3, -5, -3, -5, -3, -4, 0, -3, -4, -4, -3, -5, -3, -5, -3, 0, 3, 2, 7, 7, 7, 3, 0, -14, -17, -26, -26, -28, -21, -17, -11, -10, 2, 6, 19, 18, 32, 32, 60, 69, 98, 60, 7, -58, -8, -8, -14, -39, -30, -14, -47, -21, -45, -3, 7, 20, 14, 31, 12, 10, -15, -5, -23, -14, -15, -4, -8, 2, 1, 7, -3, 2, -8, -4, -6, -6, -3, 0, -6, -6, -8, -10, -11, -12, -9, -9, -4, -3, 0, 8, 10, 12, 15, 13, 4, -10, -15, -30, -32, -30, -23, -22, -19, -14, -4, 3, 10, 14, 26, 40, 70, 102, 127, 62, -17, -39, 9, -25, -9, -87, -12, -16, 0, -30, -27, -19, -9, 6, 18, 21, 19, 6, 0, -9, -17, -14, -16, -8, -6, 0, 4, 4, -5, -4, -11, -3, -6, 2, 2, 0, -6, 0, -2, -4, -8, -14, -21, -25, -28, -32, -36, -40, -44, -48, -51, -55, -59, -63, -67, -71, -74, -78, -82, -86, -90, -94, -98, -101, -84, -60, -38, -15, 8, 28, 27, 23, 19, 16, 11, 21, 46, 68, 93, 109, 106, 102, 98, 95, 91, 87, 83, 79, 75, 71, 67, 64, 60, 56, 52, 49, 45, 41, 37, 33, 30, 26, 22, 18, 15, 11, 7, 3, -1, -5, -9, -13, -17, -20, -24, -28, -32, -35, -39, -43, -47, -51, -54, -58, -62, -66, -69, -73, -77, -81, -85, -89, -93, -97, -100, -105, -95, -70, -48, -23, -7, -10, -14, -17, -22, -18, 4, 26, 50, 72, 96, 107, 103, 100, 96, 92, 88, 84, 80, 76, 72, 68, 64, 61, 57, 53, 49, 46, 42, 38, 34, 30, 26, 23, 19, 15, 11, 8, 4, 0, -4, -8, -11, -15, -19, -23, -27, -30, -35, -38, -43, -46, -51, -54, -58, -61, -66, -56, -31, -9, 16, 33, 30, 26, 22, 18, 15, 11, 7, 3, -1, -5, -9, -13, -16, -20, -24, -28, -32, -36, -40, -43, -48, -51, -55, -59, -63, -50, -26, -4, 20, 42, 64, 67, 62, 59, 55, 51, 47, 43, 39, 35, 31, 27, 23, 20, 16, 12, 8, 4, 0, -4, -7, -11, -15, -19, -22, -27, -17, 8, 30, 55, 72, 69, 65, 61, 57, 54, 50, 46, 42, 38, 34, 30, 26, 22, 18, 15, 11, 7, 3, 0, -4, -8, -12, -15, -19, -23, -27, -31, -35, -38, -42, -46, -50, -54, -57, -61, -65, -69, -73, -77, -81, -85, -89, -92, -96, -100, -100, -79, -64, -47, -31, -15, 0, 0, -4, -3, -6, -8, 6, 10, -8, -13, 22, 55, 15, -58, -102, -88, -25, 51, 77, 79, 82, 19, -45, -107, -128, -88, 19, 81, 86, 71, 35, -16, -50, -73, -55, -27, -14, 7, 77, 89, 31, -22, -27, -61, -86, -34, 40, 55, 67, 80, 57, -1, -48, -60, -41, -46, -31, 28, 62, 47, 43, 33, -5, -34, -45, -52, -33, 26, 66, 70, 41, 17, -34, -79, -93, -41, -6, 22, 53, 93, 62, 17, -20, -66, -118, -88, -4, 45, 60, 69, 67, 2, -72, -109, -95, -78, -7, 67, 101, 78, 69, 19, -56, -110, -89, -64, -19, 45, 100, 86, 36, -11, -65, -107, -108, -41, 24, 69, 93, 111, 56, -15, -70, -81, -88, -38, 30, 88, 90, 83, 43, -24, -81, -82, -57, -24, 38, 100, 115, 70, 26, -25, -75, -108, -66, -20, 29, 71, 105, 67, 7, -46, -67, -83, -60, 0, 58, 82, 81, 57, -9, -72, -99, -78, -60, -8, 54, 95, 69, 44, 0, -51, -92, -69, -26, 18, 53, 81, 63, 6, -44, -74, -88, -79, -19, 40, 75, 75, 72, 18, -42, -80, -74, -69, -25, 32, 76, 66, 39, 5, -41, -82, -76, -34, 3, 42, 79, 88, 38, -12, -49, -74, -92, -48, 8, 51, 70, 83, 50, -7, -58, -68, -65, -43, 13, 70, 82, 62, 34, -17, -72, -94, -65, -28, 17, 69, 101, 71, 25, -21, -60, -88, -66, -13, 37, 62, 82, 68, 11, -47, -73, -79, -66, -15, 49, 82, 76, 57, 11, -51, -88, -78, -48, -9, 49, 0, 0, 0, 0, 0, 0, -3, -5, -5, -7, -6, -2, 5, 16, 24, 21, 17, 12, 3, -10, -31, -44, -47, -42, -28, -2, 26, 29, 36, 35, 1, -26, -39, -52, -53, -38, -10, -32, -41, -7, 2, 22, 65, 89, 74, 15, -16, -24, 12, 62, 39, 6, -12, -3, 47, 48, 21, 109, 127, 119, 53, -9, 19, 9, -50, -55, -43, -71, -46, -5, -2, -20, -12, -9, 12, -27, -66, -50, -8, -19, -58, -22, -8, -19, -34, -42, 10, 32, -4, 4, 46, 96, 34, -51, -10, -8, -93, -70, -58, -46, -16, -32, -30, 6, 7, -41, -29, 3, 25, 73, 67, 45, 37, 30, 83, 0, -31, -4, -50, -28, -41, -75, -110, -53, -13, -3, 22, 14, 14, 13, 7, 9, 38, 47, 39, 17, -8, 90, 75, -5, -29, -46, -54, -102, -66, -35, -27, -29, -21, 32, 5, 1, 1, -2, 16, 16, 19, 30, 50, 89, 41, 6, 40, -10, -15, -41, -46, -43, -77, -100, -100, -48, -37, -26, -4, -9, 0, 13, 36, 70, 75, 59, 34, 12, -13, -27, 37, 71, 48, 53, 37, 7, 8, 34, 48, 40, 31, 25, 2, -20, -15, -5, 12, -11, -49, -20, 15, -13, -42, -29, 16, -6, -58, -28, 17, 12, -20, -11, 16, -3, -37, -14, 3, -32, -10, 40, 54, 53, 27, -3, -5, -34, -47, -49, -90, -68, -36, -32, -31, -16, 26, 3, 0, -2, -2, 15, 16, 19, 30, 51, 88, 40, 6, 39, -10, 3, -2, 11, -7, 23, 19, 74, 39, 32, -13, -21, -7, -39, -44, -128, -58, -21, 52, -86, -74, -94, 75, 61, 72, -38, 13, 59, 116, 71, -9, -33, -12, 68, -2, -35, -128, -42, -43, 39, -78, -57, -81, 56, 59, 63, -13, 7, 69, 98, 87, -13, -9, -24, 70, -11, -23, -128, -42, -48, 28, -68, -61, -69, 34, 64, 46, 8, -5, 79, 82, 100, -17, 5, -29, 69, -13, -21, -122, -49, -43, 11, -55, -72, -54, 13, 73, 30, 23, -16, 87, 72, 107, -17, 10, -26, 64, -6, -26, -109, -61, -31, -6, -40, -86, -41, -4, 80, 17, 31, -22, 88, 70, 106, -10, 6, -16, 53, 7, -37, -93, -76, -17, -21, -28, -99, -33, -15, 83, 12, 31, -21, 83, 76, 98, 2, -4, -1, 41, 24, -49, -77, -89, -6, -31, -20, -106, -32, -19, 79, 14, 23, -15, 71, 87, 87, 17, -16, 13, 30, 39, -57, -67, -97, -1, -34, -19, -106, -38, -16, 69, 23, 11, -5, 56, 100, 75, 32, -28, 25, 22, 50, -59, -62, -98, -2, -30, -24, -100, -52, -9, 55, 36, -4, 5, 41, 112, 67, 43, -34, 30, 21, 55, -53, -65, -93, -11, -18, -34, -88, -69, 0, 41, 48, -17, 12, 29, 118, 65, 49, -34, 28, 27, 53, -42, -72, -83, -23, -6, -44, -77, -85, 5, -69, 1, -12, -29, -28, -13, 1, 9, -4, -27, -18, -5, 11, 65, 87, 54, 59, 66, 30, 12, 8, -6, -7, 4, -7, -39, -59, -63, -48, -23, -13, -6, 22, 61, 68, 15, -59, -87, -41, 3, 5, -10, -17, -17, -20, -23, -20, -28, -17, -3, -10, -29, 23, 11, 25, 52, 56, 62, 80, 54, 22, -15, -31, -38, -5, 11, -9, -7, -36, -44, -6, 52, 127, 26, -68, -125, -105, 22, 15, -27, -27, 13, 25, 69, 28, -42, -77, -57, -70, 15, 44, 14, 26, 57, 69, 43, 33, 41, 33, 32, 25, -50, -98, -100, -38, 24, 7, -35, -38, -2, 76, 64, 15, -79, -93, -50, -12, 27, 45, 32, -4, 23, 6, -36, -47, -33, -52, -15, 37, 78, 49, 40, 17, 14, 14, 70, 81, 60, -3, -4, -12, -42, -50, -28, -20, 5, 9, 27, 46, -13, -69, -99, -88, -47, 5, -4, -10, 17, 39, -12, -8, -21, -16, 22, 9, -9, 1, 15, 15, 33, 29, 17, 11, 38, 72, 29, -8, -36, -27, -42, 17, -40, 25, 25, 8, -3, 14, 15, 2, 43, 33, -2, -19, -24, -8, 2, -69, -114, -94, -77, -87, 22, 27, 19, 24, 57, 121, 94, 40, -27, -29, 4, 28, -12, 5, -21, -28, -18, 0, -9, 1, 36, 22, 7, 6, 12, 7, 8, 55, 6, -2, -7, -13, -12, -12, -8, -5, -5, -1, -4, -4, -3, -1, 5, 11, 15, 18, 16, 11, 5, -5, -12, -16, -17, -14, -10, -7, -3, -2, -3, -3, -5, -3, 2, 9, 18, 22, 23, 18, 11, -2, -14, -20, -22, -18, -12, -8, -5, -3, -5, -6, -6, -5, 1, 11, 22, 30, 31, 24, 15, -1, -12, -20, -23, -19, -13, -8, -3, -3, -2, -6, -8, -9, -5, 6, 21, 32, 35, 29, 19, 1, -15, -27, -29, -25, -15, -9, -4, -1, -2, -7, -14, -15, -10, 4, 24, 42, 48, 43, 26, 4, -20, -36, -38, -30, -17, -7, -3, 0, -1, -4, -16, -24, -19, -3, 26, 49, 61, 60, 40, 9, -23, -45, -52, -39, -22, -5, -2, 1, 3, -2, -18, -32, -30, -10, 22, 55, 77, 78, 52, 15, -22, -51, -66, -52, -29, -5, 0, 2, 9, 6, -15, -37, -42, -22, 10, 55, 89, 99, 71, 22, -20, -58, -79, -68, -35, -8, 6, 1, 12, 13, -9, -37, -50, -35, 0, 46, 93, 116, 90, 33, -15, -60, -89, -84, -44, -9, 10, 3, 13, 19, -3, -35, -53, -43, -12, 34, 91, 127, 109, 46, -9, -57, -95, -96, -57, -13, 11, 7, 10, 25, 2, -2, -35, 0, 2, 7, 12, -7, -79, -68, 2, -6, -5, 19, 40, 33, 55, 56, 17, 32, 32, 2, -20, 5, 51, 27, -21, -13, -11, -17, -20, -6, -63, -125, -116, -86, -59, -34, 11, 23, 20, 39, 66, 50, 47, 54, 46, 11, -4, 44, 67, 30, 11, 16, 6, -2, 7, -4, -77, -114, -107, -70, -50, -20, 29, 26, 12, 48, 69, 44, 47, 49, 28, -8, 9, 53, 49, 15, 9, 8, -3, -11, 7, -33, -107, -123, -101, -62, -49, -5, 25, 6, 13, 55, 49, 32, 40, 39, 7, -17, 18, 49, 32, 7, 8, 1, -12, -3, 7, -62, -113, -109, -74, -50, -31, 23, 32, 13, 40, 69, 48, 46, 54, 42, 2, 1, 42, 52, 25, 10, 11, 0, -11, 10, -10, -90, -115, -101, -64, -52, -15, 29, 16, 10, 51, 59, 41, 46, 49, 25, -9, 15, 48, 42, 15, 10, 7, -9, -7, 16, -43, -107, -113, -89, -60, -47, 4, 27, 4, 19, 58, 47, 38, 46, 43, 6, -9, 28, 47, 29, 10, 11, 2, -14, 5, 5, -73, -111, -106, -73, -56, -29, 24, 22, 6, 40, 61, 43, 43, 52, 37, -3, 6, 41, 47, 23, 12, 11, 0, -14, 1, 3, 5, 5, 6, 8, 6, 4, 0, -4, -5, -6, -9, -9, -11, -11, -12, -13, -13, -13, -12, -11, -9, -5, -2, -1, 1, 4, 6, 9, 11, 12, 12, 11, 8, 5, 2, -2, -2, -2, -2, 0, -1, -1, -2, -5, -5, -5, -1, 4, 10, 17, 20, 22, 19, 15, 7, -1, -9, -15, -19, -21, -21, -18, -16, -13, -11, -12, -15, -19, -23, -24, -20, -13, -3, 9, 20, 34, 44, 50, 46, 35, 21, 7, -4, -14, -20, -19, -13, -8, 2, 0, -5, -15, -28, -32, -29, -14, 0, 11, 27, 42, 58, 59, 45, 22, 4, -15, -26, -37, -43, -42, -37, -17, 1, 18, 23, 8, -5, -29, -47, -47, -43, -25, -5, 20, 52, 80, 92, 76, 43, 9, -20, -35, -38, -46, -41, -29, -12, 19, 35, 22, 4, -34, -53, -58, -40, -26, -16, 14, 47, 88, 108, 90, 50, 16, -9, -36, -51, -64, -64, -52, -33, -1, 32, 40, 24, 3, -29, -62, -58, -65, -52, -18, 23, 68, 114, 127, 95, 41, 1, -36, -54, -56, -68, -55, -35, -17, 19, 42, 29, 13, -16, -46, -60, -54, -56, -47, -11, 29, 72, 116, 127, 94, 41, -3, 0, 16, 39, 54, 46, 18, 7, -15, -36, -9, -6, -16, -5, -15, -30, -23, -35, -20, 22, 3, -19, -20, -13, -9, 19, 23, 10, 12, 35, 66, 54, 4, -43, -58, -15, -10, 16, 55, 18, -39, -38, -30, 2, 9, 27, 51, -32, -60, -72, -4, 32, 71, 19, -8, 56, -2, -42, 10, 21, -6, 31, -9, -70, 8, -6, -19, -93, -20, -5, -31, 10, 5, 56, 24, -45, 11, 66, 48, 61, 89, 49, -57, -6, -20, -69, -104, -83, -50, 32, 10, -16, -87, -78, 30, 127, 63, -17, -91, -2, -12, 45, 83, 30, 56, 54, 42, 7, 79, -26, -52, -64, -97, 12, -3, -107, -99, -39, 34, 86, 19, -25, 25, 90, -8, -38, 65, 36, 10, 30, 36, 19, -6, 38, -47, -101, -52, -45, 30, -9, -106, 18, -10, -37, 16, 100, -94, -111, -25, -35, -12, -8, -9, 51, 24, -5, -70, -52, -52, -19, -11, 48, 93, 61, 17, 113, 125, 73, -16, -30, -57, -78, -116, -55, -38, -10, -5, -4, 38, 31, -3, -46, -46, -50, -20, -10, 52, 84, 48, 14, 115, 119, 64, -16, -1, 4, 0, -9, -11, -1, 6, 2, -2, 4, -6, -10, -2, 11, 14, 3, -10, -15, -1, 17, 4, 6, 4, -12, -18, 6, 10, 4, 6, -8, -36, 2, 3, 3, 5, 15, -20, -17, 9, 8, 11, 17, -8, -26, 18, 2, 5, 5, 13, -24, -8, -2, 2, 5, 7, -21, -18, 13, 5, -5, 17, 7, -14, -13, -12, 0, 14, 3, -12, -26, 13, 3, 10, 18, 12, -15, -14, -1, 3, 19, 0, -10, -29, 11, 4, 17, 15, 12, -24, -20, 6, 9, 22, -3, -13, -15, 9, 1, 7, 6, 18, -19, -26, -18, 2, 22, 0, -25, -20, 15, 8, -4, 8, 31, -12, -20, -15, 9, 33, 9, -29, -2, 27, 7, -11, 8, 20, -20, -41, -10, 15, 35, 15, -21, 11, 49, 6, -6, 4, 3, -48, -76, -35, 14, 37, 22, -24, 29, 68, 20, 3, 7, -5, -68, -90, -59, 19, 36, 28, -13, 59, 93, 30, 2, 18, -25, -88, -105, -81, 13, 26, 30, -4, 88, 109, 33, 0, 22, -30, -88, -112, -76, 17, 31, 18, 5, 94, 114, 30, -4, 0, 4, -30, -1, 0, -2, -2, -2, -1, 4, 11, 18, 30, 7, -64, -60, -30, -7, 0, 2, 22, 67, 117, 23, -128, -74, -30, -5, -2, 1, 19, 62, 116, 38, -123, -82, -31, -8, -1, -1, 16, 57, 114, 52, -117, -88, -33, -10, -2, -3, 14, 52, 112, 64, -108, -96, -35, -13, -2, -4, 12, 49, 108, 77, -99, -102, -37, -15, -2, -5, 10, 43, 104, 86, -87, -109, -40, -18, -2, -6, 8, 40, 100, 95, -73, -115, -42, -21, -2, -8, 7, 35, 95, 102, -59, -120, -45, -24, -2, -8, 5, 32, 90, 109, -44, -124, -49, -26, -3, -9, 3, 28, 85, 114, -29, -126, -53, -28, -4, -9, 2, 25, 81, 116, -13, -127, -58, -29, -6, -9, 0, 22, 75, 119, 3, -126, -63, -31, -7, -9, -2, 19, 70, 120, 18, -124, -69, -32, -9, -9, -3, 16, 65, 119, 34, -63, -107, -58, -23, -11, -7, 7, 46, 107, 89, -52, -109, -62, -25, -12, -8, 5, 42, 104, 97, -41, -87, -70, -36, -18, -11, 0, 30, 85, 100, -2, -87, -5, 11, -23, -10, -3, -20, -3, -17, -24, -33, -26, -1, -13, -12, -6, -9, 6, 25, 19, -7, -1, 22, -6, -20, 13, 6, -12, 26, 48, 0, -7, 34, 23, 4, 32, 23, -41, -11, 49, -3, -30, 35, 45, -14, -2, 62, 18, -44, -2, 26, -4, -28, -6, 16, 2, -9, -9, 2, 18, 24, 9, -25, -57, -36, 30, 38, -21, -63, -37, 9, 37, 40, 0, -56, -56, 3, 39, 20, -23, -52, -58, -46, 8, 67, 56, -18, -61, -18, 36, 70, 95, 73, -35, -128, -127, -73, -17, 32, 48, 29, 28, 60, 106, 113, 91, 36, -26, -67, -90, -91, -71, -44, -25, -13, 9, 36, 51, 69, 70, 32, -40, -92, -99, -70, -25, 12, 29, 21, 3, -9, 10, 21, 12, -11, -22, -27, -44, -23, 10, 30, 25, 24, 39, 18, 3, 8, 19, -1, -19, -8, 6, 5, 13, 50, 43, 37, 36, 40, 37, 4, 12, -10, -33, -31, -25, -1, 1, 7, 14, 10, -4, -11, -10, -6, -19, -42, -28, -54, -51, -18, -5, 3, 2, -10, -10, 10, 28, 27, 16, 5, -5, -24, -26, -7, -14, -25, -16, 53, 33, -49, -30, 53, 50, -24, -34, 40, 82, -118, -23, 120, -56, -70, -72, 106, -10, -48, 3, 87, 28, -126, -16, 81, 4, -84, -51, 38, 62, -32, 36, 84, -12, -41, 72, -42, -60, -64, 4, 77, -24, -79, -9, 122, 6, -94, 52, 43, 35, 13, -62, -7, -89, 24, -30, 16, 29, 56, -59, 83, 42, 31, 36, -76, -2, -128, -2, 45, 27, -104, -31, 66, 21, 19, 36, 121, 11, -76, -26, -93, 34, 24, -34, -65, -53, 53, 17, 73, 46, 75, -9, -64, -21, -103, 41, 51, -41, -83, -43, 108, 6, -11, 28, 127, 2, -84, -38, -72, 39, 17, -23, -15, -67, 37, 6, 29, 64, 79, 17, -39, -39, -120, 55, 23, -17, -62, -51, 81, 23, 20, 24, 99, -38, -99, 4, 17, -66, -41, -33, 63, 62, 16, 53, 91, 56, -65, -36, -99, -38, 14, -47, -29, -38, 35, 83, 9, 48, 83, 62, -45, -31, -103, -49, 14, 2, 6, -33, 33, -4, -1, 34, -93, 60, -49, 68, -21, 41, -38, -38, 27, -87, 127, -34, 38, -3, -34, -2, -85, 79, -24, 4, 75, -23, 11, -70, 1, -6, -6, 63, -48, 76, -71, 2, -7, -15, 46, -32, 48, -25, -5, 10, -31, 18, -23, 5, 6, 17, 11, 3, 24, -46, -21, -1, -5, 31, 1, 36, -23, -11, -4, -29, 14, -5, 29, 9, -2, -2, -20, -2, -15, 13, 7, 4, 15, -11, 4, -13, -1, 1, -13, 15, -6, 9, 9, -2, -4, -11, -2, -11, 7, 12, 9, 5, -6, -6, -16, -2, 3, 6, 13, 1, 7, -14, -3, -11, -1, 8, 0, 18, -3, -3, -6, -13, 0, 4, 2, 9, 2, 2, -6, -4, -1, -8, 2, 4, 2, 7, -4, 2, 1, -7, -3, -2, 0, 2, 8, -2, 2, -1, -7, -3, -1, 3, 4, 3, 3, -3, -4, -4, 0, 2, 1, 5, -1, -2, 1, -4, -1, 1, 0, 2, -5, -8, -3, -3, -9, -2, -2, 5, 10, 16, 11, 5, -3, -5, -1, -4, -6, -7, -15, -18, -27, -31, -21, -11, 22, 56, 90, 66, -17, -25, -25, 0, -12, -15, -25, -32, -39, -37, -26, 6, 33, 65, 69, 44, -1, -13, -12, 1, 0, -9, -14, -22, -40, -44, -42, -23, 8, 39, 60, 84, 57, -16, -25, -19, 2, -8, -11, -18, -32, -51, -45, -32, -6, 28, 54, 85, 96, -5, -29, -23, -7, -10, -17, -16, -28, -53, -44, -40, -7, 22, 52, 82, 112, 17, -37, -25, -20, -11, -18, -10, -23, -33, -51, -40, -23, 10, 45, 65, 96, 64, -21, -35, -34, -19, -20, -13, -5, -14, -35, -41, -39, -17, 9, 45, 58, 82, 98, -2, -57, -47, -23, -12, -11, -2, -18, -28, -39, -36, -24, -1, 26, 57, 84, 121, 23, -65, -50, -40, -12, -11, -4, -14, -20, -34, -32, -27, -5, 19, 56, 80, 127, 15, -66, -50, -2, -5, -5, 2, 10, 8, -7, -16, -9, 6, 17, 8, -19, -20, 14, 38, 34, 20, -5, 1, 50, 37, -50, -54, -66, -32, 32, -3, -13, -18, -17, 46, 89, -17, -62, 45, 127, 57, -57, -67, -109, -11, 88, -31, -90, -88, -27, 63, 97, -27, -105, -44, 65, 110, 60, -12, -30, -27, 17, 49, -2, -39, -6, 30, -16, -36, -43, 32, 67, -54, -58, -38, -21, 47, 95, 76, -33, -78, -62, 10, 107, 24, -106, -107, 12, 52, 27, 78, 8, -75, 25, 6, -26, 59, 32, -17, -7, -19, 11, 32, -51, -52, 41, -9, -13, 94, 2, -65, 5, -46, -86, 34, 62, 85, 29, -93, -89, -29, 44, 35, -31, -33, -19, 56, 127, 7, -9, -62, -52, 23, 46, 44, -56, -16, -55, -46, 22, 83, -13, -42, -7, 13, 81, 49, 3, -9, -30, -47, -30, 3, 23, 6, -7, -20, -44, 10, 96, -13, 0, 16, 31, 47, 61, 75, 87, 98, 107, 115, 121, 125, 127, 127, 125, 121, 116, 108, 99, 88, 75, 62, 47, 32, 16, 0, -16, -31, -47, -61, -75, -87, -98, -108, -116, -122, -126, -128, -128, -126, -123, -117, -109, -100, -89, -77, -64, -49, -34, -18, -2, 14, 29, 45, 59, 73, 86, 97, 106, 114, 121, 125, 127, 127, 126, 122, 116, 109, 100, 89, 77, 63, 49, 34, 18, 2, -14, -30, -45, -60, -73, -86, -97, -107, -115, -121, -126, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51, -36, -20, -4, 12, 28, 43, 58, 72, 84, 96, 106, 114, 120, 124, 127, 127, 126, 122, 117, 109, 100, 90, 78, 64, 50, 35, 19, 3, -13, -29, -44, -59, -73, -85, -97, -107, -115, -121, -125, -128, -128, -127, -123, -118, -110, -101, -91, -79, -65, -51, -36, -20, -4, 12, 2, 5, 5, 0, -16, -9, -2, -19, 4, 18, 6, 10, -16, -21, 22, -2, 3, -7, 21, 43, -57, -37, 46, -39, -31, 78, 23, -23, -10, -10, -7, -52, 44, 50, -44, 9, -9, -46, 47, 12, -75, 40, 45, 32, -10, -25, -15, -45, 24, 44, -40, -10, 18, -48, -29, 63, 44, -30, -1, 83, -45, -94, 96, 0, -103, 21, 29, -42, 21, 80, -25, -15, 26, 39, -79, -18, 73, -111, -45, 61, 29, 55, -22, -77, 40, 9, -72, 78, 35, -1, -1, -69, 12, -50, -42, 123, 45, -7, -39, -86, 3, 51, 30, 28, -4, -33, -41, -66, 54, -8, -30, 127, -7, -30, -32, -39, 48, -65, 20, 121, -33, -14, -53, -32, 46, -24, 36, 98, -49, -39, -61, 1, 49, -54, 65, 59, -83, -11, -49, 32, 39, -72, 113, 59, -83, -11, -49, 32, 39, -72, 113, 59, -2, -4, -4, -7, -8, -8, -7, -4, -3, -2, 1, 4, 6, 6, 6, 4, 2, 0, -2, -3, -4, -7, -7, -5, -3, 0, 4, 9, 11, 11, 9, 7, 4, 1, -3, -7, -9, -12, -13, -16, -19, -19, -13, -2, 9, 17, 19, 20, 18, 13, 8, 3, 0, -2, -3, -8, -14, -21, -25, -21, -9, 4, 15, 23, 28, 25, 20, 9, -7, -21, -14, 3, 3, -18, -38, -49, -32, -7, 8, 14, 26, 37, 42, 37, 26, 7, -18, -27, -5, 8, -7, -24, -34, -40, -32, -19, 1, 17, 42, 56, 58, 40, -19, -81, 1, 67, 0, -60, -49, -27, -24, 0, -18, -24, -8, 37, 67, 70, 59, 34, -42, -81, 7, 51, -12, -54, -37, -14, -25, -14, -16, -24, 4, 55, 75, 102, 52, -102, -104, 90, 30, -48, -76, 1, -14, 0, -2, -2, -3, -5, -7, -8, -8, -7, -6, -4, -2, 0, 1, 3, 4, 6, 6, 6, 6, 5, 4, 3, 1, 0, 0, -3, -4, -7, -10, -11, -11, -8, -6, 1, 5, 6, 8, 11, 11, 8, 5, 5, 2, 1, 0, 0, -2, 1, -4, -16, -36, -27, -5, 6, -3, -6, 0, -6, 2, 27, 24, 19, 16, 9, 3, 0, -4, 2, 1, 9, 19, -14, -79, -32, 22, -4, -22, -14, 25, 8, -11, 13, 28, 16, 19, 16, 1, -2, -4, -3, -6, 28, 38, -59, -111, 25, 16, -16, -40, 16, 24, -20, 4, 24, 29, 17, 27, 13, 1, -10, -6, -10, -8, 43, 61, -68, -128, 28, 12, -15, -39, 12, 21, -28, 12, 37, 25, 12, 27, 11, 0, -16, -2, -12, -11, 52, 67, -68, 35, 54, 47, 4, -60, -92, -68, -27, 0, -2, -18, -20, -6, 2, -8, -15, -11, -3, 3, -7, -11, -6, -2, 7, 15, 18, 19, 22, 27, 40, 40, 29, 20, 24, 28, 34, 30, 25, 32, 20, 14, 9, 16, 19, 17, 6, -1, 3, -6, -14, -23, -18, -7, 1, -18, -18, -24, -25, -24, -35, -35, -35, -21, -12, -14, -21, -17, -29, -24, -31, -34, -9, -11, -9, -3, -7, -7, 6, -17, -22, 7, 16, 14, -4, -11, 10, 33, 24, 21, 27, 3, -19, -25, -18, 17, 50, 48, 49, 61, 31, -48, -103, -73, 9, 56, 70, 82, 109, 127, 71, -46, -127, -96, -30, -4, 9, 47, 103, 117, 60, -39, -110, -119, -94, -64, -40, -4, 35, -8, -14, -9, -5, -4, -3, 6, 18, 19, 6, -14, -20, -12, -3, -3, -6, 2, 21, 28, 13, -16, -26, -14, -6, -6, -7, 1, 27, 36, 18, -15, -27, -15, -3, -2, -10, -6, 25, 41, 22, -17, -34, -18, -4, -3, -16, -12, 29, 56, 31, -24, -44, -20, -4, -1, -19, -22, 31, 73, 47, -27, -62, -25, -2, 4, -21, -36, 26, 91, 61, -27, -79, -33, 0, 10, -18, -49, 14, 106, 82, -24, -94, -40, 8, 14, -12, -59, 1, 112, 105, -19, -106, -51, 12, 16, -4, -63, -13, 110, 127, -12, -114, -51, 0, -1, -4, -8, -11, -8, -2, 0, 7, 14, 21, 46, 92, 120, 76, -36, -121, -119, -73, -31, -7, 3, 2, -4, -6, 2, 22, 60, 106, 116, 43, -72, -128, -105, -57, -21, -3, 3, -1, -6, -5, 7, 33, 76, 117, 102, 5, -100, -127, -89, -43, -13, 0, 2, -3, -7, -2, 14, 46, 92, 122, 79, -34, -118, -118, -72, -31, -8, 1, 0, -5, -7, 2, 23, 61, 107, 118, 46, -69, -126, -104, -56, -21, -4, 1, 0, -4, -5, 0, 16, 48, 87, 103, 60, -25, -87, -94, -58, -20, -4, -11, 12, 24, 31, -36, 29, -9, 2, -38, -5, -5, -10, -33, -10, -24, -20, -39, -36, -18, -38, -58, -5, -22, -15, -15, 90, -42, -3, -8, 25, 6, 28, 25, 17, 25, -16, 28, 80, 22, 12, -6, 35, 22, 8, -7, 28, 29, -19, 7, 8, -1, -29, -23, 10, -23, -13, -26, -17, -20, -33, -41, -19, -28, -64, -13, -21, -13, -29, 54, 25, -20, -36, 42, -4, 13, 52, -8, 47, -14, 9, 42, 88, -12, 20, -5, 43, 22, -11, 127, 127, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, -128, 1, 4, 7, 10, 12, 16, 19, 22, 25, 28, 31, 35, 38, 42, 45, 49, 51, 56, 58, 63, 65, 70, 73, 78, 80, 85, 87, 93, 95, 100, 102, 108, 109, 117, 114, 127, 85, -63, -60, -64, -60, -62, -59, -61, -59, -61, -58, -60, -58, -59, -58, -58, -57, -57, -55, -55, -54, -54, -52, -51, -50, -49, -47, -46, -44, -43, -41, -40, -37, -36, -34, -32, -30, -28, -25, -24, -21, -19, -16, -14, -11, -9, -6, 1, 1, 4, 7, 10, 12, 16, 19, 22, 25, 28, 31, 35, 38, 42, 45, 49, 51, 56, 58, 63, 65, 70, 73, 78, 80, 85, 87, 93, 95, 100, 102, 108, 109, 117, 114, 127, 85, -63, -60, -64, -60, -62, -59, -61, -59, -61, -58, -60, -58, -59, -58, -58, -57, -57, -55, -55, -54, -54, -52, -51, -50, -49, -47, -46, -44, -43, -41, -40, -37, -36, -34, -32, -30, -28, -25, -24, -21, -19, -16, -14, -11, -9, -6, 1, -3, -19, -24, -14, -8, -19, -12, -10, -5, -12, -50, -19, 23, 35, 4, -20, -7, -26, 9, 40, 69, 16, -88, -69, -38, -32, -27, 41, 65, 55, 18, -40, -38, -20, 66, 127, 121, 57, -23, -55, -48, 13, 53, 31, -20, -38, -13, 10, 8, 0, 12, 17, 13, 2, -1, -3, -3, 6, 13, 7, -17, -24, -12, 4, 3, -10, -20, -32, -22, -18, -12, -3, 6, 16, 22, 29, 30, 27, 20, 11, 0, -7, -12, -11, -5, 0, -3, -14, -20, -16, -9, -9, -17, -25, -29, -31, -33, -35, -33, -29, -25, -22, -20, -17, -14, -13, -12, -11, -9, -10, -13, -15, -11, -5, 3, 9, 10, 9, 9, 12, 18, 30, 50, 80, 119, 127, 102, 82, 77, 60, 37, 5, -34, -70, -84, -83, -74, -60, -46, -29, -12, -2, 6, -23, 28, -20, 50, 50, -14, 14, -28, -2, 28, 52, -25, -13, -52, 43, -41, -9, -26, 36, -25, -20, -17, 3, -11, 38, 30, -61, 12, -6, 5, 45, 41, -4, 4, -20, -12, 45, 33, -11, -29, -44, 27, -17, -36, -1, 17, -11, -31, -12, 4, -10, 37, 20, -39, -23, 0, -104, -55, -11, 24, 33, 30, 7, -15, -31, -30, -25, -23, -20, -9, 10, 31, 59, 91, 111, 115, 92, 51, 7, -33, -64, -81, -81, -71, -51, -22, 16, 52, 74, 82, 81, 68, 38, 0, -40, -81, -112, -124, -102, -57, -11, 0, 7, -23, -58, -85, -100, -104, -100, -92, -81, -69, -57, -45, -33, -22, -11, -1, 8, 18, 27, 37, 49, 62, 79, 99, 118, 124, 111, 84, 53, 26, 5, -8, -14, -15, -12, -6, 2, 12, 21, 28, 26, 9, -22, -58, -20, 7, 10, 21, -14, 9, 22, 57, 62, 127, 56, 28, 26, -28, 10, -81, -31, -81, -35, -19, -55, -27, -4, -4, 23, 49, 88, 85, 22, 1, 0, -3, 18, -22, -12, -39, -14, -47, -67, -53, -53, -33, -20, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83, 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35, 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83, 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35, 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, 8, -22, 25, 30, 6, -19, -62, -19, 10, 83, 57, -67, -88, -52, 63, 127, 42, -63, -121, -70, 82, 111, 46, -43, -114, -35, 45, 73, 39, -19, -54, -41, 9, 49, 24, -16, -14, -9, -6, 10, -18, -15, 80, 127, 20, 18, 72, 60, -36, 22, 33, -73, -105, -27, 29, 25, 8, 43, 23, -22, -35, -14, -8, -34, -25, -5, -18, -46, -13, -28, -3, -19, -10, -28, -10, 17, -18, 96, 127, 123, 127, 126, 126, 95, 61, 22, -17, -56, -95, -118, -123, -128, -128, -128, -128, -128, -128, -128, -128, -124, -93, -55, -17, 25, 62, 100, 107, 119, 119, 127, 41, -4, -4, -10, -27, -62, -102, -128, -117, -85, -76, -49, -25, -7, 15, 24, 14, 0, -9, -12, -3, 33, 81, 105, 111, 101, 80, 62, 45, 30, 16, 8, 1, -4, 126, 86, -44, -68, -88, -63, 4, 84, 127, 14, -29, -51, -127, -47, 58, 87, 82, 24, -17, -112, -113, 18, 46, 72, 102, 19, -72, -118, -51, 9, 27, 126, 19, -53, -114, -108, 15, 122, 111, 21, -71, -70, 5, 59, 83, 23, -72, -84, -49, 12, 37, 38, -28, -65, -26, 7, -2, 11, 5, 23, 68, 19, 27, -54, 15, -24, -31, 46, 71, 81, -24, -33, -87, -41, -71, -61, -70, -36, -44, -3, 12, -25, -20, 20, 68, 85, 127, 15, 50, -5, 27, 51, 82, 106, 127, 118, 101, 92, 74, 52, 39, 37, 14, -41, -105, -108, -94, -119, -124, -93, -57, -40, -37, -45, -51, -41, -5, 51, 127, 127, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127 }; /* NOTE: update eas_samples when this array is changed */ const EAS_U32 eas_sampleLengths[] = { 16820, 16708, 16592, 11754, 10954, 10295, 9922, 7489, 5779, 5462, 4452, 3779, 3115, 3093, 3057, 3024, 2818, 2776, 2171, 2168, 2052, 1902, 1835, 1614, 1603, 1528, 1517, 1480, 1455, 1424, 1387, 1302, 1262, 1254, 1230, 1227, 1185, 1181, 1178, 1168, 1132, 1120, 1034, 1033, 1018, 994, 964, 926, 907, 886, 881, 866, 830, 817, 816, 813, 749, 748, 739, 720, 652, 610, 610, 583, 564, 561, 556, 549, 542, 535, 530, 530, 516, 508, 492, 478, 461, 448, 437, 431, 423, 418, 403, 402, 400, 394, 387, 387, 367, 357, 347, 347, 341, 336, 334, 329, 325, 312, 294, 284, 277, 265, 255, 233, 230, 213, 207, 205, 194, 193, 184, 181, 181, 167, 164, 158, 152, 152, 145, 139, 128, 103, 100, 88, 87, 84, 84, 72, 71, 55, 46, 45, 43, 40, 40, 40, 37, 35, 32, 32, 30, 29, 27, 23, 22, 21, 21, 21, 21, 20 }; /* NOTE: update eas_samples when this array is changed */ const EAS_U32 eas_sampleOffsets[] = { 0x00000000, 0x000041b4, 0x000082f8, 0x0000c3c8, 0x0000f1b2, 0x00011c7c, 0x000144b3, 0x00016b75, 0x000188b6, 0x00019f49, 0x0001b49f, 0x0001c603, 0x0001d4c6, 0x0001e0f1, 0x0001ed06, 0x0001f8f7, 0x000204c7, 0x00020fc9, 0x00021aa1, 0x0002231c, 0x00022b94, 0x00023398, 0x00023b06, 0x00024231, 0x0002487f, 0x00024ec2, 0x000254ba, 0x00025aa7, 0x0002606f, 0x0002661e, 0x00026bae, 0x00027119, 0x0002762f, 0x00027b1d, 0x00028003, 0x000284d1, 0x0002899c, 0x00028e3d, 0x000292da, 0x00029774, 0x00029c04, 0x0002a070, 0x0002a4d0, 0x0002a8da, 0x0002ace3, 0x0002b0dd, 0x0002b4bf, 0x0002b883, 0x0002bc21, 0x0002bfac, 0x0002c322, 0x0002c693, 0x0002c9f5, 0x0002cd33, 0x0002d064, 0x0002d394, 0x0002d6c1, 0x0002d9ae, 0x0002dc9a, 0x0002df7d, 0x0002e24d, 0x0002e4d9, 0x0002e73b, 0x0002e99d, 0x0002ebe4, 0x0002ee18, 0x0002f049, 0x0002f275, 0x0002f49a, 0x0002f6b8, 0x0002f8cf, 0x0002fae1, 0x0002fcf3, 0x0002fef7, 0x000300f3, 0x000302df, 0x000304bd, 0x0003068a, 0x0003084a, 0x000309ff, 0x00030bae, 0x00030d55, 0x00030ef7, 0x0003108a, 0x0003121c, 0x000313ac, 0x00031536, 0x000316b9, 0x0003183c, 0x000319ab, 0x00031b10, 0x00031c6b, 0x00031dc6, 0x00031f1b, 0x0003206b, 0x000321b9, 0x00032302, 0x00032447, 0x0003257f, 0x000326a5, 0x000327c1, 0x000328d6, 0x000329df, 0x00032ade, 0x00032bc7, 0x00032cad, 0x00032d82, 0x00032e51, 0x00032f1e, 0x00032fe0, 0x000330a1, 0x00033159, 0x0003320e, 0x000332c3, 0x0003336a, 0x0003340e, 0x000334ac, 0x00033544, 0x000335dc, 0x0003366d, 0x000336f8, 0x00033778, 0x000337df, 0x00033843, 0x0003389b, 0x000338f2, 0x00033946, 0x0003399a, 0x000339e2, 0x00033a29, 0x00033a60, 0x00033a8e, 0x00033abb, 0x00033ae6, 0x00033b0e, 0x00033b36, 0x00033b5e, 0x00033b83, 0x00033ba6, 0x00033bc6, 0x00033be6, 0x00033c04, 0x00033c21, 0x00033c3c, 0x00033c53, 0x00033c69, 0x00033c7e, 0x00033c93, 0x00033ca8, 0x00033cbd }; #else //_16_BIT_SAMPLES /* NOTE: this array should have size of at least eas_sampleOffsets[last_element] + eas_sampleLengths[last_element] */ const EAS_SAMPLE eas_samples[0x00033cbd + 20] = { 0, 0, -768, -1024, -1536, -2048, -2560, -3072, -3072, -2816, -2048, -768, 768, 1792, 2560, 3584, 4096, 4096, 3840, 3072, 2304, 1024, -1024, -3072, -4608, -5376, -5376, -4864, -4608, -3840, -2560, -768, 2560, 5120, 8704, 11264, 13056, 13312, 12288, 11008, 9728, 6656, 2048, -3840, -9472, -13312, -15616, -16384, -16896, -16384, -15104, -12032, -7936, -3328, 1024, 4608, 7680, 9472, 10240, 9216, 7680, 6144, 4864, 2816, -512, -4352, -6144, -7168, -7168, -5376, -4608, -4096, -2560, -768, 3072, 6912, 9984, 12544, 13568, 13568, 12800, 11008, 9472, 6400, 2816, -2816, -7936, -11776, -14592, -16128, -16896, -16128, -14592, -11776, -8704, -4864, -768, 3328, 6912, 8960, 9984, 9472, 8192, 6656, 5120, 2816, 0, -3328, -5120, -6144, -6400, -5376, -4864, -3584, -2048, -512, 2304, 5888, 9472, 12032, 13568, 13312, 12544, 10752, 8960, 6400, 3328, -1536, -7168, -12288, -15360, -17152, -17152, -16384, -15360, -13056, -9984, -5888, -1792, 2560, 5888, 8960, 9984, 9728, 8192, 6656, 5376, 3840, 1024, -2304, -5120, -5632, -5376, -4864, -3584, -2816, -1280, 256, 2304, 4864, 7936, 11520, 13056, 13312, 12032, 9984, 8960, 6400, 3840, -768, -5888, -10752, -14848, -17920, -18176, -16896, -15360, -13056, -11008, -7680, -3328, 1536, 5632, 8192, 10240, 10240, 9728, 8448, 6912, 4864, 2304, -1280, -4352, -6400, -6656, -5632, -4096, -2816, -2048, -1024, 1792, 5376, 8960, 12288, 13568, 14336, 12800, 11008, 8704, 5632, 3328, -512, -5632, -11264, -16128, -19200, -19456, -17664, -15616, -13056, -11008, -7424, -3328, 1536, 5888, 8192, 10496, 11008, 10496, 9472, 6656, 4608, 1792, -2048, -4864, -6400, -6400, -5632, -3840, -2304, -1280, 0, 2560, 6144, 9472, 11264, 12288, 13312, 13312, 11776, 8448, 5120, 2048, -1280, -5120, -9728, -15104, -18944, -20224, -18688, -17152, -14080, -11008, -6656, -2816, 1024, 4608, 7424, 10496, 11520, 11520, 9728, 7424, 5376, 2816, -768, -3840, -6400, -6912, -5632, -4096, -2816, -2048, 0, 2560, 6400, 9728, 11264, 12032, 12800, 13568, 12544, 9472, 5120, 1792, -1280, -4352, -8704, -14848, -18944, -20992, -19456, -17152, -15104, -12032, -7424, -3072, 768, 3584, 6400, 9728, 12800, 13312, 11776, 8448, 5888, 3584, 768, -2816, -6400, -7168, -6912, -5376, -4096, -3328, -1792, 2048, 6912, 10496, 11264, 11520, 12032, 13824, 14080, 11264, 6400, 1792, -1792, -4608, -8192, -13568, -18176, -20736, -20736, -18432, -17152, -14080, -9472, -4096, 768, 3840, 5888, 8704, 12288, 14592, 14336, 11264, 7680, 4864, 1280, -3072, -6656, -8448, -7936, -6400, -4864, -4096, -2816, 1792, 6400, 11520, 12544, 12544, 13312, 14592, 15104, 12288, 8192, 2816, -1280, -5632, -9984, -14336, -18688, -20992, -22528, -21504, -19200, -15360, -9728, -4096, 1280, 5376, 7680, 9984, 13312, 15104, 15616, 13568, 9472, 5632, 1792, -3072, -7168, -8960, -9216, -7680, -5632, -4864, -4096, -512, 5376, 10496, 13312, 13056, 13312, 14592, 15872, 13824, 10240, 4608, -512, -4608, -9216, -13824, -17920, -20480, -22016, -22272, -20736, -17664, -12288, -5888, 0, 4608, 7168, 8960, 11520, 14592, 16384, 15104, 11776, 6912, 2304, -2816, -6144, -7680, -8192, -7424, -6400, -5120, -4096, -1280, 3840, 9216, 12032, 12800, 12544, 13568, 14592, 13824, 11008, 6144, 1280, -3584, -8192, -12800, -16640, -19200, -20992, -22016, -22016, -19712, -14848, -8192, -2048, 3584, 6400, 7680, 10496, 14336, 17664, 17664, 14592, 9216, 4352, -1024, -5120, -7424, -8192, -6912, -7168, -6912, -5888, -3328, 2560, 8448, 11776, 12800, 12288, 12800, 13824, 14080, 12288, 8704, 4096, -1536, -7424, -12800, -17408, -19200, -19968, -20992, -22016, -21504, -18432, -12032, -4096, 2816, 7168, 8704, 10496, 13056, 16384, 17920, 16384, 12544, 6912, 1280, -4352, -7680, -8448, -7424, -7424, -7680, -7680, -5632, -512, 5888, 10496, 12544, 13056, 13056, 13824, 14336, 12800, 10752, 6400, 1024, -5120, -11264, -15872, -17920, -19456, -21248, -22272, -22784, -19968, -14336, -7424, 0, 4864, 7936, 9728, 12288, 16128, 18432, 18176, 15360, 10240, 3584, -3072, -6400, -7424, -6656, -6912, -8448, -9472, -7680, -3072, 2816, 7936, 10496, 12288, 13056, 13568, 14080, 14080, 13056, 9984, 4352, -3072, -9728, -14848, -17152, -18944, -20992, -23552, -25088, -22784, -17664, -10496, -3328, 2560, 7424, 10496, 12800, 16384, 18432, 19968, 18944, 14592, 7424, 0, -4608, -6656, -7168, -8192, -9728, -10752, -9728, -5888, -768, 4608, 7680, 10752, 13312, 14848, 15360, 15616, 14592, 12288, 7168, 512, -7680, -13056, -15872, -17920, -20736, -24064, -25856, -23808, -19200, -12544, -5888, -512, 4608, 9216, 12800, 15616, 17664, 19712, 19968, 16896, 10752, 2816, -2816, -5632, -6912, -8192, -9984, -11776, -11776, -9216, -3584, 2048, 6400, 10496, 13312, 15104, 15872, 16128, 15872, 14592, 9728, 2816, -5120, -12032, -15616, -17664, -19968, -22784, -25088, -24064, -20480, -15360, -9472, -3072, 3328, 8448, 12288, 15872, 17920, 19968, 20736, 18432, 13312, 5888, 0, -3584, -6144, -8448, -11008, -12544, -12544, -9984, -5888, -512, 3840, 8448, 12032, 14592, 16128, 15872, 15872, 14592, 10240, 5120, -1792, -8704, -13312, -16640, -18944, -21248, -24064, -23552, -20736, -16128, -10752, -5632, 0, 5376, 9984, 13824, 16128, 18688, 20224, 19456, 15616, 9472, 3072, -1280, -4864, -7168, -9472, -11776, -13056, -12032, -8192, -3328, 1792, 6400, 11008, 13824, 14848, 15360, 15360, 15616, 12288, 6912, 768, -6400, -11520, -15360, -18432, -20736, -23040, -23552, -21504, -18176, -13312, -8192, -2304, 3584, 8448, 12800, 15616, 18944, 20480, 19968, 17152, 12032, 6144, 1536, -3072, -6656, -9472, -12800, -14336, -13312, -9472, -4864, -512, 4096, 8960, 13312, 15616, 16128, 15616, 15104, 13056, 8960, 3072, -3840, -9728, -14080, -16896, -19712, -21248, -21248, -20480, -17408, -14080, -9984, -4864, 1024, 6400, 10496, 13824, 16896, 18688, 19200, 17408, 13312, 7936, 2816, -1792, -5632, -8448, -11776, -13824, -13056, -9984, -6144, -1280, 3072, 8192, 12288, 14336, 15360, 15616, 14848, 12800, 9216, 4352, -2048, -7680, -11776, -16128, -18944, -20480, -20480, -18944, -17664, -14848, -11008, -6912, -1280, 3840, 7936, 12288, 15360, 17408, 18432, 17408, 14592, 9984, 5120, 512, -4096, -7680, -11264, -13056, -12800, -10496, -6912, -2560, 2304, 7168, 11008, 13568, 14592, 14592, 13824, 12288, 9472, 4864, -768, -6400, -10496, -14336, -17664, -19200, -18688, -17664, -16128, -15104, -12544, -8192, -3328, 2304, 6400, 9472, 12288, 14848, 16896, 16640, 14848, 10752, 6400, 2048, -2304, -5632, -9216, -10496, -11008, -9472, -6656, -3584, 1024, 5376, 9472, 12288, 13312, 13568, 12032, 10752, 8704, 5376, 768, -4608, -9984, -13056, -16384, -17152, -15872, -15360, -15360, -14848, -12800, -9216, -4096, 768, 4352, 7424, 10496, 12544, 14848, 15616, 15360, 12544, 7424, 2816, -1792, -4864, -7168, -8192, -8448, -7680, -6400, -3584, 512, 4864, 8448, 10496, 11520, 10752, 9728, 9216, 7424, 5120, 1536, -3584, -7168, -11008, -13824, -14848, -14080, -12800, -13056, -13824, -13056, -10496, -5632, -1024, 2816, 4864, 7680, 9472, 12032, 14080, 14336, 13056, 8704, 4096, 0, -3840, -4864, -5888, -5632, -5632, -5376, -3584, 0, 3840, 7424, 9984, 11008, 9472, 7936, 6400, 5376, 4608, 1536, -2816, -7168, -10752, -12800, -13056, -12288, -11264, -10496, -11264, -11008, -10496, -6400, -2048, 2304, 4096, 5632, 6656, 8960, 11008, 12800, 12288, 8448, 4096, -768, -3328, -4096, -4096, -3840, -3328, -2816, -1536, 1280, 4096, 7168, 9728, 10496, 8960, 6144, 3840, 3072, 2560, 1024, -2816, -6912, -9984, -11776, -11776, -11520, -10240, -9216, -9216, -9472, -9728, -7424, -3328, 1536, 4096, 4864, 5632, 6912, 9472, 11008, 10752, 8192, 4864, 512, -2560, -3328, -3072, -1792, -1024, -512, 512, 2560, 4608, 6912, 9216, 9728, 8192, 5120, 2304, 1024, -512, -1024, -2816, -5888, -8704, -10752, -10752, -9728, -7936, -7168, -7424, -8192, -8448, -7680, -4608, 0, 2560, 3072, 3072, 4352, 6656, 8960, 9216, 7936, 4864, 1280, -1536, -2816, -2304, -512, 1792, 3584, 3328, 3328, 4096, 5888, 7936, 8704, 7424, 3840, -768, -2048, -2560, -2560, -3584, -5120, -6656, -7680, -8192, -7680, -6400, -4608, -4352, -6144, -7936, -8192, -6656, -2816, 512, 1792, 2048, 2304, 4352, 6400, 7424, 7168, 5376, 2304, -512, -1792, -1280, 1024, 3072, 5376, 6144, 5888, 6400, 6656, 7424, 7936, 6912, 3840, -512, -3840, -5376, -5888, -5888, -5888, -7168, -7680, -7936, -6912, -4864, -2560, -2304, -3328, -5376, -5632, -5120, -2816, -1024, -768, -1280, -512, 1280, 3328, 4352, 4352, 4096, 2560, 1536, 0, 768, 2816, 5888, 8192, 8448, 7680, 7168, 6912, 6144, 6144, 4864, 2304, -1536, -4864, -7424, -7424, -6656, -5120, -4864, -5632, -6144, -5888, -4096, -2560, -2304, -3584, -5120, -6144, -5376, -4096, -2560, -1536, -1280, 256, 1280, 2816, 3072, 3328, 2816, 2048, 1536, 256, 1024, 2304, 5888, 8448, 9984, 9216, 8192, 8192, 7168, 5632, 4352, 1792, -1792, -5632, -7936, -8448, -7936, -6144, -4864, -4608, -4608, -4096, -3328, -1792, -1536, -2048, -3584, -5376, -6144, -5120, -3840, -3072, -2304, -1536, 0, 1024, 1536, 2048, 2048, 1280, 1280, 512, 1792, 3840, 6912, 9472, 10752, 11520, 10496, 9984, 8192, 5632, 3328, 768, -2816, -6656, -9472, -10496, -9472, -7424, -5376, -4608, -3840, -2816, -1536, -512, -512, -1024, -1792, -3328, -4096, -5120, -5376, -4096, -3584, -2560, -1536, -768, -768, 0, 768, 512, 768, 768, 2304, 4608, 8192, 10496, 11776, 12544, 11264, 11008, 8960, 6144, 3072, 256, -3584, -6912, -9984, -10240, -9216, -7936, -5632, -4096, -3328, -1536, -768, -768, -1024, -2304, -2304, -3328, -4096, -5120, -5376, -4096, -3840, -2816, -1536, -1024, -1024, -1280, -1280, -768, -768, 0, 2560, 4864, 8448, 11264, 13056, 14336, 13312, 12800, 10240, 5888, 2816, -1536, -4864, -7680, -10240, -11008, -10240, -8960, -6144, -4096, -1792, 512, 1536, 1280, 256, -1536, -2304, -2304, -2304, -3072, -4864, -5376, -5376, -4352, -2304, -1792, -2304, -2816, -3840, -3584, -2304, -1792, 1792, 4864, 9216, 13056, 14592, 15616, 15104, 14336, 12288, 8448, 3328, -2048, -6144, -8960, -11520, -13056, -11776, -9728, -6656, -3584, -1792, 768, 2816, 3840, 3072, 768, -1280, -1792, -1536, -2304, -3840, -5632, -6400, -5888, -4352, -3328, -3072, -4096, -4864, -5376, -4608, -3072, 768, 5376, 9728, 12800, 14848, 17152, 16640, 16384, 14080, 10496, 5376, -1024, -6400, -9728, -11776, -12800, -12544, -11008, -8448, -5888, -2816, 768, 3584, 4864, 4096, 2048, 0, -512, -512, 0, -2048, -4864, -6912, -7680, -6400, -5632, -5120, -5120, -5632, -6400, -6144, -4096, 256, 5632, 11008, 14336, 15872, 17152, 17408, 16640, 15360, 11776, 6144, -768, -6400, -10240, -11520, -12544, -12800, -11776, -9472, -5888, -2560, 256, 3072, 5120, 5120, 3584, 1792, 512, 768, 768, -1024, -3840, -6656, -7936, -7680, -6912, -6656, -6656, -7424, -8448, -8448, -6400, -2048, 4352, 10496, 14592, 16640, 18176, 18688, 18688, 16896, 13568, 8448, 1280, -5888, -10496, -12288, -12800, -12288, -12288, -10240, -7680, -3584, 256, 3072, 5376, 6144, 4608, 3328, 1536, 1280, 1280, 0, -2816, -6400, -9472, -9984, -8960, -7936, -7936, -8448, -9728, -9472, -7424, -3072, 3840, 10240, 15104, 17152, 18176, 18432, 18688, 17664, 15104, 9984, 3584, -4096, -9728, -12800, -13056, -12800, -12288, -11520, -9216, -5376, -1024, 3072, 6400, 7680, 6400, 4608, 2816, 2816, 2560, 1536, -2048, -6400, -9984, -11776, -10752, -9728, -9472, -9472, -10240, -10752, -8704, -3840, 3328, 10240, 14592, 16896, 18176, 18432, 18432, 17664, 15616, 11520, 4864, -2560, -8704, -11776, -12288, -12032, -11520, -11520, -10496, -7168, -3072, 1792, 5888, 6912, 6400, 4608, 3840, 4352, 4352, 3072, 256, -5120, -9472, -12032, -12800, -11776, -11520, -11264, -11520, -11776, -10496, -5376, 1792, 9472, 15360, 17664, 18688, 18432, 18432, 18432, 17152, 13312, 6400, -1536, -8448, -12032, -12800, -12032, -12032, -12032, -11520, -8960, -4096, 1536, 5888, 7936, 7680, 6144, 5888, 6144, 6400, 4608, 1024, -3840, -8448, -12800, -14336, -14592, -13568, -12288, -12544, -12544, -11520, -7424, 512, 8960, 14848, 17408, 18176, 18432, 18944, 18688, 17408, 14336, 8704, 1280, -6656, -11008, -12288, -11520, -10752, -11776, -11776, -10496, -6144, 0, 5376, 8448, 8704, 7936, 6400, 6912, 6912, 4864, 1536, -3584, -9216, -14080, -16384, -16384, -15360, -12800, -12032, -11520, -11264, -7936, -1024, 8192, 14848, 18176, 18432, 17408, 17920, 17920, 16896, 14592, 9216, 2816, -5120, -11008, -12800, -12288, -10496, -9472, -10752, -10240, -7168, -1280, 5376, 9216, 9728, 8704, 6656, 7424, 7168, 5120, 2048, -3328, -8448, -13312, -17408, -17664, -16640, -14080, -12544, -12032, -11264, -7936, -768, 7680, 14080, 17152, 17920, 17408, 17920, 17920, 16640, 14592, 9984, 3840, -3328, -9728, -12544, -12032, -10240, -8960, -9984, -10496, -7680, -2304, 4352, 9472, 11264, 11520, 9728, 8192, 7424, 5632, 2304, -2560, -8704, -13824, -17920, -19200, -18688, -16384, -13312, -11520, -11008, -7936, -1792, 6400, 13568, 17152, 18432, 17920, 18432, 17920, 15872, 13568, 9728, 4096, -2560, -8192, -12544, -12800, -11008, -8960, -8448, -9216, -7424, -2560, 4096, 8960, 11776, 11776, 10496, 8960, 7680, 5888, 2560, -2560, -8704, -13568, -17664, -19200, -18944, -16896, -13568, -11520, -10752, -8704, -3328, 4352, 11776, 16128, 17408, 16896, 16128, 16640, 16128, 13824, 11008, 6144, 0, -5120, -10240, -11008, -10752, -9216, -8192, -8192, -7168, -4096, 1792, 7424, 12032, 13312, 12032, 9984, 7936, 5376, 2560, -2304, -7680, -12800, -16896, -19968, -19712, -18176, -15104, -12544, -10752, -8704, -4352, 2304, 9472, 14336, 16896, 16896, 15872, 15872, 15616, 14336, 11520, 7680, 1792, -3328, -7936, -9984, -10240, -9216, -8448, -8192, -7168, -4608, 256, 5376, 10496, 13824, 13312, 11264, 9216, 6656, 3328, -2048, -7424, -12288, -16896, -19456, -20480, -18944, -16384, -14080, -11520, -8704, -4608, 1280, 7424, 12800, 16640, 17408, 16896, 16384, 15360, 15104, 12032, 8448, 3840, -1280, -5888, -9472, -11008, -10496, -9472, -8960, -7936, -5376, -1024, 4096, 9216, 13312, 15104, 13824, 11520, 8448, 4352, -1280, -6400, -11520, -15360, -18944, -21248, -20992, -18176, -15104, -12544, -9472, -5888, -512, 5632, 11008, 15104, 16896, 16640, 16384, 15360, 14848, 12800, 9984, 5888, 512, -4352, -8192, -9984, -10240, -9728, -8960, -8192, -5888, -1536, 3584, 8448, 12544, 15104, 14848, 12544, 8704, 4096, -1280, -6400, -11008, -15360, -18944, -21248, -21248, -19456, -16128, -13568, -10240, -6144, -1280, 4096, 9216, 13824, 16640, 17152, 16640, 15616, 14592, 13312, 11008, 6912, 2304, -3072, -6656, -9472, -10240, -9984, -9216, -8192, -7168, -3328, 1536, 6912, 11776, 14848, 15360, 13312, 9984, 5888, 1280, -4096, -9216, -13568, -16896, -19712, -21504, -20736, -18432, -15360, -11520, -8192, -3840, 1280, 6400, 12288, 15872, 17664, 18176, 17664, 16640, 14848, 12800, 8704, 4096, -1536, -6144, -9216, -10752, -11520, -11264, -9984, -8448, -5376, -512, 5632, 11008, 15104, 16384, 15360, 12032, 8704, 4352, -1536, -7168, -12800, -16896, -19456, -21504, -22016, -20992, -18432, -14592, -10240, -5376, -512, 5376, 10752, 14848, 16896, 18688, 19456, 18176, 16384, 13568, 10240, 6656, 1024, -4352, -8704, -11520, -12544, -12288, -11008, -9728, -7168, -2560, 3840, 10240, 14848, 16896, 16384, 14336, 10752, 6400, 1024, -5376, -11264, -15872, -18688, -20736, -22272, -22016, -19968, -16640, -12032, -7936, -2304, 3840, 8704, 13312, 15872, 18432, 20224, 20480, 18432, 15616, 12544, 8704, 3072, -3072, -8192, -11008, -12544, -13824, -14080, -12288, -9216, -4096, 2560, 8960, 14336, 17152, 18176, 17152, 13824, 9728, 3840, -2560, -8704, -14592, -18432, -21760, -23808, -24832, -22784, -19456, -15104, -10240, -5120, 2048, 8192, 12800, 17152, 19712, 22272, 22784, 20736, 16896, 13312, 8960, 4096, -1536, -7680, -12032, -14848, -15616, -14592, -12800, -9472, -4864, 1536, 7424, 13056, 16640, 18688, 18688, 15872, 11264, 4608, -1536, -7168, -12544, -17152, -20736, -23808, -24832, -24064, -21248, -16640, -12032, -7168, -1280, 4864, 10752, 15616, 19456, 22272, 23040, 22528, 20480, 16896, 12288, 6912, 768, -4352, -10240, -14336, -16640, -16896, -14848, -12544, -7680, -1536, 4352, 10496, 15104, 18176, 19712, 17920, 14336, 9216, 2816, -3328, -8704, -13568, -18176, -22784, -25088, -25600, -24064, -20224, -15872, -11264, -5376, 768, 6912, 13312, 18944, 23040, 25088, 24320, 22016, 19200, 15104, 9472, 3072, -3584, -8960, -13824, -16384, -17152, -16384, -13056, -8704, -2560, 2816, 8192, 12800, 16640, 18688, 18176, 14848, 9472, 3584, -2560, -7424, -12288, -16384, -20736, -23808, -25088, -24064, -20992, -16128, -11520, -6656, -1280, 4096, 10240, 16640, 21248, 24064, 24064, 21504, 19200, 16128, 11776, 5888, -768, -6912, -12032, -14848, -16384, -16384, -14336, -9984, -4352, 768, 5120, 9728, 14592, 18176, 18432, 15616, 11520, 6144, 256, -4864, -9472, -14336, -18688, -23296, -25344, -25600, -23552, -18944, -13568, -8704, -4096, 1792, 7936, 15104, 20992, 24832, 25856, 23552, 19968, 16640, 12288, 7424, 1536, -5376, -11008, -14080, -16384, -16896, -14848, -10240, -4608, 768, 4352, 8192, 13056, 17664, 18176, 15872, 11520, 6912, 1536, -3840, -8704, -12800, -16384, -20736, -23808, -25344, -24576, -20480, -15104, -10240, -5888, -1024, 5376, 12800, 19712, 24064, 25600, 23808, 20736, 17152, 13568, 9216, 3584, -3072, -9216, -13568, -14848, -16128, -14336, -10752, -5632, -1280, 2560, 5888, 10752, 16128, 17920, 15872, 12032, 7424, 3328, -1536, -6912, -11008, -14592, -18432, -21504, -25088, -25344, -22272, -16896, -11264, -6912, -2816, 2560, 9728, 17152, 23296, 25344, 23552, 20992, 17920, 14592, 10496, 5376, -768, -6912, -12032, -14848, -16128, -14848, -11264, -5888, -1280, 1792, 4352, 8960, 14080, 16896, 15616, 11776, 7424, 3328, -1024, -5632, -9984, -13056, -16640, -19968, -23040, -24320, -21760, -17664, -12032, -7680, -3072, 2304, 7680, 14592, 21248, 24576, 23296, 20736, 17152, 14592, 10752, 6656, 1536, -4608, -9984, -14080, -15872, -14848, -11008, -6144, -2048, 512, 3584, 7680, 12032, 15360, 15360, 12544, 8704, 4352, 0, -4096, -7936, -11008, -14848, -18176, -22016, -23808, -22016, -18432, -13312, -8192, -3840, 768, 5632, 12288, 19456, 23040, 22784, 19968, 17664, 15104, 11776, 8192, 3584, -1536, -6912, -12032, -14592, -14336, -11520, -7424, -3072, -1280, 1024, 4608, 9472, 13824, 14848, 13056, 9216, 5376, 1536, -2048, -5120, -8448, -13312, -17408, -21504, -23040, -21760, -18944, -14848, -10752, -5632, 0, 5120, 10752, 17152, 21248, 22272, 20480, 17408, 14848, 12032, 8704, 4864, 0, -5120, -10240, -13312, -13568, -11520, -6912, -3328, -1024, 1536, 4352, 8448, 12032, 13568, 13312, 9728, 5376, 768, -2816, -6144, -8960, -12800, -16640, -20480, -22784, -21760, -18176, -14080, -9984, -5376, -512, 5120, 9984, 15104, 18944, 20736, 19200, 17152, 14592, 12032, 9728, 5888, 1024, -4352, -8192, -11008, -11520, -9984, -6656, -3584, -1024, 1024, 3072, 6656, 9728, 12032, 12288, 8960, 4864, 1024, -2560, -5120, -7424, -10496, -14336, -18176, -19968, -20736, -18176, -14336, -11008, -5888, -1536, 3840, 8960, 12544, 15872, 18432, 17664, 16128, 13824, 11520, 10496, 7168, 2816, -2816, -6912, -9472, -10240, -8960, -6144, -4352, -1792, 512, 2304, 5632, 8960, 11776, 12544, 9472, 5376, 1024, -2304, -4608, -6912, -10496, -14080, -18176, -20224, -20224, -17920, -13568, -9728, -5888, -2048, 2304, 7936, 11776, 14848, 16128, 16128, 15104, 13312, 11520, 10240, 8192, 3584, -1536, -6144, -8192, -7936, -7680, -5888, -4608, -3072, 256, 2304, 5376, 7936, 10496, 11264, 8448, 5376, 1280, -1536, -5120, -7424, -11008, -14592, -17664, -19712, -18688, -16640, -13312, -10496, -6912, -2048, 2816, 8192, 12544, 14592, 16384, 15616, 14080, 12032, 9984, 9216, 7424, 3328, -2048, -6400, -9216, -8960, -6656, -4096, -2304, -1280, 256, 2304, 5632, 9216, 11520, 11008, 8448, 4352, 256, -2816, -5376, -8192, -11520, -14592, -18176, -19968, -18688, -15616, -11520, -8448, -5888, -2048, 2816, 7936, 11776, 13568, 14592, 13824, 12288, 10240, 8704, 7936, 6912, 3584, -1024, -5120, -7424, -7168, -5632, -3072, -1024, 256, 1024, 2048, 5376, 8704, 11008, 11008, 7936, 4352, 256, -2816, -5632, -7936, -11264, -15104, -18432, -19968, -17920, -13824, -10240, -7168, -4864, -2048, 2560, 7168, 11520, 13568, 14592, 13568, 11008, 8704, 7168, 6912, 6656, 4608, 0, -4608, -7936, -7424, -5120, -2816, -768, 512, 1280, 2560, 4864, 7936, 11008, 11264, 8704, 4864, 512, -3328, -5888, -8192, -11008, -14080, -17408, -19712, -18688, -14592, -10496, -6656, -3840, -1536, 2816, 7168, 11008, 13312, 13312, 12544, 10496, 8448, 6144, 5632, 5376, 3584, 256, -3584, -6400, -6144, -4608, -1792, -512, 512, 1792, 2560, 5120, 7936, 10240, 11008, 8448, 4608, 768, -3328, -6144, -8960, -11264, -14080, -17920, -19968, -18944, -15104, -10240, -6656, -2816, 256, 3328, 7424, 11264, 13568, 14592, 13824, 11520, 8192, 6144, 4608, 3328, 2304, -1024, -4096, -6656, -7424, -5632, -2560, 256, 2048, 3328, 4608, 5888, 8960, 10752, 11520, 9472, 5376, 1280, -3584, -7680, -10496, -12544, -14592, -17664, -19712, -19456, -15616, -9984, -5120, -1280, 2304, 5120, 8704, 12032, 13568, 14080, 12288, 9984, 6912, 3584, 2048, 768, 512, -1024, -3840, -5888, -6144, -4096, -768, 1536, 2816, 4864, 6144, 7680, 8704, 10496, 11008, 8960, 4608, 256, -4352, -7936, -11264, -13312, -15104, -17408, -19200, -18688, -15616, -9728, -4864, 256, 3328, 5888, 7680, 10752, 13312, 13312, 12032, 9216, 5888, 3584, 1792, 1024, 0, -1536, -2816, -5120, -6144, -4608, -1280, 1792, 3840, 4608, 5632, 7168, 9216, 11008, 11008, 9728, 6144, 1024, -3328, -7680, -11264, -14080, -16384, -17664, -19712, -19456, -16640, -11264, -4864, 256, 3840, 6912, 8960, 11776, 13568, 13568, 11776, 9216, 5888, 2816, 768, -1280, -1792, -2304, -3584, -5120, -5888, -4864, -1792, 2816, 4608, 5376, 6400, 7680, 10240, 11008, 11008, 9728, 6144, 1792, -3584, -7680, -10496, -14080, -16640, -18688, -19712, -18944, -16896, -12544, -6144, -512, 4352, 7424, 8960, 11264, 13056, 13824, 12544, 8960, 5888, 2816, 256, -1536, -3072, -3840, -4096, -5120, -6144, -5376, -2560, 2048, 5376, 6912, 8448, 8960, 10752, 12288, 12032, 9472, 5888, 1792, -3072, -7168, -11264, -15360, -17664, -19200, -19968, -18944, -16640, -12544, -6400, -512, 4352, 7680, 10240, 12288, 13824, 14080, 12288, 9216, 5120, 1536, -1024, -2304, -3584, -5120, -5632, -6144, -5376, -3840, -1536, 1792, 5376, 8192, 9984, 11008, 11264, 12544, 12800, 9728, 5376, 1024, -3328, -7168, -12032, -15872, -18944, -19712, -19968, -19712, -16640, -12288, -6656, -1024, 3840, 7168, 10240, 12800, 14336, 13824, 11776, 8448, 5120, 2304, -512, -2560, -4096, -5376, -5376, -5888, -5376, -3840, -1280, 2304, 4864, 7680, 9728, 10752, 11264, 11776, 12032, 9216, 5632, 1536, -2560, -5888, -9984, -14592, -18944, -19968, -20224, -19200, -16640, -13056, -8448, -2816, 2304, 6400, 9472, 11776, 14080, 14336, 12288, 8704, 5376, 2560, 1024, -1024, -3584, -5120, -6400, -6144, -5376, -3072, -768, 2048, 4352, 6656, 9216, 12032, 12800, 12800, 12032, 9216, 6400, 2560, -1280, -5376, -10240, -14592, -19200, -20992, -20224, -19200, -16384, -13056, -9472, -4096, 1280, 6400, 10240, 12288, 14080, 14080, 12544, 9472, 6400, 3840, 1536, -1536, -4608, -6656, -7424, -6400, -5120, -4096, -1792, 1280, 4352, 7424, 9984, 12544, 14336, 14336, 13056, 9984, 7168, 3840, 0, -4352, -9728, -14848, -19200, -22016, -22016, -20480, -17920, -13824, -9472, -4096, 1792, 6400, 10752, 12800, 14080, 14848, 13312, 10240, 6400, 2816, 512, -1280, -3584, -5376, -6656, -6656, -4608, -3072, -1280, 1024, 3328, 6400, 8704, 11520, 13568, 14080, 12288, 9984, 6400, 4096, 768, -3328, -7936, -13824, -17920, -21248, -21760, -19968, -17408, -14080, -9728, -5120, 256, 5120, 9216, 11776, 13056, 14080, 12288, 9984, 6912, 4352, 1792, -1280, -3328, -5120, -5888, -5888, -4608, -2560, -1024, 768, 2560, 5376, 7424, 10240, 12288, 13312, 12800, 10240, 7168, 5120, 2560, -1280, -6144, -12288, -17152, -20992, -22272, -20736, -18688, -14336, -11264, -6400, -1280, 3840, 8704, 11776, 13312, 14080, 13056, 9984, 6912, 4608, 1792, -512, -3328, -5632, -6400, -6144, -4096, -2304, 256, 2048, 3328, 5632, 7680, 10752, 12288, 12800, 12032, 9728, 6656, 3840, 1536, -2048, -5632, -10496, -15616, -19712, -22016, -20736, -17920, -13824, -10240, -6912, -2048, 3072, 7936, 10752, 12544, 12800, 12288, 9728, 6656, 4096, 1792, -1024, -2816, -4608, -5632, -5376, -4096, -2304, 0, 2304, 3840, 5376, 6656, 8960, 12032, 12800, 11776, 9216, 7168, 4608, 1792, -1792, -5632, -9472, -13568, -17920, -20736, -21248, -18432, -14848, -11008, -7680, -3584, 1280, 5632, 9472, 11264, 11776, 11264, 9472, 6656, 4352, 2048, 512, -1792, -3072, -4352, -4096, -3072, -1536, 768, 2048, 3328, 4352, 5632, 7936, 10752, 11008, 11008, 8960, 7424, 6400, 3584, 512, -4352, -8960, -13056, -16640, -19712, -20480, -19200, -16128, -12032, -8704, -4608, 1024, 5376, 8192, 9728, 10496, 10496, 9216, 7168, 4352, 2048, 256, -2304, -3072, -4096, -3840, -2304, -512, 2048, 3328, 3840, 4352, 5888, 7168, 9984, 11008, 9728, 7680, 5376, 4352, 2816, 1024, -3072, -7168, -11520, -15360, -17408, -18176, -16896, -14848, -12544, -9728, -5888, -1280, 3840, 6912, 8704, 8704, 8192, 7168, 5888, 4608, 3328, 1024, -512, -1792, -2304, -1792, -1024, 1280, 3584, 4096, 4096, 3584, 3840, 6144, 8960, 9984, 8960, 5888, 4352, 3840, 2816, 2048, -1024, -4864, -9472, -13568, -15872, -16640, -15872, -14592, -13568, -11008, -7936, -3584, 1280, 4864, 6912, 7936, 7168, 6656, 5888, 5120, 4608, 2816, 1280, -512, -1280, 0, 768, 2048, 3584, 4096, 3840, 2816, 1792, 3072, 5888, 8192, 8192, 5376, 3072, 2560, 3328, 3072, 1536, -2304, -6912, -11008, -12800, -14080, -13568, -13056, -13312, -11264, -9728, -5888, -1536, 1792, 4608, 5632, 4864, 4096, 3840, 4096, 4864, 4352, 3072, 1536, 768, 1792, 2560, 4096, 5120, 5888, 5120, 3584, 2048, 2304, 4352, 6912, 6656, 4352, 1536, 768, 1792, 2560, 1792, -1280, -4608, -8192, -10496, -11776, -11520, -11520, -11520, -11264, -10240, -7680, -4096, -768, 2048, 3840, 3072, 2560, 2816, 4096, 4864, 4864, 4096, 3072, 2560, 2816, 3840, 5120, 6400, 6656, 6144, 4608, 2816, 1536, 2816, 4352, 5376, 3840, 768, -1536, -512, 1024, 1792, 512, -3584, -6400, -8192, -9216, -9728, -9472, -9472, -8960, -8448, -8448, -6400, -3840, -1024, 768, 1024, 0, -768, 512, 3328, 5376, 5376, 5120, 4352, 4864, 5888, 6912, 7936, 8448, 7936, 6144, 4096, 1024, 512, 1792, 3328, 3328, 768, -2560, -2304, 0, 2048, 1792, -768, -3840, -5632, -6144, -7680, -8192, -9472, -9984, -9728, -9472, -8704, -7168, -4352, -2048, -512, -1024, -1024, 1024, 4096, 6656, 7680, 6656, 5632, 5632, 6400, 7424, 7936, 7680, 7424, 6144, 4352, 1536, -512, 1792, 2560, 3328, 1024, -2816, -3840, -2560, 768, 2048, 512, -2560, -4352, -4352, -4352, -5888, -7424, -8960, -9472, -8704, -9216, -8960, -7168, -4864, -2560, -2816, -3584, -2048, 2048, 5376, 6656, 6656, 5376, 6144, 7936, 9728, 10240, 9728, 9472, 8448, 6656, 3840, 1024, 256, 512, 256, -1536, -4864, -6144, -4608, -1792, 512, 1280, -1024, -2560, -2304, -1536, -1792, -4096, -6912, -8448, -8960, -9728, -10496, -9728, -8192, -5632, -5120, -4608, -2560, 1024, 5120, 7424, 7936, 7680, 7168, 8192, 9728, 11008, 10752, 9984, 8704, 7168, 3584, 1024, 256, 768, 1024, -1280, -5376, -7680, -6656, -3584, 256, 768, -1024, -2048, -2048, 0, 0, -2048, -3840, -6656, -7424, -8960, -10240, -10240, -9216, -7680, -7168, -7424, -5632, -2560, 2304, 5632, 7168, 7168, 6912, 7680, 9984, 11776, 12800, 12800, 11008, 8448, 5376, 2304, 768, 768, 256, -2560, -5632, -8960, -8704, -5632, -2048, 512, 0, -1536, -1792, 0, 1280, -512, -2304, -4608, -7168, -8704, -10496, -11008, -9984, -8960, -8448, -8448, -6400, -3072, 1280, 4864, 6656, 7424, 7936, 7936, 9984, 11776, 13056, 13312, 12032, 9728, 6912, 4608, 2560, 1280, -768, -3328, -5632, -8448, -9216, -7168, -4096, -1024, -512, -1024, -1536, 0, 2048, 1792, 0, -3072, -5632, -8448, -10240, -10752, -9984, -9472, -9728, -9984, -8192, -4352, 512, 3840, 6144, 6400, 7168, 8448, 9984, 12032, 13056, 13568, 13056, 11264, 8960, 5888, 3840, 2048, 256, -3072, -6400, -9472, -10496, -8448, -5632, -2816, -1024, -1280, -768, 768, 2560, 3328, 1536, -1280, -4352, -7168, -9728, -11008, -11264, -11264, -11264, -11008, -9216, -5888, -1792, 1792, 5120, 6656, 7424, 8960, 11008, 13056, 13824, 14848, 14336, 13312, 11264, 7424, 4608, 2304, -512, -3072, -7168, -9984, -11520, -9728, -6656, -4096, -1792, -768, 256, 1536, 3072, 3840, 3072, 768, -2816, -6400, -9472, -10496, -11008, -11776, -12032, -11776, -9984, -7168, -3840, 0, 2816, 5376, 6400, 7936, 9728, 11776, 13568, 15360, 15872, 15104, 13568, 10752, 8192, 4864, 1536, -2560, -6912, -10496, -12032, -12032, -9984, -7936, -5376, -2304, -512, 1280, 2816, 4096, 4864, 3328, 512, -3840, -7680, -8960, -9472, -11008, -12032, -12544, -10752, -8192, -5376, -2816, 0, 2048, 4864, 6912, 9728, 12032, 13056, 14848, 16128, 16128, 15104, 12800, 10496, 7168, 2560, -2304, -6656, -9472, -11008, -11264, -10240, -8448, -5888, -2816, 0, 1536, 2304, 3584, 3840, 3328, 256, -3840, -6400, -8192, -8704, -11008, -12544, -12800, -11008, -7680, -5120, -3328, -2304, 0, 2560, 5888, 9216, 11776, 13312, 14080, 15872, 16640, 16896, 15616, 13056, 9216, 3840, -1792, -6144, -8704, -10752, -11520, -11776, -10752, -8704, -5120, -1280, 1280, 2816, 3584, 4096, 3328, 512, -2560, -4608, -6144, -7936, -9984, -12544, -12288, -10752, -8704, -6144, -4608, -3840, -2048, 512, 3328, 7424, 10752, 13056, 14592, 15872, 16640, 17920, 17664, 15360, 11520, 5120, -768, -6144, -9472, -11008, -11776, -12544, -12288, -9984, -6144, -1536, 1280, 3072, 4352, 5120, 4096, 1536, -2304, -3840, -5376, -6656, -9728, -12800, -14336, -12800, -9472, -6656, -5888, -4864, -3584, -1024, 2816, 6912, 10752, 13824, 14848, 16128, 16640, 17408, 17920, 16128, 12800, 6656, 256, -5376, -9472, -11008, -11264, -11264, -11264, -10240, -7168, -2816, 1280, 2560, 4096, 4608, 3584, 1280, -3072, -4864, -5632, -6144, -8448, -12032, -13312, -13312, -9728, -6400, -4352, -4352, -4096, -2560, 1024, 5632, 9984, 13568, 15104, 15872, 16128, 16896, 17408, 16896, 14080, 8192, 2304, -4352, -8704, -11008, -10752, -9984, -9728, -9728, -7936, -4864, -768, 2560, 4352, 4864, 3072, 768, -3072, -5376, -6144, -6144, -7936, -10240, -12544, -13312, -10496, -7680, -4608, -3840, -4352, -2560, 0, 4096, 8448, 12032, 15104, 16640, 16384, 16640, 17152, 16128, 14336, 9728, 3328, -3072, -8192, -10496, -9984, -8960, -8448, -8192, -6912, -4352, -1024, 2048, 3840, 4096, 3328, 1024, -2816, -5120, -6400, -6912, -8192, -10240, -12288, -13312, -11776, -9472, -6400, -4608, -4096, -2560, 256, 4096, 8448, 12544, 15104, 16896, 17152, 16640, 16896, 15872, 13056, 9728, 3840, -2304, -7680, -9728, -10496, -8448, -7424, -6656, -5888, -4352, -1280, 1792, 4096, 3840, 3584, 1280, -2304, -4864, -6912, -7936, -8704, -10240, -12032, -13312, -12544, -10240, -7680, -5632, -4096, -2048, 1024, 4864, 8192, 11776, 15104, 17152, 18176, 17664, 16384, 14592, 12544, 9216, 4352, -1792, -6912, -9728, -10240, -8960, -7168, -5888, -4864, -3072, -1280, 1536, 3072, 4096, 3840, 2560, -1280, -4864, -7168, -8192, -9216, -9984, -11776, -13568, -13312, -11520, -8704, -6400, -4608, -1792, 1536, 5120, 8448, 11776, 15360, 17152, 18944, 18176, 16640, 14336, 11776, 9472, 4608, -512, -5120, -8448, -9728, -9728, -7680, -5632, -4096, -3072, -1536, 512, 1536, 3840, 3840, 2816, 256, -2816, -4864, -7936, -9472, -10752, -11776, -13056, -13824, -13568, -11776, -8960, -6656, -3584, 768, 4352, 8448, 11520, 14592, 17152, 19200, 19712, 18176, 15872, 12800, 9216, 4608, 0, -4864, -7936, -9216, -9472, -7936, -5888, -4352, -2816, -1536, 256, 1536, 2816, 3840, 3584, 2048, -768, -4096, -6912, -9472, -10496, -12032, -13312, -14848, -15360, -14080, -11776, -8192, -4096, 0, 4352, 8192, 11776, 15104, 17920, 20224, 20480, 19200, 16640, 13056, 8960, 5120, 512, -3840, -6912, -9728, -10752, -9216, -6912, -4352, -2560, -1024, 768, 1792, 3072, 4608, 4864, 3584, 1280, -1792, -5632, -9472, -11776, -13568, -14592, -15872, -17152, -16640, -14848, -11008, -5632, 256, 5120, 8960, 12288, 15360, 17664, 20224, 20992, 20224, 17408, 13568, 9216, 5376, 1024, -2816, -6144, -9216, -10240, -9728, -7936, -5376, -3584, -1280, 256, 1280, 2816, 4352, 5632, 4864, 3584, -512, -4352, -8960, -12288, -14080, -16128, -17152, -18688, -18432, -16384, -12544, -6912, -1024, 4864, 9216, 13312, 16384, 18688, 20736, 21760, 20992, 18432, 14336, 9216, 5120, 768, -3584, -6144, -8448, -9216, -8960, -8192, -5632, -3328, -1536, 512, 1792, 2560, 3840, 4864, 4864, 4352, 1536, -2560, -7424, -12288, -14848, -17152, -18176, -19200, -19968, -18432, -14848, -8960, -2560, 4096, 8960, 13312, 16640, 18944, 20480, 22016, 22272, 20224, 15872, 9984, 5376, 1280, -2816, -5632, -8448, -9984, -9984, -8704, -6400, -3840, -1792, 768, 2048, 4096, 4352, 5376, 5632, 4864, 2304, -1536, -6912, -12032, -15360, -18176, -19712, -20480, -20736, -18688, -15616, -9984, -3072, 4096, 9216, 13312, 16128, 18688, 20480, 21760, 22272, 19456, 15104, 10496, 5888, 2048, -1792, -4608, -7424, -9216, -9728, -8448, -5888, -3328, -2048, 256, 1536, 3584, 4608, 4864, 5888, 5888, 4352, 256, -5120, -11008, -14592, -17152, -19968, -21248, -22784, -20736, -17152, -11520, -4864, 2304, 8960, 14080, 17152, 18944, 20480, 22272, 23296, 21248, 17408, 11264, 6144, 1536, -2304, -5376, -7424, -9216, -9984, -9984, -7936, -5120, -2560, 256, 3328, 5120, 6656, 6656, 6912, 7168, 5632, 2048, -4096, -10240, -15360, -19200, -22016, -23808, -24320, -22784, -19200, -13312, -6144, 1792, 9472, 14592, 17664, 19712, 21248, 23040, 23808, 21760, 17920, 12288, 6912, 2048, -2048, -4864, -6656, -8192, -8960, -9984, -9472, -7168, -4352, -512, 2304, 4864, 5376, 6912, 7936, 8192, 7424, 3072, -2304, -8192, -13824, -18176, -22016, -24064, -24576, -23040, -20992, -15872, -8448, 512, 8704, 14336, 17664, 19968, 22272, 24064, 24064, 21760, 17664, 12544, 7424, 2304, -2560, -5376, -6912, -7680, -8448, -9472, -9216, -7424, -4352, -1280, 2304, 4864, 6400, 6912, 7936, 8448, 8448, 5376, -512, -6400, -13056, -18176, -22016, -24320, -24320, -23552, -21760, -17664, -10752, -2048, 6912, 13312, 17152, 18944, 21248, 23552, 24320, 22784, 19200, 14336, 8960, 4096, -1536, -4352, -6656, -7168, -8704, -10496, -9984, -9472, -6400, -2304, 1536, 5120, 7168, 7936, 9472, 9472, 8704, 6144, 768, -5120, -11776, -17664, -21760, -24576, -25344, -24832, -22784, -18688, -12032, -2816, 5376, 11520, 15616, 18688, 21504, 23552, 24320, 22784, 19712, 15616, 10496, 5120, -512, -3328, -5120, -7168, -9216, -11008, -11776, -10240, -7680, -4096, 0, 3072, 6144, 7680, 9728, 11008, 10496, 8448, 3328, -3584, -9984, -16128, -20480, -23808, -25088, -25600, -24064, -19456, -13312, -4864, 3584, 9728, 14336, 17920, 20480, 23040, 24064, 22528, 19200, 14848, 10240, 5632, 1536, -2048, -4864, -6400, -8448, -9984, -10496, -9728, -7936, -4864, -1280, 1792, 5376, 7936, 9984, 11520, 10752, 8192, 3840, -2048, -8192, -14080, -19712, -23808, -26112, -25856, -24064, -20480, -14592, -7424, 1280, 8704, 13824, 17920, 19968, 22528, 24576, 23552, 20480, 15872, 10496, 6144, 2048, -2304, -5376, -8192, -8960, -9728, -10496, -9984, -8960, -5632, -1536, 1536, 5376, 7936, 9984, 11776, 11264, 8960, 4608, -1280, -6912, -12544, -17920, -22016, -24832, -26112, -24576, -21504, -14848, -7680, -512, 6656, 11520, 15872, 18944, 20992, 22784, 22784, 20480, 16896, 11776, 7168, 3072, -768, -3584, -6656, -9216, -9984, -10752, -10240, -9216, -7168, -3840, 0, 4352, 7680, 9472, 11520, 12288, 10240, 5888, 768, -5120, -11008, -16384, -20736, -23808, -25088, -24576, -21760, -16640, -9728, -2048, 5120, 10240, 14080, 17408, 20480, 22528, 22528, 20992, 17408, 13824, 8960, 4608, 512, -3072, -6144, -8960, -10240, -11520, -11520, -10496, -8448, -5120, -1024, 3840, 7936, 10496, 12544, 13312, 12288, 8192, 3328, -3584, -9728, -15104, -19712, -23552, -25856, -26112, -23296, -17920, -11520, -3840, 3840, 9728, 13568, 16640, 19712, 22784, 23296, 21760, 18176, 13312, 9728, 5376, 1280, -3072, -6656, -9216, -10752, -11520, -11520, -11008, -8704, -5632, -1792, 2304, 6656, 9984, 12800, 14336, 12800, 8704, 3584, -1792, -7424, -12800, -17664, -21504, -24576, -25088, -23040, -18432, -12800, -6144, 1792, 8192, 12288, 14592, 17408, 21504, 23296, 22528, 18944, 14848, 11264, 7680, 2816, -2304, -6656, -9728, -10496, -11776, -11520, -11264, -9728, -5888, -1792, 2304, 6144, 9216, 12544, 14080, 13056, 8960, 4608, -768, -6144, -11520, -16384, -19968, -22784, -23808, -23040, -19200, -13824, -7424, 0, 5888, 10752, 13824, 17152, 20480, 23040, 23296, 20736, 16640, 12288, 7936, 3328, -1280, -6144, -10496, -12800, -13568, -13056, -11776, -10752, -7168, -2560, 2048, 5888, 9216, 12800, 15104, 14336, 11264, 6656, 2048, -3328, -8960, -14336, -19712, -22784, -24064, -23552, -20480, -15616, -9984, -2816, 3584, 8448, 12800, 16128, 19712, 22528, 22784, 20736, 17152, 13824, 9728, 5376, 256, -5888, -9984, -12800, -13824, -13568, -11776, -10752, -7936, -4352, 256, 4352, 8448, 11776, 14336, 14336, 11776, 8448, 4096, -1024, -6144, -11776, -17152, -20992, -23552, -24064, -22272, -17152, -11520, -4864, 1024, 5632, 11008, 15872, 19456, 22272, 23040, 22272, 19456, 15104, 10240, 5120, 256, -5632, -10240, -14080, -15872, -14848, -12800, -10240, -7424, -4352, -768, 3584, 8448, 12544, 15104, 14848, 12544, 8960, 5376, 512, -4352, -9984, -15104, -19456, -23040, -23808, -22016, -17920, -12544, -7424, -2048, 3072, 8448, 14592, 19200, 21504, 22272, 21504, 19968, 16640, 12032, 7168, 1536, -4608, -9984, -14848, -16640, -16384, -14592, -11264, -8448, -5632, -2560, 1536, 6656, 11264, 14336, 14336, 12288, 10240, 6912, 2816, -2048, -7680, -12544, -16640, -20480, -22016, -22272, -18432, -13056, -7936, -3328, 1280, 6144, 12288, 17920, 20736, 22016, 21248, 20224, 17664, 13056, 7680, 2048, -4096, -9472, -14080, -16640, -17152, -15616, -12288, -9216, -5376, -2560, 1280, 5632, 10240, 14080, 14848, 13568, 11008, 7936, 4096, -512, -5888, -11520, -15360, -18944, -20992, -22016, -19200, -14336, -9216, -4096, 256, 5376, 11264, 16640, 20736, 22528, 21760, 20736, 18432, 13824, 8448, 2048, -4608, -10496, -14848, -18176, -18944, -17920, -14336, -10496, -5888, -1536, 2048, 5888, 9728, 13568, 15360, 15104, 12800, 9472, 5632, 256, -5120, -10496, -14336, -17664, -20224, -21248, -19968, -15872, -10752, -5120, 512, 5632, 10496, 15104, 19712, 22016, 22272, 20224, 17152, 12800, 7936, 2560, -3840, -9216, -13312, -16128, -17664, -17664, -15104, -10496, -5888, -2304, 1024, 3840, 7424, 11264, 14080, 14336, 13568, 11008, 6912, 3072, -2048, -6912, -11264, -14592, -17408, -19968, -19712, -17152, -12288, -7424, -3072, 3072, 8192, 13312, 17920, 20224, 21504, 20992, 18688, 15104, 9728, 3840, -2304, -8448, -13312, -16128, -18176, -18432, -16896, -12800, -7680, -3328, 512, 3072, 6912, 10752, 12800, 13824, 13824, 11776, 8704, 4864, -512, -4864, -8960, -12032, -15616, -18176, -18432, -16896, -13056, -9216, -4864, 1280, 6912, 11776, 16128, 18944, 20224, 20224, 17920, 14848, 10496, 5376, 768, -6144, -11264, -14848, -16896, -16896, -16640, -13312, -9216, -5632, -2560, 1024, 4608, 8704, 11008, 12544, 13312, 12288, 11008, 7936, 3584, -1024, -5376, -8960, -13056, -15616, -16896, -16384, -14336, -11008, -7424, -2048, 4096, 9472, 13824, 17152, 18432, 18944, 17920, 15616, 11776, 6912, 1792, -4864, -10240, -14336, -15872, -15872, -16128, -14080, -11008, -6656, -2560, 768, 3328, 6656, 9728, 11264, 12032, 11008, 9984, 7680, 4864, 1280, -3072, -6144, -10240, -12032, -13056, -13568, -13056, -11264, -8192, -3584, 1536, 6144, 10496, 13824, 15616, 16128, 15616, 14336, 12032, 8192, 3328, -2304, -7936, -11776, -14336, -13568, -13824, -13824, -12288, -9472, -4608, -768, 2048, 4352, 6912, 8448, 9728, 9984, 9984, 9472, 7680, 4608, 256, -4096, -7424, -8960, -9984, -10752, -12032, -12032, -9984, -5632, -768, 3584, 7424, 10752, 13056, 14592, 14336, 13824, 11520, 9216, 5120, -512, -5888, -10496, -12800, -13056, -13312, -13568, -13056, -10752, -6912, -2048, 1280, 3072, 4864, 7168, 8960, 10240, 9984, 10240, 9472, 7168, 3072, -1792, -5888, -7168, -7680, -9472, -11008, -12544, -11520, -8192, -3840, 768, 4864, 8704, 11520, 12544, 12544, 13056, 12032, 10496, 6656, 1536, -4608, -8704, -11008, -11520, -11520, -12288, -13056, -12544, -8448, -3840, -512, 2048, 3072, 4864, 6656, 8448, 9728, 9728, 9728, 8704, 6400, 2048, -2816, -4864, -5120, -5888, -8192, -11008, -12288, -10496, -6144, -2048, 2560, 5376, 7936, 9728, 11008, 12032, 12288, 11520, 8704, 4096, -2304, -7936, -10496, -10752, -10752, -11776, -13312, -13312, -10240, -5888, -1536, 1536, 2816, 4352, 6144, 7680, 8960, 9728, 9984, 10240, 7424, 3584, -768, -3584, -3584, -3840, -6144, -9216, -12032, -11520, -8448, -3840, 768, 3584, 5888, 7424, 8960, 9984, 11264, 11520, 9728, 5632, -768, -6656, -9728, -9472, -9472, -10496, -12800, -14336, -11520, -6656, -2048, 1280, 3072, 4096, 5632, 6912, 8192, 9984, 10496, 10496, 8448, 4352, 256, -2304, -2048, -2048, -4096, -7680, -10496, -11520, -8960, -5376, -1280, 2560, 4608, 6144, 7168, 7936, 9728, 10752, 9984, 6400, 512, -5888, -9216, -9216, -9472, -9984, -12032, -13568, -12032, -7936, -2816, 768, 3072, 4096, 5888, 6912, 8192, 9472, 10240, 10496, 8448, 4608, 512, -1792, -2048, -1536, -2560, -5888, -9216, -10496, -8960, -5120, -1536, 1792, 3584, 4352, 6144, 7424, 9216, 10752, 10240, 7168, 1280, -5120, -8960, -9728, -9728, -9984, -11520, -13056, -11776, -8448, -3840, 512, 3328, 5632, 6912, 7168, 6912, 7680, 9472, 10496, 8960, 5120, 1280, -1024, -1024, -512, -768, -3328, -7168, -8960, -8192, -5888, -2560, 768, 2816, 3584, 3584, 5120, 7168, 9472, 10240, 6912, 1792, -4096, -7936, -9216, -9472, -9216, -10496, -11264, -11520, -8960, -4608, 256, 3072, 4864, 6400, 6656, 6912, 7936, 8704, 9984, 8704, 5120, 2048, 0, 0, 256, 0, -2304, -5888, -8448, -8704, -6144, -2560, 512, 2048, 2048, 2560, 4096, 6912, 8704, 8960, 6912, 2560, -2560, -6912, -8960, -8960, -8704, -9984, -11776, -12032, -9728, -5632, -768, 2560, 4864, 6656, 7936, 8192, 8192, 8960, 10496, 9984, 6400, 2304, -512, -768, -512, -512, -1792, -4864, -7680, -8448, -6656, -3584, -768, 1536, 1536, 1792, 3072, 6656, 9472, 9472, 6656, 2560, -2048, -6400, -8960, -9984, -9984, -10752, -12032, -12544, -10752, -6912, -1024, 3072, 5120, 7424, 8448, 9216, 8960, 8960, 9728, 9472, 6912, 2560, -768, -1536, -768, -512, -1792, -4096, -6144, -7168, -6144, -3328, -1024, 1024, 1280, 1792, 2304, 4864, 7680, 8448, 7168, 3072, -1536, -6144, -8960, -10240, -9984, -10752, -12032, -12032, -10496, -6656, -2048, 2560, 5632, 7936, 9216, 10496, 9984, 8704, 8448, 8448, 7424, 3840, 512, -1792, -2048, -1536, -1536, -2560, -4608, -6144, -6144, -3840, -1280, 1536, 1792, 1792, 2560, 4352, 5888, 5888, 4608, 2304, -1792, -5888, -9216, -10752, -10496, -10496, -11520, -11520, -9984, -7168, -2816, 1792, 5376, 7936, 9216, 9984, 9984, 8704, 7936, 8448, 7424, 4864, 1792, -1280, -1536, -1536, -1024, -1536, -3328, -4352, -5120, -4096, -2048, 256, 1536, 1792, 1792, 2816, 4096, 5120, 4608, 2304, -1792, -6144, -9472, -11008, -10752, -10752, -10752, -11520, -10496, -7168, -2816, 1792, 4864, 7168, 8960, 10240, 10752, 9728, 8448, 7424, 6912, 5376, 2560, -512, -2048, -2048, -1536, -2048, -2816, -3328, -4096, -3584, -2048, 256, 1280, 2048, 2304, 3840, 4864, 5120, 4608, 2304, -1024, -4608, -8704, -10752, -11776, -12032, -11520, -12032, -11520, -9216, -5120, 0, 3328, 6656, 9216, 11520, 12288, 10752, 8960, 7424, 7168, 6656, 5120, 1536, -1536, -2560, -2560, -1536, -1792, -2048, -2560, -3584, -2560, -1792, 0, 1536, 2048, 3328, 3584, 4096, 3328, 1792, -768, -3328, -6912, -9472, -11264, -12544, -11264, -10752, -10240, -9472, -6400, -2304, 2304, 5888, 7936, 10496, 11264, 11264, 9472, 7680, 6912, 7168, 6912, 3840, 512, -1792, -2304, -1536, -1792, -2304, -2048, -3328, -3072, -2048, -768, 1024, 2304, 3328, 3584, 3584, 2816, 1536, 0, -2304, -5888, -8704, -11008, -12544, -11776, -10752, -10240, -8960, -7424, -3328, 768, 4864, 7936, 10496, 11520, 11008, 9472, 7936, 7424, 7680, 7168, 4864, 1024, -1280, -1792, -1792, -1280, -2048, -1792, -2304, -2816, -2304, -1024, 0, 1536, 3072, 3584, 3328, 2304, 1280, -768, -2304, -4864, -7168, -9472, -12288, -12288, -11520, -9984, -8704, -7680, -4608, -1280, 3072, 5888, 8704, 10752, 11264, 9984, 8704, 8192, 7936, 8448, 7680, 4608, 2048, 256, -1280, -1536, -1280, -1280, -2048, -3328, -4096, -3584, -1792, 512, 1792, 2816, 2560, 1792, 1024, -512, -1792, -3072, -5632, -8192, -11520, -12800, -11520, -9728, -8448, -7680, -6144, -3328, 512, 5120, 7936, 9984, 11008, 10752, 9728, 9216, 8448, 8448, 8448, 6144, 3584, 256, -2048, -2304, -1792, -1024, -1280, -2816, -4096, -4096, -2816, -1024, 512, 2304, 2048, 1792, 768, -768, -1536, -2304, -3840, -6144, -9728, -12032, -12288, -10752, -8960, -8192, -7424, -5376, -2304, 2816, 6912, 8960, 10752, 10752, 10752, 10240, 10240, 9728, 9216, 7680, 4864, 2048, -1024, -2304, -2048, -1280, -1280, -3072, -4608, -5120, -3840, -1280, -512, 768, 1024, 1280, 1536, 256, -768, -2048, -3072, -4864, -7936, -11008, -12032, -11008, -9216, -8960, -9216, -8192, -4864, 512, 4864, 7680, 9728, 10752, 11776, 12544, 12800, 12032, 11008, 9984, 7168, 4096, 256, -2560, -3328, -2816, -2304, -3584, -5376, -6400, -5120, -2560, -1024, 256, 768, 1024, 1792, 1024, -768, -1792, -1792, -2560, -5888, -9728, -12032, -11776, -10496, -9472, -9728, -9472, -6912, -2816, 2816, 6144, 8448, 9728, 11520, 12800, 13568, 13312, 12288, 11008, 9472, 6400, 2560, -768, -2816, -2816, -2816, -3328, -5120, -6912, -7424, -5632, -3584, -1792, -512, 512, 1536, 768, -512, -768, 0, 0, -2816, -7168, -10496, -11520, -9984, -8960, -9216, -9984, -9472, -6144, -1792, 2816, 5632, 8192, 10496, 13056, 14080, 14336, 13824, 13568, 12800, 10240, 5888, 1536, -1280, -2560, -2816, -3584, -5120, -7168, -8704, -8448, -6400, -4096, -2560, -1280, 0, 0, 256, 512, 1024, 1280, -1024, -4096, -7424, -8960, -9472, -9472, -8960, -9984, -9984, -8192, -4864, 0, 3328, 5888, 9216, 11776, 13824, 14848, 14592, 15104, 14336, 12032, 8448, 4096, 768, -1280, -2304, -2816, -4864, -7424, -9216, -9984, -8448, -6656, -4608, -3072, -1792, -1280, -512, 1024, 2816, 3840, 2560, -768, -4608, -7424, -8192, -8960, -9216, -10496, -11264, -10240, -7680, -4608, 0, 3328, 7168, 10496, 12800, 15104, 16128, 16896, 16896, 15360, 11264, 6656, 2816, 512, -1536, -3072, -4864, -7424, -9728, -11264, -10496, -8448, -6400, -4096, -2304, -2048, -1536, 256, 2816, 4608, 4096, 2048, -1536, -4352, -6912, -8192, -9216, -9984, -11008, -11264, -9472, -7680, -3072, 2048, 6656, 9984, 11776, 14336, 16384, 17920, 18432, 16896, 13056, 9216, 4608, 1792, -1024, -2816, -4608, -7424, -10752, -12800, -13056, -11520, -8960, -5888, -3584, -2560, -2304, 0, 3584, 6912, 7424, 5120, 1792, -1280, -3840, -5888, -7680, -9728, -11520, -12800, -12544, -11008, -7680, -2304, 3328, 7936, 10496, 13312, 16640, 19200, 20224, 19712, 16896, 12800, 7680, 3328, 768, -1536, -3584, -6656, -10496, -13568, -14592, -13824, -11264, -8192, -5888, -4352, -3328, -1280, 2560, 6144, 7936, 7168, 5120, 2304, -1280, -4352, -6656, -8960, -10240, -12288, -13824, -13568, -11264, -5888, 0, 5376, 8960, 11776, 15360, 18688, 20736, 21248, 19712, 15360, 10752, 6400, 2816, 256, -2816, -6400, -10752, -14592, -16384, -15872, -13824, -11008, -8448, -6144, -4352, -1536, 2304, 5888, 9472, 9472, 8448, 4864, 1536, -2304, -5120, -7680, -10496, -12544, -14592, -15104, -13824, -9728, -4096, 2560, 7936, 11776, 14848, 17920, 19968, 21760, 21504, 18688, 13824, 8192, 4096, 1280, -1280, -5632, -10496, -15360, -18432, -18176, -16896, -13824, -11008, -7680, -4864, -1536, 2560, 6400, 10496, 12032, 11008, 8192, 5120, 1792, -2560, -6400, -10240, -13312, -15616, -17408, -16640, -13824, -8704, -2816, 4096, 9984, 14592, 18432, 20480, 22528, 23296, 21248, 17152, 11776, 7168, 3328, 256, -4608, -10240, -15872, -19712, -19712, -17920, -16128, -13824, -11008, -7680, -3072, 1792, 6400, 10240, 13056, 13056, 10752, 7936, 4864, 768, -3328, -8192, -12288, -15360, -17408, -18176, -16128, -12544, -7168, -512, 5888, 11776, 16896, 19712, 22016, 23552, 22784, 20992, 15872, 11008, 5632, 1792, -3072, -9984, -15104, -18944, -20480, -19968, -18432, -16128, -12800, -8960, -4352, 1280, 5632, 8960, 11520, 12544, 12544, 10752, 7936, 3328, -1792, -6400, -9728, -12544, -15104, -16896, -16640, -14592, -10752, -5120, 2048, 8704, 14080, 17664, 20224, 21504, 21504, 21504, 19712, 16384, 10752, 4608, -1536, -7424, -12544, -17664, -20992, -22272, -22272, -19968, -16896, -12288, -6912, -1024, 4352, 8448, 12032, 14336, 15360, 14848, 12544, 7936, 2048, -4608, -9216, -12032, -14592, -17152, -19200, -18944, -15360, -9216, -768, 6400, 12288, 16640, 19456, 21248, 22272, 23040, 22528, 19712, 13312, 6144, -1024, -6656, -10752, -15616, -19712, -23296, -24064, -21760, -17920, -13824, -8704, -2816, 3072, 7680, 11264, 14336, 16128, 16896, 15616, 11008, 4864, -2048, -6912, -9984, -12544, -15872, -18944, -20480, -18176, -12544, -5120, 2304, 8704, 14336, 17920, 20224, 22016, 23808, 24576, 23296, 17920, 10496, 2816, -4608, -9984, -14848, -19712, -23296, -25344, -24320, -21248, -16640, -10752, -4352, 1792, 6912, 11008, 14592, 16896, 17664, 17152, 14080, 8192, 1280, -5376, -8192, -10752, -14336, -18688, -21504, -20224, -15360, -8448, -1280, 5376, 11264, 15616, 18432, 20480, 23552, 25600, 25344, 20992, 13824, 5888, -2560, -7936, -13056, -18176, -22272, -25856, -25856, -23552, -19456, -12544, -6144, 256, 5376, 9472, 13312, 16896, 18432, 18432, 16384, 11264, 4608, -1792, -5888, -7936, -11520, -16384, -20224, -21248, -18176, -11776, -4608, 1792, 6912, 11776, 15872, 18432, 21760, 24832, 25600, 23552, 16640, 8960, 512, -5632, -10240, -15360, -19968, -23552, -25600, -24576, -20992, -15104, -7424, -1536, 3840, 7168, 11264, 14592, 16640, 17152, 16640, 12544, 6912, 512, -4352, -5888, -8960, -13568, -17920, -20224, -18688, -13312, -6912, -1024, 4096, 8960, 13824, 16640, 19712, 22528, 24320, 23808, 18688, 11264, 3072, -4352, -9728, -13824, -18944, -22016, -24832, -25088, -22784, -17664, -9472, -2816, 2304, 6912, 10752, 14336, 16640, 17408, 18176, 15104, 9984, 3328, -2304, -5120, -7680, -11520, -15872, -18944, -19200, -15360, -10496, -4608, 768, 5888, 11008, 15360, 18944, 21248, 23296, 23296, 19968, 13312, 5632, -2048, -7680, -11776, -16896, -20992, -23040, -23552, -21760, -17920, -11264, -4352, 1280, 5632, 8448, 11520, 14336, 15360, 16128, 14336, 9984, 5376, 1280, -2304, -5120, -8448, -12544, -15872, -17920, -15872, -12032, -7168, -2304, 2816, 7424, 12032, 15360, 18688, 21248, 22272, 20736, 15872, 8192, 1024, -5376, -9984, -15360, -19968, -22528, -23040, -22016, -18688, -14080, -7168, -512, 4608, 7680, 10752, 12800, 14592, 14848, 13568, 11264, 6912, 3840, 1024, -2560, -6144, -10240, -13568, -15104, -14592, -12544, -9728, -5376, -768, 4352, 8704, 12544, 15872, 19200, 20736, 19456, 16128, 9984, 3840, -2816, -7936, -12800, -17664, -20224, -21504, -20992, -18688, -14592, -8704, -1792, 3072, 6656, 8960, 10752, 12800, 14336, 13568, 10752, 7936, 5120, 3328, 256, -4096, -7680, -11008, -12800, -13056, -12544, -10752, -7168, -2816, 1792, 5888, 9728, 13312, 16640, 19200, 18688, 15872, 11008, 5120, -512, -6144, -11008, -15360, -17664, -18944, -18944, -17664, -15104, -10752, -4864, 512, 4864, 6912, 8704, 10496, 12288, 12800, 11520, 9984, 8448, 6400, 3328, -768, -4608, -8192, -10752, -12032, -12544, -12032, -10240, -6912, -2048, 2816, 7168, 11008, 14592, 17664, 18688, 16640, 12800, 7936, 2048, -4096, -9216, -13568, -16128, -17920, -18432, -17920, -15872, -11776, -6400, -1536, 2816, 5888, 7680, 9728, 11520, 12544, 12800, 11776, 10752, 8448, 5632, 1536, -3328, -6400, -9472, -11008, -12288, -12800, -11520, -8960, -4608, 512, 5376, 9984, 13056, 15616, 16384, 16128, 13568, 9728, 4864, -1536, -7680, -12544, -15104, -16128, -16640, -16896, -16384, -13312, -7936, -3584, 512, 3328, 6400, 8960, 10752, 11776, 11776, 12032, 12288, 11264, 8448, 3840, -1536, -5376, -8192, -9472, -10752, -12288, -11776, -9984, -6656, -2048, 3072, 7936, 11520, 14080, 14848, 14592, 13056, 9984, 5632, 512, -5376, -9984, -12544, -14336, -15104, -15872, -15104, -13312, -9728, -5632, -2304, 1280, 4096, 6400, 8192, 10240, 11776, 13056, 13824, 13312, 10240, 6144, 1280, -2816, -5120, -7168, -8960, -11264, -12288, -11008, -8448, -4352, 0, 4608, 8192, 11264, 12288, 12544, 12288, 10240, 7168, 2816, -2560, -6656, -9472, -11520, -13312, -14848, -14592, -13056, -10496, -7424, -4864, -2560, 768, 3840, 6912, 9216, 10240, 12800, 15104, 15360, 13056, 8448, 3840, 512, -2816, -5376, -8704, -11520, -12544, -11520, -9216, -6400, -2816, 2048, 6656, 9728, 11008, 10752, 10496, 9984, 7936, 4096, -1280, -6144, -7936, -9472, -11008, -13056, -13824, -12544, -10240, -7936, -6144, -3328, -768, 3072, 5632, 7424, 8448, 11008, 14080, 15360, 13568, 9472, 4608, 1280, -1024, -3072, -5888, -8960, -11264, -10752, -8960, -6656, -3840, -512, 3840, 6656, 8448, 7936, 7936, 7424, 7168, 5376, 1536, -3328, -6912, -7680, -9472, -11264, -12288, -11520, -9984, -8704, -7168, -4608, -2048, 1024, 4352, 5888, 7936, 10240, 13056, 14848, 14336, 10752, 6400, 3072, 512, -1792, -4096, -6912, -9216, -9984, -9472, -7936, -5376, -3072, 768, 3584, 5376, 6400, 5888, 5888, 6400, 5888, 2816, -1024, -4096, -5376, -6656, -8704, -9984, -10240, -8704, -7936, -7680, -5888, -4352, -768, 2304, 4096, 5888, 7936, 10752, 13824, 14592, 12544, 7424, 3584, 1792, 1024, -768, -3840, -6656, -8192, -8192, -7936, -6144, -4096, -1280, 1280, 2048, 2560, 2304, 2560, 4096, 4864, 3584, 1024, -2048, -3584, -4096, -5376, -7424, -8704, -8448, -7680, -7424, -6656, -5120, -2560, 512, 2816, 5120, 7168, 10240, 13056, 14080, 13056, 8448, 4352, 2304, 1536, 1024, -2304, -5120, -7168, -8192, -7424, -6400, -5120, -2816, -512, 768, 1024, 256, 1536, 3072, 4608, 4096, 2048, -1280, -2560, -3584, -4352, -5120, -5888, -6400, -6656, -7168, -6656, -5376, -3072, -512, 1536, 3328, 5120, 7424, 10240, 12288, 12288, 9472, 5888, 3328, 2048, 1792, 768, -1536, -3840, -5632, -6144, -6144, -5376, -4096, -2560, -1536, -2816, -3840, -2560, 256, 3072, 3840, 2304, 1024, 768, 256, -1280, -2816, -4608, -4608, -5632, -6400, -7424, -6912, -4864, -1792, 1024, 2560, 3584, 5376, 8960, 11776, 12288, 10240, 6912, 4096, 3328, 2816, 2816, 1280, -1280, -3584, -4864, -5376, -6144, -4864, -3584, -3328, -4352, -5376, -5376, -2816, 256, 2816, 3072, 1280, 768, 512, 1280, 1536, 0, -1536, -4096, -5120, -6400, -6656, -5120, -3072, -1024, 256, 1280, 2816, 6400, 9728, 11776, 10496, 8448, 5376, 4352, 3840, 3840, 3584, 2048, -768, -3584, -5888, -6912, -6656, -5376, -5120, -5632, -6656, -6400, -5120, -1792, 1280, 2560, 2560, 2048, 1280, 1536, 1536, 1280, 256, -1792, -3584, -5120, -5888, -5376, -4352, -2816, -1024, 512, 1792, 4352, 7424, 9728, 10240, 9472, 7680, 5888, 5376, 5120, 4352, 3584, 1280, -1536, -4864, -6656, -7424, -6400, -6144, -6912, -7168, -7168, -6656, -4608, -1024, 1536, 2304, 2048, 1024, 1280, 2560, 3072, 2816, 768, -2048, -3840, -4608, -4608, -3840, -2816, -2560, -1280, 256, 2048, 4096, 6656, 8960, 8960, 7936, 6144, 5632, 5376, 5632, 5376, 4096, 1280, -3072, -6144, -7680, -7936, -7424, -7936, -8192, -7936, -8192, -5632, -3072, 0, 1792, 2816, 3072, 2560, 2816, 3840, 3328, 2560, 512, -2560, -3328, -4096, -4352, -3584, -3584, -3072, -1536, 0, 2560, 5120, 6656, 8192, 7680, 7424, 6912, 6656, 7168, 6656, 5632, 3328, -512, -4096, -6400, -7680, -8192, -8448, -8960, -8960, -8704, -7168, -4864, -3072, -1280, 256, 1280, 2304, 2816, 4096, 4352, 4608, 2816, 768, -1024, -2560, -3072, -3328, -3072, -3328, -3584, -2560, -1024, 2048, 5120, 6912, 7936, 7936, 7168, 7424, 7936, 7680, 6656, 4352, 1280, -2304, -5888, -8192, -9472, -9216, -8704, -8960, -8704, -8192, -6144, -4096, -1792, 512, 1024, 1536, 2560, 4096, 4352, 3840, 3072, 2048, 768, -1280, -2816, -2816, -2560, -2816, -3072, -2816, -1280, 768, 3328, 5632, 7680, 8192, 6912, 6400, 6400, 7168, 6912, 4864, 1792, -2048, -5632, -7936, -8704, -8192, -7680, -7168, -7936, -7936, -7424, -5376, -3072, -1024, 256, 256, 768, 2560, 4096, 4608, 4608, 3584, 3072, 768, -1280, -2048, -1792, -2048, -2560, -3072, -3072, -1280, 1536, 4096, 6656, 7680, 7424, 6144, 6400, 6656, 7424, 5888, 3328, -512, -4096, -6656, -8192, -8448, -7680, -7680, -7680, -7680, -7424, -6400, -4608, -3072, -1280, -512, 512, 2048, 3584, 4608, 4096, 4608, 3584, 2560, 1024, 0, -1280, -1024, -1792, -2304, -3584, -2560, -768, 2304, 4864, 6656, 6656, 5888, 5888, 6656, 7424, 7168, 5376, 1792, -2560, -4864, -6400, -6656, -6912, -6912, -7424, -7680, -8192, -7936, -6912, -4864, -3328, -2304, -1792, 0, 2304, 4608, 6144, 6656, 5376, 3328, 2304, 2048, 1024, -512, -1536, -2304, -2816, -2816, -1792, 1024, 4096, 6144, 6656, 5376, 4864, 5632, 6656, 7424, 5888, 1792, -2560, -4352, -4864, -4864, -5888, -6400, -6400, -6400, -6656, -6656, -7424, -6656, -4352, -3584, -2304, -1792, 256, 3072, 5376, 6656, 5888, 4608, 3328, 2816, 2816, 1536, -1024, -1536, -2560, -2560, -2304, -512, 2304, 5120, 6400, 5888, 4608, 4608, 5888, 6656, 6144, 2560, -1280, -3328, -4352, -3584, -3840, -4352, -5120, -6144, -6400, -7424, -7936, -8192, -7168, -5632, -4096, -3328, -2048, 512, 3584, 6400, 6912, 6912, 5632, 4352, 3840, 3328, 2560, 1280, -768, -1536, -2048, -1536, 256, 2816, 4608, 5120, 3328, 2816, 3840, 4864, 5120, 3584, 1024, -1024, -3072, -3072, -3072, -3072, -3584, -4352, -5888, -7680, -8960, -9472, -7936, -6656, -5120, -4096, -3072, -1024, 2304, 5632, 7168, 6656, 5632, 4352, 3584, 3840, 2816, 2048, 1536, 512, 0, -512, 1024, 2816, 4096, 4096, 3072, 1792, 2048, 3328, 3328, 2560, 256, -1280, -2048, -2048, -2048, -1792, -1792, -2560, -5120, -6656, -8704, -9216, -8448, -7936, -7424, -6400, -4864, -3072, 1024, 4608, 6912, 7168, 5888, 5632, 4608, 4864, 4352, 3584, 2304, 1792, 1024, 0, 512, 2048, 3584, 4096, 3072, 512, 0, 512, 1280, 1536, 512, -1024, -1792, -1536, -512, -512, -768, -1280, -2816, -4864, -7168, -9472, -9472, -9472, -8704, -7424, -6144, -4608, -2048, 1792, 5120, 6400, 6400, 6400, 5632, 5376, 5376, 5376, 4864, 3840, 2816, 1536, 1536, 1536, 2560, 2816, 1536, -512, -1280, -1280, -512, 0, 0, 0, -1024, 0, 512, 1024, 512, -512, -2048, -4096, -6400, -8704, -9984, -10752, -9984, -8448, -6656, -5376, -4096, -1024, 2816, 5632, 6400, 6912, 6400, 5888, 5888, 6144, 6400, 5632, 4352, 3328, 2560, 2304, 3072, 2560, 1024, -1280, -3072, -3072, -2816, -2304, -2048, -1536, -1280, 256, 1024, 2048, 2560, 1792, 1024, -1792, -4608, -6656, -8704, -9984, -11008, -10752, -8704, -7168, -5632, -3328, 512, 3584, 4608, 5376, 5888, 6912, 7680, 8192, 7936, 7168, 5888, 5120, 5120, 3840, 3584, 2560, 512, -1280, -3328, -3840, -4096, -4096, -3072, -3072, -1280, 256, 1280, 2048, 2048, 2560, 2048, 0, -3328, -5888, -6912, -8448, -10240, -11264, -10496, -8192, -6144, -4352, -1536, 768, 2304, 4352, 5632, 6400, 7424, 8704, 9984, 9216, 8192, 6656, 6400, 5888, 4864, 2816, 256, -2304, -4096, -4608, -4352, -4864, -5376, -4352, -2048, 0, 1024, 1792, 2048, 2560, 2816, 1536, -1024, -3328, -5376, -6400, -8960, -10240, -10496, -9472, -6656, -5376, -3328, -2048, -768, 1536, 3840, 5888, 6912, 8960, 10240, 10496, 9728, 8448, 7936, 7424, 6144, 4096, 1280, -1280, -4096, -5888, -5888, -5888, -4608, -3584, -1536, 512, 768, 1024, 1792, 2816, 3328, 1792, -1280, -3328, -5376, -6400, -8192, -10240, -10752, -9472, -7168, -5376, -3584, -3328, -2304, 256, 2816, 5632, 6912, 8448, 9984, 11008, 10752, 10496, 8448, 7424, 6400, 4608, 1792, -1536, -4352, -6400, -6144, -5888, -5376, -4096, -2304, 512, 1536, 1280, 1280, 2560, 3840, 3072, 768, -2048, -4096, -5632, -7424, -9984, -11264, -10752, -8704, -6912, -5632, -5376, -4352, -2048, 1024, 4864, 7424, 10240, 12288, 13568, 13056, 12544, 11008, 9728, 7168, 4864, 1536, -2304, -4864, -6912, -7680, -7680, -6144, -4096, -2560, -768, 768, 1536, 1280, 1536, 2304, 2816, 1792, 512, -1792, -4096, -6400, -8704, -9472, -9472, -8448, -7936, -7168, -6912, -6144, -5120, -2560, 2048, 5632, 8960, 11776, 13312, 13568, 13824, 12544, 11776, 9472, 5888, 2304, -1792, -4608, -6144, -7680, -8192, -7168, -5632, -3072, -1280, 256, 1536, 1024, 2048, 2304, 2816, 2304, 768, -768, -3328, -5376, -8192, -9472, -9728, -8960, -8704, -8192, -8192, -8192, -6912, -3584, 1280, 6144, 9728, 12288, 14080, 14336, 14336, 13824, 12800, 10240, 5888, 1024, -2560, -4608, -6144, -6656, -7424, -7424, -6144, -4352, -1280, 512, 2304, 2304, 1536, 1536, 1792, 3072, 2816, 1536, -1792, -4608, -7680, -9216, -9216, -9472, -8960, -9728, -10240, -10496, -9216, -6144, -512, 5120, 8960, 12032, 14080, 15360, 15872, 15872, 15616, 12032, 6656, 1792, -3072, -4608, -5632, -6144, -7168, -8448, -7936, -6144, -3072, -512, 1792, 2304, 1280, 1024, 1280, 2816, 3584, 3328, 1792, -2048, -6144, -9472, -10496, -9728, -8704, -9472, -11264, -12800, -11776, -8448, -2560, 4096, 9216, 12544, 14592, 15616, 16384, 16896, 16640, 14080, 8704, 2816, -3584, -6144, -6656, -6656, -6144, -7680, -8704, -8448, -6144, -1792, 1280, 3072, 2560, 1280, 1536, 2304, 4096, 5632, 5376, 2560, -2560, -8192, -11520, -11264, -9728, -9728, -12032, -15616, -15360, -12288, -5376, 2816, 8704, 13056, 15360, 16128, 16896, 17920, 17664, 16128, 11520, 4608, -2560, -6912, -6912, -5888, -5120, -7168, -9216, -9472, -8192, -4352, -512, 2048, 2304, 1280, 1536, 2048, 3840, 6144, 7680, 6400, 1280, -5632, -10496, -11264, -10240, -9728, -12800, -16384, -18432, -15872, -9472, -768, 7424, 13312, 15872, 16896, 17664, 18688, 19968, 18432, 13824, 6656, -1280, -6400, -8192, -7424, -6144, -6912, -8704, -9472, -9216, -6656, -2816, 1280, 3840, 3840, 2816, 2304, 3840, 6656, 8960, 8448, 3584, -3584, -9472, -12544, -12032, -11520, -13056, -16128, -18432, -16896, -10752, -2560, 5632, 12544, 16384, 17664, 17664, 17920, 19200, 18688, 15104, 8704, 1024, -5120, -7680, -7680, -6400, -6144, -7424, -9216, -10240, -8960, -5632, -512, 4096, 5120, 4352, 3584, 3840, 6912, 9984, 10496, 6912, -1024, -8192, -12288, -13824, -13568, -15104, -16640, -18688, -18176, -14080, -5888, 4096, 12544, 17152, 17920, 17408, 18176, 19712, 19968, 16640, 10240, 2560, -4352, -7936, -8704, -7168, -6144, -6656, -7936, -10240, -10240, -7680, -2560, 2560, 5376, 4608, 3840, 4096, 6656, 10240, 12288, 10240, 3328, -5120, -11264, -14080, -15616, -16128, -17664, -19456, -19456, -16128, -8960, 1536, 10496, 16896, 19200, 18176, 18176, 19200, 19712, 17152, 11264, 4352, -2560, -6400, -8704, -8960, -7424, -6912, -7168, -8960, -10240, -8960, -4608, 256, 4096, 5376, 5120, 4864, 6400, 9728, 12032, 11008, 5888, -2304, -8704, -12800, -15104, -16640, -18432, -19456, -18944, -16896, -11008, -2304, 6912, 14848, 18176, 17664, 17920, 18176, 18688, 17152, 12288, 6400, 512, -4608, -7168, -8448, -7424, -6400, -6400, -7936, -9984, -10496, -7168, -2560, 2048, 4864, 5120, 5888, 6912, 9216, 11520, 11520, 7936, 1024, -5632, -11520, -14848, -17152, -18944, -19200, -18688, -16896, -12800, -5376, 4096, 12544, 17152, 18688, 18432, 18432, 18944, 17664, 13568, 8448, 2304, -2816, -6400, -8704, -8960, -7936, -6912, -7680, -9728, -11008, -8448, -4096, 1536, 4608, 6144, 6912, 7680, 9728, 11520, 11776, 8704, 2560, -4096, -10240, -15616, -17920, -19712, -19456, -18432, -16896, -13312, -7936, 512, 9216, 15360, 18176, 18432, 17664, 18176, 17408, 14592, 11264, 5120, 512, -4352, -8192, -9216, -8448, -7936, -7936, -10240, -11776, -10496, -7424, -1280, 4096, 6912, 8704, 8960, 10496, 12544, 13056, 10496, 4352, -2816, -8704, -14336, -18176, -20224, -20480, -19456, -17408, -14592, -9216, -2560, 5376, 12288, 16384, 18176, 18176, 18688, 17664, 15616, 12288, 8192, 2816, -1280, -5376, -7936, -8704, -8704, -9472, -11008, -12288, -11520, -8704, -3584, 2048, 6400, 8704, 10496, 11008, 12544, 13056, 11008, 6656, -512, -6912, -12544, -16640, -18944, -19712, -18944, -17920, -14848, -10752, -5120, 2304, 9728, 14336, 16384, 17152, 17664, 18176, 16896, 13568, 9472, 4096, 256, -3840, -7680, -8448, -9984, -9728, -10496, -11520, -10752, -8960, -3840, 1792, 6400, 9216, 10496, 11520, 12544, 12544, 10240, 5888, 256, -5120, -10496, -15104, -18176, -19200, -18688, -16640, -14592, -11520, -7168, -1536, 5632, 10752, 14336, 16128, 17152, 18176, 17920, 15104, 11264, 7168, 3072, -768, -4864, -8192, -10240, -10496, -11776, -12032, -11776, -9472, -5120, -512, 5120, 8704, 11520, 12288, 13312, 13568, 10752, 6656, 1024, -3840, -8960, -13056, -16640, -17920, -17920, -17408, -15616, -12800, -8704, -3840, 2304, 7168, 11520, 13824, 16384, 18176, 18432, 17152, 13568, 10240, 6144, 2048, -2560, -6912, -9472, -10496, -12544, -13568, -13568, -10752, -6400, -2048, 3584, 7936, 11008, 13312, 14336, 14336, 11776, 7680, 2816, -2048, -6656, -11008, -15104, -17920, -17664, -17408, -15872, -14080, -11264, -6400, -1024, 4352, 9216, 12288, 15872, 17664, 17664, 17152, 14592, 12032, 8448, 4352, -512, -5376, -8448, -10496, -12032, -13312, -13568, -11008, -6400, -2560, 2304, 5888, 9216, 11776, 13312, 13824, 12032, 7936, 3584, -1024, -4864, -8192, -12544, -14592, -15872, -15360, -14592, -14848, -13056, -9984, -4864, 1536, 5888, 9728, 13056, 15360, 17408, 18176, 17152, 14848, 11264, 6912, 1792, -4352, -8192, -10496, -12032, -13312, -13824, -11776, -7936, -3072, 1792, 5632, 8960, 11520, 13056, 13568, 11776, 8448, 4608, 512, -3072, -6656, -10752, -14080, -15616, -15360, -14336, -14592, -14080, -11776, -7424, -2048, 2560, 6912, 10752, 14080, 16640, 17920, 17664, 15616, 12544, 8704, 4096, -1280, -5888, -9216, -11520, -13056, -13824, -12800, -8960, -4352, 768, 4352, 7424, 9472, 11264, 13056, 12032, 9984, 5376, 1536, -2048, -5120, -7936, -11264, -13312, -14848, -15360, -14848, -14848, -13056, -9984, -5632, -1024, 3584, 7936, 12288, 15872, 17920, 17664, 16640, 14592, 11520, 7168, 1792, -3840, -7936, -11264, -12800, -13568, -12800, -9984, -6144, -1536, 2816, 6144, 8448, 11008, 11776, 11520, 8960, 6400, 3584, 256, -3328, -5888, -8960, -11264, -13568, -14592, -15104, -15104, -14592, -12032, -8448, -3840, 768, 5376, 9984, 14336, 17664, 18432, 17664, 15360, 12544, 9216, 4352, -1280, -6400, -10752, -13312, -13312, -12288, -10240, -6656, -2304, 2304, 5120, 7424, 8704, 9984, 10240, 8704, 6400, 4096, 1536, -1536, -4096, -6912, -8704, -11264, -12800, -14080, -14848, -14592, -13312, -10496, -6912, -2816, 2816, 7936, 13056, 17152, 17920, 17408, 15616, 13568, 11008, 7680, 1792, -3584, -8960, -12544, -13824, -12800, -10240, -6656, -3328, -512, 2304, 5632, 7680, 9728, 10496, 9216, 7168, 5120, 3072, 1024, -1280, -3840, -6656, -10496, -13312, -14848, -15360, -15360, -15104, -14080, -10496, -6400, -1280, 4864, 10752, 15872, 18944, 19200, 17920, 16128, 14080, 11008, 5632, -768, -6144, -10752, -13056, -12800, -11520, -8192, -5632, -3584, -512, 3584, 7168, 8960, 8704, 8448, 7680, 6400, 5376, 2816, 1024, -1536, -4608, -8192, -11776, -14336, -15616, -15616, -15872, -15360, -13056, -9984, -4096, 2816, 9472, 14848, 17920, 19200, 18432, 17152, 14848, 11776, 7936, 2560, -4352, -8960, -12288, -12544, -10496, -7168, -4352, -3584, -1792, 1024, 4608, 7168, 8192, 7424, 6912, 5376, 4864, 4096, 1792, 512, -2816, -5632, -8960, -12288, -14592, -15616, -15360, -15360, -14336, -12032, -7680, -1280, 5888, 12288, 16128, 18432, 19200, 18176, 16384, 13568, 9984, 5120, -512, -5632, -10240, -12288, -11520, -8704, -5376, -4352, -2560, -1024, 2560, 5632, 6912, 7168, 7424, 6656, 6656, 5632, 3584, 1792, -768, -3584, -7680, -11776, -15104, -16640, -16640, -16640, -16384, -14336, -10496, -4352, 3840, 10752, 15872, 18688, 19712, 19200, 17664, 14592, 11008, 6400, 1536, -3072, -7936, -11264, -11776, -9472, -6144, -4096, -2816, -768, 1536, 5120, 6144, 5888, 6144, 5888, 6400, 5888, 4096, 2304, 256, -2560, -5888, -10496, -14336, -16128, -17152, -17152, -16896, -15104, -12032, -6400, 768, 8192, 13824, 17920, 19200, 19456, 17920, 15872, 12032, 8192, 3840, -768, -5376, -9728, -11264, -10496, -7936, -5376, -3840, -2816, -512, 2048, 4608, 6144, 6912, 7168, 7424, 7424, 6144, 4352, 2048, -512, -4352, -8960, -13824, -16896, -18688, -18944, -18176, -16896, -14080, -8960, -1536, 6144, 12800, 17664, 19712, 20224, 18944, 16128, 13056, 9728, 5632, 512, -4352, -8960, -10752, -9984, -8192, -6144, -4352, -2816, -1280, 1536, 3328, 5120, 7168, 7936, 8448, 7424, 5888, 3840, 2560, 768, -3072, -7680, -13056, -16640, -18688, -19200, -18176, -17152, -14848, -10496, -4608, 2816, 9728, 15360, 19200, 19712, 18944, 16384, 13568, 10752, 7936, 3840, -1792, -6400, -9728, -10240, -9472, -7424, -6144, -3840, -2816, -512, 2304, 4352, 7168, 8448, 9216, 8448, 6912, 4608, 3328, 1024, -2048, -6656, -12288, -16640, -19200, -19456, -18432, -17408, -14848, -11008, -4608, 2816, 9472, 14848, 18432, 19456, 18688, 16128, 13056, 10240, 7168, 3328, -1536, -5888, -8960, -10496, -10240, -8448, -6144, -4096, -2304, -512, 1792, 4608, 7424, 9728, 10752, 9728, 7936, 5376, 2816, 768, -2560, -6656, -12032, -16640, -19200, -20224, -19200, -17664, -14848, -9984, -4864, 1792, 8448, 13824, 18176, 19712, 19200, 16896, 13312, 9984, 6912, 3840, -512, -5632, -8960, -10496, -10496, -9216, -6912, -4352, -2048, 256, 2816, 5632, 8448, 10496, 12032, 11520, 8960, 5376, 2816, 1024, -1792, -6144, -11776, -16896, -19712, -20736, -20224, -18688, -15872, -11264, -6144, -512, 5888, 12032, 17664, 20224, 20224, 17920, 14592, 11520, 8448, 5120, 1280, -4608, -9216, -11008, -10496, -9472, -8192, -5888, -3584, -768, 2048, 5120, 8704, 11520, 13568, 13312, 10496, 6912, 4096, 1792, -1280, -6144, -12032, -17664, -21248, -22016, -21504, -18944, -15872, -11264, -5632, 256, 6144, 12032, 16896, 19968, 19456, 17664, 14592, 11008, 7936, 4352, 1280, -3328, -8448, -11008, -11776, -10496, -7936, -5632, -3072, 0, 2816, 6144, 9984, 12544, 14592, 14848, 12288, 7680, 3840, 1024, -2048, -6656, -13312, -18944, -22016, -22784, -21248, -18944, -15360, -11008, -5376, 256, 5632, 11520, 16640, 19968, 20224, 17408, 13824, 10240, 6656, 4352, 1792, -2304, -7936, -11520, -11776, -10240, -7936, -5376, -2816, 0, 2048, 5376, 9984, 13056, 15360, 15360, 13312, 9216, 4864, 1024, -2304, -6400, -12544, -18176, -22272, -23552, -22784, -20224, -16128, -11520, -6144, 0, 5632, 11008, 16640, 19200, 20480, 17920, 14592, 11264, 7680, 4096, 512, -3584, -7936, -11776, -13312, -12032, -8960, -5376, -2304, 256, 3072, 6656, 11264, 15104, 17408, 17408, 15104, 10752, 5632, 1536, -2816, -7424, -12544, -18432, -22272, -24576, -24320, -22016, -17152, -11776, -5888, -1024, 4096, 9728, 15104, 19456, 20992, 18944, 15616, 11520, 7936, 5120, 768, -3584, -7680, -11264, -13056, -13056, -10496, -6656, -2816, 768, 3328, 6400, 11264, 15616, 18176, 18432, 15104, 11520, 7168, 2304, -2560, -8448, -13568, -17920, -21248, -23808, -24576, -23296, -18944, -13568, -6912, -1536, 3840, 8960, 13568, 18176, 20480, 19712, 16896, 13056, 8704, 5120, 768, -3840, -7680, -11520, -13568, -14080, -12288, -8192, -4352, 256, 4096, 7424, 12032, 15872, 18688, 19712, 17152, 12800, 7680, 2304, -2560, -8192, -14080, -18688, -22016, -23808, -24064, -23040, -19456, -13824, -6912, -1024, 4352, 8192, 12288, 16384, 18944, 19968, 17408, 14080, 9728, 4352, 256, -3840, -7168, -9984, -12032, -13312, -12544, -9472, -5376, -768, 4096, 7936, 11776, 15616, 17920, 19200, 17920, 14080, 9216, 3328, -2304, -8192, -14336, -18432, -21504, -22784, -23808, -23296, -20736, -15616, -7680, -1280, 4608, 8192, 11520, 14848, 18176, 19456, 17920, 14592, 10240, 4608, 256, -4352, -7168, -8960, -11520, -13312, -12800, -9984, -6400, -1792, 3840, 8448, 12288, 15360, 17152, 18688, 17920, 15360, 10752, 4864, -2048, -8704, -14592, -17664, -19712, -21248, -22272, -23552, -21760, -16896, -9984, -2560, 3072, 6912, 9984, 13312, 15872, 18688, 18432, 15616, 11776, 6400, 1024, -3584, -6912, -8704, -10496, -11776, -12288, -11008, -7680, -2816, 3584, 9728, 13568, 16128, 16896, 17664, 18432, 16640, 12288, 5888, -1024, -7936, -14336, -18432, -20736, -21248, -22272, -23296, -22272, -18432, -11776, -3840, 2816, 7168, 10240, 12800, 15360, 18176, 19200, 17664, 13824, 8192, 2048, -3328, -7424, -9984, -11520, -12288, -12800, -12288, -10240, -5376, 2304, 9472, 14592, 16896, 18176, 18944, 19200, 18176, 14080, 8192, 512, -7424, -14080, -18688, -20736, -21504, -22272, -22784, -22528, -19200, -12544, -4864, 2560, 7424, 9984, 12288, 13568, 15872, 18432, 17408, 14848, 8960, 2304, -2816, -6912, -8704, -9984, -10752, -11264, -11776, -10496, -6656, 1280, 8960, 14336, 16640, 17664, 18432, 18688, 18432, 15104, 9472, 2304, -5632, -12800, -18176, -21248, -21248, -21248, -22016, -22528, -20736, -14080, -6144, 1280, 6144, 9472, 12288, 13824, 15104, 16384, 16896, 15104, 10496, 4352, -2304, -6912, -9216, -9728, -9984, -10752, -11520, -10496, -7168, -512, 7168, 13568, 16640, 17408, 18176, 18176, 17920, 14848, 10240, 4096, -3584, -11776, -17152, -20224, -20736, -20480, -21248, -22272, -21248, -16384, -9216, -1024, 4864, 8960, 11776, 13056, 14848, 16640, 17664, 16384, 12544, 6656, -512, -6400, -9728, -10496, -9984, -10240, -11008, -11520, -8448, -2048, 6144, 13312, 16640, 18432, 18944, 18432, 16896, 14080, 10240, 5120, -1792, -9728, -16640, -20480, -21760, -20480, -20992, -21504, -20992, -16640, -9728, -2304, 3328, 7424, 10496, 12544, 14592, 15872, 16384, 15104, 12288, 7424, 1536, -4864, -9216, -9984, -9472, -8960, -9728, -9984, -7936, -2816, 4864, 12032, 16128, 17920, 18176, 18176, 16640, 14080, 9728, 4352, -1024, -8448, -14848, -19456, -21248, -20224, -20224, -20480, -20992, -17920, -11776, -4864, 2048, 6400, 9216, 11008, 13056, 15104, 16128, 15872, 12800, 8704, 3584, -2304, -6912, -8960, -9728, -9216, -9728, -9984, -7680, -3840, 2560, 8704, 13312, 17152, 18688, 18944, 17408, 13824, 9472, 5376, 512, -5376, -11520, -17408, -19968, -20736, -20736, -20480, -20224, -17920, -13056, -7168, -1024, 4352, 8192, 10240, 12288, 14336, 15104, 14592, 11776, 8704, 4608, 768, -5120, -8704, -9984, -8960, -7936, -7680, -6656, -3328, 2048, 7936, 12288, 15616, 17152, 17664, 16896, 13568, 9728, 4096, -1024, -5888, -10496, -14848, -18432, -19968, -20480, -19456, -18944, -16384, -12800, -8448, -2048, 3072, 7168, 8960, 10496, 12800, 14592, 13568, 11264, 7936, 5120, 2560, -2048, -6144, -8704, -8704, -7680, -6400, -5376, -3328, 1280, 5632, 9728, 13312, 15616, 16896, 16640, 13568, 9216, 3840, -1024, -4608, -8448, -11520, -15616, -18688, -20224, -19968, -18432, -15872, -12544, -8448, -3328, 768, 4864, 7424, 9728, 12288, 13312, 12544, 10496, 7424, 5632, 3584, 512, -2816, -6400, -6912, -6400, -5120, -3840, -2048, 1024, 4864, 7680, 10752, 13568, 14592, 15616, 12800, 8192, 3840, -1792, -4608, -6912, -9472, -12800, -16640, -18688, -18432, -16896, -14592, -12544, -9472, -4864, -768, 3328, 5888, 8192, 10496, 11264, 10496, 8960, 7424, 6656, 5376, 2560, -512, -3328, -5376, -4608, -3584, -2048, -1024, 768, 3072, 5376, 7424, 10752, 13056, 13824, 12544, 8192, 3584, -1280, -3840, -5632, -7168, -9984, -14080, -17664, -17408, -15872, -13312, -11264, -9472, -6400, -2816, 1024, 4096, 6144, 8192, 9472, 8960, 7168, 5888, 5888, 5888, 4608, 2048, -1024, -3072, -3072, -2048, -512, 1280, 2304, 3584, 4608, 5888, 7936, 10496, 11520, 11008, 7424, 2816, -2048, -4608, -5888, -5376, -7424, -11008, -15360, -16640, -14848, -12800, -9984, -8192, -6656, -4352, -1536, 2048, 4608, 6400, 7936, 7424, 6144, 4352, 5120, 6144, 6400, 4864, 2048, 0, -1280, -768, 1024, 2816, 3328, 3072, 3584, 4096, 5632, 7936, 9728, 9472, 6912, 2304, -2816, -5632, -6144, -5632, -6400, -9216, -12800, -14592, -13568, -11776, -9472, -7680, -6144, -4352, -2304, 256, 2560, 4096, 5120, 4864, 4352, 3328, 3584, 5376, 6144, 6144, 4864, 2560, 2048, 2304, 3328, 4608, 5120, 3840, 3072, 2816, 3584, 5376, 6912, 7680, 5376, 2048, -3072, -5888, -6144, -5632, -5120, -7424, -10240, -12544, -12032, -10496, -8448, -6656, -5888, -5120, -4096, -2816, -512, 1792, 3072, 3584, 3584, 3328, 3584, 4864, 6656, 7680, 6656, 5120, 2816, 2816, 4096, 5376, 6656, 5632, 4608, 3840, 3584, 3840, 4864, 5120, 4096, 1024, -3840, -7424, -8192, -6912, -5376, -6144, -8704, -10240, -10496, -8448, -7168, -6144, -5376, -5120, -3840, -3584, -2560, -1280, 256, 1792, 2560, 2560, 3072, 4608, 6656, 9216, 8704, 6912, 5376, 4352, 5120, 5888, 6400, 6144, 4864, 2816, 2560, 2304, 3072, 4096, 3584, 768, -4096, -8192, -8704, -6912, -4864, -5120, -6912, -8704, -8960, -7936, -6912, -5632, -4608, -4608, -4864, -4864, -5120, -3840, -1792, 512, 1536, 2048, 2304, 4608, 6656, 9728, 10496, 9472, 7168, 5376, 5888, 6400, 6912, 6400, 5120, 3328, 1792, 768, 1280, 2304, 2816, 1024, -3584, -7936, -8960, -7424, -5120, -4608, -5888, -6656, -8192, -7424, -6400, -5888, -3840, -4352, -4608, -5376, -6400, -5888, -3840, -1536, 0, 1280, 1536, 4096, 6400, 9472, 11520, 11008, 9216, 6912, 6400, 7168, 7680, 7424, 6656, 4096, 1792, -512, -512, 512, 768, -512, -3840, -7936, -9728, -8960, -5888, -3840, -3840, -4864, -5888, -6656, -5888, -5376, -3840, -3072, -4608, -6144, -6912, -6400, -4864, -2304, -768, 512, 1280, 3072, 4864, 8192, 10752, 11520, 10496, 7936, 7168, 7936, 8448, 9472, 8448, 6656, 3584, 1024, -512, -768, -768, -1280, -4608, -8704, -11008, -10752, -7936, -5120, -4608, -4352, -4864, -4608, -4096, -3328, -2304, -2048, -3328, -5632, -8192, -8192, -7168, -4864, -2816, -1536, -512, 1792, 4608, 7936, 10752, 11776, 11776, 10496, 9216, 8192, 8960, 9984, 9984, 7680, 4352, 1280, -768, -768, -768, -1792, -4864, -8192, -9984, -10496, -9216, -6656, -4352, -3072, -3328, -4608, -5120, -3584, -1792, -1536, -2816, -5888, -8192, -8704, -7168, -5888, -3840, -2304, -512, 2304, 4352, 7168, 9472, 11264, 12288, 11520, 9728, 8192, 8960, 10496, 11520, 9472, 5888, 2560, 256, -768, -1280, -2048, -5120, -8960, -11264, -11264, -10752, -8704, -6144, -3584, -2560, -3072, -3584, -2816, -1536, -512, -1280, -3840, -6400, -8192, -7424, -6144, -4864, -3840, -2560, 256, 2560, 5120, 7936, 10240, 11520, 12288, 11008, 9984, 9984, 11520, 13056, 11008, 7168, 3840, 512, -1024, -2048, -3328, -5120, -8704, -10752, -11520, -11520, -9216, -6656, -3328, -2048, -2816, -3328, -2048, -512, 256, -1024, -3328, -5632, -7680, -8448, -7168, -6400, -4608, -3072, -1280, 768, 3328, 6400, 9472, 11776, 12032, 11520, 10240, 10496, 12032, 13568, 12544, 8960, 5376, 2560, 512, -1536, -2816, -5632, -8192, -11008, -12800, -12800, -12032, -8704, -4352, -2304, -2304, -3072, -2304, 768, 1792, 1024, -2048, -4608, -6400, -7936, -7936, -6912, -5376, -4096, -2816, -2048, 512, 4352, 7936, 11520, 12032, 11264, 10240, 11008, 13824, 15360, 14848, 10752, 6656, 3584, 1024, -1280, -3584, -6656, -9472, -12032, -13824, -13568, -12544, -9728, -5632, -3328, -2304, -1792, -768, 1536, 2816, 1536, -1280, -3584, -5632, -7168, -7936, -7680, -7424, -6144, -4608, -3840, -512, 3584, 7424, 10752, 11520, 12032, 11520, 12288, 14336, 16128, 15104, 11776, 7424, 4352, 1280, -1024, -2816, -5888, -9216, -12544, -13568, -13312, -12288, -10240, -7424, -5376, -4096, -2816, -512, 1280, 1536, 768, -1280, -2560, -3328, -4352, -5376, -6400, -6656, -5888, -4864, -3840, -2048, 1280, 5120, 7936, 9728, 10752, 10496, 11776, 14080, 15872, 16128, 12800, 9216, 6144, 3072, 1280, -1792, -5120, -8448, -11776, -13056, -13056, -12288, -10240, -8448, -6912, -5120, -3840, 0, 2304, 1792, 256, -1536, -2560, -2816, -4096, -5632, -6400, -7680, -7168, -6400, -5376, -2816, 512, 4352, 7168, 8192, 10496, 12032, 14080, 16384, 16896, 16384, 13824, 10496, 8192, 4864, 1024, -2304, -6144, -9472, -12288, -13824, -14080, -13056, -10496, -8448, -7424, -6144, -3840, 0, 3328, 3584, 2048, 256, -1280, -1536, -2560, -4352, -6144, -7680, -8192, -8448, -8192, -5632, -2304, 2304, 5376, 6400, 8960, 11520, 14336, 17152, 18176, 18176, 16128, 12544, 9472, 6400, 2816, -1280, -4864, -8192, -11520, -13824, -15104, -13824, -11008, -9216, -7936, -6912, -4608, -768, 2816, 3328, 2304, 512, -768, -1536, -2304, -3328, -5120, -6400, -7424, -8448, -7680, -5888, -2304, 512, 2816, 4864, 7168, 10240, 13056, 16128, 17408, 18176, 16896, 14080, 11264, 7936, 4096, 256, -3840, -7680, -10496, -12800, -14592, -14336, -11776, -9472, -8192, -7680, -5376, -1792, 2048, 4352, 3072, 1280, 768, -512, -1536, -2816, -4864, -5888, -6912, -8448, -8704, -7168, -4864, -1536, 768, 3328, 6144, 9728, 13056, 15872, 17920, 18432, 17408, 15360, 12288, 9728, 5632, 1536, -3328, -6912, -9984, -11776, -13568, -13312, -12288, -10752, -9472, -9216, -6400, -2304, 1024, 2816, 2304, 1792, 2048, 1536, 512, -1536, -3328, -5120, -6144, -7168, -7936, -7680, -6912, -4864, -2560, 1024, 4864, 8448, 11520, 14592, 17152, 18944, 18944, 17920, 15360, 12032, 7936, 2560, -2048, -6400, -9216, -10752, -13056, -14336, -14336, -13056, -10240, -8960, -7168, -4096, -1024, 1792, 1792, 2560, 3072, 3328, 2816, 768, -2048, -4608, -5376, -6400, -7424, -8448, -8448, -7680, -5120, -2048, 2816, 6912, 10752, 13824, 16384, 18432, 19712, 19456, 17664, 14336, 8704, 3584, -1280, -5120, -8192, -11008, -12800, -14592, -15104, -14592, -12032, -9984, -7936, -4352, -1280, 1536, 2048, 2304, 4352, 4864, 4096, 1280, -2304, -3328, -4608, -5376, -6656, -8448, -9472, -8960, -7168, -3840, 256, 4608, 8704, 12032, 14848, 17408, 19456, 19712, 19456, 16640, 12032, 6400, 1536, -3072, -6144, -9472, -12544, -14592, -15872, -16384, -14848, -12800, -10240, -6144, -3072, 768, 2304, 3328, 5632, 6656, 6656, 4352, 1024, -2304, -5376, -6400, -7680, -9216, -10496, -11264, -10496, -6912, -2048, 3072, 7936, 11264, 14592, 17408, 19712, 20736, 20480, 18432, 14336, 8704, 3072, -1536, -4864, -7680, -10496, -13568, -16640, -17408, -16640, -14336, -11264, -7680, -4352, -2048, 512, 2560, 5888, 7936, 8192, 6400, 2560, -1024, -3584, -5120, -6400, -7936, -9984, -11520, -11520, -8960, -4352, 512, 5632, 9472, 13056, 16128, 18432, 20224, 19968, 18944, 15872, 11008, 5120, 512, -3072, -6144, -8704, -12544, -15616, -17664, -17920, -16128, -12288, -8960, -5888, -2816, 0, 2304, 5120, 7936, 9216, 8192, 5120, 1792, -2304, -4608, -6144, -7680, -9728, -12032, -12800, -11264, -7424, -2304, 2560, 6912, 11520, 15360, 18176, 19968, 20480, 19968, 17408, 13824, 8448, 3328, -1280, -4608, -7424, -11264, -14592, -17408, -18944, -16896, -13824, -10496, -7680, -4608, -1280, 2048, 4864, 6656, 8448, 8192, 6144, 3328, -1024, -3840, -5632, -6144, -7424, -10240, -11264, -10752, -7424, -3584, 0, 3840, 7936, 12288, 16128, 17664, 18944, 18944, 18432, 16384, 12032, 6912, 2816, -1024, -4352, -8448, -12800, -16896, -19968, -19968, -17408, -13824, -9728, -6400, -2816, 1024, 4608, 7936, 9728, 10240, 8704, 5376, 1280, -3072, -5888, -7168, -8704, -11008, -12800, -13056, -9984, -5632, -1536, 2560, 6656, 11776, 15616, 17920, 19200, 20224, 19456, 17152, 13312, 8704, 4608, 1024, -2816, -6912, -11520, -16128, -19456, -19968, -17920, -14592, -11264, -7424, -3840, 0, 3584, 6656, 8960, 9984, 8704, 5888, 2304, -1792, -4608, -5888, -7680, -10240, -12544, -13056, -10496, -6144, -2304, 1280, 4864, 9984, 14080, 17152, 18944, 19712, 20224, 18432, 14336, 9984, 6144, 3072, -1280, -5888, -10752, -15360, -18688, -19968, -18944, -15872, -12288, -8448, -4608, -1536, 2560, 6400, 8704, 9472, 8704, 6656, 4096, -512, -3840, -5888, -7168, -8192, -10752, -11776, -11264, -7936, -4096, -1024, 2816, 7168, 11264, 14336, 16384, 17664, 19200, 18688, 16128, 12800, 9472, 5632, 1536, -2560, -6912, -12032, -17408, -20736, -20480, -17408, -13312, -9984, -6400, -3328, 512, 4352, 7424, 9216, 9472, 8192, 5888, 1024, -3584, -6144, -6656, -6656, -9216, -11264, -11520, -9216, -5120, -1792, 2304, 6400, 9728, 12544, 14848, 16896, 19200, 19712, 17152, 13312, 9984, 6656, 3584, -768, -5376, -11008, -16640, -20736, -21504, -18944, -14336, -10240, -6912, -3840, -512, 3840, 6912, 9472, 9728, 8960, 6656, 2048, -2816, -5888, -6656, -6912, -8704, -10752, -11520, -10240, -6912, -3328, 1024, 4864, 8448, 11520, 13824, 15360, 17152, 18432, 17152, 14592, 11264, 8192, 5120, 1280, -2816, -8192, -14080, -18432, -20992, -19456, -15872, -11776, -7936, -5376, -1280, 1536, 4864, 7424, 8704, 8448, 6656, 3072, -1536, -4352, -5632, -5888, -7168, -9728, -10752, -9728, -6912, -3584, 256, 3584, 6912, 10240, 12288, 13568, 15872, 17408, 17152, 14848, 11264, 8192, 5376, 2304, -1280, -5632, -11008, -16128, -19456, -19200, -15872, -11776, -7680, -6144, -3328, 0, 2560, 5120, 7168, 7936, 6912, 3072, -1280, -4096, -5120, -4864, -5376, -7424, -8960, -8960, -6912, -4096, -1536, 2304, 5376, 8448, 10496, 12032, 13568, 15616, 16128, 15360, 13056, 9984, 6912, 3840, 768, -3328, -8448, -14080, -18432, -19200, -17152, -13312, -9472, -6656, -4608, -1792, 1024, 3840, 6656, 6912, 6400, 3584, 0, -2560, -3840, -4096, -4864, -6144, -7936, -8192, -6912, -4352, -1280, 1280, 3840, 6656, 8960, 11008, 12544, 13824, 14592, 14592, 13312, 10752, 7424, 4608, 2560, -768, -5888, -11776, -16384, -18176, -16896, -13568, -9984, -6912, -4864, -2816, 0, 1280, 4096, 5632, 5888, 3840, 256, -2560, -3840, -4608, -4352, -4352, -5120, -6144, -5632, -3584, -1024, 1792, 4096, 6400, 7936, 9216, 10496, 12032, 12544, 12544, 11776, 10496, 8192, 5376, 3328, 768, -3584, -8448, -13056, -15360, -15360, -13312, -9984, -7168, -5120, -3584, -1792, 256, 2304, 3584, 4096, 2560, 256, -2560, -3840, -3584, -3840, -3840, -3840, -4352, -3584, -2816, -1024, 1280, 3328, 5632, 7424, 8448, 8960, 9984, 11008, 11520, 11520, 10752, 8960, 6656, 4352, 1792, -2560, -6400, -9728, -12288, -13568, -13568, -11776, -8448, -5888, -4096, -3328, -2048, -768, 1024, 2304, 1792, 256, -1536, -2560, -3328, -3072, -3072, -2048, -1792, -1536, -512, 768, 1536, 2560, 3584, 5888, 7168, 7424, 7680, 7424, 8704, 9984, 10240, 9216, 7680, 5376, 3328, 256, -3840, -6912, -9216, -11264, -12288, -11520, -9216, -6656, -4352, -3328, -2560, -1536, -512, 512, 768, -768, -1536, -2560, -3584, -3328, -3072, -1792, -768, 256, 512, 1280, 1536, 2560, 3840, 4864, 6400, 6400, 6656, 6656, 7424, 8704, 8960, 8192, 7424, 5120, 3328, 1024, -3072, -5120, -6912, -8448, -9728, -10496, -9216, -6912, -4864, -3328, -2560, -2048, -2048, -1792, -1280, -1280, -1792, -2304, -3328, -4608, -3840, -3072, -1280, 768, 1792, 2560, 2560, 2816, 3328, 5120, 6912, 6912, 5888, 5120, 5120, 6144, 6912, 6400, 6656, 5888, 4352, 1792, -1536, -3328, -4096, -5120, -6656, -8192, -8448, -7168, -5120, -3328, -3072, -3072, -4096, -3840, -3840, -3072, -2560, -3328, -3328, -4096, -3072, -1792, 0, 2304, 3584, 4608, 4608, 3584, 2816, 3584, 4608, 5376, 4352, 2560, 2816, 3840, 5120, 5376, 5120, 5120, 4352, 2304, 512, -1280, -2560, -3584, -5376, -6400, -7424, -6912, -5888, -4352, -3328, -3328, -4096, -4608, -5120, -5120, -3072, -2048, -2304, -3840, -4096, -2560, -512, 2304, 3584, 4608, 4608, 4608, 3584, 3584, 4352, 5120, 4608, 3072, 2048, 2816, 3328, 4096, 4608, 4864, 4096, 2304, 768, 256, 256, -1536, -3328, -5120, -5888, -5376, -4864, -3840, -3840, -3584, -4352, -5376, -5632, -5632, -4352, -2816, -2816, -3328, -4608, -3584, -1024, 3072, 5376, 5632, 5888, 5376, 5120, 4352, 4096, 4096, 3072, 1792, 256, 1280, 1792, 2048, 3072, 3840, 3840, 2560, 768, 0, 768, 256, -1280, -3072, -4864, -4864, -4096, -2816, -2304, -2816, -3584, -5888, -7168, -7424, -6144, -4352, -3328, -3840, -4864, -4608, -2560, 1792, 5632, 7424, 7680, 6144, 5632, 4608, 4352, 4352, 2816, 1024, -512, -768, 512, 1024, 2048, 3328, 4096, 3328, 1792, 1024, 2304, 2048, 512, -1792, -4096, -3840, -3584, -3072, -2560, -3072, -3072, -4864, -6400, -7424, -6400, -4608, -3840, -4608, -5376, -4864, -3072, 256, 4096, 7168, 8704, 8192, 7424, 5888, 4608, 3840, 2816, 1024, -768, -2560, -2048, -1280, 0, 1792, 3072, 3584, 2560, 1536, 2560, 3840, 3328, 768, -1792, -2816, -3328, -3328, -3328, -3072, -3584, -5120, -7168, -7936, -7424, -5120, -3328, -3584, -4608, -4608, -3840, -768, 3072, 6144, 8448, 8192, 7424, 6400, 5632, 4096, 2816, 768, -768, -1536, -1792, -2048, -768, 512, 2048, 2816, 2816, 2304, 2560, 3328, 3328, 2048, 0, -1536, -2304, -2304, -2304, -2560, -2816, -4608, -6656, -7680, -7424, -5632, -4352, -4608, -5120, -5376, -4352, -1792, 1536, 5376, 8704, 9728, 8704, 7424, 5376, 4352, 3328, 2048, 256, -2048, -3328, -3840, -2560, -768, 1280, 2560, 2816, 2560, 2816, 3840, 4096, 2816, 768, -1024, -1792, -2304, -2048, -2560, -3328, -4864, -6656, -6656, -5888, -4352, -3840, -4096, -4352, -4352, -3840, -2304, -512, 2560, 6656, 7936, 7936, 6144, 5376, 4608, 3328, 1536, 256, -1536, -2048, -2304, -2048, -1024, 0, 1536, 2560, 3072, 3840, 3584, 3328, 2304, 1280, -512, -1792, -2048, -2304, -2048, -2560, -4608, -6400, -6400, -5888, -4608, -4096, -4864, -5632, -4608, -4096, -2560, 0, 2560, 6144, 8448, 8960, 7424, 5632, 4352, 3328, 1792, -768, -2048, -3072, -3584, -3072, -1792, -768, 1024, 2560, 3584, 4096, 4352, 4096, 4096, 2816, 768, -1792, -2816, -2560, -1792, -2560, -4864, -6656, -6912, -5888, -4352, -3584, -3584, -4352, -4608, -4096, -3072, -768, 1792, 5120, 6656, 7168, 6144, 5120, 4096, 3840, 2560, 512, -2048, -3328, -2816, -1792, -512, -512, 1024, 1536, 2304, 3584, 4352, 4864, 3840, 2048, -1024, -3072, -3840, -2816, -1280, -2048, -4608, -6400, -6144, -4352, -2304, -1536, -1792, -2816, -3840, -3840, -3328, -1536, 1024, 2816, 3840, 4096, 3840, 4096, 3328, 2304, 1280, 256, -768, -1792, -1280, -512, 768, 1280, 1536, 2048, 2560, 3584, 4352, 4608, 3584, 768, -2048, -3840, -3328, -2304, -1536, -2304, -4864, -5632, -4864, -3328, -1536, -1024, -1280, -2048, -3328, -3840, -2560, -1280, 1280, 2048, 2048, 2048, 2816, 3584, 3584, 2048, 512, 256, 256, 512, -512, 256, 1280, 1536, 1792, 1792, 1536, 2816, 3328, 4096, 3328, 768, -1536, -3328, -3584, -2048, -1280, -1536, -3840, -5120, -3840, -2560, -1280, -512, -1536, -1536, -2048, -3072, -2560, -2048, -768, 1280, 768, 768, 1280, 1792, 2560, 1536, 512, -768, -512, 512, 2048, 2304, 3072, 2816, 2048, 2304, 2048, 2816, 3328, 2816, 2560, 0, -3072, -5120, -5376, -3328, -2560, -2816, -3584, -4096, -2560, -768, 1024, 2048, 1280, 512, -512, -1024, -1024, -1792, -1024, -1024, -1280, -1792, -2048, -1280, 0, 512, 512, 0, 256, 1536, 2816, 3840, 4864, 4864, 4608, 3584, 2560, 3072, 3072, 2816, 1536, -1536, -4096, -5888, -5888, -4352, -3328, -3072, -3072, -3328, -2048, -512, 2048, 3328, 3328, 2048, 1024, 256, -768, -768, -768, -1024, -2816, -4096, -4096, -3328, -2304, -1280, -1024, -512, 256, 1536, 3328, 4352, 5376, 6144, 5888, 4608, 3584, 2560, 2816, 3072, 2048, -768, -4096, -6656, -6912, -5120, -4352, -5376, -5376, -4352, -1792, 512, 2560, 4096, 4864, 4608, 3328, 2560, 1280, 512, -512, -1280, -3584, -5632, -6656, -5376, -3840, -2816, -2816, -1536, -512, 1536, 4096, 5632, 6912, 7168, 7168, 5888, 4352, 3328, 2560, 3072, 1792, -1024, -4608, -7424, -8192, -6144, -5120, -5376, -5632, -4608, -1280, 1280, 3584, 4864, 5376, 5120, 4352, 3328, 2048, 1280, -512, -2304, -4608, -6656, -6656, -5376, -3584, -3072, -2816, -2048, -512, 2560, 4096, 5376, 6144, 6400, 6912, 6144, 4096, 2816, 1536, 1792, 1536, -1024, -4096, -6400, -7424, -6400, -4864, -4864, -5632, -4608, -1792, 1536, 3840, 4352, 4608, 4864, 4608, 3840, 2560, 2048, 768, -1280, -3840, -6144, -7680, -6912, -4864, -3840, -3840, -3328, -2048, 1280, 3584, 5120, 6400, 7168, 7936, 7680, 6656, 4608, 2816, 2304, 1792, -512, -3584, -6912, -8448, -7680, -6400, -6400, -6912, -6656, -3840, 512, 4352, 5632, 5888, 5888, 5632, 5632, 4608, 3584, 1792, -1024, -3584, -6144, -7936, -7680, -6400, -4864, -4096, -4096, -2816, -768, 2048, 4352, 6144, 7424, 7936, 7936, 7424, 5632, 4352, 3072, 2048, 512, -3072, -6656, -9216, -8960, -7680, -6656, -6656, -7424, -5120, -1280, 3328, 6144, 6656, 6656, 6656, 7168, 5888, 4864, 2816, 256, -2304, -6144, -8704, -8448, -7680, -6144, -5376, -5376, -4352, -2816, 256, 2304, 4864, 6912, 8448, 8704, 7680, 7168, 6144, 5376, 4096, 1792, -1536, -5888, -8960, -10240, -9216, -8448, -7936, -8192, -6912, -3328, 768, 4352, 6400, 7424, 8704, 8704, 7680, 5888, 4352, 2816, 0, -3584, -6912, -8192, -8448, -7680, -6656, -5376, -4608, -3840, -2304, 256, 2816, 5632, 7424, 8192, 8448, 7680, 7168, 5888, 5376, 3328, 768, -3840, -7680, -9472, -9728, -8960, -8960, -8448, -7168, -4608, -1280, 2560, 5632, 7680, 9472, 9216, 8192, 6656, 5376, 3584, 1792, -1536, -4864, -7168, -8704, -8192, -6912, -5376, -5120, -5376, -5120, -2816, 1280, 4352, 6400, 7424, 7680, 8448, 8960, 7936, 6912, 4864, 2048, -1792, -6400, -9472, -10752, -10496, -9984, -8960, -7680, -5632, -2816, 1024, 5376, 8192, 9728, 9984, 9216, 7424, 5632, 3840, 2304, -1024, -3840, -6144, -8192, -8960, -7936, -6144, -4608, -4608, -4864, -3584, -768, 2816, 5376, 6912, 7936, 8192, 8704, 8704, 7936, 6912, 4608, 256, -4864, -8448, -9984, -9728, -10240, -9984, -8960, -7168, -4352, -768, 3584, 7168, 9472, 10496, 10240, 8704, 7680, 6144, 4608, 1792, -1536, -5120, -7680, -9216, -8704, -7680, -6656, -6656, -6912, -6656, -4096, 0, 4096, 6656, 7680, 8448, 9216, 10752, 11008, 9728, 6912, 2560, -2560, -6912, -9984, -11008, -11008, -11008, -10240, -8704, -6656, -3584, 512, 5376, 9216, 10752, 10240, 9216, 8448, 7680, 6144, 4096, 1280, -2816, -6400, -8704, -8960, -8192, -7424, -7680, -7936, -7936, -6912, -3840, 1280, 5376, 6912, 7680, 8704, 10752, 13056, 12288, 10240, 5120, -768, -5376, -8192, -9728, -10240, -11008, -10752, -9728, -7680, -4608, -768, 3840, 7424, 10240, 10496, 9984, 8704, 7936, 7168, 5120, 2560, -1024, -4608, -7424, -8448, -8704, -8704, -8960, -9472, -9728, -8704, -5376, -1536, 3072, 5632, 6656, 8448, 11264, 14080, 14336, 11776, 6656, 1280, -2816, -6400, -9216, -10752, -12032, -12032, -11008, -9472, -6144, -2816, 2304, 6400, 9216, 9728, 9728, 10240, 9984, 9984, 7168, 4352, 768, -2560, -5888, -7680, -9472, -9728, -10752, -11264, -11008, -10240, -7680, -4096, 768, 4352, 6656, 8704, 11264, 14592, 15616, 13312, 8704, 2304, -1792, -5376, -7680, -9728, -11776, -12544, -12288, -9984, -6912, -3328, 1280, 5632, 8192, 8960, 8960, 9472, 10496, 11008, 8448, 4864, 1024, -2048, -4096, -6400, -8192, -9984, -10752, -11264, -10752, -10496, -8448, -5120, -1024, 2816, 5376, 7168, 9728, 12544, 14848, 13824, 9216, 4096, -1536, -4096, -5376, -7168, -9216, -11776, -12544, -10752, -7424, -4352, 0, 3328, 6656, 7680, 7680, 8960, 10496, 12032, 10496, 6400, 2304, -1024, -3072, -4352, -7168, -9728, -11776, -13312, -13056, -12544, -9984, -5888, -2304, 1024, 3072, 5888, 9984, 13824, 16896, 15872, 11008, 5888, 512, -2560, -4096, -6656, -9216, -11520, -13056, -12800, -9472, -5120, 0, 4096, 6912, 7168, 7424, 9728, 12032, 12800, 11264, 7168, 3328, -512, -2560, -4096, -6656, -8960, -11520, -14080, -14592, -14336, -11264, -6912, -3328, -1024, 1280, 4352, 8704, 13568, 16384, 16384, 11776, 7424, 3328, 256, -2048, -4352, -7168, -9984, -12288, -13056, -10752, -6656, -2048, 2304, 4608, 5120, 6144, 8704, 11776, 13568, 12032, 8448, 3840, 1024, -1024, -3328, -5632, -8960, -12032, -14336, -15104, -14336, -12288, -8192, -4608, -2048, 768, 3584, 8448, 13312, 16640, 16384, 12544, 7936, 4352, 1280, -768, -3328, -6400, -9216, -11520, -12544, -11264, -7936, -3584, 1792, 4096, 5376, 5376, 7936, 12288, 14592, 13568, 9728, 5120, 2048, -768, -2304, -5376, -8960, -12032, -14592, -15872, -15872, -13824, -9728, -5632, -3072, -1280, 1792, 6656, 12544, 16896, 17664, 14336, 9472, 6144, 3840, 1536, -1024, -4352, -7680, -11008, -13568, -12032, -8704, -4608, -512, 2304, 3584, 4352, 7424, 11776, 14848, 14336, 11008, 6400, 3328, 512, -1280, -3840, -7680, -11520, -15104, -16896, -16640, -14592, -11008, -7168, -4096, -2560, 512, 5376, 11264, 16896, 18176, 15872, 11008, 7168, 4864, 3328, 768, -3072, -6400, -10752, -13056, -12800, -9728, -4608, -768, 1280, 3072, 4352, 7680, 12288, 15104, 14848, 11520, 6656, 2816, 0, -1536, -3840, -7424, -11520, -16128, -18176, -17408, -14848, -10496, -7168, -4864, -3072, -1024, 4096, 10752, 15872, 17920, 15616, 11008, 7424, 5376, 4096, 2048, -1536, -5120, -8960, -11520, -11520, -9472, -5376, -1536, 768, 2048, 3584, 6144, 10752, 13824, 14848, 12032, 7424, 4096, 768, -768, -3072, -6912, -10752, -15872, -18688, -18944, -16896, -13312, -8704, -5888, -3584, -1280, 3072, 9728, 15360, 18432, 17408, 12544, 8704, 5888, 4352, 2560, -768, -4608, -7936, -10752, -10752, -9216, -5120, -1024, 1280, 2304, 2816, 5632, 9472, 13056, 14080, 11776, 7424, 3328, 512, -2304, -3584, -6400, -9728, -13568, -17152, -18432, -17152, -13568, -8960, -5888, -4352, -2560, 1536, 8192, 14080, 17664, 17152, 13568, 9216, 6656, 4864, 3072, 512, -3328, -6656, -9472, -10240, -9216, -6144, -1792, 768, 2304, 3328, 5120, 9216, 12544, 13312, 12032, 8192, 4352, 768, -3072, -4864, -7424, -9728, -13312, -16896, -19200, -18432, -14336, -9216, -5120, -3840, -2560, 512, 6400, 12288, 16128, 16128, 13312, 9984, 7168, 5120, 3584, 1280, -1536, -4864, -7680, -9728, -8960, -6400, -2048, 1024, 2048, 2816, 4352, 8448, 12032, 13824, 12032, 8704, 4608, 1024, -2304, -4864, -7168, -10240, -13568, -16640, -19200, -18944, -15360, -10496, -5632, -3840, -3072, -512, 4608, 11008, 15104, 16128, 14080, 10496, 7936, 6912, 5120, 3328, 768, -2816, -6144, -8960, -8704, -6656, -2816, 512, 2048, 2304, 2816, 5632, 9472, 12032, 12544, 9984, 5632, 1536, -1792, -4864, -6656, -9216, -12288, -15360, -18944, -19712, -16896, -12032, -6656, -3328, -2048, 256, 3840, 9216, 13568, 16128, 14336, 11520, 7680, 5632, 4096, 2560, 1280, -1792, -4864, -8192, -8704, -6400, -1792, 2048, 4096, 4352, 4352, 5888, 9472, 12288, 13056, 10240, 5632, 1024, -3584, -6144, -8448, -9984, -12544, -15616, -18432, -19712, -16896, -12032, -6912, -3328, -1280, 256, 3328, 7680, 12032, 15104, 14592, 12032, 7936, 5888, 4352, 3840, 1536, -1280, -4608, -6656, -7680, -6144, -2560, 2048, 4864, 5376, 5120, 5632, 7680, 10240, 12288, 10496, 6400, 768, -4352, -7424, -8192, -9472, -11776, -15104, -17920, -18688, -16640, -11776, -6912, -3584, -1024, 768, 3840, 7424, 10496, 13312, 13824, 11520, 7936, 4864, 3840, 3840, 2304, 256, -3584, -6656, -6912, -5376, -2048, 2560, 4352, 5888, 5888, 5888, 8192, 9984, 11520, 11264, 7424, 1792, -4096, -8192, -10240, -10752, -12544, -15616, -18432, -19456, -17664, -12800, -7168, -3072, -512, 1280, 4352, 7936, 11008, 12288, 12544, 11264, 8704, 6144, 3840, 3328, 2304, 1280, -2048, -6144, -6912, -5376, -1792, 2560, 5120, 6400, 7424, 7424, 8192, 9216, 10496, 10496, 8704, 3584, -3072, -8960, -11776, -12544, -13312, -15616, -18944, -19968, -18688, -14336, -7936, -3584, 512, 2560, 4864, 7936, 11264, 13824, 13568, 12032, 8704, 6144, 4096, 2304, 1024, -512, -3072, -6400, -7168, -5632, -1792, 2304, 5888, 8192, 9216, 9216, 9216, 9472, 10752, 10752, 8448, 3840, -3584, -9216, -12800, -14592, -14336, -15872, -18944, -20736, -19712, -15104, -9216, -3840, 512, 2816, 5120, 7936, 11264, 14336, 14336, 13056, 9984, 6656, 3840, 1792, 256, -768, -3328, -6656, -8448, -7936, -3584, 2304, 6400, 9216, 10496, 10240, 10496, 10240, 11264, 11264, 8960, 4352, -3328, -9984, -13824, -15616, -16384, -17664, -19456, -20736, -19968, -16128, -9984, -3840, 1024, 3584, 6144, 8960, 11520, 13824, 14336, 13568, 10496, 6400, 3584, 1792, 768, -1024, -3584, -6656, -8704, -7936, -3840, 2304, 6400, 9216, 10496, 11008, 11264, 11008, 11776, 11520, 8960, 4096, -2304, -7936, -12544, -16128, -17664, -19200, -19968, -21504, -20224, -16896, -11520, -5632, 0, 3328, 5888, 8960, 12288, 14336, 14848, 13568, 11008, 7680, 4864, 2560, 1024, -1792, -4608, -6656, -8448, -7680, -4352, 1024, 6144, 9472, 11264, 12800, 12800, 12544, 11776, 11008, 8960, 4096, -1792, -7680, -13312, -16640, -19200, -19968, -21248, -21760, -20992, -17920, -12800, -6656, -1024, 3584, 6656, 9984, 13568, 16128, 16384, 15104, 12544, 8960, 4608, 1536, -512, -3328, -6400, -8960, -10240, -9216, -5632, 768, 6656, 9728, 12032, 13824, 15360, 15616, 14592, 12800, 9984, 5120, -1280, -6656, -12544, -16896, -20480, -22272, -23296, -23808, -22528, -18944, -13824, -8704, -3072, 2048, 6144, 10240, 14080, 17408, 17920, 16896, 14080, 10496, 6656, 3584, 1536, -2304, -6400, -9472, -11008, -9984, -7168, -2304, 3840, 8192, 10496, 12288, 15104, 16640, 16640, 14848, 11520, 6400, 1280, -4352, -9728, -15616, -19712, -23296, -24832, -25600, -24064, -20224, -16384, -11264, -5888, -512, 6144, 10752, 14592, 18432, 19712, 18944, 16128, 12288, 8448, 5376, 2560, -1792, -6912, -11008, -11520, -10496, -7424, -3584, 1024, 6656, 10240, 12544, 14848, 16896, 17664, 16384, 12288, 7424, 1792, -3328, -7936, -13568, -18688, -22784, -25600, -26112, -24320, -21248, -17152, -13056, -7424, -1792, 4352, 9472, 14080, 18432, 20736, 19712, 17152, 14080, 10240, 6400, 3072, -1024, -5632, -10240, -11520, -10752, -7936, -4864, -1024, 3840, 8704, 12288, 14080, 16128, 17152, 16896, 14592, 10496, 5120, -1024, -6400, -11776, -17664, -22528, -26624, -28160, -27136, -24320, -20224, -16128, -9984, -3328, 3840, 9984, 15360, 19200, 22528, 23296, 20736, 16896, 11264, 6912, 3328, -768, -5632, -10496, -12800, -12288, -9728, -6656, -3328, 1536, 7424, 11776, 14080, 15872, 16896, 17664, 16128, 12288, 6656, 1280, -3584, -8448, -14592, -21504, -26880, -29440, -28928, -26112, -22528, -18688, -13568, -6656, 256, 7936, 14592, 19968, 23296, 24320, 22528, 19200, 15360, 10496, 5632, 256, -4864, -9728, -13056, -13568, -12288, -9216, -5632, -1536, 4864, 9984, 13568, 15872, 16640, 17664, 17152, 14080, 9216, 3584, -1536, -7168, -13824, -20224, -25600, -28416, -29696, -28160, -25088, -21248, -15616, -8960, -1536, 6656, 13568, 19200, 22784, 24576, 24576, 22272, 18176, 12800, 7424, 2560, -2304, -7680, -11264, -13568, -12800, -11520, -8192, -4864, 512, 5888, 11008, 14080, 15872, 16896, 16896, 15872, 12544, 7680, 2816, -3072, -9984, -17920, -24320, -28672, -30208, -30208, -27904, -24064, -18944, -12288, -4608, 4352, 12032, 17920, 22528, 25088, 25344, 24320, 20480, 15616, 9472, 3584, -2304, -6656, -11008, -13056, -13312, -12288, -10240, -6400, -1536, 4352, 9472, 13312, 14592, 16128, 16384, 15872, 14080, 9216, 4352, -2048, -8704, -15872, -22016, -27136, -29952, -30208, -28160, -25344, -21248, -14592, -6912, 2560, 10752, 17152, 21760, 24576, 25856, 25856, 23296, 17664, 11776, 5376, 256, -5376, -9728, -12544, -13824, -12544, -11264, -8960, -4608, 512, 6144, 11264, 14080, 16384, 17152, 16128, 15104, 11776, 7424, 1792, -5376, -13056, -20224, -26624, -29952, -31232, -29952, -27648, -24064, -17920, -10240, 0, 8704, 16128, 21760, 24576, 26624, 26880, 25344, 20992, 15104, 7936, 1024, -5120, -9472, -11776, -13056, -13056, -12800, -11264, -7168, -2048, 4352, 9728, 13568, 15360, 16640, 17152, 16384, 13824, 10240, 4608, -2560, -10240, -18176, -25088, -29440, -30976, -30208, -28928, -26368, -20992, -13312, -3584, 5632, 13568, 19712, 24064, 27136, 27904, 26624, 23808, 19456, 12800, 5376, -2816, -8448, -11008, -12288, -13568, -14336, -14336, -11776, -6912, 512, 7424, 12288, 14848, 15872, 16128, 15872, 14848, 12544, 8448, 1280, -6912, -14592, -22272, -27648, -30464, -30208, -29184, -27136, -23296, -17408, -7936, 2048, 10752, 17664, 22528, 26112, 28160, 28160, 25600, 21248, 15360, 8448, 768, -5888, -9984, -11776, -13312, -14592, -14592, -13056, -8960, -3584, 3840, 9728, 13824, 16128, 16640, 16896, 14848, 13056, 10240, 4352, -2816, -11264, -19456, -25856, -29184, -29696, -28416, -27136, -24576, -19712, -12032, -2816, 7168, 14848, 20736, 24832, 27904, 28672, 26880, 24320, 19712, 13568, 5888, -2304, -7680, -11520, -13312, -14848, -16384, -15616, -13312, -8960, -2304, 5120, 11264, 15872, 17152, 17152, 16640, 15872, 13824, 8960, 1792, -6144, -15360, -23296, -28160, -30464, -29696, -28672, -26880, -23040, -16640, -7936, 2048, 11008, 18688, 24064, 27904, 29952, 28928, 26880, 23296, 17408, 9984, 1024, -6144, -11008, -14336, -16384, -17152, -17152, -15616, -12032, -5376, 2304, 8960, 14080, 16128, 16896, 16896, 15616, 14336, 11776, 5888, -2560, -11776, -20736, -25600, -28416, -29440, -28672, -27392, -24064, -19200, -12288, -3072, 7168, 15104, 21504, 26368, 29696, 30720, 29184, 26368, 20736, 14336, 5632, -2560, -8960, -13568, -16384, -18176, -18688, -18176, -15104, -9984, -2560, 4864, 11008, 15360, 16896, 17408, 17152, 16384, 13568, 8448, 1792, -6912, -16384, -23296, -27648, -29440, -28928, -27648, -24832, -20992, -15104, -6912, 2816, 11776, 19200, 25088, 28672, 30464, 29952, 27904, 22784, 16384, 8704, 1024, -6144, -12800, -15872, -17664, -17664, -17920, -16640, -12544, -5888, 2048, 8192, 13312, 15616, 16384, 16640, 16384, 14080, 9984, 3840, -4096, -11776, -19456, -24832, -27904, -28160, -27392, -26112, -23296, -18176, -10752, -1024, 8704, 16896, 23040, 27136, 29696, 30976, 30208, 25856, 19968, 12032, 3840, -3840, -11264, -15360, -17920, -18688, -19200, -18944, -16128, -9984, -1792, 5888, 11520, 15360, 16896, 17664, 17664, 15872, 12544, 7424, 256, -8192, -16640, -24064, -27648, -28672, -27904, -26112, -24832, -21248, -14848, -5632, 4608, 13824, 21504, 26368, 29696, 30976, 30720, 28672, 23296, 16128, 7424, -1536, -8704, -13824, -16896, -19200, -20224, -20736, -18432, -12800, -5632, 2304, 8448, 12800, 15104, 17152, 17920, 17920, 15360, 11008, 3328, -5120, -13056, -19968, -24832, -27392, -28416, -27904, -26880, -24064, -18432, -9472, 1280, 10752, 18432, 24576, 29184, 31744, 32512, 30208, 25600, 19200, 10752, 2560, -5632, -12032, -15872, -18432, -20224, -21504, -20992, -16384, -8960, -512, 5888, 9984, 12800, 15616, 17664, 18176, 16896, 13056, 6912, -1536, -9216, -15872, -20736, -24576, -26624, -26880, -27136, -25856, -21248, -13312, -2816, 6912, 14592, 20992, 26368, 30720, 32512, 31232, 27392, 20992, 13568, 4864, -3072, -9984, -14080, -16640, -18688, -20736, -20736, -17152, -10240, -2048, 4096, 7680, 10496, 13312, 15872, 17408, 16896, 14336, 8704, 768, -7168, -13568, -18176, -22016, -24576, -26112, -27136, -26368, -22528, -15872, -6400, 3840, 12032, 18432, 23040, 27904, 30720, 31488, 29440, 23808, 16128, 7936, 256, -6144, -10240, -13312, -16384, -19456, -20992, -18688, -12800, -5632, 256, 4608, 6912, 9984, 13056, 16128, 17152, 15616, 11264, 4608, -3328, -9728, -13568, -17664, -21248, -24576, -26880, -26368, -23808, -17664, -9216, -768, 7680, 14336, 19712, 24320, 28416, 29696, 28928, 24832, 18432, 10752, 3328, -3072, -6400, -9728, -13824, -17920, -20224, -18944, -14592, -8192, -2816, 1024, 3840, 6656, 10240, 14080, 16640, 15872, 13056, 7168, 256, -6144, -10240, -14336, -18688, -22784, -25856, -26112, -24320, -20224, -12800, -4352, 4096, 12032, 17408, 22528, 26624, 29184, 29440, 26112, 20480, 13568, 6144, 0, -4608, -7936, -11520, -15360, -18688, -18944, -16128, -10752, -5376, -1536, 1536, 4096, 7168, 11520, 14336, 15104, 13056, 8960, 3584, -2304, -6656, -10496, -14592, -18688, -22272, -24832, -24320, -21760, -15872, -8192, -512, 6656, 12800, 18176, 23296, 26880, 28416, 26880, 22784, 16384, 10240, 4096, -1024, -5120, -8960, -12544, -16384, -17920, -17408, -13568, -8960, -4608, -1536, 1280, 3584, 7424, 11520, 14080, 13824, 9984, 5376, 1024, -3328, -6400, -10752, -16128, -19712, -22784, -23040, -20480, -16896, -11264, -4864, 2560, 8960, 14592, 19456, 23808, 26624, 26624, 23296, 17408, 12288, 7424, 3328, -1536, -6144, -10752, -14336, -16128, -15616, -13824, -10752, -6912, -4352, -1536, 1280, 4608, 8448, 11264, 12032, 9984, 6400, 2560, 0, -3584, -7424, -12800, -17152, -20224, -21760, -20736, -17920, -13568, -8192, -1280, 6144, 12032, 17152, 21504, 25088, 26368, 24320, 19712, 14336, 9472, 5632, 1536, -3584, -8704, -12288, -14336, -14592, -13312, -12288, -9472, -7168, -4352, -1536, 2048, 5888, 8704, 10496, 9728, 7168, 3840, 1024, -1024, -4096, -9728, -15104, -18688, -19968, -19200, -16896, -13824, -9472, -4864, 1792, 8192, 13568, 18432, 22272, 24320, 23552, 19968, 14848, 11264, 8192, 5120, 512, -5376, -9728, -12032, -12288, -12032, -11776, -10752, -9216, -6656, -3584, -1280, 2304, 5120, 8192, 8960, 7680, 4864, 3072, 2048, -1280, -6400, -12288, -16128, -18176, -17920, -16128, -14848, -11264, -6656, -1536, 5120, 10240, 15104, 20224, 23552, 23808, 21248, 15360, 12032, 9472, 7424, 3328, -2560, -7168, -10240, -11264, -11264, -12288, -12032, -10496, -8448, -5632, -3328, 0, 3584, 7424, 9216, 8704, 6144, 4608, 3840, 1024, -3328, -9984, -15360, -17664, -18432, -17408, -15872, -13056, -8704, -3328, 2304, 7936, 13312, 18688, 22528, 24320, 22272, 17920, 14080, 11520, 8960, 5120, -512, -5888, -9216, -10752, -12032, -12288, -13056, -12800, -10240, -7680, -4352, -2048, 1792, 5888, 9216, 9472, 7680, 5632, 4864, 3328, -768, -6144, -12544, -16640, -18176, -18176, -16384, -13824, -10240, -5120, -768, 5376, 11264, 16640, 21760, 23552, 22272, 18432, 14592, 12288, 9984, 7424, 2816, -3072, -6912, -9216, -10496, -10752, -12032, -12544, -11520, -9472, -7168, -4352, -1024, 3328, 7168, 8448, 7424, 6656, 5888, 4352, 1536, -2816, -8448, -13568, -16384, -16896, -15872, -14080, -11264, -7424, -3072, 2560, 7936, 13056, 18176, 21504, 21760, 19712, 15616, 12800, 10496, 9216, 5632, 512, -4352, -8448, -9728, -10752, -11520, -12288, -11776, -10496, -8704, -5888, -2304, 1792, 6144, 8960, 8192, 7168, 5888, 4352, 2560, -1024, -6656, -12544, -16384, -17408, -16384, -14848, -11776, -8192, -3328, 2048, 7168, 11520, 16640, 19968, 20992, 19456, 15872, 13312, 11520, 9472, 5888, 1536, -2560, -6656, -8960, -10496, -11520, -11776, -12288, -12288, -9984, -6912, -2816, 768, 3584, 5888, 6912, 7168, 6400, 5888, 3840, 512, -4352, -8704, -13312, -15360, -15616, -14336, -11264, -8192, -4352, -768, 4096, 8704, 13824, 16896, 18688, 17408, 14848, 12032, 10752, 9472, 7424, 4352, 768, -3584, -6400, -7936, -9216, -9984, -11264, -12288, -11264, -8448, -5120, -2304, 512, 3328, 5632, 6656, 6144, 5120, 3584, 1280, -1792, -5632, -9984, -12800, -14080, -13056, -11008, -8192, -5120, -1792, 2560, 7168, 11264, 14592, 16640, 17152, 16384, 13824, 11264, 9216, 7168, 4608, 1024, -2304, -5888, -8192, -9984, -10752, -11776, -11264, -9728, -7424, -4864, -3072, -1024, 2560, 5632, 6912, 5632, 3584, 2048, 256, -1536, -4352, -7680, -11008, -12544, -12032, -9728, -6656, -4608, -2560, 768, 4352, 8704, 11520, 13824, 15104, 14592, 13568, 11520, 9472, 7680, 5632, 2816, -768, -3584, -6144, -8704, -10240, -11520, -11008, -9984, -7424, -5376, -3584, -1536, 768, 4096, 5120, 4352, 2560, 768, 0, -1536, -3840, -6400, -8448, -9728, -9472, -7936, -5376, -3072, -1536, 1280, 3840, 6912, 9984, 11776, 12800, 13056, 12032, 11264, 9216, 7424, 5120, 2560, 256, -2560, -4608, -6912, -9216, -10240, -10752, -9472, -7424, -5376, -3584, -1792, 256, 2560, 4096, 2560, 768, -512, -768, -1536, -3072, -5632, -7168, -7680, -7168, -5888, -4096, -2816, -1792, 0, 1792, 4864, 7936, 10752, 12032, 12032, 11776, 11776, 10240, 8448, 5376, 2560, 512, -1536, -3072, -6144, -8448, -9472, -9728, -9216, -7936, -5376, -3584, -1792, -512, 512, 1792, 2048, 1024, -512, -1792, -3072, -3584, -4864, -5888, -6144, -5120, -4096, -2816, -1536, -512, 768, 2304, 4096, 6144, 8448, 9472, 10240, 11264, 11264, 10240, 8448, 5632, 3328, 1280, -768, -2048, -5376, -7680, -8960, -8704, -8192, -7680, -5888, -3328, -1536, -768, -768, -512, -512, -1024, -1792, -2304, -3072, -3328, -3328, -3584, -3584, -2816, -3072, -1024, -512, 512, 0, 768, 2560, 4608, 6912, 8192, 8960, 9728, 10240, 9472, 8192, 5888, 3328, 2048, 512, -1024, -2816, -5632, -6912, -7936, -7680, -7424, -6144, -3584, -1792, -2048, -1792, -2560, -2560, -2560, -2560, -2816, -3072, -3328, -3072, -2816, -2816, -1792, -512, 1024, 1280, 768, -512, 0, 2048, 3840, 5376, 6656, 7680, 8192, 9472, 9472, 8192, 6656, 4096, 2560, 1024, -1024, -2304, -4096, -5376, -6656, -7424, -7168, -5888, -3840, -2816, -2304, -2816, -3328, -3584, -3584, -3328, -3328, -3072, -3328, -3072, -2048, -768, 768, 1536, 2048, 2560, 1792, 256, -768, 512, 2048, 4352, 5632, 5632, 6912, 8192, 9472, 8960, 7424, 4608, 2816, 512, -1024, -2048, -3584, -4352, -5376, -5888, -6400, -5632, -4352, -2816, -2304, -2816, -4096, -4096, -4096, -4096, -3584, -3840, -3584, -2816, -1280, 0, 1024, 1280, 1536, 1792, 1536, 1024, 0, 768, 2048, 4096, 5376, 5120, 6144, 7168, 8704, 8960, 7424, 4352, 2048, 768, 256, -768, -2304, -3840, -5120, -5376, -5888, -5632, -5376, -4352, -3328, -3584, -4608, -5888, -5632, -4352, -3328, -2560, -2304, -2048, 0, 1536, 2304, 2560, 2048, 1536, 1536, 1024, 0, -512, 256, 2560, 4352, 5120, 5632, 6400, 7424, 7936, 7424, 5120, 2560, 512, -512, 0, -1280, -2816, -4608, -5120, -4864, -4864, -4864, -4608, -4096, -3584, -4608, -6656, -6656, -5632, -4096, -3328, -2304, -1536, 256, 1792, 2560, 2560, 1792, 1792, 1792, 1280, 0, -1024, -512, 1792, 3584, 4864, 5632, 6656, 7680, 8192, 7680, 5632, 3328, 1536, 256, -512, -1792, -3328, -4096, -4608, -4864, -4864, -5376, -5376, -4864, -4352, -4096, -5888, -6400, -5888, -4352, -2560, -2304, -1024, 512, 2048, 2560, 3072, 2304, 1792, 1280, 1024, 512, -768, -512, 768, 2304, 4608, 5888, 7168, 7424, 7168, 6912, 6656, 4864, 3072, 1536, 0, -1792, -2816, -3840, -4352, -5120, -5376, -5120, -5632, -5888, -6400, -6144, -6656, -6912, -6400, -5120, -3328, -1280, 768, 2304, 2816, 3840, 4352, 3840, 2560, 1024, 0, -1024, -1280, -1024, 512, 1280, 3328, 4864, 6400, 7424, 7168, 6656, 6400, 5120, 4096, 2816, 512, -1280, -2560, -2560, -2560, -3584, -4352, -5376, -6144, -6656, -7424, -6912, -7168, -7168, -6656, -5888, -4352, -2048, 256, 3072, 3840, 4096, 3584, 3328, 2560, 1536, 0, -1280, -1536, -1280, 256, 1536, 3072, 5120, 6912, 7680, 7168, 6144, 5888, 5376, 4352, 2816, 1024, -1536, -2304, -2560, -2560, -2816, -4096, -4608, -5376, -6144, -6656, -7424, -7168, -6912, -6400, -5888, -4608, -2816, -512, 2816, 3840, 3840, 3072, 2816, 2304, 1536, 256, -1536, -1536, -512, 768, 1792, 2816, 4864, 6656, 7168, 6656, 5632, 5376, 5888, 6144, 4352, 2560, 1024, 0, -512, -1280, -2560, -3840, -5120, -6400, -8192, -9216, -9216, -8960, -8192, -7680, -6656, -4864, -2560, 512, 3584, 5376, 5376, 4352, 3328, 2560, 1792, 256, -1280, -1280, -1536, -1024, 0, 1536, 3072, 4864, 5632, 6144, 5120, 5376, 6144, 7424, 7168, 5120, 3328, 2048, 768, 512, -1024, -2304, -4096, -6912, -8704, -10496, -11264, -10496, -9728, -8960, -7936, -6912, -4608, -768, 3328, 6656, 7424, 5888, 4608, 3584, 2816, 2048, 1024, -512, -2048, -2816, -2304, -1536, 1024, 2304, 4096, 4352, 4096, 4096, 5888, 8448, 9472, 8448, 6656, 4864, 3072, 2048, 256, -1792, -3840, -7680, -10496, -12800, -13568, -12800, -11008, -9728, -8704, -7168, -4352, -768, 3328, 6656, 7680, 6656, 4864, 3584, 3072, 2304, 1024, -512, -2560, -3584, -3328, -1792, 1024, 2304, 3072, 3328, 3328, 4352, 6400, 8192, 10240, 9984, 8192, 6144, 3840, 2816, 2048, 256, -2560, -6912, -11008, -13056, -14080, -13312, -12544, -11520, -10240, -8192, -5376, -2048, 2304, 5888, 7936, 7680, 6144, 4864, 4352, 4096, 2816, 1024, -1792, -3840, -4608, -3584, -1536, 512, 1280, 1792, 2304, 3584, 6144, 8960, 11520, 12288, 11520, 8704, 6400, 4096, 2048, 512, -2816, -6912, -11776, -15104, -16384, -15616, -13568, -11776, -10240, -8960, -6144, -2304, 2048, 5888, 7680, 7936, 6912, 6144, 5376, 4352, 3072, 1024, -1536, -3840, -4864, -4352, -3072, -768, 768, 1024, 1536, 3072, 6400, 9472, 11520, 12032, 12032, 11008, 8960, 5888, 3072, 512, -2560, -6144, -10752, -15360, -18176, -18176, -16128, -14080, -11520, -9216, -5632, -1792, 2304, 5632, 7680, 8960, 8704, 7936, 6144, 4864, 3328, 1536, -768, -3328, -5120, -5376, -4096, -2304, -768, -512, 1024, 2816, 6656, 9728, 11520, 12800, 12544, 12288, 10752, 7936, 4096, 1024, -2304, -5376, -9728, -15104, -18432, -19712, -17920, -15616, -13568, -10496, -6656, -2304, 1792, 4352, 6656, 8704, 10496, 10496, 8960, 6400, 4352, 2304, 0, -2560, -5376, -6144, -5632, -3840, -2304, -1792, -512, 2560, 6400, 9984, 11264, 12032, 12544, 13312, 12800, 9984, 5632, 1536, -2048, -5120, -8704, -13824, -17920, -19968, -19712, -17408, -15616, -12544, -8448, -3840, 768, 4096, 6400, 8192, 11008, 12544, 12032, 9472, 6400, 4096, 768, -2560, -5632, -7424, -6912, -5632, -3840, -3072, -1792, 1792, 6400, 10752, 12032, 12800, 13568, 14592, 14592, 11776, 7936, 2816, -1280, -5632, -9984, -14336, -18432, -20736, -21760, -20736, -18176, -14336, -9216, -4096, 1024, 4864, 7424, 9472, 12288, 14080, 14336, 12288, 8704, 5120, 1792, -2560, -6400, -8192, -8704, -7168, -5376, -4352, -3584, 0, 5120, 10240, 12800, 13056, 13568, 14848, 15616, 13568, 9984, 4608, -512, -4608, -9216, -13568, -17920, -20480, -21760, -22016, -20224, -17152, -11776, -5888, -512, 4352, 6912, 8960, 11264, 14080, 15872, 14592, 11264, 6656, 2304, -2560, -5888, -7424, -8192, -7168, -6144, -5120, -3840, -1024, 3840, 8960, 12032, 12800, 12544, 13568, 14592, 13568, 11008, 6144, 1280, -3584, -8192, -12800, -16384, -1280, 0, -512, -768, -768, -768, -768, -512, -512, 256, 512, 768, 1280, 2048, 2816, 2816, 2560, 2048, 1280, 256, -1536, -3328, -4864, -5376, -4608, -3840, -3328, -2560, -1792, -512, 1024, 2048, 3072, 4352, 7168, 8448, 7424, 5888, 3584, 1792, -1280, -4864, -8448, -10752, -9216, -7168, -6144, -4352, -3328, -2048, 256, 1792, 3840, 5888, 8448, 10752, 10752, 8960, 6656, 3840, 0, -4096, -7680, -11264, -11520, -8704, -6912, -5120, -4096, -3328, -1024, 1024, 3072, 5376, 7424, 10240, 11520, 10240, 7680, 5120, 1536, -3328, -6400, -9728, -11520, -9728, -7936, -6144, -4608, -3840, -2560, -1024, 1280, 4352, 6912, 8960, 11264, 11008, 9472, 6912, 3840, -1024, -4864, -7936, -11264, -11264, -8960, -7680, -5632, -4864, -4096, -2048, 512, 3840, 6400, 8192, 10752, 12032, 10752, 8192, 4608, 0, -4096, -6656, -9984, -11520, -9728, -7936, -6400, -4864, -4608, -3584, -1280, 2816, 5888, 7424, 9984, 11776, 11520, 9728, 6400, 1792, -2048, -4608, -7936, -11264, -11008, -8960, -7680, -6400, -6400, -5120, -2304, 1792, 5376, 6912, 9216, 12288, 13056, 11264, 8192, 3584, -768, -4096, -7168, -10752, -11776, -10496, -8448, -6912, -6144, -5888, -3840, 256, 4096, 6912, 8448, 10752, 12032, 11776, 9728, 5376, 1280, -2304, -5376, -8704, -11264, -11520, -9984, -7936, -7168, -6656, -5120, -2048, 2304, 6400, 8704, 10496, 12544, 13056, 12032, 7936, 2816, -1536, -4608, -7680, -10752, -12288, -11520, -9216, -7168, -6656, -5888, -3072, 1536, 5888, 8448, 9728, 11008, 13056, 12800, 9216, 3840, 0, -3072, -5632, -8960, -12800, -12800, -10240, -7936, -7424, -6912, -4608, 256, 5120, 8192, 9216, 11008, 13312, 14336, 11520, 5888, 512, -2560, -5120, -8448, -12288, -14336, -12544, -9216, -7680, -6656, -4608, -1280, 4352, 8448, 9984, 10240, 11776, 13312, 12544, 8192, 2304, -2048, -4608, -6656, -10240, -13824, -13568, -9984, -7680, -7168, -5888, -3072, 2560, 7936, 9984, 9728, 10752, 13824, 13824, 10496, 4352, -1280, -3840, -5632, -8960, -13568, -15104, -12032, -9216, -7680, -6144, -3584, 1536, 6912, 10240, 10752, 11008, 13056, 14336, 11776, 6656, 768, -3328, -5632, -8448, -12544, -15616, -14080, -10496, -8192, -6656, -4608, 0, 5632, 9728, 11520, 11008, 12288, 14080, 12800, 8448, 2816, -2560, -5376, -7424, -11008, -15104, -15360, -11776, -8960, -7168, -4608, -1536, 3840, 8960, 11520, 11776, 11520, 13312, 13568, 10496, 5120, -1536, -4864, -6656, -9728, -13824, -15872, -13568, -9984, -7424, -4864, -2816, 1536, 7424, 11264, 12288, 11520, 12032, 13312, 12544, 8192, 1280, -4608, -6656, -8192, -11520, -15616, -15616, -12288, -8960, -5888, -3584, -512, 5632, 10752, 13312, 12800, 11776, 12800, 12800, 9728, 3072, -3840, -6656, -7936, -11008, -15104, -16640, -13568, -9472, -6400, -4096, -1536, 4096, 10240, 13568, 13568, 12032, 12544, 13056, 10752, 5632, -2560, -6912, -7936, -9728, -13824, -17152, -16128, -11776, -6912, -4608, -1792, 2560, 7936, 13312, 15104, 13568, 12288, 12800, 11776, 8192, 768, -6144, -8704, -9984, -12800, -16896, -17408, -13824, -8960, -5120, -2048, 1536, 5888, 12032, 15872, 15104, 13312, 12800, 12288, 9472, 3328, -4608, -8960, -10240, -11776, -15872, -18432, -16128, -11008, -6400, -2560, 1536, 5120, 10496, 15104, 16128, 14080, 12544, 11776, 9984, 5376, -2304, -7936, -9984, -10752, -13312, -17408, -17408, -13312, -8192, -4352, -1024, 2304, 7936, 13824, 16896, 16128, 13824, 13056, 11264, 8192, 1536, -6656, -10240, -11264, -13056, -16640, -18432, -15616, -10496, -5888, -1280, 2304, 6400, 12288, 16384, 16896, 15104, 13824, 11776, 8448, 3072, -4352, -9216, -11520, -13056, -15872, -18688, -17152, -12288, -7936, -2816, 2048, 5376, 11264, 16384, 17920, 16384, 14592, 12544, 9216, 5120, -2048, -8704, -12032, -13312, -14848, -17408, -18688, -15104, -10240, -4864, 1024, 4352, 9216, 14848, 18432, 18688, 16640, 14336, 10496, 6656, 1024, -6144, -11264, -14080, -16128, -17664, -18688, -16896, -13056, -7168, -512, 4608, 8192, 13056, 17152, 19200, 18432, 15872, 11776, 7424, 2816, -3328, -9472, -13824, -16384, -17920, -18176, -17920, -14848, -9728, -3328, 3584, 7680, 12288, 16384, 18688, 19456, 17664, 13312, 8704, 3840, -1792, -7936, -12800, -15872, -17664, -18176, -18176, -16896, -12032, -4864, 2048, 6656, 10240, 14848, 18688, 20736, 19456, 14592, 9984, 5888, 512, -5632, -11520, -15872, -18176, -18688, -18176, -17664, -14592, -8192, 0, 6656, 10496, 14080, 17920, 20736, 21248, 16384, 10496, 6144, 1536, -3840, -9984, -15360, -18176, -18688, -17664, -17664, -15872, -10240, -2816, 5120, 9984, 13056, 16640, 19968, 22016, 19200, 12800, 7424, 2816, -2048, -7680, -13568, -17920, -19712, -18176, -16896, -17152, -13568, -5632, 3328, 9472, 12544, 15360, 19200, 22784, 21504, 14848, 8448, 4096, -512, -5632, -12032, -17408, -19712, -18432, -17152, -17408, -15360, -8704, 0, 7424, 12032, 14336, 17664, 21760, 22528, 17664, 10240, 5120, 1024, -3328, -8960, -15616, -19456, -18944, -16640, -16896, -16640, -12032, -3840, 5120, 11008, 13568, 16384, 20736, 22784, 19712, 12800, 6656, 2304, -2560, -7424, -13056, -18176, -19968, -18176, -16896, -16384, -13312, -6912, 2304, 9728, 13824, 15872, 18688, 21760, 20992, 15360, 8704, 3328, -768, -4864, -10240, -16640, -20480, -18944, -17408, -17664, -15616, -10240, -1024, 7424, 12544, 15616, 18432, 22016, 22016, 17920, 11520, 5376, 768, -4096, -8448, -14336, -20480, -19968, -17920, -17920, -16640, -12800, -4608, 5120, 12288, 15872, 17408, 20480, 22528, 19968, 13568, 6656, 1280, -3072, -6656, -11520, -18432, -20736, -18176, -17152, -16384, -14336, -8704, 1024, 9472, 14592, 16128, 18688, 21760, 21248, 16128, 9472, 4096, 0, -4352, -9216, -16128, -20224, -18944, -17920, -17664, -16128, -11264, -2560, 6656, 13312, 15872, 17664, 20736, 21504, 17664, 11520, 5632, 768, -3840, -7168, -13312, -19200, -19456, -17664, -17152, -16384, -13312, -6144, 3584, 11520, 15360, 16640, 18944, 20992, 19200, 13824, 8192, 3072, -1536, -5376, -11264, -17408, -19968, -18944, -18176, -17664, -15360, -8704, 512, 8704, 14080, 16896, 18688, 20224, 19968, 15616, 9984, 5120, 512, -4096, -8704, -14336, -18432, -18944, -17920, -18176, -16896, -12032, -3584, 5376, 12288, 15616, 17408, 19456, 20480, 17664, 11776, 6912, 2816, -1792, -6656, -12800, -17408, -18432, -17920, -17920, -17664, -13824, -6144, 2560, 9984, 14592, 16896, 18432, 19456, 17920, 13312, 8448, 4096, -1024, -5120, -9984, -15104, -17920, -18176, -17664, -17152, -15360, -9472, -1536, 6912, 12800, 15872, 17152, 18432, 18944, 15616, 10496, 6400, 2560, -2560, -7936, -13056, -17152, -18944, -18688, -18688, -17408, -12288, -4096, 4352, 11520, 15360, 16896, 18688, 19200, 16896, 12288, 7424, 3840, -768, -6144, -11520, -15872, -17920, -18432, -18944, -17920, -14080, -6656, 1792, 8192, 13056, 16128, 17920, 18688, 17152, 13056, 8960, 6144, 2304, -4096, -9728, -13824, -16384, -17408, -19200, -19200, -15872, -9216, -1280, 5632, 11520, 15360, 17664, 18944, 17408, 14592, 11008, 7424, 3840, -2304, -7424, -11520, -15360, -17152, -19200, -19456, -16384, -11264, -4096, 2560, 8192, 13312, 16128, 17408, 16896, 15104, 12288, 9216, 6144, 1536, -4352, -8960, -13056, -15360, -17920, -19968, -18432, -14080, -6912, 256, 5120, 9984, 14336, 16640, 17408, 15360, 13056, 10496, 7936, 3840, -2304, -6912, -11264, -14848, -17152, -19200, -18688, -14848, -8960, -2048, 2816, 8192, 12800, 15360, 15616, 14592, 13568, 12032, 9472, 6400, 1024, -4864, -8960, -12288, -15360, -18688, -19456, -17152, -11776, -4608, 512, 5120, 10240, 14336, 16384, 15872, 14336, 12544, 11008, 8704, 3840, -2560, -7936, -11520, -14592, -17920, -19968, -17664, -13312, -6912, -1024, 3328, 8704, 13312, 15360, 14592, 13568, 13312, 11776, 9216, 5632, 256, -4864, -8960, -12800, -16640, -18688, -17920, -14848, -10496, -4352, 1024, 5632, 10752, 14080, 14848, 14592, 14080, 12800, 11008, 8192, 3072, -2816, -7680, -12032, -15616, -18176, -18432, -16128, -11776, -6656, -1536, 3328, 7680, 12032, 13568, 13824, 14336, 13312, 11776, 9728, 6144, 1280, -5120, -9984, -13312, -16128, -17152, -16896, -14592, -9472, -3840, 768, 4608, 9472, 12800, 14080, 15104, 14080, 12544, 11520, 8192, 3840, -2560, -8704, -12800, -15616, -16896, -16896, -14848, -10752, -6144, -1024, 2816, 6912, 11264, 12800, 13824, 14592, 13568, 12544, 9984, 5888, 512, -5888, -11008, -14592, -16384, -17152, -15872, -12800, -8448, -3584, 1024, 4608, 9472, 12288, 13568, 14592, 14080, 13312, 11264, 7680, 3328, -3584, -9728, -13824, -15872, -16640, -15872, -13824, -10752, -6144, -512, 3328, 7168, 10496, 12288, 14336, 14592, 13312, 11520, 9472, 5888, 0, -7168, -12032, -14592, -15872, -16128, -15104, -12800, -8704, -3584, 256, 4096, 8960, 12288, 14336, 15104, 15104, 13824, 11520, 7936, 2048, -5120, -10752, -14336, -15872, -16384, -15360, -13312, -10240, -5888, -1280, 2560, 7168, 11008, 13312, 14336, 14592, 14336, 12544, 9728, 5376, -2048, -8448, -11776, -14336, -15360, -15104, -14336, -12032, -8192, -3840, 0, 4352, 8704, 12032, 14080, 14848, 14592, 13568, 11008, 7680, 2048, -6144, -10752, -13312, -15104, -14848, -14592, -13056, -10752, -6656, -2048, 2816, 7424, 10752, 12800, 14592, 15104, 14080, 12288, 8704, 3840, -3840, -9216, -11520, -13312, -14080, -14848, -14080, -11008, -7936, -4352, -512, 4096, 9472, 12800, 14336, 14848, 14848, 13824, 11008, 5888, -2048, -8448, -10240, -12032, -13824, -14592, -14848, -12288, -8704, -5888, -2560, 2304, 7936, 12288, 13824, 14080, 14080, 14592, 12800, 8192, 768, -7168, -9472, -10496, -12544, -14080, -14848, -12544, -9216, -6912, -4352, 256, 5376, 10496, 12800, 13312, 13056, 13824, 14080, 10496, 3328, -4608, -8192, -8960, -10752, -12800, -14592, -14080, -10496, -8192, -6144, -2560, 2560, 8448, 12032, 12800, 13056, 13824, 15104, 12544, 6144, -2048, -6656, -7680, -9472, -11776, -14336, -15104, -11776, -8960, -7424, -4608, 512, 6400, 11264, 12288, 12032, 13056, 14592, 14336, 9216, 1280, -5120, -7168, -7936, -10240, -13056, -14848, -13312, -9984, -8448, -6400, -2048, 3840, 9728, 12544, 12032, 12800, 14336, 15360, 11776, 3840, -2816, -6400, -7680, -9216, -12544, -15360, -13824, -9984, -8448, -7680, -3584, 2048, 8192, 12032, 11264, 11264, 13056, 15104, 13312, 6656, -1024, -5120, -6144, -7424, -10496, -13824, -14080, -11008, -8704, -8448, -6656, -2048, 4352, 9472, 11008, 10752, 12288, 15104, 15360, 10752, 3328, -2816, -5376, -6400, -9216, -13056, -15104, -13056, -9728, -8704, -8192, -4352, 2560, 8448, 11008, 11008, 11264, 14080, 15360, 11776, 5376, -1536, -4608, -5632, -7168, -10752, -13824, -13312, -9984, -7680, -8192, -6400, -1024, 5120, 9216, 9984, 9984, 12288, 15360, 14592, 9216, 2560, -2816, -4864, -5632, -8704, -13056, -14848, -12288, -8960, -9216, -8704, -3328, 3328, 8960, 10496, 9728, 11776, 15104, 15616, 11264, 5120, -1280, -5120, -5632, -7680, -11776, -14336, -13568, -9984, -8704, -9216, -5632, 256, 6400, 9984, 9984, 10752, 13568, 15360, 13824, 8704, 2560, -2560, -4352, -5376, -9984, -14592, -15104, -12288, -9728, -11008, -8960, -2816, 4096, 9472, 11008, 10752, 13312, 15616, 14848, 10496, 4864, -768, -4096, -5376, -7936, -12800, -15104, -13568, -10240, -9984, -9984, -5632, 1280, 7680, 10240, 9728, 11520, 14848, 16384, 13312, 7168, 1280, -3072, -4352, -5888, -11264, -14848, -14336, -11776, -10240, -11008, -8448, -1792, 5632, 9984, 10496, 11264, 14080, 16384, 15360, 10240, 3328, -1792, -4096, -5376, -8960, -14336, -15360, -13312, -11264, -11008, -10240, -5376, 2816, 8704, 10240, 10240, 12800, 15616, 16384, 13568, 7424, 1536, -2560, -4096, -6400, -12032, -15872, -15616, -13568, -12544, -12032, -8960, -1280, 6656, 10752, 11520, 12544, 14848, 16640, 15104, 9984, 3840, -1280, -4096, -5632, -9472, -14336, -15616, -14336, -12800, -12032, -10752, -5376, 2816, 8448, 10240, 11264, 13568, 16128, 16896, 13824, 7424, 2048, -1536, -3840, -7168, -13312, -16384, -15360, -14592, -13568, -12544, -7936, 256, 7168, 10240, 10752, 13056, 16128, 16896, 14336, 9216, 3584, -768, -3328, -6400, -11520, -15616, -15616, -14848, -13824, -12032, -9728, -2816, 5120, 9216, 10496, 11264, 14080, 16384, 15360, 12032, 7168, 2304, -1024, -3840, -8192, -14336, -17152, -16384, -15872, -14080, -12288, -6912, 2048, 7424, 10496, 12032, 14592, 16896, 16640, 14336, 9984, 4352, 0, -3328, -6912, -12544, -16896, -17408, -17152, -14848, -12288, -9216, -2048, 5632, 9728, 11520, 13568, 16128, 16640, 15616, 13056, 7168, 2816, -1024, -5120, -10240, -15872, -17920, -18176, -17408, -14080, -11264, -6144, 2304, 7680, 10752, 13312, 16896, 17664, 16384, 14848, 10752, 5120, 1024, -3584, -8704, -14592, -18176, -18688, -18688, -16128, -13056, -8960, -1280, 5888, 9728, 12288, 15872, 18176, 17664, 16640, 13824, 8192, 3584, -1536, -6656, -12288, -17408, -20224, -20992, -18432, -14592, -10752, -4608, 2816, 8448, 12288, 16128, 18688, 18432, 17408, 15872, 11776, 5632, 0, -5376, -10752, -16128, -19456, -21248, -20480, -16640, -12544, -7168, -512, 5888, 10752, 14848, 18176, 19200, 18432, 17408, 14336, 8448, 2560, -3072, -8192, -13824, -18688, -21504, -22272, -18688, -13824, -9216, -3840, 2816, 8704, 13312, 17152, 18688, 18688, 18432, 16896, 12288, 5376, -1536, -6656, -12032, -17152, -20480, -22528, -20736, -15872, -10496, -5888, 0, 6912, 12032, 16640, 18944, 18944, 18176, 17152, 14592, 8448, 1024, -5120, -10752, -16384, -19712, -22528, -22528, -18432, -12544, -6912, -1792, 4096, 10240, 16128, 19200, 19200, 18944, 17664, 16384, 11776, 4096, -3328, -8960, -14592, -18944, -22272, -23808, -20736, -14848, -8960, -4352, 1536, 8448, 15104, 18688, 19456, 19456, 18176, 17408, 14848, 7424, -1024, -7424, -12288, -17408, -21248, -24064, -23552, -17920, -10752, -5632, -1024, 5376, 13056, 18688, 19968, 19456, 18688, 17920, 16128, 10240, 1792, -6144, -10752, -15360, -20224, -23296, -23552, -19456, -13312, -7680, -3072, 2304, 9984, 16896, 19456, 19456, 19200, 18944, 17920, 13824, 6144, -3072, -9216, -13312, -18432, -23808, -25600, -23040, -16384, -9728, -5376, -1280, 6400, 15616, 20736, 20736, 19712, 19968, 19456, 16128, 8448, -1280, -8448, -12544, -17152, -23040, -25600, -23552, -18176, -11264, -5376, -2048, 3584, 12544, 19200, 20992, 19712, 19456, 19200, 16896, 11520, 2560, -6912, -11520, -15104, -20480, -25088, -25088, -20736, -13312, -6656, -3072, 512, 8704, 18176, 22016, 20480, 19200, 19712, 18176, 13824, 5888, -4352, -11264, -14592, -18944, -23808, -25344, -22272, -16640, -9216, -3584, -1024, 5120, 14080, 20224, 20992, 19968, 19968, 19200, 16640, 10496, 256, -8704, -13312, -17152, -22528, -26624, -25088, -19456, -12032, -5888, -3072, 1536, 11520, 20736, 23040, 20736, 20224, 20736, 18432, 12800, 2816, -7168, -12800, -15616, -20736, -26112, -26368, -21504, -14592, -7680, -3328, 256, 7680, 17920, 23552, 22528, 20736, 20480, 19200, 15104, 6912, -3840, -12288, -15872, -19456, -24832, -27136, -24064, -17664, -9984, -4096, -1024, 4352, 15104, 23552, 24064, 22272, 22016, 21248, 17152, 9216, -1024, -9728, -15616, -19712, -24576, -28416, -26112, -20480, -13568, -6656, -2048, 3584, 12800, 22784, 25856, 23808, 22272, 21248, 18688, 11776, 1792, -7936, -14848, -18432, -22272, -27136, -27136, -22528, -15104, -7936, -3072, 1280, 8448, 18944, 25344, 25344, 23040, 21504, 19968, 14592, 5632, -4608, -12544, -17920, -21504, -25600, -27648, -24576, -18432, -11008, -5376, -768, 6144, 15616, 24320, 27136, 25344, 23040, 20992, 16640, 8704, -1536, -10240, -16896, -21248, -24576, -27136, -26112, -20992, -13312, -6912, -2048, 3840, 12288, 22016, 27392, 26880, 24064, 21760, 18688, 11520, 1536, -8192, -15616, -20480, -23296, -26112, -27136, -23552, -16128, -8960, -3840, 2048, 9472, 18944, 26112, 27904, 25088, 22272, 19456, 13824, 5376, -4096, -12800, -19456, -22784, -25088, -26624, -25088, -19456, -11776, -5888, -512, 6400, 15360, 23808, 28416, 27136, 23552, 20992, 16640, 8960, -1280, -9984, -16896, -21248, -24320, -26880, -26880, -22016, -14592, -8448, -2816, 3840, 12800, 22016, 28416, 29440, 26112, 22528, 18176, 11008, 1792, -8192, -16384, -22016, -24576, -25600, -26112, -23552, -17152, -10240, -3328, 3328, 10752, 19200, 26368, 29696, 27136, 23040, 18944, 12544, 4096, -5376, -13824, -20480, -24064, -25088, -25600, -24064, -19200, -12800, -5888, 1024, 7680, 15872, 24320, 29952, 29440, 25600, 20736, 14592, 7168, -2560, -11776, -19200, -24320, -26112, -25856, -24832, -21248, -15616, -8192, -512, 6144, 14080, 22272, 28416, 30208, 27136, 22528, 16640, 8960, 0, -9216, -17152, -22784, -25856, -26112, -25088, -22784, -17408, -11008, -3328, 4096, 11776, 20480, 27392, 30976, 29696, 25088, 19200, 12032, 2816, -6912, -15872, -22272, -25856, -26624, -25600, -23808, -19712, -13056, -4608, 3328, 9216, 17152, 25344, 30464, 30464, 26368, 20736, 13568, 5376, -4096, -13312, -20224, -24576, -27136, -26112, -23808, -20992, -15360, -7680, 768, 7680, 15104, 22528, 28416, 30976, 28416, 22784, 15616, 7680, -1024, -10496, -18944, -24064, -27136, -26624, -24320, -22272, -17920, -10496, -2048, 5632, 12544, 20736, 27136, 30720, 30208, 25088, 18688, 10496, 2048, -7680, -16384, -22272, -26624, -28416, -25600, -23296, -19712, -13056, -5376, 3328, 10496, 18688, 25600, 29952, 31232, 27392, 21248, 13312, 4864, -4608, -14080, -20992, -25856, -28416, -26880, -23808, -21248, -15360, -7424, 1280, 8960, 16384, 23552, 28672, 30976, 28672, 22528, 15616, 7424, -1792, -11520, -19200, -24064, -27648, -27648, -24576, -22272, -17152, -9472, -1280, 6656, 13312, 21248, 26880, 29696, 29696, 24832, 17920, 10496, 1792, -8448, -17152, -23296, -26880, -28160, -25344, -22528, -18688, -12288, -4608, 3840, 11520, 18944, 25088, 29184, 30208, 26624, 20224, 13056, 4352, -5376, -14848, -22016, -26112, -27904, -26368, -23040, -19712, -13824, -5888, 2304, 9216, 15872, 22528, 27392, 29184, 27392, 22528, 16128, 7680, -2048, -11776, -19712, -24576, -27392, -27648, -24832, -20736, -16128, -9216, -1024, 7680, 15104, 21504, 26624, 29440, 28672, 24320, 17664, 9728, 1280, -8448, -17664, -24064, -26624, -26880, -25344, -22272, -18432, -11264, -2816, 5376, 12032, 18176, 24832, 28928, 28928, 25344, 19712, 12544, 4352, -4864, -14592, -22272, -25856, -26880, -26368, -23040, -18432, -13824, -6144, 2560, 10496, 16384, 22016, 26624, 28416, 26624, 21760, 14592, 6400, -1792, -10752, -19200, -24576, -25856, -25088, -23552, -20224, -15616, -9216, -1024, 7168, 13056, 18944, 25088, 28160, 27392, 24064, 17920, 9728, 1280, -7680, -16384, -22784, -25856, -25856, -24320, -20224, -16128, -11008, -3584, 5376, 12288, 17408, 23040, 26880, 27648, 24832, 18944, 11264, 3072, -5120, -13312, -21248, -24576, -24576, -23552, -20992, -17152, -12544, -6144, 2560, 9984, 15104, 20224, 25344, 27392, 25856, 21248, 13824, 5376, -2816, -10496, -18176, -23552, -25088, -24320, -21504, -17408, -13824, -8960, -1280, 7168, 13824, 18688, 23552, 26368, 26368, 23040, 16384, 7936, -1024, -8704, -16128, -21760, -24064, -23552, -21504, -17920, -14336, -9728, -2816, 4864, 11264, 16384, 21248, 24320, 25088, 23040, 16896, 9984, 2304, -5632, -12800, -18688, -22016, -22784, -21504, -18432, -15104, -11520, -5888, 1536, 8960, 14848, 19200, 22784, 24576, 23552, 19200, 12544, 4864, -3584, -10752, -16128, -20480, -22528, -21504, -18944, -15360, -12288, -7680, -1280, 5888, 13312, 17920, 20992, 23296, 23296, 20224, 14592, 7424, -768, -8448, -13824, -17920, -21504, -22272, -20224, -16640, -12800, -8960, -4096, 2560, 10496, 17408, 20480, 21760, 22528, 20992, 16384, 9216, 768, -7168, -12544, -15360, -18432, -21248, -20736, -16896, -12544, -9472, -5632, -512, 7168, 14848, 18944, 19968, 21248, 20736, 17664, 11520, 3584, -4608, -10752, -14080, -16896, -19712, -20224, -17408, -13568, -9984, -6400, -2048, 4352, 11776, 17152, 18432, 19200, 18944, 17920, 13568, 6144, -2304, -8704, -12288, -14080, -16384, -18944, -17920, -14080, -10240, -7168, -4352, 768, 8448, 15616, 17920, 18176, 17664, 17408, 15616, 9472, 768, -7168, -11264, -12800, -14592, -17920, -18688, -14848, -10496, -7680, -5376, -2048, 5376, 13312, 17152, 17664, 16896, 16896, 16384, 11264, 2560, -5632, -9984, -12288, -13312, -15616, -18432, -15872, -11008, -7424, -5120, -3072, 1792, 9728, 15872, 17408, 15616, 14336, 15360, 13056, 5888, -3072, -9216, -11008, -11264, -12544, -16640, -16640, -11520, -7424, -5632, -4864, -1792, 6144, 13312, 16640, 14592, 13312, 14848, 14592, 9216, 0, -7680, -9728, -9472, -9984, -14080, -16896, -13312, -8448, -5888, -5376, -3584, 2560, 10240, 15360, 15104, 12544, 13056, 13824, 11008, 2816, -5376, -8960, -9472, -8448, -10752, -14080, -12544, -7424, -4864, -5120, -4864, -1280, 5888, 12544, 13824, 11008, 10752, 12800, 12544, 5888, -3072, -7680, -8704, -7424, -7936, -12544, -13824, -8960, -4864, -4096, -4608, -2816, 2560, 9984, 14080, 11520, 8960, 10496, 12032, 7936, -768, -6656, -8448, -7168, -5888, -9216, -12032, -9216, -4608, -2816, -4096, -4096, -768, 5376, 10752, 10752, 8192, 8192, 10240, 8960, 3328, -3328, -6400, -6144, -4352, -5632, -9472, -9728, -6400, -4096, -4096, -4864, -2816, 1792, 7680, 10752, 8704, 6912, 8448, 8960, 4864, -1536, -5376, -5888, -4352, -3584, -5888, -7424, -5376, -2816, -2560, -4352, -4096, -1024, 3584, 7680, 7936, 5120, 5376, 7424, 6144, 1536, -2816, -4096, -2816, -1280, -2560, -5120, -5632, -3840, -3072, -4352, -5376, -3840, 0, 5120, 7424, 5632, 4352, 5888, 6400, 4096, -512, -3584, -3584, -1792, -512, -2304, -3584, -3072, -2304, -2816, -4352, -4352, -2816, 768, 4608, 4352, 2304, 3328, 4864, 4352, 1792, -1280, -1280, 768, 2048, 768, -1792, -2560, -3072, -3584, -5120, -5632, -4352, -1792, 2304, 4352, 2560, 2048, 3840, 4608, 2816, 512, -768, 256, 2048, 2304, 1280, -768, -2304, -3072, -4608, -5376, -5376, -4864, -1024, 2560, 2304, 512, 1280, 3584, 4096, 2816, 1024, 1280, 3328, 4096, 3584, 1536, -2048, -3584, -4864, -5888, -6144, -5376, -3328, -512, 1792, 768, -512, 2048, 3072, 2816, 2304, 2560, 3584, 4864, 5120, 4096, 1024, -2304, -4352, -5888, -6656, -6912, -6144, -3584, -512, 256, -1280, 768, 3840, 4352, 3584, 3584, 4352, 5632, 6400, 5120, 2304, -2048, -4864, -6400, -7680, -7424, -6656, -5632, -2816, 0, -768, -768, 2304, 4096, 4864, 5120, 5376, 6144, 7168, 7168, 5120, 512, -4096, -6400, -7680, -8704, -8448, -8192, -5888, -2304, -1536, -2048, 512, 3840, 5376, 6144, 6656, 7424, 8448, 8704, 7680, 3584, -2816, -6656, -8448, -9728, -9728, -9472, -8704, -5888, -3072, -1792, 0, 2816, 5376, 7424, 8704, 8960, 9472, 9984, 8960, 5376, -1280, -6656, -8704, -9984, -10240, -10752, -10752, -7936, -4352, -2304, -1024, 1792, 4864, 7936, 9728, 9728, 10496, 10752, 10240, 7168, 768, -5632, -9216, -10752, -11520, -11776, -11776, -9472, -5888, -3584, -1536, 1536, 5120, 8192, 10240, 10240, 11264, 11776, 10496, 7936, 3328, -3072, -8192, -11264, -12032, -12288, -12544, -11264, -8192, -5120, -2048, 768, 3840, 6912, 10240, 11520, 12032, 12800, 12032, 9984, 5376, -1536, -7424, -10752, -11776, -13056, -14336, -13312, -10496, -6144, -3328, -1024, 2816, 6912, 10496, 13056, 13312, 13568, 13312, 11520, 7424, 512, -6400, -11520, -12800, -13312, -14592, -14336, -12544, -8192, -4096, -1024, 2304, 5632, 9216, 12544, 14080, 14336, 14336, 12800, 8960, 2816, -3584, -9472, -13056, -14592, -15616, -15616, -14336, -10496, -5888, -2048, 2048, 5376, 8448, 12288, 15616, 16384, 15360, 13824, 10240, 4352, -2048, -8704, -13312, -15104, -15872, -16128, -15360, -12544, -7680, -3584, 512, 4864, 8448, 12032, 15360, 16896, 17152, 16640, 12800, 6400, -768, -6656, -12032, -15104, -17408, -18432, -16896, -14592, -9728, -5120, -1280, 3584, 7680, 11264, 15616, 18176, 18176, 17408, 14592, 8704, 1792, -5120, -11008, -14848, -17408, -18432, -17664, -15872, -11520, -6400, -2560, 1792, 6144, 10752, 15104, 17920, 18944, 18688, 16640, 11776, 4096, -3840, -9728, -13568, -16640, -19712, -19712, -17920, -13824, -8704, -4864, 0, 5120, 10496, 15360, 18944, 20992, 20480, 18176, 13824, 6912, -2048, -9216, -14080, -17408, -19968, -20992, -19456, -15616, -10240, -5120, -512, 4352, 9216, 14592, 18944, 21248, 20992, 18944, 15872, 9984, 768, -7936, -12544, -15872, -19200, -21504, -21504, -17664, -12032, -6912, -3328, 1536, 7936, 14336, 18688, 20992, 22016, 20480, 17408, 12544, 3584, -6144, -11776, -15360, -18944, -21248, -22016, -19456, -13824, -8192, -3840, 768, 5888, 12288, 18176, 21760, 22272, 20480, 18176, 14592, 6912, -3072, -10496, -14592, -17408, -19968, -22528, -21504, -16384, -10496, -5888, -1280, 4096, 10240, 16640, 21504, 23040, 22272, 19712, 16128, 9216, -768, -8704, -14592, -17664, -19456, -21760, -22272, -18688, -12288, -6912, -2048, 3328, 8704, 15360, 21248, 23296, 22016, 19712, 16896, 11264, 2304, -6656, -13568, -17408, -18944, -21248, -22528, -20480, -14336, -8448, -3328, 2304, 7424, 14080, 20224, 23808, 22784, 19456, 17152, 13312, 5376, -3840, -11776, -17664, -18944, -19712, -21504, -22016, -17152, -10752, -5120, 1024, 5888, 11008, 18176, 24064, 24320, 20480, 17152, 14336, 8192, 0, -9472, -16896, -18944, -18688, -19968, -22272, -19456, -12800, -6400, 256, 5376, 9472, 15616, 22528, 24832, 21504, 17152, 14592, 9728, 2048, -6400, -15104, -19712, -19712, -19456, -20736, -20480, -15616, -8704, -1536, 5120, 9216, 14080, 20480, 24576, 23296, 17920, 13824, 9984, 4352, -3584, -13056, -19200, -20224, -19200, -19712, -20480, -17408, -10240, -2816, 3840, 8448, 12288, 18176, 23552, 23296, 18688, 14592, 11520, 6144, -768, -9728, -17408, -20224, -19712, -19456, -20480, -18944, -13056, -4864, 3072, 8192, 11776, 16640, 22528, 24576, 21248, 15104, 10240, 6144, 1024, -7936, -17152, -21248, -20480, -18688, -18688, -18432, -14080, -6144, 2304, 7936, 11264, 14848, 19968, 23040, 21504, 16128, 10752, 7168, 2560, -4608, -13568, -19712, -20992, -19456, -18688, -18944, -16640, -9472, -512, 6912, 10752, 14080, 18688, 22528, 23040, 18432, 12032, 7168, 3328, -3072, -11520, -18944, -21504, -19968, -17920, -17408, -16128, -11008, -2304, 5888, 10752, 13312, 16384, 19968, 21504, 19200, 13312, 8192, 4352, -768, -8192, -15872, -20224, -19968, -18176, -17152, -16640, -13312, -4864, 3840, 9728, 12800, 15616, 18688, 20480, 20224, 15104, 8704, 4608, 768, -5376, -13056, -19200, -20736, -18432, -16384, -15616, -13824, -7936, 1024, 7936, 12288, 14080, 16128, 18688, 19968, 17152, 10240, 5376, 2048, -3072, -9984, -16640, -20480, -19456, -16640, -14848, -13312, -9728, -2048, 6400, 11520, 14336, 15616, 17152, 18944, 17664, 12032, 5632, 1792, -2560, -7936, -14336, -19200, -19712, -16896, -14592, -12544, -9472, -3584, 4096, 10240, 13568, 14592, 15616, 17152, 17664, 14080, 7680, 2816, -1536, -6400, -12032, -17664, -19968, -17920, -15104, -13056, -10240, -5120, 2560, 8704, 13056, 14848, 15104, 16128, 16896, 15104, 9216, 3584, -512, -4864, -10240, -15616, -19200, -18176, -15104, -13056, -10496, -6912, -512, 6656, 12032, 14848, 14848, 15104, 16384, 16128, 11776, 4864, -512, -4352, -8960, -14336, -18176, -19200, -16384, -12800, -10240, -6656, -1536, 5376, 11008, 14080, 14592, 14336, 14848, 15104, 12032, 5888, 256, -3328, -7424, -12288, -16128, -17664, -15616, -12288, -10240, -7424, -2816, 3328, 8960, 12288, 13568, 13056, 13568, 14592, 12800, 8448, 2304, -2560, -6400, -10752, -14336, -16640, -16384, -13056, -10240, -7424, -3328, 2304, 7680, 11264, 12800, 12288, 12032, 12800, 11776, 8960, 3328, -2048, -5120, -8448, -12032, -14592, -14336, -12288, -9728, -7680, -4096, 256, 5376, 8960, 11264, 11776, 10752, 11264, 11264, 9984, 5376, -768, -4608, -7680, -10240, -13056, -14592, -13056, -9472, -6656, -3584, 0, 4096, 8448, 10752, 11008, 9472, 8704, 9472, 8960, 5632, 256, -4352, -6912, -8704, -10496, -12288, -11520, -9216, -6400, -2816, 0, 2816, 6144, 8704, 9728, 8960, 7680, 7424, 7680, 6144, 2048, -2816, -6144, -7936, -9216, -10752, -10752, -8960, -6400, -3072, -512, 2304, 5376, 7424, 8448, 8192, 6912, 6400, 6656, 5888, 2304, -2048, -5376, -7936, -8704, -9216, -9472, -8448, -6656, -3328, -512, 2048, 4608, 6144, 7168, 7424, 6912, 5632, 5120, 5376, 3584, -512, -4352, -6912, -7680, -7936, -8448, -8192, -6656, -3584, -768, 1536, 3840, 5632, 6912, 6656, 6400, 5632, 4352, 4352, 3328, 768, -3072, -6400, -7680, -7936, -7680, -6912, -6144, -3584, 0, 2048, 4096, 5120, 5632, 5632, 5376, 4096, 2816, 3328, 3328, 768, -2048, -5376, -6912, -6656, -6400, -6400, -5888, -3072, 0, 1536, 3072, 4608, 5120, 5632, 5120, 3840, 2304, 2304, 2560, 768, -2304, -5376, -7424, -7168, -5888, -5120, -4864, -2560, 768, 3328, 4352, 4864, 4864, 5376, 4352, 2816, 1024, 256, 1024, 0, -2048, -4352, -6400, -6144, -5376, -4864, -4096, -2304, 1024, 3328, 4352, 4864, 5120, 5632, 4864, 2816, 768, -1024, -768, -1024, -3072, -4608, -6656, -7168, -5888, -4096, -2560, -1280, 1280, 4608, 6400, 6400, 5632, 5376, 4864, 2304, 0, -2304, -2816, -2560, -3328, -4096, -6144, -6912, -5632, -3584, -2048, -512, 1792, 4352, 6400, 6400, 5632, 5120, 4352, 2560, -512, -2560, -3072, -3328, -3840, -4608, -5120, -6144, -5632, -4096, -2048, 768, 2816, 4352, 6400, 6912, 5888, 5376, 4352, 2304, 0, -2560, -3072, -3328, -4608, -4864, -5120, -6144, -5888, -4352, -2560, 0, 2816, 4864, 6656, 7680, 6656, 6144, 5120, 3072, 768, -2048, -3840, -4608, -5632, -6400, -6400, -6400, -6144, -5120, -3072, 512, 3840, 5120, 6400, 7936, 8448, 7424, 5888, 3072, 768, -1280, -3840, -5888, -7168, -7168, -6400, -5632, -5632, -4608, -2560, 512, 3840, 4864, 5888, 7680, 8192, 7168, 6144, 3840, 1792, 256, -3328, -5888, -6912, -7424, -7168, -6656, -6144, -5120, -3584, -512, 3328, 5120, 6144, 8192, 8704, 8192, 7424, 5632, 2304, -512, -2560, -5376, -7680, -8704, -8704, -7424, -5632, -5120, -4608, -1280, 3584, 5888, 6400, 7936, 9216, 8960, 7680, 5632, 2560, 0, -2048, -5376, -8704, -9984, -9216, -8192, -6912, -5120, -3840, -1280, 3584, 6912, 7168, 8192, 9216, 8960, 8448, 6400, 3584, 0, -2816, -5376, -8704, -10240, -10496, -9984, -7680, -5120, -3328, -1536, 2560, 6912, 7680, 8192, 8960, 8704, 9216, 7424, 4352, 1280, -1792, -4096, -8448, -11520, -11520, -11008, -8448, -6144, -4608, -2304, 2048, 6656, 8192, 8448, 9984, 9728, 9216, 7936, 5120, 2560, -1536, -4864, -8192, -11520, -12032, -11776, -9984, -6400, -3072, -768, 2048, 5632, 8192, 8192, 8960, 8960, 8192, 7936, 5888, 3584, 0, -3840, -6656, -11008, -13056, -12800, -11008, -7424, -4352, -1536, 1280, 4864, 8704, 9216, 8448, 9472, 9472, 8704, 6400, 4096, 1280, -2816, -6656, -10496, -13056, -14080, -13056, -9216, -5376, -1792, 1792, 4096, 7168, 9472, 8960, 8960, 9216, 8704, 7680, 5120, 2304, -1792, -5632, -9472, -12544, -14336, -13824, -10752, -6400, -2816, 512, 3328, 6144, 8960, 9728, 9472, 9728, 9472, 8192, 6400, 4096, 256, -5376, -9728, -12032, -14336, -14848, -12800, -8704, -3584, 1024, 3328, 5120, 7936, 10240, 9984, 8960, 9216, 8704, 7168, 5120, 1280, -3840, -8448, -11264, -14080, -16128, -13824, -9728, -4864, -512, 2560, 4352, 7680, 10240, 10496, 9216, 9728, 10496, 8448, 5632, 2304, -3328, -9216, -12800, -14080, -16128, -15616, -11264, -5632, 512, 4608, 5632, 7168, 9728, 10752, 9984, 8704, 8960, 8704, 6912, 3584, -1792, -7424, -11008, -13056, -15360, -16128, -12800, -7680, -2560, 2048, 4096, 5376, 8192, 10240, 10240, 9728, 9984, 10496, 8960, 6144, 1536, -5120, -10496, -13824, -15872, -16640, -14848, -9984, -4096, 1792, 4608, 5632, 7424, 9984, 11008, 10240, 8960, 9728, 9472, 6912, 3072, -3584, -9472, -13056, -14848, -16384, -16384, -12032, -5632, -512, 3584, 4608, 6144, 9216, 11264, 11520, 10496, 11008, 11008, 8192, 4352, -2048, -8960, -13824, -16128, -17152, -17408, -14336, -7424, -1024, 4096, 6144, 6656, 8960, 11264, 12032, 11008, 9728, 9728, 9216, 6144, 0, -7680, -12800, -14592, -15104, -16128, -15616, -10240, -2816, 2816, 5120, 5120, 6656, 9984, 12288, 11776, 10240, 9984, 10752, 8448, 3072, -5120, -12032, -14848, -15360, -15872, -15616, -12544, -5888, 512, 4352, 5376, 5632, 8448, 12288, 13056, 11520, 11008, 11008, 9728, 5120, -2560, -10496, -14848, -15616, -16384, -15872, -14080, -8960, -2304, 2560, 5376, 5888, 8192, 12800, 14592, 12544, 11520, 11520, 11008, 6656, -1536, -9728, -14848, -15872, -16640, -17152, -15616, -11264, -3840, 2560, 5888, 6656, 7168, 11264, 15104, 14080, 11776, 10752, 10496, 8448, 1536, -7680, -14592, -16384, -15872, -16384, -15872, -12800, -6656, 512, 4608, 6656, 7168, 9984, 15104, 15360, 12288, 11008, 11008, 9472, 3584, -5632, -13568, -17152, -16128, -16640, -16896, -14080, -8448, -512, 4864, 7168, 7936, 9472, 14080, 16384, 13568, 10496, 9984, 9472, 5120, -4096, -12288, -16896, -16640, -15872, -16896, -15360, -11008, -3072, 3840, 6656, 7936, 9472, 13568, 17664, 16128, 11776, 9984, 9728, 6912, -1280, -11264, -18432, -18688, -16640, -16640, -16128, -13312, -6144, 2816, 7936, 9216, 9728, 12288, 16640, 17920, 13568, 9728, 8704, 7168, 1280, -8960, -17664, -19968, -17920, -16640, -16128, -13568, -7680, 512, 6656, 9728, 11008, 12544, 15872, 17664, 14848, 10240, 8448, 7168, 2304, -6400, -15616, -19968, -19200, -17664, -16384, -14080, -9472, -1792, 5632, 9216, 11008, 12544, 14592, 16896, 15872, 11264, 7936, 7424, 3840, -4096, -13312, -19456, -19712, -17664, -16128, -14592, -11264, -4096, 3584, 8448, 10752, 12288, 13824, 16640, 17408, 13312, 8448, 6912, 4864, -1536, -10496, -18432, -20992, -18944, -16640, -15104, -12288, -6144, 1792, 7424, 11008, 12800, 13568, 15360, 17152, 14848, 9984, 7168, 5632, 512, -7936, -16384, -20992, -20224, -18176, -15616, -12544, -7936, -512, 5632, 10240, 13056, 14080, 14848, 16640, 16128, 11776, 7424, 5376, 2304, -5376, -14336, -20224, -21248, -19712, -16640, -13824, -9472, -2560, 4096, 9216, 12800, 14592, 15360, 16640, 16384, 12800, 8448, 5632, 2816, -3328, -12032, -18688, -20992, -20480, -17920, -14592, -10752, -4864, 2048, 7680, 12544, 14848, 15616, 15872, 16384, 14336, 10496, 6144, 2816, -1536, -8960, -16896, -20480, -20992, -19200, -15616, -11520, -6400, -512, 5632, 11008, 14592, 16128, 16384, 16128, 14848, 12544, 7936, 3840, -512, -6656, -14848, -20224, -21760, -20736, -16896, -12544, -7936, -2304, 4352, 9984, 14080, 16384, 17664, 17152, 15616, 13568, 8960, 4096, 256, -5120, -12544, -19200, -22016, -21760, -18944, -13824, -8704, -2816, 2816, 8448, 13568, 16384, 17920, 17408, 15104, 13056, 10240, 5632, 1280, -3840, -10240, -16896, -20224, -20736, -19968, -16128, -10496, -4864, 1024, 6400, 11264, 14848, 17152, 18432, 16640, 14592, 12032, 7424, 2816, -2048, -7936, -15616, -20736, -21760, -20992, -17408, -12032, -6400, -768, 5376, 11264, 15104, 17408, 18688, 17408, 14336, 12032, 8448, 3840, -1792, -6912, -13312, -19456, -20992, -20992, -18432, -13312, -7680, -1792, 3328, 9216, 14592, 17152, 18944, 18432, 15616, 12288, 9216, 5120, -1024, -6400, -12032, -18176, -20736, -20736, -19200, -14336, -8448, -2560, 2816, 7680, 12544, 16128, 18688, 18944, 16128, 12288, 9472, 6400, 1536, -5120, -10496, -16128, -20224, -20736, -19712, -16640, -11008, -4864, 1024, 6400, 11520, 16128, 18688, 19456, 17920, 14080, 10496, 7168, 2560, -3840, -9728, -15104, -19712, -21248, -20224, -17920, -12544, -6400, -1024, 5120, 10240, 15104, 18944, 19456, 18688, 15872, 11776, 8448, 4096, -2560, -8704, -13056, -17408, -21248, -21760, -19200, -14848, -8704, -2816, 3584, 8960, 14080, 18688, 20224, 19456, 17664, 13056, 8448, 5120, -512, -7680, -13568, -17152, -20736, -21504, -19456, -15616, -9984, -3584, 2816, 8192, 12544, 17152, 19712, 18944, 17408, 14080, 9472, 5888, 1280, -5632, -11520, -15104, -18688, -21504, -20992, -17408, -11776, -6144, 768, 6656, 11008, 15872, 19200, 18944, 18432, 15616, 10752, 6400, 2560, -3840, -10240, -14592, -17920, -21248, -21504, -18176, -12544, -7168, -1536, 5120, 10496, 15104, 18432, 18432, 17664, 16128, 12288, 7424, 3328, -2048, -7936, -13056, -16896, -20224, -21504, -19200, -14336, -9472, -4096, 3072, 9216, 14080, 18176, 18944, 18432, 17664, 13824, 8704, 4096, -1280, -7168, -12032, -15616, -19200, -21760, -20480, -15360, -9728, -5120, 1024, 7680, 13568, 17408, 18176, 17664, 17152, 14592, 9984, 5120, 0, -5376, -10496, -14848, -18176, -20224, -20224, -16896, -11520, -6400, -768, 5888, 11520, 15616, 17408, 17664, 17920, 16128, 12032, 7424, 2048, -4096, -9472, -14336, -18176, -20480, -20736, -18176, -13312, -7680, -1792, 4352, 10496, 15360, 17152, 17152, 17408, 16640, 12800, 7680, 2560, -3584, -7936, -12032, -16640, -19712, -20224, -17920, -13568, -8448, -3584, 2048, 8704, 14336, 15872, 15872, 16896, 16384, 13824, 9216, 3840, -2048, -6912, -10752, -15616, -18688, -19200, -17920, -14336, -9216, -3584, 1280, 6656, 12544, 15360, 15104, 15616, 15360, 13824, 10752, 5888, -512, -5632, -8960, -13568, -17664, -19200, -17920, -14848, -10496, -5120, -768, 4608, 11008, 15104, 14592, 14592, 15360, 14336, 11264, 7168, 1792, -4352, -8192, -12032, -16128, -18688, -18432, -15872, -11776, -5888, -1536, 3072, 8960, 14080, 15360, 14592, 15104, 14336, 12544, 8960, 3584, -3328, -7168, -10240, -14848, -18432, -18688, -15872, -12800, -7936, -3328, 1280, 7680, 13056, 15104, 14336, 14848, 15616, 14336, 9728, 4352, -2304, -6656, -9472, -13312, -17408, -18944, -16128, -12800, -8192, -3584, 256, 5632, 11520, 14592, 14336, 13056, 13824, 13824, 10496, 5376, -1024, -5632, -7936, -11264, -15104, -17664, -16128, -12288, -9216, -5376, -1792, 2816, 8960, 13312, 14336, 13568, 13824, 14848, 12288, 7680, 2048, -4352, -8192, -11008, -14592, -17408, -17664, -14336, -9984, -5632, -2048, 1536, 7168, 12544, 14592, 13824, 13056, 14080, 13312, 8960, 3328, -3328, -7424, -9216, -12544, -16384, -17920, -14848, -9984, -5888, -2816, 0, 4864, 11008, 14592, 14080, 12032, 12544, 14080, 11008, 4608, -2304, -7168, -8960, -10752, -14592, -17664, -16640, -11520, -6400, -2816, 256, 3584, 9472, 14080, 15360, 12800, 11520, 12288, 10752, 5376, -1024, -6400, -8960, -10240, -12800, -15360, -15616, -11776, -6912, -3840, -1536, 1536, 6400, 11776, 14336, 12800, 11008, 11520, 12032, 8448, 2304, -3840, -7680, -9472, -11520, -14848, -16384, -14336, -9216, -4608, -2048, 1024, 4608, 10240, 14848, 15104, 12032, 9984, 10496, 8960, 3072, -3840, -8192, -9728, -9984, -11776, -14592, -14080, -9472, -4352, -1792, 256, 2816, 6912, 12288, 14336, 12032, 9472, 9728, 9728, 5376, -1536, -6144, -8192, -9472, -11008, -13824, -14592, -11264, -6400, -2304, 512, 2816, 6144, 11264, 14592, 13056, 9728, 8192, 7936, 5376, -1280, -7168, -8960, -9216, -9216, -11520, -13056, -10496, -6400, -2048, 768, 2048, 4352, 8448, 12288, 12544, 9472, 7936, 7680, 6400, 1792, -4608, -7680, -8704, -9472, -10240, -12288, -12032, -8448, -4096, 256, 2816, 4096, 7168, 10752, 12800, 11008, 7680, 6400, 5632, 2560, -3072, -7168, -8448, -8704, -8960, -10496, -11264, -8448, -4608, -512, 2304, 3072, 5120, 8192, 11008, 10496, 7424, 6144, 5632, 3584, -768, -5376, -7424, -7680, -7936, -8960, -10496, -8960, -5376, -1536, 2304, 3328, 4608, 6912, 9728, 10752, 7424, 4608, 4096, 3328, 1024, -3840, -6912, -7168, -6912, -7168, -8704, -8704, -5888, -2560, 1280, 2816, 3584, 5632, 8192, 9472, 7936, 5120, 4096, 3072, 1536, -2304, -5632, -6400, -6912, -6656, -8192, -8704, -6912, -3840, 0, 2560, 3072, 4608, 7168, 9216, 8960, 5888, 3584, 2816, 2048, -768, -4864, -7168, -7168, -6400, -6912, -8192, -7168, -4096, -512, 2816, 3584, 3584, 5632, 7680, 7936, 6144, 3840, 2816, 2048, 512, -2816, -5632, -6400, -6400, -6656, -7680, -7168, -4608, -1792, 1280, 3072, 3584, 4864, 6912, 7680, 6656, 4864, 3328, 2304, 1024, -1536, -5120, -6656, -5888, -6144, -6912, -6912, -4864, -1536, 1024, 3072, 3072, 3328, 5632, 6656, 5632, 3840, 2816, 2560, 1536, -512, -3072, -4864, -4864, -5376, -6400, -6400, -5120, -2816, -768, 1280, 2304, 3328, 4864, 6144, 6144, 5376, 3840, 3072, 1792, 512, -2304, -5120, -5632, -5632, -5888, -6144, -5632, -2816, -512, 1792, 2816, 3328, 4352, 5376, 5376, 4608, 3328, 2816, 1792, 256, -1792, -3840, -4864, -4864, -5376, -5120, -4608, -3072, -1024, 512, 2048, 2816, 3840, 4352, 4096, 3840, 3328, 2816, 2048, 1024, -768, -2816, -4096, -3840, -4864, -5120, -4096, -3072, -1280, 512, 1280, 2048, 3584, 4352, 3840, 2816, 2560, 2304, 2048, 1024, -512, -1536, -2816, -3072, -3584, -4608, -3328, -1792, -1536, -768, 512, 1536, 2560, 3328, 3328, 2304, 2048, 2304, 1536, 256, 0, -1280, -2304, -3072, -3072, -3328, -3072, -1024, 256, 768, 1024, 1024, 1792, 2816, 2560, 1792, 768, 768, 1024, 512, -512, -768, -1536, -1792, -1536, -1536, -2048, -1280, 512, 256, 256, 0, 256, 1280, 1280, 768, 0, 0, 1280, 1280, 512, 768, 0, -768, -1280, -1536, -2048, -1792, -512, -768, -1024, -512, -512, 768, 1536, 1024, 256, -768, 256, 1280, 768, 512, 0, -512, -768, -1024, -1280, -1280, 256, 512, -768, -768, -1024, -768, 1024, 1024, 0, -1280, -768, 768, 768, 512, 256, 256, 0, 0, 0, -768, -512, 256, -512, -1024, -768, -1024, 256, 1280, 512, -1280, -1792, -512, 512, -512, -512, 0, 512, 768, 512, 512, 768, 1536, 1024, -512, -1280, -1536, -512, 768, -512, -2304, -2816, -1280, 0, -768, -1024, -512, 768, 1792, 2048, 1024, 512, 1024, 768, 0, -1536, -2048, -1536, 512, 1024, -768, -2560, -2560, -1280, -512, -1024, -1280, -768, 1280, 2816, 2816, 2048, 1280, 1280, 1024, -512, -2304, -2304, -512, 0, -1280, -3328, -3584, -2560, -1280, -1024, -512, 512, 1536, 3584, 3840, 2816, 2048, 1536, 256, -1280, -2560, -3072, -1536, 256, -512, -2560, -3840, -2816, -1024, -768, -1536, -1280, 512, 3584, 4864, 3584, 2560, 2560, 2048, 768, -1536, -3840, -3072, -1024, -1024, -3072, -4608, -4352, -2560, -512, 0, 256, 1536, 4096, 6400, 5376, 3072, 2048, 1024, -512, -2048, -4608, -5120, -2816, -1536, -2304, -3584, -3584, -2560, -768, 0, 256, 1536, 3328, 5888, 6400, 4352, 3328, 2304, 256, -1536, -3328, -4608, -3584, -2816, -3328, -4352, -4864, -3584, -2048, -768, 256, 1792, 3584, 6144, 7680, 6144, 4096, 3072, 1024, -1280, -2816, -4608, -4864, -3840, -3072, -3584, -4864, -4608, -3584, -2304, 0, 2048, 3328, 4864, 6912, 7168, 5632, 4608, 2304, -1024, -2816, -3584, -4096, -3840, -4096, -4096, -4352, -4096, -3584, -3328, -1536, 1024, 3072, 4864, 6656, 7936, 6912, 4864, 3328, 768, -2048, -3072, -4096, -4608, -4864, -4352, -4096, -5120, -4608, -3840, -2560, 256, 2560, 4608, 6144, 7936, 7680, 5632, 4608, 2304, -1024, -2560, -3584, -4352, -5120, -5632, -4864, -4864, -5632, -4608, -3328, -512, 2304, 4096, 5376, 7424, 9216, 7424, 4864, 3072, 256, -1792, -2560, -3840, -5632, -6144, -5120, -4608, -5376, -5376, -4352, -2048, 1792, 4096, 5888, 6912, 8448, 8960, 6656, 4352, 1792, -1280, -2816, -3584, -5632, -6912, -6144, -4864, -5632, -6400, -4864, -2816, 1280, 4096, 5376, 6400, 8448, 9728, 7936, 4608, 2304, -512, -2560, -3328, -5632, -7424, -7168, -5376, -4608, -6144, -5632, -3840, -768, 3584, 5376, 6144, 7680, 9728, 9216, 6144, 3328, 1024, -1280, -2304, -4096, -7168, -8192, -6400, -5376, -6400, -6912, -4608, -1792, 2048, 4608, 6144, 7936, 10240, 10240, 7424, 4096, 1536, -768, -2048, -4096, -6912, -7936, -6912, -5632, -6144, -6912, -5376, -2560, 1024, 4096, 5632, 7168, 9472, 10240, 8448, 4864, 1792, 256, -1280, -3072, -5888, -8192, -7168, -5888, -5888, -6912, -6656, -3840, -512, 3328, 5376, 6400, 8704, 10496, 9728, 7168, 3584, 1024, -768, -2816, -5632, -8704, -8960, -7680, -6656, -7168, -7424, -5120, -768, 3584, 6144, 6912, 8192, 10496, 10752, 8704, 4352, 1024, -1024, -2816, -5120, -8192, -9728, -8448, -7168, -6912, -6912, -5632, -2304, 1792, 5120, 7424, 8704, 9984, 10240, 9472, 6144, 2560, 512, -1792, -4096, -7168, -10240, -10240, -8448, -7424, -7168, -6912, -4096, 1280, 5376, 7168, 8192, 9216, 10496, 10240, 7680, 3072, 256, -1536, -2816, -5632, -9472, -10752, -8704, -7680, -7424, -6912, -5120, -768, 4096, 6912, 8192, 8704, 9984, 10496, 8960, 5120, 1536, -1024, -2816, -4096, -8192, -11520, -10496, -8448, -7936, -6912, -5888, -2560, 3328, 7168, 8448, 8960, 9728, 9984, 9216, 6400, 2048, -1536, -2816, -3584, -6656, -10752, -11520, -8704, -7424, -6400, -5888, -3840, 1536, 6656, 9216, 9216, 9216, 9472, 9216, 7424, 3584, -512, -3072, -3584, -5888, -10752, -12800, -10752, -8192, -5888, -4608, -3840, 768, 6400, 9728, 9984, 8960, 8960, 9472, 8448, 4608, -768, -3840, -4608, -5120, -8704, -12288, -12032, -8704, -5632, -3584, -3072, -1024, 4352, 8960, 10496, 9472, 8704, 8448, 8448, 6144, 1536, -3328, -5632, -5632, -7680, -11520, -13056, -9984, -5888, -2560, -1536, -768, 3328, 8192, 10496, 9472, 7680, 7424, 7936, 6912, 2560, -2560, -5632, -5888, -6656, -9728, -12288, -11264, -7168, -3072, -1280, -768, 2304, 6912, 9728, 9728, 8192, 7168, 7424, 6912, 4352, -1024, -5376, -6656, -6912, -8960, -12032, -12544, -8448, -3072, 512, 1280, 2304, 5888, 8960, 10240, 8704, 5376, 5888, 6400, 5632, 1280, -5120, -7168, -7168, -7424, -9984, -12800, -11008, -4864, 768, 2560, 1792, 3840, 7424, 10496, 11008, 7168, 5632, 5888, 5632, 3072, -4096, -8448, -8192, -8192, -9728, -11776, -11008, -5376, 768, 3840, 3328, 4096, 7424, 8960, 8960, 6912, 4864, 4864, 4864, 3840, -2048, -7680, -7936, -7680, -8192, -10240, -11264, -7424, -512, 4608, 4352, 2816, 5632, 8704, 9472, 8192, 5376, 4608, 5120, 4352, -512, -7168, -9472, -8704, -8704, -9728, -10752, -7680, -1792, 4096, 5632, 4096, 5120, 7936, 7936, 7424, 5888, 4352, 4608, 4864, 1536, -5376, -9472, -8960, -8704, -8960, -9728, -8960, -3840, 3584, 6912, 5376, 3328, 5888, 7936, 7936, 6656, 4096, 3072, 4096, 3072, -2560, -8960, -9984, -8960, -9216, -9216, -8704, -5376, 1536, 6144, 6144, 4096, 5120, 7424, 7168, 6912, 5632, 4096, 4352, 3840, -1024, -7424, -10496, -9984, -10240, -9984, -9216, -7424, -1536, 5120, 6912, 5376, 4864, 7168, 8448, 7936, 6912, 4608, 3584, 3328, 512, -5632, -10496, -11008, -10240, -9984, -8704, -7168, -3072, 4096, 7168, 6144, 4864, 6400, 7424, 6912, 6144, 4864, 3840, 3072, 1024, -3840, -8704, -10496, -10240, -9472, -8192, -6656, -4608, 1280, 6144, 6144, 5120, 5376, 6656, 6912, 6656, 6144, 4608, 3072, 1536, -2304, -7680, -11264, -11520, -10496, -8448, -6656, -4864, -512, 5888, 7424, 6144, 5632, 6144, 7168, 6400, 5632, 4608, 3328, 1792, -1792, -6144, -10240, -11776, -10752, -9216, -7168, -5376, -1536, 3840, 7168, 6400, 5632, 6400, 7424, 7168, 5888, 5120, 3584, 1536, -1536, -5632, -10240, -12032, -10752, -9216, -7168, -5888, -2560, 3328, 7680, 7168, 5376, 5888, 6912, 7168, 5376, 4608, 4096, 2304, -512, -4352, -8448, -11264, -11264, -9728, -7936, -5888, -3584, 1280, 6400, 8192, 6400, 5888, 6656, 7424, 6144, 4096, 3328, 2048, -512, -3840, -7936, -11008, -11264, -9472, -7680, -5888, -3584, 256, 5376, 7936, 6912, 5632, 6144, 7168, 6400, 4352, 3328, 2560, 768, -2560, -6912, -10240, -11264, -9728, -8192, -6656, -4352, -768, 4096, 7936, 7936, 6400, 6400, 7680, 7424, 4352, 2048, 1792, 768, -2048, -6400, -9984, -11008, -9472, -7936, -6912, -4608, -1024, 3328, 7424, 8192, 6656, 6144, 6912, 6912, 4352, 2304, 2048, 1536, -1280, -5120, -8704, -9984, -9472, -8704, -7680, -5376, -2048, 1536, 5888, 8704, 7936, 7424, 7168, 6912, 5632, 3328, 1536, 1280, -1024, -4608, -8704, -10240, -9472, -8704, -7424, -5888, -2560, 1280, 5376, 8192, 7424, 6912, 7424, 6656, 5120, 3072, 1024, 768, 0, -3072, -7168, -9472, -8960, -7936, -7424, -5888, -3328, 256, 4096, 7680, 8448, 7424, 6912, 6400, 5376, 3840, 1280, -512, -768, -2304, -5632, -8960, -9216, -7936, -7424, -6144, -3584, 0, 3072, 6912, 8960, 7936, 7424, 6656, 5376, 4096, 2048, -512, -768, -1792, -4864, -8704, -9216, -8192, -7936, -7168, -4608, -768, 2816, 5632, 8192, 8192, 7680, 7424, 5888, 4096, 2816, 512, -768, -1536, -4352, -8192, -9472, -8192, -7680, -7936, -5888, -1536, 2304, 4608, 7680, 9216, 8192, 7936, 6400, 4352, 3328, 1024, -1536, -2048, -3584, -6656, -9216, -8704, -7936, -7936, -6400, -2816, 1536, 4096, 6144, 8704, 8960, 8448, 7168, 4352, 4096, 2560, -768, -2304, -3328, -5888, -8704, -9216, -8192, -7936, -6912, -4096, 512, 4096, 5632, 7680, 8960, 8448, 7680, 5376, 3840, 2816, 0, -1792, -2816, -5120, -7936, -8960, -7936, -7936, -7424, -5376, -1536, 3328, 5376, 6400, 8192, 8704, 8448, 6656, 4608, 3328, 1024, -1536, -2560, -4864, -7424, -8704, -8704, -7424, -6912, -6144, -3072, 1792, 5120, 6400, 7680, 8448, 8192, 7424, 5376, 3328, 1792, -1280, -2816, -4608, -7168, -8960, -9216, -7424, -6400, -6144, -4096, 768, 5376, 6656, 7168, 8704, 9472, 8704, 6656, 3072, 1024, -1280, -3328, -5120, -7680, -8960, -9984, -8960, -6144, -4864, -3328, -512, 3840, 6912, 7680, 8192, 8704, 7936, 7168, 4608, 1280, -1536, -3840, -5120, -6144, -7936, -9472, -8960, -6144, -4864, -4096, -2304, 2048, 6144, 7680, 7680, 8448, 8960, 8960, 6144, 1280, -1280, -2816, -5120, -6912, -8704, -10240, -9984, -7680, -5376, -4096, -2304, 1024, 5120, 8192, 9216, 9216, 9216, 8960, 7936, 3328, -768, -3328, -5888, -6912, -7424, -10496, -11264, -8448, -4864, -2816, -2560, -1024, 3584, 8192, 9728, 8704, 8448, 9216, 8448, 4608, -1024, -3328, -5120, -6400, -7168, -9472, -11008, -8704, -5632, -3584, -2048, -1024, 2304, 6656, 9984, 9728, 8960, 8960, 8704, 5888, 768, -3072, -5376, -7168, -7168, -7936, -10496, -10240, -6912, -3840, -1792, -1536, 512, 5120, 9472, 10752, 9216, 8704, 8960, 7168, 2304, -2560, -4608, -6144, -6656, -7424, -9728, -10752, -8192, -5376, -2816, -1536, -768, 3072, 8448, 11520, 10496, 9472, 9472, 7424, 3328, -1024, -4352, -6656, -7168, -7168, -8448, -9984, -9472, -6656, -3840, -2048, -1792, 1536, 7424, 12032, 11776, 9984, 8704, 7680, 5120, 256, -4608, -6656, -6656, -6400, -7424, -9472, -10240, -7936, -4352, -2048, -1792, 0, 5120, 10752, 13056, 11520, 9728, 7680, 4608, 1792, -2560, -6144, -6912, -6656, -6144, -7424, -9728, -9472, -6912, -3584, -2304, -1536, 2816, 9216, 13056, 12032, 10752, 8704, 6144, 3584, -768, -5120, -6400, -5888, -5632, -6656, -9472, -10752, -8448, -4352, -2048, -1792, 1024, 7168, 12800, 13824, 11520, 8960, 6144, 3840, 768, -4096, -6144, -6400, -5632, -5888, -8192, -10496, -9472, -5632, -2816, -2048, 0, 5376, 11264, 13824, 11776, 8704, 6656, 4608, 1792, -2816, -5632, -5376, -5120, -5376, -7168, -10240, -11008, -7680, -3840, -2560, -768, 4096, 10240, 14336, 13312, 9472, 6144, 4096, 2304, -1536, -5376, -5632, -4608, -4352, -5632, -8960, -11008, -8704, -5376, -3584, -2304, 1792, 8704, 13568, 13824, 10240, 7424, 5376, 3584, 1024, -3584, -5376, -4352, -4352, -5632, -8448, -11776, -11520, -7936, -4096, -2048, 1024, 6400, 12800, 15360, 12544, 7936, 5120, 3840, 2304, -1280, -4352, -4608, -3840, -4352, -6656, -10752, -12800, -10240, -6144, -2816, -512, 4608, 11008, 14336, 13312, 8960, 5376, 4352, 2816, 0, -3072, -4608, -3584, -3840, -5632, -9216, -12800, -11776, -7680, -3840, -768, 3072, 8960, 13568, 14080, 10496, 6144, 4608, 3072, 1280, -1024, -3840, -4608, -3840, -5120, -8448, -11776, -12544, -9472, -5376, -1792, 1792, 6400, 11776, 13824, 11520, 6912, 4608, 3584, 2560, 768, -2048, -3840, -4096, -4608, -7168, -10496, -12544, -11264, -7424, -3072, 1024, 4352, 8960, 12544, 12544, 8704, 4864, 4096, 3840, 2304, 256, -2560, -3584, -4096, -6144, -9728, -12800, -12544, -9216, -4608, -768, 2560, 6656, 11008, 12544, 9728, 5632, 4608, 5120, 4096, 2304, -1280, -3328, -4096, -5888, -9216, -12800, -13568, -11008, -6400, -2048, 1536, 5376, 9728, 12288, 11264, 6912, 4864, 5376, 4864, 3328, -512, -3328, -4352, -5376, -7680, -11520, -13312, -11776, -7424, -2560, 768, 3584, 7424, 10752, 11264, 7680, 4352, 4864, 5376, 4352, 1536, -2048, -3584, -4864, -6656, -9984, -12544, -12288, -9216, -4608, -512, 2816, 6912, 9472, 10752, 9472, 5632, 4608, 5376, 4864, 2304, -1280, -3328, -4608, -6144, -8448, -11520, -11776, -9984, -6144, -2048, 1536, 5120, 8448, 10240, 9728, 6912, 4864, 5632, 5888, 4352, 1024, -2048, -3584, -5632, -7424, -11008, -12288, -11008, -8192, -4096, -512, 3328, 6400, 8704, 9984, 8448, 5888, 5376, 5888, 5120, 2304, -1024, -2816, -4864, -6400, -8448, -11008, -10752, -8704, -5120, -1792, 768, 3584, 6144, 8192, 7936, 5632, 5120, 6656, 7168, 5120, 1536, -1280, -2816, -4608, -7168, -10752, -11264, -9728, -7168, -3840, -1280, 2048, 4864, 7168, 7936, 6144, 5376, 6400, 6912, 5632, 2560, 0, -1536, -3072, -5632, -8704, -9728, -8704, -7680, -5120, -2816, 0, 2816, 5120, 6656, 5888, 4864, 5632, 6912, 6400, 4352, 1792, -512, -1792, -4352, -7424, -8960, -8960, -8704, -6656, -4096, -1280, 1792, 3840, 5888, 7168, 6144, 5376, 5632, 6144, 5120, 2816, -512, -2048, -3584, -6144, -7424, -7936, -7936, -6912, -4608, -2304, 0, 2048, 3840, 5632, 5888, 5120, 5376, 6144, 6144, 4864, 1792, -1024, -2560, -4864, -6656, -8192, -8704, -8448, -6144, -3072, -512, 1536, 3584, 5632, 6656, 5888, 5632, 5632, 5632, 5376, 2560, 0, -1536, -3840, -5376, -6144, -7168, -7936, -7168, -4352, -1792, 512, 1792, 3328, 4864, 5888, 5888, 5376, 4864, 5376, 4608, 2048, -512, -2816, -4352, -5376, -6144, -7680, -8448, -6400, -2816, 0, 1024, 2304, 4096, 5120, 5376, 5120, 4608, 4608, 5120, 3584, 1024, -1536, -3072, -3840, -4352, -6400, -8192, -8192, -5120, -1536, -768, -768, 1792, 4608, 5888, 4864, 4096, 4864, 6656, 6144, 2816, 0, -1536, -2304, -3840, -6400, -8448, -8960, -6656, -3840, -2304, -1536, 1280, 4352, 5632, 5376, 4352, 4608, 6400, 6656, 4096, 1024, -1280, -1792, -2304, -4608, -7424, -9728, -8960, -5376, -2816, -2304, -1024, 2304, 5632, 6400, 5120, 4096, 5632, 7680, 6144, 2048, -1024, -1280, -1280, -3328, -6400, -9216, -9728, -6656, -4096, -2816, -2560, 512, 4864, 6400, 4608, 3072, 4864, 7680, 7168, 3584, 256, -512, 768, -768, -4352, -7936, -9216, -7424, -5376, -4608, -4864, -2816, 1792, 5120, 4096, 2560, 4096, 7680, 9216, 6144, 2048, 1024, 2048, 1536, -3072, -8192, -10240, -8960, -6656, -5376, -5120, -3584, 512, 4864, 5120, 2560, 3072, 6144, 8960, 7424, 3328, 1280, 1792, 2304, -768, -5888, -9472, -9472, -7936, -5888, -5376, -4864, -2048, 3072, 4864, 2560, 1536, 4864, 9216, 9472, 5888, 2816, 3072, 4096, 1792, -3840, -8960, -11008, -9728, -7680, -6912, -5888, -4096, 512, 4608, 4096, 1792, 3328, 7680, 9728, 7424, 4352, 3072, 4096, 3840, -1024, -6912, -10240, -9984, -8192, -7168, -7168, -6144, -2048, 3072, 3584, 1280, 1792, 6656, 10240, 9216, 6144, 4608, 5376, 5376, 1024, -5120, -9728, -10496, -9472, -8704, -7680, -6656, -3840, 1024, 3584, 1792, 768, 4608, 9472, 10496, 8448, 6144, 5632, 6400, 3584, -2560, -8448, -11264, -10752, -9216, -8192, -7424, -5632, -1536, 2560, 2304, 512, 2304, 7424, 10240, 9472, 8192, 7168, 7424, 5376, 0, -6144, -9984, -11264, -11264, -9728, -7936, -6144, -4096, 0, 1792, 768, 2048, 6144, 9728, 11008, 10496, 8192, 7168, 6400, 2304, -3840, -8704, -11264, -11264, -9984, -7936, -6656, -5120, -2560, 768, 512, 256, 3584, 8192, 11264, 11776, 9984, 8448, 7936, 5120, -1792, -7936, -11520, -12032, -11264, -9728, -7680, -6656, -4096, 0, 1280, 1024, 3072, 7680, 11520, 13312, 12032, 9216, 7680, 5632, 0, -6144, -10240, -12800, -12544, -10752, -7936, -6144, -4864, -2560, -768, 768, 2816, 6144, 9984, 13056, 14080, 12544, 9472, 6912, 2048, -4608, -9216, -12800, -13824, -12032, -9216, -7424, -6400, -4096, -1536, 1024, 2560, 4608, 8704, 13312, 15104, 13568, 9984, 7168, 3840, -2048, -7424, -11520, -13568, -13056, -11008, -8704, -7424, -5888, -3584, -1024, 1792, 4352, 8448, 13312, 15872, 15616, 12800, 9472, 5888, -1024, -7168, -11264, -14080, -14080, -12288, -9728, -7680, -6400, -4608, -2048, 1280, 3328, 6400, 11776, 15616, 16640, 14592, 11008, 7680, 2048, -4352, -9216, -12800, -14080, -13568, -12032, -9984, -8192, -6144, -3840, -768, 2816, 6400, 11520, 15872, 17408, 16128, 13056, 9472, 3584, -3584, -8704, -11776, -14336, -14592, -13056, -11264, -8448, -6400, -4608, -1536, 2048, 4864, 9216, 14080, 17152, 16640, 13568, 10752, 5888, -1024, -6656, -10240, -12800, -14336, -13824, -12544, -10496, -7936, -5888, -3072, 256, 3840, 8704, 13568, 16640, 17408, 15104, 12544, 8448, 1536, -5376, -9472, -12032, -14592, -15360, -14336, -12288, -9728, -7168, -4096, -512, 3584, 8448, 13056, 16384, 17920, 16128, 13568, 9728, 3328, -3584, -8704, -11264, -13568, -15104, -15104, -13568, -10752, -7680, -4864, -2048, 1280, 6656, 12032, 15616, 17408, 16384, 14592, 12288, 6656, -768, -6656, -9984, -12544, -14848, -16128, -15104, -12544, -9472, -6144, -3328, 256, 5120, 10752, 14080, 16640, 17664, 16384, 13824, 8704, 1792, -4608, -8704, -11264, -14080, -16640, -16384, -13824, -10752, -7936, -4864, -2048, 3072, 9472, 13824, 15616, 17152, 17152, 15360, 11776, 5632, -2048, -7424, -10240, -12800, -16384, -17920, -16128, -12800, -8704, -5376, -3328, 512, 7168, 13056, 15872, 17408, 17408, 15616, 13056, 8192, 768, -5888, -9216, -12032, -15360, -17920, -17152, -14848, -11264, -6912, -3584, -512, 5632, 11520, 14848, 16640, 17920, 17408, 14336, 9728, 4096, -2816, -8192, -11520, -14848, -17664, -17920, -15872, -13312, -8704, -4352, -1536, 3328, 9728, 13824, 16384, 17920, 17152, 15104, 12032, 7424, -512, -7168, -10240, -13056, -16640, -18944, -17152, -13824, -9472, -5120, -2816, 1280, 8448, 13568, 15104, 16128, 17152, 15872, 13056, 8704, 1792, -5120, -8960, -11776, -15104, -18432, -17920, -15360, -11776, -6912, -3072, 256, 6144, 12032, 15360, 16384, 17664, 16896, 13824, 9984, 3840, -3328, -8192, -11264, -13824, -17408, -18176, -15360, -12288, -8192, -4608, -1792, 3584, 9728, 13824, 15616, 17408, 17920, 15360, 11776, 6656, -512, -5888, -9728, -12800, -16128, -18432, -17408, -14080, -9984, -6144, -3328, 1280, 7936, 13312, 15616, 17152, 18176, 16384, 13568, 8704, 1792, -5376, -9216, -11776, -14592, -17664, -18432, -15360, -10752, -6912, -4352, -512, 5376, 11520, 14848, 16640, 17664, 16896, 14592, 10752, 3840, -3328, -7680, -11008, -13824, -16896, -18432, -16640, -12032, -7680, -4608, -1280, 3840, 10240, 14592, 16384, 17152, 15872, 14336, 11776, 5888, -1536, -6912, -9984, -12800, -14848, -17152, -17152, -13056, -8192, -5120, -2304, 2304, 7936, 13056, 15360, 16384, 16384, 14848, 12288, 6912, 256, -5120, -8704, -11776, -14336, -16640, -17920, -14592, -9472, -5632, -3584, 512, 6656, 12288, 15872, 16896, 16384, 15104, 13056, 8704, 2048, -4608, -7936, -10752, -13312, -15616, -17920, -16128, -10752, -6144, -3840, -768, 4864, 11008, 15360, 16128, 15360, 14592, 13312, 9984, 3584, -3584, -7168, -9216, -11776, -13824, -16640, -16896, -12544, -7424, -4352, -2304, 2560, 8448, 13824, 16384, 15872, 14848, 13568, 10752, 5888, -1280, -6400, -8960, -11776, -13824, -16128, -17152, -13824, -8448, -4352, -1792, 1792, 7680, 13056, 15616, 14848, 14080, 13056, 11008, 7168, 768, -5376, -7680, -9472, -11776, -14336, -16128, -14336, -9984, -5632, -3072, -1280, 4096, 10240, 14592, 14848, 14080, 13568, 12288, 9728, 4864, -2560, -6912, -8960, -11520, -14336, -16896, -16640, -12544, -7168, -3584, -1536, 2048, 8704, 14592, 15360, 14080, 13824, 12800, 10752, 6656, -1024, -7168, -8960, -10752, -13312, -15872, -16128, -13056, -8192, -3584, -1280, 768, 6144, 12032, 14592, 13568, 12800, 12032, 10496, 8448, 2816, -5120, -8960, -10240, -11776, -14336, -16640, -14848, -9728, -4352, -1024, 256, 3840, 10496, 14592, 14080, 12032, 11520, 10752, 8960, 4352, -3328, -8448, -9728, -10496, -12544, -14848, -14080, -10496, -5376, -1024, 0, 1792, 7424, 12800, 13312, 11520, 10752, 10240, 9472, 6400, 0, -7168, -9728, -9728, -11264, -13568, -14848, -11776, -6656, -1536, 768, 1024, 4608, 10752, 13568, 12032, 10496, 9984, 9472, 7680, 2560, -5376, -10496, -11008, -10496, -12032, -13824, -11776, -7424, -2048, 1792, 2304, 3328, 7936, 11776, 11520, 9472, 8448, 8448, 7168, 3840, -2560, -8960, -10752, -9728, -9984, -11520, -11776, -8192, -2560, 1536, 2304, 2048, 4864, 9728, 11264, 9728, 7680, 7424, 7680, 4864, -768, -7424, -10752, -9728, -8704, -10240, -11008, -8192, -3584, 768, 2816, 2816, 3840, 7680, 10496, 9984, 7680, 6400, 6400, 4864, 1024, -5376, -10240, -10752, -8192, -7680, -8448, -7424, -3840, 512, 2816, 2560, 2048, 4352, 7680, 8960, 7680, 5888, 6144, 5888, 2816, -2816, -8192, -11008, -8704, -6656, -7424, -7424, -4608, -768, 2304, 3072, 2304, 3072, 6656, 8960, 8192, 5376, 4608, 4608, 3072, -1536, -7424, -11008, -9216, -5632, -5632, -6400, -3840, 256, 2560, 2816, 2560, 2048, 4352, 7424, 7424, 5376, 4096, 4352, 3840, 512, -5376, -9984, -9984, -6144, -4352, -5120, -4096, -1280, 2304, 3328, 2560, 1792, 3072, 6144, 7168, 5888, 3584, 3072, 2816, 1024, -3584, -8448, -9984, -7168, -3840, -3584, -3072, -1536, 1280, 2816, 2304, 1792, 1792, 4096, 6656, 6400, 4096, 2560, 2816, 1536, -2048, -6144, -9472, -8192, -4352, -3072, -2816, -1280, 1280, 2816, 2816, 2560, 1792, 3072, 5376, 5376, 4096, 1792, 1024, 768, -1536, -5120, -8192, -8192, -5120, -2048, -1280, 0, 1280, 2816, 2816, 2304, 2048, 2048, 3328, 4352, 4096, 2304, 768, 512, -768, -3328, -6400, -7936, -5888, -2304, -1024, -512, 1280, 2816, 3584, 2816, 1792, 1536, 3072, 3840, 3072, 1280, -512, -512, -768, -2816, -5632, -7424, -6144, -2304, 0, 768, 2048, 3328, 3328, 3072, 2048, 1024, 1280, 1792, 2304, 1536, -768, -1280, -1024, -1280, -3584, -6144, -5888, -3328, 0, 1024, 1536, 2560, 3584, 3584, 2304, 768, 768, 1280, 1536, 1024, -1024, -1536, -1280, -1280, -2304, -4608, -5120, -3840, -1024, 1536, 2304, 2816, 3328, 3328, 2560, 1280, 256, 0, -768, 0, -1024, -1536, -1536, -1280, -1024, -2816, -4096, -4096, -2304, 768, 2048, 2816, 2816, 2560, 2816, 2048, 768, -512, -1280, -1024, -768, -1280, -1536, -1536, -512, -1280, -3072, -3840, -3328, -512, 2048, 2304, 2816, 2816, 2816, 1792, 1024, 0, -1536, -1536, -1024, -1024, -1536, -1536, -512, 0, -1792, -3328, -3840, -1280, 2048, 3328, 3072, 2304, 2816, 2304, 1024, -1280, -2816, -2816, -2048, -1280, -1280, -1280, 0, 1024, 768, -1024, -2816, -2048, 768, 2816, 3072, 2048, 1792, 1024, 512, -512, -2560, -3584, -3328, -1792, -768, -1024, -512, 768, 1024, 256, -2048, -2048, 768, 3328, 4352, 3072, 2816, 1792, 256, -1536, -4096, -5376, -4864, -3328, -1792, -512, 768, 1792, 2560, 2560, 256, -1536, -512, 2048, 3584, 3072, 2560, 1024, -512, -1536, -3840, -5376, -5120, -3840, -2048, -512, 768, 1280, 2304, 3584, 1280, -1536, 256, 3072, 4608, 3584, 2304, 1792, 512, -1024, -4608, -7168, -6912, -5632, -3072, -1280, 768, 2304, 3328, 4608, 4096, 1280, 256, 1792, 3584, 3328, 2048, 1280, -1280, -2304, -4352, -6656, -6656, -5888, -3840, -1024, 1280, 2048, 2816, 4352, 4352, 1792, 512, 1792, 4096, 4608, 2560, 1024, -512, -1536, -4096, -7936, -8448, -6912, -4608, -2304, 0, 1792, 3072, 4608, 5632, 4096, 2304, 2304, 4096, 5120, 3328, 1280, -512, -2304, -4608, -8448, -9472, -7424, -5632, -3328, -1024, 1792, 3840, 5376, 6400, 5376, 3840, 3328, 4352, 5120, 3584, 1280, -768, -2048, -4608, -8960, -10752, -9216, -6144, -4096, -1536, 1280, 3328, 5888, 6912, 6400, 5120, 4352, 4864, 5120, 3840, 1280, -768, -2048, -5376, -8960, -11520, -9984, -6400, -4608, -2816, 768, 4096, 6400, 7424, 6912, 6656, 6144, 5888, 5376, 4352, 2048, -1024, -3072, -5888, -8960, -11776, -11776, -8704, -5632, -3840, -768, 3328, 6400, 7936, 8448, 8704, 7936, 7168, 6400, 5120, 2816, -1024, -3072, -5632, -9728, -12544, -13056, -9984, -6656, -5376, -2816, 2048, 6144, 8704, 8960, 9216, 9472, 8960, 7424, 5376, 3328, 0, -2816, -5120, -9216, -12288, -13312, -11776, -7936, -5632, -3584, 256, 4864, 8704, 9728, 9984, 10240, 9728, 8704, 6144, 3840, 0, -3584, -5376, -8704, -12032, -13568, -12800, -8960, -5632, -4352, -1280, 3328, 7936, 9472, 9728, 10752, 10496, 9472, 7168, 5376, 2304, -2048, -4864, -7680, -11264, -12800, -13568, -11776, -8192, -5888, -2816, 1792, 6656, 9984, 11008, 12544, 12288, 10752, 8192, 5120, 2304, -2304, -5376, -7936, -11776, -13312, -13824, -12800, -8960, -6144, -3328, 1024, 5888, 10240, 11776, 12288, 12544, 11776, 9472, 6656, 3328, -1024, -5120, -7424, -10752, -12800, -13568, -13824, -11008, -7936, -5376, -512, 4352, 9216, 12032, 13568, 14336, 13056, 10752, 7424, 4352, 768, -4096, -7680, -10496, -13056, -14080, -14592, -13056, -8960, -6144, -2304, 2816, 7680, 12032, 13568, 14592, 14080, 11776, 8704, 5120, 1536, -3072, -7424, -11008, -13312, -14080, -14080, -14080, -10752, -7424, -3072, 2048, 6400, 10496, 14080, 15872, 15104, 13056, 9472, 5888, 2560, -1536, -6144, -10240, -13056, -14336, -14848, -14848, -12288, -8448, -4864, 512, 5632, 10496, 14080, 15616, 15616, 14336, 11520, 7168, 2816, -768, -4864, -9472, -13056, -14592, -14848, -14848, -13824, -9984, -5888, -512, 5120, 9216, 13312, 16384, 16640, 14848, 12288, 8448, 4864, 1024, -3328, -8960, -13056, -14848, -15616, -15872, -15360, -12032, -7424, -1792, 4352, 8704, 12800, 17152, 17920, 15872, 12800, 8960, 5120, 1536, -2048, -7424, -12032, -14592, -15872, -15616, -15360, -13824, -9472, -3840, 2560, 7424, 11264, 15360, 17408, 16896, 14336, 10752, 6144, 3072, 256, -4864, -10496, -14080, -15360, -15872, -15616, -14592, -11008, -5376, 1792, 6144, 9216, 13568, 16896, 17152, 15104, 11776, 7680, 3840, 1280, -2816, -8192, -12288, -14848, -16128, -15872, -15104, -12800, -8192, -768, 5632, 8960, 12544, 15360, 16896, 16128, 13568, 9728, 4864, 2048, -1280, -6400, -11008, -14592, -16384, -16384, -15872, -13824, -9984, -3328, 4096, 8192, 11776, 15104, 16640, 16896, 14336, 11520, 6656, 2816, 768, -4352, -9984, -14336, -16640, -17152, -15872, -14336, -11264, -5376, 2560, 7424, 10240, 13824, 16128, 17408, 15616, 12544, 8448, 3328, 512, -3584, -8704, -12800, -16384, -17152, -16128, -14336, -11264, -6656, 512, 6912, 9728, 12544, 14592, 16384, 15616, 12800, 9216, 4352, 1536, -1792, -6912, -11264, -15360, -17152, -16128, -14592, -12288, -8192, -1792, 5632, 9216, 11264, 13568, 15360, 15872, 14080, 10496, 5376, 1792, -768, -5120, -10240, -14848, -17408, -16640, -14592, -12032, -8704, -3584, 4096, 9472, 10752, 12032, 14080, 15104, 13568, 10752, 6912, 2560, -512, -3584, -7680, -12032, -15360, -16128, -14592, -12544, -9728, -5120, 1280, 7680, 10240, 11264, 13312, 14592, 14592, 11776, 7936, 3328, -512, -3072, -6912, -11264, -14592, -16384, -15616, -12800, -9728, -5120, 512, 6400, 9984, 10496, 12544, 14080, 13824, 11520, 8192, 4352, 0, -3072, -5888, -9472, -12800, -15104, -15616, -13312, -9728, -5632, -1536, 4352, 8960, 9984, 10752, 12288, 13568, 12288, 9216, 5632, 1024, -2304, -4608, -7680, -11520, -14336, -15104, -13824, -10752, -6912, -2560, 3072, 7424, 9472, 9728, 11264, 12800, 12032, 9472, 6400, 2304, -1280, -3328, -5888, -9728, -12800, -14080, -13824, -11520, -8192, -4352, 1280, 6400, 8704, 8960, 9984, 11776, 12288, 10240, 7424, 3328, -768, -2816, -5376, -8448, -11264, -13056, -13824, -12032, -8704, -4352, 512, 5376, 8192, 8704, 8704, 9728, 10752, 9984, 6912, 3840, 256, -1792, -3328, -6400, -9216, -11520, -12544, -11776, -9216, -5888, -1536, 3840, 6912, 7936, 7936, 8704, 9984, 9728, 7680, 4608, 768, -1536, -2560, -4864, -8192, -10240, -11776, -11520, -9216, -6144, -2816, 2048, 6144, 7424, 6912, 7424, 8704, 9216, 7680, 4608, 1024, -1280, -1280, -3072, -6400, -8704, -9984, -10496, -9472, -6144, -2816, 1024, 4608, 6144, 6400, 6400, 7424, 7424, 6656, 4864, 1280, -1536, -1536, -1536, -4608, -7168, -8448, -9472, -8704, -6144, -2816, 512, 3840, 6144, 5888, 5120, 6144, 6912, 5632, 3584, 1024, -1024, -1024, -1280, -3840, -6144, -6656, -7424, -8192, -6912, -3328, 512, 3584, 5376, 5376, 4608, 5376, 5888, 5120, 3328, 1280, -768, -1280, -1024, -2304, -4096, -5376, -6400, -7168, -6400, -3584, 256, 2560, 4096, 4864, 4096, 4096, 4608, 4096, 2816, 1280, -512, -1280, -1024, -1536, -3072, -4352, -5120, -5632, -5632, -4352, -1024, 2048, 3328, 4096, 3840, 3328, 3840, 3584, 2560, 1024, -1024, -1536, -1536, -1280, -1792, -2816, -3840, -4352, -4352, -3840, -768, 2560, 3328, 3584, 2816, 1792, 2048, 2304, 1280, -768, -2048, -1792, -1024, -512, -512, -1536, -2560, -2304, -2560, -3072, -1280, 2816, 3840, 3328, 2816, 1280, 1536, 1792, 768, -1536, -2560, -2048, -1536, -1536, -512, 256, -512, -1536, -1536, -1792, -1280, 2048, 3584, 2560, 1792, 1024, 0, 256, -512, -1536, -3072, -2816, -1536, -512, 1024, 2048, 1024, -512, -512, -1024, -1280, 768, 3072, 2048, 1280, 1024, 0, 0, -512, -2048, -3328, -3840, -3072, -1792, -768, 1536, 2560, 1792, 1280, 1536, 1024, 1536, 3584, 2560, 768, 0, -1536, -2560, -1792, -2560, -4096, -4864, -3840, -2048, 0, 2816, 4352, 3328, 2560, 2816, 1792, 1280, 2048, 2304, 512, -1024, -1792, -3072, -2560, -2560, -4096, -5376, -4864, -3328, -1024, 2560, 5376, 5632, 4352, 4352, 3584, 2304, 2304, 2304, 768, -1792, -3072, -4352, -4096, -3584, -5120, -6400, -5376, -3840, -1280, 2560, 5888, 6912, 6400, 5632, 4608, 2816, 2048, 1024, -512, -2304, -3584, -4608, -4864, -3584, -3840, -5888, -6400, -5120, -2560, 2304, 5632, 7424, 7424, 6656, 5888, 4096, 3072, 1536, 256, -1536, -3584, -4608, -5632, -5120, -4864, -6912, -7168, -6400, -4608, 0, 4864, 8192, 9216, 8448, 7936, 5888, 3584, 1792, 256, -1024, -3840, -5888, -6400, -6144, -4864, -6400, -8192, -7424, -5120, -768, 4096, 7936, 10240, 9728, 9216, 7424, 4096, 2304, 256, -1024, -3072, -5888, -6656, -7168, -6144, -6656, -8704, -8448, -6144, -2048, 3072, 7424, 10496, 11264, 11264, 9472, 5632, 2816, 1024, -1024, -2816, -6144, -7936, -8192, -7936, -7680, -9216, -9984, -7680, -2816, 2816, 7424, 11008, 13056, 12800, 11264, 8192, 3840, 1024, -1024, -2816, -6144, -8192, -8448, -8448, -8704, -9728, -10752, -8960, -4352, 1024, 6144, 10752, 14336, 15360, 13312, 9728, 4864, 1792, 256, -3328, -7168, -9472, -9472, -8960, -9472, -9984, -11008, -9472, -4864, 768, 5632, 10496, 14592, 16384, 14592, 11264, 6656, 1792, -512, -2816, -6144, -8960, -10496, -10240, -9728, -9984, -11008, -10240, -6144, 0, 5120, 9472, 14080, 16640, 16128, 12800, 8192, 2304, -1024, -2560, -6144, -9216, -10752, -10752, -10496, -10496, -10496, -9984, -6656, -512, 4864, 8704, 13056, 16384, 16896, 14080, 9728, 3840, -768, -2048, -5120, -8704, -10752, -11264, -11008, -11264, -11520, -11520, -8960, -3072, 3584, 7936, 12800, 16896, 18688, 16640, 12544, 7168, 1792, -1536, -4608, -8960, -11520, -12544, -13056, -13568, -13056, -12032, -9472, -4096, 2560, 7680, 12544, 17664, 19968, 18432, 14336, 8960, 3584, -1024, -4352, -8448, -11776, -13056, -14080, -14336, -13824, -13056, -10240, -5120, 1280, 6656, 11264, 16384, 19456, 19712, 16384, 10496, 4864, 256, -3584, -7680, -11008, -12800, -14592, -15360, -14848, -13824, -11008, -6144, -512, 5376, 9984, 15616, 19456, 20224, 18432, 13312, 7168, 2304, -2560, -6656, -10496, -12544, -13824, -15616, -15872, -15104, -13056, -8448, -2560, 3584, 8704, 14080, 19200, 20736, 20224, 16128, 9984, 4864, -512, -5888, -10240, -13056, -14336, -16384, -17152, -16384, -14336, -9984, -4096, 2304, 7424, 13056, 18688, 21248, 20992, 18688, 12800, 6912, 2304, -4608, -10240, -13312, -14336, -16128, -17664, -17664, -15616, -11008, -5120, 512, 5376, 10752, 16896, 20736, 20992, 19456, 15104, 9216, 4864, -1536, -8448, -12800, -14592, -15616, -18176, -19456, -17408, -13312, -7168, -512, 4352, 9216, 15872, 21248, 22016, 20992, 17664, 11008, 5632, 512, -7168, -13056, -15360, -16128, -17152, -19456, -18944, -14592, -8704, -1792, 3584, 7424, 13568, 19456, 22272, 21504, 19200, 13824, 8448, 3584, -4608, -11776, -14848, -15872, -17664, -20480, -21504, -17408, -11264, -4608, 1792, 6656, 12544, 19200, 23296, 23552, 20992, 16384, 10752, 5376, -2048, -11008, -16128, -17408, -17408, -19200, -22016, -19456, -12288, -5632, 1024, 5888, 10496, 16896, 22272, 23552, 21248, 17664, 13056, 7936, 1536, -7936, -15104, -17152, -17664, -18944, -22528, -22272, -15872, -8704, -1792, 4352, 9216, 15872, 22272, 24576, 23040, 19456, 15360, 9984, 3584, -5888, -14848, -17920, -18176, -18688, -21248, -22784, -17408, -9472, -3328, 2304, 6656, 13056, 20224, 24064, 23296, 20480, 17408, 13312, 7168, -2048, -12288, -17152, -17920, -18688, -21504, -24576, -21248, -12544, -5632, 0, 5120, 11264, 19200, 24576, 25088, 22528, 19200, 15616, 10240, 1536, -9984, -17152, -18432, -19200, -21248, -24320, -23296, -15360, -7424, -1792, 3328, 9216, 16896, 22784, 24832, 23552, 19968, 16640, 12800, 5632, -5376, -14848, -18176, -18688, -19968, -23296, -25088, -20224, -11520, -3840, 1024, 6400, 14336, 21504, 25856, 25344, 22016, 18688, 15360, 8960, -2304, -13568, -18432, -19712, -20480, -23040, -25088, -21760, -13056, -5120, -512, 4608, 12288, 19712, 24576, 25344, 22272, 19200, 15872, 11776, 2304, -9984, -17408, -19200, -19200, -21248, -24320, -24064, -17152, -7680, -1792, 2048, 8704, 17408, 23552, 26112, 23808, 20992, 18432, 14848, 6656, -6144, -15616, -19200, -19968, -21760, -24832, -25344, -19968, -10752, -3072, 1536, 7168, 15104, 22272, 26112, 25344, 22016, 18944, 15872, 9728, -1792, -13312, -19456, -20736, -21248, -23808, -25600, -23040, -14592, -5888, -512, 4608, 12288, 20480, 26112, 26368, 23552, 20736, 18176, 13056, 2304, -10496, -18432, -21248, -21760, -23808, -25600, -23552, -16640, -8192, -1792, 3328, 9984, 18432, 24832, 26368, 24320, 21760, 18688, 14080, 6400, -5376, -15616, -20224, -21248, -23040, -25344, -24832, -19712, -11520, -4352, 256, 6144, 15104, 23808, 27392, 26368, 23552, 21760, 18432, 10752, -1536, -13824, -20480, -22016, -23296, -26624, -26880, -22272, -14336, -5888, 0, 4608, 12288, 21760, 27136, 27136, 24576, 22272, 19712, 13312, 3328, -8960, -18176, -21504, -22528, -25088, -27136, -24576, -17920, -10240, -3584, 1536, 7936, 17920, 26368, 28416, 26368, 24320, 22528, 17408, 7424, -4864, -15616, -21504, -23296, -25344, -27136, -25856, -20480, -13056, -5632, 512, 5888, 14336, 23296, 27904, 27648, 25088, 22784, 19456, 11520, 256, -11264, -19456, -22272, -23552, -26112, -26624, -23040, -16384, -8704, -2816, 2048, 9472, 19968, 27648, 28928, 27136, 24576, 21760, 15616, 4864, -7424, -17408, -22528, -24064, -26112, -26624, -23808, -18688, -11776, -5376, 512, 7168, 16128, 25088, 28928, 27904, 25600, 22784, 17920, 8448, -3584, -14080, -20736, -23296, -25088, -26624, -25088, -20224, -13824, -7680, -2304, 4608, 13312, 22784, 27648, 28160, 26624, 24576, 20224, 11776, 512, -10240, -18176, -23040, -25600, -26624, -25600, -22016, -17152, -11264, -4864, 1792, 10240, 19712, 26880, 29440, 27904, 25344, 22016, 14848, 4352, -7424, -16128, -22016, -24832, -25856, -25856, -23552, -18944, -12800, -6656, -1024, 7168, 16896, 25088, 29184, 28928, 26112, 23040, 17408, 8448, -3840, -13568, -19456, -23808, -25856, -26624, -24576, -20224, -14592, -8704, -3840, 3840, 14336, 23040, 28160, 29440, 26880, 23808, 19200, 11264, 0, -11008, -17408, -22016, -25088, -25856, -25088, -21248, -16640, -10752, -5632, 1024, 10496, 20224, 26624, 28928, 27392, 24576, 20736, 14592, 4096, -7936, -15104, -20224, -24320, -25856, -25600, -23040, -18176, -12544, -7680, -2304, 7168, 17152, 24832, 28160, 27392, 24832, 22016, 16640, 7680, -3584, -12032, -17152, -21504, -25088, -26112, -24576, -20224, -15104, -10496, -5632, 3584, 13568, 23040, 28160, 28416, 25856, 23040, 19200, 11520, 512, -9984, -16384, -20224, -23808, -26112, -25856, -22272, -16384, -11264, -7168, 0, 9984, 20736, 27648, 28160, 26112, 23808, 20992, 14848, 4608, -6400, -13824, -17920, -21760, -25856, -26368, -24064, -18432, -13568, -9984, -3584, 6400, 17920, 26624, 28672, 26368, 24576, 22528, 17920, 8704, -3328, -12288, -16640, -19968, -24832, -27648, -25856, -20224, -14080, -10752, -6144, 2816, 14336, 24576, 28416, 26368, 24064, 23040, 19712, 11776, 1280, -8704, -14336, -18176, -23552, -27904, -27904, -23296, -16384, -11776, -7680, 0, 11264, 22784, 28672, 27648, 24320, 22528, 20480, 14592, 4096, -6912, -13824, -16896, -20992, -26624, -28672, -25600, -18176, -11776, -8704, -3328, 7424, 20480, 28416, 28672, 24832, 22016, 21504, 17664, 8192, -3840, -12288, -15616, -18432, -24064, -27904, -27136, -20992, -13824, -9472, -5888, 2816, 15616, 25856, 28928, 25856, 21760, 20480, 19200, 12288, 1024, -9472, -14336, -16384, -21504, -27392, -28672, -23040, -15360, -9472, -7424, -1792, 11008, 23296, 28416, 26368, 22016, 20480, 19712, 14848, 5120, -6144, -13312, -15616, -19200, -25600, -28416, -25344, -18432, -11264, -6912, -3072, 7424, 19712, 26880, 27136, 23296, 20480, 19200, 16384, 8448, -2304, -11008, -14848, -17664, -24064, -28416, -26624, -19968, -12544, -7168, -4608, 2816, 15872, 24832, 27392, 24064, 20480, 19200, 17664, 12032, 1536, -9216, -14080, -15872, -20736, -26880, -27648, -22272, -15104, -8448, -4608, 256, 11776, 22016, 26368, 24832, 21248, 19200, 17664, 13312, 4864, -5888, -12800, -15104, -18944, -24832, -27136, -23296, -16384, -9728, -5376, -2304, 6656, 17920, 24320, 24320, 20480, 18176, 17664, 15360, 8960, -1536, -10240, -13568, -16384, -22272, -26112, -24576, -18432, -11520, -6400, -3584, 3328, 14336, 22272, 24320, 22016, 19200, 17664, 15360, 10496, 1536, -8192, -13824, -15872, -19712, -24320, -25344, -20224, -13056, -5888, -2048, 1536, 9984, 19200, 23552, 22272, 18432, 16384, 15872, 12544, 5376, -4352, -12032, -14592, -17152, -22016, -24832, -22272, -15104, -8192, -4096, -1024, 6400, 16128, 22784, 23552, 19968, 17152, 16128, 13568, 6912, -2560, -10240, -14080, -16128, -19968, -23808, -22784, -16640, -9216, -4352, -1792, 2816, 11264, 19712, 22784, 20224, 16640, 15616, 14848, 10496, 2048, -6656, -12800, -15104, -17152, -21248, -23040, -19456, -12032, -6400, -3328, 768, 7680, 16128, 21760, 20992, 17920, 16128, 14848, 11520, 3584, -4608, -11008, -14336, -16128, -18944, -21504, -19968, -13312, -6656, -3328, -512, 4864, 11776, 18688, 20736, 17408, 14592, 14080, 12544, 6912, -1280, -8192, -12288, -13824, -16128, -19712, -20480, -15360, -8704, -4352, -1280, 2560, 8704, 15872, 20224, 18176, 14592, 13312, 12288, 7936, 512, -6656, -11520, -12800, -13568, -16640, -19200, -16128, -9472, -4096, -1536, 1024, 4864, 11520, 17408, 17920, 14592, 12544, 12544, 9984, 4096, -2816, -8448, -11520, -12544, -14336, -17920, -18176, -13056, -6656, -2048, 512, 3328, 8960, 16128, 19456, 16128, 12288, 11008, 9728, 5888, -1792, -8192, -11520, -12032, -12032, -14848, -17152, -14080, -7680, -2048, 0, 1024, 5120, 11776, 17408, 16640, 12032, 9728, 9728, 7936, 2048, -4864, -9472, -11264, -10752, -12288, -16128, -15872, -10496, -4096, -512, 1280, 4096, 9472, 15616, 17408, 13568, 9728, 8704, 7936, 3584, -3584, -8448, -10240, -9728, -10496, -13824, -15360, -11776, -5120, -1280, -768, 1536, 6400, 12544, 16128, 14080, 9728, 8192, 8448, 6144, 256, -5888, -8704, -8960, -9216, -11520, -15104, -14080, -7680, -2304, -768, 512, 4096, 9984, 15104, 15104, 11264, 8192, 7680, 6656, 1792, -5120, -8448, -8448, -8192, -10240, -13568, -13824, -8960, -3072, -768, -512, 2560, 7424, 12288, 14080, 11520, 8192, 7168, 6912, 3584, -2560, -6912, -7680, -7168, -8704, -11776, -13568, -10496, -4352, -1280, -1280, 1280, 6144, 11264, 13824, 11776, 8192, 6400, 6400, 4608, -1024, -6400, -7936, -6144, -6912, -9984, -12032, -10752, -5376, -1024, -512, 256, 3840, 8960, 11776, 11264, 7936, 5632, 5888, 5120, 1536, -3840, -6656, -5888, -5120, -7424, -10496, -10752, -7424, -2816, -1024, -1024, 1792, 6656, 10752, 12032, 9472, 6400, 5376, 4864, 2304, -2560, -6400, -6400, -4608, -6144, -9728, -10240, -7424, -2816, 256, 0, 768, 4864, 8704, 10752, 8448, 4864, 3584, 3840, 2560, -1280, -5376, -6144, -3840, -3328, -6656, -8960, -7936, -4352, -512, 0, -512, 2816, 6656, 9472, 8704, 5120, 3584, 3328, 3072, 512, -4352, -6400, -4352, -3072, -5376, -7936, -7680, -4864, -1024, 1024, 256, 2304, 5632, 8192, 8192, 4864, 2304, 2304, 2560, 1024, -2816, -5376, -4096, -2304, -3584, -5888, -6656, -5120, -2048, 0, -512, 768, 3840, 6656, 7936, 6144, 3072, 2304, 2560, 1536, -1280, -4352, -4864, -3072, -2816, -4608, -6400, -5632, -2560, 256, 512, 512, 2816, 5632, 7424, 6144, 2560, 768, 1280, 1024, -1024, -3328, -3840, -2048, -1280, -2560, -4096, -4608, -3584, -1280, -512, 0, 1536, 3328, 5120, 5888, 4096, 1536, 1280, 1280, 0, -1792, -3072, -3072, -2048, -1792, -3072, -4864, -4608, -1792, 0, 512, 1792, 3328, 4608, 5120, 3328, 768, -512, 256, -512, -1536, -2048, -1536, -768, -512, -512, -2560, -3584, -2560, -1536, -1024, 0, 1024, 2304, 3584, 3840, 1536, -512, -512, -512, -1024, -1024, -1280, -768, 512, 768, -768, -2560, -2304, -1280, 0, 0, 0, 768, 2048, 2560, 768, -1280, -1792, -1536, -1024, 0, -512, -512, 768, 1792, 1792, 512, -1280, -1536, -768, 512, 512, 0, 0, 512, 512, -1024, -2304, -2304, -1792, -768, 512, 1024, 2048, 2304, 1536, 512, -768, -1024, -768, -512, -512, -512, 0, 256, -768, -2048, -2816, -2048, -1536, -1024, 512, 1536, 2304, 2560, 2304, 2048, 1280, -1024, -1792, -768, 256, 256, -1536, -1792, -1536, -1536, -2816, -3584, -2560, -1280, 768, 2304, 3072, 3584, 3328, 2560, 2304, 256, -1536, -1280, -1024, -768, -1024, -1536, -2048, -3072, -3072, -3328, -3328, -2816, -768, 2304, 4096, 4608, 3840, 3328, 3584, 2816, -512, -1536, -1024, -768, -1280, -2816, -3328, -3072, -3584, -3840, -3584, -2560, -1024, 1536, 3840, 5632, 5376, 4096, 3328, 3072, 768, -1792, -2048, -1792, -1792, -2560, -3584, -4352, -4096, -3328, -3072, -2560, -1792, 768, 3840, 6144, 6656, 4864, 4096, 4608, 3072, -768, -2304, -2560, -2304, -2816, -4608, -5632, -5376, -4352, -3584, -3584, -2560, 0, 3584, 6656, 8192, 7168, 5888, 5632, 5376, 1280, -2304, -3072, -4096, -4608, -5632, -6912, -6912, -5888, -4352, -3328, -2048, 512, 3072, 6400, 8960, 9216, 7424, 5376, 5120, 2816, -1536, -3584, -4352, -4864, -5632, -6912, -7168, -6144, -5120, -3840, -2816, -1024, 1792, 4864, 8192, 9984, 8960, 7168, 6400, 4864, 1024, -2560, -4352, -6144, -7168, -7936, -8448, -7680, -6656, -4864, -2816, -768, 2048, 4864, 7936, 10752, 10752, 8704, 6912, 5376, 2304, -2304, -4864, -6656, -7936, -8960, -8704, -7680, -6656, -5888, -3328, -1024, 1024, 3584, 6400, 10752, 12544, 10496, 7936, 6912, 5120, 768, -3840, -7168, -9472, -9728, -9984, -9728, -8960, -7424, -4096, 0, 2304, 4352, 6656, 10496, 13312, 12288, 9216, 6656, 4864, 1536, -4096, -7680, -9984, -11008, -10496, -9984, -8448, -7424, -5632, -1280, 1792, 3328, 5376, 9216, 14080, 14336, 11776, 8704, 6144, 3840, -2048, -7424, -11264, -13824, -12800, -11264, -9984, -8960, -6912, -1792, 2816, 5120, 6400, 8704, 13824, 16128, 13568, 9728, 5632, 3584, 0, -6912, -11520, -14336, -14336, -11776, -9984, -9216, -7936, -3584, 2048, 4864, 5888, 7424, 11776, 16128, 15616, 12032, 7680, 5120, 2048, -3840, -9984, -14336, -15872, -13824, -11264, -10496, -9728, -5888, -512, 4096, 5888, 7168, 10752, 16128, 17664, 14848, 10496, 6400, 3328, -1792, -8704, -14336, -17408, -16384, -12800, -11520, -11008, -7424, -1792, 3840, 6656, 7424, 10240, 14848, 18432, 17152, 12288, 7680, 4096, 0, -6656, -13568, -17408, -17664, -14592, -12032, -11776, -9216, -4096, 2304, 6400, 7680, 9728, 13568, 18176, 18944, 14848, 9472, 4352, 512, -5376, -12544, -17920, -19456, -16384, -12544, -11008, -9728, -5376, 768, 6400, 8448, 9472, 12544, 16640, 18944, 16640, 11520, 6144, 2048, -2816, -10240, -17408, -20224, -18432, -14592, -12288, -10752, -7424, -1536, 5120, 8704, 9984, 12288, 16128, 19712, 18944, 14336, 7936, 2816, -2048, -8448, -15616, -20224, -20480, -17408, -13568, -11520, -8704, -4096, 2816, 7936, 10496, 13056, 15616, 19200, 19968, 16384, 10752, 4864, -768, -6912, -14080, -19968, -21504, -18688, -15104, -12288, -9472, -5120, 1280, 6912, 10240, 12544, 14848, 18176, 20480, 18176, 12544, 5888, 512, -5120, -12032, -18432, -22016, -20992, -16896, -13312, -9984, -6656, -1280, 5120, 9984, 13056, 15104, 17664, 20224, 19712, 15616, 8704, 1792, -4096, -10752, -17408, -22528, -23040, -19200, -14848, -10496, -6656, -2048, 4352, 9984, 13312, 15104, 16640, 18944, 19712, 16640, 10496, 3072, -3072, -8960, -15360, -20736, -22784, -20224, -15360, -11520, -8448, -4352, 1536, 7936, 12544, 15104, 16384, 18688, 20480, 18944, 13056, 5632, -1280, -7424, -13824, -19968, -23552, -23040, -17920, -12544, -8960, -4608, 768, 6656, 12288, 15360, 16384, 17408, 19200, 19200, 14848, 7936, 256, -6400, -12288, -18688, -22528, -23040, -19712, -14336, -10496, -5888, -768, 5376, 11008, 14848, 16384, 17920, 19200, 19712, 16384, 10240, 3072, -4608, -11264, -17920, -22272, -24064, -22272, -16384, -10752, -5632, -1024, 4096, 9984, 14848, 16640, 16896, 17152, 18944, 17408, 11776, 4608, -3072, -9728, -15872, -20992, -23552, -22784, -17152, -11520, -7168, -2304, 3328, 7936, 13312, 16384, 17152, 16896, 18432, 18176, 13568, 7424, -768, -8704, -15104, -20224, -24064, -24576, -19712, -12800, -7424, -2048, 3072, 7680, 12544, 16128, 17408, 17152, 17408, 17920, 14336, 8704, 1536, -7424, -14592, -19712, -23552, -25344, -21504, -14336, -8192, -2560, 2816, 7424, 11520, 15616, 17664, 17664, 17408, 17920, 15360, 9472, 3072, -5120, -12800, -18688, -23040, -25600, -23296, -16384, -9472, -3584, 1792, 6400, 10752, 14592, 16896, 17152, 16640, 17152, 16384, 11520, 5376, -2304, -10496, -16896, -21504, -25088, -24320, -18944, -12032, -5376, 768, 5888, 9984, 13824, 16384, 17664, 17664, 17152, 16128, 12800, 6912, 0, -8448, -16128, -21248, -24064, -24320, -20224, -13824, -6656, -512, 4608, 8960, 12544, 15616, 17152, 17152, 16640, 16384, 14080, 8448, 1536, -6400, -14080, -20992, -24320, -25088, -21504, -15360, -8192, -1536, 4352, 9216, 12288, 14336, 16384, 16896, 16640, 15872, 14080, 9984, 3584, -4096, -11776, -19456, -23552, -24576, -22528, -17664, -10496, -2304, 3840, 8448, 11776, 13824, 15872, 17408, 16896, 15104, 13824, 11264, 5120, -3072, -10496, -18432, -23552, -24832, -23040, -18176, -11776, -3584, 3840, 8704, 12288, 14080, 15104, 15872, 16128, 15360, 13056, 10752, 6144, -1536, -8704, -16128, -22272, -24320, -22784, -19200, -13312, -5888, 2560, 7936, 11520, 13824, 14848, 15872, 16896, 16128, 13056, 10752, 7680, 256, -8192, -15104, -21504, -24576, -23808, -20480, -14848, -7168, 1792, 8192, 11520, 13568, 15360, 16384, 17152, 15872, 13312, 10496, 7936, 2304, -6400, -14080, -19968, -23552, -23296, -20992, -16640, -9984, -512, 7680, 11008, 12544, 14336, 15616, 16640, 16128, 13824, 11264, 8448, 4096, -3840, -12032, -18432, -22528, -23296, -21504, -17920, -11520, -3072, 5632, 10752, 12288, 13824, 14848, 15616, 16128, 14336, 11008, 8192, 5120, -1024, -9216, -16640, -20992, -22272, -20992, -18432, -13568, -5888, 3840, 10240, 11776, 12288, 14080, 15616, 15872, 14080, 11008, 8192, 5376, 1024, -6656, -14592, -19200, -20992, -20480, -18688, -14848, -7680, 1280, 8960, 11776, 12032, 13056, 14592, 15616, 14592, 11776, 8704, 5632, 2304, -3840, -12032, -18176, -20736, -20480, -19200, -15872, -9216, -1024, 7168, 11776, 12032, 12544, 14336, 15360, 14592, 12288, 8960, 5888, 3072, -2304, -9984, -17152, -19968, -19456, -18176, -16640, -11520, -3328, 5376, 11520, 12800, 11776, 12800, 14848, 15104, 12544, 8960, 5888, 3072, -1024, -7936, -15872, -19968, -18944, -17920, -16640, -12544, -4608, 4608, 11008, 13056, 11520, 12288, 14336, 14336, 11520, 7680, 5120, 3072, 0, -6144, -13568, -18176, -17664, -16128, -15360, -13056, -6400, 2304, 9216, 12800, 12032, 11264, 12800, 13312, 11520, 8192, 5376, 3072, 256, -4608, -11264, -16896, -17920, -16384, -15104, -13056, -7936, 512, 8192, 12800, 13056, 11776, 12032, 13312, 12032, 8192, 4352, 2304, 0, -3584, -8704, -14592, -17152, -15872, -14336, -12800, -8448, -1536, 6144, 11264, 13056, 12288, 12032, 12288, 11776, 8704, 5376, 3072, 512, -3328, -8192, -13056, -15872, -15872, -14336, -13056, -9728, -3328, 4608, 10240, 13056, 12800, 11520, 12032, 11776, 9216, 5120, 2304, -512, -3584, -7168, -11520, -15104, -15616, -13824, -12288, -9472, -3840, 3584, 9216, 12544, 13312, 12288, 11264, 10752, 8448, 4864, 2560, 0, -3328, -6656, -9984, -13312, -14848, -13824, -12032, -9472, -4864, 2304, 7680, 11264, 13312, 12288, 10240, 9728, 7936, 4864, 1792, -768, -3072, -5632, -7936, -10752, -13056, -12544, -11008, -9216, -5632, 256, 5632, 8960, 11520, 12032, 10496, 9472, 7936, 5888, 3328, 768, -2816, -5632, -7168, -9216, -12288, -13568, -11776, -8960, -5888, -1024, 4352, 7936, 11520, 12544, 10496, 8448, 7424, 5888, 3328, 512, -2816, -5632, -6656, -7424, -9728, -11776, -11520, -8704, -5376, -1536, 3584, 6400, 9728, 11776, 11008, 8960, 6912, 4864, 2560, 768, -1792, -5120, -7168, -7168, -8192, -9728, -10496, -8960, -5888, -2048, 2560, 5888, 8448, 11264, 11264, 9216, 6912, 4608, 2560, 0, -2304, -5632, -7168, -7168, -7168, -8448, -9472, -8192, -5376, -1792, 2048, 5120, 7168, 9728, 10496, 9216, 6912, 4352, 2048, -512, -1536, -4352, -7168, -7936, -7168, -6912, -7680, -7680, -5632, -1792, 2304, 4864, 6656, 8960, 10496, 9472, 6656, 4096, 1536, -1280, -2816, -4608, -7168, -7936, -7168, -5632, -5888, -5888, -4608, -1024, 2816, 4864, 6144, 6912, 8448, 8448, 6144, 3584, 768, -2048, -2816, -3840, -5888, -7424, -7424, -5376, -4608, -4864, -3840, -1280, 2304, 4096, 5376, 6656, 7680, 8192, 6400, 3328, 512, -2304, -3328, -4096, -5376, -6912, -6912, -5120, -3072, -3328, -3584, -1792, 2304, 4352, 5120, 6144, 6400, 6656, 6912, 3840, 512, -2304, -4352, -4352, -5120, -6400, -7168, -5888, -2816, -1536, -2048, -1280, 1792, 4864, 5888, 6144, 6144, 6144, 6400, 4096, 0, -3328, -5632, -5632, -5632, -6656, -7168, -5632, -2048, 512, 256, 0, 2048, 4608, 6144, 6144, 5120, 4608, 5120, 3840, 256, -3072, -5632, -6144, -5632, -5888, -6400, -5632, -3328, 512, 1792, 768, 2048, 4096, 6400, 7168, 5376, 3840, 3840, 3840, 1024, -3328, -6400, -7424, -6144, -5120, -6144, -5376, -3072, 256, 3072, 2560, 2304, 4096, 5888, 6912, 5376, 3584, 3072, 2560, 768, -2560, -5376, -7168, -6912, -5632, -5632, -5120, -3584, -1024, 2560, 3584, 2816, 4352, 5888, 7424, 6656, 3840, 2816, 2560, 1024, -3072, -6400, -8448, -8448, -6656, -5888, -5632, -3072, 0, 3328, 5632, 4864, 5120, 6400, 7424, 6400, 3072, 1280, 768, 0, -3072, -6400, -8192, -8704, -6912, -5376, -5120, -2816, -512, 1792, 4608, 5376, 5632, 6656, 7680, 7424, 5376, 2816, 1024, -1280, -3584, -7424, -9728, -9728, -8448, -6912, -5888, -2560, 1024, 3072, 5632, 7424, 7680, 7680, 7936, 7680, 5376, 2560, 0, -2816, -4864, -7680, -9984, -10240, -9216, -7168, -5120, -2304, 1024, 3072, 5120, 7424, 8192, 7680, 8192, 8192, 5888, 3072, 768, -2048, -4608, -6912, -9984, -11264, -10240, -8192, -6400, -3840, 256, 3328, 5632, 7680, 9472, 9728, 9216, 8704, 6656, 3584, 512, -2816, -5632, -7936, -10240, -11520, -10752, -8960, -6656, -3584, 0, 3072, 4864, 6656, 8960, 9984, 9216, 8448, 7168, 4608, 1536, -1792, -4608, -7168, -9472, -11008, -11008, -9472, -7680, -4864, -1536, 2048, 5120, 6400, 8704, 10752, 10496, 9472, 8192, 5632, 2048, -1792, -4864, -8192, -10240, -11264, -11264, -9728, -7680, -5120, -1536, 2048, 4864, 6144, 7680, 10240, 10496, 9216, 7424, 5888, 3328, -768, -4096, -7168, -9984, -11008, -11264, -10496, -8704, -5888, -2816, 512, 4096, 6400, 8192, 10496, 11776, 10752, 8704, 6656, 3840, 0, -4096, -7424, -10240, -11520, -11520, -10240, -8192, -6144, -3072, -512, 3072, 5632, 6656, 9472, 11520, 11264, 8704, 6144, 4608, 1536, -3072, -6144, -9472, -10496, -10240, -10240, -9216, -7680, -4352, -1024, 2304, 4608, 6400, 9472, 11520, 11520, 10240, 7424, 4864, 2048, -2048, -5632, -9728, -11008, -10752, -10752, -8960, -7168, -4352, -1024, 1792, 4352, 5888, 8448, 11008, 11008, 9728, 7168, 4864, 3072, -768, -4864, -8704, -10240, -9728, -10240, -9728, -7936, -5632, -2048, 1280, 3584, 5376, 7936, 11264, 12032, 10496, 7936, 5120, 3328, 768, -3840, -8448, -11520, -11520, -10496, -9728, -7936, -6144, -2560, 1024, 3840, 5376, 7424, 10752, 12032, 10496, 8448, 5632, 3328, 1024, -3328, -7424, -10240, -10496, -10496, -10496, -9216, -6656, -3584, -512, 2048, 4352, 7424, 10752, 12800, 11776, 9472, 6912, 4352, 1792, -2304, -6912, -10496, -12288, -11520, -10752, -9728, -7424, -3840, -512, 2560, 4608, 6656, 9728, 12800, 13056, 10240, 7168, 4352, 1536, -1792, -6144, -9216, -11008, -11520, -10496, -9728, -7936, -4608, -2048, 512, 3328, 6656, 9728, 11264, 12544, 10752, 8448, 5632, 2048, -1024, -5120, -8192, -10496, -11776, -11264, -9472, -8192, -5376, -2048, 512, 3584, 6400, 8960, 10752, 12032, 11264, 7936, 4864, 1792, -1024, -3840, -7168, -9216, -10752, -10240, -8704, -7936, -6144, -2304, 0, 1792, 4608, 7680, 10240, 11264, 10752, 8192, 5632, 3072, 512, -2560, -5888, -7936, -9728, -10752, -9728, -7936, -6656, -3328, -768, 512, 3584, 7424, 10240, 10496, 10240, 9216, 6656, 3328, 256, -2560, -4864, -6656, -8960, -11008, -10496, -8448, -6912, -4352, -1536, 256, 3072, 6912, 11008, 12032, 10752, 9472, 7424, 3584, 0, -2560, -5376, -7424, -8704, -10240, -10752, -8448, -6656, -4608, -1280, 768, 2560, 5888, 9984, 11520, 9984, 8448, 7680, 4608, 768, -2048, -3840, -5632, -7424, -9472, -11008, -9216, -6912, -5632, -3328, -1024, 1536, 4864, 9216, 12032, 12032, 9472, 8448, 6400, 1536, -2048, -3840, -6400, -7936, -9216, -11008, -10752, -8192, -5376, -2816, 0, 1280, 3840, 8192, 11776, 11520, 8960, 7936, 7168, 3072, -1536, -3328, -5120, -6144, -7936, -10496, -11776, -9728, -6656, -4608, -2304, 256, 3584, 7936, 11008, 12288, 10752, 8448, 7168, 3840, -1280, -3840, -4608, -6144, -7936, -9728, -10496, -8704, -6656, -4864, -2048, 256, 2560, 5888, 9472, 11008, 10496, 8192, 6656, 4864, 768, -3072, -3840, -4608, -6144, -8704, -10752, -9728, -7168, -5120, -3328, -1024, 1536, 5376, 9472, 11264, 11008, 9216, 7168, 5376, 2048, -2304, -4096, -4864, -6400, -8704, -10752, -9984, -7424, -5376, -3328, -768, 2048, 4864, 8704, 10752, 10496, 9216, 7168, 5120, 2048, -1792, -3840, -4096, -4864, -7680, -10496, -10752, -7936, -5888, -3840, -2048, 768, 4864, 9216, 11008, 9984, 9216, 7680, 5888, 3328, -1536, -4864, -5376, -5120, -6656, -9728, -11008, -8960, -6400, -3840, -1792, 768, 3584, 7680, 10752, 10240, 8960, 7168, 5888, 4096, 0, -3584, -5120, -4864, -5632, -8704, -10752, -9472, -6656, -3840, -2048, 0, 3072, 6912, 10240, 10496, 8960, 7424, 5632, 4096, 1024, -2304, -4864, -5120, -5120, -7424, -9984, -9984, -7680, -4864, -2560, -768, 2560, 6144, 9472, 10752, 9472, 7936, 6400, 4608, 1792, -1792, -4352, -5376, -5120, -7168, -9728, -10240, -8448, -5632, -2816, -1280, 2304, 6400, 9472, 11264, 10240, 8192, 6144, 4352, 2560, -1280, -4608, -6144, -5888, -7168, -8960, -9728, -8960, -6656, -3584, -1280, 1280, 4864, 8704, 11264, 10752, 8448, 5888, 4608, 3328, 0, -3840, -5120, -5632, -6656, -8448, -9984, -8960, -7168, -4608, -2560, 256, 4608, 8448, 11008, 11520, 9728, 7168, 5120, 2816, 512, -3072, -5632, -6144, -7168, -7936, -9216, -8960, -7424, -5376, -2816, 0, 3840, 7680, 10240, 11264, 9984, 7936, 5376, 3328, 2048, -1280, -4352, -5120, -6400, -7168, -8192, -9216, -8704, -6912, -4608, -1792, 2304, 6656, 9984, 11776, 11520, 9216, 6400, 3584, 2560, -512, -4096, -6144, -7424, -7936, -7936, -9216, -9216, -6912, -4096, -1792, 1536, 5888, 9472, 11520, 11264, 9216, 6656, 3584, 2048, 256, -3584, -5632, -5888, -7424, -8192, -8960, -9216, -7424, -5376, -3584, 0, 4096, 8960, 11776, 11520, 9984, 8448, 5120, 2048, 768, -2304, -5376, -7168, -8192, -8704, -8960, -9216, -8192, -6400, -3840, 256, 4352, 8192, 11520, 12544, 11264, 8960, 5888, 1792, 0, -1792, -4352, -6400, -7680, -7936, -8192, -8704, -7936, -6400, -4608, -1792, 2560, 6912, 11008, 12800, 11520, 8960, 6144, 3328, 768, -1792, -4352, -6144, -7168, -7680, -7680, -8448, -8704, -6656, -4864, -2816, 1280, 5632, 9984, 12800, 12288, 9472, 6656, 4096, 1280, -1792, -4608, -5888, -6912, -7168, -7168, -8448, -8704, -6144, -4096, -2816, 512, 4352, 8448, 12288, 12288, 9472, 6912, 4608, 1792, -1280, -3584, -5120, -6400, -7680, -7936, -8192, -9472, -7936, -5120, -3840, -768, 3840, 7680, 11776, 13568, 11008, 7936, 5120, 2816, 0, -3072, -5376, -6912, -7936, -7680, -7680, -9216, -8448, -5120, -2560, -1280, 2304, 6400, 10496, 13312, 11776, 8704, 5888, 3840, 1536, -2304, -5376, -6912, -7680, -7936, -7936, -9472, -9984, -6400, -3072, -1792, 256, 4608, 9216, 13312, 13568, 10240, 7168, 5632, 3328, -512, -4608, -7424, -8192, -8960, -8704, -9984, -10240, -7168, -3328, -1792, -512, 3072, 8448, 12800, 14336, 11264, 7680, 6144, 4608, 1024, -3840, -7424, -8192, -8448, -8448, -8960, -10240, -8960, -5120, -1792, -512, 2048, 6400, 11008, 13824, 12544, 8960, 6400, 4608, 2048, -1792, -5888, -8192, -8192, -8704, -8704, -9472, -9216, -6144, -2816, -1280, 512, 4608, 9216, 13056, 13056, 9984, 7680, 6144, 3584, 0, -4864, -8192, -8960, -8960, -9472, -9728, -9984, -7424, -3072, -512, 768, 3584, 7424, 12032, 13824, 11520, 8448, 6656, 4352, 1280, -3072, -7936, -9472, -9216, -9728, -9728, -9728, -8192, -4352, -768, 768, 2304, 6400, 10752, 13568, 12544, 9984, 7936, 5888, 2560, -2304, -6912, -9728, -10240, -10496, -10496, -10496, -9216, -5888, -1280, 1280, 2048, 4608, 9216, 13056, 13056, 11008, 8704, 6656, 4096, 256, -5120, -9216, -10240, -10496, -10752, -10240, -9728, -7168, -2560, 1024, 1792, 3584, 7680, 12288, 13056, 11520, 9984, 7936, 5376, 1024, -4096, -8448, -10496, -11008, -11008, -9984, -9728, -8192, -3840, 256, 1792, 3328, 6400, 10752, 13312, 12288, 9984, 7936, 5632, 2304, -2560, -7424, -10240, -10240, -10240, -9728, -8960, -8704, -5120, -512, 1280, 2304, 4352, 8448, 12544, 12800, 11008, 8704, 6400, 3328, -1024, -5376, -9216, -11264, -11264, -10240, -8960, -8704, -6656, -2048, 1280, 2816, 4352, 6656, 11008, 13056, 11776, 9216, 6912, 4096, 256, -4096, -7936, -10752, -11776, -11008, -9472, -8960, -7424, -3072, 768, 2816, 4352, 5888, 9472, 12800, 13312, 10496, 7424, 5120, 1024, -3840, -7680, -11008, -12544, -11776, -9984, -9472, -8448, -3840, 768, 3328, 4864, 5888, 8960, 13312, 14080, 11264, 7424, 5120, 2048, -3072, -7168, -10240, -12288, -11520, -9984, -8960, -8192, -5120, -512, 3072, 4096, 4864, 7168, 11520, 14080, 12544, 8960, 6144, 3584, -768, -5120, -9216, -12544, -13568, -11520, -9728, -8960, -6912, -2304, 2048, 4864, 5888, 6656, 10240, 14080, 14080, 10496, 6400, 3840, -512, -4864, -8448, -11776, -13568, -12032, -9984, -8960, -7424, -3584, 1536, 4864, 6144, 6400, 8960, 13568, 15104, 12032, 7424, 4352, 1792, -3072, -7680, -12032, -14848, -14336, -12032, -9984, -8960, -5632, -512, 4352, 7168, 7680, 8704, 12800, 16128, 14336, 8960, 4864, 2048, -2304, -6656, -11008, -14336, -14848, -12544, -10752, -9728, -6912, -2304, 3072, 6656, 8448, 8704, 11264, 15360, 15872, 11264, 5888, 2304, -1024, -5120, -10240, -14336, -16128, -14336, -11264, -9984, -7680, -3584, 2048, 6656, 8960, 8960, 11008, 15360, 16384, 12800, 7168, 3328, 512, -4096, -9472, -13568, -15872, -15616, -12800, -10752, -8192, -4352, 512, 4608, 8192, 10240, 11264, 13824, 16128, 14080, 9472, 4352, 1024, -2560, -7936, -12288, -15616, -17152, -15104, -11520, -9216, -6144, -1280, 4352, 8448, 11008, 12032, 13824, 16384, 15104, 10752, 5120, 768, -2560, -7168, -12544, -16128, -17408, -16128, -12800, -9472, -6400, -1792, 3328, 7936, 11264, 12288, 13824, 15616, 15104, 12288, 6912, 1536, -2560, -6144, -11008, -15104, -17152, -17152, -14336, -9984, -7168, -3328, 2048, 6144, 10752, 13056, 13824, 14848, 14848, 13312, 9472, 3584, -1536, -5120, -9728, -13824, -16640, -17920, -16128, -11520, -7424, -4352, 512, 4608, 9472, 13312, 14336, 14848, 14336, 13056, 10752, 5888, -512, -4864, -8704, -12800, -15872, -17920, -17664, -13312, -7680, -4352, -768, 3840, 8448, 12800, 14848, 14848, 14336, 13312, 11776, 7424, 768, -3840, -7936, -11520, -14848, -17408, -18176, -15360, -9728, -5120, -1280, 2816, 6400, 10752, 14848, 15872, 14848, 13056, 11264, 9216, 3840, -2560, -7424, -11008, -13568, -16384, -18432, -17152, -11520, -5376, -2048, 1024, 5120, 10240, 15360, 16640, 14592, 13568, 12288, 10752, 5376, -2048, -6912, -10240, -12800, -15872, -18176, -18176, -13824, -7424, -2304, 768, 4608, 8704, 13824, 17408, 16640, 14592, 12288, 10240, 7168, 512, -5888, -10496, -13312, -15360, -18176, -19200, -15360, -8704, -3072, 0, 3328, 7936, 13312, 17664, 16896, 14336, 12800, 11264, 8448, 1792, -5376, -9728, -12032, -14080, -16640, -19200, -17152, -10496, -3840, 512, 2816, 5888, 10496, 15616, 17408, 15104, 12544, 10240, 8704, 4352, -2816, -8960, -12032, -12288, -14080, -17664, -18432, -12800, -5376, 0, 2048, 3840, 8448, 14336, 17664, 15872, 13312, 11264, 10240, 6656, -1024, -7680, -11264, -12288, -14336, -17664, -19712, -15104, -7168, -1792, 1792, 3840, 7680, 13312, 17408, 16896, 14080, 11520, 9728, 7680, 1536, -6144, -11008, -12544, -13312, -16384, -19200, -16640, -8960, -2560, 1024, 2816, 6400, 11520, 16640, 17152, 14080, 12288, 11008, 8704, 3328, -4608, -9984, -11520, -12544, -15616, -19200, -18432, -11520, -4352, -512, 2304, 5120, 9984, 15616, 17920, 15872, 13312, 11520, 9216, 4608, -2304, -8704, -12032, -13312, -14848, -17664, -18432, -13312, -5888, -1280, 1792, 4352, 8960, 13824, 16640, 16128, 14080, 11520, 9472, 5888, 0, -6912, -11520, -12544, -13568, -16128, -18176, -15104, -7936, -2048, 1792, 3840, 7168, 12032, 15616, 16640, 14848, 12032, 9728, 6912, 1536, -5376, -10496, -12544, -13568, -15872, -17664, -15872, -9984, -3584, 768, 3584, 7168, 11776, 15104, 16384, 15872, 13056, 9984, 7424, 2816, -4096, -10240, -13312, -14080, -14848, -16640, -16640, -12032, -5120, 256, 3584, 6144, 9984, 13312, 15104, 16384, 14336, 11008, 8448, 4096, -2048, -8192, -12544, -14080, -14848, -16128, -16640, -13824, -7424, -768, 3072, 5376, 9216, 13056, 15360, 16640, 15104, 11776, 8960, 5376, -1024, -7168, -12288, -14336, -14592, -15104, -15360, -14080, -9472, -3072, 2304, 4864, 8192, 11776, 13824, 14848, 14848, 12288, 9216, 6656, 1792, -4608, -10496, -13568, -13568, -13312, -14592, -14848, -11520, -4864, 1536, 3840, 6656, 10752, 13824, 15104, 15104, 13312, 9984, 7168, 2560, -4096, -10240, -14336, -14336, -13312, -13056, -13568, -11520, -5632, 1024, 4352, 6144, 8960, 11776, 14336, 14592, 13312, 10240, 7680, 4608, -1792, -8448, -13824, -14848, -13312, -12544, -13568, -13056, -8448, -1280, 4352, 6656, 8704, 11008, 13824, 14848, 13568, 10752, 7936, 4864, 0, -6144, -12032, -15360, -14080, -11776, -11776, -12800, -9984, -3328, 3328, 6400, 8192, 9728, 12288, 14336, 13312, 10496, 7680, 5120, 1792, -3840, -10496, -14848, -14080, -11264, -10496, -11264, -10240, -4864, 2560, 6400, 7168, 8192, 10496, 13568, 13312, 10752, 7936, 5376, 3328, -1280, -8192, -14080, -15360, -12032, -9216, -9728, -10240, -6656, 512, 6144, 7424, 7168, 8192, 11776, 12288, 10240, 7424, 5376, 3584, 256, -5888, -12288, -14336, -11776, -8704, -8448, -9216, -7424, -1792, 5120, 7168, 6400, 6656, 9472, 11776, 10752, 7680, 4864, 3840, 1792, -3328, -9984, -14848, -13824, -9472, -6912, -6912, -7424, -4352, 3328, 7424, 7168, 6144, 7936, 10752, 10752, 8704, 5376, 2816, 1280, -2560, -8192, -13056, -13312, -10240, -7168, -6144, -6144, -4608, 1536, 6912, 7680, 6656, 7168, 9216, 9728, 8448, 5632, 2816, 1536, -1792, -6656, -11264, -12544, -10752, -7680, -5376, -4352, -4096, -1280, 4608, 7424, 6656, 6400, 7424, 8448, 8448, 6400, 3328, 1792, 0, -4608, -9216, -11776, -11520, -7936, -5120, -4096, -4096, -2304, 3072, 7168, 7424, 6144, 6400, 7424, 7936, 6656, 3328, 512, -1280, -3840, -6656, -9984, -11776, -9472, -4864, -2304, -2304, -2816, 256, 5376, 7936, 6656, 5376, 5888, 6656, 6400, 3840, 1024, -1024, -2560, -5120, -8192, -10496, -9728, -5632, -2560, -1792, -2304, -1536, 2816, 6656, 7424, 5632, 5120, 5376, 6144, 4864, 1792, -1536, -3072, -4352, -5888, -7680, -9216, -6912, -3072, -768, 0, -1280, 768, 4608, 7168, 6400, 4608, 3840, 4096, 3840, 1792, -1024, -2560, -3584, -4864, -6144, -7680, -6656, -3328, -768, 512, -768, -512, 3072, 5888, 6656, 4608, 3328, 3328, 3584, 2304, 0, -2816, -3584, -3840, -4608, -6144, -6656, -4096, -1024, 1024, 0, -1280, 1536, 4352, 6400, 5376, 2816, 1792, 2048, 2048, 256, -2816, -3584, -2816, -2560, -3328, -5120, -4608, -1792, 1280, 1792, -768, -512, 2048, 5376, 5888, 3072, 1024, 1024, 2048, 1792, -1280, -3840, -3584, -2816, -2304, -3840, -5120, -3328, 256, 2048, 768, 0, 1536, 4352, 6144, 4096, 768, -512, 256, 0, -2560, -4352, -3584, -2048, -1024, -1280, -2816, -3072, 0, 2304, 1536, -768, 256, 2560, 4608, 4096, 1280, -768, 0, 768, -1024, -3328, -3840, -2560, -1536, -1024, -2048, -3328, -2048, 1280, 2048, 1280, 768, 2304, 4352, 4608, 3328, 0, -1792, -1280, -1280, -2816, -3584, -2816, -1536, 512, 512, -1536, -2304, 256, 2048, 1280, -512, 256, 2048, 3584, 3072, 512, -1536, -1280, -512, -1536, -3072, -2560, -512, 768, 1024, -1280, -2816, -1536, 1280, 1536, 0, 0, 1792, 3072, 3584, 1536, -1792, -2048, -1536, -1536, -2304, -2560, -1280, 1024, 2048, 1024, -1792, -2816, -512, 1536, 768, -512, 512, 2304, 3840, 3072, -512, -2048, -1536, -768, -1280, -2816, -2304, 512, 2560, 1792, -1280, -3840, -2560, 1024, 1536, -512, -512, 2048, 3584, 3584, 768, -2304, -2048, -1280, -1024, -2048, -2560, 0, 2048, 2304, 768, -2304, -3072, -768, 1536, 768, -768, 256, 2048, 3328, 1280, -2304, -3328, -1792, -512, -512, -1536, -512, 2304, 3328, 1536, -1536, -3328, -2560, 512, 1024, -768, -512, 1792, 3328, 2304, -1536, -3072, -2816, -1536, 0, -1280, -1280, 1792, 3840, 3328, 256, -2560, -3328, -1024, 1280, -512, -1792, -512, 2304, 2304, -768, -2816, -2816, -2048, 512, 256, -768, 1792, 3840, 3072, 1024, -1792, -3328, -2816, -512, 256, -1024, -768, 1792, 2816, 768, -2048, -2816, -2560, 0, 256, -1280, 512, 3072, 4352, 2816, -512, -2816, -2816, -768, 1024, -1024, -2304, 256, 2560, 768, -2304, -2816, -2048, 0, 1280, 256, 512, 2816, 3584, 2304, 256, -2816, -3840, -2816, -768, 256, -768, 768, 3072, 2816, 256, -1792, -2304, -1536, -768, -1280, -1280, 1280, 3072, 2304, 1024, -768, -2048, -2048, -1280, 0, -1024, -768, 1280, 1536, -768, -2560, -1792, -768, 0, 512, 768, 2560, 3584, 2816, 1024, -768, -2816, -3840, -3840, -2304, -1280, -1280, 1280, 3328, 1280, -512, 0, 512, 1024, 256, -768, 1024, 3072, 2816, 512, -1280, -2560, -3328, -3328, -2816, -1536, -1024, 768, 3328, 2304, 256, -512, 1024, 1280, 256, -1280, 768, 3072, 3328, 1024, -2304, -3072, -3584, -4096, -4352, -3072, -1280, 1280, 4096, 4352, 1536, 768, 2304, 2304, 512, -2048, -1792, 512, 1792, 1024, -2048, -3072, -2560, -3328, -3584, -3328, -1536, 1024, 3328, 4864, 2560, 0, 1536, 3584, 2048, -1536, -2304, 0, 1792, 1280, -2048, -4352, -3328, -2304, -3584, -4608, -3328, 512, 3840, 5888, 4096, 1024, 1280, 4096, 3840, 0, -2560, -1536, 768, 1536, -1024, -3840, -3840, -2560, -2816, -4096, -4096, -1280, 2560, 5376, 4608, 1792, 512, 3072, 4608, 1536, -1792, -2304, 256, 1792, 256, -3584, -4864, -3840, -3328, -4096, -4608, -2048, 1792, 4864, 6144, 4096, 1280, 2048, 4096, 2304, -1024, -2304, -1280, 768, 1024, -2304, -4864, -4608, -3328, -3072, -4352, -3072, 512, 4096, 5632, 4352, 1536, 1024, 3584, 3328, 256, -2048, -1536, 512, 1536, -1280, -4608, -5120, -4096, -3584, -4608, -4352, -1280, 3072, 5888, 6144, 3584, 2304, 3840, 4864, 2304, -1280, -2048, -768, 512, -1536, -4352, -5888, -4864, -3584, -4096, -4352, -2048, 1792, 4864, 6144, 4864, 2560, 2816, 4352, 3328, 768, -1280, -768, -512, -1024, -3584, -6144, -6400, -5120, -4608, -4096, -2560, 768, 4096, 6656, 7168, 4608, 2816, 3840, 4352, 2304, -1024, -1792, -1536, -1536, -3072, -6144, -7424, -5632, -4096, -3840, -2560, 0, 3328, 6144, 6912, 5632, 3584, 3328, 4096, 3328, 512, -1536, -1792, -2304, -3072, -5376, -7424, -6912, -5376, -3840, -2560, -768, 2048, 5376, 7424, 6656, 4352, 3328, 4352, 4864, 2304, -1280, -2560, -2304, -3072, -5376, -7680, -7424, -5632, -3584, -2560, -1024, 1792, 4352, 6656, 5888, 4352, 3328, 3072, 4608, 4096, 1280, -1536, -2560, -2816, -4864, -7424, -8192, -6912, -4608, -2560, -1024, 1024, 3328, 6400, 6656, 5376, 4096, 2816, 4096, 4352, 2048, -1280, -3072, -3072, -4096, -6400, -7680, -6912, -4864, -2560, -1536, 0, 2560, 5376, 6144, 4608, 3840, 3328, 4096, 5120, 3584, 256, -2560, -3072, -3840, -6656, -7936, -7424, -5632, -3072, -1280, 0, 2048, 4864, 6400, 5632, 4352, 3584, 3584, 4864, 4352, 1024, -2560, -3840, -3840, -5632, -7680, -7680, -6656, -4096, -1536, 256, 1792, 3840, 5888, 5888, 4608, 4352, 4352, 4352, 4352, 2048, -1536, -3840, -4608, -6144, -7936, -7424, -6656, -4864, -2048, 512, 1792, 3840, 5888, 6144, 5376, 4352, 3840, 3840, 4352, 3328, -1024, -4096, -5120, -5888, -7680, -8192, -6912, -4864, -2048, 768, 1792, 3584, 5888, 6144, 5120, 4096, 4096, 3840, 3584, 2560, 0, -3072, -5120, -6144, -7936, -8192, -6400, -4864, -2560, 0, 2304, 3584, 5632, 6912, 5888, 4352, 4352, 4608, 3072, 2048, 256, -3072, -4608, -5888, -7936, -8704, -6656, -4352, -2304, -512, 1536, 3584, 5632, 6912, 5632, 4096, 3840, 4608, 4352, 2560, 768, -2304, -4352, -5376, -7936, -9728, -8192, -5888, -3328, -1280, 1024, 3584, 5376, 7680, 7680, 5376, 4352, 4608, 4352, 2560, 768, -2048, -5120, -5888, -7424, -9728, -8704, -6400, -3072, 0, 768, 2816, 4352, 6656, 7936, 5888, 3840, 3328, 4096, 3584, 1280, -1024, -3840, -4864, -5888, -8960, -9728, -8192, -4864, -1792, -1280, 1536, 4096, 6400, 9216, 8192, 5632, 4864, 4864, 3840, 768, -1792, -4096, -5888, -6656, -8960, -10752, -8704, -4864, -768, 256, 1536, 4608, 6656, 9472, 8704, 5120, 3840, 3584, 3584, 1280, -1792, -3840, -5376, -5888, -7168, -9984, -9472, -5632, -1280, 256, 768, 3840, 6400, 8960, 10240, 6912, 3584, 3584, 3584, 1536, -1792, -3584, -5120, -6400, -6912, -9216, -10496, -7168, -2048, 512, 1024, 3584, 6144, 8448, 10240, 8192, 4352, 3328, 3072, 1280, -1792, -3584, -4352, -6144, -7168, -8704, -10240, -8192, -3584, 256, 1024, 3328, 6656, 8448, 10496, 10240, 6656, 3840, 3072, 1024, -2304, -4352, -5120, -6400, -7936, -8704, -10496, -9728, -5120, 0, 1792, 3072, 6144, 8192, 10240, 10496, 7680, 4352, 2816, 1024, -2560, -4608, -4864, -5376, -6912, -7936, -8960, -9216, -6144, -1280, 1280, 2304, 5376, 7936, 9472, 10496, 9216, 5376, 2816, 1024, -2048, -3840, -4608, -5376, -6656, -7936, -8704, -9472, -7680, -3072, 768, 2304, 4608, 7680, 9728, 11264, 10752, 7424, 3840, 1792, -1536, -4608, -5888, -6144, -6400, -7936, -8704, -9216, -8448, -3840, 768, 2304, 4352, 7168, 9728, 11264, 10752, 8704, 5120, 2048, -1280, -4608, -5888, -5632, -6144, -7680, -8960, -8960, -8960, -6144, -1536, 1536, 3584, 6400, 9216, 10752, 11520, 10752, 7168, 3328, 256, -3840, -6656, -6912, -6656, -7424, -8960, -9984, -9728, -7168, -2560, 1280, 3328, 5376, 9216, 12032, 12288, 11520, 9216, 5376, 1536, -2816, -6400, -7936, -7680, -7424, -8960, -10496, -10496, -8704, -4608, 256, 3840, 6144, 8960, 12032, 13312, 13056, 10752, 6656, 2048, -2304, -6400, -8192, -8704, -8192, -8704, -10240, -10496, -8960, -5632, -1280, 2816, 5376, 7680, 11264, 13312, 13056, 11520, 8192, 3840, -768, -4864, -7168, -8448, -8704, -9216, -10752, -11264, -10496, -7680, -3328, 1536, 5120, 7424, 11008, 13824, 14336, 12800, 9472, 5632, 1024, -4352, -7936, -9984, -9984, -9728, -10240, -11264, -10496, -7936, -3584, 1024, 4608, 6656, 9472, 13312, 14592, 13824, 11264, 7424, 2816, -2304, -6656, -9728, -10752, -10240, -10496, -11520, -11776, -9984, -6144, -512, 4352, 6400, 8960, 12544, 15104, 15104, 13312, 9216, 4864, -512, -5632, -9728, -11776, -11520, -11008, -11264, -12032, -10496, -7168, -1792, 3072, 5632, 8192, 11520, 14848, 15360, 13312, 10240, 6656, 2304, -3584, -9216, -11776, -12032, -11264, -11264, -12800, -12032, -8704, -3584, 2048, 5376, 7680, 10752, 14848, 16640, 14848, 11776, 8192, 3584, -1792, -7680, -12032, -13056, -12800, -11520, -12800, -13056, -9728, -5120, 1024, 4864, 7168, 9728, 13568, 17152, 16128, 12800, 10240, 5888, 512, -5632, -11008, -13824, -14080, -12800, -13568, -14592, -12288, -7936, -1536, 4352, 7168, 9984, 13568, 17664, 18432, 15360, 12032, 7424, 1792, -4608, -9984, -13824, -15104, -14336, -13568, -14080, -13312, -9472, -4096, 2560, 6400, 9216, 12288, 16640, 19200, 17408, 13824, 10240, 5120, -1536, -7936, -13312, -15616, -15616, -15104, -16128, -15872, -11776, -6144, 512, 5120, 8448, 12800, 17152, 20224, 19200, 15872, 12544, 7680, 512, -7424, -12800, -16128, -16896, -16640, -16384, -16384, -12800, -7168, -1536, 4608, 8704, 12288, 15872, 18944, 20224, 17920, 13824, 9728, 3584, -4864, -11520, -15872, -17920, -18176, -17152, -17408, -15616, -9984, -3840, 2560, 7168, 11520, 16128, 19712, 20992, 19712, 15872, 12032, 6400, -2304, -10240, -15616, -17920, -18688, -17664, -17920, -16896, -12032, -5888, 512, 5888, 10496, 14592, 18176, 20224, 21248, 18432, 14080, 9472, 1536, -6912, -13056, -17152, -19456, -19968, -19712, -19200, -15360, -8960, -3072, 3328, 9472, 15104, 19200, 20992, 22016, 20736, 16896, 12288, 4352, -5888, -12800, -16896, -19712, -21248, -21248, -19968, -16896, -11008, -4608, 1792, 7936, 13824, 18688, 21248, 22272, 22272, 18944, 14080, 7424, -2560, -10496, -15616, -19456, -21760, -22528, -21504, -18432, -13568, -7168, -768, 5632, 13056, 19200, 21504, 22528, 23552, 22272, 17152, 10240, 0, -9728, -15360, -19712, -22784, -24064, -22784, -19712, -15104, -8704, -1792, 4352, 11264, 18688, 22528, 23040, 23296, 22528, 18944, 12544, 3072, -7424, -14592, -18688, -21504, -23808, -24064, -21504, -17408, -11264, -4352, 2048, 8448, 16384, 21760, 23040, 23552, 23296, 21248, 16128, 7680, -3840, -12800, -18176, -20992, -23552, -24576, -23040, -18944, -13312, -6656, 0, 6144, 14336, 20992, 23552, 23808, 23552, 22784, 18944, 10752, 0, -10496, -17152, -20480, -23808, -25600, -24832, -21248, -15872, -8960, -2048, 4096, 11008, 18944, 23296, 24576, 24576, 23808, 21248, 14336, 4096, -7168, -15616, -20224, -23552, -25344, -25344, -23040, -18176, -11520, -4096, 2304, 9216, 16896, 22528, 25088, 24832, 23808, 22272, 17408, 7936, -4096, -13312, -19200, -22784, -25088, -26368, -25088, -20736, -13824, -5888, 256, 6400, 14336, 21248, 24832, 25088, 23552, 22528, 19456, 11776, 256, -10752, -17408, -20736, -23296, -25344, -24832, -20992, -14848, -7680, -1536, 3840, 11264, 18688, 23296, 24064, 22784, 21760, 19968, 14080, 4096, -7168, -15104, -19712, -22272, -23808, -24320, -21760, -16640, -10240, -4096, 1536, 8448, 15872, 21760, 24064, 23040, 22016, 20736, 16896, 8192, -3840, -13312, -18688, -21504, -23040, -23808, -22272, -17664, -11520, -5632, 0, 5632, 12288, 19200, 22528, 22528, 21760, 20480, 17152, 10752, 1024, -9216, -15872, -19712, -22272, -23040, -21760, -18432, -13312, -7680, -2816, 2816, 9216, 16128, 21248, 22016, 22016, 20992, 18944, 13824, 4352, -6400, -14080, -18432, -20736, -22528, -22272, -19712, -14592, -8704, -4096, 1024, 6656, 13824, 19712, 21504, 21504, 20992, 19200, 14848, 6912, -3072, -11520, -16640, -19456, -21504, -21504, -19456, -15616, -10496, -6144, -1792, 3840, 10496, 17152, 19968, 20736, 20480, 19456, 17152, 10752, 1280, -7680, -13824, -17152, -20224, -21760, -20224, -17152, -12800, -8192, -4096, 1536, 8192, 14848, 18688, 19712, 20736, 19968, 17408, 12544, 4096, -4864, -11520, -16128, -18944, -20480, -19712, -17152, -13568, -8960, -5120, -768, 5120, 11520, 16640, 18432, 19456, 19200, 17408, 14336, 7424, -1536, -8448, -13312, -16640, -19200, -19712, -17920, -14592, -10752, -7168, -3328, 2304, 8704, 14592, 17920, 18688, 19200, 18432, 16128, 10496, 1792, -6144, -11776, -15360, -17920, -19200, -18432, -15104, -11520, -7936, -4608, 0, 6400, 12288, 16128, 17408, 17920, 18176, 16640, 12032, 4352, -3328, -8448, -12544, -15872, -18688, -18688, -15616, -12288, -9472, -6400, -2560, 3584, 9984, 14592, 16384, 17152, 17920, 17664, 13824, 7168, -768, -6912, -11264, -14592, -17408, -18944, -16896, -12800, -9984, -6656, -3328, 1280, 7680, 12800, 15360, 15872, 16384, 16640, 14848, 9728, 2304, -4352, -8960, -11776, -15104, -17664, -17152, -13312, -10240, -7936, -5120, -1536, 4608, 10752, 14080, 14848, 15360, 16640, 15872, 12032, 5120, -2560, -7168, -9984, -13056, -16896, -17920, -14848, -11264, -8704, -5888, -2560, 2816, 8704, 13056, 14592, 14848, 15872, 16128, 13056, 7424, 512, -5376, -8704, -11776, -15360, -17664, -16128, -12544, -9472, -6912, -3840, 768, 6656, 11520, 14080, 14336, 14848, 15872, 14080, 9472, 2816, -3584, -7424, -9984, -13312, -16640, -16896, -13312, -10240, -7680, -4608, -1280, 4352, 9984, 13312, 13824, 14080, 14848, 14592, 11264, 5376, -2048, -6144, -8448, -11520, -15104, -16896, -14592, -11008, -7936, -5120, -2816, 1792, 7680, 12032, 13568, 13056, 13312, 14080, 13056, 8448, 1024, -5120, -7424, -9216, -12544, -16384, -16128, -12800, -9216, -6144, -3584, 0, 5632, 11008, 14080, 13568, 12544, 13312, 13056, 9984, 3072, -4096, -6912, -8448, -11520, -15360, -16896, -13568, -9472, -6400, -4096, -1536, 4096, 10240, 13568, 13568, 12032, 12544, 13056, 11008, 5632, 0, 0, 0, 0, 0, 0, 0, 0, 5632, 0, 0, -512, -512, -512, -512, 0, -512, 0, 0, 256, 512, 768, 1024, 1024, 1024, 1280, 1536, 1792, 1536, 768, 256, 0, -768, -1280, -2816, -4352, -5120, -5120, -4608, -4096, -4352, -4352, -3584, -2560, -2304, -3328, -4608, -4864, -3840, -3328, -3072, -3328, -2048, 256, 3072, 6400, 8192, 10240, 11520, 12800, 12544, 10496, 8192, 6144, 4096, 2304, 256, -3072, -5120, -5888, -6144, -5120, -5120, -4608, -3072, -2816, -3072, -1792, 0, 2560, 4352, 5888, 6400, 6144, 5376, 5632, 5888, 5376, 2560, 256, -1280, -2048, -2816, -4864, -7424, -8448, -8192, -6656, -4864, -4096, -3584, -3072, -2048, -1792, -2816, -4864, -6912, -7424, -6912, -6400, -6400, -6144, -4352, -1024, 3328, 6656, 8704, 11008, 13824, 15104, 14336, 11776, 8448, 5888, 3840, 1280, -2816, -5888, -8192, -8960, -8192, -7680, -6912, -5888, -4096, -2816, -1280, 768, 2816, 5888, 7936, 9216, 8448, 7168, 6912, 6656, 5376, 2816, 256, -2304, -3584, -4608, -5888, -7168, -8960, -8448, -6656, -4608, -3072, -2816, -1792, -1024, -512, 0, -2048, -4864, -7424, -8448, -8192, -7680, -7680, -6400, -4352, -1024, 3328, 6656, 9216, 12032, 14080, 15104, 13568, 11008, 8192, 5888, 3072, 0, -3584, -5888, -7680, -8960, -8960, -8960, -8448, -7168, -4864, -2816, -1536, 768, 2816, 5632, 8448, 9984, 9728, 8704, 7680, 6912, 5120, 2816, 0, -2304, -4352, -5376, -6656, -7936, -8704, -7424, -4864, -2048, -768, 0, -768, 256, 1024, 256, -2816, -6400, -8960, -9472, -9984, -8960, -8192, -6912, -4352, 0, 3840, 7424, 10752, 14080, 16128, 15872, 14080, 12032, 9728, 6912, 3584, -1024, -5120, -7936, -10240, -11264, -11776, -11520, -10496, -8704, -6400, -3584, -768, 2048, 5632, 8192, 11008, 11264, 10240, 9216, 8704, 6656, 4608, 2048, -512, -2816, -5120, -6400, -7424, -8448, -7936, -5376, -2560, -512, -512, -512, 1024, 1536, 2304, 0, -3584, -7168, -8960, -9984, -9728, -9728, -9216, -7680, -4096, 0, 4096, 7424, 10496, 14080, 16640, 17152, 15104, 12544, 9984, 7168, 3328, -768, -4864, -8192, -10752, -12288, -13056, -13568, -12032, -9216, -5632, -3072, 0, 2560, 6144, 9728, 11776, 12288, 11008, 9984, 8192, 6656, 4352, 1536, -1792, -4096, -5376, -6656, -7936, -8704, -7168, -4096, -512, 768, 256, 512, 2048, 4096, 3072, 512, -3840, -6912, -8704, -9472, -10496, -12032, -11264, -8448, -4096, 256, 4096, 7936, 12032, 16640, 19200, 18688, 16128, 13312, 10496, 6912, 2304, -3584, -8704, -12032, -13824, -14080, -14848, -14592, -12800, -8960, -4352, 0, 2048, 5120, 8704, 12032, 13824, 12544, 10752, 9216, 7424, 5376, 2304, -1024, -3584, -5376, -6656, -7680, -8448, -7168, -4608, -1280, 1024, 1536, 1536, 2048, 3328, 4352, 3072, -1024, -5376, -8448, -9984, -11264, -12544, -12800, -11776, -8960, -3840, 1024, 5632, 9216, 14080, 18432, 20736, 19968, 17664, 13824, 10752, 6912, 1536, -4864, -9728, -13312, -14592, -15872, -16640, -16384, -13312, -8960, -4352, -768, 2048, 4864, 8448, 11520, 12800, 12288, 10752, 8960, 7424, 4608, 1792, -1280, -2816, -5120, -6656, -7424, -6912, -5120, -3328, -1024, 768, 2048, 2304, 2816, 3072, 3072, 1280, -2048, -5632, -8448, -10752, -12800, -13568, -13056, -10752, -6912, -2816, 2304, 6912, 11520, 15872, 19200, 19968, 18688, 15360, 12288, 8192, 3584, -2048, -7680, -11776, -13824, -15360, -16384, -15872, -13568, -9984, -5888, -2048, 1280, 4352, 7680, 10496, 11776, 11264, 9728, 7680, 5632, 2816, 1024, -1280, -3072, -5120, -6400, -6656, -6144, -4352, -1792, 768, 2048, 2816, 3072, 3584, 3840, 3584, 2304, -1024, -4352, -8192, -11264, -13824, -14592, -14336, -12288, -9216, -5632, -1280, 4608, 10496, 15616, 18944, 20224, 19200, 17152, 14080, 9984, 5120, -512, -5120, -9472, -12032, -14336, -15872, -16128, -14592, -11264, -7936, -4608, -1280, 1792, 4096, 7168, 8960, 9728, 9472, 8192, 6400, 4096, 2048, 768, -512, -1280, -2816, -4864, -5376, -4096, -1792, 768, 1536, 2048, 1792, 2048, 2560, 2304, 1280, -1024, -3328, -5888, -9472, -12544, -13824, -13824, -12032, -9728, -6400, -2304, 2304, 7680, 12800, 17152, 19712, 19200, 17664, 14848, 10752, 6656, 1792, -3072, -7936, -11776, -13312, -14336, -15104, -14848, -12544, -9216, -4864, -1280, 2048, 3584, 5632, 7168, 8448, 8960, 7680, 5888, 3328, 1024, 768, 768, 0, -2048, -3072, -3328, -2560, -1536, 512, 2048, 2816, 3072, 2816, 2304, 1024, -512, -1280, -3072, -5888, -8960, -11776, -13312, -13824, -12288, -9216, -5632, -2048, 2304, 7168, 11776, 15616, 17920, 18432, 17408, 14848, 11520, 6912, 2304, -2048, -5632, -8960, -11008, -12288, -12288, -11776, -9984, -8448, -5888, -3072, 256, 2048, 2816, 3584, 4096, 4864, 4864, 4352, 2816, 1792, 2048, 2816, 3328, 1792, 1280, 512, 512, 512, 1024, 1536, 1536, 1280, 512, -768, -1280, -2304, -2816, -4352, -5888, -7424, -8704, -10240, -11520, -10496, -8192, -4608, -1280, 1792, 4864, 9216, 13824, 16384, 17152, 15616, 14080, 12288, 9216, 4608, 768, -2816, -5888, -9216, -11520, -11776, -10752, -9984, -8704, -6912, -5120, -2816, 0, 2560, 3328, 3584, 3072, 3328, 3328, 2560, 1792, 1536, 2304, 2816, 2816, 2816, 2560, 2560, 2048, 2304, 2304, 2304, 1536, 256, -1024, -3072, -4096, -5632, -6400, -7168, -7424, -7680, -9984, -11008, -9984, -6656, -2816, 0, 2048, 4864, 8448, 12288, 14848, 16128, 15616, 14336, 12800, 10240, 6400, 2048, -1280, -3840, -6144, -8960, -10496, -10752, -9984, -8192, -7424, -6400, -5376, -3328, -1536, 0, 1024, 512, 512, 768, 1536, 1536, 1792, 2816, 4352, 5120, 5632, 5888, 6144, 5888, 5376, 4352, 3072, 1024, -1280, -3328, -5632, -7424, -9472, -10496, -10240, -9216, -7936, -8192, -8704, -8704, -5632, -1536, 2048, 3584, 5120, 7424, 10496, 12800, 14336, 14336, 12544, 11520, 9984, 7680, 4352, 1280, -2048, -4864, -7168, -8704, -8960, -8192, -6912, -6400, -6400, -5888, -4864, -3072, -1792, -1024, -1536, -2560, -2816, -1792, 0, 1024, 2560, 3584, 4864, 6656, 8192, 8960, 8704, 7936, 6400, 4096, 1536, -1280, -4352, -7424, -9984, -12032, -13056, -12800, -11264, -8960, -7168, -6912, -6400, -4608, -1536, 2560, 4608, 5376, 6400, 7936, 10240, 11776, 12544, 12288, 11264, 10752, 9472, 7424, 4864, 2048, -1280, -3584, -5376, -7424, -7680, -7680, -6912, -7168, -8192, -8448, -7936, -5632, -4352, -3840, -4352, -4864, -4864, -2304, 1280, 4096, 5632, 6400, 7936, 9728, 11264, 12032, 11008, 8704, 5120, 1536, -2304, -5376, -8960, -12544, -15104, -15872, -15360, -13568, -10752, -7680, -5632, -3840, -1536, 1024, 3584, 5888, 6912, 7168, 6912, 7680, 8960, 9728, 9984, 10752, 9728, 8960, 7680, 6400, 5120, 3072, 1024, -1536, -4608, -5888, -5632, -5120, -5632, -7680, -9472, -9984, -8704, -7424, -6912, -6912, -6656, -5888, -4096, -768, 2560, 5376, 7424, 8960, 11008, 11776, 12800, 12544, 10496, 7168, 3840, -512, -4864, -8960, -12800, -15872, -17152, -17152, -15360, -12800, -9216, -5888, -3584, -1536, 768, 2816, 5376, 6912, 6912, 6144, 6400, 6912, 7424, 7936, 9216, 10496, 10752, 9984, 8448, 6912, 5632, 4352, 2048, -768, -2816, -3840, -3840, -4608, -6400, -8960, -10752, -11520, -10752, -10496, -10496, -10240, -9728, -7168, -3072, 1792, 5632, 8704, 11008, 13056, 15104, 15872, 15104, 12544, 9472, 5120, 256, -4864, -9728, -13824, -16640, -18688, -18944, -17664, -14080, -8960, -4864, -2560, -512, 2048, 4608, 5888, 6400, 6400, 5632, 5120, 4864, 5120, 5632, 7680, 9984, 11264, 10752, 9984, 8960, 8192, 7424, 4608, 1024, -2048, -3328, -3840, -4352, -6144, -8448, -11008, -12032, -11264, -10752, -10240, -10240, -9984, -8192, -4352, 768, 4096, 7168, 9984, 12032, 13568, 14336, 14336, 13312, 10240, 6144, 1280, -3072, -7424, -11008, -13824, -16640, -18432, -18176, -14336, -9216, -5120, -3328, -1024, 1280, 3072, 4608, 5376, 5888, 5120, 4608, 3584, 4096, 4864, 6912, 9728, 11520, 11520, 10752, 10496, 10752, 9472, 6912, 3840, 256, -2048, -3072, -3328, -4352, -7680, -10240, -12032, -12288, -12032, -11776, -11776, -11520, -10496, -7168, -2304, 2816, 6656, 9728, 11520, 13056, 14080, 14848, 14080, 12032, 7936, 2560, -3072, -6912, -9984, -12544, -14848, -17152, -17664, -15872, -11776, -6656, -3328, -1024, 512, 1792, 3584, 4608, 5376, 5120, 3840, 2816, 3072, 3584, 5376, 8192, 10240, 11264, 10752, 10752, 10240, 9472, 8448, 5632, 2816, 256, -1792, -2816, -2816, -4864, -7680, -9984, -11008, -11008, -10752, -11008, -11264, -11264, -9216, -5120, 0, 3584, 6400, 8960, 10752, 11776, 12800, 12800, 12288, 9216, 4352, -768, -4608, -7680, -9216, -11008, -13312, -15104, -15360, -12544, -8960, -5120, -3072, -1792, -1024, 512, 2048, 3072, 3072, 2304, 2304, 3072, 4096, 5888, 7424, 9984, 11520, 11776, 11776, 11008, 10496, 9472, 7680, 5120, 1792, -1280, -2560, -2816, -3840, -6400, -9984, -11776, -11520, -11008, -10752, -11520, -11776, -9984, -6656, -2048, 2048, 5120, 7936, 10496, 11520, 12288, 11776, 11264, 9216, 5376, 256, -5120, -7936, -8448, -9216, -11264, -13568, -15104, -13824, -10496, -6656, -4352, -3072, -1536, -768, 1280, 1792, 2304, 2816, 2816, 3072, 3840, 5120, 7424, 9216, 10752, 11776, 11520, 10752, 10240, 9728, 8448, 6400, 3328, 1024, -1792, -2560, -2816, -4352, -7424, -9728, -9728, -8704, -8960, -9984, -10496, -9984, -7936, -4096, -1536, 1024, 3584, 6144, 7680, 8704, 8704, 8960, 8192, 5632, 2048, -2304, -4096, -4096, -4352, -5632, -8448, -11008, -11776, -10496, -8704, -7680, -6400, -4864, -3584, -2304, -1536, -512, 1280, 2304, 3328, 3840, 5376, 7424, 9216, 11008, 12032, 11776, 11776, 10752, 9984, 9472, 7936, 5120, 2560, 0, -1536, -2304, -3584, -5632, -7424, -8448, -7936, -7680, -8704, -9472, -9472, -7680, -5376, -3072, -1280, 256, 2560, 5120, 7168, 7936, 7936, 7168, 5120, 3072, 0, -2048, -2560, -2560, -4096, -6144, -8448, -9984, -11264, -10752, -8960, -7168, -5888, -4608, -3584, -2560, -1024, 1536, 3072, 4096, 4352, 5632, 7424, 8448, 8960, 9728, 10496, 11008, 10496, 9728, 8704, 7680, 6144, 4096, 2304, 768, -1024, -2560, -3840, -5376, -5888, -5888, -5888, -6144, -7168, -8192, -7936, -7168, -5632, -3840, -2560, -1536, 512, 2816, 5120, 5888, 6400, 4864, 3584, 2304, 1280, 768, 512, -512, -2048, -4864, -7168, -9216, -10752, -11264, -9984, -8448, -7168, -6656, -5120, -2816, 0, 2048, 3840, 5632, 7168, 8448, 8960, 9216, 9472, 9728, 10496, 10240, 9728, 8192, 6912, 5376, 4352, 2816, 1024, -768, -2048, -3072, -4352, -4608, -4096, -4096, -3840, -4608, -5632, -6400, -6656, -6400, -5888, -4864, -3840, -2304, -512, 2048, 3328, 4352, 4608, 4352, 4096, 3840, 3328, 2560, 1536, 0, -2304, -5376, -8192, -10752, -12032, -11776, -11008, -9216, -7680, -5632, -3840, -1536, 1024, 3584, 5632, 7168, 8448, 9216, 9472, 9216, 8960, 9472, 9216, 9216, 8192, 6912, 5888, 4096, 2560, 1280, 0, -1792, -2560, -3072, -2816, -2816, -2816, -2560, -2304, -2816, -4096, -5632, -6912, -7680, -7680, -7680, -6400, -4864, -2304, 0, 1792, 3328, 4608, 5888, 6912, 6912, 6656, 5120, 3072, 256, -3328, -6912, -10240, -12800, -13824, -13824, -12544, -10752, -8448, -5376, -2560, 256, 3584, 6144, 7680, 9984, 11264, 11008, 9728, 9216, 9728, 9472, 8704, 7936, 7168, 5632, 3328, 1792, 1280, -512, -1792, -2816, -3584, -3328, -3328, -2048, -1536, -1536, -2560, -3072, -3584, -4864, -6656, -8704, -9728, -8448, -6656, -3840, -1792, 512, 1792, 4352, 6656, 8960, 10240, 9472, 7424, 4864, 1792, -3072, -7936, -11264, -13568, -14336, -15616, -15872, -15104, -11776, -6912, -2304, 1280, 3584, 6400, 9216, 12032, 13568, 13056, 11520, 9472, 8704, 8192, 7424, 6656, 5888, 4608, 3328, 1280, 0, -768, -1024, -1536, -2560, -3072, -3072, -1536, 512, 1536, 512, -1536, -3072, -4352, -5376, -7936, -10496, -12032, -11008, -8192, -5120, -2816, -1024, 2304, 5376, 10240, 12800, 12288, 10752, 8704, 5632, 1280, -4096, -9216, -13568, -14848, -16128, -17664, -18688, -16128, -11008, -4864, -512, 2304, 4864, 8704, 12800, 15360, 15616, 13568, 10752, 9472, 8192, 7680, 6144, 5376, 4096, 2816, 1024, -1024, -1792, -1536, -1280, -1280, -2560, -3584, -2816, -1024, 768, 512, -512, -2048, -3328, -4864, -6656, -9216, -10752, -10240, -8448, -5376, -2304, 256, 2560, 5632, 9216, 12544, 13568, 12032, 9216, 4864, 256, -4608, -9216, -13056, -15360, -16640, -17152, -17152, -16128, -12032, -6144, -1024, 2816, 5120, 8448, 12288, 14592, 14592, 13312, 10752, 8448, 7680, 7168, 6400, 4864, 4096, 3072, 2048, 768, -512, -512, -512, -512, -1280, -2048, -2560, -1280, -512, 0, 0, -1280, -2048, -3840, -5888, -8192, -9984, -9728, -8448, -6144, -3840, -1792, 1280, 4096, 7680, 11520, 13312, 12544, 10240, 5888, 1024, -3584, -7424, -10752, -14080, -16128, -17152, -17152, -15616, -12800, -8960, -4864, 0, 4096, 7936, 11776, 14336, 15104, 14336, 12032, 9728, 8704, 7936, 7168, 5888, 4096, 2560, 1024, 0, -512, -512, 0, -1280, -2304, -3072, -2816, -1792, -768, -768, -1024, -1280, -1024, -1792, -3584, -6656, -8448, -8192, -6912, -5120, -3840, -1792, 512, 3328, 5376, 8704, 10752, 11776, 10240, 6400, 1792, -3328, -6912, -8960, -11264, -13824, -15872, -16384, -15360, -13056, -9984, -6656, -2560, 2048, 6144, 10240, 13056, 14848, 15360, 13824, 11264, 9216, 7424, 6144, 4864, 3328, 2048, 0, -1536, -1280, 0, 256, 0, -1024, -768, -512, 0, 256, -512, -1280, -1280, -1024, -1792, -4352, -6912, -7936, -7424, -6144, -4864, -3840, -2304, -768, 1792, 4608, 6912, 8704, 9984, 9472, 6656, 2304, -2304, -6144, -8192, -9984, -12032, -14080, -15360, -14592, -13056, -10752, -8192, -5120, -1536, 3584, 7936, 12288, 14592, 15360, 14848, 13312, 11520, 8960, 6400, 5376, 4352, 2304, 0, -2048, -2560, -2048, -1792, -1536, -2304, -2304, -1536, -512, 0, -768, -1536, -1536, -512, 256, -1536, -3840, -6400, -6400, -5120, -4352, -3328, -2816, -1792, 256, 2048, 4096, 6144, 7936, 8704, 7424, 4096, -768, -4352, -7168, -8960, -10496, -12032, -13824, -14336, -13824, -11776, -9472, -6912, -3840, 1024, 5888, 10240, 12800, 14848, 15360, 14848, 12800, 10752, 8704, 6656, 4864, 3584, 1024, -1536, -3328, -3328, -3328, -3584, -4096, -3840, -3072, -2304, -1792, -1792, -1024, -1024, 512, 1792, 1280, 0, -2048, -2816, -3328, -3328, -2816, -2560, -2816, -2816, -2304, 0, 2048, 3584, 5632, 6144, 4864, 2304, -768, -3584, -5888, -7424, -8192, -9728, -12032, -13824, -13312, -11264, -8192, -5888, -2304, 2048, 5888, 9984, 13312, 15104, 14848, 13056, 11776, 11008, 8448, 6400, 4096, 2304, 1024, -1024, -2816, -3840, -4096, -4096, -3840, -3584, -3840, -4096, -3328, -1792, -1280, 512, 1280, 1280, 1280, 1536, 768, -1024, -1536, -1024, -1280, -2560, -4096, -4096, -3328, -1536, 1024, 3072, 3840, 4352, 3584, 2560, 1024, -2048, -4352, -5888, -7680, -9728, -11776, -13312, -13056, -10496, -7680, -5120, -2048, 2304, 7424, 12032, 14336, 14592, 14080, 13312, 12800, 11520, 8704, 5120, 2560, 512, -512, -2304, -4096, -5632, -6144, -5632, -5376, -5632, -4864, -3584, -1792, -1024, 256, 1280, 2816, 3840, 5120, 4352, 2304, 768, 768, 0, -1536, -3840, -5376, -5888, -4096, -2304, -768, 1024, 2560, 3328, 3840, 3328, 1024, -2304, -3840, -5120, -6912, -9984, -12288, -13056, -12032, -9728, -7424, -5376, -1792, 4096, 9216, 12288, 13056, 13312, 14080, 15360, 15104, 12544, 8448, 5120, 3072, 1792, -512, -3328, -6144, -7168, -6912, -6656, -7680, -8192, -7424, -5120, -2304, 0, 768, 2048, 4096, 6400, 7168, 5888, 4352, 3072, 1536, -512, -3584, -6656, -7936, -6912, -4608, -2560, -768, 1792, 3840, 5632, 6144, 4608, 2304, 0, -2304, -4864, -8704, -11776, -14592, -14592, -13056, -11264, -9728, -6656, -1280, 5376, 10752, 12288, 13568, 14848, 17152, 19200, 18176, 14592, 9472, 5888, 3072, 768, -3072, -6912, -9984, -11008, -11008, -11520, -12032, -10752, -7168, -3072, 512, 1792, 3072, 5120, 8192, 9728, 9472, 7680, 5376, 3328, 256, -3328, -6656, -8704, -8448, -6656, -4352, -2560, -768, 2304, 5120, 6400, 5632, 3328, 1280, -768, -3328, -7168, -11008, -13568, -14336, -13056, -11776, -10240, -7936, -3584, 2560, 7936, 10496, 12032, 14336, 17152, 19456, 18688, 16128, 11776, 7680, 4864, 2304, -1792, -6400, -9984, -12032, -12800, -13824, -13312, -12800, -9728, -5632, -2304, 1024, 3072, 5632, 7680, 9984, 10496, 9984, 7936, 5632, 3072, -768, -4864, -7680, -8192, -7424, -5888, -4352, -2304, 256, 3072, 5120, 6144, 4608, 2560, 512, -1792, -4864, -8960, -12800, -15104, -15104, -13824, -12544, -11008, -7936, -2304, 3840, 8192, 10496, 13568, 17920, 21760, 22272, 20480, 16384, 12544, 9472, 5888, 512, -5888, -10752, -13312, -15104, -16896, -17664, -17408, -14336, -9728, -4608, -512, 2304, 4864, 7936, 10496, 12544, 13056, 11264, 8960, 5376, 1280, -2304, -5632, -7424, -7680, -6656, -5120, -3584, -1792, 1280, 3840, 4352, 3584, 2304, 512, -1024, -4096, -7424, -11520, -14080, -14336, -12800, -11776, -11264, -9216, -4864, 256, 4864, 8448, 11776, 16128, 20224, 22016, 21504, 18688, 15360, 12032, 8192, 3072, -2560, -7680, -12288, -15104, -17408, -18432, -18688, -16384, -12544, -7680, -3072, 512, 3072, 6656, 8960, 11520, 13056, 13056, 11264, 7680, 3840, 768, -2304, -4352, -5120, -5376, -4864, -4608, -3584, 0, 2560, 4096, 3840, 1792, -1024, -2560, -3584, -6144, -9728, -13056, -14848, -14080, -12800, -11264, -9216, -5888, -1792, 2560, 6656, 10496, 14592, 19456, 22784, 22784, 20736, 17920, 15104, 11520, 6400, 0, -6144, -10496, -14336, -17152, -19200, -20480, -19456, -16128, -11520, -6656, -2304, 1536, 5120, 8192, 11264, 13312, 13824, 13568, 12032, 8960, 4608, 768, -1536, -2816, -3584, -4096, -4864, -4864, -3072, -1024, 1280, 1280, 0, -2048, -3072, -3840, -5376, -8704, -12032, -13056, -11520, -9984, -8704, -7680, -5888, -3072, 1024, 4352, 7936, 11520, 15360, 18432, 19968, 19200, 17664, 15872, 13568, 10240, 4608, -1280, -6144, -9728, -12800, -15872, -18688, -19968, -18944, -15104, -10496, -7168, -4352, -1024, 3584, 8448, 12032, 14080, 14848, 14080, 12288, 9984, 7424, 4096, 1024, -1280, -2816, -4608, -5376, -5120, -3840, -2048, -1792, -2304, -3328, -3840, -4096, -4352, -5888, -8448, -11008, -11264, -10496, -8704, -7168, -5888, -4096, -2048, 1280, 5376, 9216, 12800, 15872, 18688, 19456, 18688, 17408, 15104, 12288, 7680, 2304, -4096, -8960, -12288, -15104, -17920, -19712, -20224, -18432, -13824, -9728, -6144, -2048, 2048, 7424, 11520, 14336, 15616, 15872, 14336, 13056, 9984, 6912, 4096, 1024, -2048, -4096, -5632, -5888, -6400, -4864, -4096, -4352, -4864, -5120, -5376, -4608, -4864, -6400, -8192, -9728, -8704, -6144, -4864, -3840, -3072, -1792, 768, 3840, 7168, 9984, 12288, 14336, 16128, 16128, 16128, 14592, 12032, 8192, 3584, -1280, -5632, -9216, -11776, -14848, -17408, -18688, -18176, -15616, -12032, -8960, -5888, -2304, 2560, 7424, 11008, 13312, 14336, 14336, 14336, 13312, 11520, 8448, 4864, 1536, -1280, -3840, -5632, -6400, -6656, -6656, -7424, -7424, -6656, -6144, -5120, -4864, -5888, -6912, -7680, -6912, -5376, -4608, -3584, -2560, -1792, 0, 2048, 4608, 7680, 10240, 12032, 13312, 13824, 13824, 14080, 12544, 9984, 5632, 1792, -2304, -6144, -9472, -12800, -14848, -16640, -18176, -17152, -15104, -12800, -9984, -5888, -1536, 3840, 8192, 11008, 13056, 14592, 15616, 16384, 15616, 13312, 9472, 5376, 1024, -2816, -5120, -6656, -7680, -8960, -9472, -9984, -8960, -7424, -5632, -4352, -5120, -5632, -5120, -4608, -4352, -4096, -3328, -2048, -768, 512, 1792, 2560, 4352, 6912, 8960, 10752, 11008, 11264, 11520, 11264, 9728, 7168, 4096, 768, -2560, -5632, -8448, -11776, -14592, -16384, -16384, -15104, -13568, -11776, -8704, -4352, 768, 5376, 8192, 10496, 12288, 14080, 15360, 15360, 13824, 11264, 7936, 4608, 768, -2560, -4864, -6912, -7680, -8192, -8704, -8960, -7680, -5888, -4352, -4352, -5120, -5120, -5120, -4352, -3840, -3328, -2816, -2048, 256, 2048, 3072, 4352, 5888, 7680, 9984, 9984, 9472, 9216, 8960, 8704, 6912, 3584, 0, -2560, -3840, -5888, -8704, -11776, -14336, -15360, -14336, -12544, -9984, -8192, -5888, -2048, 2048, 5888, 8192, 9728, 11264, 13824, 14848, 14592, 12288, 9472, 7424, 4352, 1024, -2816, -5376, -7168, -7424, -7936, -8704, -8960, -6912, -5120, -3840, -4096, -4096, -4352, -3328, -2560, -2560, -2816, -2560, -1024, 1280, 2816, 3328, 3840, 5376, 7424, 8448, 8192, 7168, 6400, 6400, 5888, 4096, 1280, -1536, -2560, -4096, -5376, -7680, -10752, -12288, -12288, -11008, -8704, -7424, -5376, -3328, -768, 2816, 5632, 6912, 8704, 9984, 12288, 13568, 12288, 10752, 8192, 5888, 4096, 1024, -1792, -4608, -6144, -6144, -6656, -7168, -6144, -4864, -3584, -3328, -4096, -4608, -4608, -4096, -3584, -3840, -4096, -3840, -1792, 768, 2816, 3584, 5376, 6912, 8448, 9216, 8448, 7680, 6400, 5632, 4352, 2304, -1024, -3840, -5376, -6144, -7936, -9984, -11264, -11264, -9984, -7680, -5888, -4096, -2048, 1024, 3584, 5376, 5888, 6400, 7424, 9472, 11008, 10752, 9216, 7936, 6400, 4608, 2816, 1024, -1792, -2816, -3328, -4096, -5376, -5632, -4608, -3584, -3328, -4096, -4864, -5376, -5376, -4864, -4864, -5120, -4608, -2816, -512, 2048, 3584, 4608, 5888, 7680, 8704, 8960, 7936, 6912, 5376, 3328, 512, -2816, -4352, -5888, -7168, -9216, -9984, -10240, -9472, -7936, -5888, -3584, -2304, 0, 1792, 3328, 3840, 3840, 4096, 5632, 6912, 7680, 7168, 7424, 8192, 7424, 5888, 4096, 2304, 1024, 256, -512, -1792, -3584, -4864, -3584, -2560, -2560, -3584, -4608, -5632, -6144, -5888, -6656, -7168, -6912, -4608, -2048, -768, 512, 2304, 5632, 8448, 10240, 10240, 9216, 7680, 6400, 5120, 2048, -2048, -5632, -7424, -8192, -9984, -12288, -12800, -10752, -7680, -4864, -3328, -2048, 512, 2816, 5632, 6400, 5376, 4352, 3840, 5120, 5888, 5376, 5120, 5120, 4864, 4864, 4096, 2816, 2304, 1792, 1792, 768, 0, -768, -1280, -1280, -1280, -1792, -3072, -5632, -7168, -8192, -8960, -8960, -9216, -7680, -5376, -3072, -1024, 768, 4096, 7424, 9984, 11776, 11520, 10240, 8704, 6656, 3328, -512, -4352, -7168, -9472, -12288, -14592, -15360, -13312, -9216, -4864, -3072, -2048, 512, 4096, 7168, 8448, 7168, 5888, 5376, 5632, 5376, 4864, 4608, 4096, 3584, 3072, 2048, 1536, 1280, 1280, 1792, 1280, 1024, 1280, 1792, 2304, 1792, 768, -1280, -3328, -5632, -7168, -8960, -11264, -12544, -12288, -9728, -6656, -3584, -1792, 1024, 5120, 9728, 12544, 13824, 13568, 12544, 10240, 6656, 2048, -2816, -6144, -8448, -11776, -15616, -17920, -17152, -13312, -7936, -3584, -1280, 1024, 3584, 6912, 9216, 9216, 8448, 7424, 6656, 6400, 5376, 3584, 2560, 1792, 2048, 1536, 1280, 1280, 1536, 2048, 2304, 2560, 3584, 4608, 4352, 3328, 1280, -1024, -3072, -5120, -7168, -9472, -12544, -14336, -14336, -12288, -9216, -6400, -3840, -512, 4096, 9216, 13056, 14080, 14592, 14080, 12288, 9472, 5120, 256, -4352, -7680, -11008, -15360, -18688, -19456, -16128, -11008, -6144, -3584, -1536, 1792, 5888, 9984, 11264, 9728, 8704, 7936, 8192, 7680, 6144, 4096, 2048, 1280, 1536, 1536, 1280, 1280, 1536, 2560, 2560, 3328, 4096, 4864, 4864, 3584, 1280, -1792, -4608, -6400, -8704, -11520, -14080, -15616, -15104, -13056, -9984, -6400, -3072, 1280, 6912, 12288, 14848, 15360, 15616, 14848, 12544, 8192, 3584, -1024, -5120, -9216, -13824, -17664, -20224, -19200, -14592, -8960, -5376, -3840, -1024, 3072, 7168, 9984, 10752, 10496, 9728, 9728, 9728, 8448, 5888, 3328, 2048, 2304, 2816, 2304, 1280, 768, 1536, 2560, 3328, 3584, 3840, 4352, 4096, 2304, -1536, -4096, -5376, -6912, -10240, -14336, -16640, -17152, -14592, -11520, -8448, -5888, -1280, 5376, 11264, 15360, 16896, 17152, 16640, 15616, 12032, 6400, 512, -4096, -8704, -13568, -18432, -21248, -20992, -17920, -13056, -8448, -5120, -2048, 2048, 6400, 9984, 11776, 11008, 11008, 11008, 11008, 9728, 6912, 4352, 2304, 2048, 2560, 2816, 2304, 1280, 1280, 2048, 3328, 3584, 4608, 5120, 4608, 3072, -512, -3328, -4864, -6400, -8704, -12288, -15872, -17664, -17152, -14848, -11776, -8192, -3584, 2304, 7680, 12288, 15360, 17664, 18432, 17664, 14592, 9216, 3328, -1536, -6912, -12032, -16896, -20224, -21248, -19712, -16384, -11776, -7424, -3328, 1024, 4352, 7680, 9984, 10496, 11776, 12288, 11520, 10240, 7936, 5120, 3072, 2560, 3328, 3584, 3072, 2816, 2560, 2560, 3840, 4352, 5120, 5120, 4352, 3072, 0, -3584, -6144, -7680, -9472, -12032, -15360, -17664, -17408, -15872, -13056, -9216, -4608, 1280, 6400, 11520, 14848, 16640, 17408, 17152, 15104, 10752, 5120, -512, -5632, -10752, -15616, -19200, -20736, -19712, -16896, -13056, -8960, -5120, -1024, 3584, 7168, 9472, 9728, 9728, 10752, 12032, 11008, 8960, 6144, 4352, 3584, 3584, 4352, 5120, 5120, 4352, 3328, 3584, 4352, 4608, 4608, 4352, 2816, -512, -3840, -6144, -7936, -9728, -11776, -13312, -14848, -15872, -15616, -13312, -9728, -5632, -1024, 4096, 8960, 12288, 14080, 15360, 15872, 14592, 11776, 6656, 1536, -4352, -8960, -13568, -17408, -19456, -19200, -16896, -13056, -9728, -5888, -1792, 2560, 6400, 8960, 9728, 9472, 9984, 10240, 9984, 7680, 5376, 4096, 3840, 3840, 4096, 5120, 6144, 6656, 6912, 6912, 6656, 6144, 5376, 4864, 2816, -768, -4096, -7424, -10240, -11264, -12800, -13824, -14592, -14848, -14080, -12288, -9216, -5376, -1280, 3328, 7424, 10496, 12288, 13312, 13568, 12800, 10496, 6656, 1792, -3584, -8448, -12544, -15872, -17920, -17664, -15616, -12288, -9216, -5376, -1280, 4096, 7680, 8960, 8960, 8960, 8192, 7936, 7424, 6144, 4352, 3328, 3328, 3584, 3840, 4608, 6656, 8704, 9984, 9472, 8192, 7424, 6656, 5632, 3328, 256, -3840, -7424, -10240, -11776, -13056, -13824, -14080, -13312, -11776, -10240, -8192, -5632, -2560, 1280, 4864, 7168, 8448, 8960, 9472, 9728, 8448, 5376, 2048, -1792, -5120, -8960, -12800, -14592, -14592, -12544, -9472, -7168, -5376, -2048, 2560, 6400, 8192, 8192, 7936, 6912, 6144, 5632, 5120, 3840, 3328, 3328, 3840, 3840, 4864, 6656, 9216, 10752, 11008, 10240, 8448, 6912, 5632, 4096, 768, -3328, -6656, -9472, -11264, -12800, -14080, -13824, -12288, -10752, -8192, -6144, -4608, -2560, -768, 2048, 5120, 7680, 7936, 6656, 5632, 5120, 3840, 1792, -1792, -5120, -8192, -11008, -13312, -13312, -11776, -9216, -6400, -4096, -1280, 2304, 6144, 9728, 10752, 9984, 7680, 5888, 4864, 3840, 2816, 2048, 1536, 1536, 1536, 2304, 4608, 7680, 10752, 12032, 11520, 11008, 9728, 7936, 5632, 2048, -2304, -5376, -8448, -11520, -14080, -15104, -14336, -12032, -9472, -7424, -5376, -3328, -1280, 512, 2048, 3328, 4864, 5632, 5120, 3840, 2304, 1280, -768, -2304, -5120, -7680, -9984, -11776, -11520, -10240, -7936, -6144, -4096, -1536, 1792, 5376, 8960, 9984, 9216, 7936, 6144, 5632, 3840, 2560, 2048, 1280, 1536, 768, 1024, 3072, 6400, 10240, 12288, 12800, 12288, 11008, 9472, 7680, 4352, -512, -4608, -8448, -11520, -14592, -16384, -15872, -13568, -10240, -7936, -5888, -3328, -768, 1024, 2816, 4096, 4864, 4608, 4352, 3328, 1792, -768, -2560, -4096, -5632, -7936, -10240, -11520, -11520, -10496, -8192, -6144, -3840, -1280, 2048, 6144, 9984, 12032, 11264, 9728, 8192, 6656, 5120, 3072, 768, -1024, -1024, -1280, -1024, 256, 2816, 7424, 10496, 12544, 13056, 12544, 11520, 9728, 6912, 2304, -2816, -6912, -9728, -13312, -15360, -16384, -14848, -11520, -8192, -5376, -3584, -1280, 768, 2560, 3328, 3328, 3584, 3584, 3072, 1024, -1536, -3072, -4352, -5376, -6400, -7936, -8960, -10240, -9984, -8448, -6912, -4864, -3072, 256, 4096, 7424, 9728, 10752, 10240, 9216, 8448, 7680, 5632, 2816, 256, -512, -512, -768, -512, 512, 4096, 8192, 11264, 12288, 11776, 11264, 9984, 7936, 4864, 256, -5376, -9216, -12288, -14848, -15872, -15104, -12544, -9728, -7168, -5120, -3072, -512, 2304, 4096, 4096, 3840, 4096, 3584, 2304, 512, -1792, -3584, -4864, -6400, -7936, -9216, -9728, -9728, -9216, -8704, -7168, -5120, -1792, 2048, 5632, 8448, 10496, 11776, 11776, 10752, 9984, 8448, 6400, 3584, 1024, -1024, -2048, -2048, -1024, 1024, 4096, 7680, 9728, 10752, 11776, 11520, 9728, 6400, 2560, -1792, -6144, -9984, -13056, -14848, -15104, -13568, -11008, -8704, -7168, -5376, -2304, 1280, 3840, 4352, 4096, 3840, 4096, 3840, 2560, 512, -2560, -4352, -5376, -6656, -8448, -9728, -10240, -9472, -8704, -8448, -7168, -4352, 0, 3840, 7424, 10240, 12288, 12800, 12288, 11264, 10240, 8704, 6656, 3840, 768, -1536, -2816, -2816, -1024, 1792, 4608, 6144, 7680, 9216, 9728, 8960, 7936, 6144, 3328, -1792, -6400, -10240, -12800, -13568, -13056, -12032, -10496, -9728, -8448, -6400, -2560, 1024, 3584, 4864, 5376, 5632, 4864, 4864, 4352, 1792, -1280, -3840, -5888, -7936, -9984, -11776, -12544, -12544, -11776, -10496, -8448, -4864, 0, 5376, 9984, 13568, 15616, 16384, 16128, 14336, 12800, 10752, 7936, 3840, -512, -3328, -4864, -4864, -2816, 0, 2560, 3840, 4864, 6912, 8448, 9472, 8960, 6400, 2304, -3328, -7168, -9728, -11264, -11776, -12800, -13568, -13056, -11776, -9728, -5888, -1792, 2560, 5120, 5376, 6144, 6400, 7168, 7168, 4864, 2048, -1792, -4608, -7168, -9216, -11008, -13312, -14336, -14592, -13056, -11264, -7936, -3328, 1792, 7424, 11776, 15360, 16896, 18176, 17408, 15616, 13824, 11520, 8192, 3328, -1280, -4352, -5632, -5120, -3840, -2048, -512, 2048, 3584, 6144, 7936, 8960, 8192, 5376, 1024, -3328, -6144, -8704, -10752, -12544, -14080, -14848, -13824, -12288, -9728, -5888, -1024, 3584, 6656, 8192, 7936, 8192, 9216, 8704, 5888, 1792, -3072, -6400, -8960, -12032, -15616, -17408, -17408, -15616, -13568, -10752, -6656, -1792, 5632, 11520, 15616, 18176, 19200, 19968, 18944, 16896, 14336, 10752, 6144, 1792, -3328, -6144, -7424, -6400, -4608, -2816, -1792, 512, 3584, 6912, 9216, 9728, 8192, 4864, 256, -3584, -5632, -8448, -11264, -14336, -16384, -16640, -15360, -12032, -8192, -4096, 768, 4608, 7936, 9472, 9472, 9728, 10496, 8960, 5120, 0, -4608, -7936, -11008, -14336, -16384, -17664, -17408, -15360, -12800, -9216, -3840, 1536, 7936, 12800, 15872, 18176, 19712, 19968, 18944, 16896, 13824, 9728, 5120, 512, -3840, -5888, -6656, -6144, -5632, -4352, -1792, 2048, 5120, 7424, 8960, 8448, 6400, 3328, -512, -3584, -7424, -10752, -14592, -17152, -18432, -17152, -14592, -10752, -6144, -1280, 3328, 7936, 11008, 11776, 12032, 12288, 11008, 8192, 3584, -1280, -5632, -10240, -14080, -16128, -17408, -17664, -16896, -14592, -11264, -6400, -1280, 4608, 9472, 14080, 16896, 19200, 19968, 19200, 17920, 15872, 12032, 7168, 2304, -1792, -4864, -6912, -7680, -6912, -5376, -2816, 1280, 4608, 7168, 8704, 9216, 8192, 6144, 3072, -1024, -5120, -9728, -14080, -17408, -19200, -18176, -16640, -13568, -8960, -3584, 1536, 6144, 9984, 12032, 12800, 12288, 11264, 9216, 5632, 1280, -4096, -8704, -12032, -14336, -15360, -15360, -15104, -13824, -11520, -7168, -2304, 2304, 6400, 10496, 13568, 16128, 17152, 16896, 16640, 15872, 13824, 10240, 5632, 1536, -2048, -4096, -5632, -5888, -5120, -2816, 256, 3328, 5632, 6912, 7424, 6656, 6144, 3840, 512, -3840, -8448, -12544, -16384, -18944, -18944, -17152, -14080, -9984, -5120, -512, 4096, 8192, 11520, 12800, 12544, 11008, 8960, 6656, 2816, -2304, -6400, -8960, -11264, -12544, -13312, -13824, -12800, -9984, -6656, -3072, 256, 3584, 6912, 9984, 12288, 13568, 14080, 14592, 14336, 12288, 9216, 6400, 3840, 1536, -1280, -3072, -4352, -3584, -2048, 768, 3584, 5376, 6656, 5888, 5376, 5376, 3584, 768, -2816, -6656, -11264, -15616, -18432, -18432, -17408, -14336, -10752, -6400, -2816, 1792, 6144, 9472, 11264, 11264, 10240, 8448, 6400, 3328, 0, -3072, -6144, -8192, -9984, -10496, -9984, -9216, -7680, -6144, -4608, -2560, 256, 2816, 5376, 7424, 9216, 10496, 12032, 13056, 13056, 10752, 8960, 6912, 4864, 2560, 256, -1536, -2560, -2304, -512, 1536, 2816, 3328, 3328, 3840, 3584, 2560, 1024, -2304, -4864, -7936, -11520, -14848, -17152, -17408, -14336, -11008, -7936, -5120, -2304, 1792, 5376, 7936, 8960, 8960, 8448, 6912, 4608, 1792, -768, -2304, -3328, -5120, -6912, -8192, -8448, -7424, -5888, -4864, -4096, -3072, -1024, 1536, 3840, 5888, 7680, 9984, 12032, 12544, 10752, 8960, 7936, 6912, 5632, 3584, 512, -2048, -2304, -1024, 1280, 2048, 2048, 2304, 1792, 1536, 768, 0, -1280, -3072, -5632, -8960, -12800, -14848, -14848, -12800, -9984, -8192, -6656, -4864, -2048, 1792, 5376, 6656, 6912, 6400, 5632, 4608, 2816, 1280, 512, 256, -768, -2560, -4864, -6144, -5888, -4096, -3840, -4352, -5120, -4352, -2560, -512, 1536, 3072, 5376, 8192, 11264, 11520, 9728, 7680, 6912, 7936, 7936, 5376, 2048, 256, 0, 512, 2048, 2560, 1792, 256, -768, -512, -1024, -2304, -3072, -4352, -6400, -9472, -12032, -13568, -12800, -10752, -8192, -6912, -6656, -5632, -2816, 1280, 3840, 4608, 5120, 5632, 5888, 5632, 4608, 3840, 3584, 2816, 1792, -768, -3584, -4608, -4352, -4608, -5632, -6912, -6912, -5376, -3584, -1536, 768, 3072, 6144, 8704, 10240, 9984, 8960, 8192, 7936, 8704, 7680, 4864, 2560, 1024, 512, 1280, 1792, 1792, 256, -1536, -2560, -2304, -2048, -2048, -2816, -4096, -6400, -8704, -10496, -10496, -9216, -8192, -8448, -8448, -7424, -5632, -2816, -512, 1536, 3328, 4352, 5632, 5888, 5632, 5632, 6144, 5888, 5120, 3072, 0, -1792, -2816, -3584, -5120, -6656, -7168, -6656, -5632, -3840, -2304, 512, 3328, 6400, 8192, 8448, 8960, 9216, 9472, 9728, 8960, 7424, 4864, 2304, 1280, 1792, 1536, 1024, -768, -2304, -3072, -2816, -1536, -1024, -1280, -2560, -4352, -6656, -8448, -9472, -9728, -9728, -9728, -10496, -9984, -7936, -5120, -2304, -512, 1536, 3840, 5888, 7936, 7936, 7936, 7680, 7424, 7168, 5376, 3328, 512, -2304, -4352, -5120, -5888, -6656, -6912, -6656, -5120, -3584, -1536, 1536, 3584, 5632, 6656, 8192, 8704, 8960, 9472, 9472, 9216, 6912, 3840, 1536, 1536, 1792, 1280, -768, -3328, -4352, -4352, -2816, -1280, -1280, -1536, -2816, -4608, -6144, -6912, -7680, -8960, -10240, -11264, -11264, -9984, -7168, -4096, -1536, 256, 2304, 5120, 7936, 8704, 9216, 9472, 9216, 8448, 5888, 3584, 1280, -768, -2560, -4352, -5888, -7680, -8704, -7936, -5632, -3584, -2048, 0, 1792, 3840, 5120, 6656, 7680, 8960, 10240, 10240, 8704, 6912, 4608, 3584, 2304, 2048, 1280, -512, -2816, -3840, -3328, -2048, -1024, 0, 256, -1536, -3072, -4608, -5888, -7424, -9728, -11520, -13312, -13568, -12032, -9472, -7168, -4096, -1280, 1536, 4352, 7168, 9472, 10752, 11008, 10240, 9472, 7936, 4864, 2048, 256, -1792, -3584, -5632, -6912, -8448, -8704, -7168, -4608, -2048, 0, 1280, 2560, 3584, 4864, 6400, 8448, 9728, 9984, 8960, 6912, 4608, 3328, 2304, 2048, 1024, -768, -2048, -3072, -3328, -2560, -1024, 1024, 1024, -512, -1792, -3584, -5376, -7168, -9216, -11520, -13568, -13824, -12800, -11264, -8704, -5120, -1280, 1792, 4608, 7168, 9472, 9984, 10752, 10240, 8960, 7168, 4352, 1792, 0, -1792, -3072, -4608, -5888, -7168, -7168, -5888, -4352, -2048, 512, 2048, 2304, 2560, 3072, 4352, 6400, 8192, 8448, 7168, 5120, 3328, 2560, 2560, 2048, 1536, 1280, 256, -1280, -1536, -768, 768, 2560, 2560, 1280, -1536, -3840, -5376, -7168, -9728, -12544, -15104, -15872, -15104, -13056, -9984, -6400, -2048, 1792, 4352, 7168, 9472, 10752, 11264, 11008, 9728, 7680, 4352, 1792, 0, -1024, -2560, -4096, -6144, -6656, -6912, -5376, -3584, -2304, -512, 1280, 2816, 3584, 3072, 3328, 4864, 6656, 7424, 6656, 4864, 3328, 2048, 2048, 2304, 1280, 512, 512, 1024, 768, 256, 256, 1280, 2048, 1792, 0, -2560, -4608, -6400, -8192, -10752, -13312, -14336, -13568, -12288, -9728, -7424, -3584, 256, 3584, 5888, 7680, 8448, 8448, 8960, 8448, 6656, 4352, 2304, 512, 256, 0, -1280, -3072, -4864, -5632, -5376, -3328, -2048, -1024, 1280, 2560, 3072, 2560, 2560, 3584, 5376, 6400, 6144, 3840, 1280, 768, 1280, 1792, 1280, 512, 1280, 2560, 3072, 2560, 2304, 2816, 3328, 2560, 512, -2048, -4608, -6400, -8192, -10240, -12800, -14080, -13568, -11520, -8960, -6912, -4352, -1024, 2816, 5120, 7168, 7680, 7168, 7424, 7680, 7168, 4864, 2560, 1536, 1536, 1280, 0, -2560, -4608, -5120, -4608, -3584, -2816, -2560, -1024, 1536, 3328, 3328, 2816, 3328, 5120, 6400, 6144, 3840, 1792, 768, 1024, 1280, 1024, 0, 768, 2304, 3584, 3840, 2816, 2304, 2048, 2048, 1536, -1280, -4096, -6144, -7424, -8960, -11008, -12288, -12032, -10752, -7936, -5888, -4352, -1792, 1280, 4352, 6144, 6656, 5632, 4864, 4864, 5120, 4352, 2816, 1280, 512, 512, 0, -1024, -2560, -3584, -3584, -2560, -2048, -1536, 256, 2560, 4864, 5888, 5632, 4352, 4096, 4864, 4608, 2816, 256, -2048, -2816, -2560, -1792, -1024, 256, 1792, 3840, 5632, 5632, 4608, 4352, 4096, 3072, 1024, -2048, -5376, -7424, -8704, -9984, -11776, -12544, -11776, -9472, -7168, -4864, -2304, -512, 2048, 4864, 5632, 5120, 4608, 4608, 4864, 4864, 3072, 1536, 768, 512, 0, -1280, -2560, -4096, -4608, -3584, -2304, -2048, -768, 1536, 4352, 6400, 6912, 6656, 6144, 6400, 5632, 3840, 768, -2048, -3328, -3328, -3072, -2816, -1536, 0, 2304, 4096, 4864, 4864, 4096, 3328, 2560, 1536, -1280, -3584, -5632, -6656, -8192, -9472, -10496, -9984, -8192, -5888, -4352, -3584, -2560, -768, 2304, 4352, 4608, 2560, 1792, 2560, 4096, 4608, 3072, 1280, 256, 256, -1024, -3328, -4608, -4608, -3840, -3072, -2816, -2560, 256, 3840, 7424, 9472, 8960, 7936, 7680, 7680, 6144, 2816, -2048, -4608, -4608, -3840, -4352, -5120, -4352, -1536, 2048, 3840, 4608, 4096, 3840, 2816, 3072, 2048, 0, -2560, -4096, -5120, -7168, -8960, -9728, -8448, -6912, -5888, -5376, -4864, -3328, 0, 2816, 3584, 3072, 2304, 2816, 4608, 5376, 4864, 2560, 512, -768, -1280, -3072, -5376, -7168, -6656, -5120, -3840, -3072, -1536, 2304, 6400, 9728, 11008, 10752, 10240, 9728, 8704, 5888, 1536, -3072, -4608, -4608, -4608, -5888, -6400, -5632, -3328, 0, 1792, 2304, 2048, 2048, 2816, 3072, 2304, 1536, 512, -1280, -3584, -5376, -6144, -6144, -5632, -5632, -5376, -5632, -5120, -3072, -768, 1024, 1280, 1280, 1536, 2816, 3840, 4096, 2560, 1024, -512, -1792, -2816, -5120, -6400, -6912, -5376, -3328, -2816, -1280, 1536, 5632, 9472, 11776, 12800, 12544, 11264, 9984, 7936, 4096, -768, -3840, -5376, -6144, -6912, -8192, -8448, -7168, -4352, -1280, 1280, 1792, 1792, 2560, 3840, 4096, 3840, 2560, 1024, -1024, -2816, -4608, -5632, -5632, -5120, -5632, -5376, -5376, -4352, -2560, 256, 1536, 2304, 2560, 3840, 4864, 4608, 3072, 1280, 0, -2304, -3840, -5888, -7936, -9216, -8192, -6144, -4352, -2816, -1024, 3072, 7936, 12032, 13568, 14848, 15360, 14336, 12544, 8960, 3840, -1024, -4096, -5376, -6400, -8192, -10752, -11520, -8960, -5888, -3584, -2048, 0, 1536, 3328, 5120, 5376, 4864, 3840, 2304, 256, -1536, -2816, -3328, -4096, -4608, -5120, -5888, -5120, -3584, -2048, 0, 512, 1280, 2816, 4608, 4608, 3584, 1536, -512, -2560, -4608, -6912, -8704, -10496, -10240, -7936, -5120, -3072, -1792, 1024, 5888, 12032, 16384, 18176, 18176, 16128, 14336, 11776, 7680, 3072, -1792, -5632, -8960, -10752, -12544, -13312, -12288, -8704, -5632, -3584, -1792, 768, 3840, 6144, 6912, 6912, 6144, 3840, 1536, -1024, -2048, -2816, -3328, -3328, -3840, -4096, -3584, -3072, -1792, -512, 768, 2560, 3072, 3584, 3840, 1792, 0, -1792, -4096, -6400, -8192, -10240, -11264, -11264, -9216, -6144, -2816, 0, 1536, 4096, 9216, 14848, 18432, 19456, 18176, 15872, 13056, 9728, 6144, 1280, -3328, -7680, -10752, -12800, -13312, -13568, -11776, -8448, -5376, -3840, -1536, 1792, 5120, 6400, 6400, 5376, 4608, 3584, 1792, 512, -1280, -2304, -2304, -1792, -2048, -2304, -2560, -1792, -768, 256, 1536, 1792, 2048, 2304, 1536, -512, -3328, -5888, -7680, -8960, -10496, -11520, -11264, -9728, -6656, -3840, -768, 2816, 4864, 8448, 13312, 17664, 19200, 18432, 16640, 13824, 10752, 7424, 3328, -1536, -6400, -10496, -12544, -13824, -14080, -12288, -9728, -6656, -4608, -2048, 256, 3328, 6144, 7424, 6656, 4864, 2816, 1280, 512, -512, -1536, -1536, -1536, -1280, -1792, -1280, 256, 1280, 2304, 2816, 2048, 2048, 1792, 1024, -1536, -4352, -7168, -8960, -10752, -12032, -12288, -11520, -9984, -7424, -4096, -1280, 1792, 4608, 8192, 11520, 14592, 16384, 17152, 15872, 13824, 11520, 8960, 5632, 1280, -3328, -7168, -10240, -12032, -12544, -11776, -10752, -8192, -5376, -2816, -1024, 1536, 3840, 5376, 5376, 4096, 3072, 1536, 256, -768, -1280, -768, 768, 2048, 2304, 2048, 1792, 1792, 2816, 3072, 2816, 1536, -512, -2304, -3328, -5120, -7424, -10240, -12032, -12032, -11520, -10752, -9472, -7424, -4096, -1280, 1792, 4352, 6912, 9728, 12288, 14336, 15104, 13568, 11264, 10240, 9472, 7680, 4352, -512, -4096, -6400, -8192, -8960, -9216, -8960, -7936, -5888, -4096, -2560, -768, 1024, 2560, 2816, 2048, 256, 0, 0, 0, 0, 256, 1536, 3584, 5120, 5376, 4864, 3840, 3584, 3328, 2816, 1792, 0, -3328, -5376, -7168, -9472, -11776, -13056, -12288, -11008, -9472, -8192, -7168, -5376, -2304, 1024, 4352, 6912, 8192, 10240, 11520, 12800, 13056, 11776, 10240, 9728, 8960, 6912, 3072, -768, -3328, -5888, -6912, -7424, -7680, -7424, -7168, -5888, -3840, -2560, -1280, 512, 1280, 1280, 256, -512, -512, 256, 1024, 1024, 2048, 3584, 4864, 6400, 6656, 5376, 3840, 3328, 3072, 3072, 1280, -2304, -5376, -7680, -9472, -11008, -12800, -13056, -12032, -10752, -9728, -8704, -6912, -4352, -1280, 2560, 5632, 7680, 9728, 11264, 12544, 12800, 11776, 10240, 9472, 9728, 8448, 4864, 1024, -2048, -3584, -4608, -5632, -6144, -6144, -5632, -4608, -4096, -3584, -2560, -1536, 256, 256, -1536, -2048, -2304, -1536, 0, 512, 2048, 3584, 5376, 7168, 7936, 6912, 6144, 5376, 5120, 4096, 2304, -768, -4096, -6656, -8448, -10752, -12800, -14080, -14336, -12800, -11008, -9984, -9728, -7424, -3328, 1536, 4608, 6912, 8448, 10752, 13056, 13824, 13568, 12288, 10496, 9984, 9728, 7424, 3072, -1280, -3840, -4864, -5120, -5888, -6144, -5632, -4608, -4352, -3328, -3072, -2560, -1024, -768, -1024, -1792, -2048, -2304, -2304, -1792, 512, 2304, 3584, 5376, 6656, 6912, 6912, 5632, 5120, 4864, 4352, 3072, 256, -3584, -6400, -8960, -10496, -11520, -12800, -13568, -13824, -13056, -12032, -10496, -7936, -4608, -768, 3072, 6144, 8960, 12032, 14080, 14848, 14592, 14080, 12544, 11776, 10240, 6656, 2816, -1280, -4352, -5632, -5888, -5888, -5632, -5376, -5376, -4608, -3840, -2304, -1280, -768, -1024, -1536, -1792, -2304, -3072, -3072, -2048, 256, 1792, 3328, 3584, 4864, 5888, 6912, 6656, 6400, 6400, 5120, 3328, 1024, -2304, -5632, -9216, -10752, -12288, -14080, -15616, -15872, -15104, -13824, -11008, -8192, -4608, 0, 4608, 8960, 12544, 14592, 15360, 15872, 16128, 15616, 14592, 12288, 8448, 3840, -512, -3840, -6144, -7168, -6912, -5632, -5888, -6144, -5376, -3328, -1024, 768, 768, 256, -512, -1024, -1024, -2304, -3840, -4096, -3328, -2304, -1280, 512, 1792, 2816, 4864, 6144, 7168, 7936, 7424, 7168, 6144, 3072, -1024, -5376, -8448, -9728, -12288, -15616, -18432, -19456, -18176, -15616, -12032, -8704, -5120, 512, 6656, 11520, 14848, 16640, 17664, 18944, 19200, 17408, 14080, 10496, 7168, 3328, -1792, -5632, -8192, -8192, -7424, -6144, -5888, -5632, -4864, -1792, 1536, 1792, 512, -512, -768, 0, -768, -2560, -5120, -6144, -4864, -3072, -1280, 256, 1280, 3584, 5888, 7680, 8448, 9472, 9984, 9216, 6144, 2048, -2560, -6400, -8448, -11008, -14080, -18176, -20992, -20992, -18176, -14592, -11264, -7424, -2816, 3328, 8704, 13312, 16384, 17920, 18688, 19712, 19456, 16640, 12800, 8960, 5120, 1024, -3328, -6656, -7936, -8192, -6912, -6656, -6400, -5376, -2560, 512, 2048, 1280, 768, 0, 256, 512, -768, -3072, -5632, -6144, -5376, -4096, -2304, -768, 1536, 3584, 5632, 7168, 8704, 10496, 10752, 8960, 5888, 1536, -2560, -5376, -8192, -11520, -15616, -19456, -21760, -20992, -17920, -13824, -11008, -7424, -1792, 4608, 10240, 14080, 16384, 18176, 19712, 20736, 19456, 15872, 12288, 8192, 4864, 1536, -2560, -5888, -7680, -7424, -7168, -7680, -6912, -5120, -2560, -512, 768, 256, 0, 768, 1536, 1024, -2304, -4608, -6144, -5632, -4608, -3584, -2048, 0, 2048, 4096, 6144, 8192, 9728, 10752, 10752, 7936, 3840, -512, -3584, -6400, -9728, -13312, -17152, -20736, -21760, -19456, -16128, -12544, -9472, -4864, 768, 6656, 11008, 14592, 17152, 19200, 20992, 20224, 17920, 14336, 10496, 7168, 3840, 256, -3072, -5632, -6912, -6912, -7168, -6656, -5376, -3072, -768, 768, -512, -512, 256, 768, 256, -3072, -5632, -7168, -7424, -6912, -5888, -4608, -2816, 768, 4096, 6400, 8704, 11264, 13056, 13312, 11008, 6912, 3072, -512, -4352, -8704, -13056, -18176, -20992, -22016, -21248, -19200, -15616, -11520, -6912, -1792, 4096, 9472, 13568, 16128, 18432, 19968, 19712, 17408, 15360, 11520, 8448, 5120, 2560, -512, -2304, -3840, -4608, -5632, -5888, -4864, -3840, -2048, -1280, -1792, -2048, -1792, -1024, -768, -2560, -5632, -7424, -7424, -6144, -5376, -4608, -3584, -768, 3072, 5888, 6912, 8960, 11264, 12544, 12032, 8704, 4608, 256, -2816, -5888, -10240, -14592, -18688, -20736, -20480, -18944, -16384, -12800, -9216, -4864, 512, 5632, 9728, 12544, 15616, 17664, 18944, 17664, 15360, 12800, 10240, 7424, 5120, 2560, 512, -1280, -2304, -3072, -4096, -4608, -3584, -2304, -1536, -2560, -3328, -3072, -2560, -2816, -3840, -5888, -7680, -7936, -6912, -6400, -5888, -4864, -2048, 2048, 5120, 7168, 9216, 11520, 12544, 12544, 10496, 7424, 3840, -512, -3840, -7936, -12544, -16640, -19456, -20224, -19712, -17152, -14080, -11008, -7680, -3328, 1792, 6400, 10240, 13056, 15360, 16896, 16896, 15872, 13824, 11520, 9472, 7424, 5632, 3584, 1792, 768, -768, -1792, -2560, -3072, -2560, -2048, -3072, -4608, -4864, -4096, -3328, -3840, -5888, -7936, -8448, -7424, -6656, -6400, -5888, -3840, 256, 3584, 5888, 7936, 10240, 12800, 13312, 11776, 9216, 5376, 1792, -2048, -6144, -10496, -14848, -17920, -19200, -18944, -17152, -14592, -11008, -7680, -4608, -768, 3328, 6656, 9984, 12288, 14336, 15360, 14848, 13056, 11520, 10752, 9216, 7424, 6400, 5120, 3584, 2304, 1536, 768, 0, -1280, -1536, -3072, -4352, -5632, -5376, -5120, -6144, -8448, -9472, -9728, -8960, -7680, -7168, -6144, -4352, -768, 3072, 6144, 8448, 11008, 12800, 13312, 12544, 10240, 7168, 3328, -768, -4608, -8704, -13056, -16128, -18176, -18432, -17152, -15104, -12544, -9472, -6144, -2560, 768, 4096, 6912, 9472, 11776, 12800, 13568, 13056, 12544, 11776, 11008, 9472, 8192, 7424, 6400, 5376, 4352, 2560, 1024, -768, -2048, -2560, -2816, -4608, -6400, -7424, -7936, -8704, -9472, -10240, -10240, -9472, -7936, -6400, -5120, -3328, 0, 4352, 7936, 10496, 12288, 12800, 12544, 11776, 9216, 5632, 2048, -1280, -5120, -9216, -12544, -15616, -17152, -17152, -15616, -13056, -11264, -9216, -5888, -2304, 1024, 3328, 5120, 7680, 9728, 11776, 12288, 12032, 11264, 11264, 11264, 11776, 10752, 8960, 7936, 7168, 6144, 3840, 1280, -768, -1536, -2560, -4608, -7168, -8960, -9984, -10496, -10496, -11008, -11520, -10752, -9216, -7424, -5888, -3840, 256, 3840, 7168, 10240, 12032, 13056, 13056, 11776, 9472, 6912, 3584, 512, -3584, -7424, -10752, -12544, -13824, -15872, -16128, -14592, -12544, -10496, -7936, -5376, -3072, -768, 1536, 4352, 6400, 8192, 10240, 11520, 12544, 12800, 12288, 12544, 12544, 12288, 11264, 9984, 8704, 6656, 3328, 1024, -1024, -2816, -4352, -5888, -8192, -10496, -12288, -12288, -12544, -12288, -11264, -9984, -9216, -7936, -5376, -1280, 3328, 6144, 8960, 11264, 13056, 13312, 12032, 9984, 7680, 5376, 2048, -1536, -4608, -8704, -11264, -12800, -13824, -15104, -14848, -13568, -11776, -9728, -7168, -4608, -2560, -1024, 1536, 4096, 6144, 7680, 9472, 10752, 12288, 12544, 12032, 12288, 13056, 13056, 12544, 11520, 8960, 6912, 4352, 2304, 0, -3072, -5888, -8192, -10496, -12288, -13568, -14080, -13824, -13568, -12544, -11008, -9728, -6912, -3328, 1280, 5120, 8448, 11264, 13312, 14848, 14592, 12800, 10240, 7424, 4096, 1280, -2816, -7424, -11008, -13568, -14336, -15872, -16640, -16128, -13824, -10752, -8448, -6144, -4096, -2048, 768, 4096, 5888, 7424, 8448, 9728, 11264, 11776, 11520, 11008, 11520, 12544, 13312, 12288, 10752, 9472, 7168, 4864, 2560, 0, -3328, -6400, -9216, -10752, -12032, -14336, -14848, -14336, -13568, -12544, -12288, -10240, -6656, -1536, 3328, 6912, 9984, 12544, 15104, 16384, 15872, 13568, 10752, 7424, 4096, 512, -4608, -9472, -13312, -15360, -16640, -18176, -19200, -17408, -14080, -10496, -7680, -4864, -2560, 0, 3584, 6144, 8448, 9472, 9728, 9984, 10752, 11520, 11520, 11008, 11520, 12288, 12032, 11776, 10496, 8960, 7168, 4864, 2048, -1536, -5120, -7680, -9728, -11264, -12800, -14080, -14592, -15104, -14592, -13568, -11776, -8960, -4864, 0, 4352, 8192, 11520, 15104, 16896, 16896, 15104, 13824, 11776, 8192, 3840, -1280, -6144, -11008, -14592, -16640, -18176, -19456, -19968, -18176, -14848, -10496, -6912, -4096, -1280, 1280, 3840, 6912, 9472, 11008, 11008, 10752, 10752, 10752, 11008, 11776, 11776, 11776, 11520, 10752, 10496, 8960, 7168, 4608, 1792, -1536, -4608, -7424, -9472, -11264, -13056, -14336, -15104, -15616, -15360, -14080, -11520, -8448, -4608, -512, 4608, 9472, 12800, 15616, 17152, 17408, 16640, 15104, 12032, 7936, 2560, -2816, -8192, -12032, -14848, -18176, -20736, -22016, -21248, -17920, -13312, -9216, -5376, -2304, 512, 3328, 6400, 8960, 10496, 11264, 11008, 10240, 9984, 9984, 10240, 11008, 11008, 10240, 9984, 10240, 10240, 9216, 7168, 4608, 2304, -1280, -4608, -7168, -9216, -11264, -13312, -14592, -15616, -16384, -16128, -14336, -11008, -6912, -3328, 1536, 6656, 11264, 14336, 16896, 18176, 18176, 16384, 14080, 10752, 5888, 768, -4864, -9728, -13312, -16896, -19456, -20992, -22016, -20736, -17152, -12544, -8192, -4864, -2048, 768, 3840, 7168, 9216, 10752, 11008, 11008, 10496, 10496, 10240, 10240, 10496, 10240, 10240, 10496, 10496, 9216, 7680, 6144, 4352, 2560, -1280, -4864, -7424, -9472, -11008, -12800, -14592, -16384, -16896, -15360, -12800, -10240, -7168, -2560, 3072, 8192, 11520, 13824, 15104, 16384, 17152, 16128, 13824, 8960, 3584, -1536, -5632, -8960, -12800, -16384, -19200, -20992, -20736, -18688, -15104, -11776, -8448, -5376, -2048, 1280, 4864, 6912, 8448, 10240, 11264, 11264, 10752, 10240, 10752, 10496, 10240, 9728, 9984, 9728, 9728, 8960, 7680, 5376, 3328, 1024, -2048, -4096, -6400, -8960, -11520, -13568, -15872, -16640, -16128, -14336, -12032, -9984, -6400, -1536, 3840, 8192, 11520, 13568, 14848, 16384, 16640, 15360, 12288, 7680, 2304, -1792, -4864, -7936, -12032, -15360, -18432, -20224, -20224, -18688, -15616, -12800, -9472, -6144, -2560, 768, 3072, 5632, 8448, 11008, 12032, 11776, 11264, 11008, 11520, 11776, 11520, 11520, 11008, 10496, 9728, 8704, 6656, 4096, 1792, -512, -2560, -4864, -7424, -9984, -12800, -15104, -16384, -15872, -14848, -13056, -11264, -8704, -5632, -512, 4096, 7680, 10496, 13312, 14336, 14592, 14848, 13824, 10752, 7424, 3328, 512, -3072, -6912, -10752, -14336, -17152, -18176, -18688, -17920, -16128, -14080, -10752, -6656, -2560, 512, 2816, 5120, 8448, 10496, 11776, 11520, 11008, 12544, 13568, 13312, 12288, 11264, 11008, 10752, 9728, 8448, 5632, 3072, 1024, -1280, -3328, -5888, -8704, -11008, -12800, -14592, -15616, -15360, -14080, -12544, -10240, -7424, -3584, -512, 3072, 6400, 8960, 11264, 13056, 14336, 14336, 12544, 9984, 7680, 5120, 2560, -512, -4352, -8192, -12288, -15360, -17152, -18944, -19712, -18944, -16896, -12800, -9216, -5376, -2304, 0, 3584, 7680, 11008, 13056, 13568, 14592, 15872, 16384, 15872, 14848, 13568, 12288, 10752, 9216, 6400, 3072, 1024, -1024, -3072, -5376, -7936, -9728, -11008, -11520, -12032, -12544, -12032, -11264, -10240, -8704, -7168, -5632, -2816, 256, 2816, 5376, 7168, 9984, 12544, 13568, 13312, 12544, 11264, 9728, 7424, 4096, -1024, -6144, -10496, -14592, -18944, -22016, -23040, -22016, -18688, -15104, -11264, -7680, -4096, 256, 5376, 10240, 13824, 15616, 16896, 17152, 18176, 18432, 16640, 14592, 12544, 10496, 8448, 6144, 3072, 256, -2048, -3072, -3840, -5632, -7936, -9472, -8960, -7936, -8448, -9216, -9984, -10240, -9728, -8704, -8192, -7424, -6144, -3584, -512, 2816, 6144, 9216, 12288, 14336, 15616, 16128, 15104, 13824, 11264, 6912, 1536, -4864, -11776, -17408, -21504, -24064, -25344, -25088, -23040, -18432, -13056, -7680, -3840, 256, 5632, 11776, 16384, 19456, 19968, 20480, 20736, 19968, 18432, 15360, 11520, 8704, 6144, 3328, 0, -3328, -4608, -4608, -4608, -5632, -7168, -7424, -6144, -4864, -4864, -6656, -8448, -9728, -10240, -10240, -10496, -10752, -10496, -8192, -3840, 1536, 5632, 9472, 12800, 15872, 18944, 20224, 19456, 16640, 12800, 7680, 1536, -6144, -13824, -19968, -24064, -27136, -28160, -26368, -22784, -17664, -12544, -7424, -2560, 2816, 9216, 14592, 18688, 19968, 20480, 20992, 21248, 19712, 16896, 13056, 9472, 6144, 3584, 1280, -1280, -3072, -4352, -4352, -4352, -4608, -4864, -4352, -3328, -3328, -4864, -7168, -9472, -11264, -11264, -12288, -13568, -15104, -13824, -8960, -3072, 2816, 7424, 11776, 15616, 19968, 22528, 23040, 21504, 17408, 12544, 6144, -1536, -9984, -18176, -23552, -26624, -29440, -29696, -27648, -22784, -16896, -11008, -5376, 256, 6144, 12544, 17408, 19968, 20992, 20736, 20736, 20224, 18176, 14336, 9472, 6144, 3840, 1536, -1024, -2304, -2816, -2304, -1536, -1536, -2560, -2816, -1536, -1024, -2048, -5120, -8448, -11264, -14080, -15616, -16640, -17920, -17408, -14080, -7936, -1536, 3840, 9728, 15616, 20992, 24832, 25856, 24064, 20480, 15616, 9472, 2304, -6400, -15360, -22528, -27392, -30464, -31488, -29696, -25344, -19712, -13568, -7680, -1280, 5120, 12032, 17408, 20480, 20992, 20992, 20480, 19712, 17920, 14592, 10240, 5888, 2560, 768, -512, -768, -1024, -768, 512, 1280, 1792, 1280, 1280, 1024, -1024, -4352, -8192, -11520, -15360, -17664, -18944, -20224, -20480, -17920, -12032, -5120, 2304, 8192, 14080, 19456, 24064, 26624, 26368, 23296, 18176, 11776, 4096, -4096, -12288, -19200, -24832, -29440, -30976, -29952, -25856, -20480, -14592, -8192, -2048, 3840, 9984, 14848, 17408, 18688, 18688, 18688, 17664, 15616, 12800, 9984, 6656, 3840, 1792, 1024, 1792, 3072, 4608, 4864, 5120, 4608, 4352, 3840, 2560, -1024, -5120, -10496, -14592, -17408, -19712, -21760, -23296, -23040, -19456, -13568, -6400, 512, 7168, 14080, 20224, 24832, 27136, 26624, 24064, 19712, 13312, 5632, -2304, -9984, -17152, -23552, -28416, -30464, -29440, -25344, -20224, -14080, -8448, -2816, 3840, 9472, 14080, 17152, 18176, 17408, 15616, 13056, 11264, 10240, 8960, 6144, 2560, 768, 1024, 3328, 6400, 9216, 10752, 10496, 8704, 7424, 5120, 3072, -512, -5376, -11008, -16896, -21504, -24064, -24576, -24576, -23808, -20736, -14080, -6656, 1024, 7680, 14336, 20480, 25088, 27392, 27136, 24320, 19712, 13568, 6144, -2048, -9728, -16384, -21760, -25856, -27904, -27904, -25600, -20480, -14080, -7936, -2048, 3328, 7936, 11776, 14336, 15616, 15104, 13312, 11008, 9216, 7680, 6400, 4096, 2048, 1792, 2816, 5888, 9472, 12288, 14336, 15104, 14336, 12288, 8448, 4352, -1280, -7424, -13824, -20224, -24576, -27136, -27904, -26880, -24576, -20992, -14592, -6400, 2048, 9728, 15616, 20224, 24064, 26368, 26112, 23552, 18688, 11776, 4864, -2560, -9216, -15872, -20736, -24320, -25856, -25600, -23040, -18176, -12032, -6400, -768, 4608, 7936, 10496, 12544, 13568, 12800, 10752, 8192, 5376, 3328, 2304, 1792, 2048, 2048, 3072, 7680, 12544, 16128, 18176, 19456, 19200, 17152, 12288, 6400, -768, -7680, -15104, -22272, -27392, -30720, -31744, -29952, -26880, -22784, -16128, -7936, 1280, 10240, 16128, 20736, 23552, 25600, 25600, 22528, 17664, 11776, 5120, -1536, -7936, -14080, -18688, -22272, -23296, -22528, -20480, -16384, -11520, -5632, 256, 4096, 6912, 8704, 9984, 11520, 10496, 7936, 5120, 2304, 1024, 768, 256, 768, 1536, 3840, 8192, 13568, 18176, 20736, 21760, 22016, 19968, 15616, 8960, 768, -7424, -16128, -23808, -28928, -31744, -32768, -31744, -28160, -22784, -16384, -8192, 1280, 9728, 15872, 20480, 23296, 25088, 23808, 20480, 16128, 10752, 4864, -1280, -7424, -13056, -17408, -19968, -20736, -20224, -18432, -14848, -10240, -4864, 0, 3328, 5376, 7424, 8960, 8960, 7424, 5376, 3584, 2048, 512, -512, -768, 256, 2560, 5120, 9216, 14336, 18688, 21504, 22784, 22784, 20736, 16640, 10496, 1536, -8192, -16128, -23040, -28160, -31744, -32512, -31488, -28160, -22784, -15616, -7680, 512, 8448, 14336, 18176, 20736, 22016, 21760, 18944, 14848, 9728, 4352, -1280, -5376, -9728, -13312, -15872, -17664, -17664, -16384, -12800, -8704, -4608, -1280, 1280, 3328, 5888, 7168, 6912, 5632, 3840, 2560, 1536, 256, 0, -512, 512, 2304, 5888, 10496, 14336, 18432, 21504, 22528, 22784, 20736, 16896, 11520, 3840, -5120, -14080, -21504, -27136, -30464, -30976, -29696, -26880, -22784, -17152, -9728, -1792, 5376, 11264, 14848, 17664, 19200, 18944, 16384, 12800, 9216, 5632, 2048, -2560, -6656, -9984, -12032, -13824, -14336, -13568, -12032, -9216, -6400, -2816, -512, 1280, 3584, 5888, 6144, 5120, 3072, 1792, 1536, 1536, 1536, 1024, 1280, 2560, 5632, 9984, 14592, 18432, 20480, 20992, 20480, 18688, 15872, 11520, 4608, -3328, -12288, -19968, -24576, -26880, -26880, -26624, -24832, -20736, -16384, -10240, -3840, 2560, 7168, 10240, 12544, 13824, 13568, 12544, 10752, 7936, 5632, 3328, 512, -2304, -4352, -5632, -7680, -9728, -10240, -9472, -8448, -7168, -5632, -4096, -2560, -1280, 1280, 2816, 2816, 1536, 768, 1280, 2816, 4096, 4096, 4608, 5632, 7424, 10240, 13824, 17408, 19200, 18944, 18432, 16128, 12544, 8960, 3840, -2560, -9472, -16128, -21248, -24064, -24320, -22784, -20992, -18688, -16128, -11776, -6144, -512, 4096, 6400, 7936, 8960, 9984, 10496, 9472, 7680, 5632, 3840, 2816, 1024, -768, -2816, -4608, -6400, -7936, -8960, -8448, -7168, -5632, -4608, -4096, -3328, -1024, 1280, 2560, 2816, 2560, 1280, 1536, 3584, 5376, 5888, 6144, 6912, 8448, 11520, 15104, 17408, 18432, 17152, 14592, 11776, 8704, 4864, 0, -6144, -12544, -17920, -20736, -20992, -19712, -17920, -16640, -15360, -12544, -8704, -3840, 512, 2304, 3328, 3584, 4608, 5120, 5376, 4864, 4608, 4352, 4096, 3840, 3328, 2560, 1280, -768, -3072, -5120, -6656, -7168, -6912, -6144, -6656, -6400, -4608, -2304, 768, 2304, 2560, 2560, 2816, 4608, 6912, 8192, 8448, 8448, 8960, 10752, 13056, 14848, 15104, 14080, 11776, 9216, 6400, 4096, 768, -3840, -8448, -12800, -15616, -16640, -16384, -15104, -14592, -14336, -13312, -10752, -7424, -3584, -1280, -512, -768, 256, 2048, 3072, 3328, 3328, 4096, 4096, 4608, 4864, 4864, 3584, 1024, -768, -2560, -4864, -6144, -6144, -5632, -5120, -6144, -5888, -4096, -512, 2560, 4096, 3584, 3328, 4096, 7168, 8960, 9216, 8960, 8192, 8448, 10240, 11520, 12544, 12032, 10496, 7936, 5120, 3072, 1024, -2048, -4096, -7424, -10496, -12800, -13568, -12800, -12544, -13056, -13056, -12288, -10240, -7680, -5120, -3328, -3328, -3072, -1536, 512, 2048, 3072, 3328, 4096, 5376, 6656, 6912, 5888, 3840, 2048, 0, -2560, -4864, -5888, -6144, -6144, -6656, -6400, -5376, -2304, 1280, 3840, 4864, 5120, 5632, 7168, 9216, 9984, 9728, 9216, 8448, 8448, 8960, 9472, 9728, 9216, 7680, 5120, 2304, 1024, -768, -2560, -4352, -6656, -8960, -10240, -11520, -12032, -13056, -13312, -12544, -11776, -9984, -7680, -5888, -4864, -4352, -3072, -1280, 256, 1024, 1792, 2816, 4608, 5632, 5632, 5632, 5120, 4352, 3072, 768, -2048, -4096, -4608, -4096, -4352, -4864, -4608, -3072, 768, 3328, 4864, 5120, 6144, 7424, 8704, 8960, 8448, 8192, 7936, 7936, 7680, 6656, 6144, 6144, 6400, 5376, 3584, 1536, 0, -1024, -1280, -2560, -4864, -7936, -9472, -10240, -12032, -13056, -12800, -12544, -11520, -9984, -7936, -6400, -4864, -3072, -1536, -768, 0, 512, 1536, 3328, 4352, 4608, 4096, 3840, 4096, 3584, 1792, -768, -2560, -3072, -3328, -3328, -3584, -3328, -1536, 1536, 4608, 6144, 6400, 6656, 7424, 8448, 8192, 6656, 6144, 5888, 5888, 5632, 4608, 3584, 3840, 5376, 6144, 5632, 3584, 1536, 1024, 1024, 256, -2304, -5376, -8192, -10496, -12032, -12800, -13824, -13824, -13056, -12032, -9472, -7680, -5376, -2560, -768, 256, 1024, 1536, 1792, 2048, 1792, 1792, 1792, 1792, 1536, 1536, 1280, 512, -768, -2048, -2048, -1536, -768, 256, 768, 2304, 4352, 6400, 7424, 8192, 8448, 7424, 6656, 6144, 5888, 5120, 4352, 3584, 2816, 2048, 2048, 3584, 5376, 5632, 4352, 3328, 2304, 2304, 1792, 256, -2816, -6400, -9472, -11264, -13312, -13568, -14080, -14080, -13056, -11008, -8960, -6144, -3584, -1024, 768, 1024, 1024, 1536, 1792, 1536, 768, -512, -512, 512, 1536, 1280, 256, -1024, -2048, -1792, -1280, 768, 2304, 2304, 3072, 4352, 6400, 8192, 9472, 9472, 8192, 6400, 5376, 4864, 4352, 3840, 2304, 1536, 1536, 1536, 2048, 3584, 5888, 6144, 5120, 3840, 3584, 2816, 768, -1536, -4608, -7936, -11264, -13568, -13824, -14592, -14848, -14080, -12032, -9472, -6656, -4096, -1024, 1792, 2560, 2560, 2304, 1792, 768, -512, -1536, -2048, -1536, -1280, -1024, -1792, -2560, -2048, -1536, 0, 1536, 3072, 4096, 5120, 6912, 8448, 8960, 8960, 9216, 8704, 7168, 5376, 4096, 2560, 1792, 1792, 1280, 768, 256, 1280, 3072, 5376, 6400, 5888, 4352, 3584, 3328, 2304, -768, -4352, -7680, -10496, -12800, -13824, -15104, -15616, -14080, -11776, -9472, -6656, -3840, -1024, 1792, 3584, 3840, 3072, 1536, 256, -768, -1792, -3072, -3584, -3840, -3328, -3072, -3072, -3072, -2048, 0, 2048, 3840, 5120, 6400, 7936, 9216, 10240, 10496, 10496, 9728, 8448, 6912, 5376, 3072, 1024, 256, 0, -1024, -1280, -512, 1280, 3072, 4352, 4864, 4864, 4608, 3584, 2816, 512, -2304, -5376, -8192, -10752, -12544, -14080, -14592, -14336, -12544, -9984, -7680, -5120, -2048, 768, 3072, 4352, 4608, 3072, 1280, -512, -2048, -3584, -4608, -5376, -5632, -5376, -5376, -4864, -3328, -1792, 1024, 3584, 6144, 8192, 9984, 11264, 12288, 12032, 11264, 10496, 9728, 8448, 6912, 4352, 1792, -768, -1280, -1280, -1280, -1280, -1280, 768, 3072, 4352, 4864, 4096, 2816, 1792, 768, -1536, -3840, -6656, -9216, -10752, -12288, -13568, -13824, -12800, -10240, -7936, -5632, -3072, -512, 2816, 4864, 5120, 3328, 1536, 512, -1280, -3072, -5376, -6656, -7424, -7936, -7680, -6912, -5376, -3328, -512, 3072, 6400, 9216, 12288, 14592, 15872, 15360, 13056, 11776, 11008, 9472, 7168, 3840, 768, -2048, -3072, -3584, -3072, -2560, -1792, -1024, 2048, 4096, 5120, 4352, 3584, 2560, 1536, -512, -3072, -6144, -8192, -9984, -11520, -13056, -13824, -13312, -11008, -8192, -5376, -3072, -512, 2816, 5632, 7168, 6144, 3328, 1024, -1536, -3584, -5888, -8192, -9728, -10496, -10752, -9984, -7936, -5120, -2048, 1536, 5376, 9472, 12800, 16128, 17664, 17408, 15616, 14080, 12288, 9984, 7424, 5120, 2304, -1536, -3840, -4352, -3328, -2816, -1792, -1024, 768, 2816, 3328, 4096, 3840, 2560, 1280, 0, -2048, -3840, -6400, -7936, -9472, -10752, -12544, -13312, -11776, -9472, -7680, -5376, -3072, 0, 3584, 6400, 7168, 6400, 3840, 512, -2816, -5632, -7424, -9216, -11264, -12544, -12544, -11008, -8192, -4608, -1280, 3328, 7680, 12800, 16896, 18944, 19200, 18176, 17408, 15616, 12800, 9472, 6656, 3840, 768, -3328, -5632, -5632, -5120, -4096, -3584, -2304, 256, 2304, 2816, 2816, 2304, 2304, 2304, 1536, -768, -3840, -6400, -8192, -9472, -10496, -12800, -13568, -12800, -10496, -7680, -5120, -2048, 1536, 5376, 7936, 8448, 6656, 3840, 0, -3072, -5888, -8704, -11776, -14336, -15360, -13824, -11264, -7936, -4864, -512, 5376, 11264, 16896, 19712, 20736, 20224, 19200, 18432, 16128, 13056, 8960, 5888, 2560, -1024, -4096, -6400, -7168, -6656, -5632, -4096, -3072, -1792, -512, 1024, 2048, 2560, 3584, 3584, 1792, -768, -3072, -5120, -7168, -9216, -10752, -12288, -13568, -13568, -11008, -7936, -4864, -1536, 3072, 6400, 7936, 7680, 6656, 3840, -512, -4352, -7168, -10240, -13312, -15360, -15616, -13568, -10240, -6400, -2304, 2816, 8192, 14336, 18944, 21504, 21760, 20736, 19456, 18432, 15616, 11776, 7424, 3328, -512, -4096, -5888, -7424, -8448, -7936, -6400, -4864, -3584, -2048, 512, 2560, 3584, 4608, 4864, 4352, 2048, 256, -3072, -6144, -8960, -10752, -12544, -13824, -14592, -13568, -11008, -7680, -3328, 1792, 5632, 8192, 8704, 8192, 6656, 2816, -2048, -6144, -10240, -12800, -15360, -16896, -16128, -13568, -9216, -4352, 512, 5888, 11520, 17152, 21504, 23040, 23296, 21760, 19968, 18432, 15872, 11264, 6144, 1024, -2304, -5376, -8192, -9984, -10496, -9216, -7680, -5888, -4352, -2304, 512, 3328, 5888, 6912, 6656, 4864, 3072, 512, -3072, -6656, -9728, -12032, -13824, -15104, -15104, -13568, -10496, -5888, -1280, 3584, 7168, 9216, 9216, 7936, 5376, 1536, -3328, -7936, -11776, -14848, -16896, -17920, -16640, -12800, -7168, -1792, 3584, 8960, 14848, 19456, 22784, 24576, 24064, 23040, 20992, 18432, 13824, 8960, 4096, -1280, -5376, -7936, -10240, -12288, -12032, -9728, -7168, -5120, -3328, 256, 3840, 7168, 8448, 8448, 6912, 4608, 2048, -1536, -5376, -9472, -13312, -16384, -16896, -16640, -14848, -12032, -7680, -2304, 3328, 7168, 9728, 11008, 10240, 7936, 3840, -1280, -6144, -10240, -14592, -17664, -19200, -18944, -16640, -12288, -6656, -512, 6144, 12032, 16896, 21248, 24832, 26112, 26112, 25856, 23296, 18688, 13056, 7168, 1792, -3840, -8448, -11520, -14336, -15360, -13824, -10752, -7168, -4352, -1024, 3328, 6656, 9216, 9728, 9216, 7424, 4096, 512, -3584, -8704, -13312, -15872, -16896, -16640, -16128, -13568, -9216, -3840, 2304, 6912, 9216, 10496, 10240, 8960, 6400, 2048, -4096, -9472, -14080, -17408, -19712, -20736, -19200, -15360, -9472, -3072, 3072, 8960, 14592, 19200, 24064, 26880, 27392, 26368, 24832, 21504, 16384, 10496, 4608, -1536, -6400, -10240, -13056, -14592, -14336, -11776, -8192, -4864, -1536, 1792, 5120, 7680, 8704, 8192, 6144, 3072, 0, -4352, -8448, -12032, -15360, -16640, -16384, -14848, -11776, -7936, -3072, 2048, 6656, 9472, 11008, 11264, 10496, 7168, 2816, -3072, -7936, -12544, -17152, -20736, -22272, -21760, -18432, -13312, -7680, -1536, 5376, 11520, 17664, 22272, 25856, 28160, 28928, 28160, 25600, 19712, 13056, 6912, 2048, -2816, -8192, -12544, -15104, -15104, -13568, -10496, -6912, -2816, 768, 3584, 6144, 7168, 7168, 6144, 4352, 1280, -3840, -8192, -11520, -13824, -15616, -14848, -13824, -11264, -8192, -3328, 2048, 6656, 9472, 10496, 10240, 9216, 7424, 4096, -768, -6144, -12032, -16896, -20736, -22784, -22528, -19456, -14848, -9472, -4096, 2560, 8704, 14848, 19968, 24064, 27136, 28416, 27392, 24832, 20736, 14848, 9472, 4352, 0, -4352, -8448, -11520, -13056, -12288, -9728, -6656, -3584, -768, 2304, 4096, 4864, 4352, 3584, 2560, 0, -3840, -7680, -10752, -12544, -13312, -12544, -11264, -9472, -6400, -2048, 2304, 5376, 7424, 8192, 8960, 8448, 7424, 4864, 256, -4608, -9728, -14848, -19200, -21760, -21760, -20224, -17920, -13312, -7424, -1536, 5120, 11264, 17152, 22784, 25856, 28160, 29184, 27392, 23808, 18432, 12544, 7168, 2560, -2304, -6400, -9728, -12288, -12544, -10752, -7936, -5120, -2816, 0, 2304, 3328, 3072, 1792, 1280, 0, -2816, -6144, -9216, -10752, -11264, -11008, -9728, -7168, -4096, -1024, 2048, 4096, 5632, 7424, 7680, 7424, 6144, 3328, 512, -3584, -8192, -13056, -17408, -20224, -21248, -19712, -17664, -14336, -10496, -4864, 1536, 7936, 13568, 18944, 23040, 25856, 27648, 27904, 25856, 21248, 15360, 9728, 6144, 2304, -2560, -6400, -9216, -10240, -9472, -7424, -5376, -3328, -2048, 0, 768, 0, -1280, -1536, -2048, -4096, -6912, -8960, -9984, -10240, -8448, -6912, -5376, -2816, 768, 3584, 5376, 6144, 6912, 6656, 5632, 4864, 3328, 768, -3584, -8192, -13568, -16896, -18944, -20480, -20480, -19200, -16128, -12032, -7168, -1024, 4864, 10496, 16896, 21760, 25344, 26880, 27136, 26624, 24320, 19456, 13056, 7424, 3328, 512, -3072, -6912, -9216, -9728, -8192, -5632, -3840, -3072, -2048, -768, -1024, -2304, -3072, -3584, -4608, -6656, -7936, -8960, -9216, -7424, -5120, -2560, -512, 1792, 4096, 6400, 6400, 6144, 4864, 3840, 2560, 1024, -1024, -4096, -7680, -11264, -14592, -17152, -18688, -19200, -17920, -15360, -12288, -8704, -4096, 1280, 6912, 13056, 18176, 21760, 23552, 25344, 25856, 24320, 20992, 16384, 11264, 7168, 3584, 256, -3072, -5632, -7168, -6912, -5632, -4608, -4352, -3840, -3840, -3840, -5376, -5888, -6400, -6144, -6912, -7936, -8704, -7680, -5376, -1536, 1792, 3328, 4352, 5632, 6912, 7168, 6144, 4096, 1792, -768, -2560, -4352, -6912, -8960, -11008, -12800, -14848, -17408, -17920, -16640, -13568, -10752, -8192, -5632, -1024, 3840, 9216, 13824, 17920, 21248, 22784, 23552, 23296, 20992, 17408, 13824, 10752, 7424, 3584, 512, -2304, -4352, -5376, -5632, -5120, -5376, -5120, -5888, -6656, -7680, -8192, -8192, -7424, -6912, -7168, -7680, -6656, -3840, 0, 3840, 6400, 6400, 6400, 6656, 6912, 5376, 2816, 0, -2304, -4352, -6144, -7680, -9728, -11520, -12032, -12544, -14080, -15104, -14336, -12288, -9984, -7168, -5120, -2304, 1792, 6656, 11264, 14080, 16640, 18432, 20224, 20480, 19712, 16896, 14592, 12544, 10496, 7680, 4864, 1792, -512, -1792, -3072, -4352, -5632, -6400, -7424, -8448, -9216, -9984, -10496, -9216, -7424, -6656, -6656, -5632, -2816, 512, 4352, 7168, 8192, 7936, 7424, 7168, 5888, 2816, -512, -2304, -4352, -6144, -9216, -11264, -12288, -12544, -12800, -13568, -13824, -13824, -12032, -9216, -6400, -4352, -1792, 1792, 5376, 9216, 12032, 14080, 16128, 17920, 18432, 17664, 15360, 13312, 11776, 10752, 8704, 5888, 3840, 2048, 768, 0, -1792, -3584, -5376, -6144, -6912, -8192, -9984, -11264, -11008, -9472, -7424, -6400, -5888, -4096, -512, 3584, 6656, 8192, 8448, 8192, 7680, 6400, 4096, 1024, -1536, -4096, -6400, -9216, -11520, -12800, -13824, -13056, -13056, -13824, -13824, -12288, -9216, -5888, -3840, -1536, 1280, 4352, 7936, 10752, 13056, 15104, 15872, 16128, 15616, 14336, 13056, 11008, 10240, 9728, 7168, 5120, 3328, 2304, 1792, 512, -2048, -4096, -5888, -6912, -7936, -9216, -10240, -11008, -9984, -7936, -5888, -5120, -3840, -1024, 2816, 6144, 7936, 8192, 7936, 7680, 6400, 4352, 1792, -768, -3328, -5888, -9216, -12288, -14336, -14848, -14592, -13568, -12800, -13312, -13056, -10240, -6400, -3072, 0, 1792, 4096, 6400, 9216, 12544, 14848, 15360, 15104, 14592, 13824, 12544, 11008, 9216, 7936, 6656, 4608, 3328, 2560, 1536, 1024, 0, -1536, -3072, -4864, -5632, -6656, -7936, -8960, -8960, -8192, -6912, -5632, -4096, -1792, 1024, 3328, 5376, 6656, 7680, 7424, 6912, 5632, 3840, 1024, -1792, -4864, -7936, -11264, -14080, -15104, -15104, -14848, -13824, -13312, -12544, -10496, -7168, -3584, 0, 2560, 4608, 6656, 8448, 11264, 12800, 13568, 13056, 12800, 12288, 11776, 10496, 9472, 7680, 6144, 5376, 4608, 3840, 3328, 2048, 1024, 0, -1536, -2304, -3584, -4864, -5888, -6912, -8448, -8448, -7936, -6400, -4864, -2816, -768, 768, 2816, 5120, 7168, 7936, 7168, 5632, 3584, 2048, -768, -3840, -7424, -10240, -12544, -14592, -15872, -15360, -14336, -12800, -12032, -10752, -8192, -4608, -768, 2816, 5120, 6400, 7424, 8960, 11008, 12544, 13056, 12032, 11008, 10496, 9472, 8448, 7424, 6144, 4608, 3840, 3584, 3328, 2816, 2048, 1280, 256, 0, -1280, -2816, -4864, -5888, -6144, -6400, -6400, -6656, -5632, -3840, -2304, -768, 1024, 3072, 4864, 6400, 6656, 6144, 4352, 2816, 512, -2816, -6656, -9472, -11520, -13568, -14848, -15104, -14592, -13568, -12032, -10752, -8960, -6400, -2560, 1280, 3840, 4864, 5632, 7424, 9472, 11520, 12288, 12032, 11264, 11264, 11008, 10240, 8448, 6144, 4864, 3584, 3328, 3072, 2048, 512, -512, 256, 256, 256, -1024, -3072, -3840, -3584, -3328, -3584, -4608, -4608, -3840, -3072, -2048, -1280, 512, 2560, 4608, 5376, 5120, 3840, 2560, 768, -1792, -4608, -7936, -10752, -12032, -12800, -13568, -14592, -14592, -13056, -10752, -8704, -6400, -3840, -1280, 1792, 4096, 5632, 7680, 8960, 10240, 11008, 10752, 9984, 9984, 9728, 9728, 7936, 5632, 4096, 3584, 3840, 4352, 4096, 3072, 1536, 1024, 1280, 1792, 1536, 0, -2048, -3072, -3328, -3840, -4864, -5376, -5120, -4352, -3584, -2816, -1536, 512, 2560, 4608, 5376, 5376, 4864, 2816, -512, -4352, -7424, -9472, -10752, -11776, -13312, -14080, -14848, -13312, -10752, -8704, -6144, -3840, -1280, 1280, 3072, 4352, 6144, 8192, 9472, 9472, 9216, 8448, 8448, 8960, 8960, 8192, 6656, 5632, 4096, 4352, 4864, 4864, 3584, 1792, 1280, 1280, 1536, 1280, 0, -1792, -2560, -2304, -1536, -1792, -3328, -4352, -3840, -2816, -2048, -1792, -1536, 256, 1792, 3072, 3328, 2816, 1792, 0, -3072, -6400, -8960, -10240, -10752, -11008, -11264, -12032, -12544, -11008, -8704, -5632, -3072, -1792, 0, 1024, 2304, 4352, 6400, 7936, 8448, 8448, 7936, 7680, 6912, 7168, 7680, 7424, 6400, 5120, 4352, 5120, 6144, 5632, 4352, 2816, 2560, 2304, 2304, 1280, -1536, -2816, -3328, -2304, -1280, -2304, -4096, -4864, -4096, -2304, -1536, -1536, -512, 1024, 2048, 2816, 2816, 1536, -1024, -2816, -5376, -8704, -9984, -10496, -10240, -9728, -10240, -11264, -9728, -7168, -4352, -2560, -1536, -1280, -768, 768, 2560, 3840, 4352, 5120, 5888, 6656, 6400, 6144, 6656, 7168, 7680, 7680, 7168, 6400, 6144, 5888, 6400, 5632, 4608, 3584, 2304, 1280, 0, -1792, -3072, -3328, -3072, -1792, -1536, -2304, -3072, -2560, -1024, 512, 512, 768, 768, 768, 1536, 1792, 768, -2304, -5376, -7168, -8960, -10240, -10240, -9472, -9472, -9216, -9216, -7424, -5632, -2816, -768, 512, 768, 0, 256, 768, 1536, 2304, 2560, 2560, 2560, 3328, 4096, 5376, 6144, 7424, 7936, 8448, 8448, 8448, 8192, 7680, 6912, 5888, 4096, 3072, 1792, -512, -1792, -3584, -4864, -4096, -2560, -1280, -1792, -2304, -2304, -1536, 512, 1536, 2048, 1792, 1024, 768, 256, -768, -2304, -4096, -6400, -8704, -9984, -10496, -9472, -8448, -7936, -7936, -7424, -5632, -3072, -1024, 512, 1792, 1280, 256, -512, 0, 1024, 1024, 512, 512, 1280, 2560, 3584, 4864, 6144, 7168, 8192, 9216, 9728, 9216, 8704, 7936, 6912, 5888, 4608, 2816, 768, -1280, -3072, -3840, -3840, -2816, -1536, -1280, -1536, -2048, -1792, -768, 256, 1024, 1536, 768, -512, -1792, -2304, -3072, -4864, -6144, -7680, -8704, -9216, -8960, -8192, -7424, -6656, -5632, -4096, -2560, -768, 1024, 2048, 2304, 1024, 0, -768, 0, 256, -1280, -1792, -1280, 256, 1792, 3328, 3584, 4352, 6912, 8960, 9728, 9472, 8960, 8448, 7936, 7424, 6400, 4864, 2816, 768, 0, -1536, -2560, -2560, -1792, -1280, -1280, -1792, -1792, -1536, -768, 256, 1024, 768, 0, -2048, -3840, -4608, -5120, -5888, -6912, -7680, -8192, -8448, -7424, -7168, -6400, -5120, -4096, -3328, -1536, 256, 1536, 1792, 1024, 0, -1280, -1280, -1280, -1536, -1792, -1536, -512, 1280, 2560, 3840, 5120, 6400, 8192, 8704, 8704, 8704, 8192, 7424, 6144, 5632, 4864, 3584, 2304, 1536, 1024, 512, 0, 0, 512, 512, -512, -1024, -1536, -1280, -1280, -1024, -1024, -1792, -3072, -4864, -6400, -6656, -6656, -6656, -6656, -7424, -7168, -7168, -6400, -5632, -4608, -3584, -2560, -1280, 0, 768, 1024, 1280, 1024, 768, -512, -1792, -2560, -3072, -2304, -1536, 0, 1536, 2816, 3584, 4096, 5632, 7680, 8448, 8704, 7424, 6400, 5888, 5376, 5632, 5632, 5120, 4608, 4096, 3584, 3328, 2816, 2816, 2816, 1536, -1024, -3072, -4096, -4352, -4096, -3328, -4096, -5632, -6656, -7680, -7680, -6400, -5376, -4608, -4352, -4864, -4608, -5120, -4864, -3840, -3328, -2304, -1792, -1536, -1280, -512, 768, 1280, 1024, 0, -1280, -2048, -1536, -1536, -1536, -512, 1024, 2304, 2816, 3328, 3840, 4864, 5888, 6400, 5632, 4864, 4096, 4352, 5120, 5376, 5632, 5888, 6144, 6400, 6144, 5888, 5632, 5376, 4096, 1792, -1024, -3584, -5376, -5888, -6144, -6144, -7168, -8704, -9728, -9216, -7936, -5376, -3328, -2304, -2048, -2560, -2816, -3072, -3584, -3328, -3072, -2304, -2560, -3072, -2816, -2304, -1024, 768, 1024, 256, -768, -1024, 256, 1024, 1792, 2560, 2560, 2816, 3072, 2816, 2048, 2304, 2816, 3328, 2816, 1280, 1024, 2816, 5120, 6656, 7424, 8192, 8960, 9984, 9984, 8704, 7680, 5888, 3840, 1280, -2560, -5888, -7936, -8704, -8192, -8448, -9472, -10752, -10496, -8192, -5376, -2816, -1536, -768, -768, -1536, -2048, -2816, -3584, -3840, -3584, -3584, -3584, -4864, -5120, -3840, -1792, 0, -512, -768, 0, 1024, 2560, 4352, 4864, 4608, 4608, 5120, 4608, 2816, 1280, 256, -512, -1024, -1792, -2048, -1024, 1024, 3584, 6144, 8192, 9728, 11776, 13056, 13312, 11776, 9472, 7168, 4864, 1280, -3072, -7424, -9984, -11264, -11776, -11776, -12800, -12288, -9984, -7424, -3584, -1024, 1536, 2304, 2048, 1536, 0, -2048, -3328, -3840, -4608, -5632, -7168, -7680, -6656, -4608, -2304, -1792, -1024, 512, 2560, 4608, 6144, 6656, 6656, 5888, 5632, 5376, 3584, 768, -1280, -2304, -3584, -4096, -4096, -2816, -1024, 1536, 3584, 6144, 9472, 12800, 14848, 14848, 13568, 11520, 9216, 7168, 4352, 256, -4608, -9216, -12032, -13568, -13824, -13568, -13056, -11008, -8448, -5120, -2048, 1280, 3840, 4352, 3328, 1280, -1024, -3072, -3584, -4608, -5888, -7680, -8704, -8192, -6144, -3840, -2560, -1536, -768, 1792, 4608, 6912, 8192, 8448, 7680, 7168, 6144, 4864, 3072, 512, -2560, -4608, -6144, -6656, -5888, -4096, -1536, 1024, 3072, 6400, 9984, 13568, 15360, 15360, 14848, 13056, 10752, 7680, 4096, 0, -5120, -9472, -12544, -14592, -15616, -14592, -12800, -10240, -7424, -4352, -1024, 2304, 4352, 4352, 2816, 1280, -768, -2048, -3328, -5376, -7680, -8960, -8704, -7424, -5632, -4096, -2816, -1536, 256, 3072, 6144, 8704, 9984, 9984, 8960, 7168, 5376, 4096, 2048, -768, -4096, -7424, -8960, -8704, -6656, -4096, -2304, 256, 3584, 7680, 11776, 14336, 15360, 15872, 15104, 14592, 11776, 8192, 3840, -512, -4352, -8960, -13056, -15616, -15616, -14080, -11776, -9984, -7680, -4864, -1024, 2560, 3584, 3328, 1792, 768, -512, -1536, -3840, -6144, -7936, -8448, -7936, -6656, -5888, -4864, -2816, -512, 1536, 4352, 7680, 9728, 10496, 9984, 8704, 6400, 4608, 3584, 1536, -2304, -6144, -8704, -9728, -8704, -7168, -4608, -2304, 0, 3584, 8192, 11264, 13312, 14848, 16128, 16896, 15104, 11520, 7936, 4608, 1024, -4352, -9216, -13568, -15360, -15104, -13824, -11776, -9984, -7680, -4608, -768, 1536, 2048, 1536, 768, 256, -768, -2816, -5632, -7424, -7168, -5888, -5120, -5120, -4608, -2560, -512, 1792, 4352, 6912, 8704, 9472, 9728, 8448, 6656, 4864, 3840, 2816, 0, -4352, -7936, -9984, -10240, -8704, -6912, -5120, -2816, 256, 4096, 7936, 11008, 13312, 15104, 17152, 17920, 15872, 12032, 8192, 4864, 1024, -4608, -9984, -13568, -15360, -14592, -13056, -11264, -9472, -7680, -4352, -1536, 256, 512, 256, 0, -512, -1792, -3840, -5888, -6912, -6400, -4864, -4096, -3840, -3072, -1024, 1280, 3840, 6400, 8448, 9472, 8704, 7936, 6912, 5632, 4352, 2816, 512, -2816, -6400, -8960, -10496, -10496, -8704, -5888, -3328, -1024, 1536, 4608, 7936, 11008, 13824, 15616, 16640, 15872, 13568, 11264, 8704, 5632, 512, -5120, -9728, -12032, -12800, -12032, -11008, -10752, -10496, -8192, -4864, -3328, -2816, -2560, -1792, -1280, -1280, -2304, -3584, -4608, -4352, -3072, -2304, -2048, -1536, 256, 1536, 3072, 4096, 5376, 6400, 6400, 5888, 4864, 4608, 3584, 2816, 2048, 0, -2560, -5888, -8704, -9216, -8192, -6144, -4096, -3072, -1536, 1024, 3840, 7680, 10752, 13312, 15104, 15360, 14848, 13568, 11776, 9984, 6912, 1280, -4864, -8960, -11008, -11264, -11008, -11520, -12544, -12288, -9984, -7936, -6912, -6144, -4864, -2816, -1536, -768, -1024, -1536, -2048, -1280, 768, 1280, 1792, 1536, 1792, 2304, 3072, 3328, 3840, 3584, 3072, 2816, 2816, 2304, 2048, 1280, 1024, 0, -3072, -5632, -7168, -6656, -5376, -4352, -3328, -2560, -1280, 1024, 3584, 5632, 8192, 11264, 14336, 15616, 15104, 14336, 12288, 9728, 6400, 1792, -2560, -6144, -8448, -9728, -11264, -12800, -13056, -12032, -10496, -10496, -10496, -9472, -6656, -3584, -1536, 0, -512, -768, 1280, 3328, 4864, 5376, 4096, 3072, 2304, 2304, 2560, 1792, 768, 512, 512, 256, -512, 0, 768, 1024, 256, -1024, -3072, -4096, -4096, -2304, -2304, -2560, -2304, -1280, 512, 1792, 2816, 4352, 6912, 9984, 13056, 13824, 13312, 13312, 12544, 10752, 7168, 2560, -1024, -3840, -6400, -9216, -12288, -14336, -14848, -14336, -13312, -13568, -13824, -11520, -7168, -2816, -512, 768, 2048, 3840, 6144, 7680, 8704, 7680, 5632, 4096, 3072, 1536, -1024, -2304, -2304, -2048, -3072, -3584, -3072, -1280, 768, 1024, 512, -768, -1024, 0, 768, 512, -1024, -1536, -1536, -1280, -1024, -1280, -768, 2048, 5376, 9216, 11264, 12800, 14080, 14848, 14080, 11520, 8448, 5120, 1280, -2816, -6912, -11008, -14080, -15360, -15616, -15872, -16384, -16896, -14848, -10240, -5120, -1536, 768, 2048, 4096, 6656, 8704, 9984, 9728, 7680, 5376, 2816, 512, -2304, -3584, -3328, -3328, -3840, -4096, -3584, -1536, 256, 1024, 1024, 768, 1024, 1792, 2560, 2560, 1280, -768, -1792, -2048, -2304, -3072, -3584, -2816, 0, 3328, 7168, 10240, 13056, 14848, 15616, 15360, 14336, 12032, 8448, 3840, -2048, -7168, -11264, -14080, -15872, -18432, -20736, -21248, -18944, -14848, -9984, -5376, -1536, 2048, 4608, 7680, 10240, 12032, 12544, 11264, 8448, 4864, 1536, -1536, -3584, -4864, -5888, -6656, -6144, -4864, -3328, -1280, -512, 512, 1280, 2048, 2816, 3584, 3328, 2304, 512, -1024, -2048, -3072, -3840, -4864, -4608, -3328, -768, 3584, 7680, 11264, 13568, 15872, 16896, 16896, 15104, 12288, 8448, 3072, -2560, -7936, -11776, -14848, -18176, -20224, -21504, -20736, -18176, -13824, -8704, -3584, 256, 3584, 6656, 9472, 11264, 12288, 12544, 10496, 7424, 3072, -768, -3328, -4352, -4864, -6144, -6656, -5632, -4096, -2048, -768, -512, 768, 1536, 2560, 3328, 3072, 2560, 1536, 512, -1024, -2816, -4608, -5632, -5632, -4864, -3584, -768, 3328, 7680, 11776, 15616, 17408, 18176, 17920, 16384, 13312, 8192, 2560, -3072, -7936, -13056, -17152, -20736, -22528, -23296, -21504, -17664, -13056, -8192, -3072, 2048, 6400, 9472, 11008, 12032, 13312, 12800, 10240, 5888, 1280, -2048, -3328, -4608, -5888, -7168, -6656, -4864, -3072, -1536, -1024, -512, 512, 1536, 2816, 2816, 1280, 768, 1024, 256, -2304, -4352, -5376, -5888, -5632, -4864, -3584, 0, 4352, 9472, 13824, 16640, 17920, 19200, 19456, 17152, 12800, 7680, 1536, -3840, -8960, -14336, -19200, -22528, -23808, -22528, -19968, -16384, -12032, -6656, -768, 4352, 7936, 9472, 10752, 11776, 12288, 10752, 6912, 2560, 0, -768, -1792, -3584, -5376, -5376, -3328, -1024, 256, -512, -768, 256, 1280, 1792, 1024, -768, -2048, -1792, -1792, -3584, -4864, -5632, -5888, -5376, -5120, -4096, -1536, 3072, 8192, 13056, 16128, 17920, 19456, 19968, 19200, 16128, 11264, 5120, -1280, -6656, -11776, -17152, -21248, -24064, -23808, -21248, -17664, -14080, -10240, -4352, 2048, 6400, 8704, 9728, 11008, 12288, 11520, 8960, 5120, 2048, 512, 768, -512, -3072, -4608, -3840, -2048, 0, 0, -1280, -1536, -1024, -768, -1280, -2816, -3840, -3584, -3072, -3328, -4096, -4864, -5120, -5120, -4096, -2560, -512, 2816, 6144, 10752, 14592, 16384, 17920, 18688, 18432, 16384, 12288, 6656, 1024, -3840, -8960, -12800, -17408, -20736, -22528, -20736, -17408, -14080, -11264, -7424, -2560, 2304, 5632, 6400, 7680, 9472, 9728, 8960, 6144, 3584, 2816, 3328, 3584, 2304, 0, -1280, -768, 768, 1024, -512, -2560, -3840, -3840, -3840, -4864, -6400, -6144, -5120, -4608, -4864, -5120, -4608, -4096, -3328, -2304, 256, 3072, 6400, 9472, 13568, 16128, 17664, 18944, 18688, 17664, 14336, 9472, 3840, -1536, -6400, -10752, -15104, -19200, -20992, -20736, -18432, -15616, -12800, -8960, -4352, -512, 3328, 5120, 6912, 7936, 8704, 8704, 7168, 4864, 3584, 3328, 3840, 3584, 2048, 1024, 768, 1280, 1280, 256, -1536, -3840, -4608, -5632, -6912, -8448, -8704, -7936, -6400, -6144, -5120, -4864, -4352, -2560, -512, 2304, 4608, 7168, 9984, 13056, 15360, 17152, 18176, 18432, 17152, 13568, 8960, 4096, -1024, -5376, -10240, -14592, -17920, -19456, -18944, -16640, -14080, -11264, -8704, -5376, -1792, 1536, 3840, 4608, 5120, 6144, 6144, 5376, 4096, 3840, 4096, 4352, 4352, 4096, 3328, 3072, 3328, 3328, 2304, 0, -3072, -4352, -5632, -7936, -10240, -11008, -10240, -8960, -7680, -6656, -6144, -5120, -2816, -512, 2304, 4864, 7424, 9984, 11776, 13824, 15360, 16896, 17152, 16896, 14848, 10496, 5376, 1280, -2816, -7424, -12032, -15872, -17408, -17408, -16640, -14592, -12544, -9984, -6912, -3328, -512, 1536, 2816, 4608, 5888, 6144, 5376, 4864, 4864, 5376, 5376, 4608, 3840, 2816, 3328, 3840, 3840, 2560, -512, -2048, -3584, -5376, -7680, -9984, -11264, -11264, -10240, -8448, -7424, -6912, -5376, -3072, -768, 1536, 4096, 7168, 10240, 12288, 13824, 14336, 15104, 15616, 15872, 14592, 11264, 7168, 3072, -768, -5632, -10240, -14080, -16384, -16128, -15616, -14336, -13056, -10496, -7424, -3840, -1536, 256, 2048, 3840, 5120, 5120, 4608, 4352, 4608, 5888, 5888, 5120, 4352, 3840, 4608, 5120, 5120, 3840, 1024, -1280, -2816, -5120, -8192, -11008, -12544, -12288, -11008, -9216, -8192, -7424, -5376, -3328, 0, 2816, 5120, 7680, 9728, 11776, 12800, 13056, 13568, 14336, 13568, 12288, 10496, 7680, 4864, 1280, -2560, -6656, -10752, -12800, -14336, -14592, -14336, -13568, -11776, -9728, -6912, -4608, -2560, -512, 2048, 4096, 4864, 6144, 6144, 5632, 5888, 6400, 5888, 4352, 4096, 3840, 4096, 3584, 2560, 768, -1280, -2816, -5120, -7168, -8960, -10752, -11264, -10752, -8960, -7424, -6400, -4864, -2816, 0, 2560, 5120, 6656, 7936, 9728, 11520, 12288, 11776, 11776, 11264, 10496, 9472, 7680, 5632, 3328, 256, -3840, -6912, -9216, -11264, -12544, -13056, -13312, -12544, -11264, -9472, -6912, -5120, -3072, 256, 2560, 4864, 5888, 7168, 7424, 7168, 7168, 6144, 4864, 4352, 4096, 3840, 3584, 2560, 1024, -768, -2560, -3840, -5888, -7936, -9216, -10496, -10496, -9984, -8192, -6144, -4864, -2816, -768, 1280, 3840, 6144, 7936, 9216, 10752, 11520, 11264, 10496, 9472, 8448, 7936, 7424, 5888, 3584, 512, -2048, -4096, -5632, -7936, -10240, -11264, -11776, -11776, -11776, -11264, -9472, -7168, -5120, -2560, 512, 2816, 5120, 7168, 8192, 8192, 7424, 6656, 5632, 4864, 4352, 3584, 3072, 2816, 2048, 512, -1280, -3584, -5120, -6144, -7680, -8704, -9472, -9728, -9216, -7680, -5376, -3584, -1536, 512, 2816, 4864, 6656, 7680, 8704, 10496, 11264, 10752, 9728, 8192, 6912, 6400, 6144, 5376, 2816, 256, -2304, -4096, -6400, -8704, -10240, -11008, -11520, -12288, -12800, -12544, -10240, -6912, -3840, -1536, 1024, 3840, 6912, 9216, 10240, 9472, 8192, 6912, 5632, 3840, 2816, 2560, 2048, 1536, 0, -2048, -3584, -4096, -4352, -4608, -6144, -7936, -8448, -8448, -6912, -5632, -4352, -2560, -1024, 1536, 3328, 4352, 5632, 6912, 8448, 9728, 9984, 9472, 8960, 8448, 7936, 6912, 5888, 4864, 2816, 768, -1792, -5120, -7680, -9728, -10752, -10752, -11776, -13568, -14848, -13568, -10496, -6912, -3328, -512, 2560, 4864, 7680, 9984, 11008, 9728, 7424, 5888, 4608, 3072, 2048, 1536, 1536, 1024, -768, -2048, -3072, -3328, -2560, -3072, -4352, -6144, -6400, -5888, -5888, -5888, -4864, -3072, -1024, 512, 1280, 2304, 3584, 5632, 8192, 9472, 9984, 9984, 9472, 9472, 8448, 7168, 6912, 5376, 3072, 0, -3584, -6400, -8448, -9728, -11008, -12288, -13824, -15360, -15104, -12288, -9216, -5120, -2048, 512, 3072, 6656, 9984, 11264, 10240, 8192, 6912, 5888, 4096, 2048, 768, 768, 512, 256, -1024, -2304, -2304, -1536, -1536, -2048, -3328, -4096, -4608, -5376, -5632, -5376, -4096, -1792, -512, 0, -512, 512, 3328, 6400, 7680, 8704, 8704, 8704, 8704, 8448, 8448, 7936, 6656, 5376, 2816, -768, -3840, -6400, -7936, -9472, -12288, -14592, -15872, -16128, -14336, -11776, -8960, -6400, -3072, 1280, 4608, 8192, 10240, 10240, 9216, 8192, 7424, 5632, 3840, 1792, 768, 0, 0, 0, 256, -512, -512, 0, 0, -768, -1024, -1792, -3328, -5632, -7168, -6400, -4352, -2560, -2560, -2816, -2560, -1024, 3072, 6656, 9216, 9984, 10240, 10496, 10240, 9472, 8960, 8448, 7168, 4864, 768, -2816, -5632, -7680, -9472, -11776, -14336, -16128, -16640, -15104, -13312, -11008, -7424, -4352, -1024, 2560, 5888, 8192, 9216, 9216, 8704, 7424, 6144, 4864, 3072, 1280, -512, 0, 1024, 1792, 2560, 2304, 1536, 1280, 1280, 1280, 0, -2560, -5120, -6656, -7424, -6656, -5120, -4608, -4864, -4352, -2304, 768, 4096, 7168, 9216, 10240, 10752, 11008, 10496, 10240, 9216, 8448, 6656, 4096, 768, -2560, -5376, -7936, -10752, -13568, -15616, -16640, -16128, -14848, -13312, -10496, -7936, -4608, -1024, 2304, 5376, 6656, 7424, 7680, 7936, 7936, 7168, 5376, 3072, 1536, 1280, 2560, 3328, 3328, 3584, 2304, 2048, 1792, 1280, 0, -2048, -4352, -6144, -7168, -6912, -5888, -4352, -3584, -3072, -2048, 512, 3840, 6656, 8192, 9216, 9984, 9728, 9472, 9216, 8448, 7168, 5376, 4096, 2560, 256, -3328, -6400, -8704, -10496, -12800, -15104, -15872, -15872, -13568, -11264, -9472, -7168, -4864, -1536, 1792, 3584, 4608, 5632, 6656, 7168, 7168, 5376, 3328, 1536, 1536, 3840, 4864, 5376, 5120, 5120, 4608, 4096, 3328, 1792, -768, -3072, -5376, -6912, -7936, -7680, -6144, -3840, -2816, -2048, 0, 2560, 5888, 7424, 8192, 8704, 8704, 8704, 8448, 8192, 6912, 5888, 5120, 4352, 2560, -512, -3840, -6400, -8704, -11008, -13312, -15616, -16128, -14848, -12544, -11008, -10496, -8448, -5632, -2304, 768, 2816, 4352, 5376, 6656, 7680, 7168, 5888, 4352, 3840, 4608, 5632, 5632, 5120, 5376, 5376, 4608, 3072, 1024, -1280, -2816, -4096, -5632, -7168, -8192, -6144, -3584, -1792, -1280, 256, 2816, 5120, 6912, 7680, 6656, 6400, 7424, 7680, 7424, 5632, 4352, 4608, 5632, 5120, 2304, -2048, -4608, -6400, -7936, -10240, -13568, -15360, -14848, -13824, -11776, -11520, -10752, -8192, -5120, -2560, -512, 1280, 3072, 4864, 6400, 6912, 5632, 4608, 4608, 5376, 6144, 6400, 5632, 6144, 6656, 6912, 5632, 2560, 0, -1792, -2304, -3072, -5376, -7168, -7168, -5120, -2304, -1024, -512, 1280, 3584, 5632, 6144, 5376, 3840, 4608, 6144, 7168, 6144, 4864, 5376, 6656, 7680, 5632, 1792, -1536, -3840, -5888, -8704, -12800, -15616, -16896, -15616, -13312, -12800, -12544, -11520, -9216, -5632, -2560, 256, 2816, 3840, 5120, 6656, 6656, 6144, 5376, 5376, 6912, 7168, 6144, 5376, 5632, 6656, 6144, 4096, 1280, -1280, -1792, -1280, -2816, -4352, -5632, -4352, -1792, 0, 256, 1024, 2304, 4096, 4864, 4608, 3328, 3072, 4096, 5632, 6144, 5888, 5888, 7168, 8448, 6912, 4096, 512, -3072, -5888, -8448, -11520, -14592, -16384, -16384, -14080, -13056, -13312, -12544, -9984, -6400, -3328, -1536, 256, 1536, 3072, 4096, 4608, 5120, 4608, 5120, 6400, 7168, 7168, 7424, 7936, 9216, 9472, 7168, 3840, 1792, 768, 0, -1024, -3584, -5376, -5888, -4096, -1792, -1024, -768, 256, 2560, 4096, 4352, 2560, 1792, 2304, 4608, 6144, 6144, 6144, 7168, 8704, 8704, 6656, 3072, -768, -3840, -6656, -10240, -13568, -15616, -16640, -15872, -15104, -14592, -14080, -12544, -9984, -6912, -4608, -1536, 768, 2048, 3584, 4352, 5376, 6400, 6656, 6912, 7168, 7680, 8192, 8192, 7936, 8192, 7168, 5632, 3584, 1536, 768, 0, -768, -2048, -3072, -3072, -1280, 0, 512, 256, 768, 1536, 2816, 2816, 1792, 1024, 1536, 3328, 5120, 6144, 7168, 7936, 8192, 7168, 4864, 1792, -1792, -5120, -8192, -11264, -13568, -14848, -14848, -14080, -13824, -13568, -12800, -11776, -10240, -6912, -3584, -1536, -1536, -1280, 0, 2048, 4096, 5120, 5888, 6400, 7680, 9472, 10752, 11008, 10496, 9984, 8704, 7168, 4608, 2304, 1024, 768, 0, -2560, -3328, -3072, -2560, -1280, 256, 256, 0, 1024, 2048, 1792, 1280, 1536, 2816, 4864, 5888, 6912, 8192, 8448, 6912, 5120, 2560, 0, -3840, -7680, -10496, -12544, -13312, -13824, -14080, -14080, -13568, -12800, -11520, -10240, -8192, -6144, -4096, -2816, -2560, -2048, -768, 1536, 3328, 4352, 5376, 7424, 9472, 11008, 12288, 12032, 11008, 9728, 8960, 7680, 4864, 2816, 1792, 512, -1280, -2304, -2304, -1280, 256, 256, 0, -512, 256, 768, 1536, 1280, 1024, 1280, 2560, 4096, 5120, 6144, 6912, 6400, 4608, 2560, 768, -2304, -5376, -7936, -9984, -11264, -12032, -12032, -11264, -11776, -12288, -12288, -11520, -9984, -9216, -7680, -6656, -6400, -5888, -4864, -2304, 1024, 3584, 6144, 8192, 10496, 12288, 13824, 14336, 14592, 13312, 12032, 10240, 7168, 4352, 2560, 1024, -768, -2048, -2560, -2048, -1536, -1280, -1280, -1280, -768, 0, 768, 1024, 1024, 1280, 1792, 3072, 4864, 6656, 6912, 6144, 4608, 3072, 1280, -768, -3072, -6144, -8704, -11008, -11776, -12288, -12288, -11776, -11776, -11520, -11264, -10752, -9728, -8448, -7424, -6656, -6656, -5632, -3584, -1280, 1280, 3328, 5888, 8192, 10240, 12032, 13312, 14336, 14592, 14080, 13312, 12032, 9216, 6912, 4864, 2816, 768, -1280, -1536, -2048, -2560, -3328, -3840, -3584, -3328, -2816, -1536, 256, 1024, 1792, 2816, 4352, 5376, 6656, 7168, 6656, 4864, 2560, 512, -1792, -4352, -6656, -9216, -10496, -11520, -12032, -11520, -11264, -11264, -10496, -9984, -10240, -10240, -9472, -8448, -8704, -8192, -6656, -4608, -2304, 512, 3072, 6656, 10240, 12032, 14336, 16128, 16896, 16896, 16128, 15360, 13568, 10240, 6912, 3584, 768, -2048, -2816, -3072, -3840, -4864, -4864, -4608, -3840, -3072, -2048, 0, 1536, 2816, 3328, 3584, 4352, 5888, 7424, 6912, 4608, 2304, 256, -1792, -4096, -6400, -8960, -11008, -12544, -12032, -11264, -11008, -10752, -10240, -9216, -8704, -8448, -8448, -8448, -8960, -8704, -7680, -5888, -4096, -2304, 512, 3584, 6912, 9984, 12544, 14848, 16896, 17664, 17408, 16896, 15616, 13568, 11520, 8192, 4608, 256, -2816, -3584, -4352, -4352, -5120, -5888, -5376, -4352, -3328, -768, 1024, 2560, 3328, 3584, 4352, 4608, 5376, 6144, 5632, 3840, 1536, -1024, -3072, -5632, -7168, -9728, -12544, -13056, -12288, -11520, -11008, -10240, -9728, -9216, -8960, -8704, -8448, -8448, -8704, -8960, -8448, -7424, -4608, -1536, 1536, 4864, 8448, 11776, 15104, 18176, 19968, 19968, 19968, 18944, 17152, 13824, 9984, 5632, 1536, -2048, -4096, -5632, -6400, -6400, -6656, -5632, -4352, -3072, -768, 1536, 3840, 4352, 4096, 3584, 3584, 4096, 4352, 4096, 3328, 1536, -512, -2816, -5120, -6912, -8704, -11008, -12544, -12288, -11264, -10496, -9984, -9216, -8448, -8704, -8448, -8704, -8192, -8448, -8960, -8960, -7680, -5376, -2816, 0, 2304, 5888, 9728, 13312, 16640, 18944, 19456, 19456, 18944, 17920, 15872, 12032, 7168, 3328, 512, -1536, -3584, -5376, -5888, -5120, -4608, -4096, -3328, -1792, 256, 2048, 2560, 2816, 2304, 2816, 2816, 3328, 3840, 4096, 3328, 2048, -512, -2816, -4864, -6912, -9472, -12032, -13312, -13056, -12288, -11776, -11008, -10240, -9728, -9216, -8960, -8960, -9728, -9728, -8448, -6912, -5376, -4096, -1792, 1536, 5376, 9216, 12544, 15616, 17920, 19200, 20224, 19968, 18688, 15872, 12544, 8960, 5632, 2048, -768, -3072, -4352, -5120, -4608, -3584, -3328, -3840, -3072, -1280, 1024, 1792, 2048, 2048, 2304, 2048, 2304, 2816, 3584, 3584, 2560, 1024, -1536, -3840, -6400, -8960, -10496, -12288, -13824, -13568, -12032, -10752, -9728, -9472, -8960, -7936, -7936, -7680, -7680, -7424, -6656, -6144, -4864, -3072, -512, 2560, 5632, 8960, 12288, 15360, 17920, 19456, 19456, 18688, 17152, 14592, 11264, 7168, 3584, 1280, -768, -2048, -3328, -3584, -3328, -2560, -2816, -2816, -2048, -512, 1024, 1536, 1280, 1280, 1280, 1536, 2560, 2816, 2560, 2048, 1024, -512, -2304, -3840, -6144, -8960, -11264, -12800, -13312, -12544, -11520, -10752, -10752, -10240, -9472, -9472, -9472, -8448, -7424, -6656, -6144, -5376, -4096, -1792, 1536, 4608, 7680, 10496, 13824, 16896, 19200, 19712, 20224, 19456, 17152, 13568, 9472, 5376, 2048, 512, -1280, -2560, -3584, -3584, -3072, -3072, -2816, -2560, -1280, 1024, 1792, 1024, 256, 512, 1536, 2304, 2304, 1792, 1280, 1024, 0, -1792, -3584, -5888, -8192, -9472, -11008, -12288, -12800, -13056, -12032, -10752, -8704, -8192, -8192, -8704, -8192, -6656, -5376, -4608, -4352, -3584, -2816, -1024, 1280, 3328, 6144, 10240, 14080, 17152, 18432, 18944, 19456, 19200, 17152, 13056, 9472, 5888, 2816, 1024, -1024, -2816, -3840, -4352, -4352, -4096, -3584, -3328, -2048, -512, 256, 256, 256, 768, 1280, 2304, 1792, 1280, 1024, 1024, 768, -1280, -3584, -6144, -8192, -9728, -10496, -12032, -13312, -13568, -12544, -10496, -8960, -8704, -8960, -8448, -7424, -6144, -4864, -3328, -2560, -2304, -1792, -512, 2048, 4352, 7424, 11008, 14336, 17152, 18944, 19200, 19200, 18432, 16384, 13568, 9728, 5888, 3328, 1024, -1280, -3072, -4096, -5120, -5376, -4608, -4096, -3584, -2816, -2048, -1280, -768, 0, 512, 1536, 1536, 1536, 1280, 1280, 1536, 768, -1536, -4864, -7936, -9472, -10496, -11520, -12800, -13312, -13568, -12288, -9984, -8192, -7680, -6656, -6400, -5632, -4096, -2560, -1792, -2816, -2560, -2048, -512, 1536, 4352, 7936, 11520, 14848, 17408, 19968, 20480, 19456, 17920, 16640, 14080, 9472, 4608, 1280, -1024, -2560, -4864, -6400, -6656, -6144, -4608, -3328, -2816, -2304, -1536, -512, 1024, 1536, 1280, 1024, 768, 1024, 512, 256, -768, -1024, -2816, -5120, -7424, -9728, -11008, -11520, -12288, -13056, -12288, -11264, -9984, -8960, -8704, -7936, -7680, -6400, -3840, -2048, -2048, -2560, -2048, 256, 2816, 5632, 8448, 10752, 13824, 16896, 19456, 20480, 19200, 17920, 16896, 15104, 10752, 5888, 1536, -1024, -2304, -4352, -5632, -6912, -6400, -4864, -2304, -1792, -2048, -1280, 0, 1024, 1280, 512, -512, -1280, -1280, -1024, -1536, -1792, -1536, -2560, -4096, -5376, -7424, -8704, -9472, -9728, -10496, -11264, -10752, -9216, -8192, -8448, -9472, -9984, -8960, -6912, -4352, -3072, -3328, -3072, -1536, 1536, 5632, 9216, 11264, 13824, 16896, 19712, 20992, 20480, 19200, 17408, 15104, 12032, 7424, 2560, -768, -3328, -4608, -5888, -6656, -6912, -6144, -4096, -2304, -1280, -1024, -512, 768, 1536, 1024, -512, -1536, -2048, -1792, -2048, -2048, -2304, -2560, -3328, -4096, -5632, -7424, -7936, -7680, -8704, -9216, -9216, -8192, -7168, -7680, -9216, -9984, -9728, -8448, -7168, -6144, -6144, -5632, -3840, -512, 3328, 6656, 9728, 13568, 17152, 19968, 21504, 22528, 21760, 20736, 18176, 15104, 9984, 3328, -1280, -3584, -4864, -6656, -8192, -8704, -7680, -5632, -3328, -1280, 0, 1536, 1792, 2560, 2048, 512, -1024, -2560, -3072, -3840, -4608, -5120, -5120, -5120, -5632, -6144, -6656, -6656, -5888, -5888, -5888, -6144, -5376, -4352, -4608, -6400, -7936, -8960, -9472, -9472, -9216, -8448, -7424, -5632, -2560, 1280, 4864, 7936, 11520, 15872, 19200, 21504, 22016, 22528, 22272, 20480, 16896, 11520, 5632, 1024, -2304, -4608, -6656, -8704, -9472, -8448, -6144, -3840, -2304, -768, 1536, 3328, 3840, 2816, 512, -1280, -2560, -3328, -5120, -6400, -6912, -6656, -6400, -6656, -7424, -7424, -5888, -4608, -4096, -4864, -4608, -3840, -2304, -1536, -3072, -5376, -8192, -9216, -9216, -10240, -9984, -9216, -7680, -5376, -2560, 1536, 5120, 9216, 14080, 17664, 20224, 21760, 23040, 23552, 22528, 19200, 14336, 8448, 3072, -768, -3840, -6144, -8448, -9472, -8960, -7168, -5120, -3072, -1024, 1536, 3584, 4608, 4096, 2304, 0, -2048, -3840, -4864, -6912, -8448, -8960, -8704, -8704, -9216, -9216, -7424, -4864, -2560, -2560, -2560, -2048, -1024, -512, -512, -2048, -4608, -7168, -9216, -11008, -12288, -11776, -9216, -6400, -3584, -1024, 2560, 6912, 11776, 16640, 19968, 22016, 22784, 22272, 21760, 19968, 16384, 10752, 4864, 0, -3072, -5120, -7424, -8704, -9216, -7680, -5632, -3072, -1536, 256, 2048, 4096, 4608, 3328, 512, -1792, -3072, -4352, -6144, -8448, -9728, -9984, -9216, -9216, -9216, -8704, -6656, -4608, -2816, -1792, -1536, -1280, -1280, 256, 256, -1280, -3584, -6144, -8448, -10496, -10752, -9472, -7168, -4864, -2560, 768, 4096, 7680, 12032, 16384, 19456, 21248, 21760, 21248, 19968, 17664, 13824, 9472, 4352, -512, -3584, -5376, -7168, -8192, -8192, -6912, -4608, -2816, -1536, 512, 3072, 4608, 4096, 1280, -1280, -2816, -3584, -4864, -7680, -10240, -12032, -11520, -9728, -9216, -8704, -8448, -6656, -3840, -1536, -512, 256, 256, 768, 1280, 1024, -768, -3328, -6656, -8960, -10496, -9984, -8448, -5888, -3328, -1280, 1792, 5376, 9216, 13568, 17408, 20224, 20992, 19968, 18432, 16896, 15104, 12032, 7680, 2560, -1536, -4096, -5376, -5632, -6400, -6912, -6400, -4608, -2560, -1024, 1024, 2560, 2816, 1536, -1024, -2816, -3328, -4608, -6400, -8704, -11008, -11520, -10496, -9216, -8704, -8192, -6912, -4864, -2560, -1280, 0, 512, 1280, 1280, 1280, 256, -1792, -4096, -6400, -8448, -9728, -8960, -6400, -3328, -1536, 0, 2816, 6912, 11776, 15360, 17664, 17920, 17408, 17664, 17408, 15872, 13312, 9984, 5632, 2048, -512, -2816, -4608, -5376, -5632, -5888, -6144, -4352, -2560, -1280, 256, 1280, 1280, 512, -768, -1280, -2304, -4352, -7168, -10496, -11776, -12288, -11008, -10752, -10752, -9984, -7680, -4864, -2304, -768, 1536, 2816, 3840, 4096, 3072, 1280, -512, -3072, -5888, -8448, -9472, -8704, -6400, -4608, -2048, 256, 3840, 8192, 12288, 15872, 17664, 17408, 17152, 16128, 15872, 14848, 12800, 8704, 3840, -512, -2048, -2560, -2816, -4096, -6144, -6144, -4864, -3072, -1536, -512, 512, 768, 256, 0, -1536, -2560, -4352, -6656, -9472, -11776, -12288, -11520, -11264, -10752, -9728, -8192, -5632, -3072, -1536, 1024, 2560, 3584, 4096, 3840, 2816, 1280, -512, -2816, -5888, -7936, -7424, -5632, -4608, -4096, -2816, 768, 4352, 8704, 12800, 14336, 15104, 15616, 16128, 15872, 15104, 13568, 11264, 8192, 4096, 768, -2048, -2304, -3328, -5120, -6656, -6912, -5376, -4096, -2816, -2304, -1536, 256, 1792, 1792, 0, -2560, -3840, -5120, -7680, -9984, -11520, -12288, -12288, -11776, -10496, -9216, -7424, -5120, -2816, 768, 2816, 3584, 4864, 5376, 4864, 3840, 1536, -768, -3328, -4608, -4608, -4352, -5120, -4864, -3072, 512, 3840, 6656, 9216, 11008, 13056, 15104, 15616, 15616, 14592, 13824, 12544, 9472, 5376, 2304, 256, -2048, -4352, -6400, -7424, -7168, -6912, -5888, -4864, -3328, -1280, 512, 2048, 1280, -1024, -2816, -3328, -4352, -6912, -10240, -12544, -13568, -13568, -12800, -11264, -9472, -7168, -4864, -1792, 2048, 4608, 5632, 6656, 6656, 5888, 4352, 2560, 0, -2048, -3840, -5120, -6400, -5888, -4864, -2816, 0, 3328, 6400, 8704, 11264, 13824, 15360, 15872, 15360, 14848, 14336, 13312, 9728, 5376, 1536, -1536, -4096, -6656, -8192, -8448, -7680, -6656, -6144, -4352, -2048, 768, 3328, 4096, 2560, 256, -1792, -3072, -4608, -8704, -12800, -15616, -16128, -14848, -13824, -12800, -11520, -8448, -3328, 1536, 5376, 6912, 8704, 9472, 9216, 7680, 5120, 2816, -512, -3328, -6144, -8192, -9472, -8704, -6144, -2560, 512, 3072, 6400, 10496, 14080, 15616, 16384, 16640, 17152, 16384, 15104, 12288, 8192, 4096, 0, -3072, -5120, -6912, -8448, -8448, -7936, -7168, -5888, -3072, 0, 2560, 3328, 2304, 512, -512, -1792, -3328, -6400, -10496, -14336, -16640, -16896, -15872, -14336, -13568, -10752, -6400, -1280, 3328, 6144, 8704, 9984, 10752, 9984, 8192, 5632, 2816, -512, -3840, -6912, -9216, -9472, -7936, -5632, -3328, 0, 3072, 6912, 11008, 14080, 15616, 16384, 16640, 16128, 15360, 13568, 10752, 7168, 2560, -1536, -5120, -6912, -7168, -7168, -6400, -5888, -5120, -3328, -512, 2816, 4096, 3584, 2048, 512, -1536, -3584, -6400, -9728, -13568, -17152, -18688, -18688, -17152, -14848, -11776, -8192, -3584, 1536, 6144, 9216, 11008, 11520, 11264, 9984, 7680, 4608, 1280, -2816, -6400, -8960, -9984, -9472, -7168, -4352, -1792, 1024, 4096, 8192, 12288, 14848, 16384, 16896, 16128, 15616, 14336, 11776, 7936, 4608, 768, -3328, -5376, -6400, -5888, -4864, -3840, -2816, -1792, -512, 1536, 3328, 3584, 2048, -768, -3072, -5376, -8192, -10240, -14080, -17920, -19968, -19200, -17152, -14336, -12032, -7424, -3072, 2560, 7424, 10240, 12032, 12544, 12288, 11008, 7936, 3840, 0, -4096, -7424, -9984, -11520, -10496, -8192, -4608, -1536, 768, 3328, 6912, 11008, 14592, 16384, 16640, 15616, 14848, 13312, 11008, 8192, 4608, 1536, -2304, -4608, -5120, -4352, -3072, -1024, 256, 768, 1792, 3072, 4352, 4096, 2304, -768, -3840, -6912, -9984, -12288, -15360, -18432, -20992, -20992, -18688, -14848, -11520, -8448, -3584, 1792, 7168, 10752, 12544, 13056, 13056, 12288, 9728, 5632, 512, -4096, -7680, -9472, -10752, -11520, -10240, -6656, -2816, 768, 2816, 5120, 8704, 13312, 16640, 17664, 16384, 13824, 11776, 9728, 7168, 4096, 1024, -2816, -4608, -4096, -2560, -1024, 768, 3328, 5376, 5888, 5632, 5120, 4608, 2816, -512, -4096, -8704, -12032, -15104, -17920, -19456, -21248, -21248, -19456, -16384, -12288, -7936, -3072, 2560, 7680, 10752, 12800, 13568, 13056, 11776, 9472, 6400, 2048, -3328, -7680, -10496, -11520, -11008, -8960, -5888, -3840, -1280, 2048, 4352, 7168, 10240, 14336, 16384, 16128, 14080, 11520, 8704, 6144, 3584, 1792, -1024, -3072, -3328, -2304, -512, 2816, 5888, 7936, 8448, 8448, 7936, 6656, 4352, 1024, -3584, -7936, -12288, -15872, -19200, -22016, -23040, -22272, -20224, -17408, -13824, -9984, -4608, 1024, 5888, 9984, 12032, 13312, 13312, 12032, 9984, 7424, 3840, -1280, -5888, -8960, -10496, -10240, -8704, -6656, -4096, -2048, 512, 3072, 5632, 7680, 11008, 13312, 14848, 13824, 11520, 9216, 6400, 4096, 1792, -512, -1792, -2048, -768, 1024, 3328, 6144, 8192, 9984, 10752, 9984, 7680, 4864, 1536, -2560, -6400, -11264, -15872, -20224, -22528, -23040, -21760, -19968, -17920, -15104, -11520, -6144, 0, 5120, 8960, 11008, 12288, 12288, 11776, 10752, 8448, 5120, 512, -4864, -8192, -9728, -10496, -9472, -7424, -4864, -2048, 256, 2816, 4864, 6656, 8960, 11008, 12288, 12288, 10496, 8960, 6656, 4096, 1792, 0, 0, 768, 1536, 2560, 4096, 6144, 8192, 10240, 11264, 11008, 8448, 5376, 2048, -1280, -4864, -9472, -13824, -18432, -21504, -22272, -20736, -19200, -17408, -15616, -12800, -8448, -3072, 2048, 5632, 7424, 8704, 10240, 10752, 10496, 8960, 6144, 3328, -512, -4096, -6912, -8448, -8448, -6912, -5632, -4352, -3328, -1024, 2304, 4608, 6400, 7936, 9216, 10752, 11264, 10240, 8192, 5376, 3072, 2304, 1792, 2048, 2304, 3328, 4352, 5888, 7424, 8960, 10240, 10240, 8960, 6656, 3328, 0, -2816, -6144, -10496, -15360, -18944, -20480, -20224, -18688, -17408, -16128, -14336, -11008, -6912, -2560, 1536, 4608, 6144, 7424, 8704, 9728, 9472, 7680, 5120, 2304, -768, -3584, -6144, -6912, -6912, -6400, -5888, -4608, -2304, 512, 2560, 4864, 6400, 7680, 9472, 10240, 10496, 8448, 5632, 4096, 2560, 1536, 1536, 2560, 4096, 5376, 7168, 7936, 8960, 9728, 11264, 11520, 8704, 4864, 1280, -1280, -4352, -8448, -13312, -17408, -19456, -19968, -19200, -18176, -17152, -15872, -13056, -9472, -5120, -1792, 1024, 3328, 5376, 7424, 8704, 9216, 8448, 6656, 4352, 2560, 0, -2048, -3328, -4864, -5376, -5376, -4352, -2816, -1536, 1024, 2560, 3328, 4864, 6400, 7680, 7936, 7168, 5120, 3584, 2560, 1792, 1792, 2816, 5120, 6656, 8192, 9216, 9984, 10496, 11264, 11776, 10496, 7680, 3328, 0, -3328, -6912, -11264, -15872, -18432, -18944, -18944, -18944, -18176, -16896, -14592, -12032, -8192, -4864, -2304, 512, 3584, 6144, 7168, 8192, 8704, 8448, 6400, 4352, 2304, 512, -1280, -2560, -4352, -5632, -4608, -3328, -1792, 0, 1024, 2560, 4352, 5888, 6656, 6400, 5376, 3840, 2304, 2304, 1792, 1024, 1792, 4096, 6912, 8704, 9984, 11008, 12288, 12544, 13312, 12544, 9984, 6144, 2304, -768, -4352, -8192, -13312, -17152, -19200, -19200, -18176, -17920, -17920, -16896, -14336, -11008, -7936, -5376, -3072, -512, 2816, 5376, 6912, 7680, 8448, 7936, 7424, 5632, 3840, 2048, 0, -1536, -3328, -3584, -3584, -2816, -1280, 0, 1024, 2048, 3328, 4096, 4608, 3840, 3072, 2560, 1792, 1792, 1536, 1792, 3584, 6144, 9216, 11264, 11776, 11776, 12544, 13312, 13568, 12032, 8960, 5376, 2304, -1536, -5888, -11008, -15104, -17408, -18176, -18944, -18944, -19456, -18688, -16384, -13312, -9984, -7936, -6400, -3840, 0, 3072, 5120, 6144, 7424, 8192, 7680, 6656, 5376, 4096, 2560, 1024, -512, -1792, -1792, -1280, -768, 0, 768, 1280, 1536, 2304, 2048, 2048, 1536, 768, 512, 1024, 1280, 1792, 3584, 5632, 8704, 11008, 12544, 14592, 14592, 14080, 13312, 12288, 11008, 7936, 4352, 512, -3328, -8448, -12544, -15104, -16128, -16896, -18432, -19200, -19456, -17920, -15616, -13312, -11264, -9472, -7680, -4608, -1024, 2816, 5120, 6400, 7168, 8192, 8192, 7680, 6656, 4864, 3328, 1280, 0, -1024, -1280, -768, 256, 512, 256, -768, -512, 512, 1536, 1024, 512, -768, -512, 768, 2560, 3328, 4608, 6912, 10240, 12544, 14336, 15104, 15360, 14336, 13312, 12032, 10496, 7680, 4352, 256, -4864, -9984, -14080, -16384, -17152, -17920, -19456, -20736, -19968, -17664, -14336, -11776, -10240, -8448, -6144, -3072, 768, 3840, 5632, 6400, 6656, 7424, 6912, 5888, 4864, 3584, 2304, 1024, 0, -512, 256, 1280, 2304, 1792, 512, -768, -768, 768, 768, -512, -2560, -3328, -2560, -512, 1792, 3584, 5632, 7936, 11520, 15104, 16640, 17408, 16640, 15872, 14848, 12800, 10496, 7168, 3072, -2304, -7936, -12544, -15104, -16640, -17920, -19456, -21504, -21504, -19712, -16128, -12800, -11520, -10240, -8192, -5376, -1792, 1792, 4096, 6144, 7168, 7424, 7168, 5888, 4608, 3840, 2816, 1536, 0, -1024, -768, 1024, 2816, 3584, 2816, 1536, 1280, 1792, 1792, 512, -1792, -3072, -4096, -3328, -1536, 256, 2048, 4352, 8192, 12800, 16128, 17408, 17408, 17664, 17920, 16640, 14336, 11008, 6912, 1792, -4352, -9728, -13312, -15872, -18176, -19968, -22016, -22528, -21504, -18688, -15104, -12800, -11008, -8704, -6400, -2816, 512, 2816, 4864, 5888, 6656, 6656, 5376, 4352, 3072, 2304, 1792, 1280, 512, 512, 1024, 2816, 4096, 3584, 2560, 2304, 2560, 2304, 256, -2048, -4096, -4864, -4096, -2816, -1536, 0, 2048, 6144, 11008, 14592, 16896, 17920, 18432, 18432, 17152, 16128, 13312, 9472, 4608, -1280, -5888, -10496, -13824, -15872, -17920, -19968, -20736, -20992, -19456, -17152, -14336, -11520, -9216, -7936, -5632, -3072, 0, 2560, 4096, 5120, 5376, 4352, 3328, 1792, 768, 768, 1536, 1536, 1536, 2304, 3584, 5120, 5376, 5120, 4352, 4352, 3840, 2304, -768, -3840, -5888, -6912, -5120, -3584, -2304, -1024, 2304, 7936, 12544, 16384, 17920, 19200, 19968, 19456, 17920, 15360, 11520, 7936, 3072, -2816, -7936, -11776, -14848, -16896, -17920, -18688, -19712, -18944, -17152, -15104, -13312, -11264, -9216, -7424, -5632, -3584, -1536, 256, 2816, 3584, 3584, 2816, 1536, 1536, 1792, 2560, 2816, 3072, 3840, 4608, 6144, 5888, 5376, 4864, 5120, 4608, 3072, 0, -3328, -5120, -6912, -6912, -5632, -4096, -2816, 256, 4864, 9216, 13312, 16384, 18688, 20224, 20736, 19712, 17664, 14336, 11008, 6656, 1280, -4096, -9472, -13824, -15872, -16896, -17664, -18432, -18176, -16640, -15872, -14336, -12032, -9984, -8448, -6656, -4864, -3584, -3072, -768, 2304, 2304, 768, -1536, -1024, 1280, 2816, 3072, 2816, 3072, 5120, 7424, 7936, 7424, 6400, 6400, 6912, 6144, 2816, -1536, -4352, -6400, -7936, -8192, -7680, -6656, -4096, 0, 4352, 8960, 13056, 16896, 19968, 22272, 22528, 21504, 18688, 14592, 10240, 5888, 768, -5120, -10752, -14592, -16640, -17664, -18176, -17920, -17408, -16128, -14848, -13312, -11520, -9728, -7680, -6656, -6144, -5888, -4096, -2048, -512, -1280, -2304, -1536, 256, 2304, 3072, 3328, 4352, 6144, 8192, 9472, 9472, 8704, 8192, 8448, 7936, 4864, 512, -3840, -6400, -7936, -9216, -9728, -8960, -6912, -3328, 1024, 5888, 10240, 15104, 19456, 23296, 24576, 23296, 20480, 17664, 14080, 8960, 3328, -3072, -8960, -13312, -15616, -16896, -18176, -17920, -16128, -13824, -12288, -11264, -10752, -9216, -7936, -7680, -8704, -9216, -8448, -6656, -5120, -5120, -5376, -4608, -2304, 1280, 3328, 4608, 5376, 7424, 10240, 12032, 12800, 12544, 11264, 10240, 8704, 5888, 1536, -3584, -6912, -9984, -11520, -12288, -11520, -8960, -5888, -1792, 2816, 7680, 13056, 18688, 22784, 24832, 24576, 22784, 20480, 16128, 11264, 6400, 1024, -4608, -9984, -13568, -15104, -16128, -15616, -14848, -14080, -13312, -12544, -11520, -9984, -8960, -9472, -10496, -11776, -11008, -9728, -8448, -7424, -6400, -4608, -2816, 768, 3328, 5120, 6400, 7680, 9728, 11776, 13056, 12800, 12032, 11008, 9472, 6656, 2304, -1792, -4864, -8192, -11520, -13312, -13056, -10240, -7168, -3072, 1024, 4864, 9728, 15616, 21248, 24064, 24320, 22784, 20992, 17152, 12800, 7680, 3072, -2048, -6656, -10240, -13312, -14592, -14336, -13312, -12288, -11776, -11264, -10240, -8704, -8192, -8192, -9472, -11264, -12032, -11520, -10496, -9984, -8960, -7168, -4352, -1536, 1792, 3840, 5888, 8192, 10240, 12032, 13312, 13312, 13056, 11776, 9984, 8192, 4352, 256, -3584, -6656, -9472, -11776, -12800, -11520, -8960, -6400, -2816, 1280, 6144, 11264, 15872, 20224, 22528, 22016, 20224, 17920, 15104, 11520, 6400, 1792, -3328, -6400, -9216, -11776, -12800, -13056, -12800, -11776, -11008, -10496, -9472, -8704, -8448, -9216, -10240, -11008, -11776, -11776, -10496, -9216, -7936, -5632, -2560, 1024, 3328, 5376, 7680, 10240, 12032, 12800, 13568, 13312, 12032, 9984, 7680, 4608, 768, -3072, -5632, -8448, -10752, -12032, -11520, -9216, -6400, -3584, -512, 3584, 8704, 13312, 17152, 19456, 19712, 18432, 16640, 14080, 11008, 6912, 3072, -1792, -5376, -7424, -9216, -10496, -11264, -11008, -9984, -9216, -8192, -6912, -6656, -6656, -7424, -8448, -9216, -11008, -12544, -12288, -11264, -9728, -8192, -5632, -2816, 1024, 3840, 6400, 8704, 11264, 12800, 13568, 13824, 13312, 11264, 8960, 5888, 2304, -1024, -3840, -6912, -9472, -11008, -11520, -10752, -8704, -5376, -2304, 1280, 4864, 8704, 12800, 16128, 17920, 17664, 16128, 13824, 11776, 8960, 5120, 1024, -2816, -5888, -7424, -8448, -9472, -10496, -10240, -8448, -6400, -5120, -4864, -5376, -5632, -5888, -6656, -8704, -10752, -12032, -11776, -11008, -9216, -7680, -5632, -2816, 1280, 4352, 7168, 9472, 11520, 13312, 14080, 13568, 12544, 10496, 7680, 4864, 1024, -3072, -5888, -8448, -10496, -11520, -11520, -10240, -7936, -4608, -768, 2816, 5888, 9728, 13056, 16128, 16384, 14848, 13056, 11520, 9216, 6400, 2560, -1024, -3840, -6144, -7168, -8192, -9216, -8960, -7424, -4864, -3328, -3328, -3584, -3328, -3328, -3328, -5376, -8448, -11008, -11520, -11520, -10496, -9728, -8704, -6400, -2816, 1024, 4352, 7424, 9984, 12544, 14592, 15360, 14080, 12288, 9984, 7424, 4096, 256, -3584, -6912, -8960, -10752, -12032, -12288, -10752, -7424, -3840, -768, 2560, 5120, 8704, 12288, 14336, 14592, 13056, 11520, 9728, 7680, 5120, 1792, -1792, -4352, -5632, -6656, -8192, -9216, -7936, -5376, -2304, -1536, -2048, -2048, -1024, 256, -1024, -3328, -6656, -8960, -9984, -10240, -10752, -11264, -10240, -7424, -3328, 768, 4096, 7424, 11008, 14848, 17152, 17152, 15104, 12544, 9984, 6912, 2816, -2304, -7168, -9984, -12032, -12800, -13568, -13312, -11264, -7424, -3072, 1280, 3328, 6400, 9728, 13056, 14592, 13312, 11520, 9728, 7680, 5376, 2304, -1024, -3584, -5376, -6656, -7424, -8448, -7168, -4608, -1792, 512, 512, 512, 1024, 2048, 2560, 1280, -2560, -6400, -9216, -10752, -11520, -12544, -12544, -11520, -8448, -3584, 1280, 5632, 8960, 13824, 17664, 19968, 19456, 17152, 13568, 10496, 6912, 1536, -4352, -9216, -12800, -14080, -15360, -16128, -15872, -13056, -8704, -4096, -512, 2304, 5120, 8704, 11520, 12800, 12288, 10752, 8960, 7424, 4608, 1792, 0, 0, 0, 0, 0, 0, 1792, 0, -256, -1792, -4608, -4096, 768, 1536, -4608, -7424, -5376, 1536, 1536, -3072, -2560, -2560, -512, 1024, 3840, 5376, 3584, 1024, 2304, 7424, 6912, 3840, 2304, 3328, 5120, 0, -5376, -2816, 768, -2816, -9472, -9216, -1792, 2816, -1024, -6656, -5888, -1024, 3840, -1024, -3840, -2816, -2560, -256, 2304, 5888, 3840, 2048, 1536, 6144, 8960, 4864, 3584, 1536, 4352, 2560, -3840, -6656, -1792, -256, -5888, -10240, -6144, 1024, 2560, -4096, -6400, -3328, 2816, 2560, -3584, -3840, -3072, -1536, 256, 4864, 5632, 1536, 1792, 3840, 10240, 7936, 5632, 1792, 1792, 3840, 1280, -5632, -5376, -1280, -2304, -8448, -8192, -3840, 1280, -1024, -4864, -5120, 256, 4352, -1024, -3840, -2816, -3072, -1024, 2304, 6912, 3328, 1792, 2816, 8192, 11264, 7680, 3584, 512, 1792, 2304, -2048, -6400, -4608, -2304, -4864, -7680, -5376, -1024, 512, -2560, -5376, -3328, 3840, 2048, -2816, -3328, -4096, -3072, 0, 5120, 6144, 2304, 2304, 4864, 11264, 12032, 6400, 1536, 512, 2816, -256, -5376, -6912, -4864, -4352, -5120, -5888, -4352, -1280, -1280, -3584, -5120, 0, 3840, -1024, -1792, -4352, -4352, -2048, 1792, 6400, 4608, 1792, 2816, 7936, 13824, 10496, 3584, -256, 2560, 768, -3584, -6912, -7424, -5376, -4096, -4096, -4608, -4352, -2816, -2560, -4096, -4096, 2560, 1536, -768, -2304, -4864, -4096, -512, 4608, 6912, 4096, 2048, 4864, 11520, 13824, 7424, 1280, 1536, 1024, -2304, -4608, -7424, -7680, -4608, -2560, -2304, -3584, -5120, -3072, -3328, -4352, -1280, 3072, 1792, 512, -4096, -5632, -3328, 2048, 6400, 5888, 3072, 2816, 8192, 13568, 12288, 4352, 2304, 2304, -1792, -4096, -6144, -9472, -7168, -3072, -1024, -512, -4608, -5376, -4608, -5888, -4352, 1792, 2816, 2560, -1024, -4096, -5632, -1792, 5376, 7168, 4608, 2304, 5120, 11008, 14080, 9472, 2816, 2816, 256, -3584, -4352, -7936, -8704, -5376, -2560, 1024, -512, -5120, -5888, -6656, -7424, -768, 1536, 3328, 2048, -1280, -5888, -6912, 1792, 7168, 6912, 3840, 3072, 8192, 12288, 12800, 6144, 2304, 2048, -3072, -4864, -6656, -9472, -8960, -4864, 768, 1536, -3072, -5376, -7936, -9728, -4352, 1536, 1024, 3584, 1536, -2048, -8960, -3840, 4864, 6656, 5376, 1792, 5888, 11008, 13312, 10752, 3584, 2304, -512, -4096, -5376, -6400, -8448, -8448, -1024, 3328, 768, -3328, -7680, -12032, -9472, 256, 1536, 1792, 3072, 1536, -3840, -7936, -256, 5632, 7680, 3584, 2304, 9472, 12288, 12800, 6656, 2048, 1536, -2816, -5632, -5632, -6400, -11520, -5632, 3328, 3840, 256, -5632, -11008, -14336, -5376, 1792, 1536, 2560, 3840, -1792, -6400, -5376, 1792, 7168, 5376, 512, 6400, 12032, 13568, 9984, 2816, 2560, 256, -5120, -5632, -4608, -9472, -10752, 512, 3840, 3840, -2048, -8192, -14592, -12288, -2304, 2304, 1280, 3584, 2048, -3584, -5120, -3328, 4352, 8448, 2048, 2304, 9472, 13312, 14080, 6400, 1792, 2048, -2816, -5888, -3840, -5888, -12032, -5120, 3072, 5376, 2560, -5888, -12800, -14592, -7936, 512, 2560, 2304, 2816, -2048, -2560, -4608, -768, 7680, 5632, 256, 5632, 11520, 14592, 11520, 2816, 2816, 0, -5888, -5632, -4096, -9216, -9216, -1536, 3840, 4608, -768, -11008, -14336, -12544, -5376, 1280, 2816, 3072, -512, -2048, -2304, -3840, 3072, 7936, 2304, 2560, 8704, 12288, 15360, 7424, 4096, 2560, -4352, -6144, -5376, -6912, -7936, -4352, 1280, 3584, 3072, -5632, -12800, -12288, -10496, -2304, 1792, 3328, -256, -2048, -512, -2816, -1280, 6656, 4864, 1536, 5376, 9472, 14080, 12544, 6400, 5632, -1280, -5120, -6144, -6656, -7424, -5888, -2304, 2048, 3328, -256, -10496, -12288, -12032, -7680, -768, 3072, 1792, -3072, -512, 256, -2048, 2560, 5120, 2816, 4096, 6656, 10240, 13824, 10752, 9216, 1792, -3328, -4608, -6656, -7424, -6656, -3584, -512, 1792, 2048, -4608, -11520, -12288, -11520, -4864, 1536, 2816, -2560, -2048, 1280, -1792, 512, 3072, 4352, 3840, 4096, 5888, 11520, 14080, 12288, 6912, -1792, -3072, -4608, -7680, -7936, -4352, -1280, -768, 1024, 1280, -6144, -10240, -12800, -9728, -2048, 2048, 256, -3328, 256, -256, 768, 2048, 3840, 4608, 3840, 3840, 7168, 13312, 15104, 12032, 2304, -2304, -2560, -6400, -10240, -7424, -768, -1280, -3328, 256, 768, -6656, -12032, -13568, -5888, -512, 1280, -2816, -1536, 1024, 1536, 2560, 2560, 4864, 2816, 3328, 3840, 10752, 15616, 15616, 8192, 768, -1280, -3072, -8960, -11008, -3584, 256, -4096, -3328, 2304, -256, -8448, -14592, -11776, -4864, -768, -256, -4096, -512, 1280, 3840, 1536, 4352, 2304, 1280, 2304, 6656, 13824, 16640, 13312, 5376, 768, -1536, -5376, -12288, -8448, -1024, -1792, -5632, -512, 4608, -1024, -12032, -14848, -8448, -2816, 512, -3328, -3840, 768, 4096, 3840, 2304, 3840, -256, 1280, 3584, 12288, 16896, 16640, 9472, 5888, 512, -2816, -10752, -12288, -5120, -1024, -5888, -4608, 4608, 4864, -4352, -15616, -13312, -6912, -512, -1280, -6144, -1792, 2304, 5120, 3584, 4608, 512, -768, 1792, 8704, 16128, 17408, 12800, 9472, 4864, -2304, -6400, -12544, -9728, -3584, -3584, -7168, 1536, 6400, 2304, -10240, -15872, -11520, -4352, 768, -5376, -4096, -768, 3072, 4608, 4608, 2560, -1536, 0, 4096, 14336, 17664, 16128, 11008, 9728, 512, -5120, -10752, -11264, -8448, -3584, -6400, -2560, 5632, 4608, -2816, -14080, -14592, -9472, -768, -2560, -6656, -2560, 512, 4352, 5376, 5120, -768, -512, 1280, 9984, 17152, 18688, 14336, 12032, 5632, -4352, -8960, -11008, -9216, -7168, -4608, -5120, 2304, 5632, 2048, -8448, -14336, -13568, -6656, -512, -5888, -6144, -2816, 1024, 5888, 7680, 1024, -768, 0, 6912, 15360, 18176, 17664, 14848, 11008, -1536, -8960, -11008, -8960, -9216, -6912, -4608, -512, 4864, 4352, -2304, -10496, -13056, -11520, -2560, -3072, -7936, -5376, -2304, 2048, 8448, 4352, 0, 512, 2048, 12800, 17664, 19200, 17920, 16384, 4096, -7936, -12032, -8960, -8192, -8704, -6400, -3584, 2560, 4096, 1280, -6656, -10752, -12800, -8192, -2048, -5632, -7936, -5632, -2048, 5632, 8192, 1792, 1536, 1024, 7168, 16128, 17664, 18176, 19968, 11008, -5120, -13056, -10496, -5888, -8704, -7680, -5632, 512, 3328, 2304, -2560, -7936, -11520, -11264, -5376, -4864, -6912, -9216, -6656, 512, 7424, 6144, 3072, 2816, 3328, 11520, 17664, 17408, 20736, 17920, 1536, -12032, -13312, -7168, -5888, -6912, -6656, -3584, 2816, 2560, -512, -4608, -8448, -11008, -8704, -6400, -5632, -9216, -11264, -3584, 3584, 7424, 6912, 5632, 4608, 7424, 15360, 16640, 18176, 22016, 10496, -8192, -14592, -10496, -5888, -5632, -5632, -6144, -1024, 2560, 0, -2816, -5376, -7936, -9472, -9472, -7424, -7424, -13568, -8448, -768, 4096, 8448, 7936, 6912, 5888, 11776, 16384, 16640, 21760, 18176, -1024, -12288, -12032, -7936, -5120, -3840, -3840, -4864, 256, 0, -1280, -3584, -5376, -6656, -10240, -9984, -7168, -13056, -12800, -4608, 1024, 6656, 9728, 9216, 7680, 8192, 15616, 16384, 17920, 20480, 7936, -8960, -11008, -10240, -6400, -4864, -1536, -4352, -2816, 0, -1536, -2816, -4352, -3840, -7936, -12032, -9984, -11520, -15872, -8704, -2048, 3072, 9216, 9728, 10496, 9472, 13056, 16640, 15360, 18176, 14336, -1792, -9216, -9728, -8960, -6912, -2816, -1280, -4352, -2048, -2048, -2304, -4352, -3328, -5120, -9472, -12032, -12800, -15872, -12544, -4096, 256, 6400, 8704, 11008, 13568, 12544, 15872, 14848, 15872, 16640, 5632, -5888, -7936, -8704, -8960, -4864, -768, -2048, -4608, -1792, -1024, -3584, -4352, -2304, -6912, -10240, -14336, -17408, -16384, -6912, -1024, 2304, 7168, 9472, 13824, 15360, 15616, 15104, 13824, 16128, 11008, -256, -6400, -5888, -9472, -7168, -2048, 1024, -2560, -3840, -768, -1792, -6656, -3840, -2816, -7424, -13056, -18176, -18176, -12544, -2048, 1280, 3584, 7680, 12288, 16896, 17408, 16128, 13056, 14336, 13056, 4608, -4608, -5120, -6400, -9984, -5888, -1280, 768, -3328, -1536, -1280, -5376, -7168, -2560, -4608, -11008, -17152, -19968, -16384, -6400, 256, 2048, 3840, 9728, 15360, 19200, 18944, 14848, 13824, 14592, 7168, -1792, -4608, -2048, -7936, -8704, -3840, 1024, -512, -1024, 0, -3840, -8192, -5376, -2048, -7168, -14592, -19712, -19200, -11264, -3072, 1536, 2048, 5120, 12544, 17408, 19712, 18176, 13568, 15616, 10496, 768, -4608, -1024, -3584, -9216, -7168, -1792, 256, 1792, 1536, -2048, -8704, -8960, -4096, -3840, -10496, -16896, -19200, -15104, -7936, -1024, 2560, 2816, 7936, 14336, 18432, 21760, 16128, 14848, 14080, 3584, -4352, -2560, -256, -6144, -7680, -5632, -1536, 2816, 4096, 2304, -6912, -11008, -6912, -3840, -6656, -13568, -16128, -16896, -11776, -5376, 768, 3328, 3840, 10240, 16128, 21248, 19968, 15360, 17152, 9728, -2304, -5120, 1024, -1792, -5888, -6400, -5632, 1536, 6144, 5120, -2048, -12288, -11008, -6144, -4096, -9984, -14080, -14592, -14592, -9216, -2560, 2304, 2816, 5632, 12800, 18688, 22528, 18176, 16640, 15104, 3584, -6144, -2304, -768, -3840, -4608, -7936, -3584, 6400, 7168, 2560, -9216, -14336, -10496, -5376, -7424, -12288, -12032, -13056, -12800, -6656, -512, 2816, 1536, 7680, 14592, 20992, 21248, 17664, 16640, 8960, -3072, -4096, -768, -2560, -3072, -5376, -6656, 2816, 8448, 6656, -1792, -14336, -13824, -8192, -6656, -10496, -9984, -9472, -13312, -10496, -4096, 1280, 1792, 2816, 9472, 18432, 23296, 19968, 16896, 14080, 2816, -4864, -3584, -3840, -2304, -1792, -4864, -2048, 5632, 7680, 3328, -8192, -15872, -11264, -7936, -8704, -10240, -7424, -10240, -11776, -7424, -2048, 512, 256, 4608, 12544, 21504, 22016, 18432, 17152, 9984, -1536, -5376, -6400, -4096, 512, -1536, -3072, 1536, 5888, 4608, -1792, -13056, -14336, -9984, -8448, -10496, -7680, -6144, -10496, -9216, -4352, -2048, -1280, 1792, 8192, 16896, 21504, 19968, 19200, 14848, 5120, -3840, -7424, -8448, 512, 1024, -256, 256, 2816, 4352, 1024, -6912, -14336, -11776, -9216, -9472, -9984, -5632, -6144, -9728, -5888, -4096, -4096, -1792, 4608, 11776, 18432, 20992, 20736, 18432, 11264, -256, -6400, -10496, -4608, 3584, 2048, 2560, 0, 1280, 512, -2816, -10240, -12800, -10752, -9728, -9472, -8448, -2816, -6912, -6656, -5120, -5632, -3328, 0, 7936, 13312, 18688, 20992, 20480, 15616, 6656, -4096, -9472, -10240, 0, 4608, 4352, 3072, -1280, -2048, -2560, -5376, -10496, -11008, -11264, -9216, -8960, -5120, -3072, -5888, -3584, -8192, -5376, -3072, 3840, 9728, 14848, 19456, 20992, 18432, 11776, 1024, -6656, -10496, -5888, 3584, 6400, 4608, 512, -5888, -4608, -3584, -7424, -8960, -11520, -10752, -8960, -7424, -3840, -4864, -768, -5888, -8192, -4864, -256, 6912, 10240, 17152, 20736, 19456, 15616, 6656, -2816, -8448, -9216, -1536, 7168, 7168, 3328, -3840, -9728, -4864, -5120, -6656, -9216, -11776, -8960, -8192, -5120, -5376, -1024, -1024, -7168, -6400, -4096, 3328, 7936, 12544, 18944, 20224, 17664, 12288, 2048, -4096, -8448, -5376, 1792, 8448, 6144, 1280, -8192, -9728, -5632, -5376, -5632, -10496, -11008, -8192, -6400, -5888, -4096, 1536, -2304, -7424, -7168, -1280, 5120, 9984, 14848, 19200, 18176, 15360, 5632, 0, -4608, -6912, -2560, 4096, 7680, 3840, -3584, -12544, -8704, -4864, -4096, -6912, -11008, -7936, -6400, -6912, -6144, -256, 1792, -3840, -8192, -5632, 768, 7168, 12800, 15616, 17152, 15104, 9728, 3328, 1280, -4352, -4096, -768, 5376, 5888, 768, -8704, -12544, -7168, -4352, -4864, -8704, -8704, -4608, -6656, -8192, -4096, 3584, 1536, -5888, -8704, -2816, 3584, 11264, 13824, 14336, 15360, 11264, 6400, 4608, 512, -4608, -2304, 768, 5376, 2304, -3584, -11520, -9984, -6144, -5632, -7168, -8192, -4608, -4352, -9216, -7680, 1280, 5376, -1280, -7936, -6912, 256, 7680, 14336, 11776, 12800, 12032, 8192, 7424, 5120, -1024, -2304, -2304, 1024, 2560, -512, -7168, -9728, -7936, -8448, -6656, -6656, -4864, -2304, -6144, -9728, -2816, 6144, 2560, -4352, -9216, -3584, 3584, 12288, 12544, 9472, 11008, 9984, 8448, 8192, 2816, 256, -1280, -2816, -1536, -768, -4096, -7424, -7168, -10240, -9728, -6912, -5120, -1536, -2816, -7936, -7424, 3840, 5632, 0, -6400, -6400, 512, 7936, 13056, 9728, 8960, 10496, 10496, 8704, 6912, 2048, 1536, -1792, -5120, -3584, -1792, -5120, -4864, -8704, -13312, -8960, -5888, -2816, -1280, -4608, -8448, -1280, 6656, 1280, -2816, -6912, -2816, 4352, 11008, 11008, 7680, 7424, 11776, 11520, 9728, 4352, 1536, 512, -5632, -6912, -4096, -4096, -4608, -4608, -13568, -12288, -5888, -4864, -768, -2560, -5376, -4864, 4608, 3072, -1536, -5120, -5376, 1536, 7424, 10752, 7936, 5888, 9472, 13824, 12288, 7936, 3328, 3328, -3328, -7936, -6400, -4096, -4096, -2816, -9728, -15872, -8448, -7168, -1792, -768, -3072, -4352, 1536, 4096, 512, -2816, -4352, -1280, 3840, 8960, 8704, 6400, 5888, 11264, 14080, 10496, 5632, 3584, 512, -7424, -8192, -5888, -2816, -3328, -4608, -15360, -12800, -8192, -4096, -1536, -2816, -1024, 768, 2816, 768, -256, -3584, -2048, 1280, 5120, 9984, 7936, 6144, 6656, 13824, 14592, 9472, 4096, 2048, -4864, -8192, -6912, -4352, -4352, -4352, -9216, -14848, -10240, -8192, -2816, -2816, -512, 1536, 2560, 512, 0, -1024, -3072, 256, 2048, 8448, 10752, 6656, 4352, 8960, 16128, 13568, 6656, 1536, -2304, -6912, -7680, -6400, -4352, -5888, -6144, -12032, -13056, -9728, -4352, -2816, -1536, 3072, 4352, 2048, -2048, -256, -2560, -1792, 1024, 4608, 10240, 8448, 4608, 5632, 12544, 17920, 11776, 3072, -2816, -4096, -5888, -6912, -4864, -7168, -6656, -9216, -12800, -12288, -7936, -3328, -3328, 2560, 5120, 5376, 0, -1536, -256, -1792, 768, 3840, 8192, 10240, 6144, 4352, 7936, 14848, 17152, 7168, -512, -5376, -3584, -7936, -4608, -6144, -8448, -8448, -12544, -12544, -10496, -4608, -5120, -512, 5120, 5888, 4864, -3072, -1792, -512, -768, 2560, 5632, 8448, 9472, 5376, 5888, 9984, 18432, 13056, 2560, -4352, -4608, -5120, -7424, -4352, -8448, -9216, -12544, -12288, -12032, -6144, -4096, -3840, 2816, 6144, 7680, 1536, -3072, -512, -512, -256, 4608, 7424, 8960, 6912, 6400, 6400, 14336, 16128, 5888, -1280, -4864, -3584, -5888, -5376, -5376, -9728, -13312, -13824, -10240, -8192, -3840, -5888, -1792, 4608, 7936, 5632, -512, -1792, 768, 0, 3072, 5376, 8704, 7936, 7168, 5632, 8960, 16896, 10240, 512, -4864, -4864, -3840, -5376, -4096, -7680, -15360, -15872, -10752, -8448, -4608, -4608, -5632, 1024, 7424, 7424, 3584, -512, -1024, 1280, 1536, 4096, 7168, 9216, 6144, 7424, 6656, 13312, 12544, 3584, -3328, -6144, -4864, -3584, -3840, -4352, -13568, -19200, -13824, -8192, -4608, -2816, -6656, -4608, 4608, 7168, 6400, 3328, -1536, 1024, 3328, 2304, 4352, 9472, 6144, 7168, 8448, 9472, 12544, 6656, 256, -4864, -6656, -4096, -2816, -1792, -8448, -19712, -18176, -11520, -3840, -2048, -4608, -7680, 256, 6400, 5376, 6656, 768, 1280, 4352, 3584, 2816, 8448, 6912, 4352, 8704, 9728, 10752, 8448, 1536, -2816, -7168, -5632, -3072, -768, -4096, -15360, -20736, -15872, -6400, -512, -3584, -6912, -4352, 5120, 4608, 6144, 4608, 1536, 4096, 5376, 3072, 6144, 7168, 3072, 6656, 11264, 10752, 8960, 3328, -1280, -5376, -7936, -4608, -512, -512, -10752, -19712, -19456, -12032, -2560, -1536, -5632, -6144, 1024, 4096, 4608, 6400, 4608, 4608, 6144, 5120, 5120, 8192, 3584, 2816, 10240, 12544, 10496, 5376, -1536, -3328, -6912, -7168, -1280, 1280, -4608, -15104, -20224, -16128, -7680, -1536, -2816, -7168, -2816, 2048, 2560, 5888, 6912, 4352, 6144, 6400, 6400, 7168, 4864, 2048, 6400, 12032, 11776, 6912, -1280, -3840, -4608, -8448, -5120, -1280, -768, -8960, -17920, -16896, -13056, -5632, -1792, -5376, -4864, -768, 1536, 4352, 7424, 6656, 5888, 7168, 6400, 8192, 5888, 3584, 2816, 9984, 12800, 9728, 768, -4864, -2560, -5376, -7424, -3072, -768, -3072, -14080, -16640, -14336, -10752, -3584, -2560, -5888, -2816, -768, 2560, 5888, 8192, 6656, 7168, 7168, 8960, 7424, 5632, 3328, 4608, 10496, 11008, 4608, -4096, -4608, -3584, -7424, -5376, -2816, -2048, -8192, -15616, -13312, -13312, -7680, -2816, -4608, -4096, -2560, 512, 5632, 8960, 7680, 6400, 8192, 8704, 10240, 6912, 4864, 2816, 5888, 9984, 8192, -256, -5632, -3584, -5632, -5888, -3584, -2816, -4352, -11520, -13312, -13056, -13056, -5632, -4352, -4864, -4352, -2560, 2816, 8960, 9984, 7424, 6656, 8704, 11008, 11008, 6912, 4096, 3072, 6400, 7936, 4608, -3328, -5120, -4864, -5632, -3072, -3584, -3840, -7168, -11264, -12032, -13568, -8448, -3840, -5632, -6144, -5120, 1280, 6912, 9728, 7936, 5376, 6912, 11776, 13056, 10240, 4608, 2048, 3328, 5888, 6144, 768, -5376, -5632, -5632, -2048, -2304, -5632, -6656, -7936, -10240, -13056, -11264, -4352, -3840, -6656, -7936, -2560, 6144, 8960, 9472, 6400, 5376, 10752, 14592, 13568, 7680, 2816, 1792, 2816, 5376, 3072, -2816, -5888, -6400, -3072, 0, -4608, -8192, -7936, -7680, -11520, -11776, -6656, -3328, -6400, -9984, -6400, 3840, 9216, 7424, 6400, 5120, 9472, 14848, 16128, 11776, 3840, 768, -512, 4864, 4096, -512, -4864, -6400, -5888, 1024, -1024, -7936, -9216, -7424, -8192, -11008, -9472, -4352, -4096, -9984, -11008, -512, 8704, 7936, 5376, 4352, 7680, 15872, 17152, 15872, 6912, 2304, -2304, 768, 6656, 2048, -4608, -6656, -6656, -1280, 2304, -5888, -11264, -8448, -6656, -8448, -10240, -7168, -3072, -7680, -13312, -6144, 5888, 8448, 3840, 3584, 5632, 13824, 19200, 17408, 12032, 3584, -2304, -3072, 4864, 5888, -3072, -5120, -5120, -3328, 2816, -1536, -10240, -10496, -4864, -5888, -8704, -8704, -3584, -3328, -12288, -12288, 1024, 8960, 5888, 1792, 3328, 10240, 19712, 19968, 14592, 7936, -768, -4608, 768, 6912, 1792, -6144, -4864, -4096, 256, 1280, -7424, -12544, -7168, -3328, -6656, -8704, -6656, -1024, -7680, -14592, -6144, 5632, 7680, 1536, 1792, 7936, 16128, 22016, 17408, 10752, 2560, -4864, -3328, 3840, 6400, -2560, -5632, -3584, -1792, 1536, -2816, -11520, -10240, -3584, -6144, -8960, -7936, -3072, -2048, -13056, -11264, -512, 7424, 2816, -256, 5632, 12032, 18944, 19968, 12544, 6400, -2048, -6656, -1024, 6656, 3072, -4096, -4864, -2816, -256, -256, -7168, -11520, -5632, -3328, -7424, -7424, -5888, -256, -6656, -14080, -6656, 3584, 5120, -768, 3328, 9984, 16128, 20480, 15616, 8448, 2048, -5632, -6400, 2560, 5632, -256, -3584, -3840, -1792, -256, -3584, -9472, -6656, -3328, -6400, -7168, -6656, -512, -1280, -12288, -11264, -1792, 4608, 768, 2304, 7680, 12544, 18176, 17920, 11520, 5888, -3328, -8448, -1280, 5632, 2816, -1792, -4352, -3584, -1536, -2048, -7424, -7424, -3840, -4864, -6656, -7936, -3840, 1536, -6400, -13312, -7680, 1792, 1792, 512, 5376, 10240, 15360, 17152, 13312, 8448, 1792, -7424, -4864, 4096, 5632, 1024, -2048, -3840, -2816, -1536, -5888, -6144, -2560, -2816, -5888, -6912, -5632, 256, 0, -8704, -11520, -3584, 512, 256, 3840, 8960, 13312, 15872, 12544, 9216, 5376, -4096, -6656, 256, 5120, 3072, -1792, -2560, -5120, -2560, -4864, -7168, -2304, -2048, -3840, -6656, -6912, -2816, 512, -3840, -10496, -8704, -2560, -1792, 1536, 8192, 12288, 14336, 13056, 8960, 6656, 256, -6144, -2560, 3840, 4608, 512, -2304, -4352, -4608, -2816, -8192, -1536, 512, -2304, -4608, -5632, -4352, -768, -512, -5376, -8704, -6656, -3328, -2048, 5120, 12032, 13568, 13312, 9728, 6144, 1280, -3584, -3840, 2304, 3584, 1024, -1536, -3584, -5376, -3584, -7168, -5632, 3072, 0, -2560, -5888, -6144, -3328, 512, -2560, -5888, -8704, -6656, -3328, 1024, 9984, 14848, 13056, 11520, 7168, 1536, -2304, -2816, 768, 4352, 1792, -768, -2560, -4608, -3840, -5632, -8960, 512, 4608, 512, -2816, -5888, -5120, -256, 0, -3840, -6144, -9984, -6400, -1536, 4352, 13312, 14336, 12032, 8960, 1536, -2560, -2048, 0, 3328, 3328, -512, -2304, -3328, -3328, -6400, -11008, -4096, 5376, 4864, -768, -5376, -6400, -2560, 512, -1280, -3584, -7680, -10240, -3328, -256, 8704, 14848, 13056, 11264, 4608, -2560, -2304, -512, 1536, 3072, 1792, -1792, -3072, -3072, -4608, -10240, -8448, 2304, 8192, 4864, -2304, -5888, -3840, 256, 768, -2304, -4608, -10240, -7168, -1024, 1792, 12032, 15104, 12544, 6144, 256, -3328, -1280, 256, 2560, 2816, 1280, -3072, -3072, -3840, -8960, -10752, -2304, 5888, 8448, 2304, -5632, -6144, -1280, 256, -1280, -3072, -7680, -10240, -1792, -768, 5632, 14336, 14848, 8960, 2816, -3072, -2304, -1280, -256, 1792, 3328, -1024, -3328, -3328, -6400, -11008, -7424, 2560, 8704, 8192, -1536, -6912, -2048, 768, -1280, -3328, -5632, -10240, -4608, -768, -256, 9472, 15616, 11776, 5888, -1280, -3328, -1024, -1024, -1792, 3072, 3584, -2560, -4608, -5632, -8704, -8960, -2560, 5632, 9984, 5888, -3840, -3584, 1280, 768, -2048, -3840, -9216, -5888, -256, -1792, 3584, 13056, 14592, 9472, 2048, -3328, -1792, -512, -3584, -1536, 5120, 768, -5376, -6656, -6912, -7680, -6912, 256, 7168, 9216, 1792, -2560, 0, 1280, -2048, -3584, -7680, -7424, -768, -2560, -1280, 7936, 14336, 11776, 4864, -1792, -2560, 768, -2816, -5376, 2304, 4864, -2560, -7680, -7424, -4864, -6144, -5120, 2560, 8960, 7424, 2048, -256, 1280, -512, -3328, -7168, -8448, -768, -256, -3328, 3072, 12544, 14080, 7936, -256, -3072, 512, -768, -6656, -512, 5376, 512, -7168, -8704, -5376, -4352, -7424, -3072, 5888, 8704, 4864, 1536, 1792, 1024, -1024, -5888, -10240, -2560, 1792, -3072, -512, 8704, 14080, 9216, 2048, -2560, 256, 768, -4864, -4608, 3840, 3840, -2560, -8448, -7680, -2304, -4864, -6400, 1024, 8192, 7680, 4096, 2816, 2560, 768, -3840, -8960, -6912, 2304, -1024, -2560, 4096, 13312, 10752, 3072, -1792, -1536, 1024, -1536, -5376, -512, 4352, 0, -5120, -10496, -3328, -2304, -7936, -4096, 4608, 8704, 5888, 3584, 2304, 2560, -1792, -6656, -8704, -768, 2560, -2560, 512, 10752, 13056, 4096, -2048, -2816, -512, -512, -2816, -2304, 2304, 512, -2048, -9216, -7936, 768, -5888, -7680, -256, 6912, 6912, 5888, 3840, 4608, 768, -4352, -7936, -4864, 2048, 256, -1024, 6144, 13056, 7680, -2816, -4096, -1536, -768, -1280, -2560, 768, 256, -2560, -5632, -10496, -1024, -1536, -7424, -4608, 3072, 6400, 6656, 5888, 5120, 2816, -2560, -5376, -6912, -1024, 1792, 0, 3328, 10496, 10240, 768, -6144, -2816, -256, -512, -768, 1280, 1280, -3584, -3840, -8960, -5120, 0, -4864, -6144, -1024, 2816, 5888, 7936, 6144, 4096, -768, -3328, -5888, -3584, 512, 768, 4608, 8192, 9728, 5376, -5120, -7424, -1280, -512, 0, 1280, 2816, -3584, -5632, -6400, -6656, -768, -2816, -6656, -2816, -512, 2048, 8192, 8704, 6144, 512, -2048, -4096, -3328, 256, 256, 2560, 7936, 7936, 8448, 256, -9216, -5632, 0, 0, 2048, 4608, -768, -6912, -5632, -5632, -2560, -2304, -6144, -4096, -1280, -4096, 4096, 10240, 8704, 2048, -768, -3328, -3072, 256, 256, 768, 7680, 7680, 6144, 4608, -7168, -8960, -3328, -512, 1536, 4864, 2560, -6400, -7168, -3840, -2304, -2560, -4864, -5120, -768, -3840, -2048, 6912, 10752, 6400, 256, -3584, -4608, 1792, 2304, -256, 4864, 9472, 4864, 5888, -2560, -10496, -6656, -2304, 512, 5120, 4864, -4352, -8960, -5376, 0, -2304, -4608, -5120, -1792, -2048, -6144, 1536, 9472, 11008, 3584, -2560, -5632, 768, 4608, 1024, 1536, 9216, 5888, 4096, 1024, -8192, -9472, -4864, -768, 4352, 6912, 0, -9472, -8704, -768, 1792, -4352, -6912, -4864, -256, -5120, -3328, 4352, 11264, 8960, 512, -5632, -2304, 4864, 5120, 512, 6656, 8192, 3840, 1280, -4352, -10240, -7424, -2304, 2560, 7168, 4352, -5888, -10496, -5376, 2304, -512, -6912, -7680, -1280, -1792, -5376, -1024, 6912, 12032, 6912, -3584, -5376, 2816, 7424, 3584, 3840, 8192, 5120, 1024, -2816, -7936, -9728, -3840, 512, 5632, 5632, -768, -8192, -8704, -1536, 2048, -3328, -9728, -4864, 0, -4096, -3584, 1536, 9472, 9984, 2816, -4608, -1024, 6400, 6400, 4096, 6144, 6912, 1792, -2560, -6144, -9728, -6400, 0, 3072, 5888, 2048, -4096, -7936, -5888, 0, 0, -6912, -8448, -512, -2304, -4096, -2816, 4352, 10496, 8192, 1280, -3840, 3072, 6400, 6144, 5376, 6912, 3584, -1024, -5376, -7936, -7424, -1024, 2304, 4864, 2304, -2304, -4864, -6400, -2560, -1280, -3840, -9728, -3328, -1536, -3328, -4352, -256, 7680, 9216, 6912, -512, 512, 5120, 6144, 6400, 6144, 4864, 512, -4096, -8192, -7424, -3328, 2048, 4608, 4096, -1536, -3328, -5376, -3840, -3584, -3328, -6656, -5632, -1536, -2816, -3584, -3584, 2816, 7680, 9472, 4352, 256, 3328, 5120, 5888, 6144, 5376, 1280, -2560, -8192, -7936, -3840, 0, 4352, 5632, -768, -3840, -4352, -2816, -3840, -4864, -5888, -5632, -2048, -2048, -3328, -4608, -2048, 4608, 10240, 9728, 3072, 3072, 3840, 5376, 5888, 6144, 1792, -2304, -5632, -8704, -4864, -1536, 2816, 7680, 2304, -4352, -5120, -4096, -2816, -5632, -7680, -6912, -2048, -1792, -2560, -4864, -4096, -512, 8192, 13312, 7936, 4352, 4096, 3328, 5376, 4864, 4864, -2304, -4352, -7680, -6400, -1792, 768, 7424, 6400, -2304, -5376, -5120, -2816, -3584, -7424, -9472, -3584, 512, -1280, -3584, -5632, -3072, 3328, 12800, 12544, 6912, 5888, 3840, 3328, 2304, 4608, 1792, -5632, -5632, -7168, -2816, -1280, 4864, 8960, 3328, -5120, -6144, -4608, -2048, -5632, -9728, -7936, 512, 768, -1536, -6656, -5632, -768, 9728, 14336, 10752, 8704, 5376, 3072, 1536, 2816, 4352, -3840, -6144, -5120, -3840, -1536, 2304, 7424, 7424, -1024, -7168, -5888, -3584, -3328, -7680, -9984, -4096, 2304, 1536, -3072, -8448, -4096, 4864, 14592, 12544, 10496, 7680, 3328, 1024, -256, 1536, -1024, -6912, -5376, -3328, -1536, 512, 3072, 8704, 3072, -6144, -6144, -5120, -4096, -6144, -9728, -8448, 512, 3072, -512, -7680, -7936, 512, 11520, 15104, 11776, 10496, 6144, 2048, -768, -1536, 256, -3840, -6400, -4096, -768, 1280, 512, 5376, 7168, -2816, -6656, -5888, -4608, -5120, -8192, -10240, -3584, 3584, 2816, -2560, -10240, -5120, 7680, 15360, 14080, 10752, 8704, 3840, 1536, -3072, -3072, -1024, -4864, -5376, -2304, 2048, 1024, 2560, 7168, 1536, -6400, -5632, -5120, -5632, -7424, -9728, -6912, 1280, 4096, 1024, -6144, -9984, 3072, 13056, 15616, 13056, 10496, 6912, 2560, -1792, -6400, -2304, -2560, -4352, -3840, 0, 2304, 1280, 5376, 3840, -3328, -6912, -4352, -5376, -5888, -9728, -8448, -2816, 2560, 1536, -1024, -9728, -4352, 9216, 14080, 14080, 11520, 8960, 5376, 1024, -6912, -6400, -512, -2560, -3584, -3328, 768, 1280, 3584, 4096, 0, -6144, -5376, -4608, -5632, -9216, -9984, -4352, -768, 1280, 768, -3840, -7168, 4096, 12800, 13568, 13312, 11008, 7424, 3328, -3584, -9216, -2560, -256, -3840, -3840, -1536, 1536, 1280, 3328, 1024, -2816, -6144, -4352, -4608, -6912, -11008, -4608, -3072, -1792, 1024, 768, -4352, -1024, 9728, 13568, 13312, 12288, 10496, 5888, 0, -7936, -7680, 512, -1792, -3584, -3328, -1280, 768, 2816, 1792, -1024, -5376, -6400, -5376, -4864, -9984, -5888, -2304, -4864, -2048, 1280, -256, -2560, 6144, 11776, 12288, 11776, 11264, 8192, 2560, -4608, -9472, -1792, 0, -3072, -3584, -3328, -1024, 2048, 2304, 256, -4096, -7424, -7168, -4352, -8448, -7936, -1536, -5376, -5376, -1024, 3072, 768, 3328, 10496, 11776, 11264, 11776, 11264, 5120, -1792, -9216, -6912, 1536, -768, -4608, -5376, -3072, 512, 3072, 1536, -1280, -6912, -9216, -5376, -5120, -8704, -3072, -2048, -7424, -4096, 2816, 3840, 2560, 7168, 12032, 11776, 10496, 11520, 8960, 1280, -6144, -7680, -1280, 768, -3584, -6656, -4096, -1792, 1792, 2048, -768, -4608, -9984, -8192, -4096, -7168, -6656, -2048, -5888, -6656, 0, 4864, 4096, 5120, 10752, 14080, 11520, 9728, 9984, 5120, -2816, -6144, -3328, -512, -1536, -6400, -5632, -1792, -1280, 3328, 0, -2816, -9216, -10496, -5120, -4096, -7424, -4096, -3584, -7168, -3072, 3328, 4352, 3840, 8192, 12800, 14592, 10496, 9728, 7680, 512, -3584, -2304, -768, -768, -4864, -8448, -2560, -1792, 1792, 1792, -3328, -7680, -10752, -7168, -3328, -4352, -6656, -3584, -5632, -3840, 1792, 4864, 3840, 6656, 11776, 15104, 13056, 8704, 8448, 3072, -1792, -2816, -1024, -1280, -3328, -9728, -5888, -768, 768, 3840, -1792, -8192, -11520, -8704, -5376, -2816, -6912, -6400, -5376, -4864, -256, 3328, 3840, 5632, 9472, 13568, 15872, 11776, 8704, 3840, -512, 0, -1024, -2048, -2304, -8704, -9728, -2048, 1024, 4352, 768, -6400, -12800, -11264, -6656, -3072, -3328, -8192, -6144, -5120, -1792, 2816, 4608, 4352, 8448, 12800, 16640, 14592, 10496, 6144, 0, 1280, 1280, -2304, -2816, -6400, -11264, -6400, -256, 4352, 3328, -4608, -10752, -13056, -8448, -5120, -1792, -6912, -7424, -5888, -4096, 0, 3584, 3584, 7168, 12288, 15360, 16896, 13056, 8704, 1024, 0, 3840, -768, -3584, -5120, -8960, -9472, -3072, 3072, 6912, -1792, -9472, -12800, -10240, -7424, -3840, -3840, -7680, -6144, -3840, -1792, 1536, 4352, 6400, 11776, 15104, 17408, 16128, 11008, 5120, -1536, 3584, 2560, -2048, -5120, -7680, -8704, -5632, -512, 6144, 3840, -7680, -12544, -12544, -9472, -7168, -3840, -6656, -7168, -4608, -2816, -1792, 1792, 6912, 10752, 14848, 17920, 17920, 13568, 8960, 1024, 0, 4608, -256, -3840, -8192, -7936, -6656, -3072, 3072, 7168, -1024, -11264, -13568, -11264, -9984, -6400, -5888, -7168, -4864, -2816, -3072, -4096, 3328, 10752, 14336, 18176, 18176, 14592, 11520, 5888, -768, 2560, 2816, -1536, -6912, -8960, -6400, -5632, -256, 5888, 4352, -7424, -13824, -11776, -11264, -9984, -7424, -7168, -5376, -3840, -3840, -6656, -3072, 9984, 14592, 17920, 18688, 15360, 12544, 10496, 3328, 256, 2816, 0, -4096, -8192, -6400, -3840, -3584, 2560, 5888, -1280, -12288, -11776, -10752, -12544, -11008, -7936, -6144, -3840, -3328, -6144, -8192, 4608, 15104, 18176, 19712, 17152, 14592, 12032, 8448, 768, 1280, 1280, -2304, -5888, -8448, -4096, -3584, -1280, 4352, 3072, -7424, -11264, -8960, -12800, -14592, -11008, -7680, -4608, -2816, -5632, -9984, -2304, 11264, 17408, 20992, 17664, 15616, 12544, 10752, 4608, 1280, 1280, -2048, -3072, -6656, -3584, -1792, -2304, 1280, 4096, -1536, -9216, -8192, -10752, -15872, -14080, -9984, -7424, -3840, -3584, -8704, -7680, 5120, 15104, 20992, 20224, 16896, 14848, 11520, 9728, 2304, 256, -1792, -2816, -4096, -4864, -768, -1536, -1536, 2304, 1280, -5632, -8192, -8192, -14848, -17920, -14336, -10752, -6144, -4096, -6400, -9984, -2304, 10496, 18432, 22016, 18688, 16640, 11776, 10240, 7680, -1024, -1792, -3584, -3072, -5120, -768, 1024, -1280, 256, 2048, -2304, -6912, -6400, -10240, -17152, -17152, -14080, -9728, -6144, -4352, -6400, -7168, 4096, 15616, 20736, 20992, 18176, 15360, 9472, 10752, 4352, -3584, -4352, -2816, -3328, -2048, 2560, 512, -512, 256, -256, -4352, -5120, -6656, -13824, -17664, -17920, -14848, -8704, -6400, -4096, -5888, -2304, 9472, 17920, 22272, 20480, 17408, 11264, 9728, 9984, -1280, -6912, -4864, -3072, -1536, 3328, 2560, 1024, 256, 256, -1280, -4864, -5120, -9472, -15104, -18176, -18176, -13824, -8960, -4352, -2304, -5120, 2816, 12544, 20480, 22016, 18432, 13824, 9216, 11520, 5888, -6400, -8704, -4096, -2304, 2816, 4352, 2048, 1280, -1024, -512, -3840, -4864, -6656, -12800, -17664, -19712, -18176, -13056, -7424, -1792, -2816, -1536, 6656, 16384, 22272, 19968, 15360, 10240, 10752, 11520, 512, -9728, -8704, -3072, 2560, 6144, 2560, 2816, 768, -256, -1536, -5120, -4096, -7936, -15616, -20736, -20480, -17664, -10496, -4096, -1280, -2048, 2560, 12032, 20736, 22016, 17920, 11264, 9216, 12288, 8192, -5376, -12288, -7936, -768, 6144, 6144, 2560, 3840, 0, 512, -4352, -5376, -4608, -11520, -20736, -22272, -20480, -14592, -8448, -2816, -1536, 512, 7680, 18944, 22016, 19712, 14080, 8704, 10752, 12288, 3328, -9984, -12800, -5120, 3840, 8704, 3584, 4096, 3072, 1024, -1280, -6656, -4096, -4864, -16384, -23552, -23296, -16640, -11008, -6656, -3072, -256, 4096, 12032, 21248, 19456, 16896, 10240, 8448, 11520, 8448, -2048, -13312, -10496, -1280, 8192, 7680, 3840, 6400, 3328, 2048, -5632, -7168, -2816, -8704, -21760, -25856, -22016, -13312, -9216, -6400, -3328, 3840, 8192, 17664, 20480, 17664, 13312, 8192, 9472, 9984, 4864, -7680, -13824, -6144, 2560, 9728, 6400, 6400, 5632, 4608, -1536, -8960, -5120, -3584, -15104, -25088, -25344, -17408, -10496, -7680, -5888, 1280, 7168, 13312, 18944, 17152, 15104, 11008, 8192, 8960, 8192, -512, -12032, -9728, -3328, 5888, 8448, 7936, 6656, 6912, 4096, -7424, -9472, -3840, -8448, -20480, -26624, -22784, -13824, -8960, -7936, -2816, 4352, 10752, 16128, 17408, 15360, 15104, 9472, 6912, 8448, 5632, -7168, -9472, -6656, 768, 8192, 9728, 7680, 6400, 7680, -768, -10496, -7424, -5888, -14080, -23040, -25088, -19456, -9984, -8192, -5376, 1024, 9216, 13312, 15616, 15616, 16128, 12288, 6144, 7168, 8704, -2560, -7936, -7424, -3584, 3840, 9472, 9472, 7168, 7936, 4864, -6912, -10240, -6144, -9728, -17664, -24320, -24576, -15360, -8192, -6656, -2560, 4864, 11520, 13568, 14848, 15104, 14848, 7424, 5888, 9984, 3584, -5376, -6400, -5888, 256, 6912, 11008, 8704, 8704, 5376, 0, -9216, -8192, -7936, -12544, -21504, -26112, -21248, -10496, -5632, -4864, -256, 8960, 12544, 13312, 13568, 14336, 9984, 5888, 8704, 8448, -768, -5888, -5632, -2560, 4352, 9216, 9216, 9984, 6656, 2048, -4096, -8704, -7424, -9216, -15616, -23808, -24320, -14848, -6656, -4608, -2816, 5632, 12288, 13568, 13568, 13056, 10496, 7936, 8448, 9472, 4096, -3840, -6144, -3584, 1024, 7424, 8704, 10496, 8192, 2048, -1792, -4864, -7168, -7680, -13824, -21248, -25856, -19456, -10240, -5120, -5376, 256, 9216, 13824, 14080, 11264, 8448, 8192, 8960, 9216, 7680, 1792, -6656, -4864, -1280, 5632, 9216, 9472, 9472, 3840, -768, -1280, -3840, -6144, -11008, -19200, -24064, -22272, -12032, -7424, -6400, -3584, 6656, 12288, 15872, 12544, 7424, 5888, 8960, 11520, 9728, 4864, -4096, -7168, -1792, 2560, 7424, 8192, 9728, 5888, -512, -2560, -1536, -3072, -7168, -17152, -23040, -25088, -15104, -8192, -7168, -6400, 768, 11008, 14336, 15104, 6400, 4096, 6144, 11776, 11008, 7936, 0, -7936, -3584, 1280, 6400, 7424, 8192, 7424, 1536, -3328, -1536, -768, -2048, -12544, -21760, -24832, -19200, -7936, -7680, -7680, -3072, 7936, 12800, 15616, 10240, 3072, 3584, 8704, 13568, 11008, 5120, -5888, -5120, -768, 5376, 7424, 5888, 6144, 3840, -2560, -2048, -256, 512, -6400, -19200, -25088, -23552, -10752, -7936, -8960, -6144, 3584, 10496, 12800, 12544, 5632, 2816, 5120, 11520, 13312, 9984, 0, -6656, -3072, 2304, 8960, 6400, 4608, 3584, 256, -3328, -1536, 1024, 768, -12544, -22784, -26112, -15616, -6912, -7680, -6912, -1024, 8704, 11776, 11776, 8192, 4352, 3328, 6656, 12032, 12800, 7424, -4864, -5632, -1024, 7680, 9472, 3840, 1792, 1792, -1280, -2560, -1024, 2304, -5120, -18432, -25600, -22016, -10496, -8448, -7936, -4096, 4608, 11008, 8704, 8192, 6912, 5888, 3840, 7936, 12032, 12288, 2304, -6144, -4096, 3072, 11008, 6400, -512, 0, 2304, -2304, -3840, 512, 2048, -10240, -22272, -25344, -17664, -9472, -7936, -4864, 1536, 9728, 8960, 6400, 7936, 8960, 6656, 4608, 9216, 12544, 10240, -2560, -5632, -2304, 7424, 10240, 1536, -3072, 1536, 1536, -4096, -2816, 2304, -1536, -15616, -24320, -23040, -14848, -8960, -6656, -1280, 5888, 9216, 4608, 5376, 9216, 10496, 7168, 5632, 9728, 13312, 5888, -4352, -4352, 1792, 9984, 5376, -3072, -3328, 4096, -2048, -5632, -1280, 1536, -6400, -19712, -23808, -20224, -11776, -7680, -2816, 3840, 9216, 5632, 1280, 7424, 12032, 12032, 6144, 5632, 10496, 12288, 1792, -3840, -1024, 5632, 8448, 1536, -5888, 1024, 2048, -5376, -3840, -256, -1280, -12544, -20224, -23552, -18176, -11008, -5120, 2816, 7936, 7424, 1024, 4096, 10240, 14080, 10496, 5632, 7936, 12800, 6400, -2304, -512, 2048, 5888, 4096, -4352, -1536, 2048, -2560, -3840, -1536, -1024, -7424, -14336, -20480, -22016, -15616, -10752, 0, 7680, 8448, 3072, 512, 6144, 12032, 14080, 9472, 7168, 9984, 10240, 1024, -256, 1536, 1536, 4096, -1024, -3328, 256, -512, -2304, -2816, -2816, -5376, -8960, -14080, -20992, -20480, -16384, -6144, 6912, 9216, 5888, 768, 2560, 8960, 15616, 14080, 10240, 8960, 8960, 4864, 1536, 3072, 1024, 256, 768, -3072, -768, -512, -1024, -1024, -3584, -5888, -7680, -9472, -14848, -21248, -21504, -14848, 2048, 9472, 8448, 2816, 768, 5120, 11776, 15872, 14080, 12800, 7168, 4096, 3072, 3840, 2304, -1024, -2304, -2304, -1024, -1280, -1792, 512, -1792, -7168, -8960, -7936, -9216, -17152, -23040, -22016, -5888, 7168, 9728, 6400, 1280, 3328, 8704, 14848, 14848, 17664, 12800, 3840, 2560, 5120, 4096, -768, -3584, -3584, -512, 256, -3072, -768, 768, -5120, -9216, -9984, -6656, -11776, -20736, -25088, -15616, 1536, 6912, 7680, 4096, 3072, 6400, 12800, 14592, 16896, 18944, 7936, 1024, 4096, 5376, 2048, -3328, -5376, -2560, 2048, -1280, -2816, 1536, -2048, -7936, -10240, -7424, -7680, -16896, -23808, -21504, -5632, 4352, 5632, 6656, 4096, 5120, 11008, 14336, 14336, 17920, 15360, 4352, 2048, 4608, 3840, -2560, -6656, -5376, 1536, 1792, -3072, -256, 256, -5120, -8448, -8704, -7936, -13056, -20224, -23552, -13312, -1536, 2304, 4864, 5888, 5376, 10240, 14592, 15104, 15360, 18432, 11008, 4352, 3328, 4608, 768, -5888, -8192, -1280, 3584, -1792, -2816, 1792, -3072, -6656, -7936, -9472, -11776, -16896, -21760, -17152, -5376, -1280, 768, 4096, 5632, 9472, 13824, 15104, 14080, 15360, 14848, 7680, 4096, 3328, 2816, -3840, -8704, -5888, 2304, 1792, -3072, -512, -1024, -4864, -4096, -7936, -12544, -16384, -19456, -18432, -8960, -3072, -3584, 0, 3840, 8704, 13568, 15360, 14848, 13568, 14592, 11008, 7680, 4608, 3072, -1024, -6912, -7168, -2048, 3584, -768, -2304, -512, -3328, -2304, -4352, -12544, -16896, -17920, -17664, -11264, -3840, -4864, -2816, 512, 5376, 13568, 16384, 17408, 14080, 12288, 11264, 9216, 7168, 3840, -256, -4608, -5888, -4864, -1024, 1280, -768, 256, -2304, -1792, -256, -8960, -17920, -18944, -17920, -12800, -5376, -3584, -5632, -1792, -256, 9984, 16896, 19712, 17664, 11776, 9728, 9216, 9728, 5632, 1280, -3072, -4096, -3072, -4352, -2048, -1280, 512, 256, -1536, 1280, -3328, -16384, -19968, -18688, -15360, -7936, -3584, -4352, -4096, -2560, 1792, 15616, 20224, 20736, 14592, 9728, 7168, 8192, 6144, 2304, -1024, -2560, -1024, -2816, -5120, -3328, -512, 2816, 1024, 1024, -512, -10496, -19456, -19456, -17664, -11008, -5632, -3072, -4352, -3584, -3584, 6400, 18944, 23552, 20224, 12032, 7936, 6656, 6656, 2816, 768, -1280, 0, 0, -5120, -6656, -2816, 2304, 3584, 2304, 1024, -6144, -15616, -19456, -18944, -13568, -7680, -3328, -2048, -3072, -6400, -2048, 13056, 23040, 23808, 16128, 10752, 5376, 4608, 3328, 1536, 512, 256, 2048, -3072, -7680, -6912, -512, 3584, 4608, 2816, -3328, -12288, -17408, -20224, -17920, -11264, -4864, -512, -1280, -5376, -7936, 4608, 19712, 25600, 20736, 14080, 7424, 1792, 2048, 1536, 1792, 1024, 3584, 0, -6656, -8704, -3328, 2304, 4096, 4352, 256, -8960, -14848, -17920, -20992, -15872, -7424, -512, 256, -3584, -9216, -3840, 12800, 22784, 24320, 18176, 11776, 1280, -1536, 1024, 2816, 768, 2816, 3584, -3072, -7936, -5632, -512, 2048, 4096, 4096, -3840, -13568, -14336, -20480, -20736, -10496, -1280, 2304, -768, -7680, -8704, 4352, 18688, 24832, 22016, 16128, 6400, -3072, -1536, 2816, 3328, 256, 3840, 1024, -4864, -6400, -1280, 512, 2304, 4864, 2560, -9984, -12288, -15616, -24320, -17152, -4352, 3072, 2048, -5888, -11008, -2304, 12544, 21760, 23296, 19456, 12800, 256, -5888, 512, 5632, 1280, 512, 3584, -1280, -5888, -3072, 0, -512, 3328, 4352, -3840, -12288, -11008, -21248, -22528, -9728, 1280, 4352, -2816, -10496, -7168, 6912, 17152, 21248, 20992, 16640, 7424, -5376, -4608, 5376, 4864, -1792, 768, 1536, -2048, -3584, 256, 0, 0, 3328, 512, -8704, -10752, -15104, -25344, -16128, -3072, 4352, 0, -8960, -10752, 256, 13568, 17664, 20224, 18432, 13568, -256, -8704, 512, 8192, 768, -2048, 256, 512, -512, -768, 2048, -512, 768, 1792, -4608, -10240, -9984, -19456, -20736, -8960, 2304, 4352, -5632, -11776, -6144, 8704, 15104, 17408, 18944, 16896, 6912, -6656, -5632, 7936, 6144, -2560, -2816, 0, 3584, 256, 1280, 2048, -1280, -512, -2560, -8704, -8960, -12288, -19712, -15104, -3328, 5120, -1024, -9472, -8960, 2048, 12032, 14080, 17408, 18944, 12544, -1024, -8704, 2560, 9984, 256, -3328, -2816, 3584, 3584, 768, 5120, 1536, -2304, -3584, -7424, -9472, -7168, -14336, -16896, -10752, 2304, 2304, -6400, -9728, -3584, 6912, 11520, 13824, 18432, 15616, 5376, -6400, -3584, 7936, 4864, -2560, -3840, -512, 5632, 1536, 5632, 6144, -1024, -5120, -7168, -9728, -6144, -7168, -13824, -14592, -5120, 3584, -2560, -7424, -6656, 512, 7424, 9984, 15616, 16896, 9984, -1536, -6400, 4096, 7680, 0, -4096, -2048, 3072, 3328, 4608, 9728, 2560, -5120, -9216, -8704, -7936, -4096, -8448, -14336, -10752, 0, 0, -5376, -5632, -3072, 2816, 6400, 12544, 17408, 13568, 3584, -5120, -768, 7424, 3840, -2816, -3072, 768, 3328, 3328, 10752, 8704, -3072, -9984, -9472, -6912, -5632, -4608, -11264, -12800, -5376, 768, -3072, -3840, -4608, -1280, 2304, 6912, 15360, 15360, 8192, -1536, -3072, 5376, 6400, -1024, -3072, -512, 1792, 2048, 8448, 13568, 2048, -9472, -10496, -6400, -5632, -4096, -6912, -12032, -8704, -2560, -2560, -3840, -3840, -3840, -1280, 1280, 10496, 16128, 11264, 3072, -2816, 2560, 8192, 2560, -3584, -2048, 2048, 1280, 4864, 13568, 8704, -6144, -11008, -6400, -3584, -3840, -4864, -8960, -8960, -5120, -3072, -2048, -3584, -4352, -4864, -3328, 4864, 14080, 13568, 5632, -2048, 1024, 7936, 6656, -2048, -3328, 1536, 2560, 1792, 9984, 12800, -512, -10496, -7936, -2560, -3328, -5888, -7936, -8448, -6144, -3840, -1792, -3328, -4096, -5632, -5888, -1536, 9728, 14080, 8704, 256, -256, 5888, 8704, 2304, -4608, -768, 3584, 2304, 5120, 13056, 6144, -7168, -9472, -1536, 512, -5120, -7680, -6912, -5376, -5632, -1536, -3072, -4352, -5376, -8192, -6912, 2304, 12544, 11008, 3072, -1024, 3584, 8704, 6144, -2304, -3072, 3072, 4864, 3328, 7680, 9472, -768, -8960, -3840, 3072, -2560, -7936, -7680, -3840, -4608, -3328, -768, -4864, -5120, -7936, -8960, -4352, 7168, 11264, 5632, 0, 1792, 7168, 6912, 1280, -3840, 256, 5120, 5120, 4352, 7168, 4864, -5376, -5888, 3072, 2048, -5632, -8192, -5120, -2048, -3840, 0, -3328, -5888, -6400, -11008, -9216, 1024, 9472, 7680, 2816, 1024, 5632, 7168, 3840, 0, -2560, 2304, 5888, 3584, 2816, 6144, 1280, -5376, 512, 4352, -2048, -6912, -6912, -1792, -2560, -1536, -256, -5120, -6656, -9984, -13568, -5120, 5888, 9216, 4352, 1792, 3584, 7168, 4096, 3072, -768, 512, 4864, 4096, 512, 3584, 4864, -2048, -1280, 4352, 1024, -3840, -6656, -2560, -1024, -3072, 256, -2048, -5888, -9728, -14848, -10496, 0, 7424, 5888, 2816, 4096, 5376, 3840, 2304, 2816, -1536, 2816, 5120, 1024, 768, 6144, 1280, -1280, 2560, 4352, -1536, -3840, -3840, 1536, -3840, -2048, 0, -2816, -9472, -13824, -14336, -6144, 3328, 7424, 3072, 3840, 5120, 4864, 1536, 4096, 1280, -512, 2560, 2816, -768, 5632, 4608, 0, 1536, 5120, 2560, -1536, -3072, 256, -1536, -5888, 0, 256, -5888, -14336, -15360, -11008, -2560, 4864, 5632, 3840, 5632, 4608, 1536, 2816, 4352, -512, -1280, 2560, 1024, 1792, 5888, 256, 768, 4096, 5632, 1280, -256, 0, 1280, -5376, -3584, 1536, -1536, -11776, -16384, -13824, -7424, 256, 4352, 4608, 6144, 6400, 2560, 256, 4352, 2304, -2048, -256, 3840, 1536, 5120, 2816, 512, 3584, 6400, 4096, 2304, 1280, 1792, -2816, -6656, -1280, 1024, -6912, -15872, -15872, -10240, -4352, 2048, 2816, 5376, 7424, 4352, -512, 2560, 4352, -2048, -4096, 1536, 3328, 2816, 3840, 768, 2048, 6144, 6656, 3584, 3072, 3072, 1024, -6656, -3840, 256, -3072, -12800, -16384, -12288, -6912, -2560, 1280, 2048, 8192, 7936, 256, -256, 4608, 0, -5888, -1536, 4608, 3584, 2816, 1280, 768, 4352, 8960, 6400, 4096, 4608, 3584, -2816, -6912, -2048, -1536, -7680, -14080, -13568, -9216, -5120, -1280, 1280, 3584, 11008, 3328, -1536, 2816, 2816, -5632, -5632, 1792, 4864, 3328, 2560, 256, 1792, 7680, 9216, 5632, 5888, 5888, 1536, -7168, -5120, -1536, -5888, -11008, -12544, -11008, -7424, -4864, 768, 256, 8704, 7424, -1024, 768, 3328, -3328, -8192, -768, 5120, 3584, 2816, 1280, 512, 5888, 10752, 8704, 5632, 5888, 5376, -3328, -6656, -3584, -4864, -8192, -9728, -11008, -8192, -7424, -1536, 1024, 4096, 8960, 2304, -1024, 2816, 0, -8448, -5632, 2304, 3328, 3072, 2304, 768, 3584, 8960, 12032, 8704, 5888, 6912, 2048, -5632, -4864, -4096, -7680, -7424, -10752, -8448, -8192, -5888, 1024, 2304, 6144, 5120, -256, 768, 2560, -5120, -9216, -1280, 3328, 2304, 2816, 2048, 2048, 5376, 11008, 12288, 6912, 5632, 5888, -1792, -6400, -5120, -7168, -6400, -7936, -9216, -7168, -8448, -2048, 2816, 3584, 3584, 1536, -2048, 1792, -1280, -9984, -6400, 1792, 3584, 2304, 2560, 3072, 3840, 7424, 14080, 10496, 5888, 5632, 2304, -3072, -5888, -7168, -6144, -5888, -8704, -6656, -7936, -5376, 2304, 4864, 2304, 256, -768, -256, 1792, -8192, -9728, -2304, 3328, 2816, 2304, 2816, 3584, 5376, 11776, 13568, 8192, 6144, 3072, -512, -4096, -6656, -6144, -4352, -8704, -8448, -6400, -6144, -1024, 4352, 3584, -768, -1024, -1792, 768, -3328, -11776, -6400, 512, 4352, 1280, 2048, 3072, 4608, 8192, 14336, 9728, 7424, 3840, 2048, -1024, -5632, -7680, -3584, -5632, -10752, -6400, -3840, -2560, 1536, 4352, 256, -1280, -1792, -2560, -512, -9728, -9472, -1792, 3840, 2304, 512, 2048, 5376, 6656, 11008, 11264, 7424, 4608, 1792, 3072, -2304, -6400, -6144, -2816, -8960, -11008, -4352, -1280, 768, 2560, 2304, -768, -768, -5888, -2304, -5888, -11520, -5632, 1792, 3840, 512, 1024, 4352, 8448, 7936, 11520, 8960, 5888, 2048, 4352, 1536, -4096, -6656, -3584, -5120, -12288, -6912, -512, 1536, 2816, 2304, -256, 1536, -3840, -7168, -4608, -9984, -8192, -1792, 2816, 1792, 1536, 1792, 8448, 7680, 7936, 10496, 6912, 1792, 3328, 6144, -768, -4608, -5632, -2304, -10240, -10496, -2560, 1024, 2304, 4352, 768, 1280, -1024, -9472, -7424, -7424, -8960, -4864, 256, 2560, 768, 1792, 6400, 10496, 4864, 7936, 8192, 3328, 1280, 6912, 3584, -1536, -4864, -3072, -5888, -12288, -5632, 1792, 2048, 4096, 2816, 256, 1536, -7424, -11776, -8192, -8192, -5120, -1280, 1792, 1024, 768, 5376, 11008, 8192, 3840, 7424, 4096, 2048, 4864, 6656, 768, -2304, -5632, -3328, -10752, -9472, -2048, 2816, 3584, 6400, 2304, 1024, -4352, -12800, -11264, -7680, -6400, -3584, -256, 2816, 256, 4608, 9216, 10496, 3072, 3584, 4608, 3584, 3840, 5120, 4352, 1536, -3584, -4608, -6912, -9984, -4864, 1280, 3072, 6144, 6912, 2048, -3328, -12544, -13568, -8192, -6912, -4864, -3072, 1792, 1792, 3072, 7936, 11008, 6656, 512, 2048, 3584, 5632, 3328, 4352, 4608, 1536, -4352, -6656, -9216, -7168, -1536, 3584, 6400, 8960, 5120, -1536, -10752, -14592, -9472, -5888, -5888, -5120, 0, 2304, 2048, 6400, 10496, 10240, 1792, -1024, 256, 5888, 5376, 3584, 5632, 5120, -512, -6144, -8704, -7936, -3328, 2048, 6144, 9472, 8448, 2048, -8192, -15872, -11264, -5120, -5632, -6912, -2304, 2304, 1792, 4096, 7936, 10752, 5120, -2560, -3328, 2560, 6656, 1792, 3328, 6400, 4608, -2816, -8960, -9984, -5120, 0, 4352, 9472, 9472, 4864, -4352, -14848, -14080, -6656, -4608, -6400, -5376, 0, 3584, 3072, 5120, 9728, 8960, 0, -4864, -2304, 6144, 4864, 768, 5376, 7936, 4352, -6144, -10752, -7680, -768, 3328, 8704, 10752, 7168, -512, -11520, -15872, -9728, -5632, -4864, -5120, -3072, 3072, 4352, 2816, 7424, 10752, 4608, -4096, -5120, 768, 6144, 512, 1024, 6656, 9216, 0, -9728, -11520, -3328, 3072, 6912, 10496, 8704, 3584, -6912, -15872, -14080, -7680, -4864, -3840, -4096, -512, 4608, 2816, 3584, 9472, 7936, -1536, -5632, -3072, 3840, 2560, -2560, 3072, 9216, 7680, -4864, -11776, -8448, 2816, 6144, 7168, 8960, 7168, -1280, -11264, -16640, -11264, -5888, -2816, -2304, -2048, 1280, 3584, 2560, 6400, 9472, 3584, -4352, -4608, -512, 3584, -1792, -1536, 5888, 11008, 2560, -8448, -9728, -2304, 6144, 6144, 7168, 7680, 2816, -5376, -14592, -15616, -9984, -3072, -1280, -1280, -768, 1792, 2560, 4352, 7936, 7680, -768, -5120, -3584, 1536, 256, -4096, 512, 9728, 9728, -1280, -7680, -6144, 3328, 6400, 5376, 7168, 3840, 256, -8704, -16384, -15872, -5888, 0, 512, -256, -256, 1280, 3584, 6144, 8448, 3584, -3072, -5888, -1024, 1792, -4608, -4608, 4608, 11008, 6400, -2304, -5632, -512, 5376, 4864, 6144, 5120, 2816, -3328, -12032, -17664, -11776, -1792, 1280, 1536, -256, -1024, 2304, 5376, 7936, 6400, 1280, -3840, -5120, 768, -2048, -8448, -1792, 7424, 9472, 5120, -2560, -2560, 2304, 3840, 4352, 3584, 3072, 256, -5888, -14080, -17920, -7680, 1280, 3328, 512, -2048, -256, 3840, 6400, 7680, 3840, -256, -5120, -2048, -768, -7936, -7168, 2048, 7936, 10496, 3840, -1536, 0, 2304, 3584, 3072, 2304, 2048, -2560, -7168, -16128, -14080, -3072, 4352, 2816, -1792, -3328, 2048, 5632, 6656, 4864, 2304, -1792, -3328, -1280, -5888, -9984, -2560, 4352, 10496, 9728, 2048, 0, 1280, 1792, 3072, 1280, 1792, -1536, -2048, -9984, -15360, -8960, 1792, 4864, 1536, -2560, -1536, 3840, 6656, 5632, 3840, 2304, -2048, -3328, -6144, -11520, -7424, -256, 7424, 12288, 7680, 512, 1536, 1280, 2304, 1280, -256, -1280, -1024, -3328, -13056, -13056, -4096, 5120, 3328, 0, -2816, 1792, 6400, 5632, 4608, 4352, 2560, -2048, -5632, -12800, -11008, -3328, 3840, 11776, 10752, 4096, 1792, 2048, 1792, 1792, -256, -1536, -2560, -1024, -6912, -11520, -9216, 1280, 4096, 1792, -1280, -1280, 5120, 5632, 4864, 4864, 5632, 1792, -3840, -11008, -15872, -7424, 768, 8960, 11008, 6912, 2816, 2304, 2048, 1024, 512, -2304, -3328, -1792, -3840, -7680, -11008, -4096, 3072, 3328, 1024, -2048, 3072, 6144, 4352, 4096, 6144, 6400, -768, -9728, -18432, -13312, -2304, 6400, 10752, 7680, 5376, 2048, 3584, 1024, 1536, -768, -3328, -3072, -3328, -4608, -9216, -8704, 768, 3584, 2304, -2304, 1280, 6656, 4608, 3328, 6656, 8704, 3328, -7936, -17664, -17408, -4096, 4864, 8960, 7424, 5632, 1536, 4096, 768, 512, 1536, -1280, -3840, -5120, -4864, -5376, -8704, -4352, 2048, 4096, -512, -768, 6144, 6912, 4096, 5888, 8704, 8192, -2560, -14336, -20480, -11520, 1536, 7424, 7424, 5632, 2560, 3584, 3328, -1024, 1536, 1792, -2048, -6912, -6912, -4608, -5120, -7168, -2048, 3584, 2048, -1792, 2816, 7424, 5376, 4352, 6400, 8960, 4096, -9216, -19712, -17152, -3584, 6400, 7680, 5632, 2816, 2560, 4864, 1280, 512, 1536, 1280, -4608, -8704, -6400, -3328, -5888, -4864, 1024, 3328, 0, 1792, 6144, 8192, 6144, 5632, 7936, 7680, -3072, -15872, -19456, -10496, 2304, 7168, 6144, 3840, 1536, 4608, 4096, 1536, 1536, 1792, -1792, -8192, -9472, -4096, -4608, -6144, -2048, 2816, 1792, 1792, 5120, 7936, 8960, 6400, 6144, 8448, 2304, -10240, -18432, -14848, -4096, 4352, 6912, 4096, 1536, 2560, 5632, 3072, 2048, 2048, 512, -5888, -11008, -6656, -4096, -6144, -4608, 512, 1536, 1792, 5376, 7424, 9216, 8192, 5376, 6912, 5632, -5376, -14592, -17152, -9728, -1024, 6656, 5376, 2304, 768, 4608, 6400, 4608, 2560, 512, -2816, -10752, -9216, -6144, -6912, -5888, -2304, 1280, 512, 4352, 8192, 10752, 9216, 6912, 4608, 6400, -512, -9984, -14848, -13056, -6912, 2816, 6912, 2816, 256, 2304, 6144, 6400, 5376, 1280, -2048, -7936, -9472, -7680, -8448, -6144, -3840, 0, -512, 3328, 7936, 12288, 12032, 8448, 3840, 4608, 2560, -6912, -12800, -13312, -11264, -3072, 5376, 5376, 1280, -256, 3328, 8448, 7680, 4096, -1536, -6656, -9984, -8448, -8960, -7168, -5120, -2560, -2048, 1024, 6912, 13056, 15616, 11520, 5376, 3328, 3584, -2816, -9984, -10240, -11264, -9216, 256, 6400, 4096, 256, 512, 6912, 10240, 7168, 768, -5632, -9728, -9728, -8192, -8448, -5376, -4608, -3584, -2048, 4608, 12800, 16896, 15360, 6912, 1792, 3072, -768, -7936, -9216, -9472, -11776, -6912, 4608, 6656, 1280, -768, 2048, 8960, 11008, 4096, -3584, -9216, -11008, -8192, -8192, -6400, -4096, -5888, -3584, 1536, 11776, 16384, 18944, 12544, 2304, 1024, 1792, -5888, -9472, -8704, -10496, -11264, -2048, 7936, 4864, -1280, 0, 5376, 12032, 8448, -512, -8448, -11008, -11008, -8192, -7424, -3584, -5632, -5888, -1536, 8704, 15872, 19200, 18176, 7680, 0, 2048, -3328, -9472, -8704, -8960, -11520, -8704, 4608, 7936, 1280, -1280, 1792, 8960, 11264, 3072, -5888, -11520, -12544, -10240, -7424, -4608, -4608, -6912, -3840, 5632, 14592, 18944, 20480, 14592, 3840, 1024, -256, -9984, -8704, -8704, -10240, -11776, -1024, 6400, 3328, -768, 512, 5632, 11264, 6400, -2560, -9728, -11264, -12800, -8704, -5120, -3584, -7936, -5376, 1280, 12032, 16128, 20736, 19456, 9728, 2048, 2304, -7680, -11520, -8960, -9216, -11008, -5120, 2304, 3584, 1280, 768, 1792, 9216, 8192, 768, -8192, -11008, -12800, -10240, -7168, -3328, -6144, -7168, -512, 8960, 14336, 18688, 22016, 14848, 5888, 5376, -2560, -12544, -11520, -8448, -9984, -6400, -768, 1280, 1280, 2048, 1280, 4608, 8192, 4352, -4864, -11520, -12544, -10496, -8960, -5632, -4864, -7936, -3072, 7168, 13312, 15104, 19456, 18944, 10496, 7936, 2560, -9984, -14848, -10496, -8192, -6912, -1280, -768, 768, 2048, 2048, 2560, 6144, 5632, -1024, -9984, -13312, -10752, -8960, -7680, -4608, -7168, -5632, 5120, 13568, 13312, 15360, 18688, 15872, 11008, 7936, -4608, -14336, -15616, -8960, -7168, -2304, -1536, -768, 768, 2304, 2560, 3072, 4608, 2048, -5888, -13568, -12800, -7936, -8960, -6144, -7168, -6656, 768, 12288, 14080, 13312, 15104, 16896, 14592, 11776, 1792, -9472, -17152, -13568, -6144, -2816, -1024, -1536, 0, 768, 3328, 2560, 1792, 2560, -1536, -9728, -14848, -9216, -7680, -7680, -6656, -6656, -2816, 8448, 15360, 14336, 12544, 15104, 17152, 14848, 8192, -3840, -14848, -17664, -8704, -3584, -2048, -1536, 256, -1024, 1792, 2048, 512, 1024, 1024, -5376, -13824, -12544, -7680, -7680, -7168, -7424, -4608, 3328, 13568, 15360, 12800, 11264, 16128, 15616, 12544, 2816, -8448, -18176, -12544, -4864, -2304, -2560, 1280, 512, -256, 1024, -256, 1024, 1280, -1280, -9728, -14080, -10240, -7168, -5376, -6400, -6656, -512, 10240, 15616, 14336, 9984, 13568, 16896, 13824, 8448, -1024, -14080, -16128, -7424, -4608, -3072, 768, 2816, -1024, -1024, -2304, -768, 1024, 1024, -4608, -12544, -12544, -8960, -4608, -4608, -6400, -4096, 6144, 13056, 15360, 10752, 11008, 16896, 14592, 10752, 5376, -5888, -16128, -11264, -6656, -4608, -2560, 3328, 2304, -2048, -4608, -4352, 1280, 1280, -1024, -8960, -12032, -10752, -6144, -2816, -5120, -5376, 1280, 9216, 14336, 13568, 9472, 15360, 15104, 10240, 8704, 2816, -8704, -13312, -8448, -5376, -3840, 256, 5376, 512, -4864, -8448, -2560, 2048, 768, -5120, -10752, -10496, -8448, -3584, -4096, -4608, -1792, 5376, 11008, 13824, 9984, 12032, 15616, 11264, 7936, 6912, -1024, -10496, -12032, -7168, -5888, -2304, 2816, 3840, -2304, -8704, -8704, 256, 2560, -512, -7680, -9728, -8704, -4608, -3840, -4352, -2560, 2560, 6912, 11008, 10752, 10752, 13568, 13824, 9216, 6144, 3584, -3840, -10752, -9216, -8192, -5632, 256, 3328, 1792, -6656, -12288, -6144, 2816, 2560, -3584, -8960, -8192, -4864, -4096, -3840, -2816, 1280, 4608, 7936, 8704, 10496, 12288, 13056, 11776, 7168, 6656, 2048, -6656, -9216, -8448, -8960, -3072, 1792, 3072, -2048, -11520, -12032, -2304, 3328, 1280, -6144, -8192, -4352, -3584, -4096, -2816, 1536, 3584, 5120, 6656, 6912, 12032, 12544, 12544, 8704, 6400, 5632, -1536, -7936, -6912, -9984, -7680, -2560, 3328, 1536, -7168, -14592, -7936, -768, 3072, -1792, -7168, -4864, -2048, -5376, -4608, -512, 4608, 4352, 4352, 4864, 8704, 12032, 13568, 10752, 8704, 7680, 3328, -5632, -5120, -7680, -11264, -8192, -1024, 3840, -1792, -11520, -12544, -4608, 1024, 2560, -3584, -4608, 0, -2816, -6656, -1792, 3840, 5888, 2560, 2560, 5120, 8704, 13056, 12544, 9728, 10496, 7680, -2048, -7168, -3840, -9984, -12032, -7168, 1280, 2560, -6656, -14080, -8704, -2304, 2560, 768, -3328, -1024, 256, -5376, -4864, 768, 6400, 3328, 1280, 2304, 4608, 9216, 13824, 9984, 10240, 11776, 4096, -6912, -4352, -5888, -12032, -12032, -4608, 2304, -512, -12032, -13056, -5888, 0, 1024, 0, 256, 2304, -2816, -5120, -2304, 5120, 5888, 1024, 512, 2048, 5120, 11520, 11776, 9728, 13568, 10496, -3328, -7680, -4864, -9216, -13312, -10240, -2304, 1280, -5888, -13568, -8960, -1536, 1024, 768, 1536, 2560, 1280, -4096, -4352, 1536, 7680, 3072, 0, -1024, 2304, 8192, 12032, 11008, 14080, 14592, 4096, -6912, -7680, -7168, -11264, -13312, -7936, -1536, -2048, -11008, -11008, -3840, -256, -256, 2048, 2560, 3328, 512, -4608, -2816, 5376, 5888, 1536, -1280, 0, 4864, 8448, 10496, 14336, 17152, 11264, -1280, -8704, -8960, -8192, -11776, -12032, -6912, -1792, -7680, -11264, -5888, -512, -512, 768, 1792, 3584, 4608, -256, -4864, 1024, 5120, 4096, -1280, -2304, 2560, 6912, 7680, 11776, 16640, 16128, 6656, -5632, -10752, -8704, -10496, -11776, -10240, -4608, -6400, -9984, -7168, -1024, 256, -256, 1280, 2560, 6144, 4864, -2048, -1536, 2816, 5120, 1024, -3328, 512, 5632, 6144, 9216, 15104, 17920, 13056, 1280, -9984, -9984, -11008, -12032, -11520, -7936, -7680, -9984, -8448, -1792, 256, -512, 256, 1024, 4864, 6400, 1280, -1280, 256, 3072, 3328, -3072, -3072, 4608, 6400, 5376, 11776, 17408, 17664, 9216, -4352, -9984, -11264, -13056, -11008, -8448, -8960, -10496, -9728, -3840, 2048, 0, 0, 0, 3328, 6656, 4864, 1280, 0, -256, 2560, -512, -3584, 1280, 6400, 4864, 7424, 13824, 18176, 15104, 2304, -7936, -11008, -14336, -12800, -8192, -9728, -12032, -10752, -6656, 2048, 2560, -768, -768, 1792, 5120, 5888, 4096, 2048, -1280, 768, 512, -4352, -1536, 5632, 5120, 4608, 10240, 16896, 18176, 9472, -3328, -9216, -13312, -15616, -9728, -8192, -12032, -13056, -9728, -1792, 4864, 1536, -1536, 1024, 3584, 4864, 5376, 4864, 512, -1280, 0, -3328, -3072, 3584, 5376, 3328, 6912, 13568, 18176, 14592, 3072, -6400, -10752, -15616, -13824, -8448, -9728, -13312, -12800, -5632, 3328, 4352, -1024, 256, 4096, 4352, 4864, 6400, 2816, -512, -512, -2816, -4608, 1536, 5376, 3840, 4608, 11008, 16896, 17152, 8704, -1792, -7680, -12544, -14848, -10752, -9216, -10752, -13824, -9216, -512, 5120, 1024, -1024, 2816, 4096, 4352, 6656, 4352, 1024, 256, -2048, -5632, -2048, 4352, 4096, 4352, 6912, 14080, 16896, 12288, 2560, -6400, -9216, -12544, -13312, -10752, -9984, -12032, -11776, -4608, 3328, 3584, -256, 768, 3328, 4864, 6912, 4608, 512, 1280, 256, -3584, -4352, 1536, 3328, 4096, 6656, 11264, 16384, 13824, 6912, -3840, -7680, -8448, -12544, -12800, -11008, -11264, -11520, -7680, -256, 3328, 768, 1536, 2560, 5632, 7680, 5376, 768, 512, 512, -768, -4608, -2304, 2048, 2816, 5888, 8960, 14080, 14848, 9472, 256, -6400, -4608, -8448, -13056, -12288, -11776, -10496, -7680, -4352, 1536, 768, 1792, 2304, 4096, 7680, 6912, 2304, 768, 768, 256, -2560, -4608, 0, 768, 3072, 9472, 11776, 13312, 10240, 3840, -5888, -4096, -3584, -9984, -12288, -12288, -11520, -7936, -5120, -1792, 256, 1024, 3584, 3328, 5376, 6656, 4096, 512, 256, 256, 256, -4096, -3072, 256, 1280, 7424, 12800, 12032, 9984, 5376, -2816, -5376, -768, -5888, -10496, -11520, -12032, -9472, -5376, -3328, -1536, 256, 4096, 5120, 5632, 5632, 4608, 2560, 512, 256, 1536, -1792, -4096, -2560, 0, 4096, 13056, 13568, 9728, 5632, -256, -5376, -256, -1024, -7680, -10496, -11520, -11520, -7168, -3328, -3328, -2048, 3328, 6144, 6656, 3840, 3328, 3840, 2048, -1024, 256, -512, -2816, -3840, -2816, 512, 10240, 14336, 11264, 5376, 256, -4096, -2560, 1280, -4096, -8192, -9728, -10496, -9216, -5632, -3584, -3840, 1024, 6144, 8192, 4608, 1792, 3584, 3584, 1024, -512, -256, -2048, -3072, -3840, -1536, 6144, 12800, 13056, 7168, 256, -3328, -3584, 1024, 256, -4608, -7936, -8960, -9216, -8448, -5376, -5376, -1280, 4864, 9728, 5888, 768, 1280, 4352, 3840, 512, -768, -1792, -2048, -4608, -3584, 3072, 9984, 12800, 8960, 512, -3584, -3584, -768, 1536, -1536, -6144, -6912, -8192, -10240, -6400, -5632, -3072, 2048, 8960, 8704, 2560, 512, 1280, 4864, 2304, -1536, -1024, -768, -3840, -4608, 1024, 7680, 10752, 10240, 3328, -4352, -4096, -1792, 768, 1280, -3584, -5376, -6144, -10496, -9472, -5888, -4608, -256, 5632, 9472, 4352, 1024, -256, 2816, 4352, 256, -1792, -1024, -3072, -5632, -1536, 6144, 8960, 8448, 6400, -1792, -6656, -3840, 512, 3584, 768, -4096, -4864, -8448, -10752, -6912, -5888, -2560, 3840, 7168, 6912, 2048, 512, 1280, 5120, 2816, -1024, -1536, -1792, -4864, -2816, 4352, 7936, 6656, 6400, 1536, -6144, -6400, -1536, 2816, 3584, -768, -3328, -6400, -9984, -8448, -5888, -4352, 1792, 4864, 6656, 4864, 1024, 256, 3840, 3584, -256, -1280, -2560, -3584, -5632, 2048, 8448, 7168, 5120, 4096, -3328, -6656, -4352, 2304, 5632, 1280, -2048, -4608, -9472, -8960, -7168, -5888, -1024, 3072, 4096, 7168, 3072, 256, 3072, 4608, 768, -512, -2304, -2560, -6912, -2560, 7424, 8704, 4608, 4096, 512, -6656, -7424, -768, 6912, 4864, -1024, -2560, -7424, -9216, -7680, -7424, -3072, 2304, 768, 4608, 5376, 1792, 3072, 4352, 768, -512, -1792, -1792, -4864, -6656, 3840, 9216, 5376, 3072, 2304, -3840, -7680, -4608, 4864, 7680, 1536, -1280, -5376, -8192, -6400, -7424, -5632, 1536, 0, 768, 5120, 3584, 3072, 4608, 3072, 0, -2304, -3072, -2304, -6656, -1024, 7936, 7168, 2816, 2560, -1536, -6144, -7424, 768, 8960, 4864, -768, -3840, -6656, -4864, -5888, -7936, -1536, 1024, -1792, 3328, 4864, 4352, 5120, 4608, 2304, -2304, -4864, -1280, -4352, -5120, 4096, 8704, 4608, 2304, 0, -4096, -6400, -2560, 7680, 7424, 768, -2560, -4864, -4864, -4096, -7424, -4864, 768, -2304, -1280, 3328, 5376, 6144, 4096, 3328, 256, -5888, -3584, -3072, -4864, -512, 7168, 5376, 2048, 256, -2816, -5888, -4864, 4096, 10496, 3584, -2048, -3328, -2304, -3328, -4608, -6912, -1024, -1280, -3072, -256, 4864, 7936, 4608, 2560, 4096, -5120, -5632, -3328, -3584, -3072, 4608, 6656, 3072, 1024, -1024, -4352, -4608, -256, 9728, 7936, -1280, -3584, -1792, -1792, -3584, -6144, -3328, -768, -3328, -3072, 1792, 7680, 8704, 3584, 4608, -1280, -8448, -4608, -2560, -3584, 256, 4864, 3584, 1536, -2048, -3328, -3840, -512, 4864, 10240, 2048, -3328, -2304, -1024, -2048, -4608, -5120, -2304, -3584, -4096, -1792, 5632, 9472, 5888, 4096, 2560, -6656, -7168, -3328, -2304, -1280, 3584, 3584, 2304, -2304, -4352, -3328, -256, 2048, 7936, 6656, -1536, -2560, -1024, -512, -3072, -4864, -2816, -2816, -4352, -3072, 1536, 8704, 7424, 3840, 4096, -1792, -8960, -6400, -2304, -1536, 2048, 3584, 3072, 256, -3840, -3584, 768, 2560, 4864, 7424, 2048, -2560, -2304, 256, -1792, -5120, -2560, -2304, -4352, -4352, -256, 7680, 8960, 4608, 3840, 1280, -7168, -8448, -4352, -1536, -1024, 2048, 3328, 1280, -3584, -4864, 256, 3584, 3584, 5120, 4352, 0, -2048, -512, -768, -3584, -4608, -2304, -3072, -4608, -1536, 5376, 9472, 6656, 1792, 2560, -3328, -8448, -6144, -1536, -512, 0, 2304, 2816, -1280, -4864, -1792, 4096, 4608, 3328, 4608, 2816, -512, -1536, -768, -1536, -5632, -2560, -2816, -4096, -2816, 4352, 8704, 8192, 2304, 2304, 512, -6656, -7680, -3584, -512, -1280, 768, 2048, 768, -4096, -3072, 2048, 5376, 3328, 3328, 3840, 512, -768, -1280, -1280, -5120, -4096, -2048, -4096, -5120, 1536, 8192, 8704, 3584, -1024, 1536, -3072, -6656, -5120, -1792, -1536, -1024, 1024, 1792, -512, -3840, 256, 4352, 3840, 2304, 3840, 2560, 0, -768, -1792, -3840, -5632, -1024, -1792, -4864, -1792, 7424, 9216, 5120, -1536, -256, 0, -4352, -4864, -3072, -2304, -1792, -256, 512, 1536, -768, -2048, 2560, 4608, 2304, 2048, 5376, 1024, -512, -2048, -3328, -5120, -3072, -512, -4096, -3584, 3584, 9984, 6656, -768, -4352, 256, -1536, -4096, -3072, -1792, -2304, -2304, 0, 768, 2816, -768, 0, 3840, 3328, 768, 4864, 3072, -2048, -1536, -3584, -4864, -4096, 0, -1536, -4352, 768, 8448, 8960, 1280, -4608, -2304, 256, -3840, -2816, -2048, -2048, -4096, -2048, 256, 3840, 3840, 768, 2816, 4864, 512, 3072, 6656, 0, -2560, -3328, -5376, -2816, 256, -256, -4608, -512, 5888, 8960, 4352, -3072, -5376, -512, -2048, -2304, -2048, -2304, -3072, -4352, -1280, 2560, 5632, 2048, 1792, 4608, 1792, -256, 5888, 3328, -3328, -4864, -5888, -3584, 1280, 512, -3840, -3328, 4352, 7680, 5632, -768, -6144, -1792, -512, -2304, -1536, -2560, -2048, -5376, -4864, 1280, 5632, 5632, 3328, 3840, 3328, -768, 2816, 4608, -1024, -5120, -7168, -5120, 1024, 2816, -2560, -4608, 1536, 6656, 4352, 768, -5120, -3072, -512, -2816, -1792, -2048, -2048, -4096, -6912, -1792, 4864, 7680, 5376, 4864, 3840, 1024, 768, 4608, 512, -4352, -8448, -6144, 0, 4352, 256, -4096, -1536, 6144, 4864, 1280, -4352, -4608, 256, -2048, -3072, -1792, -2816, -2560, -5632, -3584, 2560, 7424, 7424, 8192, 5888, 3328, 0, 2304, 1536, -3072, -7168, -9216, -1792, 3328, 3072, -2048, -4352, 3072, 6144, 1536, -2560, -5120, 256, 256, -3328, -2304, -3072, -4096, -5120, -4352, 0, 5376, 6912, 7936, 8960, 5120, 1792, 0, 512, -3328, -4864, -9472, -4864, 2048, 4608, 2304, -4096, -2304, 5120, 2816, -512, -6400, -3328, 2048, -1024, -4096, -3328, -4608, -5888, -4352, 0, 3584, 7424, 6912, 11008, 8960, 4352, -256, -1024, -3328, -5632, -7424, -7936, -512, 4352, 5120, -1280, -5376, 1536, 4096, 1280, -4096, -6400, 1024, 2816, -3072, -4352, -5120, -6912, -4864, -512, 3328, 6656, 6912, 9216, 11776, 8192, 1792, -2048, -4608, -6656, -6400, -8192, -4096, 3072, 6656, 2816, -4608, -2816, 1024, 3328, -256, -6912, -3072, 3584, 512, -5376, -5888, -7936, -6656, -2816, 2560, 6144, 7680, 7424, 11008, 12800, 6144, -1024, -4096, -8704, -7168, -7168, -6912, -256, 6912, 6144, -1280, -5376, -3072, 1536, 4096, -3328, -7168, 256, 3328, -2304, -5888, -8448, -8192, -4608, 512, 6144, 8704, 8448, 8704, 12800, 12544, 3072, -2816, -8704, -9472, -7168, -6400, -3584, 3584, 7168, 2560, -2560, -6400, -2304, 5376, 3840, -6912, -3840, 3072, 512, -4608, -8448, -9216, -6144, -1792, 3328, 7680, 9984, 10752, 8960, 13824, 9216, 256, -7424, -11520, -8960, -6656, -4352, -256, 5120, 4864, 512, -5888, -7680, 256, 7680, -1280, -8192, 256, 1792, -2048, -6912, -9472, -6400, -3072, -256, 5888, 9472, 13056, 9728, 10496, 12544, 4096, -3840, -10496, -10240, -7936, -5376, -2816, 1024, 4864, 3840, -2048, -8448, -4864, 5632, 5120, -5376, -3328, 512, -1536, -4352, -9216, -8192, -2816, -2048, 2304, 7168, 12288, 13824, 9216, 12288, 7680, 768, -7680, -10496, -8704, -6144, -3840, -1536, 512, 4352, 2048, -4864, -9472, 0, 7936, 768, -5120, -1536, -1024, -1792, -7936, -8960, -2304, -768, -1024, 4096, 9472, 15872, 11264, 10496, 8448, 3328, -2816, -9216, -9984, -7424, -5376, -2816, -2816, 1536, 3584, -512, -7168, -6144, 3840, 5632, -1280, -2560, -2816, -2560, -5120, -8960, -3328, 512, -1280, 512, 5376, 14080, 16384, 11776, 9472, 4864, 512, -5888, -9216, -7168, -5888, -4352, -4608, -4352, 2560, 2816, -3072, -8192, -1792, 5888, 4096, -1792, -3584, -4352, -2048, -6912, -5888, 256, 256, 0, 1536, 7936, 16128, 15360, 11776, 5376, 1792, -3072, -7424, -6144, -4608, -6144, -5888, -6912, -2816, 2816, 1280, -4096, -4864, 2816, 5376, 1024, -2304, -5376, -3840, -4352, -7680, -1280, 1792, 512, -256, 2304, 12288, 16640, 15104, 7680, 3328, -1024, -6400, -4864, -1536, -5632, -8448, -8192, -7936, -768, 1792, -768, -5120, -1024, 3584, 2816, -256, -2816, -4864, -3328, -5120, -4096, 2304, 1792, 512, -768, 6912, 15360, 17664, 11264, 3072, 1792, -4608, -5120, 256, -1024, -8960, -9728, -8704, -5632, -2304, 1024, -512, -2816, 2048, 2048, 512, -1536, -4864, -5888, -3584, -4096, 768, 3328, 512, 512, 3072, 12032, 16640, 15872, 5632, 2560, -768, -5376, -2304, 2304, -4352, -11776, -10240, -8704, -5888, -1536, 1024, -256, 768, 1792, 512, -1024, -3328, -6400, -4608, -2816, -1024, 4608, 768, -512, 1280, 7680, 14848, 16896, 9984, 3072, 2304, -2560, -4608, 2048, 1280, -10496, -12544, -9728, -8448, -4608, -1024, 512, 1792, 2048, 512, -1792, -3072, -4608, -5888, -3072, -1536, 4608, 3840, -2048, 0, 5376, 11264, 15872, 12288, 5632, 3584, 1792, -4096, -1792, 4608, -4608, -13312, -11264, -10752, -8192, -4608, -256, 3072, 2560, 1536, -2048, -5120, -2816, -4608, -4864, -2560, 3584, 6144, 512, -1280, 3584, 8704, 14592, 13056, 6912, 4864, 5120, -256, -3328, 3840, -256, -10752, -11520, -12544, -9728, -7168, -3840, 3328, 4864, 2560, -256, -5888, -4096, -2816, -6144, -2560, 1536, 5376, 3584, -1280, 768, 6144, 12288, 14848, 7424, 4352, 6144, 4608, -1536, 1024, 2048, -7168, -9728, -11776, -12800, -9216, -7424, 768, 5632, 3840, 1024, -4608, -7936, -1792, -5120, -4352, 1280, 2816, 4608, 1024, -512, 3840, 9472, 14848, 8960, 2816, 6656, 7936, 2816, -512, 1536, -3328, -8192, -9984, -14080, -11520, -9728, -4352, 5376, 5888, 2816, -2560, -7936, -4608, -2816, -6400, 256, 2304, 3584, 3840, 0, 1792, 6656, 12544, 12544, 3328, 2560, 8448, 6656, 2048, 1024, -1280, -6400, -8960, -11776, -13568, -10496, -8960, 1280, 6144, 4352, 0, -6400, -6656, -3584, -6144, -2304, 1536, 1280, 4352, 1536, 1536, 5120, 9728, 14080, 7680, 768, 6400, 9728, 4608, 2560, -1024, -4096, -7680, -10752, -13056, -11776, -10496, -4096, 5376, 5888, 3584, -4096, -7680, -4096, -4352, -4352, 0, 512, 3072, 4096, 768, 4352, 7168, 11776, 12544, 3584, 3328, 9984, 7680, 4352, 1024, -2304, -5120, -9728, -12544, -12800, -12800, -8704, 1024, 5376, 5120, 1024, -7424, -5888, -3840, -3840, -2048, -768, 1792, 4864, 2048, 2304, 6656, 8960, 12032, 7424, 1536, 7424, 8960, 6656, 3328, -1280, -4608, -7424, -10752, -12544, -13056, -12800, -4096, 2816, 5888, 4608, -4352, -8704, -3584, -3840, -2304, -2560, -512, 4352, 3584, 1280, 5376, 8448, 11264, 9728, 3584, 5888, 9472, 7680, 5120, 1536, -2048, -6656, -8704, -12032, -13312, -13824, -8704, 0, 4096, 4864, 1280, -7424, -5120, -3328, -2560, -2304, -2560, 1024, 4864, 2816, 3328, 7424, 9472, 9216, 5632, 5632, 9984, 8192, 5888, 2560, 512, -4608, -8192, -10240, -13824, -14336, -12544, -5888, 2048, 4352, 2816, -3840, -6656, -2816, -3328, -2304, -3840, -2816, 3584, 4352, 2560, 5888, 8704, 9216, 6144, 5376, 8960, 10752, 6656, 3072, 512, -1024, -5888, -7936, -12032, -14592, -12800, -8448, -1792, 4352, 2816, -512, -4608, -3072, -3072, -2816, -2560, -5376, -1536, 4608, 4864, 5376, 8448, 8960, 7168, 5888, 8704, 13056, 10240, 3072, -512, 256, -2304, -6912, -11008, -15104, -13568, -9984, -5888, 1024, 3840, 256, -2560, -3584, -2304, -2048, -2560, -5632, -4608, 1280, 4864, 4096, 6912, 8704, 7168, 5888, 6912, 12032, 13568, 6912, -768, -1024, -256, -3328, -8448, -13568, -14592, -11520, -7936, -3328, 3584, 1024, -1024, -2816, -2304, -2304, -2816, -4864, -7168, -4096, 2560, 6144, 5888, 8960, 6144, 6656, 6656, 9728, 15360, 11264, 512, -3328, -768, -1280, -4864, -11264, -14848, -12544, -8448, -6656, 256, 3584, 256, -1024, -1280, 0, -1792, -3584, -7424, -6656, -2816, 5120, 6912, 7680, 8192, 5376, 6912, 8704, 15104, 14848, 5632, -2816, -2560, -1536, -2560, -7424, -14080, -13568, -9728, -8704, -4096, 3072, 2304, -1280, -2048, 1280, 256, -4096, -7936, -8192, -7168, 0, 6656, 6656, 8448, 5888, 6144, 8448, 12544, 15616, 9472, 768, -3840, -2048, -2816, -4864, -11008, -14336, -11264, -8704, -6400, -512, 4352, 1280, -2816, 512, 3072, -512, -5888, -8192, -8960, -5888, 3584, 6656, 6912, 8960, 5888, 8192, 11520, 14848, 12032, 4864, -1280, -2304, -2560, -4096, -6912, -11776, -12288, -10496, -8704, -4608, 2816, 5120, -1536, -2560, 3072, 2304, -4608, -8704, -9728, -7424, -1792, 4352, 6912, 8192, 7680, 7680, 11776, 13312, 13056, 7168, 1536, -2048, -2304, -3840, -6144, -8192, -10496, -11520, -10240, -7680, -256, 5888, 2560, -3072, 512, 4352, -512, -7936, -9984, -8192, -4608, -1536, 4608, 7424, 9728, 8192, 11520, 13824, 13824, 8448, 2816, 512, -2304, -2816, -4864, -8192, -8448, -10496, -11520, -10240, -4608, 4096, 4864, 512, -1536, 3328, 3072, -5120, -11008, -8960, -5376, -4608, -1280, 5376, 8960, 9216, 11776, 14848, 13312, 9728, 4352, 2304, -1280, -2304, -3328, -7424, -8192, -7168, -10496, -11008, -9216, 0, 5632, 4608, -1024, -768, 4352, 512, -8448, -11008, -6400, -4608, -4096, 1024, 6912, 9728, 12032, 16384, 14592, 10240, 4608, 2560, 1280, -1792, -2560, -5632, -9984, -6144, -7680, -10752, -9984, -5632, 3328, 7168, 3584, -2304, 768, 4352, -4096, -13056, -9216, -4352, -5888, -4608, 2048, 8960, 12800, 16896, 17408, 11008, 5888, 3072, 3328, -256, -2816, -4352, -8192, -6912, -5632, -10240, -9728, -9472, -2560, 5632, 8704, 256, -2560, 2048, 1536, -9984, -12288, -6912, -4864, -6400, -2560, 4608, 12544, 16896, 19968, 13824, 6656, 4352, 4096, 768, -1792, -3840, -6400, -7424, -3072, -8192, -9472, -8960, -7168, 768, 9728, 6656, -1792, -1024, 2816, -3840, -11776, -10752, -6656, -5888, -6144, -512, 8704, 16896, 20736, 17920, 7680, 4864, 5376, 2560, -1280, -2816, -6400, -7424, -3072, -5120, -9472, -8448, -9984, -4352, 6400, 11776, 1536, -2816, 512, 0, -7424, -11264, -10496, -7680, -6912, -4352, 3072, 14848, 20224, 21504, 11776, 4864, 5632, 4864, 512, -1792, -6656, -8960, -3072, -256, -7424, -8448, -9984, -9216, 768, 11776, 7936, -2816, -1536, -256, -3584, -9728, -11776, -9984, -8192, -5632, -1280, 10240, 19456, 22528, 16384, 5888, 5632, 7680, 3072, -2048, -5120, -9984, -5632, 0, -3328, -7424, -8448, -11008, -5120, 6144, 12544, 3328, -3072, 512, -1536, -6656, -11520, -11520, -9984, -8192, -3840, 4864, 17408, 21760, 19712, 8192, 5632, 8960, 6912, 0, -4608, -9216, -9728, -1536, 768, -4352, -7424, -11264, -9472, -512, 10240, 8704, -2048, -1536, 768, -4608, -11264, -12032, -11264, -11008, -5376, 768, 12544, 19456, 20480, 13568, 5376, 8960, 9984, 3840, -4608, -8960, -10752, -5888, 512, -768, -4864, -8448, -10752, -5888, 4096, 11776, 4096, -2048, 512, -1536, -9472, -11520, -12032, -13056, -8448, -2048, 7936, 17408, 18944, 16896, 8448, 8960, 11520, 9216, -768, -8448, -10240, -8704, -1792, 1280, -2048, -4608, -8960, -9984, -3328, 8192, 8192, 768, -256, 1280, -6656, -11776, -12800, -13312, -11264, -5120, 3840, 15104, 17408, 17664, 12800, 8192, 10752, 12288, 5376, -6656, -10752, -10752, -6144, 512, 512, -2048, -5120, -9728, -8960, 1536, 8448, 4352, -512, 1280, -1536, -10496, -14080, -14592, -11776, -8448, -1536, 10240, 16384, 15872, 16128, 11520, 9728, 13824, 10240, -1024, -10752, -12800, -10240, -2816, 1536, -512, -2048, -6144, -10496, -4864, 4352, 7168, 2560, 0, 256, -6656, -13312, -16384, -13056, -10240, -5888, 4864, 13824, 14336, 15616, 15360, 9728, 13312, 14080, 6144, -7680, -12800, -12032, -6912, 1024, 2048, -1536, -2816, -7680, -9216, -1536, 4864, 6400, 1024, 256, -2304, -9728, -16384, -15616, -10752, -9216, 0, 11264, 14080, 13056, 16896, 12800, 12544, 15872, 11776, -1280, -12288, -13056, -10240, -2816, 2816, 1024, -3584, -3840, -9216, -6400, 256, 4864, 3840, -256, -512, -4608, -13568, -17664, -12288, -10752, -5120, 5376, 13056, 11520, 14336, 15872, 13056, 15360, 15104, 5888, -8192, -13568, -12544, -7168, 1280, 4352, -3072, -4608, -5632, -8192, -3072, 2304, 5120, 256, -1536, -1280, -7424, -17920, -15872, -12288, -8192, 512, 9216, 11520, 11264, 15872, 15872, 15360, 16384, 12032, -2560, -11520, -13824, -10752, -2816, 5376, 1280, -4864, -4608, -5888, -5120, -256, 3840, 1024, -1536, -512, -1536, -13056, -18432, -14592, -11264, -3328, 4864, 10240, 10496, 13056, 16640, 16896, 17664, 16128, 3584, -8192, -12032, -12800, -7680, 2560, 3584, -3072, -4096, -4608, -4096, -3584, 1792, 2048, -1536, -2048, -256, -5376, -16640, -17152, -13824, -7424, 256, 6656, 9728, 11264, 13568, 17664, 19712, 18688, 9472, -4352, -10496, -11776, -9472, -2560, 3328, -256, -2816, -3584, -3584, -2560, -1536, 2304, -1280, -1536, -2816, -768, -11008, -17152, -17408, -10752, -3840, 3072, 6912, 10240, 12032, 16640, 20480, 21248, 14080, 1792, -8704, -11008, -8704, -5632, -1280, 512, -768, -512, -3328, -2560, -2816, 768, -512, -1024, -3328, -1280, -3840, -13056, -18432, -16128, -7936, -768, 4096, 7424, 10752, 14080, 19968, 23296, 17408, 6400, -2816, -10240, -8192, -5632, -5376, -2304, -256, 2048, -256, -4864, -2816, -768, 256, -1280, -2816, -3072, -768, -7424, -14848, -17920, -12288, -4608, 1536, 3840, 8960, 12800, 17408, 22784, 21504, 9472, 2816, -6912, -9728, -4864, -5120, -5888, -2048, 2560, 4608, -2560, -4864, -2048, 1024, 0, -2816, -3584, -1792, -5120, -10752, -16128, -15360, -9472, -1024, 1792, 5888, 10496, 17152, 20992, 23040, 13568, 4864, -1024, -8704, -5888, -5120, -7936, -5632, 1280, 6400, 2048, -4352, -5120, 0, 2560, -1280, -5120, -2304, -3072, -7936, -12032, -15360, -13568, -6656, -768, 3072, 8192, 14848, 20736, 21760, 17920, 6912, 2304, -4864, -6656, -4864, -7168, -7936, -2048, 6144, 5376, -512, -6656, -2816, 3584, 2560, -5120, -4608, -2048, -6144, -8448, -13568, -14336, -11264, -5888, 768, 5632, 11264, 19712, 21760, 18944, 10240, 4352, -768, -5376, -5376, -6144, -9216, -6400, 2816, 5632, 3840, -3328, -7168, 1280, 5888, 0, -7168, -3072, -4864, -6656, -10752, -14336, -12288, -9984, -4352, 3072, 8704, 15872, 21504, 18688, 13312, 6656, 2304, -3072, -5376, -5632, -7936, -7680, -256, 3840, 4096, 1536, -6400, -3584, 5888, 4864, -4352, -5376, -3328, -6144, -8704, -13824, -11264, -9984, -9216, -2304, 6912, 11776, 20224, 20224, 15104, 9728, 4096, -512, -4352, -6400, -6400, -6912, -2560, 1280, 2560, 3840, -1024, -6144, 1280, 7424, 1280, -6144, -4608, -4864, -7168, -12288, -12800, -8960, -9728, -7168, 2560, 8448, 15872, 20992, 15872, 11776, 6912, 1024, -2048, -5888, -6144, -6400, -3840, -768, 0, 2048, 1536, -3072, -2304, 5632, 6400, -1536, -5376, -5632, -7168, -11520, -13568, -9984, -7680, -9472, -2816, 5120, 11008, 19200, 16896, 13568, 10496, 2560, -2048, -4096, -6400, -5888, -3840, -512, -1024, -1280, 1024, 256, -1792, 2048, 7424, 4864, -2304, -5376, -6144, -10752, -14080, -12288, -7680, -7936, -4864, 1280, 5888, 15616, 18944, 14848, 13568, 6656, -1792, -2816, -4608, -6400, -3584, 0, 256, -4096, -2048, 1024, 0, 768, 5120, 7168, 2816, -4096, -4864, -9728, -14848, -14080, -8960, -6912, -4096, -256, 1280, 8192, 16128, 15616, 14336, 11264, 768, -4352, -3328, -5632, -4864, -1024, 1280, -2048, -5376, -1536, 1792, 2048, 3072, 6400, 6400, 512, -4352, -6656, -13824, -16384, -12032, -8192, -2816, 1280, 768, 4096, 10240, 15360, 14848, 14336, 6656, -4096, -4864, -4096, -5120, -2048, 0, -1024, -5120, -5632, 256, 3072, 2304, 4352, 7680, 5120, -512, -3840, -10752, -17408, -14592, -11264, -4864, 2816, 1536, 2560, 4864, 10752, 14848, 14848, 11520, 1536, -5888, -4608, -3328, -3328, -768, -768, -2560, -6656, -3584, 2304, 3840, 3072, 6656, 6912, 2560, -1792, -6400, -15616, -17408, -13824, -9216, 2560, 3840, 3328, 4096, 4864, 10752, 14080, 13312, 7936, -2304, -6400, -4608, -3840, -1792, -768, -2304, -5888, -6656, -512, 3840, 4864, 4864, 6656, 4608, 1792, -2560, -10496, -18432, -15360, -13056, -2048, 6400, 5632, 5120, 3328, 4864, 11520, 13056, 11264, 4864, -3840, -7168, -3840, -1792, -1024, -2304, -4864, -7168, -3584, 1536, 4608, 4608, 6144, 5632, 3072, 256, -4352, -14080, -17152, -14336, -8960, 4864, 8448, 7680, 5120, 2304, 5888, 11264, 12288, 9984, 1536, -5632, -6400, -2304, -2048, -2304, -3840, -7424, -5376, -768, 2560, 4096, 5120, 5888, 3328, 1792, -1024, -7936, -16128, -15616, -12800, -2816, 8448, 9472, 7680, 3072, 1792, 6144, 11264, 12288, 7168, -1024, -7168, -3584, -1024, -3584, -3584, -6912, -6912, -2048, 1280, 3328, 3840, 4864, 4864, 2816, 768, -3072, -11264, -16384, -14848, -7936, 4352, 10240, 9984, 6144, 2048, 768, 7680, 11776, 10752, 4096, -4608, -5376, -1536, -4096, -4608, -6656, -8192, -3840, 256, 1536, 2560, 2560, 3840, 3072, 2560, -768, -5888, -13056, -16128, -12800, -1024, 8704, 10496, 8448, 4352, -1024, 2560, 8960, 10752, 8192, 1280, -3840, -2048, -2560, -4608, -5376, -7680, -5632, 0, 768, -512, -512, 1536, 1280, 1024, 768, -1792, -6400, -11520, -11520, -4608, 6400, 8448, 8192, 5376, 1792, 2048, 5120, 7680, 7936, 5120, 768, -1792, -2560, -3584, -4352, -5888, -7424, -3072, 1536, -512, -2816, -2816, -1024, 512, 768, -1792, -2560, -6912, -8448, -5376, 3328, 6912, 5888, 4864, 2048, 3840, 4352, 4608, 5376, 5888, 4864, 512, -3072, -2560, -2304, -3840, -6912, -7168, -512, 2304, -2048, -4608, -4352, -1024, 2304, -1536, -1792, -2560, -4352, -3328, 512, 5376, 5120, 3584, 1024, 3840, 6400, 3840, 2816, 3584, 4864, 3328, -3328, -4352, -1536, -1280, -5120, -9216, -5888, 1024, 1536, -4608, -7168, -5120, 1536, 1536, 0, 768, 1280, 1280, 7168, 7936, 7936, 12544, 14080, 8960, 2816, 6912, 6656, 1024, 1792, 2816, 7936, 13824, 9728, 6656, 8704, 8960, 5120, -2560, -8192, -11008, -12032, -11008, -5120, -1792, -9472, -14080, -15872, -15616, -16128, -8704, -5376, -8960, -7168, -2560, 3840, 6144, 5888, 1280, -7936, -9728, -1536, 5888, 4864, 3840, 6144, 5120, 7936, 14592, 13824, 7168, 3328, 8448, 5120, 256, 1024, 4352, 9728, 11264, 8448, 7936, 11008, 9216, 2560, -3584, -8704, -13568, -13568, -11776, -5632, -5632, -9728, -11776, -13824, -15360, -14848, -7424, -6400, -9984, -7424, -3072, 2816, 6400, 6912, 1536, -7936, -8448, -768, 6912, 8192, 5376, 3328, 4096, 9728, 15360, 13568, 6656, 4608, 7168, 2816, -512, 2048, 6656, 9472, 8704, 9216, 10752, 12032, 7936, 1536, -3584, -10496, -15616, -13824, -12544, -6656, -7680, -10496, -10240, -11264, -13824, -12288, -5888, -7168, -10496, -8448, -1792, 3584, 6656, 7424, 768, -8192, -6912, 1536, 8448, 8960, 4608, 1280, 5376, 11520, 15616, 12544, 6400, 7680, 5632, 0, -1280, 2304, 9472, 9984, 6912, 8448, 12032, 12800, 7936, 256, -5632, -13056, -16640, -15104, -11520, -7936, -10240, -9216, -7424, -8960, -12544, -10496, -7168, -9984, -11264, -6656, -2048, 1536, 6912, 7936, -1280, -7936, -4608, 3584, 8448, 7936, 4352, 1024, 6400, 12288, 14592, 11520, 8192, 6912, 2304, -1536, -1280, 3584, 11008, 9216, 7424, 9984, 13056, 12800, 7936, 0, -8192, -16640, -18688, -15872, -9472, -9216, -11776, -9216, -5888, -6656, -9472, -8192, -8960, -11776, -10752, -5632, -2816, 512, 7680, 7168, -2048, -7424, -3072, 5632, 8448, 8192, 3840, 1024, 6400, 12544, 14848, 12800, 9216, 5120, 512, -2304, -768, 5376, 11008, 9472, 8192, 11264, 14080, 13568, 8448, -1792, -10752, -17152, -18432, -16384, -11008, -11008, -11776, -8960, -4352, -4352, -6144, -7936, -10240, -12032, -9984, -4608, -3840, 0, 8448, 5632, -3584, -5632, 1280, 7424, 7424, 7168, 2816, 1792, 5888, 12544, 13824, 12800, 9472, 3328, -1536, -2816, -1536, 6400, 11264, 9728, 6656, 10240, 14592, 13824, 7168, -3072, -12288, -17920, -18688, -16896, -11008, -11008, -11008, -7424, -3072, -3840, -4096, -8192, -12288, -13056, -9728, -6144, -4864, 1024, 7936, 3072, -4096, -3584, 5376, 8704, 6144, 6144, 3328, 2560, 6912, 12544, 13568, 13568, 8448, 1536, -2304, -4096, -1024, 8448, 12288, 9472, 6144, 11520, 15616, 13824, 5888, -3840, -15360, -19456, -19456, -15360, -12288, -11520, -9728, -6656, -2816, -768, -1280, -8448, -12544, -13312, -8960, -6400, -5376, 1792, 6144, 256, -3840, -256, 8704, 7680, 5888, 7424, 4352, 1280, 6656, 12544, 14080, 13568, 6656, -768, -4096, -4096, 1024, 9728, 11008, 8448, 8448, 12544, 15104, 11520, 4864, -4608, -16128, -19968, -20224, -14848, -12800, -9984, -7936, -5376, -2816, -512, -768, -7680, -12544, -13056, -8960, -7424, -5120, 2048, 3072, -2560, -2816, 4352, 9472, 6912, 7424, 7424, 3328, 512, 8448, 14336, 14080, 9728, 4608, -1792, -4864, -4352, 3328, 10240, 10752, 8448, 8960, 13312, 14848, 10240, 2560, -7168, -17408, -21504, -19968, -14336, -12032, -9216, -7680, -4352, -1792, 1280, -1024, -7680, -12544, -13056, -8704, -7680, -4608, 2560, 256, -4608, -2304, 7680, 9984, 6656, 8192, 7168, 2304, 1792, 9728, 13056, 11520, 8960, 4096, -3328, -7168, -2816, 6912, 10496, 10496, 8704, 11520, 14848, 13824, 7424, 1792, -8448, -17664, -20480, -19968, -15104, -11008, -7936, -6144, -3840, -768, 2304, -1024, -7424, -13056, -13056, -8448, -6912, -2048, 2048, -3328, -6144, -256, 10240, 10496, 7424, 7936, 5632, 1792, 3840, 11776, 12288, 9728, 8448, 2816, -4864, -7168, -1792, 6656, 10752, 9216, 9984, 13824, 13824, 12288, 5120, 768, -9984, -17408, -20224, -19968, -13824, -9472, -8192, -6912, -4096, 1280, 2816, -1536, -7936, -12800, -12544, -8448, -6144, -768, -768, -7424, -6656, 3328, 11264, 9216, 7680, 8192, 4352, 1792, 7168, 11008, 9472, 7936, 7168, 1024, -4352, -6912, -1280, 6144, 11776, 11008, 12288, 14336, 12800, 10496, 5120, -256, -12032, -16384, -20992, -19968, -12288, -8960, -8704, -6656, -3584, 1536, 2304, -2560, -7936, -11776, -11008, -8448, -5376, 256, -4096, -9728, -3840, 6144, 9728, 8960, 11264, 8448, 2560, 3840, 9472, 11008, 7680, 5632, 4608, 1024, -5120, -7424, 0, 7680, 11008, 12288, 13824, 13312, 11776, 8960, 4864, -2304, -10496, -15360, -21248, -18688, -11264, -7424, -9472, -6912, -3072, 1536, 2048, -2560, -7168, -11520, -11008, -6400, -2304, -768, -8448, -11008, -1024, 8192, 8960, 9472, 12544, 6144, 1792, 6656, 12032, 8960, 4352, 2816, 3584, 768, -5376, -7680, 1536, 7680, 11264, 15360, 14336, 11264, 9472, 8448, 3840, -2816, -10240, -16128, -20992, -15616, -9216, -8448, -9984, -6656, -3328, 0, 1024, -2304, -7424, -10752, -9472, -4608, -1792, -3328, -9984, -8704, 512, 7680, 8704, 11520, 12544, 4096, 2816, 9472, 11520, 6656, 2816, 2048, 2304, -256, -6656, -6400, 4352, 7936, 11776, 15872, 13312, 10752, 7424, 6656, 3840, -3072, -11520, -16384, -18176, -12288, -8704, -8960, -8448, -6912, -4096, 256, 512, -2560, -5888, -10496, -8192, -3072, -1536, -7424, -11776, -7168, 3072, 6656, 9216, 13824, 11008, 2560, 5888, 13312, 11008, 4608, -512, 1280, 1280, -1792, -6400, -2816, 4864, 5632, 12544, 15616, 12800, 10240, 6144, 5120, 3840, -2560, -12032, -15872, -15872, -11520, -8704, -7680, -7680, -5888, -4096, -1536, -256, -2048, -6400, -9728, -7424, -2304, -2560, -9984, -10752, -4864, 1280, 5888, 12288, 14592, 8448, 1792, 8192, 14592, 9984, 2048, -1792, 768, -512, -4096, -4096, 256, 5120, 5632, 12288, 14080, 11776, 9984, 4352, 4096, 4352, -2304, -12288, -14848, -13824, -10240, -9472, -7168, -6656, -5632, -5888, -1280, 512, -2816, -7168, -9472, -6912, -2560, -4608, -11264, -8960, -4608, 768, 7936, 13824, 13312, 6400, 3328, 11520, 15616, 7424, -1024, -2560, 0, -1280, -4096, -2048, 1024, 5376, 5376, 12800, 13824, 11520, 7936, 1024, 5120, 4608, -3840, -11008, -12288, -12288, -9984, -8448, -7168, -6400, -5632, -5376, 0, -256, -4864, -7424, -7424, -5632, -2816, -7424, -10752, -7680, -4352, 768, 9728, 15616, 11776, 6144, 6400, 13568, 14848, 5120, -2560, -2304, -1280, -4096, -3072, 1024, 2816, 5632, 4352, 12288, 13056, 11008, 4096, 512, 4608, 3328, -3840, -8960, -11776, -11008, -9728, -7936, -5888, -6912, -6144, -3328, 768, -2048, -6400, -7424, -6912, -5632, -4608, -9216, -9728, -7936, -4864, 1536, 11776, 15360, 9216, 6144, 8448, 14336, 11264, 2560, -2048, -2304, -3072, -6144, -1792, 3584, 5888, 4608, 2816, 11520, 12032, 9984, 3328, 1280, 4096, 256, -4864, -5632, -9984, -11520, -11520, -7936, -5120, -6144, -4096, -1536, -768, -4864, -6144, -6400, -6656, -5632, -6144, -9984, -8960, -6400, -3328, 2048, 13824, 16384, 9216, 7424, 10496, 14336, 9216, 1280, -3072, -2816, -3584, -6656, -1536, 6144, 8448, 1792, 3072, 11520, 11264, 7680, 3328, 2560, 4352, -1024, -4352, -4096, -8704, -11776, -12800, -7680, -5120, -5888, -3072, 256, -2816, -6656, -6912, -6144, -5376, -4864, -8704, -12288, -8192, -5888, -2560, 3328, 16896, 16640, 8448, 8192, 12288, 14080, 6400, 0, -2048, -256, -4608, -9216, -1024, 10240, 8448, -256, 4352, 9472, 8960, 6400, 2560, 3584, 2560, -3328, -3840, -2304, -6656, -11776, -13056, -8192, -4608, -3840, -1024, 768, -4352, -7936, -7168, -6400, -5120, -6656, -12288, -12288, -6912, -5120, -3328, 4864, 18176, 15616, 7168, 8448, 14336, 12800, 3072, -2048, -512, 1280, -6144, -10496, 512, 13312, 7424, -256, 6144, 9216, 6656, 4096, 3584, 4864, 1536, -4864, -3072, 256, -5376, -12544, -12800, -7168, -3072, -768, 512, -512, -6400, -8192, -7424, -6144, -3584, -7936, -15616, -11264, -4352, -3840, -2304, 7168, 18432, 15616, 6400, 9728, 15616, 10496, 1792, -1792, 1024, 768, -8192, -9216, 2304, 11520, 5376, 1024, 7680, 8448, 3840, 2816, 4608, 4352, -256, -4608, -1792, -1024, -5632, -12032, -11520, -6144, -1536, 512, 1280, -1792, -6912, -8704, -7168, -5376, -3584, -10752, -17664, -10240, -2816, -4096, -768, 10496, 17408, 13568, 7424, 12288, 15616, 8192, 0, -1280, 2048, 512, -8448, -7168, 2304, 7936, 4096, 4096, 8704, 5632, 0, 2560, 6144, 2560, -2304, -4864, -1536, -2048, -6656, -9728, -8704, -5120, -2560, 256, 2816, -2304, -8448, -7936, -8192, -6400, -4608, -12800, -16640, -10240, -3840, -2048, 3328, 12032, 16640, 12800, 8448, 13824, 15872, 6144, -512, 512, 3072, -1536, -7936, -5120, 3072, 5376, 2560, 7168, 8704, 2304, -1280, 5120, 5120, -512, -3328, -2560, -1024, -4608, -8448, -6656, -4096, -4864, -3584, 1536, 2048, -3584, -7936, -8192, -7424, -7424, -7936, -13056, -17664, -12032, -3072, 512, 5376, 12544, 14336, 11008, 11520, 15872, 13824, 4096, -512, 1792, 2304, -3328, -5632, -1024, 3072, 1792, 3328, 9472, 8448, 1792, -1024, 5888, 2304, -2048, -2048, -512, -2048, -8448, -9728, -1792, -256, -5632, -4864, 2816, 1792, -5376, -7424, -7424, -7424, -7936, -8192, -14080, -20480, -12544, -1792, 4096, 7936, 11008, 11520, 11264, 14336, 16896, 11520, 3072, 512, 2560, 768, -4608, -3328, 1792, 2304, -512, 4352, 9728, 5632, 256, 1280, 4352, 1024, -3584, -3072, -256, -2816, -11008, -9728, 1536, 1280, -5632, -3840, 3072, 0, -5888, -6656, -7168, -7936, -8192, -9216, -15360, -20992, -11776, 768, 6144, 8960, 9728, 10496, 11776, 15104, 15872, 10496, 3328, -256, 768, -1536, -4608, 768, 5632, 512, -2304, 5120, 9216, 4608, 2560, 1792, 1024, -1280, -4352, -2304, -512, -4608, -14080, -7680, 4352, 1536, -5120, -2560, 1536, -1280, -4096, -6656, -8192, -6912, -7680, -10752, -17664, -21504, -10496, 3328, 7936, 10752, 9472, 9728, 11520, 16128, 16640, 10496, 3072, 768, 256, -4608, -2560, 5888, 6912, -512, -3072, 4352, 9216, 6656, 3328, 1024, -512, -1280, -3584, -3584, -2816, -6656, -13824, -4864, 5376, 2048, -4096, -2048, 1536, -1792, -5120, -7680, -8448, -6144, -8448, -12800, -18944, -20992, -8192, 4608, 8704, 10752, 9728, 8704, 12800, 17664, 14848, 8704, 4096, 1792, -2304, -7424, -512, 10496, 8192, -1792, -3840, 2816, 8704, 7680, 2304, 512, -768, -1792, -5888, -5376, -3840, -7680, -13312, -2560, 4608, 2560, -2048, -1024, 1280, -1024, -6400, -8448, -6656, -5632, -10752, -15104, -20224, -18432, -5120, 5888, 9216, 10496, 9472, 8704, 13824, 18944, 13568, 5632, 4352, 3840, -4352, -8704, 2560, 13312, 9472, -2048, -2816, 3072, 8448, 5888, 2048, 1024, -256, -4096, -7936, -6400, -4608, -9728, -12544, -768, 4864, 2816, -1024, 0, 1792, -2048, -8704, -7936, -4864, -6656, -13312, -15872, -20224, -14080, -1792, 5888, 10496, 12032, 10496, 8448, 15616, 19200, 11008, 5632, 5376, 3328, -6656, -8448, 4352, 14848, 9984, -1536, -2048, 3328, 6912, 2560, 1280, 3328, -512, -8192, -11008, -8192, -4864, -9728, -9216, -768, 3072, 1024, 1024, 3328, 1536, -5632, -10496, -7936, -3328, -8448, -15104, -18176, -19456, -8960, 512, 5120, 9984, 13568, 12032, 9984, 15360, 15872, 9472, 6656, 5632, 1280, -8448, -7424, 6656, 16384, 10240, 0, -1280, 3072, 5376, 2048, 4096, 2560, -3328, -9984, -12544, -9472, -6400, -10496, -7680, -1536, 2304, 2304, 3328, 5888, 0, -7680, -11264, -6656, -3328, -11520, -17152, -19456, -17408, -5120, 2560, 4864, 9984, 14080, 12800, 11776, 14592, 12800, 9472, 7680, 4096, -768, -8704, -5632, 8704, 16640, 10240, 3328, -512, 1536, 4864, 3072, 5376, 1280, -5888, -12544, -13312, -9728, -8448, -9216, -6144, -2304, 2560, 3072, 6400, 5888, -2816, -7424, -11008, -6912, -5376, -14080, -18688, -19712, -12800, -512, 4864, 4864, 8960, 15104, 15104, 12544, 11520, 10240, 9216, 6912, 1024, -2560, -6144, -3072, 7936, 15104, 11264, 5632, -1280, 1024, 4864, 5120, 3072, -1024, -6912, -13312, -12800, -11520, -9984, -6144, -5888, -3328, 4096, 5120, 7680, 3840, -4096, -7168, -9472, -7680, -9216, -16384, -20224, -18688, -7168, 4352, 6144, 3584, 9216, 16640, 17408, 11520, 8448, 9984, 10240, 5632, -512, -1280, -2816, -2816, 7168, 14848, 14592, 5120, -3328, 0, 6912, 5888, 256, -3840, -8960, -14848, -14080, -13312, -9984, -5120, -5632, -2304, 5120, 7424, 7680, 2560, -3840, -7936, -9984, -8192, -12288, -18432, -22016, -15104, -1024, 6912, 4864, 4352, 11264, 19712, 17664, 7936, 6656, 10240, 9728, 3584, -1536, 0, 256, -2816, 6656, 17152, 15872, 2560, -4608, 1536, 7936, 5120, -1280, -5632, -11264, -16896, -15616, -12800, -7936, -4352, -6144, -1792, 6144, 8704, 7936, 768, -4352, -7936, -9216, -10240, -15616, -18688, -19456, -11776, 2816, 8704, 5120, 5632, 14336, 21248, 15360, 5632, 6144, 11776, 8192, 1280, -1024, 2304, 0, -2048, 7936, 18688, 13568, 0, -3328, 4096, 7168, 3584, -3840, -7936, -13056, -18944, -16384, -11008, -6400, -5632, -6400, -256, 7680, 9472, 5120, -512, -5120, -9216, -9984, -14080, -17664, -19200, -17664, -8192, 5376, 9216, 5632, 7936, 16128, 19456, 12800, 5632, 6400, 12544, 7424, 768, 1024, 2304, 512, 0, 11008, 18944, 9472, -2048, -256, 7168, 6144, 2048, -5632, -10752, -16640, -20480, -15360, -7936, -6400, -7936, -6144, 2048, 10496, 9472, 2560, -768, -5632, -10240, -11520, -15360, -17664, -17664, -14080, -3840, 8192, 9472, 6400, 10752, 18432, 17920, 9472, 5376, 8192, 10496, 5120, 1280, 3840, 2048, 0, 2304, 11776, 15872, 6656, -1792, 2048, 7168, 5376, 1024, -7424, -13568, -20224, -20992, -14592, -6400, -6912, -8192, -5376, 3584, 12288, 8960, -256, -1792, -6144, -11264, -13312, -17920, -17664, -15360, -9728, 256, 8704, 8448, 8192, 14592, 17920, 14848, 8704, 6656, 7936, 7936, 4096, 3584, 3584, 768, 2048, 6400, 12032, 12032, 4608, -512, 3328, 6400, 4864, -512, -8448, -16384, -22272, -21248, -13568, -6144, -7424, -8192, -4352, 5376, 11776, 6912, -1024, -3072, -7680, -13056, -15616, -18688, -15360, -11776, -4352, 2304, 6400, 8192, 12032, 17664, 15616, 12288, 10496, 7680, 6656, 6144, 4608, 6144, 3840, 512, 3584, 9472, 10752, 8704, 4352, 2304, 4864, 5120, 2816, -1792, -8960, -20224, -24832, -20224, -11520, -5376, -7424, -8448, -3072, 6656, 11008, 6912, -768, -3840, -11008, -14848, -16896, -17664, -13312, -9472, -512, 4096, 6144, 9728, 15616, 18432, 14336, 11008, 10496, 8192, 7168, 5632, 5632, 6656, 3072, 256, 5888, 11520, 8704, 5376, 2048, 4352, 5632, 4864, 1024, -4608, -12032, -23808, -24832, -17920, -10240, -7424, -8448, -5632, -1280, 6144, 11264, 4864, -1536, -5888, -13568, -15360, -18944, -16128, -10496, -5120, 2560, 4608, 4864, 10240, 17920, 17920, 12032, 10496, 11008, 9472, 6912, 3584, 6144, 8192, 2560, 256, 7424, 11264, 6912, 3072, 1792, 7168, 8192, 2304, -2816, -6912, -14336, -25600, -24064, -16384, -11008, -9728, -7936, -1792, 0, 6912, 10496, 2816, -1792, -8960, -15360, -15872, -19200, -13824, -7424, -1280, 4352, 5632, 3584, 11776, 20480, 18432, 11776, 10752, 11264, 10752, 6144, 4096, 7936, 8192, 2304, 1024, 8448, 11520, 5632, 1280, 2048, 10496, 8704, 0, -5632, -9216, -17664, -25600, -23552, -16640, -10240, -11264, -6400, 0, 1280, 7168, 9216, 1024, -3072, -12800, -16384, -16384, -17408, -11776, -4864, 512, 6400, 7168, 4864, 11264, 18432, 17152, 11776, 11520, 11264, 9984, 5376, 5376, 9728, 7424, 256, 2304, 9984, 9984, 3328, -1024, 2304, 13824, 10496, -2816, -9728, -13056, -19456, -23296, -23552, -16640, -11264, -12032, -4352, 3072, 2816, 5376, 6912, 1536, -6144, -15104, -16640, -17152, -15616, -10240, -4352, 2048, 7936, 6656, 5120, 12544, 18944, 16640, 11520, 12288, 12032, 9216, 6400, 7168, 9216, 6400, 1280, 4864, 10752, 7168, 1536, -512, 5376, 14336, 6912, -5632, -11520, -15872, -21248, -23552, -21504, -16640, -12544, -9472, -2048, 3840, 4096, 5632, 5888, -256, -9728, -16640, -16896, -16640, -13056, -8960, -3840, 5120, 10752, 6656, 6400, 13056, 17920, 15360, 11520, 13312, 12032, 6400, 6400, 9984, 8448, 6144, 4096, 7936, 9472, 3584, 768, 512, 8448, 14080, 3584, -8960, -14080, -17152, -21504, -22528, -21504, -17408, -12032, -7168, -256, 4352, 5632, 6144, 4352, -3584, -13824, -16896, -16384, -15616, -11776, -8192, -2560, 6656, 11520, 6144, 7424, 13312, 16896, 14592, 12544, 14336, 10496, 4096, 7424, 11776, 7936, 5632, 6144, 9472, 7680, 3072, -256, 1280, 10240, 9984, 256, -10496, -16128, -18432, -22784, -22784, -19712, -15872, -12288, -4352, 1280, 3328, 6656, 7936, 2560, -7424, -15872, -16384, -16640, -13824, -10496, -6400, -1024, 8192, 13312, 7424, 8192, 14080, 15616, 14080, 14336, 14592, 8960, 4352, 8448, 10240, 7168, 6912, 9472, 9216, 6656, 3584, -768, 3328, 10496, 5632, -3328, -11520, -16640, -19968, -23040, -22272, -17920, -14336, -12032, -3072, 2304, 4608, 8960, 6912, -1280, -10496, -16128, -15616, -16640, -13312, -9472, -4352, 1280, 8960, 13312, 8704, 9728, 14080, 14848, 13568, 15360, 13824, 7936, 5376, 8448, 8704, 7680, 8960, 10240, 8192, 7424, 3840, -1024, 4608, 7680, 2816, -6400, -13568, -17664, -21760, -23296, -20992, -16896, -13824, -9216, -1792, 1536, 5120, 10240, 4864, -4352, -13312, -16128, -15360, -16640, -12800, -8192, -2816, 2304, 8704, 12800, 10240, 11776, 13056, 14336, 15360, 15360, 12800, 7168, 5888, 8448, 8448, 7936, 10240, 11008, 9728, 9728, 3328, -1536, 3328, 4864, -512, -8704, -14592, -19968, -23296, -21760, -18688, -16128, -14080, -7168, -256, 1536, 6656, 9984, 3328, -7168, -14336, -15616, -14080, -15616, -11008, -6912, -3328, 3072, 9728, 12288, 12544, 13824, 11776, 13312, 16384, 16384, 12288, 6912, 5632, 7168, 8448, 9216, 11264, 10752, 9984, 11264, 3840, -768, 2560, 1536, -4864, -11776, -15360, -20736, -23552, -21248, -18688, -13312, -11264, -5632, -1280, 1280, 9728, 9472, -1536, -10496, -14080, -13824, -12544, -13568, -11520, -7168, -2304, 4864, 10496, 12032, 14336, 14592, 10496, 14336, 17664, 16384, 10752, 6656, 5888, 6912, 9216, 9984, 11264, 9984, 12288, 13568, 3072, -1024, 512, -2048, -8448, -15616, -18432, -21504, -22272, -20480, -18688, -12544, -9216, -3072, -1280, 2304, 10752, 6144, -3840, -11264, -12800, -13056, -13056, -13056, -11520, -6656, -1024, 5120, 10240, 12032, 16384, 14848, 9728, 15616, 18176, 14080, 9472, 8192, 5888, 7680, 8704, 9984, 12800, 11008, 14848, 13568, 2304, 1024, -768, -6912, -12544, -18176, -20224, -20224, -20224, -20992, -17920, -11264, -6656, -1792, -1280, 4096, 9216, 2304, -4608, -10240, -12032, -12544, -11520, -10752, -11008, -5120, 256, 5376, 10240, 13568, 18432, 13824, 9216, 16384, 16896, 10496, 7680, 9216, 6656, 7168, 7936, 11264, 14592, 12288, 15872, 11520, 3328, 768, -3584, -12032, -16640, -19712, -22272, -19968, -18176, -19200, -17408, -11008, -4096, -512, -256, 4608, 5120, -1024, -4608, -9472, -11776, -12800, -9216, -9984, -11776, -3840, 1792, 5888, 10496, 15872, 18432, 12544, 10496, 17664, 15104, 8448, 7424, 9728, 6144, 7168, 7936, 13312, 15104, 12544, 15616, 11520, 5376, 512, -7936, -16384, -18688, -19968, -22784, -20224, -18176, -19712, -15872, -9216, -2048, 768, 1280, 3840, 1280, -2560, -4352, -8704, -12544, -12800, -6912, -9472, -11008, -3072, 3584, 6400, 11520, 17152, 17408, 12288, 12288, 16384, 12288, 6912, 8448, 10496, 6400, 6144, 8192, 16384, 16896, 13056, 15872, 10496, 5376, -1792, -11008, -19712, -20736, -21248, -22272, -18944, -18176, -19712, -13824, -7424, -256, 1792, 3328, 3072, -1536, -2304, -4608, -9728, -13824, -11264, -5376, -9472, -10496, -2048, 4096, 7168, 13568, 18688, 15616, 11776, 13312, 15360, 8960, 6400, 8704, 9728, 5120, 6400, 10752, 18688, 15872, 15360, 14848, 9984, 5632, -4864, -13824, -21760, -22528, -24320, -22528, -16640, -17664, -18688, -12032, -5632, 768, 3584, 3840, -1280, -3584, -1536, -5888, -10752, -13312, -8704, -4864, -10752, -9728, 0, 4608, 7680, 15872, 19456, 15616, 12544, 13312, 12544, 6656, 5888, 8704, 8448, 5632, 5376, 12800, 19968, 17408, 16896, 12032, 10240, 5632, -5888, -16896, -24320, -26112, -24832, -18944, -15616, -19712, -17408, -9216, -3072, 2304, 3840, 3328, -4608, -3584, -1280, -7936, -12800, -11264, -5376, -6400, -12544, -6400, 2048, 4096, 7680, 17920, 20992, 14336, 11520, 14080, 9984, 5376, 6400, 7936, 6144, 5376, 7168, 16384, 20736, 17408, 16384, 12032, 11264, 3840, -7680, -19712, -25856, -26624, -24576, -18176, -16896, -19456, -13568, -5632, -2304, 1536, 5632, 2560, -5632, -3840, -3328, -9728, -12288, -8192, -2304, -8448, -12544, -3584, 2560, 2816, 9472, 19712, 21760, 13056, 11264, 12288, 7680, 4608, 5376, 6656, 4096, 5376, 9216, 18176, 19456, 18688, 17408, 12288, 8960, 1024, -9728, -20736, -26368, -27904, -23296, -17152, -18176, -17664, -10240, -3840, -3072, 768, 5888, 1792, -5888, -4352, -6144, -10496, -11520, -6144, -2816, -11776, -11776, -256, 2560, 2048, 12544, 21504, 21248, 12288, 12800, 12288, 6912, 4096, 4608, 5120, 3584, 6656, 11264, 18432, 19200, 20992, 18176, 12032, 6656, -1536, -11520, -20480, -27392, -28160, -22528, -17920, -17664, -14848, -7168, -2304, -3072, 512, 5888, 512, -5376, -4864, -8960, -9728, -8448, -3328, -4352, -12800, -8960, 2048, 2304, 2560, 14592, 22784, 18944, 11520, 13312, 10496, 6144, 3840, 2816, 3584, 3328, 5632, 13824, 18432, 18944, 22016, 18432, 10496, 3328, -3584, -12032, -22016, -28928, -28416, -22528, -18432, -17152, -10752, -4608, -2816, -2816, 512, 4608, -512, -4352, -6912, -11264, -9472, -7168, -3072, -6656, -12544, -5632, 2304, 768, 5376, 17664, 22272, 16128, 11776, 12544, 9216, 6144, 3328, 2816, 2816, 2048, 6656, 16384, 17408, 19456, 22784, 18944, 9728, 768, -4352, -11264, -22016, -29952, -29184, -22016, -16640, -14848, -9728, -4864, -1792, 0, 2048, 2304, -1280, -5120, -9472, -11520, -7424, -4864, -3840, -9216, -9984, -2560, 1536, 1024, 8448, 20224, 20736, 14080, 12288, 10752, 7680, 5888, 2560, 3328, 2560, 768, 6912, 15872, 15360, 19456, 22528, 17408, 7680, -1280, -5376, -12544, -22784, -30720, -29440, -20736, -13824, -11776, -8704, -3584, -256, 1792, 2304, 256, -1536, -4608, -11520, -13312, -7424, -4096, -4352, -8960, -9216, -3072, 1280, 2816, 12032, 20736, 18432, 13568, 13056, 9984, 7168, 6144, 2304, 3328, 1792, 1280, 9216, 14592, 14080, 20992, 23040, 15872, 7936, -2560, -7424, -14080, -23296, -30976, -29440, -19456, -12032, -9728, -8704, -3328, 256, 3328, 2304, -1024, -2304, -4352, -12544, -14336, -6656, -2304, -3072, -8448, -10240, -4352, 3072, 6400, 14592, 18176, 15872, 13312, 12800, 8960, 5632, 5376, 3584, 2816, -512, 2560, 10496, 12800, 12288, 21760, 22272, 16896, 7424, -3840, -8704, -16384, -24832, -30976, -27648, -18688, -11008, -9472, -7168, -1792, 1792, 4096, 1536, -1792, -1280, -3840, -15104, -14336, -4864, -1024, -3584, -9472, -10752, -2560, 5376, 9728, 16896, 16128, 14592, 13312, 12544, 7168, 5632, 7168, 4096, 1280, -768, 5632, 12032, 9728, 11520, 20224, 21760, 17408, 5888, -4096, -8704, -17920, -25600, -31232, -27392, -15872, -9984, -9728, -6400, -1024, 3840, 4608, 512, -768, 0, -6912, -17920, -13056, -4352, -768, -4096, -11264, -10240, -256, 6912, 11520, 17152, 14592, 13824, 12288, 9984, 4352, 4608, 7168, 4352, 768, -768, 6912, 12544, 9472, 10752, 17664, 22016, 16896, 4096, -4352, -9472, -18432, -25344, -29952, -25856, -14080, -9984, -9216, -6144, 256, 5120, 3328, 1024, 1024, -1280, -11776, -18944, -11008, -2304, -1024, -7168, -12544, -8448, 1536, 8448, 16128, 17408, 13824, 13568, 12544, 8448, 4608, 5376, 6144, 3840, 1792, 2304, 8448, 10752, 8960, 9984, 17920, 21760, 14080, 2560, -4096, -10240, -19200, -25088, -28928, -23552, -12032, -9728, -8960, -5376, 256, 5376, 3840, 2048, 1792, -3584, -15872, -17920, -7680, -2816, -3840, -8704, -12544, -5888, 2304, 9984, 16384, 14848, 13056, 14336, 10752, 5120, 4096, 4864, 4096, 4096, 1024, 3328, 10240, 11776, 8448, 7936, 16640, 21248, 12544, 768, -6144, -10496, -18688, -25088, -26880, -19712, -11520, -10496, -7680, -3328, 1792, 4864, 3072, 3328, 2048, -6656, -17408, -15616, -5632, -3584, -6400, -9728, -10240, -4608, 3072, 12032, 17408, 15104, 12544, 13056, 10752, 4864, 4352, 4352, 3072, 3328, 1280, 4608, 10496, 12032, 6656, 6656, 17152, 19968, 11264, -512, -7936, -12032, -18176, -24832, -24576, -17152, -11264, -10752, -7424, -2816, 3328, 5376, 3328, 4352, 2048, -8704, -17408, -13824, -4352, -4608, -9216, -11008, -8960, -3072, 3584, 12800, 17664, 14336, 12544, 11264, 8960, 4096, 3328, 4352, 3328, 3328, 1536, 6912, 11776, 12800, 6144, 7168, 16896, 16384, 7168, 0, -6400, -12544, -19200, -25344, -22272, -13824, -10752, -9728, -7168, -2048, 5120, 4864, 2816, 4352, 256, -10496, -15872, -12544, -4608, -6912, -10496, -9984, -7424, -2048, 3840, 14080, 18688, 14080, 10752, 10752, 8448, 4096, 3072, 3072, 2304, 1536, 3584, 10240, 13312, 12288, 5376, 7936, 15360, 12800, 5888, 0, -8192, -15360, -19456, -23040, -18688, -11264, -9984, -9216, -8192, 256, 7424, 5120, 1536, 3328, -768, -10496, -13568, -11008, -5376, -8704, -12032, -9728, -5632, -512, 5632, 13824, 16640, 12544, 9728, 10752, 8192, 4352, 3072, 1792, 1536, 768, 5376, 12288, 13568, 10752, 6144, 9984, 13568, 9728, 3840, -768, -9728, -16640, -19456, -21760, -15104, -9216, -8960, -10240, -6656, 3840, 6656, 3072, 1536, 2560, -3072, -10240, -12544, -8448, -6656, -10496, -13568, -9216, -3072, 1280, 7168, 12800, 15616, 11776, 8704, 9472, 7936, 5120, 3072, 256, 0, 1280, 8192, 13568, 14336, 10496, 5888, 9984, 12288, 8960, 3328, -2560, -11264, -18432, -20736, -20224, -12800, -6912, -8704, -10496, -4608, 5120, 6912, 3072, 1280, 256, -4864, -9216, -10240, -5632, -8704, -12800, -14080, -8448, -768, 3584, 8448, 13312, 13824, 8960, 6912, 9216, 9472, 6400, 1792, -3328, 256, 4864, 10496, 12800, 12800, 9728, 8192, 11008, 10496, 8192, 1536, -4352, -11776, -17664, -20224, -19200, -11008, -5120, -8704, -9728, -2048, 5888, 6656, 3072, 1536, -2048, -5888, -7680, -7680, -5888, -11776, -14336, -13312, -7424, 1536, 5888, 8960, 11264, 12032, 7936, 6400, 8448, 10240, 6656, -1024, -5632, 768, 7168, 9984, 10240, 12800, 10240, 7168, 8704, 9472, 7168, 0, -5632, -12800, -17920, -20736, -18432, -8704, -5632, -9216, -8448, 512, 6144, 6400, 3072, 1024, -3840, -6144, -6656, -6400, -5888, -11776, -14336, -12800, -6144, 2560, 8448, 9216, 10240, 8960, 5376, 6400, 11008, 12032, 6400, -3328, -6400, 2816, 10240, 9216, 10240, 14336, 9728, 6912, 7936, 8448, 6144, -1024, -6144, -13568, -18176, -20480, -15104, -8704, -6912, -7936, -6912, 2048, 6144, 6400, 4352, 512, -5632, -6400, -6656, -4864, -6144, -13056, -14848, -10240, -2304, 3584, 9472, 9216, 8960, 6912, 3584, 7168, 12288, 11776, 4864, -4864, -6144, 4608, 10240, 7424, 10496, 12800, 7424, 7424, 6912, 8448, 4608, -3072, -7424, -13568, -18176, -19200, -12288, -8448, -8192, -6400, -3584, 3328, 6144, 4864, 4352, 512, -6400, -7168, -7168, -4608, -7168, -14080, -15104, -7680, -768, 5120, 10496, 8704, 6144, 3840, 3840, 9216, 12544, 9984, 4352, -4352, -4352, 5632, 10496, 8448, 11520, 9728, 6656, 7680, 6144, 6912, 2560, -2816, -8704, -14848, -17920, -16896, -9728, -8192, -9216, -5376, -512, 3584, 7168, 4864, 3584, 0, -6400, -7424, -7168, -4352, -7680, -14592, -13056, -5632, 768, 5888, 9984, 8704, 3840, 2816, 4352, 9728, 11776, 9984, 3840, -4608, -3584, 6912, 10240, 9472, 11520, 8192, 7168, 7680, 7424, 7168, 256, -4096, -9728, -14080, -16640, -15872, -9472, -7936, -8704, -4352, 2304, 4608, 6912, 4608, 2304, -256, -5632, -8960, -7424, -4352, -8192, -14592, -11520, -4352, 3840, 7680, 7680, 6400, 2048, 2560, 4864, 8960, 11776, 9472, 1024, -4864, -2048, 7936, 8448, 8448, 10752, 7168, 5632, 6144, 7424, 5888, -1536, -5376, -11008, -13824, -15104, -14080, -8192, -8704, -9984, -2560, 4864, 7680, 6400, 2304, 512, -512, -5120, -9728, -7680, -5888, -10496, -13056, -8960, -3072, 6144, 8192, 5632, 3072, 2048, 4096, 5888, 8192, 12288, 8448, 256, -4096, 0, 7424, 7680, 8448, 9216, 6144, 5888, 5632, 8448, 3584, -3584, -5120, -10752, -14080, -12800, -11264, -6912, -9728, -10496, -768, 7936, 8960, 5888, 1280, -512, -1024, -3840, -8704, -8448, -9728, -12032, -10240, -6656, -768, 7936, 7936, 2304, 512, 3328, 3584, 5120, 9728, 13568, 6912, -1536, -3584, 2816, 7680, 5888, 8192, 7168, 6400, 5632, 6144, 8192, 1280, -5120, -6656, -11520, -12544, -10240, -9216, -9472, -12288, -10240, 2048, 10240, 9472, 4096, -768, -1536, -512, -2304, -6912, -10752, -13312, -12288, -8192, -5376, 2048, 9984, 7168, -512, -1280, 3328, 4352, 5888, 10240, 11520, 4864, -1024, -768, 4608, 3840, 4864, 8448, 7680, 7424, 5632, 5376, 5632, 0, -4352, -6912, -11776, -12288, -8448, -7936, -9728, -13568, -8448, 5888, 11008, 7936, 2816, -1792, -1280, -768, -2048, -6656, -12544, -15104, -12288, -6400, -3584, 3840, 10496, 5888, -2048, -1536, 2816, 2560, 6656, 12544, 10496, 3072, 0, 2560, 4864, 1024, 5632, 7936, 6400, 6400, 6144, 5120, 3072, -1024, -2560, -9472, -12800, -9472, -5888, -6656, -11008, -14080, -4608, 8704, 10496, 7168, 2560, -2304, -1536, -768, -2048, -6912, -14592, -15872, -9472, -3840, -2048, 6144, 11264, 5888, -2560, -1536, 768, 2048, 9984, 14080, 7680, 3072, 2816, 5120, 2048, 768, 6912, 6656, 5120, 5376, 6144, 4864, -256, -2560, -3584, -10752, -12032, -6400, -3584, -7168, -12544, -12800, -1280, 9728, 9728, 5888, 2304, -2816, -2304, -256, -1280, -8448, -16384, -15104, -8704, -3584, -512, 8192, 12544, 4352, -2816, -1536, -512, 2816, 11776, 11776, 4864, 4096, 5888, 6144, -768, 768, 7424, 7424, 4096, 4352, 5632, 2816, -3072, -3072, -4608, -12800, -11008, -3840, -2816, -7680, -13568, -9728, 2560, 7936, 7936, 6400, 768, -4096, -768, 768, -2048, -10496, -17152, -13568, -6144, -3584, 768, 8960, 11776, 4352, -512, -1792, -2304, 4096, 12544, 10496, 5120, 5632, 8704, 5376, -1280, 1280, 7936, 7424, 3072, 3584, 4608, 2048, -5632, -4352, -5120, -13312, -9728, -3328, -4864, -8192, -12288, -6400, 2816, 5888, 7424, 6656, 256, -3584, 256, 256, -4608, -12032, -15360, -12032, -7936, -2816, 3328, 11520, 9984, 2048, -512, -512, -2816, 4096, 11008, 8960, 6400, 8704, 10240, 4608, -1792, 1536, 8704, 7168, 3584, 1792, 2816, 512, -5888, -6400, -7424, -13056, -7680, -2816, -6144, -9728, -10240, -3840, 2304, 4608, 7424, 8192, -256, -2560, 0, -2304, -6912, -12288, -13312, -11776, -7680, -512, 6912, 12032, 7680, 2560, 1792, -1536, -3840, 3072, 8960, 7168, 7680, 11520, 10752, 4864, -1024, 2816, 7424, 5376, 1536, 256, 768, -768, -6912, -7936, -8704, -10240, -5632, -4608, -7936, -8960, -7680, -4608, 1280, 4864, 8192, 7168, -2304, -1792, 256, -3584, -7680, -10752, -11520, -12032, -7168, 1792, 9728, 11520, 5888, 3584, 5120, -512, -6144, 1792, 8192, 7680, 9472, 11008, 10496, 5632, 1792, 4608, 5632, 3584, 1024, -1792, 1024, -1792, -9216, -9472, -9472, -6912, -3840, -6656, -8704, -8704, -7424, -4608, 1024, 4864, 7936, 5120, -1024, 0, -768, -5376, -8192, -9472, -10496, -10240, -6400, 3584, 12544, 11264, 4608, 4864, 6400, -256, -4864, 1280, 6656, 8960, 9728, 11776, 10496, 4608, 4608, 4096, 3328, 3072, 512, -1280, -768, -5888, -11264, -9472, -8192, -5120, -5120, -8448, -7168, -8192, -8192, -4096, 256, 4352, 7936, 4352, -512, 512, -768, -5632, -8448, -9984, -10240, -8704, -5888, 3840, 14336, 11264, 3840, 6912, 5888, -1024, -3584, 512, 5632, 9728, 9472, 12288, 10240, 6400, 6144, 3840, 2816, 512, -512, -768, -3840, -7936, -10240, -9472, -8448, -4352, -4352, -7168, -7424, -10496, -8704, -1792, 256, 3328, 7936, 4352, -512, 1024, 256, -5120, -8960, -12032, -9472, -6144, -2560, 5632, 13312, 9728, 6656, 8960, 6656, -512, -2304, 1024, 5888, 10240, 9728, 11776, 9984, 8192, 7936, 4096, 512, -1792, -2048, -512, -5376, -9728, -11264, -9728, -7936, -4608, -3840, -7424, -8960, -11520, -8192, -256, -768, 1024, 7680, 4096, 768, 2048, 1024, -5120, -10752, -12288, -7680, -4352, -2048, 5376, 12544, 10496, 7680, 9728, 5888, -512, -1280, 256, 5376, 8960, 9472, 11264, 10240, 10240, 8448, 4352, 256, -3328, -2560, -2304, -8960, -10496, -10496, -9984, -8448, -4864, -3072, -6912, -10240, -12288, -7168, -1024, -2560, 2560, 7168, 3840, 2304, 3072, 1280, -6144, -11008, -11008, -5888, -4608, 0, 6656, 12032, 11008, 8960, 10240, 5120, -256, 256, 1024, 5120, 7168, 9472, 10752, 10752, 11776, 7936, 5632, 2048, -4352, -3840, -3840, -10752, -10496, -9472, -11264, -9472, -4096, -3328, -8448, -10496, -10496, -5120, -2816, -4352, 2560, 4608, 3328, 4096, 4352, 256, -6144, -9728, -9728, -6912, -5376, 2304, 7424, 11776, 11264, 11008, 9728, 4608, 768, 1536, 1536, 3072, 4864, 9728, 10496, 12032, 11264, 7168, 7424, 2816, -6656, -6400, -6912, -11520, -9984, -9984, -12288, -10496, -4608, -3328, -8448, -9728, -9216, -5376, -4864, -3584, 3328, 2816, 2816, 6656, 4352, -1536, -6400, -8192, -8192, -8960, -3584, 5376, 7936, 9728, 12544, 12544, 8704, 4864, 3328, 2560, 1024, 2304, 5120, 9472, 10496, 11520, 9984, 7424, 8960, 1536, -7168, -7168, -8960, -11008, -9472, -10752, -12800, -11264, -5120, -5120, -9472, -9472, -6912, -4096, -5888, -2816, 2560, 1280, 4352, 9216, 4096, -4096, -5888, -5376, -8448, -9728, -1280, 5888, 7168, 8960, 14080, 14080, 7936, 4352, 4608, 3072, 768, 1024, 5376, 8448, 10496, 11520, 7936, 8192, 9984, 768, -7424, -8960, -10496, -10240, -9728, -11520, -14080, -11520, -6656, -7936, -9216, -6656, -5632, -5632, -7424, 256, 2304, -256, 6144, 9984, 2048, -4864, -4352, -3584, -8192, -8704, 1280, 7424, 7424, 8960, 14848, 13056, 8192, 7424, 5888, 2816, 256, 1536, 7424, 9472, 9728, 9216, 6144, 11008, 9984, -512, -8192, -11264, -11520, -9216, -9216, -11520, -14080, -13056, -9472, -8960, -7680, -5632, -5120, -8192, -6144, 1536, 512, 768, 7680, 9216, 768, -4352, -4096, -4608, -7424, -6144, 2560, 7936, 6400, 8704, 14848, 11264, 8448, 9472, 6656, 2048, 1280, 2560, 9472, 9216, 8960, 7424, 5632, 12032, 9216, -1536, -9216, -13056, -12544, -8704, -9728, -12288, -14848, -13568, -11776, -10752, -6144, -5888, -5632, -8192, -3328, 1024, -1792, 2048, 8960, 7680, 1536, -3584, -5120, -4864, -5376, -5120, 3584, 8704, 7424, 11008, 13312, 9472, 9984, 11008, 6144, 2048, 1792, 3840, 11520, 8448, 9216, 6144, 6400, 11008, 6400, -2560, -9984, -13568, -12032, -8704, -9984, -13568, -14336, -13824, -14336, -10752, -5376, -5888, -7424, -6400, -1280, 256, -2560, 3072, 8960, 6912, 1792, -3584, -6400, -4864, -2816, -2560, 3328, 7936, 9472, 11264, 10752, 9472, 11520, 11264, 6144, 3584, 3328, 6144, 10240, 7168, 8960, 5888, 7936, 8960, 3840, -4096, -9728, -13568, -11520, -9472, -12288, -14336, -13824, -16128, -16128, -10240, -5888, -6144, -6912, -4864, 768, 256, -2816, 3584, 8448, 6144, 1280, -4096, -7168, -4352, -1536, -256, 3840, 9728, 9984, 9728, 7424, 9216, 13824, 10752, 5120, 5120, 4864, 8192, 9728, 7680, 7936, 5888, 8448, 5888, -256, -4352, -8960, -11264, -11008, -12032, -13056, -13056, -14336, -18176, -17152, -11520, -7168, -5888, -5888, -3328, 3072, -256, -3840, 3840, 8448, 5120, -512, -5632, -6400, -4352, -768, 2560, 6144, 11776, 11264, 7936, 6656, 10496, 13568, 10752, 5888, 5888, 6656, 9984, 9472, 8192, 6144, 7168, 9216, 2816, -1792, -4864, -9728, -9984, -9472, -12544, -13824, -13056, -15872, -19456, -17408, -13056, -7168, -4864, -5376, 256, 5632, -768, -2816, 3584, 6400, 4096, -1280, -6400, -6400, -3840, -512, 5120, 9216, 13056, 10752, 4864, 4864, 11008, 14848, 11008, 6400, 5376, 8960, 11776, 10496, 8704, 4352, 6656, 8448, 1280, -3840, -6400, -9984, -8704, -9472, -14080, -12800, -12544, -17664, -20480, -17152, -12800, -7936, -4608, -3072, 3072, 4352, -1280, -1280, 3584, 4352, 1536, -3840, -6912, -5632, -3584, 768, 9472, 12544, 12288, 10240, 5632, 5632, 9216, 13056, 11264, 7424, 5632, 10752, 12544, 10496, 7424, 4096, 7424, 7936, -2304, -7680, -8448, -8960, -7424, -9728, -14080, -11520, -13824, -20224, -20480, -16640, -13056, -8704, -4096, -512, 4608, 4608, 1280, 1792, 2048, 1536, 768, -4864, -5376, -5632, -4864, 3072, 13056, 13568, 12288, 9984, 5632, 4608, 9216, 11776, 10752, 8960, 7936, 11264, 11776, 10752, 7936, 6144, 8960, 5376, -6400, -9984, -8448, -7680, -6144, -10496, -13568, -12032, -15360, -20736, -20736, -16128, -13568, -10240, -3584, 1536, 6144, 5120, 2048, 1792, 0, -256, -1024, -5376, -5888, -7424, -4096, 7680, 15360, 14080, 12800, 9472, 4864, 4864, 8960, 11008, 11776, 9472, 7424, 11008, 12544, 11008, 8192, 6912, 7936, 3328, -8960, -11776, -9216, -6656, -7168, -11264, -13312, -12032, -16640, -21504, -21504, -17408, -12544, -6912, 0, 2560, 3840, 4864, 3840, 2304, -768, -2560, -4096, -5120, -6656, -7168, -512, 10496, 15104, 15872, 14336, 9472, 4096, 3840, 7936, 11008, 12800, 10752, 7680, 10496, 12544, 12544, 9728, 7168, 5888, 1280, -10752, -14080, -10752, -5376, -5632, -10240, -12544, -13824, -18176, -22016, -20736, -15872, -11264, -5376, 1280, 4352, 4096, 6400, 5888, 0, -3328, -4352, -4352, -6144, -8192, -5376, 3840, 11520, 14848, 16896, 13312, 8448, 3840, 2304, 8960, 10752, 11264, 11264, 9216, 9728, 12800, 13312, 10240, 7168, 4096, -2816, -12288, -15360, -11008, -5632, -5376, -10240, -13568, -14848, -19968, -23040, -20224, -15616, -10752, -2304, 3584, 3840, 4096, 5632, 5376, -1024, -5120, -5376, -4864, -7680, -7936, -2560, 6656, 13824, 16128, 17664, 13056, 8448, 3072, 3328, 10240, 10752, 11520, 10752, 8448, 9216, 13568, 14592, 11264, 6144, 768, -6144, -13568, -16128, -11520, -5376, -3840, -9984, -14592, -16128, -19968, -22784, -19456, -14080, -8704, 768, 4608, 2304, 4096, 5376, 3840, -2048, -6656, -7168, -6400, -8192, -6144, 1024, 8704, 14336, 17152, 19200, 12288, 5632, 1792, 5888, 11264, 9984, 10240, 10240, 8960, 10240, 15104, 15104, 11264, 4608, -1536, -7936, -13824, -14848, -11264, -5120, -3328, -11008, -16128, -17664, -20480, -22528, -18176, -12288, -5376, 3072, 4096, 3072, 4608, 3328, 1536, -3072, -6912, -8192, -7680, -8704, -5120, 3328, 11776, 16128, 18944, 18688, 10240, 3840, 3328, 9984, 11776, 8448, 8192, 8960, 9216, 12288, 14848, 15616, 11008, 4096, -3328, -9216, -14592, -15872, -10496, -5632, -4096, -10752, -16896, -18688, -20224, -21760, -16640, -9728, -1792, 3328, 2304, 1792, 4096, 2816, -512, -4608, -9216, -9984, -6656, -6400, -4096, 5376, 13568, 16384, 18944, 17408, 9216, 4864, 5632, 9728, 11264, 8192, 7168, 8192, 9728, 13312, 15360, 14336, 11008, 3328, -6400, -9984, -13824, -13312, -8960, -7680, -6912, -11776, -17920, -20224, -20480, -20224, -14848, -6656, 768, 3840, 1536, 0, 3072, 1536, -2048, -6912, -11520, -9984, -4352, -4096, -3328, 7168, 14592, 17152, 18176, 14592, 9472, 5632, 6400, 10496, 11776, 7424, 6144, 8704, 11264, 14336, 14080, 13312, 11264, 1792, -6912, -9728, -12288, -11264, -8960, -7936, -7424, -11776, -19712, -21248, -18688, -17920, -12288, -3840, 1536, 2304, 256, 256, 2304, -768, -5120, -10496, -12288, -7680, -1280, -3584, -2304, 9984, 16128, 17920, 16896, 12032, 9216, 6400, 8192, 10240, 11008, 6656, 5376, 9216, 12032, 15104, 12800, 12544, 8960, 0, -6656, -9216, -11264, -10496, -9216, -8960, -8448, -12800, -20224, -20224, -16896, -16128, -9216, -2048, 1536, -768, -2304, 512, 768, -3328, -7680, -12544, -11776, -4608, -512, -3840, 1024, 10752, 14848, 16640, 15616, 12800, 9728, 7168, 9472, 10240, 9728, 7168, 7680, 9728, 12288, 12800, 10752, 11776, 7168, -768, -7168, -9472, -9216, -9216, -9984, -9216, -9472, -15104, -20224, -17664, -15872, -13312, -6144, -512, 768, -3072, -2816, 1024, -1280, -7424, -10752, -13568, -9984, -3072, -1024, -1024, 3584, 9472, 13312, 16128, 14848, 12800, 9472, 8704, 9472, 9216, 9472, 9728, 9216, 8960, 12032, 11776, 11264, 10752, 4608, -1792, -7680, -8704, -8192, -8704, -10496, -9472, -11520, -16896, -18944, -16384, -14592, -9216, -3072, 256, -2048, -5888, -1792, 1536, -4608, -9984, -12544, -13568, -7424, -1280, -256, 2560, 4864, 7680, 11776, 15104, 14848, 12800, 9216, 9472, 9472, 8192, 10240, 11776, 9728, 8704, 11264, 10752, 10496, 9216, 2304, -2304, -6912, -7424, -6656, -8704, -10240, -10240, -14336, -17664, -16896, -14336, -11776, -5632, -1792, -1792, -4864, -5376, 768, 256, -8960, -12288, -13568, -12544, -5632, -768, 3072, 5888, 4608, 5632, 11776, 16896, 15104, 12032, 9728, 11008, 8960, 7680, 11776, 13056, 9984, 8448, 10496, 9472, 10752, 6144, 512, -2048, -5632, -5888, -6144, -8448, -9984, -12800, -16896, -17664, -15104, -12544, -7936, -3328, -2560, -4352, -6400, -4096, 256, -4352, -12800, -14080, -14848, -10752, -4352, -256, 5120, 7936, 3584, 3840, 12288, 17920, 15104, 10752, 9728, 11520, 8448, 8448, 13056, 13568, 9216, 8960, 9472, 9216, 9472, 3072, 0, -2304, -4096, -4608, -5632, -8448, -10752, -15104, -17152, -15872, -13312, -10240, -5120, -2816, -3840, -5888, -5888, -2816, -768, -7168, -13056, -15104, -15616, -9728, -3584, 1024, 6656, 7680, 2560, 4608, 13568, 18176, 14336, 10240, 10752, 11520, 8192, 8704, 13568, 13312, 9472, 9216, 8192, 9472, 8192, 2560, -768, -2560, -2560, -2816, -4352, -7936, -11776, -15872, -16128, -13824, -11264, -7680, -3584, -3584, -5888, -6912, -5632, -2816, -2816, -8960, -13056, -16640, -15104, -8192, -2816, 2816, 7424, 6400, 2048, 6144, 16128, 18688, 13056, 9728, 11776, 11264, 7424, 8704, 13056, 13056, 9984, 8704, 6912, 8704, 5888, 768, -1280, -2304, -1536, -2560, -4608, -8448, -13056, -16896, -15360, -12800, -8960, -5120, -2560, -5376, -8448, -7424, -4352, -2304, -5120, -9984, -14080, -18176, -14592, -6656, -1792, 2816, 5888, 5632, 2816, 8960, 17920, 18176, 11776, 9984, 12288, 10752, 7424, 8448, 13056, 12032, 9728, 7936, 7168, 8960, 4352, 0, -3072, -1792, 0, -1024, -3840, -9216, -14336, -17152, -14336, -10752, -6656, -3840, -3072, -7424, -9216, -7168, -3840, -3328, -6400, -10240, -14848, -17920, -12544, -5888, -1536, 2048, 4864, 4352, 4608, 12544, 19456, 16896, 10240, 10752, 12544, 9984, 6400, 8960, 13056, 11008, 10240, 7680, 7936, 8192, 3840, -256, -3584, -1792, 256, -512, -4352, -10240, -15104, -15616, -13056, -9728, -5376, -2560, -4352, -8704, -8960, -7168, -4608, -4352, -6144, -10240, -16384, -16640, -10240, -4608, -2048, 1280, 3328, 4352, 7936, 15616, 19200, 15360, 10496, 11008, 12032, 8704, 5120, 9216, 12032, 11008, 10496, 7936, 8192, 6656, 1792, -1792, -4096, -1536, 0, -768, -5632, -11264, -15360, -14336, -12032, -8704, -4864, -2048, -5120, -9984, -10240, -6912, -4608, -5120, -7424, -11264, -16128, -14336, -9728, -5888, -2816, 1024, 3584, 5376, 10752, 16640, 18176, 15104, 11520, 10752, 8704, 5376, 5120, 10752, 12288, 11264, 10496, 7936, 8704, 6144, 1536, -2560, -5120, -2816, 1024, 0, -5120, -12288, -14592, -12032, -9984, -7680, -4352, -1024, -6144, -11008, -10240, -6656, -4864, -6144, -7424, -11520, -15104, -13056, -9472, -6400, -3584, 768, 3840, 6912, 13056, 18432, 19456, 15616, 11264, 9728, 5888, 3072, 5376, 11008, 11776, 11520, 10240, 7936, 8960, 5376, 1280, -4352, -5632, -3328, 768, 256, -6144, -13056, -13312, -11008, -9472, -7168, -2048, -1792, -9728, -11776, -9216, -5376, -5376, -7936, -8448, -11520, -13056, -12032, -10240, -7680, -3328, 1024, 3584, 8448, 15360, 19456, 19456, 15616, 12032, 7680, 4096, 2048, 5120, 10240, 11520, 12288, 9472, 9472, 9472, 5632, 768, -4864, -5120, -2560, 1024, -1536, -7680, -12544, -11264, -10496, -9728, -5888, -256, -3584, -10496, -11264, -9216, -5632, -6656, -8960, -8448, -11520, -13312, -12288, -10240, -8192, -2304, 1536, 4608, 8960, 16640, 21760, 20480, 15872, 11776, 6144, 1536, -256, 5888, 10496, 12288, 11520, 7936, 10752, 10240, 5888, -1536, -5376, -3840, -1536, 0, -3328, -7936, -11264, -10496, -9728, -8192, -3840, 0, -5632, -10240, -10496, -9216, -6144, -7936, -7168, -8192, -11776, -12544, -12032, -11008, -7680, -1536, 2304, 4864, 11776, 19712, 22272, 19712, 15616, 10752, 4608, -512, -1792, 5632, 9984, 13056, 10496, 8192, 11008, 8960, 3328, -4608, -4608, -2560, -1280, -2048, -5376, -7424, -9984, -10752, -10496, -5888, -768, -768, -8192, -9984, -9728, -8704, -7936, -8960, -5888, -8192, -11776, -12800, -13056, -11776, -6656, 0, 3072, 5120, 13824, 22272, 23296, 18432, 15360, 9728, 3328, -2560, -2816, 6144, 11264, 13312, 11008, 9984, 11520, 8704, 512, -4864, -2048, -256, -2048, -4864, -4864, -6400, -8960, -10752, -9984, -4352, 1792, -1792, -9728, -9216, -9216, -9472, -9472, -7936, -5120, -8704, -12544, -13568, -12800, -11008, -4864, 1536, 2560, 6400, 16896, 23296, 21504, 17152, 15360, 9216, 256, -4608, -2560, 6912, 12288, 13312, 10752, 10752, 9728, 6400, -768, -4608, -1280, -512, -3328, -5632, -6144, -7168, -8960, -11520, -8960, -1024, 3584, -4352, -10496, -9216, -8448, -8960, -10496, -7424, -5120, -9728, -13056, -13824, -11776, -8448, -3584, 1536, 3584, 9472, 18944, 22272, 19456, 16640, 16384, 7424, -2304, -5632, -1792, 5888, 13312, 14080, 11776, 10752, 6400, 4352, -1280, -3072, -1024, -768, -4352, -6400, -8448, -9216, -8448, -9984, -7680, 1280, 3072, -6400, -9472, -8448, -8704, -10752, -10496, -6400, -5632, -10496, -13312, -13568, -10240, -6400, -2560, 2816, 5376, 11008, 18432, 19968, 18944, 17664, 14848, 3840, -3328, -3840, -1024, 5632, 13824, 14848, 13568, 10496, 3840, 1536, -512, -256, -768, -1536, -4608, -6144, -10752, -10240, -7424, -8192, -5120, 3328, 2048, -6400, -8960, -8704, -7424, -10752, -11008, -6912, -6912, -10752, -13056, -12800, -7680, -3584, -1280, 4352, 6656, 11776, 17920, 18432, 18432, 17664, 12288, 512, -3328, -2304, -768, 4864, 14080, 15104, 13568, 7680, 256, -256, 1280, 2048, -1792, -3840, -4864, -6400, -12288, -11520, -7936, -7168, -2560, 3840, 256, -6144, -8960, -8960, -5632, -9472, -11008, -9216, -8960, -10496, -12032, -11520, -4608, -1536, -256, 6144, 8192, 13056, 16640, 16640, 17152, 16128, 9472, -768, -3328, -2304, 256, 7424, 13824, 15360, 12800, 4608, -1024, -1024, 3328, 2304, -2560, -3840, -4352, -7680, -13824, -12032, -7424, -5120, -2048, 1024, -2048, -3840, -7424, -8960, -5376, -9472, -11008, -11776, -9472, -8448, -12288, -9984, -2560, 768, 3328, 7936, 8704, 13824, 14336, 14592, 16128, 14336, 8192, -768, -4096, -1536, 3584, 9728, 12288, 13568, 10240, 2816, -768, 256, 1536, -512, -2816, -2304, -2816, -7168, -13824, -13824, -7424, -2048, 512, -2048, -4096, -3328, -6912, -7936, -5376, -8192, -11520, -13824, -9216, -6912, -11264, -8448, 256, 4096, 6400, 7424, 9984, 14336, 12288, 13056, 14592, 12288, 5632, 768, -3584, 0, 5632, 9984, 10752, 11776, 9216, 1792, -1792, 0, 0, -768, -2048, -2048, -3840, -8704, -12800, -12544, -6912, -768, 0, -3840, -3584, -4096, -7168, -6656, -5376, -8704, -14336, -14080, -8192, -7680, -10496, -5888, 2048, 5120, 7936, 8448, 11520, 13568, 9728, 10752, 13824, 10240, 4608, -768, -2304, 3584, 8448, 9472, 8704, 8704, 6912, 2048, -1280, -256, -2304, -768, -256, -2048, -4864, -8960, -11008, -10752, -7168, -1792, 256, -4608, -3328, -4352, -7424, -6144, -5376, -8704, -14080, -13312, -8704, -7680, -6656, -2304, 3840, 7168, 7168, 8192, 14080, 12800, 7424, 9728, 11520, 8960, 4352, -768, -256, 4608, 9216, 10240, 6912, 6144, 4864, 0, -1280, -256, -3584, -1792, -512, -3072, -5120, -7680, -10240, -10752, -6400, -1280, -1280, -6144, -3584, -4096, -6400, -5120, -6656, -9728, -13312, -12544, -8960, -7936, -3328, 2048, 4096, 7168, 7424, 10752, 14592, 10240, 5888, 8192, 8960, 7680, 3072, -1280, 2304, 5632, 10240, 9728, 4864, 4352, 4096, -256, -2304, -1792, -3072, -1536, -1280, -3328, -4608, -7424, -9984, -9984, -4608, -768, -4864, -6656, -2816, -4608, -6144, -4864, -7680, -10240, -13056, -11520, -7680, -6144, 0, 4864, 5632, 7168, 9216, 12544, 13824, 10496, 5632, 7680, 7936, 6656, 2560, 512, 2560, 6656, 11008, 7168, 3584, 4096, 1792, -1536, -3072, -2304, -2304, -1280, -3072, -4864, -4096, -7424, -8960, -8704, -2048, -2048, -8960, -5120, -1792, -6656, -5888, -5888, -7680, -9984, -13568, -9728, -6400, -3072, 2816, 6144, 6144, 7424, 12032, 12800, 12288, 9216, 5120, 7424, 6144, 3840, 1280, 2048, 3072, 8192, 10240, 5376, 4352, 2816, 0, -768, -3840, -3584, -1792, -1024, -3328, -4352, -4096, -7168, -7936, -5888, -1536, -5120, -9472, -3840, -3072, -7424, -5632, -7168, -7680, -9728, -13824, -8704, -5120, -1024, 5376, 8448, 6144, 8448, 12800, 11520, 10240, 8448, 6912, 7168, 3584, 2048, 2048, 2816, 2816, 7680, 8448, 6656, 5120, -256, -2048, -1024, -4352, -4096, -512, -1792, -5632, -5120, -5120, -6656, -6656, -3840, -2560, -6912, -8960, -3072, -4864, -7936, -5376, -5888, -5888, -10752, -14592, -7936, -2816, 2304, 8960, 8448, 5888, 9984, 13568, 12032, 10240, 7936, 7936, 5376, 2560, 2304, 2816, 2560, 3328, 6656, 8960, 8448, 3328, -2816, -2560, -1024, -4864, -5632, 768, -512, -7168, -6656, -4096, -5376, -6144, -3072, -3072, -7936, -8704, -4352, -6912, -8704, -6400, -4352, -4864, -12288, -15104, -7424, -512, 6912, 11776, 6656, 5632, 11008, 13824, 11264, 9728, 7680, 7424, 4096, 1536, 3840, 3840, 1536, 2304, 5632, 9216, 9472, 2304, -5120, -2560, -1280, -5376, -5376, 512, -1280, -7424, -7936, -4608, -2816, -4352, -2816, -3840, -8192, -8704, -5888, -7680, -7680, -6400, -3840, -5632, -13312, -12800, -4352, 2304, 9216, 10752, 6656, 7424, 12800, 13568, 10240, 8448, 8192, 6912, 3584, 1792, 2304, 1792, 1024, 3072, 5632, 9216, 9216, 768, -6912, -4096, -2304, -5120, -5376, -256, -3072, -7936, -6912, -3328, -3072, -4608, -3072, -4352, -8448, -9984, -7424, -8704, -8960, -5888, -1792, -6400, -14080, -10752, -2560, 5120, 11008, 10240, 6912, 8448, 13056, 13056, 9472, 8704, 7936, 5376, 2304, 2048, 1280, 512, 2816, 4096, 4608, 8704, 8960, 768, -5632, -4352, -4096, -5120, -4352, -1792, -5120, -8192, -7168, -3584, -3072, -2560, -2048, -4352, -8704, -10496, -8960, -8704, -7936, -4864, -2048, -6912, -12288, -7424, -1024, 6656, 12800, 11264, 8192, 9472, 12800, 12544, 10240, 9216, 5632, 2816, 2816, 3072, 1280, 768, 3584, 3072, 3328, 8704, 9472, 2304, -5888, -6144, -4096, -5376, -4096, -4352, -7680, -6912, -6912, -5120, -2560, -2560, -2304, -4608, -9984, -11776, -10752, -8960, -7936, -3584, -2304, -8448, -10752, -4864, 256, 9216, 14080, 10496, 8192, 11776, 14080, 12032, 8960, 8192, 4608, 1536, 1792, 2304, -512, 1792, 4352, 2048, 3328, 8704, 8192, 2560, -5632, -6912, -3584, -5120, -5376, -6656, -7936, -5888, -6912, -5632, -1536, -1280, -2816, -5376, -9984, -11776, -11776, -9472, -7680, -3584, -3072, -8448, -7936, -2048, 1536, 10496, 14080, 10240, 9728, 13824, 14592, 9984, 7680, 8448, 4352, 512, 256, 1024, 1792, 3584, 3584, -512, 2816, 9472, 7936, 2816, -6656, -7680, -4096, -5120, -4608, -5376, -6912, -8192, -7168, -3072, 0, -1024, -2816, -5888, -10240, -11776, -11008, -8448, -6656, -4096, -3840, -7424, -4864, -256, 3328, 11264, 14848, 10496, 12544, 17408, 15104, 9216, 7168, 9216, 4608, -2304, -2304, 1024, 4352, 5120, 1792, -1536, 4608, 9216, 5632, -256, -7680, -6656, -4864, -6400, -6656, -7936, -8960, -8448, -5376, -768, -2048, -2560, -3584, -6144, -10240, -11520, -11008, -8960, -5120, -4608, -5120, -5632, -3072, 0, 3840, 12288, 14848, 10496, 14848, 19712, 14592, 7680, 6912, 8448, 1792, -5888, -4096, 2816, 5888, 5376, 512, -1280, 6144, 8448, 2560, -2560, -6144, -4864, -6400, -9472, -7680, -7680, -8704, -7424, -3584, -1280, -4096, -2048, -2048, -6656, -12800, -12032, -10496, -7680, -4096, -6400, -6144, -3584, -1536, 768, 5888, 12800, 13056, 12544, 17664, 20736, 14336, 7424, 8448, 7680, -512, -7424, -3584, 3840, 6656, 4608, 512, -256, 7936, 7168, 0, -5120, -5376, -5376, -8192, -11008, -8704, -8448, -9216, -5888, -1024, -2048, -5120, -2048, -2816, -6400, -11264, -10496, -9984, -8192, -4352, -7680, -5632, -1024, 256, 1536, 7936, 12288, 12032, 16128, 20480, 20992, 13312, 7936, 9728, 5888, -3328, -8448, -2816, 5120, 7424, 3584, -256, 2304, 8704, 4864, -3072, -6656, -3328, -5888, -11776, -11776, -9728, -9984, -8960, -6144, -768, -1792, -4352, -3840, -4096, -6400, -11520, -9472, -9472, -8448, -6656, -9216, -5120, 1280, 768, 1024, 8192, 10752, 12800, 19456, 21248, 19200, 12544, 8704, 9216, 4352, -6144, -8448, -3072, 5888, 8192, 2560, 256, 5888, 7680, 1792, -4352, -5632, -2048, -6912, -12544, -12800, -10752, -9728, -7168, -4608, -768, -2048, -3328, -3584, -3840, -6144, -11008, -8960, -8448, -7424, -6912, -8704, -3840, 4096, 2048, 1280, 8192, 11008, 15872, 21504, 21504, 18688, 13568, 10240, 7680, 1536, -6656, -8704, -3840, 6400, 7168, 2048, 2304, 9728, 6912, -1024, -6656, -5376, -3072, -8448, -13824, -12032, -12288, -9728, -5376, -3584, -512, -768, -2816, -6400, -4608, -6656, -8192, -8704, -8704, -7424, -7936, -8960, -2560, 4608, 2816, 1792, 8448, 12032, 17408, 21248, 20736, 18176, 14848, 10752, 5120, -1280, -6400, -9216, -3840, 5888, 5888, 1792, 5120, 10240, 5376, -3584, -8960, -5376, -4096, -10240, -14848, -13312, -13312, -7936, -2816, -2304, -1536, -256, -3840, -6656, -3840, -7424, -7936, -9216, -7936, -7424, -9216, -8192, -1024, 4352, 2048, 3840, 9216, 12288, 16896, 19712, 21248, 19712, 15104, 9728, 2304, -2816, -5120, -8704, -3072, 5632, 5120, 3584, 8448, 9984, 4096, -5632, -9216, -5888, -5376, -10240, -14336, -13312, -12032, -6144, -2560, -1024, 768, 256, -4352, -5632, -4608, -7168, -6656, -8192, -7680, -8192, -7680, -5632, 256, 3840, 3840, 6912, 10752, 13312, 15872, 19200, 21760, 20480, 15104, 8960, 256, -4096, -5120, -8960, -3072, 4608, 4352, 4608, 10240, 8704, 1280, -8704, -9728, -6912, -7168, -10752, -15360, -14848, -12288, -4608, -1024, 0, 768, -1024, -4608, -5120, -5632, -8960, -7424, -6912, -8704, -10752, -7168, -3072, 768, 2048, 4864, 7936, 10240, 11520, 15360, 19200, 20224, 19456, 15872, 9472, -512, -5120, -5632, -7936, -2816, 3328, 3840, 7936, 11008, 6912, 0, -7168, -8448, -9216, -9472, -11008, -14848, -15616, -12032, -3328, 256, 256, 768, -1280, -3072, -4352, -6400, -9216, -6912, -6400, -9984, -11520, -6144, 256, 0, 2048, 6400, 11008, 11520, 10752, 14592, 19456, 19456, 18688, 15360, 9472, -2048, -6400, -5632, -6400, -1536, 2304, 5376, 10496, 10496, 3840, -1536, -4608, -8448, -12288, -10240, -9728, -14592, -16384, -11776, -1536, 2304, -1024, 256, -256, -2304, -4608, -7168, -8448, -6144, -6912, -10752, -11520, -4608, 512, 768, 3328, 7936, 12544, 11008, 9472, 15360, 18944, 17408, 17408, 15360, 7680, -3072, -7168, -5888, -4864, -2048, 1280, 6656, 12288, 9472, 2816, -3072, -4352, -9472, -13824, -10240, -10496, -14848, -16640, -10752, 1280, 3072, -2048, 0, 512, -1536, -5632, -7424, -7680, -7168, -9472, -11264, -10752, -2304, 1536, 1792, 4352, 8448, 11264, 10752, 10240, 15616, 18432, 14592, 16128, 15616, 6144, -4096, -8704, -5376, -3840, -3072, 768, 7936, 12032, 7168, 1792, -2560, -3840, -11008, -13056, -9728, -11520, -15616, -15616, -7936, 2560, 2048, -768, 1536, 1280, -2048, -6144, -6912, -7168, -7936, -11264, -10752, -7424, -768, 1536, 2560, 6144, 10240, 11264, 11520, 11776, 14592, 15872, 14336, 16640, 14336, 4096, -3328, -8192, -4608, -3072, -2560, 2816, 8192, 9984, 6400, 1536, -2560, -4864, -12288, -11264, -9728, -12544, -16128, -15616, -4864, 3072, 768, 1024, 1536, 768, -2304, -6400, -6656, -6912, -9728, -11776, -9984, -4608, 256, 3072, 5120, 7424, 8448, 9216, 12544, 12032, 13824, 15104, 12544, 16128, 13056, 2048, -3072, -6400, -4608, -4608, -1536, 5120, 8448, 7168, 4864, 1024, -2304, -6912, -11008, -10496, -11520, -14080, -16384, -13056, -3328, 1792, -768, 0, 1792, 768, -3072, -7168, -6912, -8448, -11776, -13056, -8448, -2560, -1280, 3840, 7936, 8704, 6656, 8192, 12032, 13056, 13568, 12032, 12800, 15616, 10496, 256, -2048, -3072, -5376, -5120, 1280, 6912, 7424, 4096, 3328, 2048, -2304, -7168, -10240, -10240, -11264, -14080, -15872, -10240, -2048, 1280, -512, 1024, 2816, 1024, -3840, -6656, -6656, -9472, -12544, -12032, -6912, -2048, -768, 5632, 11520, 9728, 5632, 8704, 12032, 14080, 13312, 9984, 11264, 14848, 8192, 512, 0, -1792, -6400, -5376, 2560, 7424, 7680, 2304, 0, 0, -1792, -6656, -9728, -10240, -13568, -15616, -13568, -7680, -1280, 256, -512, 1280, 2560, 768, -4608, -6400, -8448, -11008, -13056, -11776, -5120, -2560, -2048, 6656, 13312, 8960, 4864, 8192, 12032, 14336, 11776, 8448, 11264, 12288, 5120, 2560, 2816, -1792, -7424, -5120, 3840, 8960, 7168, 512, -2304, -2048, -1536, -6656, -8192, -9216, -13824, -16384, -13312, -5632, 256, 768, 512, 768, 3840, 512, -5632, -6144, -8704, -10496, -11520, -9984, -4864, -2304, 256, 8960, 14592, 9472, 4608, 6912, 11776, 13312, 10496, 9472, 11264, 10240, 4608, 4096, 3328, -1792, -7424, -3584, 5888, 9216, 4352, -1536, -4352, -512, 256, -6144, -9728, -11008, -15104, -15872, -11264, -5632, -1024, 1792, 512, 1280, 4096, -512, -6144, -6912, -9216, -11008, -12288, -9472, -5120, -1280, 3584, 10240, 13312, 9216, 5120, 6656, 11008, 11776, 10240, 10496, 10752, 7168, 4864, 4864, 2304, -1024, -5376, -2560, 6912, 8192, 2560, -1536, -4096, -1024, -1280, -3584, -9472, -12288, -15104, -14848, -9216, -6144, -256, 3328, -768, 1792, 4096, -1280, -4864, -8192, -9728, -11776, -11008, -8192, -5632, -1792, 5632, 12544, 14592, 9472, 5632, 5120, 9472, 10496, 9216, 11776, 10496, 5376, 4864, 4096, 2304, -512, -6400, -2304, 6912, 6144, 2048, -3072, -2816, -512, -2304, -2560, -9984, -13056, -15104, -15104, -8960, -5376, 512, 3840, -1280, 2560, 2816, -3072, -4864, -8960, -9984, -11776, -8960, -7424, -6656, -1280, 9472, 15360, 13568, 9216, 6656, 4864, 8448, 9472, 8448, 12288, 10496, 4608, 4352, 4864, 2816, -2048, -5888, -768, 7680, 5376, -1280, -3584, -512, -1536, -2304, -2304, -10752, -15104, -16384, -13824, -8448, -4096, 1536, 3584, 0, 3840, 1024, -3584, -4352, -8960, -11520, -11776, -8448, -6912, -5632, 512, 10752, 14336, 12544, 9472, 6656, 4864, 6656, 5888, 9216, 14848, 11264, 2816, 2048, 5888, 2560, -1792, -3840, 768, 6656, 3072, -2560, -2048, 768, -2560, -1792, -3328, -11776, -14848, -15360, -14592, -10240, -2816, 2304, 2304, 768, 3328, -1536, -3072, -4352, -10752, -13568, -11520, -7168, -5888, -3584, 2816, 12544, 15360, 12544, 10240, 6912, 3584, 4096, 3328, 11008, 15872, 11776, 1536, 2048, 5632, 1792, -2304, -2560, 2816, 5888, 1024, -4352, 512, 1536, -1536, -1792, -5376, -13056, -14848, -14848, -14080, -9728, -3072, 3072, 2560, 3328, 256, -3840, -1792, -3584, -12032, -15872, -11520, -7424, -4864, -512, 5376, 13056, 16128, 11776, 9472, 7936, 4096, 0, 1024, 11008, 16384, 11008, 1536, 2304, 6144, 1024, -3840, -512, 3584, 2304, -2304, -3840, 3584, 1792, -2816, -2560, -7424, -13568, -13824, -14592, -12288, -8960, -2304, 3328, 2304, 2816, -1280, -1536, -512, -5632, -14592, -15360, -9984, -6144, -2816, 1280, 7680, 13312, 15872, 12544, 10752, 9728, 2816, -2304, 1792, 11520, 15616, 11264, 2560, 3840, 5376, -1024, -3840, 768, 3328, 256, -3328, -2304, 3328, 1792, -2304, -3328, -8192, -13056, -13568, -14336, -11264, -8960, -2304, 3840, 2816, 1792, -2048, 0, -512, -8704, -16640, -14336, -7936, -6144, -1792, 5120, 9472, 12544, 14336, 12032, 12032, 9984, -768, -4096, 3072, 10240, 13568, 11520, 4096, 5888, 4352, -1792, -2048, 1792, 2048, -1280, -3072, -1792, 1792, 1792, -1024, -4352, -9728, -14336, -15360, -12800, -9472, -8448, -2048, 1792, 2304, 0, -1536, 1792, -2048, -12032, -18176, -12800, -6400, -5888, 0, 8448, 10496, 11776, 13312, 13568, 13824, 8960, -1536, -2304, 3328, 8192, 12800, 12288, 5888, 6400, 3328, -1024, -768, 0, -256, -1792, -1792, -2048, 768, 1536, -768, -5632, -10496, -14080, -15872, -11776, -7680, -6144, -1280, 0, 1280, 512, 768, 2560, -5120, -14592, -17664, -10496, -4864, -4096, 1280, 9472, 12032, 11776, 12544, 13824, 14848, 7424, -1024, -1536, 1792, 5376, 12544, 12544, 6144, 6144, 3072, -512, -1280, -2304, 0, 0, -2560, -3840, 512, 2048, -1024, -5888, -10752, -14592, -16896, -11008, -5632, -4096, -2816, -2048, 768, 1280, 1792, 1024, -7168, -15616, -15616, -9216, -4864, -2816, 2560, 11520, 13056, 11008, 11776, 13312, 13824, 6656, 768, -2048, -768, 3840, 13312, 12288, 6912, 7680, 3840, -256, -2304, -3584, 0, -512, -3840, -4352, -512, -256, -1280, -5888, -9472, -15872, -16384, -8704, -4352, -3840, -4864, -2048, 1024, 1792, 2048, -2048, -9472, -14080, -12800, -8448, -4864, -1280, 4096, 12544, 13824, 11264, 11520, 13312, 13568, 8192, 768, -3072, -1280, 3584, 11776, 11776, 9728, 8704, 5376, 1536, -3328, -5376, -512, -768, -4608, -4864, -3584, -2304, -512, -3584, -11264, -18944, -14336, -6656, -3840, -4096, -4608, -1536, -256, 1792, 1536, -5120, -11008, -12288, -8960, -8192, -6144, 256, 5888, 13056, 13824, 10496, 10752, 13312, 12544, 8192, 768, -3584, -1280, 4864, 10752, 12032, 11008, 9728, 6912, 2560, -4608, -4864, -1280, -1792, -4608, -6912, -5888, -2304, 512, -2048, -13056, -19200, -10496, -4864, -3840, -3328, -3840, -2816, -1280, 2560, 256, -7680, -9472, -10240, -7680, -8448, -6144, 1536, 7680, 12544, 12544, 11520, 11008, 13312, 9984, 6144, 1792, -2560, -1792, 3072, 8448, 11264, 12288, 11008, 9216, 1792, -7424, -4608, -1536, -3584, -5888, -9216, -8192, -3072, 512, -4096, -15360, -16640, -6912, -5632, -5632, -2304, -1536, -3584, -1536, 2816, -2560, -9728, -8960, -6912, -6656, -8960, -3840, 4608, 9984, 12032, 12288, 13056, 14080, 13056, 7168, 5632, 3328, -1280, -1536, 1280, 6912, 11776, 14592, 12544, 9984, 256, -7424, -3072, -1792, -3840, -7168, -12288, -9984, -2816, -256, -7168, -15616, -13056, -5632, -7680, -5632, -768, -1024, -5376, -1536, 2048, -5888, -11520, -7424, -4608, -6912, -8192, -2816, 6144, 11264, 10240, 11776, 14336, 15616, 11264, 4352, 4608, 4864, 256, -2816, -512, 6144, 12288, 14592, 13824, 11520, 512, -6912, -3072, -2816, -4608, -8192, -12544, -10496, -4096, -2560, -8192, -12032, -8448, -6400, -8704, -3328, 1536, -1280, -6144, -3328, -1024, -7424, -11008, -7424, -4608, -6400, -5376, -256, 6400, 11264, 10240, 12544, 17152, 15360, 7936, 3072, 4608, 6144, -512, -4608, -1280, 5632, 11520, 15872, 16640, 11776, -1280, -5376, -3072, -3072, -4352, -9216, -14592, -12288, -5888, -3840, -7424, -8960, -7168, -8448, -7936, -768, 3072, -4096, -8192, -3072, -4864, -9216, -8448, -6400, -5632, -7424, -2560, 3584, 7680, 10496, 8960, 13056, 18688, 14592, 6912, 4096, 5376, 3584, -1024, -3072, -512, 5376, 10496, 15872, 18176, 11008, -1792, -3072, -4864, -5632, -5888, -11776, -14592, -13056, -8960, -5120, -4352, -5632, -6656, -9472, -6912, 1792, 3072, -6144, -7936, -3584, -7424, -8704, -7680, -5632, -5120, -5376, 512, 3840, 6656, 10240, 11520, 14080, 16896, 13312, 7168, 5120, 4352, 2560, -256, -3072, -1024, 5376, 11008, 16640, 18944, 9984, 256, -2304, -6400, -6912, -6144, -11520, -15616, -14080, -11008, -5632, -2304, -3072, -6144, -8192, -6656, 2304, 1792, -6400, -7936, -7680, -10240, -7936, -6656, -4864, -5120, -2816, 3584, 4608, 6912, 11520, 13824, 13312, 15616, 12544, 8448, 6144, 3840, 1280, 0, -3584, -512, 6144, 11264, 15872, 17152, 9472, 3072, -2304, -7680, -7424, -8448, -12544, -16896, -14848, -13056, -6400, -512, -1536, -4864, -7936, -6144, 1536, 768, -5376, -9472, -11008, -10752, -7936, -6400, -4352, -4864, -1280, 3840, 4864, 7680, 13312, 14336, 11520, 13824, 13312, 9728, 5632, 2816, 2048, 0, -4096, 512, 6912, 11264, 16128, 15360, 8704, 4096, -2560, -6400, -7936, -9728, -14080, -17408, -15872, -13568, -4608, 1280, -512, -4352, -7936, -4096, 1280, -1024, -5632, -11008, -12800, -9728, -8192, -5376, -4096, -2816, 2048, 2560, 4864, 8192, 15360, 15360, 11008, 11776, 13056, 9472, 6144, 3328, 2048, -1536, -4352, 1024, 8192, 13312, 14336, 13312, 9984, 5888, -1280, -5888, -10496, -12288, -16384, -16640, -16128, -14592, -3584, 2304, 768, -4608, -7168, -2304, 0, -2816, -6400, -12032, -13568, -9728, -7680, -4864, -2816, 0, 2560, 2816, 5888, 10752, 16896, 15360, 10752, 12544, 13568, 9216, 6144, 5120, 2304, -4352, -4608, 768, 9984, 15104, 12544, 10496, 9984, 6656, 256, -6144, -13568, -15104, -17920, -15616, -16896, -14848, -3072, 4352, 1792, -5120, -6656, -1792, -1792, -4096, -7680, -13056, -15360, -11520, -6656, -2816, -1280, 1280, 2048, 2560, 5888, 12288, 16896, 14080, 10240, 12288, 12288, 8448, 7680, 6400, 512, -5376, -3840, 2560, 10496, 13056, 11264, 9472, 10496, 6912, 1536, -7168, -15360, -16640, -17920, -16128, -17920, -14080, -1536, 5376, 256, -5120, -3840, -512, -3840, -6144, -8192, -13824, -16896, -11520, -5632, -2048, 1536, 3328, 1280, 3840, 7936, 13056, 16384, 14848, 10496, 10752, 11264, 8960, 9216, 7424, 0, -5120, -2304, 3584, 11008, 13568, 11776, 9984, 9984, 6144, 1792, -8448, -17664, -19200, -18688, -17920, -19200, -11776, 1024, 4352, -512, -4608, -1536, 768, -4608, -8192, -9728, -15616, -16640, -9984, -4352, -512, 2560, 2560, 1280, 4864, 8448, 14080, 15616, 13824, 9984, 10240, 10496, 10496, 10240, 7680, -1536, -6400, -1536, 5632, 11264, 12288, 10752, 10752, 9472, 5888, 2816, -10752, -18688, -19712, -19200, -18944, -19200, -9984, 1024, 2048, -1280, -3840, 256, -256, -7680, -8448, -9728, -17664, -16896, -10240, -3584, 768, 4096, 2048, 1280, 5376, 9984, 15360, 15104, 12288, 10240, 9728, 9984, 10752, 10752, 7680, -2048, -5120, 0, 6656, 12288, 13056, 12288, 11008, 7424, 5376, 256, -12032, -17920, -20480, -21248, -20480, -17920, -6400, 0, -512, -2304, -1536, 2304, -1792, -7424, -8448, -12544, -18432, -15104, -7424, -768, 768, 2816, 1536, 3584, 6912, 12032, 15616, 13824, 12032, 11008, 8704, 10752, 11520, 9984, 5376, -2560, -4352, 1024, 7424, 13568, 13824, 12032, 9984, 7424, 5632, -2816, -13568, -17920, -21248, -22016, -19712, -15616, -4864, -1536, -1792, -3072, -512, 2304, -3584, -7424, -8960, -15616, -17920, -13824, -6400, -2048, 512, 2816, 2048, 4352, 6912, 13824, 15360, 12800, 11520, 10752, 10240, 11008, 9984, 8960, 4608, -2304, -1792, 2048, 7168, 14080, 14336, 12544, 8192, 7680, 3840, -5376, -13568, -18176, -22528, -22272, -18944, -11520, -3072, -2816, -3840, -3584, 1536, 3072, -3072, -7680, -12288, -16896, -15360, -11264, -4608, -2048, 1280, 3328, 3840, 5376, 7936, 13056, 14592, 12288, 11008, 10752, 10240, 11008, 9472, 7424, 4096, -768, -256, 1792, 8960, 15360, 13824, 9728, 6656, 7424, 1280, -7680, -13824, -18432, -23808, -22272, -17664, -8704, -3584, -4864, -6400, -3072, 3328, 1536, -4352, -9472, -14336, -16896, -12544, -9728, -4608, -2816, 256, 4352, 6144, 6656, 8192, 12032, 13312, 12800, 12544, 11520, 9984, 10240, 8448, 8192, 3328, 1024, 768, 768, 12032, 16640, 13312, 7424, 6912, 5120, -1280, -8960, -14336, -19456, -23040, -20224, -16128, -6912, -4352, -6656, -6144, 0, 3072, -512, -4096, -8448, -15616, -15616, -10752, -8448, -4352, -4096, -1536, 5632, 7680, 6400, 7424, 11520, 12800, 11776, 13568, 10496, 9472, 9472, 8448, 7168, 4352, 3840, 512, 3840, 13824, 16384, 11776, 5376, 6400, 2304, -3072, -9984, -14848, -19712, -22272, -19200, -11776, -5376, -5888, -8704, -6144, 2304, 2304, -1792, -4352, -10240, -17152, -13568, -8448, -6912, -5632, -6656, -1024, 8704, 8704, 6400, 6912, 11776, 11264, 13312, 15104, 9472, 7680, 8960, 8192, 6656, 6400, 4096, 512, 7680, 15872, 14592, 8448, 4864, 4352, -1792, -6400, -11008, -14848, -20480, -20992, -16384, -9216, -6656, -6656, -8448, -4352, 2816, 1024, -2304, -4608, -11520, -15872, -11264, -7680, -6144, -7168, -7424, 1280, 9728, 8192, 6400, 7680, 12288, 10496, 13568, 14592, 8960, 7168, 6656, 6912, 7936, 7424, 3584, 3072, 12032, 16128, 12288, 8960, 6144, 1024, -4864, -8192, -11776, -14080, -19456, -19712, -14848, -7936, -7680, -8448, -9216, -2048, 3072, -1024, -2304, -5632, -13056, -14592, -7680, -5888, -6912, -10240, -7936, 4608, 9216, 7936, 7680, 8448, 9984, 9216, 14336, 13056, 8192, 6912, 5120, 6144, 9984, 7680, 4096, 7424, 14080, 13568, 11008, 9216, 5376, -1280, -7168, -9984, -11520, -14080, -18176, -17920, -12032, -6912, -8960, -9216, -6400, -512, 256, -1024, -1536, -5888, -12288, -12288, -6400, -4096, -6400, -11776, -5888, 6144, 7680, 8960, 8704, 7424, 8448, 9472, 13056, 10496, 7680, 5376, 3072, 6912, 12032, 8448, 4864, 9728, 13056, 11008, 9984, 9216, 3840, -4352, -8960, -8960, -10752, -14080, -17408, -15872, -11520, -8448, -10240, -9216, -4864, -1280, -1024, -768, -1536, -6144, -12032, -9728, -4352, -3328, -9472, -12288, -3328, 6656, 7680, 9216, 8192, 6912, 7424, 9216, 12288, 9728, 6912, 2304, 1280, 8704, 12032, 7936, 7680, 12544, 12032, 9216, 9728, 7168, 2816, -5376, -8192, -8192, -12032, -14336, -15360, -13824, -10240, -9984, -10752, -7936, -3072, -1280, -1792, -256, -1024, -5376, -9984, -7168, -2816, -3328, -11520, -10752, -512, 5888, 6400, 10752, 8448, 6656, 6656, 8448, 11264, 8704, 5120, 256, 1280, 9216, 12032, 9728, 10240, 12032, 9472, 8960, 9728, 5120, 256, -5888, -6656, -8960, -12544, -14336, -14080, -12288, -10240, -11776, -10752, -7168, -3072, -3072, -2560, 512, -1536, -6400, -8192, -6400, -3328, -5632, -11008, -7680, 1280, 4608, 6144, 11520, 8960, 7424, 5376, 6912, 9984, 7168, 4096, 512, 2304, 9984, 10240, 11264, 14080, 11520, 6400, 7936, 8704, 3840, -256, -4608, -6400, -10496, -12544, -12800, -13312, -11776, -10752, -12288, -10240, -5888, -2304, -4608, -3328, 2304, -256, -6144, -6912, -5632, -3584, -7680, -10496, -6656, 2048, 3840, 6400, 10240, 9216, 6656, 3840, 6656, 8960, 5376, 2816, 512, 4352, 11264, 9472, 13824, 16128, 9472, 4096, 7936, 6912, 3072, -768, -3072, -6144, -11520, -12032, -11776, -11520, -10240, -11264, -14080, -10240, -4352, -3072, -5632, -1792, 4864, -512, -5632, -6144, -3840, -4352, -9216, -9216, -2816, 4096, 2560, 4352, 9728, 11008, 6400, 3840, 6400, 6656, 3584, 1792, 512, 6400, 9984, 9728, 16128, 17152, 7680, 4096, 6400, 4608, 3584, -1280, -2304, -6656, -11008, -11520, -12032, -10752, -9728, -13312, -14592, -8960, -3584, -5632, -6912, 0, 5888, -1280, -6144, -5632, -3072, -5376, -10240, -7936, 256, 4864, 1536, 2816, 8960, 11264, 5632, 4608, 7168, 3584, 1024, 1024, 2816, 8192, 8704, 9728, 17920, 17408, 5632, 4608, 4352, 3840, 4352, 0, -2560, -7936, -11520, -11008, -10752, -8704, -9216, -15872, -15616, -6400, -2816, -7168, -7424, 768, 6400, -768, -6656, -3840, -3072, -7168, -8704, -5376, 2304, 4352, 512, 2560, 7936, 10240, 6144, 5888, 7168, 1280, -768, 1536, 4864, 8960, 8448, 10752, 18432, 15104, 5632, 5632, 3072, 4352, 4352, 512, -2816, -7936, -10240, -10240, -9216, -7168, -10240, -16896, -14592, -4608, -3840, -8192, -5632, 2304, 5632, -768, -5888, -2048, -3072, -7936, -8192, -3072, 4608, 3840, -256, 2304, 6400, 9216, 6656, 6912, 5120, -1792, -1280, 3072, 5888, 7424, 8448, 11520, 17920, 12288, 6400, 5120, 2048, 4096, 2304, 1024, -2816, -8448, -9984, -9472, -8704, -7680, -11776, -16640, -12800, -5888, -5632, -7680, -4864, 3328, 5632, -1024, -5376, -1536, -3840, -8192, -7168, -768, 4608, 2304, 0, 2304, 5376, 7680, 7168, 7680, 3072, -3584, -256, 4352, 4864, 6912, 10496, 13056, 16128, 8960, 7168, 5632, 3072, 2560, 1536, 2304, -3584, -7936, -9216, -7936, -6912, -9728, -12544, -15872, -12288, -7424, -6400, -6912, -3328, 3328, 3328, -768, -2304, -2304, -5376, -7680, -5120, 1024, 3072, 1024, 1280, 3072, 4864, 6912, 8448, 7424, 1536, -3072, 512, 5376, 4352, 7936, 11520, 13824, 14080, 7936, 7936, 6400, 3584, 768, 1280, 2816, -3584, -6912, -8448, -6144, -6912, -10496, -12544, -16128, -13568, -9472, -6656, -5632, -1792, 2816, 2048, 0, -768, -3584, -4864, -6912, -3584, 2048, 1280, 512, 2304, 3072, 5120, 6400, 7936, 4608, 0, -1536, 2048, 5120, 3584, 6912, 11008, 15104, 12288, 6144, 7168, 6400, 3584, 512, 2048, 1536, -3840, -6656, -7680, -4096, -7168, -11264, -13568, -15616, -14848, -9472, -6912, -5376, -1024, 2048, 768, 256, -512, -4608, -5376, -6144, -2816, 768, -1024, 768, 3840, 4352, 5120, 5632, 7424, 3840, 768, -512, 2048, 4352, 4608, 7680, 11776, 14336, 10240, 5376, 7424, 6656, 3584, -256, 1280, 1024, -1536, -5632, -7424, -3328, -6912, -11776, -13056, -15872, -15616, -9472, -7168, -3584, 512, 1792, 0, 1280, -512, -4096, -4352, -4864, -2560, -1792, -2304, 2816, 5120, 5632, 4608, 4352, 6400, 4864, 1024, -256, 2560, 4864, 6400, 8192, 11264, 13568, 9216, 4864, 7424, 6144, 2560, -1024, 1280, 1024, -512, -5632, -6144, -3328, -7936, -12288, -14336, -16128, -15360, -10240, -7936, -2816, 2048, 2048, 512, 2048, -1536, -5120, -4352, -3072, -2560, -5120, -3072, 3584, 7680, 6656, 2560, 3584, 6144, 6144, -256, -1792, 3072, 6400, 6912, 7680, 10240, 13312, 8704, 4352, 7168, 6144, 1792, -2304, 256, 2048, 768, -5120, -5120, -4096, -8448, -13568, -15104, -15872, -15616, -12032, -7424, -1280, 3840, 1280, 256, 2304, -2048, -5120, -3584, -1280, -3072, -7680, -2816, 5120, 9472, 6400, 2560, 4864, 6400, 4864, -1280, -512, 4608, 7168, 6656, 7424, 10496, 12544, 7936, 5120, 7680, 6144, 256, -2048, 1024, 2560, 768, -4352, -3072, -4608, -10240, -14592, -15616, -15872, -15104, -12288, -5888, 0, 4608, 1280, 1280, 3072, -2304, -4864, -2304, -512, -5120, -9472, -1792, 6400, 9984, 5888, 2816, 6400, 6656, 2560, -2560, 1280, 5888, 6144, 6656, 7680, 10240, 10752, 6912, 5888, 7936, 4608, -1792, -1280, 512, 1792, -256, -2560, -2560, -5632, -11520, -15104, -16128, -15872, -14848, -11520, -5376, -256, 4352, 2560, 3328, 1792, -4608, -5376, -1280, -768, -6912, -9728, -1792, 6656, 9728, 5376, 5120, 7936, 5888, 0, -2304, 3840, 6400, 5376, 7168, 8448, 8960, 8960, 7424, 7168, 7936, 3072, -1280, 0, 0, 1024, 0, -768, -3584, -6912, -12288, -14592, -17664, -16896, -15616, -10240, -4864, 256, 4096, 3328, 4096, -768, -4608, -4352, -1024, -2304, -7680, -8448, -256, 6144, 8960, 7168, 8704, 7936, 4096, -1024, -512, 5632, 7424, 5120, 6912, 9728, 8448, 7680, 7680, 7936, 8448, 2304, 256, -768, -1792, 512, 1536, -256, -5632, -7936, -12800, -15616, -18944, -17152, -13312, -8704, -6400, 256, 4864, 5376, 3584, -2048, -4608, -3584, -2560, -3584, -6912, -6656, -1280, 5376, 8960, 9728, 10240, 7936, 3072, -256, 1280, 5632, 7424, 4864, 7936, 10496, 7168, 7680, 7168, 7936, 7168, 3072, 1792, -3328, -2816, -512, 3328, -1280, -6656, -8192, -13312, -17152, -20480, -16640, -11776, -8704, -6656, 512, 3840, 6400, 2304, -2048, -3584, -4096, -2560, -4608, -6400, -6400, -2304, 5120, 9472, 11776, 8960, 6656, 2560, 1792, 2048, 4608, 6912, 4608, 7936, 9984, 6400, 7424, 7424, 8704, 6656, 5120, 512, -4608, -2560, -1280, 3072, -2304, -5632, -7936, -12288, -18944, -20224, -16896, -10752, -8704, -5632, -256, 3584, 6400, 3328, -1536, -4864, -4096, -2048, -4864, -5632, -5376, -1280, 5376, 10496, 13056, 8192, 6400, 3584, 4864, 3328, 3584, 5376, 5376, 8192, 8704, 6656, 6656, 7680, 8192, 6400, 6400, -768, -4864, -3328, -512, 2048, -3072, -6144, -8192, -11776, -19200, -20224, -17152, -11008, -8448, -4608, -1792, 3072, 6400, 4608, 0, -5888, -3328, -1792, -5888, -4608, -3840, -1024, 5376, 12288, 13056, 6912, 6912, 5888, 5632, 3072, 3072, 4864, 5632, 7168, 7168, 7168, 7168, 7936, 7168, 5888, 7168, -768, -5120, -5632, -1280, 0, -3584, -5888, -7168, -12800, -19968, -20736, -16128, -11264, -8704, -4864, -3584, 2560, 6400, 4608, -1536, -4864, -1280, -2816, -7680, -4352, -2048, 512, 5376, 13824, 11520, 6400, 7168, 8448, 6400, 2304, 3072, 5376, 6656, 5888, 6144, 8448, 9472, 8960, 5120, 5888, 8192, -256, -5376, -6400, -3072, -2816, -3072, -4864, -6912, -13568, -19968, -20224, -14080, -10752, -7936, -6656, -4608, 3072, 6144, 3328, -2304, -3072, 0, -5120, -8448, -3328, 256, 1536, 6656, 14080, 9728, 6400, 8448, 11520, 6656, 1792, 3328, 5376, 6656, 4096, 4608, 9728, 11264, 8448, 3584, 6400, 7680, 1024, -6144, -8192, -5376, -4608, -4864, -4864, -6400, -13824, -20224, -19968, -13568, -11008, -7424, -7168, -5120, 1536, 5120, 3072, -768, 0, -768, -8960, -7168, 256, 2304, 2048, 6400, 11776, 8704, 7680, 9472, 11264, 4864, 3328, 5120, 4352, 5120, 3072, 4608, 12544, 12544, 5888, 3328, 7168, 8448, 768, -8704, -9472, -7168, -7680, -5376, -2560, -6656, -14592, -19712, -18944, -13312, -10240, -6400, -8192, -5632, 768, 4352, 3072, 768, 2048, -3840, -10240, -4608, 2560, 2560, 1024, 8192, 9984, 6912, 9728, 12288, 9984, 2816, 4608, 7168, 4352, 3840, 1280, 5888, 15616, 11776, 5376, 5888, 8960, 6656, -768, -7936, -9472, -9984, -9728, -5888, -768, -7424, -15360, -18944, -17408, -14848, -9472, -6912, -8960, -5632, -1792, 3840, 5888, 3584, 2048, -6912, -10496, -1536, 4864, 3584, 2304, 8960, 7936, 7936, 12288, 13824, 8960, 2816, 6912, 6656, 1024, 1792, 2816, 7936, 13824, 9728, 6400, 8704, 8960, 5120, -2560, 4864, 768, -2048, -11520, 16384, -3840, -10496, 5888, 10240, -14848, 5632, 7424, -6912, -7168, 10752, -9216, 5376, -3072, -4864, 9984, -3584, 768, -4608, 8192, -6912, 4608, -2048, -11008, 11008, 6400, -13312, 1536, 4864, 3328, -1792, -12800, 14080, 1280, -11776, -5632, 24064, -13568, -8448, 8960, 6912, -11520, -512, 5120, 4864, -7680, -5888, 12032, 2048, -14848, 1280, 19456, -17152, -5632, 10752, 7680, -13824, 2048, 5888, 2816, -13056, 768, 12032, -8448, -1792, 1280, 6912, -8448, 8704, -8960, 4352, 1024, -6656, 1280, 4352, -7680, 8448, 1280, -7424, -1280, 11264, -4608, -12800, 15360, -8448, 2560, -1280, 2560, -1792, 256, -1280, 4864, -9216, 768, 9472, -4352, -13056, 13312, 9472, -16384, 2304, 1024, 9472, -11264, -3328, 6400, 11520, -19200, -2304, 20224, -8704, -14592, 13568, 6144, -15104, 4608, 5632, -768, -6144, 2560, -512, 4608, -13568, 7424, 8960, -5120, -11008, 9472, 4608, -4352, -7936, 2048, 11520, -12544, 2048, 2816, 2304, -5888, 7680, -6144, -5632, 7424, 3584, -11008, 6912, 3328, -5632, -256, 512, 5632, -9472, 1280, -1280, 9728, -11008, 1536, 9216, -5376, -5120, 5120, 0, -1280, -6912, 6912, 5376, -13568, 1024, 13312, -512, -21504, 17920, 1280, -7424, -4864, 9216, -1536, -2048, -3072, 768, 8960, -8192, -6400, 12288, 1536, -15360, 12544, 1024, -6912, -3328, 7936, -3840, -2304, -1024, 7936, -3328, -6400, 7424, 3072, -8704, -1536, 7680, -10496, 9216, -5888, 1536, 7936, -7680, 0, 4352, -11520, 12032, -1280, -12032, 4864, 7168, -2048, -7680, 6912, -1536, 3840, -13824, 8704, 5376, -6912, -2304, 6400, 768, -11520, 6656, 6912, -13312, 5632, 5120, -7424, 8704, -11776, 5632, 10240, -17664, -6912, 27648, -12544, -13824, 17664, -2816, -768, -4608, 768, 3840, -3072, -5888, 7424, -2048, 1024, -5888, 12800, -9728, -2048, 8448, -8192, -512, 6656, -6912, 3072, 3328, -9984, 14336, -7936, -5632, 7168, 512, -9984, 13824, -5120, -9216, 13056, -1536, -8704, 3840, 512, 256, 512, -9216, 10752, 512, -2560, -9984, 16384, -9216, -4096, 6144, 256, -256, -4608, -2560, 13824, -6912, -13824, 20480, -4608, -15616, 13056, 6912, -19456, 16384, -7680, -256, 2304, -4864, 6144, 3328, -7424, -3328, 12544, -4608, -11776, 11008, 1536, -12032, 10752, -7168, 3584, 4608, -4608, 512, 3584, -9984, 6400, 4096, -14848, 8448, 7424, -12544, 4096, 10496, -15872, 11008, -4352, -4352, 6400, -2560, -7168, 10496, -1280, -7680, 6912, 3584, -13568, 6912, 8960, -16128, 4096, 7680, 0, -7680, -2560, 5632, 7936, -14592, 0, 17408, -15104, 512, 9472, -7680, 1536, -768, -4864, 8960, -7424, 256, 5120, 5632, -17408, 8448, 9984, -18176, 5376, 6912, -5632, -256, 768, 0, 4608, -4096, -3328, 4352, 1024, -9472, 11264, -3840, -6656, 12288, -7424, -2816, 8704, -6400, -1024, 6400, -12288, 11008, 1024, -12544, 7168, 10752, -18432, 1792, 15104, -9216, -7168, 11520, -2304, -7168, 6400, -4864, 5888, -2304, -10240, 12032, 4608, -21760, 19968, -512, -13568, 9984, -4352, 512, 3584, -9216, 2560, 16128, -19968, 4352, 15104, -16896, -2048, 13824, -12544, 3584, 256, 1280, 512, -4608, 4096, -3072, 7680, -14848, 5632, 13568, -21248, 4352, 20224, -21504, 4864, 4352, -8704, 11264, -8448, -6912, 20992, -15872, -4864, 23296, -23808, 5632, 12544, -13056, -6400, 12288, -3072, -1536, 256, -512, -256, 5632, -8192, -256, 15104, -19968, 3072, 14848, -12544, -6656, 17920, -10240, -2048, 4096, -2048, 3072, 2560, -16640, 18944, -256, -24832, 23040, 0, -14336, 5888, 6400, -4352, 2816, -5888, 3584, 2304, -6144, -7936, 19712, -10496, -12288, 24320, -9728, -11776, 15104, -256, -14592, 12544, -8448, 4864, 4608, -11776, 8704, 7936, -20224, 12032, 2816, -9728, 2560, 4864, -3584, -2560, 6656, -7424, 7168, -4352, -6912, 12288, -3840, -13056, 19968, -3584, -18688, 16384, 3072, -14080, 7424, 768, -6144, 13312, -16640, 6656, 12800, -19200, -1280, 20736, -19456, 0, 10752, -1536, -6656, 2560, 4608, -3584, 1024, -6144, 8448, 512, -17664, 15616, 11008, -25856, 10240, 13824, -18688, 5632, 4608, -10496, 11264, -4864, -11008, 24064, -17664, -3328, 16640, -6656, -11776, 8960, 6144, -8704, -512, 5888, -3328, 1536, -4864, 1024, 9728, -14336, 3584, 10240, -9472, -4864, 16896, -14592, -2304, 12800, -12032, 5376, 1536, -7936, 14080, -8704, -12800, 25088, -11264, -12032, 11264, 7168, -13056, 1536, 7936, -768, -8704, 2048, 2816, 1536, -4608, -6912, 19968, -12288, -7168, 14080, -512, -15360, 14592, -9472, 3584, 3840, -12288, 12544, 5632, -24576, 18944, 5888, -21248, 9216, 4608, -4352, -6400, 10496, -3072, -1024, -512, 256, 2304, -3584, -4608, 9216, 3072, -19712, 13824, 8192, -17152, 5120, 9728, -17152, 15616, -13568, 8192, 5376, -15360, 6912, 10496, -18944, 6912, 8448, -7680, -1536, 5632, -256, -7680, 5120, 256, -1024, -5632, 2304, 2048, 9472, -16640, 4608, 15616, -17664, -768, 9472, -4864, -3840, 3840, -4096, 14592, -19968, 5120, 16896, -17152, -6912, 19456, -9472, -4096, 2816, 2816, -1280, -4608, 2560, 4096, -1280, -9728, 9216, 2304, -5120, -8192, 18688, -10496, -9216, 15872, -8448, -2304, 8704, -10496, 8960, -1792, -10240, 16640, -8960, -6656, 8448, 512, -11008, 10752, -1024, -2304, 1280, -2816, 4864, -2560, -4096, 2816, 4096, -7168, -2304, 10496, 512, -17920, 17152, -768, -14080, 5888, 8448, -6656, 1536, -7424, 11008, 4096, -21760, 13056, 7168, -13824, 1792, 6912, -2304, 512, -4608, 6912, -1024, -10752, 7936, 2560, -4864, -2304, 4608, 2048, -6144, -768, 11520, -14592, 6400, 0, -1792, 3840, -7168, 2560, 8448, -11776, -1536, 13312, -9216, -3840, 11776, -7424, -1024, 3072, -3584, 8704, -14592, 4096, 10240, -10496, 768, 4096, 2048, -8192, 4096, 3840, -4352, -6912, 12032, -7680, -256, 3584, -1280, 4096, -4352, -8448, 17920, -11264, -10752, 21504, -8704, -6912, 4608, 3840, 768, -5120, -5632, 14080, -8960, -5632, 7936, 2560, -2816, -6912, 6912, 3328, -7168, -2560, 10496, -5376, -768, -5632, 10496, -5376, -3328, 1536, 8704, -17408, 11776, 6400, -16640, 12800, -5376, -256, 2560, -8448, 8704, 256, -11008, 14848, -8704, -512, 3328, 2048, -6400, 0, -512, 8704, -7424, -6656, 11520, -3072, 1024, -8704, 8192, 3840, -13824, 4352, 13568, -19456, 10496, 1024, -4352, 3328, -6656, 3328, 7936, -12032, 256, 13312, -13568, 2816, 2048, 3584, -7936, -1792, 4864, 7680, -15360, 6656, 6912, -5632, -2560, 0, 4608, -3328, -6144, 13312, -9728, -4352, 17408, -15360, 6656, -2304, -6400, 10496, -7424, -2048, 10240, -6400, -2304, 6656, -7168, 3840, -2304, -768, 2816, -5376, -256, 11264, -12032, 4864, 0, 768, -3584, -3072, 9728, -5632, -5888, 9472, -2560, -3328, 2304, -1536, 5376, -3584, -9984, 15616, -1024, -17408, 15360, 1536, -11008, 7168, -3584, 5376, -5632, -3328, 9216, -1792, -10240, 11776, -3584, -1280, -4608, 5120, 5632, -12544, 5632, 2560, -4608, 5376, -7680, 2304, 8704, -13824, 4864, 5632, -8704, 6912, 1792, -11520, 7680, 0, -5120, 5888, -5888, 7424, -2560, -5376, 6400, 768, -5888, -256, 1280, 4096, -8448, 3584, 6400, -5376, -2816, 4096, 768, -5632, 1280, 1536, 8192, -18688, 6912, 15872, -18432, 1280, 6656, -5376, 7680, -9472, 1024, 10240, -11520, 1280, 4608, -4608, -256, 3072, -768, 0, -4608, 7168, -2048, -3584, 2816, -2816, 3328, -3840, -768, 6912, -4352, -7680, 16640, -11520, -1280, 7168, -6400, 256, 5120, -9216, 9728, -2816, -5120, 8960, -5888, -5120, 6912, 2816, -10752, 3328, 4352, 256, -6400, 5120, 2560, -8448, 2560, 1536, -1792, 2304, -6656, 10240, -768, -16128, 18944, -7680, -2816, 2560, -2560, 1280, 4352, -12032, 13568, -2560, -12032, 7424, 7936, -11520, 1024, 4096, 3584, -3840, -8448, 10240, -2816, -768, -2560, 512, 4608, -5120, 2304, 5632, -11264, 4864, 5120, -10752, 6400, -1280, -2816, 6400, -6400, -768, 12032, -16128, 7168, 5120, -10752, 1792, 9984, -10496, 512, 3328, 2560, -6144, -2048, 10496, -6656, -256, -3328, 2304, 10752, -15360, 0, 15616, -13824, -1024, 4864, -1536, 2816, -4864, -3328, 13312, -9472, -6656, 16896, -9728, -7680, 12544, -4608, -2816, 1280, 1792, 2560, -7680, 1024, 4352, 512, -3072, -3840, 9728, -4864, -5120, 7680, -4096, -5888, 9728, -3328, -4096, 7424, -5632, 6656, -4352, -8960, 15872, -7680, -8960, 13056, -4096, -6912, 10240, -4096, 768, -2048, -1024, 2304, 1024, -6656, 2816, 5120, -2816, -9728, 14336, -4864, -7424, 7936, 1792, -9984, 4352, 2560, 1536, -2048, -10496, 11520, 6656, -20224, 9216, 10752, -14848, 5376, 1536, -2560, 1792, -4864, 4352, -256, -3840, -3072, 13568, -5632, -8192, 6144, 6400, -15104, 6144, 5632, -9216, 2560, 4608, -6912, 11264, -11520, 0, 10752, -11520, -512, 7680, -6912, 3072, 5888, -9728, 3328, 1280, 1024, -1024, -5120, 256, 11008, -6912, -9216, 11008, 3584, -13056, 3072, 10240, -10496, 1280, 4608, -2816, -256, -1280, -2816, 13568, -14336, -7424, 23296, -10496, -11520, 14592, -1792, -4608, -768, -1024, 7424, -5120, -4864, 5120, 6656, -14592, 7936, 4352, -5632, -3328, 7168, -7936, 768, 9216, -8448, 2304, 4352, -9984, 10752, -2304, -13824, 14848, 1536, -17664, 11264, 7680, -12800, 6144, 768, -4352, 2304, -5120, 4352, 2048, -5888, 256, 11776, -12800, 256, 6912, 256, -12544, 9472, 1280, -4352, 1024, -1280, 1792, 4608, -14080, 9984, 9216, -21760, 9472, 12288, -16128, 1280, 6912, -3328, -1536, -1024, 1280, 6144, -6656, -3072, 10752, -6400, -8704, 8448, 5120, -8448, -3328, 7424, -512, 1792, -8704, 3072, 9472, -12800, 256, 12032, -11776, -256, 14336, -13824, -4608, 15104, -8960, -1536, 3072, -4096, 5120, -512, -6912, 11008, -3072, -8704, 5632, 6400, -10496, -1792, 11008, -5120, -4608, 4864, -256, 256, -1536, -5120, 13824, -14080, -3072, 17152, -6144, -14336, 14336, -2048, -3072, -1792, -768, 4096, 5120, -12288, 5120, 8192, -11776, 2048, 5888, -4352, -9728, 13824, 256, -8704, 512, 7680, -256, -5376, -4608, 9728, -3584, -8960, 10496, 768, -9216, 4864, 5632, -11520, 10240, -8192, 3072, 3072, -6656, 512, 8960, -13824, 8704, 3584, -6400, -7680, 12032, 2560, -13568, 6144, 3328, -1024, -4608, 768, 1280, 6912, -15616, 9728, 3840, -9984, 1536, 10240, -9216, 0, 512, -1536, 7168, -10240, 1792, 11776, -9472, -7680, 15104, -5376, -7424, 1536, 12288, -14080, 3072, 7680, -5376, -1536, 1280, -512, 256, -3584, -1792, 11776, -10496, -1024, 8960, -2048, -8448, 7424, -5120, 6656, -7936, -2560, 16128, -11776, -1024, 3072, 1792, -2816, -3840, 6656, -3584, -5632, 13824, -12032, 3072, 2304, -256, -2048, -1792, -2048, 10496, -3072, -15360, 19712, -5376, -6656, 2816, 3328, 256, -6656, -2304, 15104, -11520, -4096, 9728, -768, -6912, -256, 7168, -2048, -4864, 2816, 5120, -10496, 8704, -5888, 5632, -5120, -2304, 1536, 13056, -20224, 10240, 4608, -10240, 5888, -1280, -4864, 3328, 512, 768, -1024, -8960, 18176, -9984, 1280, -7680, 8448, 1536, -7424, -768, 9728, -7424, -1280, 4608, -2304, -1024, -2816, 4096, 3840, -8192, -3584, 19712, -21248, 7680, 2560, -2560, -4864, 5120, 3840, -4352, -4864, 7424, 1792, -8192, 1536, -256, 3584, -3584, -1536, 1280, 9216, -14848, 12032, -4608, -3584, 1024, 2048, 2048, -6144, -3840, 15360, -9216, -5120, 11008, -8192, 768, -512, 256, 2304, -1280, -2048, 7680, -8448, 1536, 1536, 512, -3072, -2816, 6144, 256, -5632, 2304, 8704, -15616, 6400, 2816, -1280, -4608, -256, 9728, -4864, -8448, 12544, -4864, -5376, 4608, -1792, 256, 1280, -1024, -768, 3328, -7680, 6400, -1280, -3072, 512, 2048, 4352, -9472, 0, 12800, -9728, -6656, 10240, -3840, 1792, -6144, 7936, -2816, -2048, 1536, -1536, -768, 256, 2304, -2048, 1536, -5120, 6400, 0, -5376, 1792, 5632, -12288, 7424, -1024, 2560, -5632, 1792, 5632, -2304, -8704, 11520, -3840, -7936, 7680, -512, 0, -7680, 11776, -4608, -1536, -4352, 7936, -1536, -1792, -5376, 2048, 11520, -12032, -1792, 7936, -4352, -2816, 6400, -5120, 4352, -7680, 12032, -9728, -512, 1280, 4096, -9216, 6144, -512, 768, -1792, 1536, 2560, -5888, 1280, -2816, 8960, -10752, 4352, 0, 5376, -8960, 2816, 4096, -4608, -3840, 9216, -6144, -768, 2304, 1280, 3328, -12544, 9216, -2816, -512, -3584, 9472, -8192, 3328, -256, 0, -512, -512, -2048, 4352, -2816, -5376, 7680, -256, -256, -10496, 18432, -16640, 3584, 3584, 3072, -10496, 5376, 1024, 3840, -8192, -256, 6400, -2304, -4608, 768, 7424, -9728, 8960, -5632, 3584, -5120, 4096, -1536, -1536, -3328, 7424, -1024, -4352, 1792, 3584, -1536, -9728, 13824, -8192, 768, -4096, 9216, -9984, 10752, -10240, 9216, -5632, -3328, 4352, 3584, -9216, 3072, 5888, -6400, 1536, -6400, 13568, -8448, -3072, 1280, 9472, -11776, 1536, 5120, 2304, -13568, 13312, -4096, -5632, 6144, -2304, 2560, -4352, 3072, -5120, 12288, -18688, 10240, 4608, -7680, -5120, 13312, -8704, 2816, -1536, 0, 256, -3840, 6144, -4096, 4096, -7680, 11264, -6912, -2560, 0, 8704, -13312, 6144, 768, 512, -1536, 3072, -6400, 8960, -9728, -3584, 18432, -18688, 1792, 7936, 3840, -12800, 5120, 3072, -1280, -6400, 5888, 768, -2560, -2304, 3840, 2304, -10496, 7168, 1536, -1280, -9216, 11264, -3328, 2560, -4864, 512, 3584, -2560, -7424, 14336, -6912, -8960, 14848, -4864, -6912, 4352, 4096, -7680, 2560, -1792, 3840, -3072, -768, 2816, 4608, -7680, -3328, 9728, -4352, -4096, 768, 8192, -9472, 5888, -6144, 7680, -3072, -6656, 10240, -3584, -13312, 15104, 3072, -14080, 4096, 8960, -5120, -7680, 9984, -6144, 5376, -6656, 3072, 3328, -2560, -4864, 5888, 512, -8960, 4352, 8448, -7680, -4352, 9984, -3840, 3072, -13568, 12800, -3328, -6400, 512, 12800, -10752, -256, 6400, -5632, 1536, -1280, 768, -1024, 512, -4608, 9984, -6400, -768, 256, 7424, -14592, 5632, 6656, -5632, -4608, 8704, -2560, -2560, -2816, 3328, 7936, -19712, 11776, 5888, -5632, -8960, 15616, -6144, -3328, 1792, -768, 0, 1024, -6144, 6912, 3072, -12800, 8960, 3328, -4864, -9472, 17664, -11776, -1024, 3328, 1280, -2048, 1536, -6400, 10240, -6656, -3328, 9728, -3072, -7168, 5376, 5632, -14592, 10240, -3840, 2816, -4864, 1024, 4864, 2304, -9216, 768, 10752, -8960, -7680, 11776, 0, -12800, 15104, -6656, 2304, -4096, 3072, -2560, 2560, -8448, 11264, -2048, -7424, 2048, 10752, -11008, -1536, 6656, -4864, 3584, -7680, 8704, 1024, -5376, -4352, 12544, -7936, -6144, 8704, 3584, -13568, 8192, 3328, -6656, 3072, -5632, 6656, -768, -5632, -2816, 16896, -15104, 0, 11008, -6912, -5888, 10752, -8192, 1792, -1792, 2816, 2304, -4864, -256, 3840, 4096, -14848, 11008, 256, -8192, 2816, 9216, -11264, 4608, 0, 1024, -1024, -1792, -5632, 12800, -5632, -11264, 17152, -3584, -11008, 9472, 512, -8192, 3840, 1792, 2048, -5632, -256, 3584, 4864, -11008, 0, 10240, -7680, -3584, 7168, 2560, -8192, 2816, 256, 5376, -8448, -2304, 7936, 3840, -18432, 15616, 1024, -10240, 5376, 3584, -9472, 5632, 1024, -1024, -2304, 1280, -2048, 5888, -4096, -5632, 8960, -6144, 0, 3072, 768, -4352, 3840, 512, -2560, -1536, -2048, 5376, 1792, -14848, 10240, 11008, -19200, 6400, 7168, -6400, -4608, 7168, -3840, 1536, -1280, -1024, 5632, -1280, -9984, 9472, 256, -7680, 3072, 5888, -6912, -2048, 8704, -5632, 0, -3072, 3840, 2560, -7168, 512, 11520, -11520, -2304, 9216, -5632, -1792, 3328, -1792, 1536, 512, -4608, 4352, 2560, -8704, 2304, 4608, -5632, -256, 5632, -2304, -4352, 5888, -256, -5632, 5376, -5120, 5120, -4352, -1536, 9728, -8448, -4608, 14080, -8192, -5376, 6656, -1280, -2304, 1280, -2048, 4096, 2304, -12032, 9216, 2816, -9216, -768, 9728, -1792, -12288, 11264, -512, -2816, 512, -4096, 3840, 2816, -9216, 8448, -768, -4608, 2304, 4864, -11776, 6656, -256, -2816, 5120, -6144, 3072, 4096, -4096, -4352, 9472, -8192, -1536, 3328, 3328, -8448, 6400, 3584, -6912, 2048, 256, -4608, 5632, -1280, -3840, 8192, -11776, 9472, -512, -4864, -3328, 9728, -8192, 2048, 512, -1024, 3840, -3072, -1024, 4864, -6400, -2560, 9472, -4864, -2816, -2560, 14592, -13824, 4864, -4352, 4608, 768, -4608, -2304, 6912, -1536, -9216, 14592, -5888, -5376, 3584, 2816, -5888, 8192, -13568, 14336, -6144, -1280, -768, 2816, -4096, 4096, -1792, -5120, 4352, 2816, -768, -7936, 10752, -8448, 3584, -1536, -512, -2048, 9984, -14336, 12288, -5376, -5120, 7680, -2048, -5120, 3072, 3840, -8192, 10496, -9216, 7424, -6400, 3584, -5632, 5632, -4864, 2304, 1024, 2560, -7936, 4352, 2816, -3584, -256, -1792, 4352, -4096, 1536, -4608, 16384, -22528, 12032, 1536, -5120, -1280, 5632, -3328, 4608, -7168, 512, 6400, -4864, -2560, -768, 7424, -5888, 2816, -5632, 9984, -6400, 3328, -6912, 5120, -512, -4608, 3840, -768, 768, 2304, -4352, -2048, 9728, -14592, 8960, 256, -2304, -6144, 11008, -8192, 7680, -7680, -768, 4864, -768, -5376, 3072, 3584, -3072, 512, -1280, 2816, -9472, 9472, -768, -3328, -1024, 2560, 2816, -1024, -9728, 10496, -2304, -6912, 9472, -9472, 4096, 4352, -1792, -3840, 5632, -10240, 8448, -512, -4096, 1024, 768, 2048, -1024, -5120, 5376, -768, -2560, 2048, -6656, 9472, -5376, 2048, 0, -768, -768, 0, -2048, 5120, -3840, -8192, 13824, -2560, -6656, 4352, -3072, 2560, 6144, -18176, 13056, 768, -5376, 2304, -768, 4352, -5632, 512, 3840, -5376, -2816, 9984, -6400, 2816, -6912, 7168, 768, -2816, -6656, 11520, -11008, 6144, 1792, -9984, 12032, -6144, -3840, 6912, -3328, -3840, 8960, -6912, 3840, -4352, 2304, 0, -1792, 0, 1024, -2304, 3328, -768, -4096, 7168, -7424, 5376, -5888, 2816, -1024, 2560, -7680, 16384, -16128, 3328, 7168, -7680, 4096, -3328, 0, 6400, -9984, -512, 13568, -10240, 1280, -4864, 10496, -6400, -1536, -768, 9472, -10240, 1536, 2048, 0, 1536, -8704, 8192, 1024, -6912, 3328, 3840, -8704, 13312, -16128, 10240, -1280, -5632, 1280, 6144, -8192, 5632, 2816, -6656, 3584, -5632, 6656, -5376, 2560, -2048, 1280, -2560, 11776, -16896, 11264, -5120, 3584, -1792, -6912, 5888, 7680, -13568, 6144, 2560, -9472, 11264, -10240, 5376, -2816, 768, 1536, 5120, -12032, 6912, 1280, -512, -4608, -1024, 7424, -3328, -5120, 6912, 2304, -12032, 11008, -9472, 14080, -15872, 3584, 8448, -3328, -7168, 6144, -2304, 5888, -8960, -1024, 8192, -3584, -3328, 7168, -2560, -7680, 11776, -11008, 11008, -11776, 3328, 3328, -2560, 1792, -768, -5120, 9984, -4864, -4864, 3584, -3840, 9984, -7936, -2560, 6400, 512, -8704, 10496, -8960, 3840, -1024, -768, 5632, -4608, -6912, 11776, -256, -9216, 2560, -1024, 10752, -14336, 3328, 7936, -4864, -4608, 7168, -7424, 6912, -8192, 6144, 2560, -11264, 5120, 8192, -8192, -4352, 8192, -3328, 3328, -8960, 5120, 8192, -13568, 5120, 2304, -4096, 4096, -9216, 9984, -768, -8448, 11008, -6656, 512, 512, 512, -4352, 6144, -5632, 3584, -768, -3072, 7936, -7168, -2048, 6656, -7424, 4864, -1024, -3840, 8448, -9984, 5632, 4096, -9472, 1536, 4352, -1024, -3328, -3072, 9472, 2304, -16640, 8704, 6400, -6912, -2304, 1792, 1280, 2560, -9216, 11520, -2816, -10496, 10752, -1536, -5376, 1792, -1280, 7936, -1280, -14592, 15872, -3072, -3840, -4096, 5888, 1024, -6144, 3072, 6656, -8960, -2816, 11264, -6400, -2048, -256, -1024, 7168, -2816, -9472, 15616, -12288, 5888, -256, -7680, 7424, -2048, -512, 1536, -4864, 4608, 3840, -10496, 7680, -1024, -2816, -2816, 7168, -2560, -1024, -9472, 20736, -11520, -11008, 15616, -4864, 256, -2816, 0, 7936, -7680, -6400, 17408, -11008, -2816, 0, 6912, -256, -8448, -1792, 19712, -13824, -7680, 11264, -1536, -1280, -3584, 4352, -1536, -2560, 1536, 7680, -17408, 12800, -4096, 1280, 1280, -7680, 7680, 6656, -17664, 9216, 2048, -8704, 9472, -7168, 2816, 0, -256, 2304, 256, -10496, 13568, -5632, -6144, 5888, 1280, -2304, -2816, 3072, 7168, -15616, 7168, 9216, -17408, 13056, -8448, 6400, -1536, -6656, 1792, 13568, -16640, 512, 12032, -6400, -5888, 4352, 5120, -1024, -13056, 9728, 7424, -17152, 7936, 256, 5632, -8960, -2048, 10240, -2304, -11776, 12032, -3328, -2048, 1280, -3840, 9472, -6912, -5120, 11520, -4096, -11520, 15104, -9472, 4864, -1536, 512, 256, -2816, -768, 8704, -10752, 0, 8448, -7680, 4096, -3328, 3328, 512, -5888, 4608, -1280, -6656, 11008, -6144, 3840, -6656, 1024, 8960, -3840, -15872, 16384, 4864, -19200, 12800, -2048, 2048, -3584, -3072, 7936, -4864, -7680, 11520, -2560, -3072, -2560, 9216, 768, -13568, 3584, 11520, -9472, -5632, 10752, -6400, 5376, -9216, 5376, 9472, -15616, 1280, 12032, -12544, 4864, -1024, 1280, 256, -3072, 1792, 768, -2816, 512, 4608, -7168, 3328, -1024, 4608, -3328, -5120, 8448, -5632, -2048, 5376, -3072, -2560, 6144, -2304, 512, -6912, 3840, 8448, -10496, -4608, 14336, -10240, 2304, -1280, 1536, 5120, -11264, 2816, 9984, -8960, -5632, 12800, -1792, -9216, -1536, 10496, -2560, -7680, 3840, 5120, -5632, 1792, -2816, 4096, 1536, -13056, 15104, -5376, -6656, 6144, 3072, -6144, 2048, -1792, 3072, 768, -9216, 6912, 4608, -10752, 5632, 2304, -5632, 2816, -512, 3840, -10240, 9728, -3328, -4096, 2048, 6144, -8448, 3840, -3328, 1024, 5888, -10752, 4352, 7680, -8704, -1280, 7168, -5632, 2816, -5888, 7680, -3584, -7168, 9472, 3072, -11776, 2816, 7936, -5888, -3072, -1792, 9216, -4352, -1536, -1024, 6400, -4608, 1024, -7424, 13568, -12288, 1024, 6144, -2304, -5376, 7680, -256, -5120, 512, -3328, 13056, -13056, -256, 9984, -5888, -4608, 8448, -5888, 768, 768, 512, -3328, 2816, 1024, -3328, 3840, -3584, -768, 256, 6144, -13568, 14080, -6144, -4352, 9216, -256, -12544, 11520, -1792, -3072, -512, -1024, 6144, -5888, 256, 1536, 5888, -13056, 7680, -2048, 3584, -7424, 4352, 3072, -2304, -5376, 5376, 256, 768, -8192, 5376, 7680, -15104, 6912, 6400, -5376, -6656, 9216, -6144, 4096, -5888, 3840, 2560, -3840, 2816, -2816, -768, 3584, 256, -7680, 8192, -6144, 6912, -6400, 2560, -3072, 7424, -8448, 1792, -1280, 6400, -7424, 3584, 3840, -10752, 5120, 4608, -6912, 256, 5376, -4864, 4352, -4608, 512, 4864, -3072, -8704, 12032, -5376, -1536, 2304, -512, 3584, -8192, 8192, -5888, 3584, -5376, 5376, 0, -3328, -2048, 10752, -8960, -4864, 8448, 1024, -8704, 5888, -1280, -1536, 5632, -7936, 5376, -2048, -1280, -768, 3840, -5632, 2560, 512, 1792, -4352, 2816, 768, -2560, 512, -256, -512, -2304, 6400, -5120, 2816, -4608, 4352, -768, -3072, 512, 2304, -256, -2560, 1280, 0, 3840, -10240, 9216, -1280, -7168, 4096, 6144, -8704, 4096, -256, 3328, -8192, 2816, 2304, 1280, -6656, 1280, 8192, -8192, 1024, -256, 7424, -9728, 2048, 1792, -1536, 1280, -512, -1280, 4608, -6656, -512, 9984, -10752, 0, 6656, 512, -11008, 11520, -7680, 5120, -2816, -1536, -768, 4096, -1792, -1536, 768, 3072, -3328, 1280, -1792, -5376, 12032, -7424, -2816, 2304, 9216, -11520, 2048, 0, 5632, -7168, -1792, 8192, -5632, -2304, 5120, 3072, -10240, 6144, -2048, 3584, -7168, 2560, 2304, 3072, -7424, 3840, -1792, 3840, -5888, 1280, 3584, -6144, 3072, 2048, 1024, -9728, 9216, -1024, -1792, -7680, 12032, -3328, -6144, 4096, 5888, -11776, 7424, -768, -2560, 5120, -11008, 8960, 0, -1024, -7680, 12032, -4608, -5376, 4096, 4864, -8960, 2816, 4864, -5376, -2816, 6912, -3072, -2304, 4096, -5376, 5888, -8192, 7680, 768, -5632, -3840, 13056, -9728, -256, -512, 2816, 3840, -7168, -256, 4096, 3328, -10752, 5888, 1024, -1536, -8192, 15616, -6144, -8960, 8704, 7424, -14080, 1024, 3328, 2304, -1536, -6656, 8960, -1536, -2816, -2816, 4864, -1536, -768, -3840, 11008, -10496, 1024, 5632, -256, -8704, 4608, 3840, -8960, 4608, -256, 5888, -8960, 4608, -512, -2304, 256, 2560, -4608, 4352, -4608, 5376, -2048, -4352, 6144, -256, -5120, -1792, 6656, -2816, 1536, -8448, 10752, 0, -10240, 2304, 11776, -12288, -1536, 6144, 3328, -9984, 2048, 10496, -11008, 768, 1536, 1536, -1792, -1536, -2048, 10752, -9472, -2816, 9984, -4096, -6656, 6400, 768, -6144, 2304, 2816, 1536, -8704, 4352, 3584, -3072, -5632, 5120, 0, 3584, -9728, 6912, 2560, -9472, 5632, -256, -1280, -1792, 2816, 1024, -768, -7424, 9728, -1280, -6656, 1024, 5120, -4352, 1536, 512, 2816, -4352, -2560, 10240, -12544, 2560, 6656, -2048, -6144, 2816, 3072, 1280, -9216, 5376, 5120, -5632, -7424, 7168, 7680, -7680, -6144, 7936, 6400, -17920, 9984, 1024, -4096, 768, 2304, -3328, 4096, -6656, 5888, 4864, -11776, 256, 7424, 1536, -9472, 2048, 6912, -2048, -8448, 9216, -6144, 1280, 3584, -2048, -2048, 256, 1024, 3840, -6912, -2816, 11264, -9728, 1536, 3072, -768, -3072, 5120, -4352, 4096, -8960, 7168, -1024, 0, -3328, 2048, 5888, -6144, -4096, 7168, 2816, -14848, 12288, 1536, -9984, 2816, 6144, -2304, -2048, -6400, 10752, -4096, -3584, 3072, 512, 3328, -7936, 1536, 6656, -2560, -12288, 16384, -5632, -5376, 1536, 7168, -3840, -2816, -512, 5632, -7680, 2816, 3840, -6400, 3328, 512, -256, -1792, -1024, 1536, 4352, -9472, 4352, 0, 256, 3584, -5888, 1024, 4096, -5888, 1536, 3072, -7936, 7680, 1536, -4608, -6400, 11520, -1792, -5120, -3840, 11264, -9728, 2304, 5632, -9472, 6144, 1536, -5120, 3584, -4352, -2048, 11264, -6912, -5632, 4096, 7680, -8448, -4608, 5120, 7936, -12800, 2816, 6912, -5376, -1024, -768, 6656, -3840, -6144, 3840, 5120, -6912, 4096, -3072, 2304, 1280, -6144, 768, 6656, -6912, 1280, 3840, -4864, 2304, -2304, 6656, -6400, -1280, 2560, -1024, -1536, 7936, -11520, 4608, 6144, -5888, -5888, 6912, -768, 512, -4608, 2304, 3328, -4608, 4864, -4352, 1792, -256, -6144, 7936, 1280, -12544, 7936, 8192, -10240, -1792, 2560, 3584, -3072, -3072, 1280, 5376, -7680, 6400, -3072, 1024, -4608, 2304, 2816, -3328, -5120, 9472, -2048, -768, -3328, -768, 8448, -5376, -8192, 11264, -1792, -5632, 7168, -6144, 1280, 3072, -4864, 512, 1536, 512, -4096, 2816, 2560, -1536, -5888, 7936, -6400, 1792, 1536, -4096, 4608, 256, -8960, 10240, -2304, -4608, 3072, 1024, -512, -6400, 5120, 4864, -4096, -8960, 11776, -3584, -2048, -768, -256, 6144, -3072, -6400, 6656, -1024, -1536, 768, -3072, 5120, -6144, 4608, 2304, -5120, -512, 4608, -3328, -256, -4096, 2048, 6656, -8960, 3072, 2560, -2816, 1536, 512, -7680, 11776, -11008, 4096, 1536, 256, -5120, 6656, -4608, 2048, -3328, 2304, -768, 768, 256, -6400, 7424, 3328, -12800, 3072, 10496, -12032, 3840, 3584, -3072, 512, -768, -256, 3584, -6400, -768, 6656, -5888, 4864, -8960, 10496, -1280, -5888, -256, 7936, -7680, 2048, -3840, 8192, -7424, -1792, 5632, 2560, -8960, 3072, 1536, -512, 5120, -12800, 9216, 1792, -4352, -1024, -256, 1792, 512, -5376, 4864, -3072, 256, 7168, -6400, -1280, 2304, -768, -3072, 8192, -11520, 4096, 5376, 0, -11008, 5376, 7168, -4864, -9728, 11520, -3840, -2048, 7168, -11008, 9984, -3072, -5888, 3328, 4864, -9984, 5888, -768, 4352, -8192, 1536, 5120, -1280, -8192, 5888, 2048, -3840, -256, 2816, 2304, -7168, 1280, 5120, -4608, -1536, 2304, -4608, 12800, -12800, -2048, 12544, -7680, -1280, -1024, 3584, -4864, 7168, -5376, 512, 1024, 2816, -5120, 1536, 768, -1280, -6144, 13824, -8704, -3584, 6656, -1024, -512, -4096, 1280, 5120, -5888, 256, 1536, -2304, 8192, -9472, 256, 6400, -5632, -2048, 7936, -1536, -9472, 7936, 0, 768, -9472, 6144, 6400, -6912, -5120, 6912, 256, 1024, -6656, 3328, 768, -3584, 3072, -1536, 1536, -768, -1536, 4608, -3584, -6912, 9728, 1280, -9216, 3584, 3328, -5632, 6656, -3328, -5632, 9216, -5888, -1280, 768, 4608, -3072, -5888, 7936, -1280, -6144, 5888, -3840, 4352, -1792, -5888, 5120, 1536, -1024, -4864, 5120, -2048, 3840, -8192, 3328, 4352, -7680, 4352, 3328, -4864, -2048, 1024, 6144, -4608, -7424, 9216, 1792, -5376, -5120, 7168, 3328, -4352, -7936, 9216, -2304, -1792, 1792, 1536, -2304, -1024, 1792, -1536, 2560, -8192, 10496, -6656, 3072, -2560, -3072, 8960, -2560, -9984, 9216, -2304, -1792, 1792, 1536, -2304, -1024, 2816, -3584, 1280, -1792, 2304, -3328, 6144, -6912, 1024, 3584, 1792, -7936, 4864, -3584, 4352, -1280, -8704, 14592, -7936, -1792, -1536, 7168, -3840, -2816, 512, 6400, -5376, -3584, 3840, 4608, -8960, 3072, 256, 2304, -5120, -512, 8192, -9472, 6656, -4352, 1792, 256, -2560, -4608, 13824, -9472, -4096, 5888, 2816, -3328, -5888, 8704, -1280, -4096, -2560, 6400, -7168, 7680, -2560, -1792, -1280, 4608, -6144, 6400, -6144, 4608, -2816, 0, 768, -4864, 8704, -3072, -3072, 512, 768, -3328, 8192, -9472, 5120, 1024, -1536, -6400, 7424, -768, -512, -2816, -512, 7168, -9728, 4608, 1792, -1280, -1792, 0, -1024, 5376, -9216, 7680, -4864, 6400, -7424, -3840, 12288, -2816, -11008, 8448, 8448, -16384, 4352, 6656, -3072, -4608, 2304, -256, 4608, -8448, 5888, -3328, 5376, -4608, -3328, 4608, -512, -5120, 5120, 1536, -3840, 1024, -3072, 7168, -6912, 256, 2560, -1280, 768, 0, -4352, 3840, 4352, -7680, 512, 1280, -2048, 4352, -2816, -512, 2304, -5120, 5888, -6912, 5888, -2560, -768, 1792, -768, -6400, 7936, 2304, -7168, -2304, 7680, -1280, -7168, 3840, 7424, -9216, -2304, 7424, -2816, -5120, 8448, -6912, 5376, -3584, -3072, 5376, -768, -2304, -512, 3072, -1280, -6912, 6912, 1792, -5120, -2816, 8192, -2304, -3840, -256, 2304, 5120, -10752, 3072, 2304, -1024, 768, -1536, -768, 1536, 0, -3072, 3840, -6400, 6912, -1536, -1536, -1536, 1536, -512, -1024, 1280, 2304, -5120, 3072, 2048, -4352, -2560, 7680, -3072, -6144, 6400, -3840, 4608, -5376, 5376, -2048, -1536, -2304, 3072, -1536, 3840, -8448, 6656, 2048, -8192, 3328, 5376, -3072, -7168, 5120, 2816, -1536, -7168, 6912, 2816, -5376, -2560, 5632, -256, -2816, -1792, 6144, -3072, -6912, 8960, -2048, 0, -5120, 5888, -2560, 2304, -7680, 8192, -3840, 768, -1792, 1536, -512, 2560, -4352, 256, 2048, -1024, -1280, -768, 3584, -2304, 256, -2816, 4608, -3328, 3840, -8448, 5632, 3584, -8192, 2816, 2304, -256, -4352, 3584, 0, -768, -4096, 7424, -5376, -1024, -256, 7168, -6144, -512, -2816, 10496, -6400, -5888, 6144, 1536, -4608, -3328, 9472, -5376, -512, -1024, 7424, -10240, 2816, 3072, 1024, -6400, 3072, -2304, 5888, -4352, -3584, 6912, -512, -6656, 2304, 4608, -3584, -256, -3840, 7424, -4608, -1024, 1280, 3072, -6656, 4608, -768, -1792, 768, 3328, -2560, -6400, 11264, -9728, 2816, 2048, -512, -6400, 7168, -2304, 3072, -3328, -3328, 2560, 6912, -13568, 4864, 4096, -1024, -5120, 3072, 3072, -5376, 1280, 3072, 768, -8960, 5632, 2048, 0, -7168, 4608, 4096, -6400, -768, 2304, 2048, -768, -4864, 2048, 6144, -8704, -1024, 9728, -4096, -7680, 7424, -256, -512, -6400, 7168, -256, -5376, 2816, 2560, -4608, -256, 2560, 256, -1792, 0, 256, -1792, 3840, -3840, -1280, 4096, 512, -5632, 2048, 0, -256, 6656, -8704, -5632, 14336, -6656, -2816, 3072, 2304, -2304, -2304, 1024, 1792, -2048, -256, 2048, 0, -5376, 2560, 4864, -2048, -6400, 4352, 2560, -4608, 768, -1024, 6656, -3840, -7424, 7680, 2304, -11776, 9216, 3072, -8448, 256, 4608, -512, -4096, 1024, 4096, -2560, -4096, 2816, 512, 2048, -4864, 1280, 256, 2560, -5376, 5120, -2048, -256, -768, 256, 1792, -4864, 1792, 2816, -3072, 1280, 1280, -6656, 7424, -2816, -1280, -512, 3072, -3328, 2304, -5632, 5888, 768, -5120, 1024, 4352, -4096, -3328, 4352, 3840, -4096, -8704, 9472, -1280, 2048, -8192, 5888, 4352, -9216, -512, 9216, -6400, -1024, 7168, -4608, -5120, 3840, 1024, 1792, -3072, -6144, 11008, -4864, 0, -2816, 6400, -2304, -3072, -1792, 2560, -256, 2816, -512, -3072, 3328, -6912, 7680, -2304, -3840, 2048, 4352, -7168, 4608, -2304, 768, 1792, -2048, -2560, 4096, -6656, 8960, -5632, -2560, 9472, -8960, 256, 2816, 2816, -4864, -512, 2304, 4352, -9472, 2816, 2560, 2304, -4096, -3072, 6912, -2816, -5632, 4096, 6144, -12288, 6400, -256, -768, 1024, -5120, 3328, 9984, -18432, 8704, 256, 512, -1536, 1024, -256, -2048, 512, -2048, 4608, -2560, -256, -1280, 4864, -7680, 1280, 7680, -4096, -6656, 9216, -6656, 768, 5376, -6912, 2560, 1024, -2560, 0, -1024, 3840, 2304, -10496, 8192, -2816, 512, -2816, 3840, -768, -1792, -2048, 4096, -768, -5376, 5888, -512, -2304, -1024, -512, 5120, -1280, -9472, 12544, -5120, -1536, -2304, 4352, 4352, -9216, -2048, 10240, -6144, -1280, 768, 2048, 1280, -3072, -1536, 3840, 512, -6912, 7168, -1024, -5888, 4096, 1280, -256, -6656, 7424, 2816, -9728, 5632, -3072, -2048, 9728, -8704, -768, 2560, 1024, -512, -1280, -2048, 6144, -4096, -5120, 5376, 256, -1792, 2816, -1792, -1024, -3840, 3840, 3840, -5376, -1536, 2560, -256, 4352, -11520, 5888, 7424, -10752, 512, 4608, -1280, -1536, -256, 5632, -5120, -4864, 4096, 5376, -5120, -4608, 5888, 512, 1280, -10496, 9216, 2560, -8704, 3072, 3072, -6400, 2816, 256, 1536, -1536, -2816, 5120, -2816, 2560, -2816, -3072, 3328, 2048, -5376, 1280, -256, 3584, 768, -6656, 1280, 6912, -9984, 4608, 1792, -6912, 8704, -5120, 3328, -5120, 1792, -1024, 6400, -5888, -4096, 1792, 12032, -8960, -7424, 9472, 2560, -8960, 1024, 3072, -256, 0, -3840, 6400, -5888, -3072, 8960, 1792, -13056, 7168, -256, 4096, -8448, 1280, 6912, -5376, 512, -1280, 3328, -768, 0, -5120, 6912, -7680, 2048, 4096, -1024, -3328, 3584, -3840, 4864, -3072, -1536, 2048, -2304, 4864, -6912, 1024, 5120, -2304, -3072, 5376, -9472, 10496, -5632, 256, 256, 3328, -8448, 5120, 3584, -7680, -512, 5632, 5376, -13056, 768, 9728, -1792, -8960, 4352, 1536, 2816, -11008, 8448, 2304, -9216, 2560, 7936, -6144, -3328, 4096, -1536, 6144, -9216, -256, 4096, 4864, -11520, 5120, 2816, 512, -7680, 7936, -5376, -3584, 7424, -1024, -3072, 768, -1536, 2304, 3840, -9472, 5120, -1024, 2048, -4608, 3072, -1792, 4352, -2048, -3072, -2304, 5888, 2048, -7168, 256, 7424, -4864, -4608, 6912, -512, -2048, -7168, 11264, -1024, -9216, 3840, 8448, -7680, -3328, 3328, 3584, -5120, -1792, 6400, -2816, -1280, -2048, 5376, -256, -2048, -9472, 12800, 256, -13568, 6912, 7168, -5376, -2560, 1024, 4096, -6144, 2560, 1536, -3072, 0, 512, 1536, 256, -3328, 512, 5376, -6656, 768, 3328, -4864, 2560, 2304, -4608, -768, 5632, -4608, -256, -512, 3584, -256, -5888, 5376, -1536, -512, -2304, 5120, 1280, -8960, 256, 8704, -5376, -4096, 5632, 256, -2048, -1280, 256, 4608, -3072, -5888, 4608, 1280, -4352, -1792, 9472, -1536, -8960, 1536, 12032, -11264, -1792, 5120, 1280, -2560, -5888, 8960, -1536, -3072, -3072, 9984, -6912, -2560, 2304, 5376, -5376, -1536, 512, 1280, 256, 1536, -7168, 4352, 5120, -7936, -768, 3840, 1792, -6656, 7936, -10240, 11008, -8192, 5888, -4864, 2816, -5632, 6656, -1536, -256, -6400, 8448, 512, -6400, -1792, 2304, 6656, -4096, -7680, 7424, 5120, -12032, 3328, 4096, -2304, -4864, 4608, 5888, -8192, -4352, 8192, 5376, -9728, -3328, 3584, 11008, -16896, 4864, 5888, 1280, -12800, 12032, -5120, 512, -2816, 5632, -1280, -1536, -5376, 1024, 9728, -3840, -8192, 3072, 8960, -8960, -1024, 1792, 4608, -4352, -256, -1792, 1536, 1280, 0, 0, -1792, 0, -2048, 5376, -2560, 1280, -7168, 7680, 768, -4352, -7424, 14592, -4096, -4352, -2560, 7168, -2304, -5120, 6656, -3072, 768, -5120, 6912, -768, -1792, -10752, 16640, -2304, -11520, -768, 16128, -8448, -2816, -1536, 7168, -4352, -256, -1536, 1536, 1792, -3072, 0, 6400, -5376, -7680, 13824, -2304, -9472, 256, 7168, 1792, -10752, 4608, 2816, 4352, -11776, 6144, -2304, 6912, -9728, 5632, -5120, 5888, -5376, 2816, -1536, 10752, -18176, 5120, 8192, -2816, -11008, 11264, -768, -1024, -6912, 3072, 6144, -2048, -4608, -2048, 7680, -4864, -5888, 11264, -2048, -7680, 0, 11520, -9984, 0, -256, 7168, -4096, -4352, -3840, 11264, -3328, -2816, -3328, 9216, -6144, -2816, 3072, 4352, -7680, 2048, 4352, -2560, -4608, 2304, 5632, -4608, -3840, 768, 6400, -6400, 2816, -1536, 1280, 1792, -4608, -768, 3840, -256, -4352, 2048, 7168, -8192, -4352, 9216, 2048, -10496, 3072, 1792, 3328, -5632, -3584, 4608, 10496, -14592, -256, 6400, 2560, -10240, 4608, 2816, -2048, -5888, 6400, -4096, 9472, -11520, 4352, 2560, 512, -15360, 16384, -3840, -768, -4096, 5632, -2304, 2304, -6912, 7680, -1792, -5376, 768, 5120, -2560, 1536, -3072, 3840, -4864, 3584, -4864, 768, 5632, -2048, -7424, 9472, -7168, 7424, -6656, 2816, -3840, 3840, -4352, 5376, -6656, 4608, 1280, -1280, -2816, 512, 4096, -2560, -2560, -1280, 7424, -7680, 1024, 768, 4608, -5376, 1024, 256, 2048, -3328, -2560, 256, 10240, -8960, -6656, 11264, 1280, -9728, 2048, 7680, -6144, 0, -256, 0, 3072, -4608, -256, 4608, -2048, -7168, 9984, -4608, 6144, -8960, 6144, -9216, 11776, -10496, 3072, -768, 6144, -9472, 7936, -7168, 8192, -4096, 512, -6912, 9984, -8704, 1792, 6144, -4864, -1536, 3584, -2560, -256, 3584, -4096, -1024, 6400, -6656, -1024, 2048, 5632, -10240, 8448, -7680, 5632, -3840, 9216, -16128, 9984, 256, 2560, -13824, 9216, 2304, 1280, -13056, 12544, -3328, 1280, -1792, -1792, 3840, -2304, -2560, 512, 3072, -4608, 1536, 768, 4608, -7424, 2304, 2560, -2560, 256, -5120, 5120, -768, -256, -3328, 5376, -6656, 10496, -9216, 512, 5888, -5888, -2560, 9984, -10496, 4352, -2560, 2048, 1792, -3328, 5888, -13824, 16896, -6656, -12800, 13824, 4352, -16896, 15104, -11776, 7680, -2560, 1536, -2048, -4608, 4864, 4096, -8192, 3072, 1536, -512, 768, -9216, 8448, -1536, -1792, 3072, -4096, 1536, 3584, -5376, 3584, 4096, -14848, 9472, 768, 0, -8960, 11264, -4096, 4352, -9728, 7168, -3584, 6400, -11520, 7168, -5376, 8192, -7936, 2816, 4352, -6144, 2816, 1280, -6144, 4608, -1536, -768, 0, -768, 5376, -8448, 6144, 5120, -19968, 16896, -2048, -6144, 768, 4352, -3584, 6144, -10496, 8704, -6400, 6912, -8192, 4352, -1280, 3328, -6656, 7168, -7424, 5632, -2048, -4096, 8448, -7680, 512, 6400, -6912, 256, 7936, -9216, -1792, 7936, -2048, -3072, -1280, 4352, -1792, 1280, -6656, 8192, 256, -4608, -4096, 6912, -1792, -2560, 512, 5376, -10752, 7680, -768, -4864, 8448, -10240, 4864, 1536, -3328, -1280, 4352, -2560, 7168, -16128, 10240, 1536, -2560, -2304, 1792, -768, 3072, -5120, -256, 4352, -256, -1536, -3584, 4608, 256, -4864, 3072, 1280, -2304, -512, -3584, 8448, -768, -11264, 13056, -4352, -1536, -4096, 9216, -8960, 7424, -7936, 7936, -6144, 3840, -5888, 8448, -8960, 5120, -1024, -256, -4864, 6912, -256, -7424, 6400, 256, -5120, 6400, -5888, -3328, 15872, -12800, -4608, 11008, -5120, 256, -1024, 4096, -4608, 1024, -4096, 9216, -10752, 10752, -10752, 9728, -7168, 2304, -2560, 7936, -10240, 7680, -9984, 7680, 2048, -7168, 2816, 2304, -1792, -1536, -2048, 2560, 5632, -9216, -1280, 6656, 1024, -10496, 7680, 3072, -2816, -2560, -3584, 9472, -7424, 768, -1536, 2304, -1280, 3840, -7680, 10240, -6656, 3072, -6400, 6400, -5376, -3072, 11776, -4352, -9984, 12032, 1792, -14592, 11520, -3584, 256, -3328, 5376, -5376, 3584, -1792, 1792, -2816, 4608, -8704, 6400, 1792, -7168, 5632, 256, -3072, 2816, -6144, 1024, 9728, -11264, 4352, 512, -3072, 4864, -4352, 0, 2304, 4352, -14080, 7424, 768, 768, -6912, 12288, -9728, 4096, -4352, 6144, -4864, 6656, -12544, 7424, 2304, -4608, -6400, 12800, 512, -7936, -5120, 11008, -768, -8960, 5888, 3328, -8704, 2304, 5120, -3840, -2048, 7424, -9472, 7424, -5376, 1024, -2048, 9216, -13312, 7424, -2048, 1536, -4608, 8960, -8704, 5632, -5376, 2560, 1280, -2816, -3328, 8960, -6656, -768, 3072, -4352, 3328, 256, -3072, -1024, 6144, -4608, -1536, 4608, -1792, -3328, 4352, -1024, -7680, 12288, -10496, 2560, 8704, -9984, -5632, 18688, -12288, -3072, 3072, 5632, -3584, -7936, 4608, 7424, -4352, -5376, 5632, -768, -2048, -3072, 6400, -2816, 3328, -10496, 9216, -768, -512, -6912, 9472, -1536, -9216, 4352, 4608, -1792, -2560, 1024, -1280, 2560, -5376, 3328, 3840, -5376, 512, -256, -1280, 2048, -256, -4096, 7424, -6144, 3584, -4608, 6656, -6144, 4352, -6656, 5376, -4608, 6144, -12544, 20992, -13312, -2816, 9216, -5632, -4352, 7680, -5376, 256, 256, -256, 2048, -512, -1792, 512, 4352, -2304, -9216, 9472, -1280, -3840, -1024, 6912, -5120, 2816, -7936, 11776, -4608, -3328, -2816, 14848, -17152, 4864, -1024, 10240, -11008, 2304, -3584, 10496, -8192, -4096, 11776, -4864, -3328, 1280, -1280, 1536, 512, -4096, 2560, -2304, 4608, -3328, 768, 6144, -9472, 2816, 256, 0, -2048, -2304, 7168, -256, -10496, 10240, -2560, 1536, -3328, 256, -2816, 7680, -7168, -2560, 7680, 256, -9216, 4352, 7168, -13824, 13056, -6144, 256, -1536, 1536, -3072, 8448, -12288, 5888, 4608, -4352, -5888, 6912, 2816, -5888, -3328, 6912, -1792, -256, -6144, 8960, 768, -12288, 8960, 2048, -5120, -768, 768, 4096, -2816, 2048, -8960, 8192, 1792, -6912, -5632, 20736, -21760, 9216, -1792, 4096, -4096, 512, 0, 3328, -7168, 3072, -4096, 6144, 1536, -6400, -3584, 12032, -3840, -6400, 768, 9472, -10496, -1280, 8192, -6400, 2816, 1536, -4096, 6400, -8704, 3584, 2048, 3328, -13312, 7680, 1536, 3328, -14336, 14336, -6912, 3328, -2816, -1536, 4096, -3072, -256, 4608, -10240, 4608, 4864, -3328, -2816, 1792, -512, 2304, 2560, -9984, 2304, 11776, -12288, -4608, 15104, -8192, -768, 3584, -2560, 2560, -3328, 2560, -3328, 3584, -2816, -2560, 1280, 7936, -11008, 2560, 5888, -4096, 768, -7424, 12800, -5888, -4864, 4096, 3840, -4864, 768, -5120, 9984, -4864, -3584, -1536, 13824, -11264, -3072, 4608, 7680, -14336, 7168, -3840, 5632, -4096, -3840, 7936, -2048, -2304, -256, 256, 256, 512, -2048, 2304, 2560, -11008, 10496, -2304, 2048, -12288, 15872, -7680, -2304, 3328, 1536, -6144, 8192, -7936, 2048, -1024, 4096, -6912, 6912, -4864, -256, -1536, 9472, -10240, 3584, -768, 0, 6400, -15104, 8704, 4608, -4608, -5376, 4352, 3328, -2816, -2048, -2816, 11008, -10240, 256, 1536, 6144, -9472, 2560, 3584, -1024, -3072, -512, 4352, 2816, -10240, 2560, 4096, 4352, -13056, 6144, 3584, -1024, -7936, 5632, 4608, -8192, 3840, -6144, 11776, -9728, 2304, 512, -512, 3584, -3840, -3072, 3840, 768, -7168, 7424, -1792, -1536, 3328, -1792, -1536, 512, 768, -4352, 7168, -7168, -2304, 9472, -4352, 0, 768, 2560, -4864, -1280, 4864, -4352, 3072, -6400, 7680, -4864, 2048, -6912, 12544, -3840, -6912, 2304, 2560, 1792, -7936, 1536, 7680, -3072, -11520, 10496, 6144, -10752, -256, 7168, -512, -9728, 7424, -4608, 5888, -1024, -11008, 8960, 6656, -13824, 5888, 1792, 1536, -7680, 4352, -3584, 8192, -10240, 6144, -3328, 4352, -3840, -2816, 4096, 4096, -5120, -6656, 12032, -2560, -6656, -1536, 10496, -4864, -5632, 9216, -10496, 8448, 1280, -8192, 3072, 7168, -13056, 4864, 6912, -10240, 1792, 8960, -8704, 2304, -5632, 10752, -5120, -3840, -768, 11008, -14080, 3840, 5888, -2560, -2816, 768, 3584, -8192, 7936, -6656, 5376, 1792, -11264, 3840, 10240, -5632, -10496, 13824, -4352, -4352, 2048, -1536, 2560, 2816, -4352, -1536, 3840, -512, -5120, 7936, -4864, 1024, -4352, 5632, 0, 512, -9216, 9984, 0, -7936, 5888, -9728, 15104, -3840, -7424, -3328, 17664, -12800, -5632, 11008, -2816, -4096, 0, 4096, -2304, -2560, 3328, 1280, -2048, -4608, 6912, -2048, -512, -3072, 3328, -256, -4096, 4096, -4608, 6912, -2816, -4864, 9984, -7168, -6656, 7168, 9216, -21760, 18432, -10240, 6144, -2560, 0, -2304, 7680, -7424, -2816, 5632, -3328, -1792, 5888, -2560, -3584, 1536, 3328, -3840, 5632, -7936, 3072, 0, 0, -768, -3840, 4864, 3584, -5376, -5632, 6912, 8960, -18432, 9216, -768, 4608, -13824, 12800, -7424, 9728, -12032, 3584, 4864, -2816, -6400, 6912, 2304, -5888, -512, 512, 4096, -1536, -6144, 5632, 2560, -6912, 1792, 4096, -7680, 2816, 6144, -10240, 7936, -7168, 7424, 256, -7168, 1792, 4352, 768, -11520, 10240, -2816, -1792, 1024, 4864, -11520, 6144, 6144, -12800, 12288, -8960, 2816, 2304, -3072, -3584, 7680, -5888, 2048, 1792, -3840, -1792, 13568, -15104, 3328, 1280, 3840, -11776, 12544, -12288, 14592, -9216, -5120, 8704, 256, -2560, -3840, 3840, 5120, -9216, -2304, 8960, 1536, -9984, 1792, 3584, 6912, -20736, 17920, -5376, 1280, -5632, 5376, -1536, 256, -3328, 4864, -4864, 1024, -2560, 8960, -11008, 7936, -768, -1792, -3840, 10240, -14336, 8448, -256, -8448, 13056, -8960, -512, 6144, -4608, 1280, 0, 1024, -4096, 2560, -1536, 2304, -7168, 9472, -9728, 11520, -8960, 0, 9472, -9728, 1792, 4864, -8192, 768, 4352, -512, -5888, 4864, 3840, -5888, 1280, -512, 3328, 256, -9472, 2048, 15104, -20480, 6656, 3328, 3840, -7936, -2048, 7680, -1792, -1792, -4864, 5632, -512, -2304, -512, 3072, -1792, 768, 256, -6400, 12032, -13568, 8960, -1280, -6912, 5376, 3840, -6400, 3328, -6144, 10752, -10496, 4864, 512, -3328, 256, 5888, -10240, 9472, -11520, 11776, -2048, -10496, 11264, -2816, -4352, 5888, -2304, -5120, 5632, -768, -3840, 5632, -5888, 4864, -1792, 512, -8704, 16640, -14336, 1792, 7168, -2048, -9472, 9472, 768, -2048, -8704, 9984, -2816, 2304, -7424, 1536, 8960, -3584, -12544, 12288, 1280, -6400, 1280, -6400, 16896, -12032, -2304, 7168, -1792, -3072, 0, 4352, -5120, -512, 5376, -3072, -5888, 13824, -12800, 5120, 1792, -5120, 1792, -512, 768, 1024, -6656, 6656, -1536, -3584, 3840, -768, -2560, 3072, -2560, -1024, 5888, -8448, 3584, -3072, 9728, -14080, 9216, 0, -1536, -1280, 0, -1024, 1792, 0, -3584, 512, 2048, -2816, 3328, 1280, -8448, 10496, 1024, -15872, 10240, 2048, -1536, -2048, -7936, 13312, -1024, -11264, 6400, 5120, -4608, -6144, 8192, -2816, -2304, -1024, 7680, -9472, 8704, -7936, 1792, 7680, -7424, -3584, 7168, -2560, -2304, 1536, 0, -1280, 3584, -2304, -768, -512, 2560, -5632, 7424, -5632, -512, 1536, -1280, 4096, -6400, 1536, 6912, -4864, -2304, -2816, 7424, -3328, -1280, -1536, 4096, 1280, -5120, -256, 7680, -5120, -2048, 1792, -2048, -512, 768, 3584, -2304, -6144, 8960, -1792, -3584, -3072, 8192, -1280, -4608, -3840, 8960, -1792, -3328, -256, -1024, 6912, -5120, -7680, 14848, -3840, -7424, 2304, 3840, -4096, -768, 256, 1024, 1280, -1024, -2816, 4352, 768, -7424, 7168, -2560, -4608, 5120, -1792, -512, 1024, 512, -4352, 5632, -768, -7936, 5888, 5888, -8192, -3584, 8704, -768, -3584, -3328, 2816, 5376, -6656, -4096, 9216, -1792, -3328, 3840, -2048, -768, -256, -2816, 3840, -2048, -1024, -1024, 6144, -5376, 256, 2816, 768, -5632, 1280, 3840, -6144, 0, 9472, -7936, 1792, -4608, 3840, 4096, -3840, -4864, 6656, 0, -2560, -6656, 7936, 1536, -4864, -1536, 5376, -4864, 5120, -3328, -768, 3328, -512, -8192, 6144, 512, -2048, -2560, 9216, -7424, -2560, 4864, 2560, -6400, 1280, -2304, 7936, -5888, -5376, 5376, 6656, -6400, -2304, -1280, 8960, -4352, -8704, 4352, 10752, -11264, -2816, 7680, 2816, -10240, 4608, 2048, -1536, -2816, 2816, -6656, 9984, -4608, -5888, 9472, -3072, -8192, 11520, -2048, -5632, 1280, 4096, -3840, -2560, 1536, 4352, -3840, -768, 2304, -5632, 10496, -5632, -6400, 7424, 1280, -7680, 1536, 3072, 4352, -8192, 1792, 5120, -6656, 2304, 2304, -2560, 1792, -4352, 2560, 2816, -4096, -1792, 3072, 1280, -1024, -6656, 6400, 6144, -11776, -1024, 12800, -9984, -2816, 2048, 8960, -9216, 512, -2304, 8448, -1792, -5632, -6656, 19456, -9472, -10496, 8448, 7168, -11008, 3584, 1536, 512, -2048, 512, -5120, 8704, -4864, -512, -1024, 3840, -1536, -5888, 7168, -768, -8192, 8448, -4096, 1792, -2816, 3584, 2304, -2560, -7680, 8960, -6400, 4352, -3584, 256, 3584, 3072, -9728, 4096, 3840, -1792, -7680, 3840, 4608, -6144, -1536, 12032, -9728, 1536, 1792, -2304, -512, -768, 256, 3072, -2048, -5888, 5120, 8960, -12032, -3584, 13056, -2304, -12288, 4864, 5120, 0, -6400, -512, 5120, 4096, -7424, -6400, 15360, -4352, -5888, -2048, 7936, -1024, -7680, 3072, 5120, -3584, -1024, -256, 4352, -2816, -2304, 1792, 1792, -4352, 256, -3072, 6400, -1280, -5120, 3840, 4864, -7424, 512, 1280, 2816, -4864, -4608, 7936, 256, -6912, 4608, -4352, 13056, -13568, -512, 7424, 1024, -9472, 4352, 2816, -2816, -5888, 10496, -4352, -2560, 3328, -1024, -2048, 4608, -6912, 4352, 256, -4864, -1792, 13056, -9472, -7168, 13568, 1024, -12032, 1280, 4608, 4352, -8192, -2048, 3584, 9216, -11776, 768, 2816, 2816, -6144, 1024, 0, 4096, -1792, -6656, 6400, 5120, -11264, 1792, 5120, -3072, 512, -3584, 1024, 8448, -9728, 256, 2048, 5120, -8704, -3072, 15616, -11776, -4864, 11264, -2560, -1024, -4608, 3072, 3072, -2048, -6656, 4096, 5632, 512, -13056, 4608, 13568, -14336, -1280, 7680, -2304, -5632, 8192, -2816, -4608, 4608, 3328, -6400, -1792, 2048, 2304, 768, -5120, 256, 8192, -6912, -2304, 1280, 4864, -5120, -3328, 4608, 2048, 768, -8960, 5632, 7936, -12032, -512, 4096, -2048, 3840, -2560, -5632, 13824, -5120, -5888, -1536, 13056, -13312, -3328, 12288, -5888, -2816, 7168, -7680, 9728, -1536, -12800, 7168, 8448, -14848, 512, 8704, 4096, -13568, -256, 14080, -3328, -10752, 3840, 5888, -1792, -8448, 3328, 5376, -3584, -1536, 512, -512, 6912, -11008, 6912, 2816, -4864, -4096, 6656, -4096, -1024, 4096, -4352, 256, 5120, -4352, 2048, -4352, 1536, 6656, -6400, -6144, 10240, -3328, 1536, -3584, -3584, 7424, 768, -8192, -1280, 11776, -5376, -7168, 9728, -7680, 1536, 7168, -12032, 768, 16640, -17152, -1280, 15616, -8704, -6912, 7936, 3072, -7680, -1792, 2816, 4864, 0, -11008, 4608, 12032, -13312, -5120, 13312, -3584, -2304, -2560, -1280, 14080, -11520, -7424, 14080, 4096, -21248, 7168, 9216, -5888, 1536, -2048, -3328, 9472, -4352, -7680, 8192, -2304, -1536, 2560, -4864, 4096, 1024, 2304, -8960, 5632, -256, -4352, 768, 2048, 2560, -2560, -5376, 10240, -6912, -1280, 4096, -1536, -6912, 12032, -5888, -6656, 12288, -4608, -4864, 3584, -256, -2304, 1280, 256, -5120, 14848, -14592, -3584, 14080, -4096, -10240, 9472, -1536, 2816, -4864, -5632, 11008, 512, -14080, 6912, 9472, -9728, -7424, 14848, -1536, -2816, -5632, 1024, 6656, -1792, -17152, 17152, 5376, -14336, 4864, 3840, -1280, 0, 512, -10496, 9472, 2560, -16640, 12544, 2048, 256, -4864, 256, 2304, 2048, -5120, -2304, 5632, -3584, -768, 1024, -256, 3328, -1536, -2816, 3840, -2048, -3840, 3328, 4096, -9728, 3584, 6144, -9984, 5120, 2304, -4352, 3584, -3840, 1792, 768, -3072, -768, 7680, -6400, -6144, 11008, -256, -10240, 4608, 4352, 0, -5632, -3584, 7936, 5120, -17408, 8960, 8192, -11008, -2304, 8960, -4096, 1024, 512, -8960, 8960, 6912, -20736, 10240, 7936, -5376, -7680, 7424, -3072, 3328, 2560, -10752, 6656, 4352, -8448, -256, 4096, 3072, -7424, 1536, 1024, 5376, -6912, -2304, 9984, -1536, -13824, 10240, -3584, 3840, -1024, -4352, 5120, 1024, -4608, -1024, 5888, -6144, -768, 7680, -10496, 3840, 4352, -1024, -7424, 4864, 1024, -2304, -2560, 3072, 4352, -5376, -1792, 6656, -4864, -4352, 4352, 768, 256, -768, -7680, 12032, 4096, -15872, -1024, 17408, -7424, -13824, 11008, -256, -1024, 5120, -10752, 5632, 8704, -8192, -11008, 16128, -3072, -6656, 2048, -1536, 2560, 5632, -16896, 14080, 6400, -16640, 3840, 2304, 5376, -5632, -7168, 9216, 1280, -4096, -13056, 26112, -12544, -3072, 1536, 5376, -3072, -5888, 6144, -3840, 2816, -3584, -2048, 7936, 1024, -13568, 16384, -8960, 3328, -7168, 5888, -5888, 5632, -4096, 3328, -5632, 5888, 6912, -13056, -2048, 10496, 1536, -16896, 9216, 3328, 1024, -6656, 1792, 2816, 2304, -8704, 0, 8960, -5376, -3840, 2560, 8704, -14592, 15360, -17664, 15360, -5632, 256, -6912, 6912, 3584, -6912, 256, -3328, 8960, -512, -13056, 9216, 8960, -12544, 1280, -256, 7936, -10752, 6400, -6656, 8704, -1792, -15360, 25088, -11776, -5632, -256, 12544, -11520, -512, 2560, 6656, -8448, 6400, -9216, 9472, -4864, 1024, -768, -1792, 2304, 1792, -2048, -7424, 12288, -5888, 0, -8448, 11520, 0, -5888, -4096, 12032, -1792, -7936, -2304, 9728, -512, -9216, 4608, -2048, 11008, -14080, 4096, -256, 10496, -18432, 13824, -8960, 6144, 1024, -11776, 12032, -2816, 1536, -10240, 6144, 2560, 2048, -9728, 4096, 4096, 6144, -25088, 20480, 512, -7168, -7168, 11264, 2816, -12032, 7936, -1792, 8960, -10752, -6400, 10496, 3072, -16384, 8704, 3584, -512, -5376, 6144, -3584, 2816, -768, -6144, 5632, -7168, 11776, -13056, 9728, -5632, 8960, -10240, 512, 2816, 5632, -12288, 5888, -2304, 8704, -8960, -6144, 13312, -1792, -9472, 2304, 9216, -5376, 0, -8192, 15616, -11264, 1536, -256, -4096, 10496, -7168, 4864, -9472, 12544, -2816, -9728, -2048, 16640, -13568, 2304, -5376, 15104, -9472, 2048, -8448, 15104, -3328, -20480, 17152, 4864, -9984, -7168, 17920, -5376, -6400, -768, 5888, 4352, -7424, -11264, 21248, -10496, 0, -5888, 13568, -6912, -3072, 5376, -4864, 5376, -5376, 3328, -1024, -3072, -1280, 9728, -14848, 8704, 2560, -5632, -4096, 12032, -2048, -9984, 4864, 3072, 1024, -11776, 9984, -6144, 12288, -17664, 11520, -4608, 2560, -1280, -512, -1024, 2560, -1280, 1792, -4352, -768, 5120, 0, -10240, 6656, 10240, -16384, 2816, 8704, 256, -12544, 2816, 8960, -5632, -3584, -8192, 25088, -12032, -9472, 2304, 19456, -17920, -2048, 1792, 16128, -23552, 14336, -12544, 19712, -16384, 512, 10496, -7168, -6400, 9472, 0, -6656, 8960, -10240, 4096, 768, 3584, -11776, 5632, 4608, -1536, -2304, -2816, 5632, 6656, -11264, -11776, 24064, -15360, 4608, -9472, 17664, -8448, 1280, -5120, 10752, -8192, -5120, 6144, -256, -2560, -3072, 9984, -7936, 3328, 256, 2304, -12032, 10752, -6656, 9984, -18688, 12288, 12288, -18688, -3328, 14336, 3584, -19968, 9728, 2816, 3072, -12800, 2048, 9984, 768, -20224, 18688, 512, -6400, -4352, 5888, 6912, -14848, 6656, -9472, 17152, -12544, 2816, -3072, 15872, -20992, 16384, -10496, 768, 6656, -4352, -11520, 14080, -1024, -5632, 2560, -512, 9728, -13824, 2048, 1280, 12032, -20224, 1792, 13824, -1792, -16384, 10496, 12544, -18688, 7424, -6144, 13824, -13056, -1024, 3584, 8448, -21504, 20992, -11776, 4352, -6400, 14592, -11264, -512, 2816, 2048, 3840, -16896, 11776, 4864, -6400, -11264, 14848, 2560, -9728, -5888, 19712, -12288, -768, -3072, 6144, 6144, -17920, 9472, 5376, -3840, -12288, 20736, -16896, 11264, -7424, 1536, 1024, 2304, -7680, 7936, -6144, 1280, 4864, -13056, 8704, 5376, 2816, -23552, 19968, 4864, -11264, -13824, 26624, -12032, -2048, -4864, 7424, 11520, -19968, 1536, 14080, -2816, -19200, 16896, -2560, 2048, -9728, 6144, 2560, 1024, -14592, 16896, -5120, -6400, 5120, 1536, 2304, -18176, 25600, -15360, -1536, 2048, 7168, -9472, 7424, -10752, 19968, -14848, -5632, 10752, 2560, -17664, 8704, 8448, -9216, 7424, -13824, 20736, -13824, 0, 1792, 256, -4864, 5632, -3584, 1024, -768, 8192, -3328, -15104, 22016, -13824, 1024, 0, 5376, -8960, 11008, -17408, 23296, -7936, -13568, 9728, 12288, -18432, -3840, 12800, 768, -2816, -18432, 24576, -256, -12544, -5888, 20736, -5376, -14592, 3840, 16128, -17152, 1280, 6400, -6912, 8704, -12288, 12544, -6656, 3072, -8448, 16896, -18688, 3584, 8960, -5120, -6912, 11520, -6144, 3072, -3072, 0, 6144, -12800, 8448, -6656, 11520, -16640, 12032, -1792, -1024, -2304, 4864, -4864, -512, 3840, -4352, 7680, -9984, 6400, 512, -768, -14592, 27904, -22016, 2560, 3584, 7936, -13568, 1792, 8192, 1280, -11264, -5120, 21504, -8960, -8704, -1536, 25344, -24832, 256, 5888, 10240, -16640, 3840, 2304, 9216, -11520, -5632, 14080, 1024, -14080, -768, 18688, -20480, 16128, -12544, 7168, 512, -2560, -4864, 6144, -3328, 2048, 256, -3840, 1280, 5632, -1024, -14592, 18432, -10496, 4096, -11520, 19456, -14592, 7680, -6656, 9728, -4096, -8704, 8192, 3072, -13568, 5632, 12032, -11776, -1024, 1536, 11520, -16640, 8192, -5376, 11520, -11264, -5632, 17664, -11264, -4096, 7424, 4864, -15104, 10240, -1792, 10752, -19712, 9984, -1024, 7424, -18944, 6912, 9728, -3072, -15360, 17664, 1792, -8192, 256, -2304, 12800, -14336, -3840, 4864, 12032, -19200, 11264, 1280, -5632, 6912, -1792, -5632, 0, 5888, -7680, 256, 1024, 8448, -11264, 7424, -6144, 14592, -17152, 4352, 4608, 1024, -15104, 8192, 12288, -18432, 7168, -512, 3328, -2560, -5376, 4096, 14848, -29952, 21760, -3584, -1280, -8704, 5376, 7424, -6912, -5120, 7936, 5888, -12544, 4096, -3584, 13056, -18944, 6144, 9728, -9728, -4096, 14336, -8448, -1792, 768, 0, 9216, -20480, 12544, 5888, -4864, -12288, 19456, -15616, 11008, -10496, 6912, -2816, 5888, -7680, 2048, 768, 3840, -3584, -5632, 4096, 768, 3840, -9984, 2816, 9728, -3328, -17920, 22528, -10496, 512, 1024, -7680, 20480, -21504, 3840, 9472, -1536, -15616, 14848, -4864, 6912, -18432, 16384, -1536, -4096, -7680, 15104, -5376, -5376, -3072, 11264, 5632, -25856, 19968, -2560, -4096, -2816, 5120, -5376, 7936, -9216, 9472, -4608, -5120, 11776, -6144, -5888, 2560, 5376, -9216, 8192, -9728, 17408, -12800, 3072, -1536, 4864, -8448, 3584, -4096, 5120, -2816, -3584, 12032, -15104, 14336, -3584, -6912, 1280, 7424, -11008, 12544, -24576, 27136, -8960, -10496, 7168, 8960, -7680, -7424, 9472, 3072, -2816, -14848, 20224, -7936, -4096, -2816, 11008, -3328, -6400, 768, 18176, -19456, -3328, 16384, -9984, 768, -11520, 16896, -3328, -256, -11520, 20480, -10240, 1536, -7424, 6656, -3072, 1536, -4864, 5376, -1024, 2304, 0, -9472, 11264, -7168, 2816, -5632, 4864, 1792, 256, -11520, 15360, -3328, -10752, 8192, -4096, 7936, -12800, 8960, 2560, -5632, -5888, 15360, -15872, 5376, -512, 9984, -12544, -1024, 6144, 7680, -13568, -5888, 16896, -8448, 512, -8704, 17664, -8448, -2560, 1792, 6144, -13056, 7168, 0, 2304, -6144, -768, 9728, -6144, -4096, -2304, 17408, -20736, 9728, -4096, 8960, -8704, -1024, 4096, 5120, -11008, 2560, 1792, -768, 3584, -7680, 9728, -9984, 9728, -5120, -3072, -5120, 19968, -20224, 5632, -1024, 11264, -12288, -1536, 9472, -512, -6400, -6144, 15360, -10496, 3840, -7680, 12800, -11008, 1792, 2304, 6912, -16384, 11520, 1280, -3840, -4352, 256, 12544, -14336, 768, -2816, 17664, -19968, 9472, -1280, 9728, -15360, 6656, -512, 2304, -13056, 13568, -5120, -768, 2304, -256, 9728, -18944, 10240, 1536, -3328, -13824, 17664, -6144, 1536, -5632, 7936, 0, -4352, 3072, -3328, 2048, -2304, 5120, -13568, 14336, -6912, 7424, -16128, 10496, 2048, 2816, -18688, 15104, 3840, -6400, -5376, -256, 15616, -17664, 2560, 4352, 7168, -15104, 8704, -3584, 8192, -13824, 4352, 5632, -2816, -12032, 16128, 1792, -14336, 11776, -7168, 12800, -24576, 15360, 512, 0, -9472, 9216, -2816, 3840, -9728, 10496, -4864, -7936, 11776, -3072, -6400, 2304, 12544, -17152, 12032, -12288, 13056, -7680, -3840, 5888, 4864, -11008, 2048, 4352, 1024, -2816, -7424, 13824, -12288, 9728, -7168, 2560, -2304, 9728, -12288, 6912, -12032, 14080, 768, -15104, 5632, 10496, -1280, -15104, 9728, 1280, 7936, -25856, 18432, 2816, -9216, -4608, 13824, -6400, -256, -7680, 13824, -7168, -8704, 15616, -6912, 3328, -11776, 14080, -5376, -2560, -5376, 13312, -8704, -2048, 7680, -5376, 5120, -2816, -5376, 5632, -512, -11776, 20224, -21504, 15360, -2304, 3328, -14592, 13056, 512, -4096, -9728, 8704, 3840, -5888, -1792, -1536, 13568, -9728, -5632, 7424, 5888, -16128, 16640, -8704, -5376, 8704, -1792, -4864, -2048, 6144, 3328, -2048, -16128, 28160, -14336, -2048, -9472, 20224, -14336, -768, -768, 15872, -14592, 4864, 2304, 2048, -5120, -7424, 6912, 3328, -7168, -4864, 20224, -20480, 14848, -7936, 6144, -4096, -8960, 11776, 0, -13312, 9216, 5376, -7424, 4096, -5888, 6656, -7424, 9728, -10752, 6656, -10496, 15360, -7424, -4096, -1024, 10752, 1792, -21760, 13568, 12032, -13824, -7424, 17152, -13568, 9984, -14848, 11520, -1280, 1280, -9472, 15616, -14336, 6912, 4352, -10240, 256, 3840, 4352, -11008, 4864, 1024, 7680, -12544, 3072, -256, 12544, -16384, -6912, 24576, -10496, -12032, 11520, 2048, -9728, 8960, -12800, 18944, -20736, 13824, -3584, 6144, -16384, 14592, -1280, -6400, -4864, 6912, 4096, -6912, 1024, 4096, 512, -6400, 6656, -7936, 5632, -8960, 14336, -13824, 0, 14080, -5888, -7424, 2304, 9728, -9728, 3072, -10496, 18944, -7168, -7424, -768, 15616, -18176, 9216, -8192, 11008, -4864, -3584, 5376, 0, -2560, -4864, 8192, -10752, 5120, 2816, 5888, -24064, 27392, -3328, -13568, 1280, 8960, -4352, -2816, -6400, 8192, 10240, -19456, 7424, 8192, -2304, -16640, 20480, -10752, 1536, -5632, 10752, -6912, -512, 2560, -512, 3328, -10496, 8192, 2560, -4352, -6656, 13568, -12800, 10240, -10752, 7680, -4864, 10496, -12800, 8448, -5120, -256, 10240, -17152, 2048, 7424, 3840, -14848, 6400, 8192, 3840, -20736, 11776, 3584, -2048, -13056, 6144, 10240, -11264, 4352, 2560, 512, -6656, 12032, -17408, 12544, -12544, 12800, -6912, -768, -5120, 21504, -15872, -8192, 13312, 3072, -13312, 0, 10752, -7680, 6144, -12032, 11520, -4096, 2816, -13056, 18944, -12032, -2304, 11520, -4864, -4608, -1280, 10496, -9984, 2816, -8448, 14336, -5120, -3584, -2048, 16384, -21760, 15360, -5888, -3328, -768, 8448, -5120, -6400, 14592, -8704, 512, -5888, 10752, -5376, 768, -12544, 21760, -8960, -6912, 256, 13824, -8704, -7936, 6144, 3840, 1536, -11520, 13824, -7680, 3072, -6912, 10240, -15616, 9984, 256, -1280, -4608, 4352, 3584, 1792, -8448, -6912, 21248, -11264, -10240, 5376, 16896, -20992, 8192, -1792, 8448, -13824, 6912, 768, 512, -3328, -3840, 13312, -14592, 3584, 3584, -1536, -6912, 13824, -11520, 5888, -2816, 4096, -6912, 6912, -8448, -768, 9216, -11776, 12032, -3840, -2048, -1792, 17152, -23808, 3072, 8704, 4352, -18688, 8192, 3840, 7424, -11264, -4352, 12032, 512, -10240, -7936, 20736, -11008, 768, -6144, 13312, -8192, 1024, 256, 5120, -12288, 5120, 10240, -17408, 5888, 3584, 4864, -16384, 11776, -2048, 4352, -12288, 14080, -7424, 5888, -15104, 12288, -512, -6912, 2816, 256, 5376, -7680, 6400, -6144, 7424, -10496, 5376, 0, -3840, -4352, 16384, -12032, 256, 7936, -5632, 512, -2816, 5632, -14336, 17664, -13568, 8192, -7680, 7936, -4096, 8192, -17408, 7424, 10752, -9984, -12544, 20480, 4352, -18944, 4352, 0, 14080, -22528, 6400, 7424, 3584, -18432, 14336, 0, 0, -8448, 5120, 1280, -8704, 8960, -8448, 11520, -9472, 5888, -2304, 2560, -13824, 17152, -5632, -3328, -3840, 10496, -3584, -4096, 2048, 0, 4864, -13056, 14336, -13056, 9984, -5120, 4864, -8704, 6656, -4608, 4864, -7936, 5888, 0, 3072, -7936, 1792, 11520, -16640, 5632, 1024, 6144, -18688, 18944, -3328, -8704, 4608, 5888, -4096, -6400, -512, 10240, 1280, -21504, 19456, -1024, 1536, -18944, 19200, -1792, -2560, -13056, 15360, -3328, 0, -11520, 12800, 4608, -14592, 5120, 5376, -1792, -6656, 12032, -13056, 7168, -4864, 3072, -3328, 768, -256, 5120, -5888, 256, 7168, -4608, 768, -10496, 17152, -18432, 8704, -2816, 8448, -12032, 12032, -2304, -5120, -512, 7168, -5376, -6912, 2816, 6656, -3840, -6400, 14592, -11264, 11776, -17152, 12544, -1280, -7680, 256, 10752, -9216, -2304, 5632, 1792, -3328, -8704, 17152, -7424, -4096, -6656, 21504, -12544, -5376, -2816, 19712, -13568, -11008, 15872, 0, -768, -8192, 5888, 3328, -1280, -17664, 22528, -10752, 1792, -4352, 9472, -8960, 6912, -1536, -3328, -2816, 7936, -4352, -7168, 11520, -4352, 2048, -8192, 10496, -12288, 9984, -8960, 10496, -4096, -7168, 10496, -768, -3328, -6656, 5888, 3072, -5632, -12800, 26624, -14592, 2304, -7168, 17152, -13568, -1792, 0, 11520, -10496, -5632, 12800, -2048, -5376, -2304, 9728, -4864, -4608, -512, 14080, -19456, 9728, -3072, 9984, -12544, -3584, 16384, -6144, -11520, 6400, 12800, -16896, 5888, -3840, 8192, -9216, 8192, -11776, 11264, -3584, 512, -4096, 5632, -1792, -2816, 3584, -7168, 5376, 1024, -2560, -4608, 16128, -16896, 7680, -5120, 9216, -8960, -4096, 6656, 3072, -9472, 1536, 12800, -8960, -3840, 1536, 12288, -16384, 1024, 3072, 11776, -21760, 8448, 3072, 6400, -12544, -2816, 19712, -13568, -4608, 4864, 7424, -10496, -256, 768, 9984, -17920, 14080, -1536, -256, -5888, 9728, -5632, -3072, 256, -2816, 9216, -9984, 1280, 3840, 8448, -14080, 8192, -2048, 1536, -9472, 9984, -8192, 1024, 6912, -5888, 2816, -256, 2560, -7168, 4864, -6144, 13312, -17664, 6912, 5376, 2816, -18432, 13312, 4352, -8960, -3328, 4096, 8448, -11264, 1024, 4864, 4608, -15360, 3328, 8960, 3072, -23808, 20992, 2304, -8960, -5120, 6656, 10240, -18944, 3584, 4608, 7168, -16896, 9472, 1024, 2304, -11008, 8704, -3840, 4352, -8960, 9728, -2816, -3584, 3584, -1280, 512, -9216, 13824, -8960, 512, 256, 7424, -8960, 2304, -1024, 6144, -8192, -1280, 7936, -4864, -4352, 7168, 8704, -22016, 12544, 3328, -4096, -13312, 18176, -7424, 768, -7680, 13056, -256, -9216, 1536, 6400, 1024, -19200, 14336, 2560, -5376, -4608, 9472, -4096, 4352, -13568, 15360, -1792, -9728, -2304, 16128, -4608, -17920, 17152, 256, -4864, -8192, 12800, -5120, 2816, -5888, 6144, -2560, -768, -5376, 8192, -6656, 1792, 3072, -4864, 8960, -7424, 6656, -10496, 8192, -5632, 3584, -11008, 10496, 1792, -4096, -6144, 14592, -5120, -8960, 6400, 1792, -2816, -5120, 7936, -4608, 2560, -8704, 11264, -1792, -5632, -2304, 12544, -8448, -4608, 6656, -1024, 3072, -16128, 13056, 2816, -4096, -10240, 20480, -7168, -9472, 1280, 15616, -19968, 5632, 4096, -768, -2560, -1280, 6656, -2048, -512, -11008, 17408, -10752, -6144, 9984, 2816, -7936, 3840, -2304, 4608, -5120, -256, 1792, -4352, 6656, -7680, 7936, -7936, 10752, -7168, -256, -3840, 12544, -13056, -512, 6656, 768, -3072, -2816, 1792, 5632, -2304, -13056, 17920, -6912, -3584, -3328, 13568, -9472, -3072, 2304, 11264, -14592, -3584, 13056, -1536, -6912, -2560, 15360, -14080, 512, 3584, 4608, -11520, 8192, -4864, 7424, -6912, -3072, 7936, 3584, -13824, 4352, 10496, -15872, 13056, -10240, 10240, -10240, 3072, -2048, 7168, -9984, 4096, 2560, 2560, -11776, 9472, 3072, -10752, 4352, -1024, 512, -4352, 8960, -8704, 9728, -7680, 5376, -1536, -9216, 9216, 3328, -14336, 3584, 13568, -9216, -3328, -256, 15616, -16384, 1792, -768, 13824, -16128, 1280, 3584, 8704, -17152, 2560, 11776, -6912, -4608, 6656, 5120, -10496, 3584, -3328, 10240, -16896, 5120, 9728, -8704, -2816, 9984, -4096, 2816, -6656, 1792, 7168, -14848, 6656, 0, 7680, -15616, 11264, 2816, -7680, -4352, 16896, -10240, -8448, 8960, 1536, -5376, -512, 2304, 4096, -3328, -9984, 20224, -18176, 6912, 2304, -2304, -7424, 7168, 1024, -4352, 256, 3584, 512, -5120, -512, 4096, 6144, -17152, 5120, 9472, -1024, -20480, 19200, 4608, -11776, 512, 2560, 6400, -7936, -7168, 11008, 4864, -19200, 15104, -3328, 3584, -10240, 7424, 1792, -5632, -5120, 11264, -5120, -4096, 2560, 8192, -5376, -10752, 15616, -4864, -7424, 3072, 9984, -14080, 8192, -1024, 0, -512, -6144, 10240, -4864, -9728, 8704, 5632, -8448, 2816, -768, 7936, -12544, 5376, -4096, 10240, -13824, 3072, 7424, -4864, -2048, 4352, 4352, -13312, 7168, 5632, -9984, -512, 11520, -10752, 5888, -11776, 13056, 2816, -17408, 6656, 14080, -8704, -11264, 11520, 2304, -4864, -11008, 14592, -4096, -1280, -2304, 10240, -6144, -3072, 2048, 7424, -13824, -1024, 12800, -9472, 0, 2816, 1792, -1024, 0, -6400, 14592, -15872, 4864, 4608, -1792, -5632, 3072, 4864, -6912, 2304, -1280, 3840, -4864, 512, 3840, 1024, -11520, 9216, -1280, 2048, -12288, 15360, -3328, -8960, 9216, -4864, 5376, -6144, -1792, 5888, -6144, -5632, 18688, -14848, -1280, 8704, 6400, -18176, 4864, 7680, 0, -11008, -1024, 12800, -2304, -5376, -5376, 17664, -7168, -11776, 6144, 7424, -11520, 3072, 768, 5376, -3328, -7168, 12032, -2304, -9472, 5376, 5632, -11776, 5376, 2048, -256, -8192, 10752, -5632, 3584, -6912, 4864, 4096, -7424, 768, 4352, -256, -9984, 7168, 5376, -10752, 2048, 12032, -11520, 512, -4096, 12800, -5120, -13824, 12800, 2304, -6400, -3072, 10496, -7424, 2048, -768, -1280, -3328, 6400, -4096, 4864, -7680, 3840, 3840, -512, -13312, 9728, 9728, -17664, 3072, 9472, 2304, -13824, 2560, 9216, 1280, -20224, 6912, 14592, -8960, -10240, 12288, 5376, -10496, 3328, -768, 2560, -7424, 1024, 4608, 1024, -12800, 13312, 256, -7168, -1536, 10496, -6400, -5632, 8704, -5632, 2560, -1280, 768, -1536, -256, 512, 6656, -12288, 6144, 3072, 1280, -13824, 9216, 4608, -8192, -1536, -768, 12288, -7168, -5376, 5632, 8960, -16128, 1536, 11008, -7168, -6912, 10752, -1792, -5632, 1536, 5376, 2048, -14336, 7936, 5888, -2560, -18688, 19456, 4608, -12544, -6656, 17920, -5376, -5888, -2048, 8960, 0, -10752, 1792, 10752, -6656, -7168, 12032, -7936, 0, 3328, 2816, -6400, 3584, -1536, 2560, -3328, -6656, 10240, -3584, -1280, -2048, 10752, -9216, 256, 3840, -2560, -8704, 12032, -6144, 1280, -5632, 9728, 3584, -9984, -2560, 13568, -6656, -17152, 18432, 0, -3840, -6400, 7424, 4864, -7424, -6400, 12800, -3584, -7936, 2560, 10752, -11264, -6144, 20736, -10240, -8192, 3072, 11520, -10496, -1280, -256, 12032, -6912, -13824, 13824, 8192, -16384, 1024, 6656, 256, -256, -10496, 11264, 1024, -5632, -5632, 12032, -7680, 1792, 1280, 768, -9472, 11520, 256, -13568, 11264, -256, -5120, 1792, 3072, -3328, 2304, -5888, 6656, -512, -12032, 8192, 9472, -15616, 1536, 10752, 0, -6400, -11008, 19456, -5888, -9728, -2560, 18688, -6144, -14592, 12032, 11520, -17920, 768, 4864, 1792, -4864, -2048, 2560, 6144, -3072, -9216, 16896, -15360, -256, 12800, -8192, -4864, 2048, 6656, 512, -11264, 2816, 13568, -10752, -6656, 5120, 10752, -13312, 3584, 4096, -6656, -2816, 10752, -10496, 4096, 4096, -5888, 3328, 256, -1536, 4352, -4608, -10496, 18176, -9984, -5888, 10240, 3328, -7680, 512, 4864, 0, -9984, 2560, 6144, -3840, -6400, 3072, 16896, -20736, 1536, 12032, 2304, -17664, 3072, 12032, -2304, -9216, -6912, 19456, 2304, -27392, 14848, 13568, -17408, 4864, -2560, 9984, -12544, 2048, 3584, -2816, -4352, 5376, 4608, -6400, -4352, 12032, -1024, -12288, 8192, -2304, -1024, -768, 2048, -1280, 7424, -10240, 3328, 3584, -7936, 6144, 1792, -12288, 6912, 9472, -15616, 5632, 3840, 1792, -11776, 4352, 2560, 5632, -11520, -2304, 14336, 256, -18688, 11008, 8704, -13056, -3840, 10240, 512, -12032, 8960, 2048, 6912, -22272, 7936, 22016, -24064, -6912, 17152, 2560, -11264, -3840, 11008, 2816, -11776, 1536, 2304, 8448, -18176, 8960, 6656, -7680, -4608, 9472, -4608, -2304, 5120, -3840, 256, 1280, 2304, -512, -5888, -2816, 12800, -10752, -768, 6144, 1536, -5376, 4352, -1280, -2048, 2816, -6656, 6144, -4864, -2304, 8448, 5632, -19968, 9728, 11264, -12288, -13568, 20480, 1536, -16896, 3584, 9216, 2048, -9472, -3840, 16896, -6144, -19200, 22272, -3584, -6912, -2560, 11520, -3072, -9728, 3328, 8448, 1792, -17152, 5120, 19200, -14080, -17152, 21760, 2048, -13312, -2816, 11520, -2560, 3328, -8704, 3072, 6656, -9216, 1792, -256, -256, -1792, 5888, -6912, 4608, 3840, -3072, -7168, 6912, -1536, 2304, -13312, 10240, 6656, -12800, 768, 13056, -2560, -18176, 17152, 2560, -15104, 1024, 14336, -6912, -5120, -4864, 14848, 1536, -20736, 9728, 12544, -9984, -9984, 12032, 3584, -6400, -10240, 13824, -512, -5120, -9728, 20992, -6400, -13056, 11264, 6144, -15360, 2048, 13056, -12032, -512, 1536, 5632, 2304, -8704, -5120, 19968, -14336, -6400, 9216, 4864, -12544, 4352, 8192, -12800, 11264, -7424, 1024, -2816, 3584, 768, -3328, -2816, 4864, 3328, -6144, 7168, -8192, 8448, -9472, 9984, -15616, 30464, -19456, 30720, -17920, 25344, -31232, 22784, -28928, 23296, -31488, 31232, -31488, 19712, 22016, -29696, 1536, -30208, 31488, -5888, 16384, -23808, 4352, 6144, -32000, 31744, -32000, 31744, -6144, -3072, 14336, 22272, -13824, 9728, -23296, 16384, -512, -10496, 32256, -32512, 5120, 2048, -12288, -15872, 32512, -32768, 22528, -11008, -4608, 22016, -25600, 11264, -8192, -6656, 18176, -3328, 1536, 13056, -8448, -12800, 27136, -15104, 8448, 1280, -5120, 17664, -14336, 13824, -12288, -1536, 9728, -1280, -9728, 8960, -256, 3072, -256, 1024, 5888, -14336, 4864, -1792, 1280, -1024, 7936, -9728, 768, -3072, -2304, -6400, -1792, 6144, -8192, 4352, -5376, -5632, 6144, -5120, 1536, -4608, 0, -3840, 1280, -4096, 3840, 768, 512, -2560, 768, 6912, -7936, 9472, -3072, 8192, -1280, 512, -5376, 6912, -3584, 5120, -2048, 1280, 3840, -1792, -2816, 5120, -9472, 1792, -5888, 4352, -5632, 2816, -3584, 2048, -11264, 9984, -13312, 6656, 768, 3584, -2560, 13056, -11520, 7424, -4864, 4864, -768, 10496, -5376, 11776, -5888, 2560, 4096, -6400, 768, 1792, -7680, 4864, -2304, -1280, -256, 256, -4864, 256, -6144, -5888, 13056, -12288, -2560, 4352, -8704, -9728, 15360, -18176, 6656, -11008, 16640, -15104, 17920, -6656, 15616, -13056, 16128, -13056, 10752, -6400, 14848, -9216, 7936, 2560, -3584, -2304, 2048, -4608, 2048, 1024, 2048, 1792, 7936, -13312, 9984, -13568, 13568, -14336, 6144, 2816, 256, -5120, -2048, -8192, -4608, -2560, -6400, 1024, 256, 9472, -9472, 10752, -10752, 13568, -14592, 13312, -4608, 7680, 2816, 5120, -13312, 14080, -15616, 14336, -12800, 6144, -6656, 9728, -10752, 9216, -256, -11008, 14848, -11776, 1536, 4608, -8960, 7936, -9216, 7168, -14080, 14080, -25088, 13312, -10496, 6656, -6144, 12288, -7936, 12288, -6656, 7680, 4864, -4352, 5888, -2048, 3328, 3840, 4864, -1792, -5888, 10496, -9216, 5120, -9984, 16640, -16384, 16896, -9728, -2304, 1792, -3584, -2560, -768, 1536, 3840, -4864, -10240, 13568, -17152, -2816, -3072, -6400, 5888, -2816, -3072, 11776, -12288, 9984, -5120, 5120, -3584, 7936, -13824, 18176, -6400, 512, -2048, -1280, -2304, 256, 1792, 6912, 4352, -3584, 11008, -7936, 6912, 2816, -8448, 5120, -512, -8448, 11520, -9728, 4352, -2304, -2816, -4352, -5632, -4864, 5120, -6400, 1024, 7424, -8960, 3584, -4352, 256, -1792, 4864, 512, 4096, 8192, -768, -4352, 1024, 0, -2304, 4352, 1280, -2048, 13312, -8192, 10240, -9984, -1280, -4608, 3584, -5376, 7936, 2560, -4352, 2048, -8704, -1792, 256, -11264, 1792, 2560, -2048, -1536, -4608, -6400, -256, -4864, 4096, -7424, 15872, 1536, 2304, 5376, 0, -3584, 1024, 1280, 5120, 3328, 6912, -256, 4608, -1280, 5376, -7936, 2816, 512, -2304, -1024, 5376, -6912, 2048, -5376, -7168, -4864, 3584, -3072, 1280, -5120, 5120, -9216, 1024, -4608, -6912, -1024, -1024, 3840, 1024, 12288, -1792, -2816, 5120, -1536, 1792, 5120, 256, 5120, 0, 8960, -8960, 7168, -9472, 1792, -11008, 5376, -5632, 5888, -4608, 3072, -5632, -3328, -5120, -2816, 1792, 5888, -2560, 4864, -4608, 4352, -10496, 1024, -4096, -2048, 5376, 2816, -1024, 2560, 7680, -6144, 8192, -3840, 3840, -3328, 7168, -1280, 9728, -2560, 0, -5632, -3328, -3072, 6144, -4608, 7680, -1792, 1024, -4096, 6912, -7168, -768, -256, 4608, -3584, 7936, -6144, -768, -3328, -4864, -9216, -512, -7936, 2304, -512, -3072, 4352, 3072, -12800, 11776, -12544, 11008, -3840, 3328, 5632, 3840, -6400, 2560, -2048, -1536, 3584, -512, 6144, 3840, 2304, 4352, -3328, 1280, 3584, -3840, 1792, 5120, 1024, 1024, 4608, -4096, 768, -12032, 7936, -11776, 4864, -6144, 1280, -4864, -256, -10752, 3584, -11264, 4608, -1792, -256, 3840, 2304, -8960, 8192, -11264, 9984, -11776, 5888, -4096, 9216, -6400, 11520, -8704, 8192, -2048, 2560, 1280, 7168, 0, 3072, 2816, 768, 5120, -5888, 1536, -2048, 4096, 1792, 4352, -4864, 8192, -11264, 768, -2048, -5376, -2048, -1280, 512, -7424, 512, -768, -4864, -3584, 768, 1792, -5888, 2560, 256, 768, 2048, 3328, -11264, 5120, 5376, -4096, 5888, 768, 1280, 2560, -2816, 8192, -2816, 3328, -1792, 7680, 1024, 4096, -1792, -1536, -1792, 3584, -10240, 1024, -4096, -6656, 768, -256, 0, -1536, 1280, -12800, 9472, -6912, 4608, -4096, -3584, 1536, -256, -1024, -3840, 2048, -3072, 3584, 2304, -5632, 10752, -2560, 5888, -2816, 9216, -3840, 3328, 7680, 256, 12032, -5120, 8448, -3584, -3072, 256, -5120, -2304, -2304, -2816, -3328, 1792, -9472, 6400, -12032, 3584, -3328, 1024, -3072, 2304, -8192, 4608, -12288, -256, -8960, -256, -1792, 8960, -5120, 13568, -1024, 8704, -1792, 3328, 4864, 2304, 7680, 1536, 11520, -5632, 5888, -4608, -1536, -256, 768, -7680, 3584, -3840, 2304, -9984, 2560, -8448, -3328, -6144, 2560, 3584, 3584, -2560, 512, -8704, -1024, -5120, -5376, -3584, 10240, -2560, 4352, -3584, 7168, -4352, 9472, -6656, 17664, -3840, 9728, 512, 5376, -6400, 9472, -15616, 3328, -2304, 1280, -4352, 4608, -10496, 5632, -14592, -256, -2304, -3328, 6144, -2560, 9728, -1280, 2048, -4096, -512, 256, 3072, -6400, -512, -3328, 512, 512, -4096, -4864, 8192, -7680, 5632, 5120, -1024, 3072, 2816, -4352, 4864, -4352, -768, 5120, -8448, 16640, -6912, 8192, -3584, 2048, -2048, 3328, -4864, 2304, -512, 1792, 8448, -10240, 4608, -4608, -4608, 1536, -5888, -2816, -2816, -7168, 1024, -2816, -3840, -3584, -2048, -1280, 8704, -1536, 4864, 256, -768, 2304, -256, 1280, 1280, 3584, -2816, 10240, -768, 4608, -5120, 4096, -1792, 512, -1280, 2304, -4096, 2304, -4352, 0, -4352, 1024, -4352, -768, 768, 2048, -3584, -4864, 3072, -5376, -1792, 256, -512, -2048, 4096, 768, -1536, 8960, -5888, 8448, -3328, 2816, 3072, 768, -1792, 6656, -2816, 4864, -4608, 5888, -5632, 9984, -12544, 9984, -12800, 2816, -9728, 6656, -7424, 2560, -1536, -5632, 3840, -2048, 3840, -9472, 9216, -11008, 9984, -11008, 4608, -6656, 256, 2816, 1024, -512, 2304, 1792, 512, 1792, 4864, 256, 256, -1024, 4096, -1280, 4096, -2304, -768, 1024, -1024, -256, -4352, 0, 2816, 4096, -6912, 3072, -3840, 3840, -768, 0, 2560, -768, -1280, 3072, -3328, -1792, -3328, -7936, -256, -768, -4352, 3840, -7936, 6400, -2560, 3840, -256, 512, 1024, 2560, 1792, 8192, -3328, 1792, -5632, 512, -2560, 4096, 256, -3840, 4864, -6144, 4096, -4608, -3072, 4608, -2304, 2304, 6144, -2048, 2048, 2816, 0, -7936, 4352, -14080, 5376, -11008, 10240, -10240, 7424, -13824, 11264, -8704, 5632, 2816, 4096, 1792, 4864, 5376, -1536, 512, -1792, -4096, 5632, 0, -256, -1024, 1280, -2048, 6656, -10752, 1024, -1536, -5376, 8960, -4096, 2048, 0, -5632, -3328, 2816, -7936, 1792, -7168, 1024, 4352, -3072, -4608, -512, -5888, 5888, -256, 4864, 8704, 1792, 1792, 8960, -4864, 2816, -2048, -4352, 2048, 1024, 4096, -4096, -3328, 2304, -3840, -1280, -256, -1536, 1792, 768, 2816, 256, -1792, -6144, 5376, -7936, 9216, -768, -2560, 2048, 512, -4352, 3072, -6144, 1536, -768, 2304, 3840, 768, 3328, -2048, -3328, -768, 1536, -4864, 3584, -8448, 4096, -4352, -1280, -7936, 768, -7424, 6144, -1792, -1536, 8960, -5120, -1280, 8704, -5120, 6400, -768, 2560, 6400, 2048, 3584, -3328, 0, 256, 4352, -8448, 13056, -9728, 11520, -8192, 9984, -768, -512, -6144, 768, -4608, 3584, -1024, -11264, 512, -6400, -3840, -512, -5888, 768, -512, -512, 5120, -3584, 2048, -2560, -1024, 5376, 2816, -3328, 8192, -1024, 2048, 4864, -4096, -512, -512, -512, 3584, -512, -256, 6912, -6656, 5120, 2816, -3328, 2560, -768, -1792, 3072, -3328, -768, -7680, -4096, 2560, -6656, -768, -2560, -512, -2304, 3840, -4352, 256, -512, -1792, 3584, -2048, 3072, -768, -256, 512, 12032, -6656, 5632, -4864, 4096, 512, 3328, -768, 5376, -2560, 5632, -8192, 11008, -6144, 4096, 0, 1280, -512, 3072, -11264, -3072, 256, -6656, 256, -9216, 1280, 512, 2304, -4352, 5120, -9472, 3584, -2304, -1280, 1536, -768, -3328, 5888, -4864, 6400, -8448, 1536, 4352, 2560, 4864, 3840, -1024, 3072, 1280, -2304, 8448, -5120, 6656, -2304, 2816, -512, 2816, -5376, -1792, -3328, -1024, -2048, -3072, 0, -2560, -2304, 2048, -8448, 2304, -6656, 2048, 1536, -2048, 3072, 1792, -2048, 0, 1792, -4096, 6400, -2048, 6912, 3072, 0, 2304, -2304, 1024, -4352, 3584, -4096, 2816, -2048, 4608, -512, 1024, 512, -5120, -4608, 5632, -4096, -1280, 768, -6144, 3328, -2560, -3072, -2560, 512, -4096, 8448, -3840, 5376, -3840, -1024, -4864, 7424, -5632, 4608, 512, 5120, 3072, 4608, -5632, -1792, -4096, 1792, -4864, 3584, 256, -4352, 8448, -5632, 9728, -2048, 768, -768, 5376, -4352, 13056, -11008, 3840, -5632, -5888, -1536, -3072, -3584, 3584, 2304, 1536, 1024, -7936, 768, -4096, -3584, 5632, -5632, 1280, 3328, -6400, 4352, -512, -4608, 1792, 256, 1280, 9216, -4096, 5888, 1024, -3840, 7424, -5120, 2560, 256, 6144, 4352, 4096, -1024, -4096, -9472, -2816, 256, -8448, 6912, -9216, 4352, -5632, 512, -8448, 4096, -7424, 8192, -1792, 6144, -3072, 3584, -3072, 5632, -4096, 3840, -5120, 4864, 2304, 3584, 3072, -256, -6144, 3328, -1536, -256, 8192, -4864, 6144, 3072, -6656, 1024, -7936, -9728, 4608, -4096, -3328, 768, -3584, -256, 2816, -3840, 3840, 0, -512, 7680, -1536, 8960, -5888, 2560, -8960, 1280, -3584, 4352, -5376, 5120, 1024, 1792, 2048, -1280, -3840, 5120, -6400, 6656, 1536, -768, 768, 1280, -6144, 6656, -8960, 1024, 0, -1536, 3328, -5888, 2048, -6400, 256, -512, 2304, 768, 4352, 1024, 0, 3328, -3840, 768, -5376, -4096, 1024, -1280, -2560, 2816, -512, 1792, 5888, -5632, 6400, -4864, 4608, 6400, -2304, 3584, -5376, -1792, 2816, -6144, 5632, -3072, -1792, 1536, 2304, -8448, 2816, -5120, 512, -2304, 512, 768, -3328, 3072, -3840, 5888, -5376, 4096, -4096, -512, 2048, 3328, -3072, 4608, -2560, 4096, -3072, 5120, -4608, 4608, -256, 5376, -5376, 5120, -7680, -1536, 2560, -512, 3328, -1536, -3840, 1536, 512, -256, 256, -4864, 2304, -3840, -768, -2816, 0, -1280, 256, 1280, 256, -1024, -2048, 256, -4096, 5888, 0, -5888, 512, 2048, -1536, 9728, -1024, 512, 3328, -4352, 7936, -1024, -2048, 5632, -3584, 0, 3072, -5632, 1792, -1792, 2816, 1024, -1024, -3072, -2304, -5632, 512, -4352, -4352, -2816, 1792, -4352, 4864, -6144, 2304, -2048, -1536, 7424, -1024, 2560, 1024, 1024, 5888, -256, 2304, -1536, -3072, 5888, 4096, -1536, 8448, -7424, 3072, -1792, -2560, 4352, -1024, -4608, 5376, 0, -3584, -512, -5120, -5376, 2560, -7168, 1280, -4608, -1024, 0, -2816, 256, 1280, -4352, 768, 2304, 5120, 1536, 256, -1792, 512, -1792, 768, 2304, -5632, 7424, 1536, -256, 6400, -2560, 1536, -256, 1024, 3072, 4608, -3328, 7168, -2816, 1536, -3840, -3584, -5632, -1792, 1280, -3584, 256, -4096, -3072, -1280, 1280, -2304, 1024, -256, -3584, 5376, -2560, -1280, 0, -4352, -1792, 512, -2560, 1536, 2816, 256, 9472, -4352, 1536, 5376, -6144, 10496, 512, 5888, 0, 2560, -4608, 4096, -6656, 3584, -5376, -4864, 4608, -2304, -3584, -256, -2304, -3584, -768, -1792, -2560, 1792, -1792, 4864, -2816, 3840, -6400, -768, -1536, 512, 2048, -2560, 1024, 3072, -768, 2816, -512, -512, 1280, 7936, -2304, 9984, -5376, 3584, -5888, 4608, -4096, -256, -768, -1536, 0, 5632, -2304, -1280, -4352, -1024, -3072, 512, -768, -1792, 2560, -2560, 1792, -5120, -4864, -2560, 0, -3584, 8192, -3840, -4608, 3328, -2304, 512, 4352, -3584, 1536, 9216, -2304, 7168, 256, 0, 4352, -2560, 1280, 4352, -2048, 3072, -512, 768, 512, -5632, -1536, -3584, 1536, 2048, -2816, -3584, 512, -5888, 6400, -8960, 768, -4608, 256, -3584, 5632, -256, -3072, -1792, -2304, 3328, -1024, 3072, 1024, -768, 4608, 0, 256, 2048, -3584, 3584, -512, 256, 4352, -768, -3584, 8960, -4352, 4864, -3584, -1536, 256, -2304, 4608, -4352, -1024, -3328, -512, -3584, 2560, -2560, -1536, 0, 768, 1280, -3072, -3328, -768, -1536, -1536, 2816, -3328, -1792, 3328, -512, 1536, 3328, -1792, 2816, -1280, 5888, 256, 7424, -4352, 5888, -2560, 4608, -4096, 3072, -5120, 2560, 1792, -2304, -1280, -5376, -2304, 1280, -3328, -512, 0, -3840, -2816, 768, 0, -4608, 1280, -6400, -512, 768, -512, -768, 1024, 2048, 3584, -1792, 3840, 1024, 2048, 4864, 2304, 2816, 1792, -768, 3584, -2816, 256, 3840, -8960, 768, 768, -2560, -4096, 0, -3840, 512, 768, -3072, 6912, -5888, 8192, -3840, 2560, -3584, 768, -6912, 2560, -3840, 3072, -6144, 1792, 512, 2304, -512, -512, -256, 768, 256, 256, 2048, -1024, 0, 1536, -1536, 256, 256, -256, 2048, -2816, 7936, -6912, 3328, 1024, -768, 1280, -256, 0, 512, 2304, 0, 3072, -7936, 1024, -6912, 256, -6400, 5120, -5376, -3584, 3072, -3584, 0, -1280, -5888, 4608, -256, 3840, 4864, -1280, 5120, -2048, 3584, -1792, 4096, 768, 0, 2048, 2560, 0, -2048, -2560, 768, -2048, 2304, -3072, 1024, 3840, -1536, 512, -3072, -7424, -768, -4096, -2816, 8960, -4608, -256, -7168, 1792, -3072, 0, 1792, -1280, 5632, 2560, 2560, -1024, 1536, -3328, 5376, -5888, 5120, 2048, -3328, 2816, 3840, -1536, -1536, -5632, -256, 768, 3584, 1792, 2816, -6912, 3072, -4352, -3072, 2048, -3840, 768, -2048, 3072, -3072, 1280, -7680, 3072, -4608, 2304, -512, 768, 1024, 3840, 256, 1280, -2304, 0, -2048, 6144, -512, 5376, 1280, -1024, -1024, 3584, -3840, 0, -256, 768, 4352, -1280, 3328, -4864, -2560, -1024, -1536, -1024, -1792, 4608, -6912, 2048, 256, -3072, -5376, -3328, 256, -2304, 2816, 256, -768, -256, 5632, -5376, 2304, 1536, -768, 5120, -512, 4352, 1792, -3072, 256, 1024, 1024, -2304, 2304, -5120, 6144, 1792, -2304, -768, -1792, -1536, 2560, 1792, 768, 2304, -512, -768, -1024, 256, -4864, -2048, -4096, 0, -3072, 0, -6400, 1024, -5632, 2560, -2304, 0, -768, 3840, -256, 2048, 2816, -3840, 2560, 3328, 256, 5632, -1280, 3840, 256, 6144, 1536, 0, -1536, 1280, 1280, 2560, 2048, -256, -2816, -3584, 768, -7936, 512, -5632, -1024, -2048, -3840, -512, -7936, -3072, 1536, -1792, 1280, 512, 768, -1024, 4864, 768, 1024, 1792, 1792, -2048, 7936, -1536, 6656, 256, -512, 512, -768, -2560, -1024, -1024, 2304, 768, 3072, -4096, 4096, -2304, -256, 1280, 1024, -1792, 3328, -4352, 0, -2816, -3328, -5632, 256, -2304, 1024, -1792, 1792, -2560, 1280, -256, -1536, -768, -5376, 1792, -2560, 4608, -768, 256, -1792, -2816, 2816, -2048, 3072, 5120, 768, 3328, 4096, -256, 768, 3328, -768, 5888, 4096, -768, 3840, -3584, 3072, -1536, -2048, -7168, 0, -8448, 1024, -2816, -3072, -3328, -5376, -4352, -4096, -1280, -3072, 4096, -1792, 3840, -1536, -1280, 768, -2304, 5376, 4352, 3328, 3584, 2816, 5376, -3072, 7936, -4608, 1792, 3072, 2048, 2304, 1792, 256, -768, -1792, -3584, 4352, -8960, -2560, -512, -4608, -2048, -2560, -5120, -5632, 512, -2560, -768, 256, -256, 1024, -1280, 2816, -5120, 2816, -1536, 6912, 1792, 4608, 2048, -256, 512, 768, 2816, -2304, 1280, 1280, -1792, 7424, -1536, 5120, -5376, 5888, -3840, 4864, -4864, 512, -5632, 2816, -6656, -1792, -2560, -7680, -256, -768, -1536, 3840, -5632, 4096, -1792, -2304, -512, -1792, -1280, 2816, 4352, -3328, 512, 2048, -1280, 1536, 6912, -1536, 3072, -1536, 1024, 3840, 768, 3584, -768, -3072, 2816, -512, 1536, 1280, 1024, -1536, -3072, 0, -8192, 512, -5632, 5632, -3072, -1280, -1792, -2816, -1792, 1536, -256, -768, -768, -4096, 512, -256, 0, 0, -1792, -512, 256, 3072, -1024, 1280, 5120, 256, 4096, -512, 3584, -256, 4864, 2048, 7424, -2048, 1792, -3584, -512, 768, -3328, 2048, -10240, 5632, -4608, 512, -3584, -2048, -2816, -2048, 3072, -5376, -256, -2560, -3072, -1536, -1024, -3584, 1536, -4864, 1792, 3584, 256, 2816, 2816, -2816, 6400, 256, 3584, -1280, 7936, 0, 5632, 1024, 256, 768, 1536, -768, 1024, -512, -5120, -1792, -6656, 256, -3072, -1792, -2560, 512, -256, -1280, -1792, -2048, -2560, 1536, -1792, -1536, 2560, -4352, 1536, 768, 3840, -2048, 3840, -1792, 3072, 256, 2304, -1024, -512, 2560, 2304, -256, 2560, -1024, 2304, -2048, 4352, 0, -3328, -1792, -512, -2816, 768, -512, -3840, -1024, -2816, -1280, -2304, 256, 2048, -2560, 2048, -2048, -1536, -4608, 5376, -4864, 6656, -4864, -256, -2816, 2560, 1024, 3072, -2560, 4096, -2560, 4352, 2048, 3328, -256, 4352, 256, 1280, -256, 2816, -2048, 2304, 4096, -4352, 768, -6656, -4352, -3584, 1536, -4352, 1024, -5120, 0, -256, -1536, -1024, 512, -3840, 3328, -768, -256, 0, -512, -2048, 2816, 1792, -768, -2048, 1280, 3584, -256, 7168, -4864, 3328, -1024, 2048, 256, 2816, 1792, 1536, -2048, -512, -3328, -2560, -5632, 1536, 2816, -256, -256, -1280, -3328, 4608, 768, -2560, 2304, -4352, -2048, 2304, -2304, 256, -4352, -1024, -4096, 4608, -1536, 3840, -2560, 4352, 1280, 0, -1280, 0, -2816, 3072, 3840, 1024, 2048, 1280, -1024, 0, -512, 768, -4352, -512, -256, 2816, -1536, -1792, 512, -8448, 5888, -1536, -256, -512, -512, -256, -2048, 768, -7424, -512, -8704, 4096, -768, 4096, 256, 2560, -3072, 5888, 0, -768, 4096, 3072, 4864, 5888, -256, 2048, -6656, 4096, -8192, 6656, -3328, 512, -2816, 1280, -256, -3840, -2304, -4096, 1792, -1536, 3584, -3840, 1280, -2560, -1792, -2304, -2304, 1536, -4352, 3328, 4608, -1280, -768, -1024, -1024, -4608, 7168, -1536, 3328, 4352, 6144, -512, 2304, -3584, 256, -2816, 1792, 4352, 256, -3840, 2560, -5888, -1024, -3072, 1280, -5120, 4352, -2560, 1536, 0, -2304, 1024, -2048, -3840, 1536, -4096, 1792, 2304, 768, 1536, -3072, -4352, 0, 1024, 3328, 5632, -1024, 2560, -2048, 1792, -3072, 1280, 1280, 256, 2816, 512, 2560, -768, -512, 768, -2560, -1280, -1792, -1024, -4608, 4352, -512, -3584, -4096, -1792, -2560, -768, 1536, -256, 3584, -2816, 3840, -4608, 512, -1536, 0, -256, 0, 5120, -4352, 256, 1536, 512, 1536, 3072, -768, 1792, 6400, -1280, 4352, -3584, 0, -1536, 0, -512, -1280, -256, -2560, 2048, 512, -2304, -4864, -1792, -4352, 1280, 768, -1792, 1024, -3840, -1280, 2304, -3072, -256, -1280, 768, -1280, 6656, -512, 768, -1024, 1280, 768, 1792, 2560, 1280, 1536, 1536, 6656, -4352, 0, -256, 768, -768, 2560, -1792, -1792, -2304, 2816, -4608, 0, -4096, -1536, -1280, 768, 1792, -3584, -3584, 0, -5376, 3584, -2048, -256, -3072, 512, 256, 512, -768, -256, -768, 4608, 1280, 1280, 2304, 3072, 1792, 4608, 2048, 1280, -6400, 4096, -3840, 4096, -1792, 2304, -5632, 256, 3584, -3328, -1280, 512, -1536, -2048, 3328, -4352, 1536, -4096, 256, -1280, -3584, -1536, -1536, -3840, -512, 2304, -2304, -4608, 3840, -4864, 3072, 1792, 1024, 2048, 3584, 3840, 1536, 2560, -768, 2304, -1792, 5888, -4352, 5376, -5120, 1792, 0, -2304, 2048, -2560, 256, 1024, 512, 768, -2304, -2304, -3840, -1536, -5376, -4096, -1536, 0, -2816, 4864, -2048, -2304, 1280, -1536, 0, 1280, 3584, 1792, 256, 3072, 2048, 1792, -1280, 3072, 2048, -1024, 4864, 1024, -1792, 512, 768, -3072, -2048, -256, 0, 1280, 1792, -1280, -2048, -5632, -2048, -5376, -512, -2304, 2560, -5120, 3328, -1536, 2048, -4352, -2304, -1536, 512, 1280, 2048, 1536, -768, 2560, -2304, -512, 3840, -1536, 5120, 1792, 2816, 2560, -768, -1024, -2048, 6400, -6400, 4608, -3072, 4352, -1536, 5120, -5632, -256, -4352, -2560, 1280, -2560, 2304, -3328, -2304, -1536, 2560, -6400, -1280, -512, -1280, 3328, 512, -1280, -2048, -2560, 2816, -6912, 2560, -1024, 2816, 0, 8448, -1024, 2560, -3584, 256, 3072, -512, 6912, -2048, 1536, 2816, 2304, -3072, -1024, -2560, -3328, 3072, 1280, 256, -2560, -3584, -3840, -2048, -1792, -2304, 768, -1280, 2560, 768, -2816, -3072, -3328, -768, -768, 768, 512, 2304, 4352, -1536, 6400, -768, -768, -2048, 4864, 768, 7680, -2560, 3072, -5632, 1792, -1280, -2560, -768, 5376, -2048, 3072, 1536, -1280, -3328, -3328, -2304, -2304, -256, -5888, 3328, -4352, 3840, -5632, -2816, -4608, 2048, -3584, 5120, 256, 1024, -1280, 768, 768, 1280, 2816, 256, 512, 6912, 256, 2560, -1792, -2048, -512, -512, 1792, -256, 4352, -1280, 6144, -1792, 1280, -2560, -5120, -1536, 1280, -1024, -1280, -256, -4608, -1280, -3584, -256, -5120, 256, 1792, -1792, 3072, -1024, -512, -1024, 512, 2048, 0, 1792, 256, 1536, -512, 4608, -1280, -1792, 1024, 768, -512, 3328, 1024, 0, 512, -768, 512, -2560, -1536, 256, -1536, 1536, -1792, -768, -5376, -512, -3072, 1280, -256, -2304, 1792, -768, 3328, 1280, 1280, -2048, 0, -2048, 4864, -1280, 3328, 3328, -1792, 768, 0, -2560, 0, -2048, 5120, -2048, 3328, -5120, -1280, -1792, 768, 1280, -1792, 512, -1280, -1024, -3584, 2816, -5888, -3328, 512, -256, 3072, 3328, 1280, -1536, 5888, -2304, 2304, -1536, -2304, 4608, -3328, 4096, -768, -1792, -4352, 768, -3328, 3072, -2304, 1024, 0, 0, 3328, -4608, -256, 768, -3328, 5120, -1280, 256, -5120, 3840, -5888, 4608, -1024, -2048, 1280, -1792, 4096, 1024, 1536, -768, 1792, -5376, 4864, -4352, -1792, 2304, 1280, 768, -1280, -768, -4096, -2304, 6400, -2304, 3072, -1280, 2560, -1280, 2304, -1024, -1536, -768, 1024, 2560, -512, 2816, -3072, -512, -3584, 2048, -5888, -1280, 0, -2048, 2304, -512, -2816, -768, -2304, 2304, 512, 512, 1024, -1280, 1792, 2816, -4096, 0, -1536, 1792, 1536, 6400, 1280, 1536, -1024, 768, 1024, 768, 512, -2048, -768, 1280, -256, -2816, -1024, -2304, -768, -3840, 2560, -3072, -1280, 2816, -1024, -1792, 1536, -7424, -1280, 1536, 2816, 768, 2304, -4608, 3328, -3584, 4864, -256, -512, 1024, 1280, 3072, 256, 1280, -2048, 768, 256, 5120, -1536, 512, 768, -4096, 2560, -2560, -4608, -2816, -1792, -1792, 2304, -1024, -2048, 2304, -3840, 3328, -3328, -768, -1792, 768, 2048, 2816, -1536, -4096, 256, -2048, 5120, 1024, 3840, -1280, -768, 2816, -1280, 1536, 0, -1280, 2560, 3328, 0, -1536, -2816, 0, 2816, -2816, 2560, -1792, -2048, 256, 4096, -2304, 512, -5632, -2304, 0, 1024, 1280, -3072, -5632, 512, -2048, -2048, 3584, -4096, 0, 3328, 0, 2304, -1792, 512, -256, 1792, 2048, -768, -768, 512, 3840, 1280, 2560, -1792, 3072, -1024, 5632, -1024, -768, -3072, -512, -3840, 2048, -512, -5632, 1792, -2560, 1280, 3072, -5120, -2304, -2816, -512, -3072, 512, -2304, 1280, -768, 2816, 1792, -2304, 1024, -1024, 6144, -1792, 5376, -3840, -768, 512, 3584, -256, 1280, 4608, -3072, 3328, 768, 1280, -2560, -2816, 0, -2048, -512, -1024, 512, -3840, 2304, -2560, -4096, -2304, -1792, 0, -256, 768, -2048, -2560, 1280, -2048, 1024, -768, 2048, -512, 5120, 256, 1536, -1024, -2304, 1024, 3584, 1792, -256, 768, -1280, 4608, -1792, 5120, -1536, -2560, 2048, 256, -512, 768, -1024, -1280, -768, -1536, 0, -4096, -1792, 3072, 0, -4352, 1024, -7936, -1792, 256, 256, -1024, 2048, -2816, 1536, -256, 2816, -1280, -1792, -1024, 512, 1024, 3840, -768, 5376, -1280, 5120, 768, -3072, 5376, -256, 2560, 1280, 1536, -5120, -256, -4608, 512, 768, -1024, -1280, -256, 1536, -512, -2816, -4352, -3840, -3328, 0, 1536, -4608, 1792, -4608, 1792, -1792, 1536, 1792, -2560, 4608, 4096, 512, -256, 768, -2816, 1536, 3584, 256, 3840, -512, 7424, -2048, 4352, -3584, 512, -4864, 3072, 2048, -1536, -256, -5888, 1536, -2816, 1792, -4864, -4608, 0, 256, -2048, -2048, -1024, -5120, 2048, -2048, 1024, 2560, -3072, 3328, 0, 4608, -2560, -768, -1024, 1536, 1024, 4352, 1792, -512, 4608, -2304, 3584, -2560, -1024, -2816, 1024, 768, 5888, -4352, -1536, -512, -1792, -1792, 2304, -2560, 256, 512, -1024, -3584, -1792, -1536, -2048, -1024, 1792, 512, -768, 768, 0, 3328, -2560, -1024, -2304, -1536, 4608, 2816, -1024, 4096, -2048, -1024, 256, -256, 1792, 768, 768, 768, 2560, -3840, -512, -2304, 2304, 0, 512, 512, -2304, 3072, -1792, 0, -5888, -1792, -4864, 512, -256, 0, 1024, -3840, 1792, 768, -768, 0, 2304, -3072, 4864, 1024, 2048, -3328, -1536, 1280, -256, 3584, 2560, 2304, 3328, -768, 4096, -4608, 3328, -4608, 1792, -2560, 3328, -1536, -2816, -768, 1792, -5888, -1536, -2816, -5376, 2304, -256, 1024, -768, -4096, 0, -3072, 1792, 3584, -1280, 3840, 0, 1536, -1280, -768, -2304, 2304, 1024, 2560, 1024, -512, -1792, 2560, -256, 2560, -1536, -3584, 3840, -1024, 3328, -1024, -1024, -3584, 1280, -512, 1024, -2304, 768, -3584, 512, 768, -2560, -256, -2304, 0, 768, -1536, 3072, -4096, 0, 1024, 2560, -6400, 1536, -1280, 512, 2048, 768, -512, -1024, 3840, 1024, 1792, 512, -256, -1536, 2560, 2816, 512, -512, -3584, 1536, -768, 0, -768, -2304, -2560, 256, -256, -3840, 2304, -7424, 2304, -2560, 1792, -768, -768, -2560, -512, 3584, 1024, -1536, 0, 256, 3072, 1024, 4608, -3840, 4864, 256, 3840, 256, 256, 768, -2560, 2048, -256, 1792, -7680, 2048, -4864, -512, -1280, -2304, -2560, 0, -256, 1536, -1024, -3072, 256, -4608, 2560, -256, -3072, 512, 1792, 3072, 2816, 0, -1024, -256, 1536, 2560, 4352, -2048, 256, -3072, 1280, -512, 256, -1792, -256, 1024, 768, -768, -256, -4608, 2048, -2304, 0, -512, 2048, -3072, 3072, 1792, -1280, -512, -4096, -1792, 2304, -1280, 2816, -2304, -1024, 768, 256, -2304, -256, -512, -1536, 1792, 3072, 0, -2048, 2304, -2560, 768, 0, 512, -768, 2816, 3584, 1024, 768, -3072, 768, -768, 512, 3072, -1024, -512, -512, 2304, -5376, -1280, -7168, -1536, -2560, 1536, 1792, -1536, -768, -6144, 1792, -2816, 2560, 0, 2048, 3328, 2560, 1536, -1792, -512, -1280, 1792, -256, 2304, 4608, -512, 3072, -1024, 1792, -6656, 3328, -1536, 4864, 1536, 1536, -1280, -4096, -1536, -2048, -4608, -512, 256, -2816, 768, 1024, -4096, -2048, -2560, -768, 512, -768, 1280, 1280, 0, 2816, 0, -3584, 0, 256, 3584, 2816, 3328, 0, -512, 1280, -256, -1024, -512, -1024, 1280, 5376, 768, 3584, -1280, -5632, 1280, -2816, -768, -1536, -768, -2816, 0, -1280, -3328, -2560, -4608, 768, 2304, -2560, 512, 768, -2816, 2816, -2816, 1280, -4864, 5888, -256, 5120, 4608, 1024, -768, -1536, 2304, 1024, -768, 2048, 1024, 1536, 512, 1280, -3584, -1536, -768, 512, -1536, -1024, -768, -2816, 0, -1280, 0, -5376, -512, -2560, 2816, 1280, -1024, -1280, -1280, -2048, 2560, -2560, 1024, -256, 1536, 3072, 2304, 512, 2048, -5120, 2048, -512, 2816, -2816, 256, -1024, 1280, 1536, -1536, 1536, -3584, 3584, 1024, -512, 3072, -768, -2560, 2048, -1280, -3840, -2304, -256, 1280, 2048, -768, 0, -5888, -2304, -2816, 1024, -3072, 768, -1024, 1024, 256, 3840, -3072, 768, 3328, 512, 1280, 2048, -2048, 1792, 2816, -768, 4352, -2816, 1280, 768, 4864, 3328, 768, -2816, -2816, -512, -2304, -1792, -1024, -6144, -256, -4352, -768, -4352, 0, -3840, 512, -256, -1280, -1024, 768, 512, 512, 2816, -1024, 768, -1536, 2816, 2048, 768, 1536, 768, 1792, 1792, 1536, -1536, 512, 0, 3584, 3584, 768, 2048, -1536, 1024, -768, 1536, -3328, -512, -2304, -1024, 1280, -3328, -1280, -5376, -256, -1536, -256, -1280, -3584, 2048, -1792, 1280, -1792, -4352, -2816, 1792, 768, 5120, 1792, 256, -768, 1024, 1280, 3584, -768, 1280, 768, 2560, 2048, 1536, -1536, -512, 1536, 768, 1792, -1536, -768, -768, -1536, -256, -6912, -2816, -4352, 0, 2816, 1792, 256, -1792, -2304, -3328, 1280, -2816, 0, -2560, 3840, 512, 1280, -512, -1280, 256, 1536, 1536, -1536, -1280, 1536, 512, 1280, 768, 2560, -4096, 2816, 2048, 4608, 768, 3328, -2816, 1792, 1280, -1792, -1536, -5120, 3840, -256, 2560, -256, -3328, -4352, -2816, -768, -3328, -1024, -3584, -768, -512, -1536, 1536, -7168, 2304, -2048, 2560, 0, 3072, -512, 2560, 2304, 256, 768, -1536, 1280, 4352, 6144, 4608, 768, 1024, -2304, -1024, 512, -2048, -1024, -512, -2816, 256, -2048, -3072, -2304, -2560, 1280, 0, -1792, -2304, 1792, -4608, 1536, -2560, -3072, -256, -256, 3328, 256, 4608, 512, -768, 1024, 768, 768, -768, 768, 2560, 2304, 1792, 1280, -2048, -1792, 0, 768, -1792, 1792, -512, -512, 1280, -2560, 512, -1280, -768, -256, 1024, 256, -512, -2560, 1024, -2304, -1280, -3072, -4608, 768, 1536, -768, 768, -3840, -256, -3328, 1536, -512, 2048, 0, 2048, 4096, -512, 4352, -1024, 2048, 768, 5888, -256, 2816, -2048, 2560, -1024, -1280, -768, -3328, -512, -256, -512, 512, -2304, -3328, -3328, -512, -2816, -512, -5120, -1280, 0, 768, 512, -256, -2560, 256, 2048, 768, 2304, 1536, 1024, -768, 3328, 768, 1024, 2816, 512, 2816, 2048, -512, -256, -512, -512, -512, -256, -5376, -256, -3584, 2048, 1536, -2048, -2560, 512, -4096, 1024, -768, -256, -2560, 1792, -256, 1024, -1024, -3072, 768, -512, 3328, 512, -768, -2304, -512, 1536, -1792, 2048, -2048, -1280, 3072, 1792, 2048, -768, 1536, -256, 4096, 0, 1792, -2048, 768, -1792, -256, 0, -1536, -1024, -2048, 1536, -256, 1024, -4864, 512, -768, -2048, -768, -3072, 1024, -1536, 512, -1792, 256, -3328, 512, 2304, -256, 4352, -4864, 768, -768, 5888, 2304, 1536, 768, 1536, 1536, -1280, 2816, -2816, 256, 0, -1280, 1536, -1536, -1024, -1280, -1792, 768, -1024, -3584, -2304, -1792, -256, 1280, -2816, 1024, -4864, 3584, -1024, 768, 1024, 512, 0, 2304, -512, -768, 512, -512, 2560, 3840, -768, 3584, -1536, -1024, 1536, 256, -2048, 2816, -2304, 1024, 768, -2304, 512, 512, -512, 512, -512, -2304, -512, -512, 256, -1536, -1536, -5632, -4096, -2560, 3072, 0, 1280, -2048, -512, -1024, -512, 1280, -256, 1792, 1792, 2304, 256, 1792, 1536, -256, 2560, 2816, 1280, -768, 2048, 256, -256, 2048, -3840, -1536, -2560, 3072, 0, 512, -1280, -2304, -3072, -1792, -1024, -3584, -1024, 0, -256, 1280, -1792, -2048, -3072, 0, 512, 4096, -768, 2816, -1024, 4096, 2816, 512, -768, 512, 2048, -256, 1792, -3328, 1024, -768, -256, 768, -2560, -512, -2816, 768, 512, 768, -1792, -2560, -1280, -2560, 3072, -2048, 1280, -1792, 3840, 256, -2560, 1792, -4096, 256, 768, 1024, -1280, 1792, -1792, 1024, -512, -256, -2048, 0, -512, 4352, 2560, -512, 1536, -1280, 768, 2560, -1792, 512, -768, 1024, 1280, 1280, -768, -2048, -2048, -256, 256, 1792, -1280, -2816, -512, -2560, -1024, -3840, -1792, -2560, -512, 512, -1024, -2560, -2048, 0, 512, 1536, 768, 512, 768, 2560, 3584, 2048, 1792, 768, 1280, -1280, 5120, -1536, -256, -512, 0, 256, -512, -512, -2048, 768, -768, 2560, -3584, 768, -768, -512, 0, -1280, 0, -3840, 1024, -512, 0, 1024, -1792, 768, -2048, 1792, -3584, -512, -1536, 1024, 512, 768, -2560, -512, 1280, -768, 3072, -512, -1280, -2304, 256, 1024, 256, 2816, -3072, 3840, 1280, 5120, 2560, -1280, 256, 1280, 768, -3328, 1536, -4096, 1280, 256, -1280, -2048, -768, -3584, -1536, -512, -1280, -2048, -4352, -2304, 768, -1536, -512, -768, -768, 256, 3584, 512, 1024, 1280, 768, 2048, 1792, 3072, 0, 2816, 1024, 4096, 512, -768, -2304, -256, 256, -256, -768, -1536, -3584, 1024, -1536, 512, -3584, -2304, -2816, -256, 0, 0, -1280, -1536, -2560, 1280, -1280, 512, -768, 512, 512, 4352, -512, -256, -768, 768, 2816, 256, 2560, 512, 1792, 1536, 1280, -1280, -768, -768, -512, 1792, 512, 256, -4608, -1280, -512, -768, -1280, 0, -512, 0, 2048, -2304, -2560, -3840, -1792, -512, -256, 1536, -2048, 4096, -2560, 3328, -1024, 512, -1024, 1024, 1792, 2304, 1536, -1280, -512, 2048, -256, 2816, -1536, -256, 1280, 2048, 0, 2304, -5120, 0, -2304, 1024, -768, 256, -1024, -2816, 512, -1536, 0, -3072, 0, 256, 1280, -512, 256, -1792, -1024, 768, -256, -2560, 768, -768, 1792, 1024, 2048, -2304, -1536, -2560, 0, 0, 512, -1024, 1536, 2304, 2560, 512, 0, -256, 512, 3584, 768, 1792, -1792, 512, -512, -512, -1536, -2304, 512, -768, 1536, -768, -1792, -2304, -2560, -512, 512, -256, -2816, 512, 256, 1792, -1024, -1792, -4864, 768, -256, 1536, 1536, 1536, 1536, 0, 1536, 1792, 768, -256, 768, 2048, 768, 1024, -2560, -1280, -1792, 1280, -1024, -3584, 512, -2048, 1280, -512, 512, -4096, -1024, -2816, 512, 1024, -256, 512, -256, 0, 1280, 1024, -3072, 768, 2304, 1792, 3328, -768, -1792, 512, 1536, -256, 1792, -256, -256, 1280, -1280, 1792, -2816, -2304, -3328, 512, 1280, 512, -512, -1792, 1280, 1024, -1024, -512, -3840, -1024, 768, 0, 0, -1280, 512, -1792, -256, 2304, -512, -256, 1280, 256, 256, -1024, -1280, -1024, 1536, 2048, 1792, -1280, 1024, -1792, 1024, 0, 256, -1536, -1280, -512, 1280, -256, 0, 256, 256, 768, 2304, -1024, -512, -1024, -2304, -256, 1024, -4352, 256, -3328, 2816, -256, 1536, -2304, -256, 1280, 256, 2048, -768, 1024, -1280, 256, 1792, -1280, 256, -768, 1280, 768, 1024, -1792, -2816, -1792, 256, 1280, -3328, 2816, -2816, 256, 768, 1536, -2304, 1536, -1280, -1792, 1024, -3328, 1280, -1792, 2560, 1280, 1536, -3840, -256, 1536, 1024, 4608, -1792, -1792, -768, -1024, 512, -1280, 768, -1024, 2304, -1024, 768, 768, -768, -2560, 0, -256, 512, 1280, -768, 1792, 768, 512, -1536, -2816, -512, -256, 1024, -1280, 1024, -1280, 0, -1280, 1280, -1280, -1024, 512, 1024, 512, 1280, -2048, -3328, -768, 0, -256, -512, 1024, 1536, 2304, 256, 768, -1792, -256, 256, 3072, 256, 256, -256, -1280, -256, 512, -2048, -2304, -1792, -512, 768, 2560, -1536, -1792, -3072, -1792, -1024, -1280, 1536, 0, 2560, 1280, 1792, -1024, -512, -2048, 2560, 1280, 2304, 1024, -256, -256, -256, -256, -256, -512, -768, 768, 2304, -512, 2304, -3584, -3328, -2048, -2560, 256, 256, 768, 768, 256, -768, -3072, -1280, -1792, 256, 1536, 1536, -512, -1792, -768, -768, 512, 512, 1024, -2304, 3584, 2048, 2816, -768, 1280, -2816, 256, -256, 1280, 768, 2048, 512, 2048, -512, -1536, -3328, -2560, 0, 1024, 768, 1024, -768, -2304, 256, -1280, -1280, -1536, 256, -512, 512, -2560, -1536, -3840, 256, -1280, 1024, -256, 512, 512, 1024, 2560, 1024, 512, -3328, 0, 1024, 2048, 4352, 512, 1280, 1024, 512, -1536, 1280, -1280, 0, 2048, -512, -256, -1280, -1024, -1280, -256, -1280, -1024, -1280, 0, 0, 256, -2304, -3840, -768, -3072, 256, -256, -1792, 2560, 512, 1280, -256, 512, -1536, 512, 512, 2560, 2560, -256, 512, -512, 1024, 1280, 0, -1536, 3072, 1280, 768, -256, -2048, -2048, -1024, -1024, 768, -2816, 0, -256, -256, 0, -512, -3584, -1536, -2304, 512, 256, 1792, -1024, 768, -256, 0, -768, 256, 512, 1792, 1280, 1024, 768, -512, -768, 256, 1536, -256, 1536, -2816, 1792, 512, -1536, 512, -1024, 0, 512, 768, -1792, -2304, 768, 0, 1024, -1536, 0, -5376, 0, -1280, -256, 0, -256, 256, -1536, -256, -256, 0, -1792, 1280, 1792, -512, 2048, -1024, -256, 768, 2304, -1536, 2560, -1536, 1792, 2304, 2560, 2304, -1536, 1280, -3584, 1536, -1280, 256, 512, -768, 0, -2304, -2560, -3584, -512, -768, 1536, -2048, -3840, 768, -2304, 0, -768, 0, -1536, -256, 768, 2304, 2560, 768, 768, -2560, 1536, 256, 768, -256, 2304, 3072, 1024, 1024, -2304, -1792, -1280, 2048, 1536, 256, 256, -1024, -1280, -1280, -256, -2816, -768, -1024, 256, -256, 256, -2560, -1792, -512, -768, -1024, -768, -1536, 2816, 1280, 768, 512, -2048, -1280, -512, 768, 2304, 3328, 1280, 1024, 1024, 0, -1280, -256, -1280, 2304, 512, 768, -2304, -1024, 768, -1536, 512, 256, -2304, 1280, -512, 768, -512, -2304, -2048, -3840, -1280, -768, 768, -3328, 2816, 1536, -768, 256, -1536, -1536, -256, 1536, 1024, 1536, 1792, 256, 1280, 0, 2048, -1536, 1792, 512, 1536, 512, -1280, 0, -768, -256, 768, -1792, -256, -768, 1280, 1792, 1536, -4608, -2560, -2816, -1792, -768, 2560, -1024, 768, -1024, -2048, -1280, -3072, -768, -1024, 3072, 2560, 512, -1024, 1536, 768, 256, 512, 0, -768, 768, 1792, 1792, -1280, 512, -1024, 256, 768, 2816, 512, 768, 1024, -512, -1792, -1280, -4352, -2816, 1024, -768, 1280, -1792, -1792, -1536, -256, -2048, -1280, -1280, 256, 1792, 256, 512, -256, -2304, 1792, 256, 1792, 768, 768, 1536, 2304, 1536, 256, -1536, -1024, 512, 1280, 1792, 1024, -512, 256, 768, -2816, -256, -4096, -512, -1536, 256, 768, -2048, -3840, -2816, 1024, -256, 2304, -512, -1280, 0, 1536, 0, -1792, 0, -2048, 1024, 512, 1536, 512, 0, 512, 1536, 512, -512, 1024, -512, 1024, 3584, 512, 512, -1536, -1536, -768, 1024, -1024, -256, -1024, 256, -768, -1536, -256, -3328, -256, -512, 1792, -2048, -1792, -2560, 0, 1024, 768, -2048, -768, 256, 1024, 1536, 1024, 1536, -768, 1280, 768, 1024, 0, 1536, 256, 1024, 1792, -768, -2560, 2048, -256, 2304, -256, 256, -2816, -1792, -768, -768, -1536, -2048, -2304, -1536, 256, -768, -1536, -1536, -1280, 0, 0, 512, -768, 0, 1536, 1024, 768, 512, 1792, 1024, 2816, 3584, 1280, -256, -1280, 256, -512, 1792, 768, 0, 256, 512, -1280, -1792, -2560, -3072, -2560, -1280, -1280, -1536, -1536, -2304, 256, -2048, -512, -256, -2304, 256, 2048, 512, -1280, -512, -1280, 0, 1280, 1536, 1536, 1792, 2048, 2560, 512, 0, -768, -256, 512, 3328, 768, 0, -1536, 0, 256, -768, 0, -3072, -512, 1024, -1024, 1024, -2048, -2816, -256, -512, 256, -256, 512, -3072, 768, -1536, 256, -3072, -1792, -1792, 768, 0, 2304, 0, 256, 1536, 256, -256, 512, 256, 512, 2048, 2304, -768, -256, 0, 1792, 768, 2048, -256, -1024, -256, 256, 768, -2304, -256, -4352, -768, -512, -1024, -1024, -768, -1024, -1536, -2816, -3840, -512, -1280, 1536, 2560, 256, 768, -256, -768, 3328, 1792, 256, 1536, 1024, 1024, 2304, 1280, -768, -1280, 2304, 768, 1280, -768, 256, -768, 768, 0, -1792, -1280, -1792, 0, -1280, 0, -256, -3840, -2816, -1024, -1280, -2560, 512, -1792, 1280, -1024, 256, -2304, 512, 256, 2048, 1792, 2560, 512, 512, 0, 1024, 768, -512, 0, 1024, 512, 1536, 2048, -512, 1024, 1024, -512, 1280, -768, -1536, 768, -768, -1280, -2304, -2048, -2816, -1280, -256, -256, -1280, -1792, -1280, -2048, 0, -768, 1280, -1792, 2816, 256, 0, 512, -768, -256, 768, 2304, 1536, -768, 2048, 256, 2816, 512, 2048, -768, -768, 1536, 512, 256, 512, -1792, -768, -512, -1024, -2048, -768, -768, 1280, -2560, -2560, -1024, -3072, -512, 768, -1280, 768, -1536, -2048, -512, 1280, -768, 0, 256, 1024, 2048, 1024, 1280, 0, 1024, 2048, 256, 1792, -768, 0, 768, 1024, 1024, -1280, -512, -1792, -768, 0, 1280, -1280, -2304, 768, -512, -256, -512, -1280, -256, -1024, -768, -2816, -1024, -1280, -1536, 0, 1280, 0, -1280, 1280, 768, 2048, -256, 768, 768, 512, 1280, 1792, -1024, 768, 256, 768, 2560, 512, -1792, 256, 0, 1536, -1024, -768, -1280, -1792, -512, -1024, -768, -1536, 0, -2560, 1024, -1536, -1024, -1792, -512, 256, -1024, -256, -768, -256, 512, 1536, 512, 1024, -512, 512, 1024, 512, 1280, -768, 1024, 512, 256, 0, 2048, -768, 512, 1280, -1280, 768, -1280, -512, 1280, -1280, 768, -256, -1024, -768, 1024, -2560, -1280, -1792, -1024, -1024, 0, 0, -1792, -256, -256, 512, 256, -512, -3072, -1024, -256, 0, 1024, -1280, 512, 0, 768, 3072, 2816, 768, 2816, -256, -768, 1536, -1536, 256, 256, 1792, 1536, -1792, -256, -1792, -1024, -1024, -1792, -2048, -256, -1536, -1536, -512, -768, -1280, 0, -1024, 2048, -1792, 256, 1024, -768, 1536, 256, -1792, 768, 1280, 1536, 1280, 3328, 512, 512, -1024, 1024, -768, 256, 1024, -1024, 512, -768, -2560, -2560, -1792, -512, -512, -512, 0, -1536, -512, 256, -768, -1024, -512, -1280, -512, 1792, 256, 1536, -1280, 1536, -256, -256, 512, -768, 1024, 2816, 512, -256, 512, -1792, -1280, 2048, 0, 768, -768, -1280, -256, -512, 768, 256, -1024, 1024, 1792, 0, 512, 768, -768, 0, 256, -1280, -3840, -1280, -768, 256, 768, -768, -2816, -1024, -1792, 256, -512, -256, -256, 0, 256, 256, -1280, -256, 768, -512, 1792, 256, -1024, -256, 0, 1024, 1280, 768, 768, -256, 2048, 2816, 256, 1024, 256, -1280, 1792, -1536, -1024, -512, -1024, -512, 768, -2048, -768, -3328, -1536, 768, -768, -1792, -1024, -1792, 768, 768, -768, 512, -256, 256, -1024, -512, -512, -1280, 256, 2816, 2304, -512, 1536, -768, 1792, 1792, 256, 256, -1792, 512, -768, 256, 1024, -1024, -1024, 1280, 256, 0, -768, -1536, 512, -768, 0, -2048, -3072, -1536, -512, -768, 1536, -256, -2304, 0, -256, 256, 768, -512, -256, 0, 256, 1536, 0, -768, 1280, 256, 1536, 256, -256, 1024, 256, 1792, -768, -256, -256, -1024, 1024, 3584, -256, -256, 512, -1024, -256, -1536, -2048, -2048, -768, -512, 512, -2304, -1280, -1792, -3072, 1280, 0, -768, -1024, -768, 1280, 1024, 768, -512, -1536, 1024, 1792, 768, 1280, 1792, -768, 2048, 0, -1280, -256, -256, 2816, 2560, 768, 1024, -2048, -768, -768, 256, -768, 0, -1024, -768, 256, -1792, -2048, -4096, -1792, -1536, -512, 768, -1792, -512, 256, -1024, 0, -1280, -1280, 256, 1280, 2560, 1280, 0, 768, 0, 256, 3328, 0, 1280, 2304, 1536, 2048, -256, -1024, 0, -768, 1536, 1024, -1024, 0, -768, -3840, -512, -3072, -3840, -768, -1536, 512, 256, -768, -1024, -2304, -2304, -768, -768, -512, 768, 1024, 2304, 0, 512, 256, 512, 3584, 1280, 768, 2048, 512, 1792, 1024, -1024, -1024, -256, -2304, 2304, -1280, -256, -1792, -2560, -512, -1792, -1024, 0, -1280, 512, 1280, 256, 0, -1280, -1280, -256, -256, -768, 1024, -2048, 1280, 768, -1024, 1024, -1280, -768, 2304, 1024, 2048, 0, 0, 512, 0, -512, 0, -512, -1792, 3072, -256, 1280, -1024, 512, -768, 0, 512, -512, -1024, -512, 512, -1280, 768, -1792, -2304, -1024, -768, -512, -1536, -1536, -512, -1536, -256, -1792, -2048, 256, 768, 1536, 2560, 1024, 1280, 0, 1280, 2048, 256, 768, 2048, 1280, 2816, 3072, -1792, 1024, 0, -768, 512, -256, -2048, -1792, -1024, -512, -1536, -2304, -1536, -3328, -1024, -256, 0, -2304, -1280, -768, -1024, -512, 768, 256, 256, 2304, 1024, 512, 1536, -256, 768, 1536, 512, 0, -768, 768, 512, 1536, 768, -256, -1024, 1024, 256, 512, 512, -1280, -2048, -256, -768, -256, -2304, -1024, 256, -1280, 1280, -1792, -1024, 0, 768, -2560, 768, -768, -1280, 256, 1280, 1024, 256, -1280, 256, -1280, 1024, 256, -1536, 0, 1280, 2048, 2048, 256, 1536, 0, 768, 1024, 512, -768, 256, -768, -768, 768, -2560, -1536, -2048, -512, -256, -768, -1536, -1536, -1280, -1536, -1536, -1280, 1280, -768, 1280, 1536, -512, -256, -256, -1024, 1536, -512, 1536, 1536, 512, 3072, 2048, -512, 768, -1536, -512, 1280, 1024, -768, -512, -1280, -1024, -1792, -1536, 256, -1280, 512, 512, 0, 256, -1792, 0, -1024, -512, -256, -512, -1280, 1792, -1280, -512, -768, -512, -768, 1024, 1024, 2304, 0, 256, 256, -1280, -768, -1024, -1024, 1024, 768, 1536, 256, -512, -512, -1792, 1024, 256, 256, -768, 768, -256, 512, 0, -1792, 0, 0, -256, -768, -512, -256, -1280, -512, -768, -2048, -1280, -1280, -256, 1280, 1280, 512, 512, -768, 1024, 768, 1024, 1536, 768, -256, 2560, -1024, -768, -512, -768, 0, -1024, 0, -512, -512, 0, 512, -1280, -512, -1280, -2304, 2048, -512, -256, -256, -768, -768, -512, -1536, 512, 256, 512, 2304, 0, 256, 1024, -1280, 512, 1024, -1536, -256, 512, -256, 1536, 768, 0, -1280, -768, -256, 0, 768, -768, 0, -1536, -512, -768, -1024, -512, 0, 768, 512, 512, 0, -2560, 256, -1536, -1280, -256, -512, 1280, 768, 1536, -512, -1536, -256, -768, 512, 1024, 256, -256, 0, 256, 256, 768, -256, 1280, -256, 1792, 1536, 256, -512, 0, -1536, -512, -512, -2048, -512, -512, -768, -1280, -1280, -2048, -768, -256, 1280, -768, 256, 512, 256, 512, -768, -512, -768, 512, 1536, 512, 1536, 0, 0, -512, 2304, -256, 768, -512, 768, 0, 0, 0, -1536, -1536, -256, -1280, -1792, 256, -768, -1536, 512, -512, -256, -1280, -512, 256, 1024, 512, 512, -768, -256, 1536, -512, 512, 1024, -768, 512, 512, 512, -768, 256, 0, -1024, 512, -256, -512, 768, 256, 256, -256, -1280, -2048, -512, -1280, 0, 256, -1536, 768, -1024, 512, 768, -1536, 768, 0, 512, -512, -256, -1024, -512, -1024, 1024, 0, -768, 0, -1536, -768, 2560, -768, 768, 0, 1024, 1792, 768, 0, 1280, 256, 1280, 256, -768, -512, 0, -1536, 768, -256, -1792, -1280, -1792, -256, -512, -512, -512, -768, -512, 512, -512, -256, -768, -768, 512, -512, -1536, -768, -768, 1024, 768, 512, 0, -256, 1280, 1280, 2048, 512, 512, -512, 1024, 0, 1280, -1280, -768, -256, -768, -768, -1536, -1024, -512, 768, 0, -512, -512, -1280, 1280, -256, 768, -256, -256, -768, 0, 0, -1280, -1024, -768, -512, 1280, 0, -1024, -1024, 256, 512, 1536, 0, -768, -256, 512, 768, 1792, -768, 0, -1024, -512, 1024, 768, 0, 256, 768, -768, 256, -1792, -1024, 0, 256, 256, -1024, -1024, -1024, -2304, -256, -512, -768, -512, -768, -768, 1024, 768, -256, -1024, 512, 1024, 1024, 768, 512, -256, 0, 2304, -256, 1024, 512, 1792, -256, 1536, -512, -512, -1280, -256, -2304, -512, -512, -1536, -256, -256, 256, -2048, -1536, -1280, -256, -256, 256, -1024, -1280, 768, 256, 1280, 768, -768, 0, -512, 1792, 0, 256, -512, 768, -256, 1280, -256, -1280, 1792, -256, 768, 512, -1280, -1536, -512, 1024, 512, -256, -768, -256, -256, -256, -256, -512, -1024, 256, -1280, 768, -256, -768, -1280, 512, 1536, -1536, -256, -1280, -1024, 1024, -256, -256, -512, -256, 512, 0, 768, 256, 1024, 512, 1792, -256, 512, 0, -512, 256, 1024, -1280, -768, -1792, -512, 0, -256, -256, -768, 0, 0, -512, -1536, 512, -1024, 512, -1024, 256, -1792, -512, -256, 1280, 768, -512, -1792, -1024, 256, 1536, 1024, 1280, 256, 1024, 0, 1280, 256, -256, 512, 0, -768, -768, -1280, -1536, 768, -256, 1280, -256, -512, 256, 256, 1024, 512, -1536, -768, -1024, -768, 512, -512, -2048, -768, -1536, -1024, -512, -2816, 0, 0, 256, 1536, -768, -512, 256, 512, 2560, 2048, 1024, -512, -256, 512, 512, 256, -512, 768, 256, 1280, 768, -256, 0, -1024, 1024, -1792, -512, -1792, -2048, -1024, -768, -512, -1792, -1792, -768, -256, 1280, -512, 0, -1792, 512, -256, 768, 256, 1024, 1536, 1280, 2048, 768, 512, -256, 768, -768, 0, 0, -1280, -256, 256, 256, -1280, -768, -512, 1536, 1024, 1280, -1024, -2048, -1024, -768, -512, -1280, -1024, -1024, -1024, 512, -768, -512, -1024, -1024, -1024, 1536, 256, 0, 256, 768, 768, 1280, 512, 256, 0, 1536, 512, -256, 256, -768, -768, 512, -256, 0, 256, 768, 256, 1024, -1024, -1280, -2560, -2048, 256, -1536, -768, -1024, -1536, -768, 0, 512, -768, -256, 512, 0, 2048, 256, 1024, 1024, 768, 1536, 768, 256, 768, 1280, 256, 512, -1024, -1792, -768, -768, 768, 0, -1792, -1280, 0, -768, -256, -512, -1024, 0, -1280, 256, -1536, -256, -1280, -768, 256, 1024, -256, -768, 768, 768, 1280, -256, -512, 512, -256, 512, 256, -256, -1280, 1280, 256, 512, 512, -1024, 0, -256, 768, 0, -512, -256, 512, 256, 1280, 1024, -768, -1280, 0, -512, -512, -1536, -768, -768, -1024, -256, -1280, -1024, -256, -512, 0, 512, -512, -1536, -768, 256, 256, 256, -256, 768, 1024, 1792, 512, 768, 1024, -256, 1792, 512, 768, 256, -256, 256, -512, 0, -1024, -1280, -1536, 0, -512, -1792, -512, -1280, -1280, 256, -1024, -1280, -1280, 768, -256, 256, 512, -512, 0, 256, 1024, 256, -1024, 512, 512, 0, 2304, 512, 0, 1024, 768, 256, 512, -1024, -512, -1024, 768, -1024, -512, -1536, 0, -256, 1280, 512, -1024, 0, -1024, -1024, -256, -1280, -1024, -1792, -768, 256, 0, -512, -256, -1280, 256, 0, -256, 0, 512, 1024, 0, 768, -512, 256, 512, 1536, 0, 256, 1280, 0, 768, 768, 512, -1280, -512, 256, 1280, 512, -512, -1280, -2304, 0, -1536, -256, -1536, -1792, -1280, -1024, 0, -512, -1280, -768, 512, -512, 768, 512, 0, 2304, 512, 0, 1024, -768, 1024, 1280, 2048, 1536, -512, -1024, -256, 0, -512, -512, 256, -1280, 512, -1280, -256, -1024, -768, -1024, 0, -512, -1792, -768, -256, 0, -256, 0, -1536, 768, -512, 1280, 512, -256, -512, 256, 0, 256, -256, -768, 512, 768, 256, 512, -1024, -768, -256, 1280, 1280, 768, -1024, 0, 256, 512, 1280, -1280, 256, -1280, 512, -512, 512, -1024, -768, 0, -1024, -768, -2304, -1792, -1024, 512, -512, 256, -1536, -768, 0, 256, 1280, 256, -1280, 0, 0, 512, 256, 512, 0, 1536, 1024, 1536, 768, 512, 768, 256, -512, -512, -2304, -1024, -256, 1024, 0, -256, -1280, -2048, -1280, -1024, 0, -1024, -256, -768, 0, 0, -1024, -768, -256, 256, 512, 0, -512, -768, 256, 768, 512, 768, 768, 0, 2048, 512, 1792, -256, 768, -512, 1024, 0, 0, 256, -1024, 1280, -256, -768, -768, -1536, -1024, 512, 256, -1280, -1024, -1792, -1024, -1024, -1792, -512, -2560, 256, 0, 256, -768, 1024, -512, 1280, 512, 256, -768, -256, 512, 2048, 1024, 1280, 0, 256, 1024, 1280, 512, 512, -512, 256, -1024, 0, -768, -768, -256, 0, 512, -1024, -1024, -1280, -256, -1792, 0, -1024, -1280, -256, -768, 512, -512, 0, 768, 0, 512, 0, 256, -512, 512, 1024, -256, 0, -768, -256, 256, 768, 512, -768, 512, 0, 512, 512, -256, 512, -512, -768, 0, 0, -512, 512, -512, 1024, -768, -1536, -1792, -1536, 512, -256, -1024, -256, -1792, -256, -768, 768, -256, 0, -512, 512, 512, -768, 768, -1024, 1280, 1792, 1536, 768, 256, -256, 1536, 512, 256, 0, -256, -256, 256, -768, 256, -768, -1280, -1280, -768, -2048, -768, -2816, -256, -256, 0, -2048, -512, -1280, 768, 1024, 0, 256, -512, 512, 0, 1536, 1024, 256, 1024, 256, 1280, 0, 0, 256, 512, 1280, 0, 256, -2560, 0, -1280, 512, 0, -1536, -1536, -512, -512, 512, -768, 0, -1024, 512, -1024, 256, -768, -1024, 256, -512, 512, 256, -512, 0, 768, 512, -768, -256, -1280, -768, 1024, 512, 768, -256, 1024, 256, 1280, -256, 512, -768, 512, -768, 0, -768, -512, 256, 256, 1280, 256, -512, -1280, 256, -256, -1024, -768, -1792, 0, -1280, -1024, -1024, 0, -1024, 1024, 0, -256, 256, -2048, 256, 0, 2304, 256, 512, -512, 1280, 1280, 256, 1536, -256, 1536, 768, 256, 256, -512, -512, -1024, -768, -512, -768, -1792, -1024, -1024, -256, -768, -2048, -256, -2048, 1024, -1280, 0, -768, 256, 0, 1024, -256, 0, 256, 768, 768, 1024, -1024, 1536, -512, 512, 1280, 1024, -768, 1024, -768, 1280, 0, -1024, 0, 0, -256, 0, -1024, -1024, 768, -256, -512, -1024, -2048, -2304, -1280, -1024, 1024, -1024, 256, -1024, 256, 256, -256, -256, -256, 768, 512, 768, 0, 256, 512, 256, 1280, 768, 256, 0, 1280, 768, 768, 0, -1280, -1024, -512, 1280, 0, -512, -1280, -512, -1536, -512, -1280, -2048, -512, 256, -256, -768, -1792, -2048, -1536, 0, 1024, 1792, -512, 1792, -256, 1792, 768, 512, -1280, 0, 512, 0, 256, -768, 512, 512, 768, 768, -768, 0, -512, 768, -256, -256, -1024, -1536, -512, -768, 1024, -1024, 0, -1024, 1536, -512, -1536, -512, -1792, 256, 512, -256, -768, -512, -512, 768, -256, 0, -768, -256, 1024, 1792, 1024, 0, 512, -256, 0, 1536, -512, 256, 256, 1280, 1024, 256, -768, -768, -512, 512, 512, 256, -1536, -1536, -768, -1024, -512, -1536, -1280, -1024, -1280, -512, -2048, -2048, -768, 0, 1024, 0, 256, -256, 512, 1280, 1024, 512, 512, 768, 768, 1024, 2560, 0, 512, 0, 768, 256, 256, 0, -768, 256, -768, 256, -1792, 0, 256, -512, 256, -1536, -1024, -2560, -256, -1024, -512, -512, -768, 512, -1024, 256, -1280, -1024, -1024, 512, 256, 256, -1024, -256, 768, 256, 1536, 512, -512, -512, 768, 768, 512, 1792, -1280, 1280, 0, 2048, 256, -256, 512, 768, -256, -1536, 0, -2560, 768, -256, -256, -1280, -1536, -2048, -512, 0, -768, -1280, -2048, -1024, 512, -768, -256, -512, 0, -256, 1792, -256, 768, 512, 1024, 1792, 768, 1024, -256, 1280, 256, 2304, 256, -512, -256, -256, 256, -768, -512, -1536, -1792, 256, -768, -256, -2304, -1024, -1536, 0, 512, -768, -512, -1024, -768, 0, -1024, -256, -1024, 0, 256, 1536, -256, 256, -256, 768, 1280, -256, 768, 1024, 1280, 1792, 1024, -512, 0, -512, 0, 768, 256, -256, -2048, -512, -256, -512, -1280, -256, -512, -512, 512, -1280, -1792, -2304, -512, -768, -512, 256, -1280, 1024, -1024, 1280, -256, -256, -768, 512, 768, 1792, 768, -256, 768, 1024, -256, 1280, -1024, 0, 1024, 1024, 768, 1024, -2304, 256, -1280, 512, -512, -512, -768, -1792, -256, -512, -512, -1280, -768, -256, 256, -512, -256, -1024, -1024, 256, -256, -1792, 0, -256, 512, 1280, 1024, -1024, -1280, -1024, 0, 512, 256, -256, 768, 1280, 1024, 0, 0, -256, 768, 2048, 768, 768, -1024, 0, 256, 0, -512, -1536, -512, -1024, 768, -512, -768, -1280, -1536, -768, -256, -256, -1792, 0, 0, 768, -1280, -1024, -2816, 0, 0, 768, 768, 256, 256, 256, 1024, 1536, 256, 256, 512, 2304, 768, 768, -1024, -1024, -768, 512, -256, -1536, 256, -1280, 512, 0, -256, -2048, -1280, -1536, 256, 0, -512, -256, -512, -256, 512, 0, -2304, 0, 1280, 1024, 1792, -768, -768, 768, 1024, 512, 1024, 0, -256, 768, 256, 1280, -1280, -1536, -1792, 0, 768, 0, -512, -1024, 768, 768, -768, -1024, -1792, -512, 1024, 256, -256, -1024, -256, -1536, -512, 768, -512, -768, 256, 1024, 256, -256, -1024, -768, 768, 1024, 1280, -512, 512, -768, 1024, 0, 768, -768, -768, 0, 768, 256, -512, -256, -768, 512, 1024, -512, -512, -768, -256, -256, 768, -2816, -512, -2048, 1280, -256, 768, -1280, -512, 512, -256, 768, -768, 0, -256, -256, 1280, -512, 0, -512, 768, 512, 768, -512, -1536, -768, 512, 1024, -1536, 1280, -1536, 256, 512, 768, -1536, 512, -768, -1024, 768, -2304, 512, -1536, 768, 1024, 512, -2304, -256, 256, 512, 2048, -768, -1024, -256, -512, 512, -512, 512, -768, 768, -256, 256, 512, -256, -1536, 256, 512, 512, 256, -512, 512, 768, 256, -768, -1536, -768, 0, 256, -768, 0, -768, -256, -1024, 512, -1024, -768, -256, 1024, 0, 1280, -1536, -1792, -256, 0, 0, -768, -256, 512, 1024, 0, 768, -1024, -256, 256, 1792, 1024, 512, -256, -1024, 0, 512, -1024, -1280, -1280, -256, 256, 1024, -1280, -1024, -1536, -768, -512, -768, 512, -512, 1280, 512, 768, -1024, -512, -1280, 1536, 768, 1024, 512, -768, 256, 0, 0, 256, -768, -256, 256, 1792, 0, 1536, -1536, -1792, -512, -1792, 0, -256, 0, 512, 256, -512, -1792, -512, -1280, 0, 512, 0, -768, -1280, -256, -768, 0, -256, 0, -1536, 2048, 1024, 1280, -256, 256, -1024, 256, 256, 1024, 512, 1280, 768, 1536, 0, -512, -2304, -1024, -256, 0, 0, 256, -256, -1024, -256, -1280, -1280, -1280, 0, 0, 256, -1536, -1280, -2304, 0, -768, 0, -512, 0, 0, 768, 1024, 512, 256, -1792, 256, 768, 1024, 2304, 256, 1024, 1024, 512, -1024, 512, -512, 256, 1280, -512, 0, -768, -1024, -768, -512, -1024, -1024, -1024, 256, -256, 512, -1536, -2048, -768, -2048, -256, -512, -1024, 1280, 512, 768, -256, 0, -1024, 512, -256, 1280, 1280, -256, 768, 0, 768, 768, 0, -1024, 2304, 1024, 512, -256, -1536, -1024, -512, -512, 512, -1792, 0, 0, -512, -512, -512, -2560, -1024, -1792, 0, -512, 512, -512, 512, 256, 0, -768, 0, 256, 1536, 768, 512, 0, 0, -256, 512, 768, -256, 1024, -1280, 1536, 512, -768, 0, -768, 0, 256, 0, -1280, -1536, 256, 0, 256, -1280, -512, -3584, 0, -1024, -256, -256, -256, 256, -768, 0, -512, -256, -1024, 1024, 1280, -256, 1280, -256, 768, 768, 1280, -768, 1280, -768, 1280, 1280, 1536, 1024, -1536, 512, -2304, 1024, -1024, 0, 256, -512, -256, -2048, -1536, -2816, -512, -768, 768, -1536, -2048, 768, -1280, 256, -768, 256, -768, 256, 768, 1280, 1536, 512, 256, -1536, 1024, -256, 256, 0, 1792, 1792, 512, 768, -1536, -1024, -1024, 768, 768, 0, 256, -256, -512, -1024, 0, -2048, -512, -768, 256, -512, 256, -1280, -512, -256, -768, -768, -1024, -768, 1792, 1024, 256, -256, -1536, -1280, -768, 512, 1280, 2048, 768, 768, 512, 256, -1024, -256, -512, 1536, 768, 512, -1024, -256, 256, -1280, -256, -256, -1280, 512, -512, 256, -512, -1792, -1280, -2816, -1024, -768, 768, -2048, 2048, 1024, -512, -512, -1024, -1024, -256, 1024, 768, 1280, 1280, 512, 1024, -256, 1536, -768, 1536, 512, 768, 0, -1024, 0, -512, -512, 0, -1280, -512, -256, 1024, 768, 256, -3328, -2048, -2048, -1280, -768, 1792, -512, 768, -512, -1280, -768, -2048, -512, -768, 2048, 1536, 256, -512, 1280, 768, 256, 512, 0, -256, 512, 1024, 768, -1280, 256, -768, 0, 256, 1792, 256, 512, 768, -256, -1024, -1024, -2560, -1792, 768, 0, 512, -1280, -1280, -1024, -256, -1792, -768, -768, 256, 768, 0, 0, -256, -1536, 1536, 256, 1024, 256, 512, 1280, 1536, 1024, -256, -1024, -768, 256, 512, 1280, 512, -256, 256, 768, -2048, -256, -2560, -512, -1280, 0, -256, -1536, -2560, -1792, 512, -512, 1536, -256, -512, 256, 1024, -256, -1280, -256, -1280, 1024, 256, 1024, 512, 256, 768, 1024, 0, -512, 256, -256, 768, 2048, 512, 256, -1024, -768, -768, 768, -768, -256, -1024, 0, -1024, -1536, -512, -2048, 256, -512, 1280, -1536, -1280, -1536, 0, 768, 256, -1536, -768, 256, 512, 1024, 512, 1024, -512, 768, 768, 768, 256, 1280, 256, 512, 768, -512, -1536, 1536, -256, 1536, -512, 256, -1792, -1280, -512, -768, -1536, -1536, -1536, -1024, 0, -512, -1024, -1024, -768, 0, -256, 256, -768, -256, 768, 256, 256, 0, 1536, 1024, 2048, 2560, 1280, 0, -768, 256, -512, 1280, 512, 256, 256, 256, -1024, -1536, -2048, -2048, -2048, -1280, -1024, -1280, -1024, -1280, 0, -1280, -768, 0, -1792, 0, 1024, 256, -1024, -256, -1024, -512, 1024, 1024, 1280, 1536, 1536, 1792, 0, 0, -256, 0, 512, 2304, 512, 256, -768, 0, 256, -768, 256, -2304, -256, 768, -1024, 768, -1536, -1792, -512, -256, -256, -256, 256, -2304, 512, -1280, 256, -2048, -1536, -1536, 256, -256, 1536, 0, 512, 1280, 512, 0, 512, 256, 512, 1536, 1280, -512, -256, 0, 1024, 256, 1536, 0, -512, 256, 0, 768, -1792, -256, -3328, -1024, -768, -768, -768, -512, -768, -1280, -2304, -2816, -512, -768, 1024, 1792, -256, 512, 0, -512, 2048, 1280, 256, 1024, 768, 512, 1792, 768, -512, -1024, 1792, 512, 768, -512, 256, -256, 512, 0, -1280, -1024, -1024, 0, -1024, 0, -256, -2560, -2304, -768, -1280, -2048, 256, -1280, 768, -768, 0, -1792, 256, 0, 1280, 1024, 1792, 256, 256, 0, 512, 512, -512, -256, 512, 256, 1024, 1536, -256, 1024, 768, -256, 1024, -512, -768, 768, -256, -512, -1536, -1536, -1792, -768, -256, 0, -1024, -1536, -1280, -1536, 0, -768, 768, -1280, 1792, 0, -256, 256, -768, -256, 256, 1536, 768, -768, 1792, 256, 2560, 256, 1536, -256, -512, 1280, 512, 256, 256, -1024, -512, 0, -768, -1792, -512, -1024, 1024, -2048, -2048, -1024, -2560, -512, 512, -1024, 256, -1280, -1792, -256, 768, -256, 256, 256, 1024, 1536, 512, 512, 0, 1024, 1792, 0, 1280, -512, 0, 768, 768, 768, -768, -256, -1280, -512, 0, 768, -1024, -1536, 512, -256, 0, -512, -1024, 0, -1024, -768, -2304, -768, -1024, -1024, 0, 768, -256, -1024, 768, 256, 1280, -512, 256, 512, 512, 1024, 1280, -768, 512, 256, 768, 1792, 256, -1280, 256, 0, 1280, -768, -512, -768, -1024, 0, -768, -512, -1280, 0, -2048, 768, -1536, -1024, -1536, -512, 512, -1024, -512, -768, -512, 256, 1024, 512, 768, -512, 512, 1024, 256, 1024, -512, 768, 512, 256, 256, 1792, -256, 512, 1024, -1024, 512, -1024, -512, 1280, -1024, 768, -256, -768, -512, 768, -2048, -1024, -1536, -768, -768, -256, 0, -1536, -256, 0, 256, 256, -512, -2560, -768, -256, 0, 512, -1280, 256, 256, 512, 2560, 2048, 512, 2048, -256, -512, 1024, -1280, 512, 512, 1792, 1536, -1536, -256, -1280, -1024, -768, -1536, -1792, 0, -1280, -1280, -256, -512, -1280, 0, -1024, 1536, -1536, 0, 768, -768, 1024, 0, -1536, 512, 1280, 1280, 1024, 2560, 0, 512, -768, 768, -512, 0, 768, -768, 512, -768, -2048, -2048, -1280, -256, -256, -256, 0, -1280, -512, 0, -768, -1024, -256, -1280, -512, 1280, 0, 1280, -1024, 1024, -256, -256, 256, -768, 768, 2304, 512, -256, 256, -1536, -768, 1792, 256, 768, -512, -1024, 0, -256, 768, 256, -768, 1024, 1536, 0, 256, 512, -768, 0, 0, -1280, -3328, -1024, -512, 256, 512, -768, -2560, -1024, -1792, 256, -512, -512, -256, 0, 256, 256, -1024, -256, 512, -512, 1792, 256, -768, 0, 0, 1024, 1280, 512, 512, -256, 1536, 2304, 256, 768, 256, -1280, 1280, -1536, -1280, -512, -1024, -512, 512, -1792, -1024, -2816, -1280, 768, -768, -1536, -1024, -1536, 768, 768, -768, 512, 0, 256, -768, -256, -512, -1024, 256, 2560, 2048, -512, 1024, -768, 1536, 1536, 256, 0, -1792, 512, -512, 256, 768, -1024, -1024, 1024, 256, 0, -512, -1280, 512, -512, 0, -1792, -2816, -1280, -512, -512, 1280, -256, -2048, -256, -256, 256, 512, -512, -256, 256, 256, 1280, 0, -768, 1280, 256, 1536, 256, -256, 768, 256, 1536, -768, -256, -256, -768, 1024, 3072, -256, -256, 512, -1024, -256, -1536, -2048, -1792, -768, -512, 256, -2304, -1280, -1536, -2560, 1280, 256, -512, -768, -512, 1280, 1024, 768, -256, -1280, 1024, 1536, 768, 1024, 1536, -512, 1792, 0, -1024, -256, -256, 2304, 2048, 512, 512, -2048, -768, -768, 0, -512, 0, -1024, -512, 0, -1536, -1792, -3584, -1536, -1280, -256, 768, -1536, -512, 256, -768, 0, -1024, -1280, 256, 1280, 2304, 1024, 0, 768, 0, 256, 3072, 0, 1024, 2048, 1280, 1792, -256, -1024, 0, -768, 1280, 1024, -1024, 0, -768, -3328, -512, -2560, -3584, -768, -1280, 512, 256, -768, -1024, -2048, -2048, -768, -512, -512, 768, 1024, 2048, 0, 512, 256, 512, 3072, 1280, 768, 2048, 512, 1536, 768, -1024, -1024, -512, -2048, 2048, -1280, -512, -1536, -2560, -512, -1536, -1024, 0, -1024, 512, 1280, 256, 0, -1024, -1024, -256, -256, -768, 1024, -1792, 1024, 768, -768, 1024, -1024, -768, 2048, 1024, 1792, 0, 0, 512, -256, -512, -256, -512, -1792, 2816, -256, 1280, -1024, 512, -512, 0, 512, -512, -1024, -512, 256, -1280, 768, -1536, -2304, -768, -768, -512, -1280, -1280, -512, -1536, -512, -1792, -2048, 256, 768, 1280, 2304, 1024, 1024, 0, 1280, 2048, 256, 768, 1792, 1280, 2560, 2816, -1792, 768, 0, -768, 256, -256, -1792, -1792, -768, -512, -1536, -2304, -1536, -3072, -1024, -256, 0, -2048, -1280, -768, -768, -512, 768, 256, 256, 2304, 1024, 512, 1280, -256, 512, 1536, 512, 0, -768, 512, 512, 1280, 512, -256, -1024, 1024, 256, 256, 512, -1280, -2048, -256, -768, -256, -2304, -1024, 256, -1024, 1280, -1536, -1024, 0, 768, -2304, 768, -768, -1280, 256, 1024, 1024, 256, -1024, 256, -1024, 1024, 256, -1536, 0, 1280, 1792, 2048, 256, 1536, 0, 768, 1024, 512, -768, 256, -768, -768, 768, -2304, -1536, -1792, -512, -256, -768, -1280, -1536, -1280, -1280, -1536, -1280, 1024, -768, 1280, 1280, -512, -256, -256, -768, 1536, -512, 1280, 1536, 512, 2816, 2048, -256, 768, -1536, -512, 1280, 1024, -768, -768, -1280, -768, -1792, -1280, 0, -1280, 512, 256, 0, 256, -1792, 0, -768, -512, -256, -512, -1280, 1792, -1024, -512, -768, -512, -768, 1024, 1024, 2304, 0, 256, 256, -1280, -768, -1024, -1024, 1024, 768, 1536, 0, -512, -512, -1536, 1024, 256, 256, -768, 768, -256, 512, 0, -1792, 0, 0, -256, -768, -512, -256, -1280, -512, -768, -2048, -1280, -1280, -256, 1280, 1280, 512, 512, -768, 1024, 768, 768, 1536, 768, -256, 2560, -1024, -768, -512, -768, 0, -1024, 0, -512, -512, 0, 256, -1024, -512, -1280, -2304, 2048, -512, -256, -256, -768, -768, -512, -1536, 512, 256, 512, 2304, 0, 256, 768, -1024, 512, 1024, -1536, -256, 512, -256, 1536, 768, 0, -1280, -768, -256, 0, 768, -768, 0, -1536, -512, -768, -1024, -512, 0, 768, 512, 512, 0, -2560, 256, -1536, -1280, -256, -512, 1280, 768, 1536, -512, -1536, -256, -768, 512, -256, 0, 0, -256, 0, 0, 0, 256, -512, 512, -512, -1280, -256, -512, 4096, 3072, -4608, -2560, 768, -3584, -2560, 4096, -256, -768, -4096, 7168, 768, -256, -256, 3072, -1280, -1536, 1536, 1792, -1792, -4608, -7168, 2816, 0, 1536, -512, 6656, -5376, -2560, -256, 6144, -768, 5120, -4864, 3840, -3584, -768, -768, 3840, -8960, -512, 1536, -3584, 7680, 1536, -9216, -2048, 4352, 0, -6912, 6656, 4096, -9728, 2048, -3584, 14592, 768, -7936, -3584, 8704, -5120, 8448, 512, -1536, -1792, -7168, 5120, -6144, 2048, 3328, 2048, -9984, 4352, 10240, -10752, -2816, 3328, -11776, 256, 7168, -5632, 2816, -768, -3584, 1280, 5120, -3072, -1024, 12544, -5632, -6144, 9984, -2816, -256, -2304, 9472, -7680, 3328, 8704, 1024, -2816, -6400, 4608, -5632, 256, 7424, -4352, -768, -6656, -4096, -5376, 3072, -4608, 1792, -4352, -1536, 13056, 0, -5376, 2560, 6144, -11520, 2048, 3584, 7936, -2560, -9472, 1536, 0, 6144, 768, -4608, -3328, 3584, 2816, 0, 1792, -256, -9728, -7424, -5376, 8192, -7680, 5632, -6656, 3584, -10240, 14080, -9216, 7680, -3072, 2048, 7936, -4096, 4864, -3840, 5888, -12288, 9216, 256, 16128, 768, 6144, 0, -768, 3584, 6656, -5376, 3840, 12032, -5376, -20480, 3584, -1024, -6400, -8448, 2816, 6400, -8960, -11264, 3328, -512, -12288, -2816, -5888, -1792, 6912, -1024, -3840, -5632, 1280, 6656, -9216, 12800, 5888, 2816, -5888, -3584, 4864, 8192, 3584, 9728, -16896, 14336, -2816, 6656, 4608, -3072, 4352, -7680, -1536, -13824, 5632, 19712, -15872, -3072, -4096, 8704, -6400, 512, 3584, -15872, 3072, 5120, -5632, -12800, 14848, -7424, -14848, 1024, 7168, 7680, 3328, 6400, -19968, 9728, 11520, -4864, -1792, 13312, -15616, 6912, 4352, -5376, -1024, 1536, 9472, -6144, -9728, 18688, 2048, -4096, 5376, -512, -3840, -4864, -4864, 4608, 768, 1792, -12288, -2560, -2560, 2560, 1024, 3328, -3328, -1024, 0, 11776, -3072, 1536, -4608, -6400, 1024, 3584, 6912, -5632, -9472, 3584, -1536, -4352, 14080, 10240, -28416, 16128, 2304, -9728, -4096, 11776, -8960, 1024, 0, -2560, -2048, -3072, 14848, -17664, 256, 16896, -9728, 5376, -8448, -1536, 2560, 0, 2560, -2816, 4608, -4096, 8192, -1792, -2560, -6400, 16640, -10752, 10752, -15872, 4608, -768, -512, -2048, 5376, 1024, -18176, 3328, 10240, -768, 4608, -4864, -7424, 3840, -16896, 15360, -12800, -1536, 17152, -20480, 4352, 16896, -5376, -5120, -3840, 17408, -4096, 18432, -1024, -5888, 1024, 13568, -2048, 2048, -1024, 0, 6912, -6656, -5632, 6400, -7936, 1792, -9984, -4608, 6912, -11008, -6400, -8448, -1536, 4352, -4096, 0, -14080, 1536, 6656, -768, -17152, 1792, 15360, -21248, 6400, 3840, 11520, -2048, 13056, -14080, 7168, 10752, 10752, -4352, 9472, -1536, 4352, 2048, 2816, -256, 15104, -1792, -11520, 3584, -10496, 27392, -12544, -12800, -6400, 16128, -14848, -6912, -14592, 4864, 3328, -3328, -6912, 4864, -10752, 16128, -28928, -256, 11264, 2048, 256, -2560, -8448, 0, 14080, -10496, 3840, 0, 19456, -4352, -9984, 15360, -5120, 7168, 13824, -23808, 3840, 21248, -7680, 1024, -14336, 12544, -14848, 7680, -7168, 512, 13824, -16384, 21248, -32768, 22016, 6144, -10240, -6912, -16896, 13056, 2816, -13056, 15104, 1536, 5120, -14848, -6144, 19968, -1792, -5888, -6912, 256, -768, -6144, 2560, -1536, -4096, 8704, 9984, -9472, -4352, 6656, 13312, -17664, -1792, 2816, 6144, -15872, 9728, -3328, 10496, 1280, -512, -1280, -3072, 3840, 19712, -12544, -2560, 18944, -3072, -2816, -9728, 8192, -6144, 6400, -1536, 4864, -6144, -512, -9728, 16128, -23296, 16384, -6912, -2816, -14336, -11008, 6912, -10496, -14080, -3840, 256, -1024, 6912, 2048, 9472, -14592, 768, 7168, -2816, -1024, 11776, -9984, 768, 3072, 25600, -8448, 9984, 4352, 1536, 12544, 1280, 9728, -3072, 2560, 5376, -8960, 5888, -1536, -9216, 2560, -2304, 768, -256, 3328, -16640, -10240, 9216, -6400, -7168, 1280, -9472, -5120, -3584, 7936, -4096, -8192, -4096, 1024, 3840, -2816, 6656, -4096, 7424, -10752, 11776, 1792, 9984, -256, -1280, -2304, 8448, -7936, 8960, -8448, -1792, 4352, 14336, -6144, 5632, 3584, -5632, -8704, 11264, 4096, 2816, -11776, 11008, -12288, -6912, 11008, 9216, -11520, 5376, 2816, 0, -25088, -5632, 22272, -32256, 13312, -11520, 8704, -7168, -4352, -7936, 5888, -9728, 5888, 6400, -2816, 6400, -16128, 5376, 3328, 4864, 12032, 7168, -5888, 5120, 5376, -1280, -3584, 28672, -7680, -17152, 9472, 11008, -3072, -14592, 8704, -2304, -7424, 13312, -4864, 3584, -13056, 0, 6656, -17664, 768, -4608, -6144, -8704, 7936, -3840, -8448, -9216, 2560, -5120, -9728, 16128, 0, 11264, -12800, 18432, 6400, -4096, -1536, 1536, 3840, 5888, 7936, 768, -5120, -2304, 4864, 16128, 4352, -4608, -1280, -3072, -22272, 7936, 6656, -9472, -7424, 12544, -10752, -3840, 3584, 2816, -4096, -7936, 11776, -4864, -3328, -9472, 15104, -23296, 12032, 1024, -2816, -6656, 9984, -7424, -6144, 12288, 2560, 9984, -2816, 11520, -13056, -256, -6144, 12032, -4864, 9984, -8704, -7424, -4352, 256, 14336, -6400, -4096, -3328, 0, 12288, -18176, 12544, 512, -512, -11520, -2560, 15104, -4352, -6400, 2304, 2304, 11264, 10752, -8192, -5888, -12544, 11776, -2816, -12800, 19456, -11008, -11520, -256, 10496, -2048, 512, 18176, -9216, -15616, 8960, 5376, -3328, -9216, 11264, -11520, 6656, -11520, -5376, 7168, -9472, 9984, -7424, 3840, 1024, -1280, 6144, -1792, 1792, 768, 17408, -20480, 6656, 6144, -5632, 2048, 6656, 7168, 2560, -6656, -768, 4096, -13056, 21760, -2048, -3584, -13824, 9984, -7168, -2304, -6400, 11776, -9984, -5120, 8704, 2816, -6400, -1792, -3072, -10496, 3072, -4352, -1280, -11008, -2048, 0, 4608, 3328, 2304, 7168, -10240, 8704, 0, 3328, 10240, -5120, 1280, 5632, -6400, -3328, 13056, 2304, -8704, 11008, -4096, -4608, 512, 8960, -1024, -7168, 3584, -9472, 1536, -2048, 7936, -12544, 2304, -7936, 15616, -14080, 8960, -11776, -9472, -3072, 8192, 18944, -15104, -7680, -5376, 1280, 9728, 768, 12288, -8960, -10752, 512, 7424, 20736, -2048, -9472, 6144, 10752, -7936, 4608, -2816, -5376, -17152, 25088, -4608, 2816, -6656, -3584, -19456, 2816, 18176, -17920, 7680, -13312, 9472, -11520, 15616, 1536, -8448, -11264, 14848, 6144, -4096, -13056, 12544, -7168, 13056, -1536, -3840, 11776, 2560, -6144, 9216, -1024, 1536, -7680, 11776, -16896, 13824, 6912, -4096, -8704, -5888, 23040, -15616, -12544, 5632, -768, -5632, 4352, -8960, -2816, -15104, 5888, 512, -6400, 17664, -6144, -6656, -7168, 9472, 3072, 2816, -16128, 6912, 4608, 768, 8704, -6400, 2304, -3584, 7424, 1024, 6144, 5376, -19712, 3072, 3584, 9472, 256, 11520, -16128, 256, 12544, -3584, -5888, -1792, -1024, -10752, 12288, -14592, 4608, -9216, 4352, 3840, -9472, 12032, 256, -10496, -3584, 2816, 12544, -8192, 8192, -9216, -4864, 5376, -2816, 9984, -7936, 11008, 0, -6144, 3840, 1536, 2304, -11776, 1280, 5376, -5888, 512, -7168, -3840, 15104, -3328, -7424, 12800, -1792, -11520, -3072, 5888, -256, 6912, 1536, -4352, 1792, -1024, -768, -768, 13568, -2560, 4352, -13312, 4864, 6144, -2048, -1792, 4864, -13056, -7680, 14080, -5632, -5632, 7424, -9728, -6400, 9984, 768, 8704, -21504, 6656, -9472, 10752, 3840, 1024, -1024, -4096, -8448, 7424, 4352, 11008, -23808, 6144, -1536, -5120, -3584, 27392, -7424, -9216, 17664, -5376, 2560, -1792, 18944, -17152, 9728, -5888, -2048, 6912, -8960, -12544, 7424, -2048, -1024, 1792, -2048, 1280, -9728, -7168, -8448, 5632, 17920, -9472, -2560, -14336, 6656, 1280, 1792, 15104, -5376, -14848, 2560, -512, 1536, 12544, -4096, -2304, -9728, 15360, 3328, 11008, -11008, 5888, -3584, -2304, 9728, 4352, -9728, -3840, 7424, 1536, -1280, -2816, -768, -1024, -16640, 11520, -3328, 6656, -3328, -1024, -1280, -9728, 12288, 0, 1024, -10240, 10240, -12288, 5888, 5376, 5888, -10752, 1280, -4352, 3328, -2304, 3072, -768, 1280, -6400, 8704, -6144, -768, -4608, 4096, -11264, 3328, 6912, -7680, 11264, -13824, 1536, -4608, -768, 1024, 5376, -6400, -3328, 5632, -5120, -3072, 9472, -2560, -2560, 1280, 6144, -4352, 5888, 2304, 0, 1024, 768, 3072, 6656, -6912, 4352, 2304, -10496, 17664, -256, 3840, -9472, 3840, -1536, 0, -256, 768, -3328, -5888, -4608, 6912, -1280, 5376, -4096, -10496, -512, 5120, 3328, -6912, 1536, -5376, 2048, 1536, 0, 1536, -1280, -5376, -5632, 18688, -10240, 1024, 1536, 5376, -2048, -1280, 7424, -12032, -256, 256, 4864, 768, -2560, -256, 512, -12288, -2816, 11520, -6912, 2816, -8448, -5376, 5376, 1792, 3072, -5632, 5376, -10240, 3328, 6912, -5120, 9472, 1280, -4608, -4608, 8960, 10240, -2816, 5120, -6400, 2560, -1024, 8448, 3072, -7424, 2304, -5120, -7680, 8704, 6144, -2304, -2560, -6144, -4096, 2048, 5632, 1536, -14848, -1280, -3328, 4608, 1280, -11008, 2560, -4096, -6400, 3328, 17920, -6400, -1792, -6400, -4864, 4096, 14848, -11776, -1280, 1536, -1280, 10240, -6144, 5632, 12800, -18688, -1792, 1792, 8192, 9984, -6912, -5888, -5888, 14336, -8960, 5376, 4352, -10240, 10240, -13312, 1024, 0, 12544, -7424, -10752, 6144, 2304, 7936, 512, -11776, 0, -2304, -1280, 2304, -7936, 16384, -1280, -11520, -6656, 10752, -1024, -8704, -2048, -768, 8192, -3840, -2048, 5632, -6144, 3328, -7936, -512, 7936, 2560, -2560, -4608, 2048, 6144, 5120, -7424, 512, 3584, 5888, 6400, -1024, -4864, 5120, -6400, -1280, -768, 5888, -2048, 13312, -10752, -4352, -1792, 7424, -6656, 512, -4864, 14080, -12800, -7168, 256, -2560, -1792, 1792, -10496, 4096, 5376, 256, -5120, 0, 4096, -4864, 3584, -9984, 22016, -4352, -8704, -16384, 18688, 0, 5120, -7168, 7680, -5632, 2304, 14848, -1024, -2048, -4608, -5120, 7936, -5376, 256, 6656, -12544, 1280, 10496, -6400, -3328, -1536, -1792, 1536, 2560, 10752, -7680, -6656, -11008, 2816, 11264, -13824, 7936, -2560, -2816, -4352, 6400, 8192, -11008, 16384, -5888, 768, -9472, 8448, -7680, -1024, -8960, 12032, -7424, 2304, 5888, -8704, -1280, 16384, -9472, 8192, -2816, -11264, 5376, 6400, -4864, 2048, 1536, -6400, 8704, 512, -4608, -5888, 9728, 5120, 1792, 5376, 256, -8192, -9472, 12800, -2304, -6400, 8704, -15616, 14080, -8192, 1792, -12288, 5120, 3328, 0, -8960, 4352, 2304, -10752, -7168, 3584, 10752, -8448, -6400, -1280, 5376, 10496, -15360, 8192, -1792, 9728, -2304, -768, 5120, -1024, 7424, -17664, 15872, -4096, 8960, -16384, 11520, 2560, 1280, -256, -4608, -4608, -256, 1280, 8192, 0, -5376, -3072, -5888, 7424, -3840, 3328, -9984, -768, -768, 1536, 8960, -6144, -5888, -1792, -512, 11264, -2560, -9472, 6400, 6400, -6400, -5888, 1792, 10240, 1024, -10240, -4608, 5376, -512, -768, 256, -4096, 11520, -6656, -512, -4096, 4608, 10496, -16384, 2048, -6656, 10240, 1280, -8192, 2048, 4608, -256, 3840, -256, 2304, 512, 512, -3328, -3072, 8960, -2304, 3328, -15872, -7424, 18432, 4608, 1792, -7680, 6656, -1792, -7424, 9984, -9728, 7936, -14336, -6400, -768, 4352, 512, -768, -11776, 8960, 1536, 6912, -9984, -768, 768, 7936, -6400, -4864, -512, 9728, 6656, -19712, 5632, 4608, 10240, 768, -5632, 16640, -12288, 8448, -4096, -9472, 19968, -8704, 256, -13312, 5888, 4096, 256, -9472, 4352, 3072, 256, -1024, 2048, -6912, -256, -2816, -4608, 6912, -5888, -2560, -2816, -4864, -1536, -1792, 13056, -18944, 4096, 5120, 4352, -3584, 1792, 1792, -3328, -2048, -1280, -2816, 9984, 5376, -1280, -11264, 7936, 16384, -9728, -4608, 5120, 10240, -1024, -2560, 2560, -5888, 5888, -1536, -5120, 2816, 2304, 2560, 1536, -5888, -2816, 256, 4352, -14336, 14336, -10240, 0, -4352, -15360, 21504, -20480, 4096, -3328, 1024, -6400, 3072, 4352, -10752, -6656, 13824, -7424, 3072, -1280, 9472, 4096, -15872, 24064, -1280, -512, -512, -512, -2304, 1280, 13056, -6400, -1280, -2816, 1280, 4096, -3584, -2304, 11008, -11264, -2048, 6912, 512, -256, 2304, -4608, -1536, 1280, 5888, -11776, -2304, 3328, 4096, -2560, -2560, -5888, 15104, -12032, -3584, 5888, 7424, -3840, -3584, -7680, 5376, -5376, 0, 3584, -768, 6400, -4096, -8960, -512, -2048, 8192, -4864, 5632, -5888, -9472, 7680, -8448, -4864, 2816, 3072, -8192, 12032, -1024, 6912, 2816, 2304, -8960, 9984, 7424, -4608, -512, -2816, 6912, -512, 3328, 0, 4608, -6656, 3840, -6400, 6656, -1024, 5376, -7424, -8448, 4608, -2048, -7936, -1280, 5376, -256, -9728, -7168, 10496, -4608, -1024, -5632, 12032, -3072, -11264, 14080, -20224, -1280, 4864, -2560, 6400, 1024, 5376, 3840, -7168, 3328, -1536, 11520, -6144, 6400, 2560, -6656, 1024, 512, 7936, 768, -1792, 768, 1280, -5888, 13056, -2304, -8192, -1280, 8960, -8192, -5376, -5120, 8960, -10240, -2560, 5120, -2048, 1792, -1280, -9728, -256, -6144, 9984, -6656, 5120, -4096, -2304, -6912, 6400, 8704, -8192, 256, 3072, -3328, 768, 9472, 3328, 768, -7936, 6912, 7680, 1280, -3840, -5376, 512, 2560, -3328, 4096, 9216, -2304, -15104, 10496, -2560, 15616, -15360, -8960, -2816, 1792, 1280, -7168, 7680, 1280, -5888, -16896, 8704, 12800, -6656, -4864, -2560, 2816, 2048, 2048, -8960, -1280, -2816, 14336, -6144, 2560, 8960, 4096, -2560, -4864, 7680, 1024, -2816, 5888, 0, -1536, 1536, 9216, -3840, 0, 3840, -3584, -6656, -2048, -1280, 3840, -7936, -11520, 10752, -7680, 0, -2304, 1536, -5632, 2304, -5632, 1792, -2048, 3840, -4864, -768, -3328, 7424, -3584, 2304, -4096, 768, -1280, -2560, 16128, 0, 1024, 1024, 5120, 4096, -5376, 4608, 7936, -6144, -4864, 7936, 13824, -9984, -1792, -4096, 1280, -768, 0, -7424, 4096, 1536, -7424, -6400, -13312, 12544, -2304, -16896, -768, 12800, -768, -512, -3584, 1024, -2048, 8448, -10240, 512, 3840, -1536, -4352, -1024, 2560, 12288, -4096, 3584, -2304, 6912, 2560, 512, 512, 10240, -8960, 1280, -2560, 1792, 7168, 256, 1024, -7680, -1024, 0, 256, -3584, -3328, -2816, 6656, -4352, 3328, -11264, -2304, -1536, -5888, 4352, 2816, 2816, -5376, -2816, 0, 2304, 2048, 2048, -7680, 7424, 2560, -6656, -3072, 3840, 4352, 1024, -6656, 3584, 4864, 5120, -2304, -6144, 9984, 5888, -2560, -8960, 2048, -1536, 4608, -6400, 3840, -4352, 10496, -12288, -7936, -1280, 12032, -3584, -5120, -1024, -1792, 1280, -4864, 768, 5376, 3072, -5888, 3840, -6144, 2048, 768, -6400, 512, 7168, 3584, 5376, 6400, -18432, 3840, 6656, -1536, 11520, -6912, 7424, -7680, -4352, 5888, 1536, -512, 6912, -11776, 3328, 2304, 3840, -14592, 6912, 256, -4608, 256, -2816, -512, -5120, -4096, -5888, 6144, 4608, -5376, -1280, -3840, -3584, 6656, -3072, 7680, -12288, 9472, -6144, -768, 5888, 2304, -1280, 2304, 2048, -11008, 5888, 6656, 1536, 7168, -7424, 7680, -2048, -3072, 6400, -4608, 8448, -12288, -1024, 7424, 256, -2048, -1024, -5120, 10496, -5632, 256, 3072, -8448, 0, -4352, -4096, 7424, -768, -512, -9216, 1536, -256, -2816, 1024, -6144, 10240, -6144, -1280, 6656, -512, -7168, 3328, -2816, 8960, -2304, -512, -768, -1536, 3328, 2560, 256, 2816, -5632, 5632, -6912, -1280, 5120, 2816, -256, 2048, -5888, 2048, 1792, -1792, 4352, -1536, 4096, -2304, -2560, 768, 3328, -768, -4352, 4864, -5376, 1536, -3328, -3840, -1792, 5632, -3840, -1792, 2816, -5120, -4864, -1536, 0, 7168, -2560, -1792, -3328, 2304, 1792, 256, -2816, -1536, 5376, -8448, -1024, 13312, -2816, -256, -512, -512, -1024, 8192, 4352, -7936, 1792, 3072, 512, -1280, 2816, -256, -1536, 256, 768, -2816, 1280, 1024, -3840, -2048, 2560, 1280, -4608, 1280, -6656, -2816, 5632, -3840, -5888, 5632, 4864, -7680, 768, 256, -1280, 2560, -4352, 2560, -512, 2560, 1792, -4352, -1280, 9216, -3072, -6144, 6912, 5632, -768, -2816, -1536, -1792, 5120, 1280, -5376, 0, 5888, -7936, -6912, 3584, 512, 2048, 1792, -3840, 0, 3328, -1792, -768, -5376, 8448, -1024, -6656, 1792, 1280, -1792, -1792, 256, 768, 1024, 2816, -6144, 1536, 2816, -1792, 3584, -2304, -2816, -256, 8704, -5632, 2816, 256, -4608, 4352, 1024, -4864, 7168, -3840, -1792, -2816, 3072, 256, -1792, -2304, -3072, 4352, -5120, 1536, 1280, 512, -2560, 3072, -5888, -768, 6656, -256, 1024, 1536, -6400, 3072, -768, -6656, 512, 3840, 3584, -4608, -1536, -4352, 3584, 1024, -2560, 5376, -3328, 1280, -3840, -5120, 6912, 1536, 2048, -2816, 4608, 3840, -8704, 4352, -512, -3328, 10496, -2304, -2560, -1536, -512, 1792, -2816, -1024, 7168, -6656, -1536, 6400, 4352, -9216, -512, 8448, -9984, -3840, 2816, -512, 6656, -8192, -7936, 5376, 6656, -2816, -6144, 3072, -4352, 1024, -8448, 6144, 3584, -2560, 3072, -4864, -768, 7168, 2816, -2048, 0, 6656, -4352, -1792, 2048, -1536, 5120, 6656, -7424, -6912, 6400, -3584, -512, 2560, -4096, 9984, -6144, -4352, -1024, -3328, 6144, -2560, -768, -5120, 6400, -256, -6144, 6144, -5120, -1280, 5376, -6656, 1792, 5376, -6656, 3840, 4352, 1536, -8704, 1280, 2816, -6912, 5120, 4352, -3328, -2048, -4096, 2304, 8448, -9216, 4864, 1280, 1024, -512, -8448, -3072, 9728, -4352, -2560, -1024, 4864, 3584, -1024, -8192, -10496, 16384, 1280, -9728, 7168, 1536, -512, -2816, -5632, 2816, 4352, 4352, -6144, 5888, -1792, 2304, 2560, -9728, 0, 6400, -2304, -1536, -6912, 5120, 512, -6912, 8704, -5888, 4352, -5632, 1024, 3072, -11008, 7424, -2048, 6400, -4864, 3328, -4352, -2816, 6912, -2048, 3584, -4864, 3072, 2304, -5632, -1536, 2816, -2560, 4352, -1024, 512, -768, 3840, -12032, 8192, -4608, 2816, 3584, 0, 2048, -8448, -3584, -3072, 5888, 4352, -3072, -1024, 3328, -6912, 2560, -4352, 5120, -512, -2816, -2816, 6912, 4608, -5376, -1536, 6656, -4608, 2304, -1792, 6912, -3072, 768, -2304, -2304, 5632, 1792, -9728, -512, 3584, -4096, 3072, -5376, -2560, 5632, 256, -7168, 5120, 7936, -2816, -12544, 2304, 4096, -1024, -1792, -1024, -1280, 11776, -9984, 2304, -4608, 4096, 5632, -6144, -3328, 3584, 7424, -2560, 768, -5888, 1024, 2816, -8448, 7680, 4608, -2304, 1280, -2816, 1024, -5120, 7680, -2304, -3584, -1792, -2304, 1024, 0, 1024, -3840, -2816, 5888, 1280, -6144, 6656, -1536, -2048, -4352, 5376, 0, 768, 3328, -2560, -3328, 4864, -4096, -2560, -1280, 2560, 2048, 5632, -4864, 1024, -2048, 0, -6144, 9728, 3072, -8448, 2560, -2304, 1280, -3328, 2816, 768, 1792, -4608, -3072, 2816, -1024, 2048, -4352, -1792, 4096, -2304, -512, -2304, 0, 2560, -512, -256, -256, 3072, -1536, 3328, -4608, 4608, -1536, 2560, 256, -768, 2304, -512, -7680, 5888, -2304, 7424, -2816, -7936, 2560, 1536, -5376, -4864, 13824, -7680, 4608, -3072, -6656, 5888, -2560, -7936, 5888, -1280, 12544, -8704, 1024, -4608, 768, 2816, -6144, 6912, 3072, -6144, 768, -3328, 768, 4096, -1536, -1792, 256, 4864, -2048, -768, -2816, 3328, -3584, 4864, 2560, 4352, -5376, 3584, -10240, 3072, 3328, -1280, -768, 5376, -3584, -7424, 4096, -6144, 256, 2560, -256, -768, 1536, -3840, -4096, 4096, -1024, 512, 5888, -8192, -256, 1792, -1280, 3328, 1024, -3840, 8448, 256, -1792, -1792, -3072, 3328, 1536, -2048, 512, 5376, 512, -5376, 4352, -3584, -4864, 9216, -512, -4096, -1024, 768, 2304, 3840, -9984, 768, 2304, -2560, -768, -3072, -1792, 7168, -4864, 2048, -4608, 5632, -4608, -2816, -512, 4352, 5888, -3840, -6144, 2816, 3328, -3584, -2560, 2304, 1024, 3584, -2560, -3328, 3328, -768, -3072, 6400, 1536, -3072, 3072, -4864, -768, 4864, -2560, -3328, 4864, 2560, 4608, -7936, -3840, 4864, -2304, -3584, -1536, 6400, -4608, 512, 4352, -10496, 2816, 4096, -5120, 768, -2560, 4096, 2304, 3584, -6912, -256, -768, 2304, -4864, 9216, -1536, -1024, -1024, -4096, 1280, -1792, 6144, -256, -7680, 3328, -2048, -1024, -2304, 12032, -9472, 768, 5376, -6144, 256, 768, 2816, 1280, -2560, -2048, 5120, -7936, 4096, 2560, -256, 0, -2304, -256, -1536, 3584, -1536, 1536, -4352, 5120, 768, -5888, 2560, -3584, 4352, -4096, -512, 6656, 1792, -5120, -2560, 2304, -4608, 7936, -8960, 768, 3584, -2048, 3328, -6912, -1024, -1024, 6656, -5120, -2304, 3584, 5632, -6912, -1024, 4608, 2304, 2304, 768, -3328, -5120, 3840, -3328, 1536, 3072, -1280, -1536, -3072, 0, 1024, -2560, 4608, -1792, -2048, -3840, 256, -2816, 4352, 1280, -2816, 3584, -1536, -2816, 1024, 2560, -1280, 3328, 0, -1792, 3840, -512, -4096, 512, -768, 2304, -1536, 512, 8704, -2816, -4352, -2048, 5376, 3328, -5376, -1024, 3584, -1792, -1792, -4864, 3328, -1792, 1024, -6400, 1792, 4096, -3584, -10240, -2816, 9216, 768, -2560, 1024, -2560, 1792, -256, -256, 1024, 3584, 1536, -3584, -3584, 4352, 5888, -3328, -512, -256, -3072, 2304, 2048, 256, -1792, 5632, -7424, 1792, 1792, 0, -6144, 3328, -2560, 4608, -256, -768, 3328, -6144, 7680, -8192, -1280, 4608, -512, -1536, -2048, 2816, -4608, -3072, 4352, -2816, 0, 1280, -1024, -3584, 7936, -3840, -4096, 3328, 3072, -1024, 1024, -1024, -256, -2816, -3840, 6656, -4608, 7424, -3840, -768, -2048, 1536, 1536, -8704, 5632, 0, 2816, -4608, 4096, 5120, -4864, -5376, -1280, 2816, 5376, 2560, 2560, -6912, -1280, 768, 512, -1280, 2304, -2304, -256, 256, -2816, -768, 2048, 1024, 256, -256, -2816, 4864, -256, -5376, -1280, -512, 2816, -512, -2048, 2560, -1792, -256, 512, -4608, 768, 0, 1792, 512, 1792, 256, 256, -7168, -3584, 2560, 4864, 3072, -5376, 1792, -4864, 5120, -512, -768, -256, 4352, -2816, -3328, -4096, 8192, 1024, -1280, -768, 1024, -1024, 4608, -512, -4352, -1536, 4096, -768, 1024, -3072, 1024, -512, 512, 1536, -4608, 5120, -6144, 4352, -2560, 4864, -4096, -4352, 2048, -1792, -1280, 4096, -3072, -4608, 2816, 2304, 512, -2048, 4352, -2304, -768, -3328, 1792, -1536, 7680, -3840, -2816, 1280, 3584, -512, -3840, -1280, 3584, 3328, -3072, -6144, -2560, 5632, -512, -2048, -256, 5376, -1280, -4864, -4096, 2048, 10752, -1536, -6912, -3072, 5888, 2560, -4352, -3584, 4096, 3584, -4096, -512, 2304, -512, 4096, -2304, -7936, 5632, 0, -512, 768, 1024, -1280, 5120, -6144, -1280, 3328, -256, -1280, -2560, -1536, 2048, -2816, 512, 2048, -2048, -1280, -2304, 256, -1536, 4096, -256, -4608, 1024, 2304, -768, 1536, -1024, 1536, 2304, -1792, -2304, -256, 2560, -1792, 1024, 768, -768, 1024, -2048, -1280, 768, -1024, 2560, 1536, -3840, 512, 768, -1280, -512, -768, -3072, 4608, 512, -4096, 1792, 3328, 0, -4864, -2048, 2816, -1536, -256, -2304, 1280, 3328, -2048, -1536, 1536, 1792, 2816, -2816, -1536, 3328, -512, -1280, -256, 2304, -512, -1792, -3840, 2560, 1280, -256, -3328, 2048, 0, -1536, -512, -512, 4608, -4096, -1792, 512, 768, -1024, 1536, -2816, 1024, 1536, 256, -1280, 5632, -2816, -1280, -1536, -768, 2816, -256, -256, 1024, 256, -1024, -3328, -1024, 2816, -2304, 256, 2304, -256, -2048, 256, -1280, -1792, 1280, -3584, 4608, -256, -3072, 2816, -3072, 4096, -1280, -2816, 2816, -512, 3840, -1792, -4608, -2560, 0, 4608, -3072, 2048, 768, 1536, -4096, -768, 768, 1536, 0, -256, -768, 1024, 2304, 768, -4352, -1792, 2816, 2816, -4864, 1280, 3840, -3072, -768, -3072, 1024, 2816, -4864, 0, 0, -3584, 5376, -3840, 512, 2048, 768, 2048, -2048, 1280, -4608, 2304, -512, -2048, 5888, -1280, -4096, 1280, 768, -5120, 3328, 2816, -1536, -3840, 1280, 1024, -3072, 512, 2560, -1280, -3072, 1280, -3584, -512, 4608, 2816, -3584, 0, 7168, -2560, -5120, 1024, 1792, 2304, -3328, -1536, 3840, 2816, -2304, -1536, 3584, -2048, 2560, 1024, -3072, 2816, -4608, 3328, -4352, -2304, 4096, -1024, -3584, -1792, 4352, -6144, -1280, 1024, 1536, -1536, 3584, 512, -6144, -5632, 2816, 3328, 2048, -4096, 1536, 3328, -7168, 2560, -512, 2816, 2048, -256, -2048, -3584, 5632, 768, -1280, -3328, 4608, 1792, -6656, 3840, 5120, -1536, -2560, 1024, 2816, 1280, -2048, -768, -1280, 0, -256, -1536, 0, 1024, 1024, -3584, -256, 256, 2048, -3584, -2560, -1024, 1536, 1024, -2048, 768, -2304, 0, 2816, -1024, -1792, 1280, 1024, 1536, -7424, 4608, 5632, -4864, -4096, -2816, 4352, 1792, -1024, 768, -5888, 5120, 2048, -4864, 768, 3328, 3328, -4096, -4608, 3840, -1536, 0, 768, 4352, -1792, -1024, 512, -5632, 5376, -256, -512, -256, -3840, 3328, 768, -1792, 1024, 0, -1792, 2048, -1792, 2816, 768, -512, -2048, 2560, -3840, 0, 2304, -3584, -2048, 2048, -512, -2304, 2560, -3328, 2304, 1792, -1536, 512, -3072, -1024, 1536, -3072, 2048, 3072, 768, -2560, 1536, 1792, 256, -512, -2816, -256, 1792, -1792, 2048, -3328, -2560, 2816, -2304, -2560, -2048, 5120, 2304, -2816, 2048, -1280, -1024, 1536, -768, 1280, 3328, -3328, -1792, -1792, 1536, 4864, 0, -2304, 2304, -256, -768, 1024, -1792, 0, -512, -1024, -1280, 1280, 0, -1280, 3584, -4864, -3584, 4608, -256, -1280, 768, -3072, 4608, -4864, 1024, -3840, -2560, 2560, 2560, -4352, -1024, 4864, -1536, -512, 1280, 2816, -1024, -768, 2304, -5632, 7168, -1536, -1280, 0, -256, 2816, -2816, -3328, 5632, 768, -2048, -2304, 256, 768, 0, 256, 512, 1792, -1280, -6400, 2560, 1536, 1536, 512, -2816, 2048, -4096, 3840, -5120, 1280, 2304, -1536, -3328, -1280, 3584, 1536, -5376, 5632, -1792, -3584, 1024, 6656, -2048, -3328, 2048, 256, -2560, -3328, 2816, 2560, -2560, 512, -3328, -2304, 3840, 0, 2560, -7680, 3584, 1792, -3328, -1280, -3072, 2048, 2560, -1024, 2560, 3072, -3840, -1792, 1280, 512, 512, 2560, -3328, -768, 0, 5376, -512, -4096, 2304, 768, -256, 1536, 3840, -768, -5376, 2560, -2048, 1280, 256, 256, 512, -4864, 2560, -1792, -768, -256, 2048, 1536, -6656, -2560, 4608, -7168, -768, -768, 1024, 0, -1792, 1536, -2560, -512, 6400, -4864, 1280, -2816, -512, 3584, 1024, -1280, -768, 1024, -1280, 1536, -512, -768, 2816, -256, 3328, -3072, 1280, 5120, -3840, -768, 4352, 1024, -3584, -1280, 2816, 768, 256, 1536, 2816, -5120, 2560, -1024, -1024, -1024, -1024, -4608, -1792, 1280, 2560, -6400, 1792, -2304, -3840, 256, -1024, 1024, 1024, -1024, -256, -4608, 2304, -1536, 1024, 1792, -4864, 2560, 0, 768, -1536, 3072, 4608, -1280, 512, 1024, -1024, 2816, 512, 1280, 512, 256, 768, -1024, 768, 1024, -768, -512, -2048, 2816, 1280, -2560, -3072, 3072, -1536, 1536, -2304, -1536, 1024, 2304, 0, -2304, 1024, 768, -1792, -1280, -3072, 4864, 512, -7168, 256, 0, 2304, -2560, -1536, 768, 768, -2816, -1024, 1536, 1792, -1792, -768, 1280, -3072, 2304, 2560, -3072, 1792, 1280, 1280, -1536, -2304, 4096, 1536, -4096, 768, 2048, -4352, 3072, -1280, 512, 256, 5376, -6400, -2560, 1280, -512, 3840, -1536, 256, 768, 1280, -4096, -512, -4096, 8192, -4352, 1792, -3328, 1536, -256, -1024, 0, -1024, 2560, -512, -4352, -1792, 7424, 0, -3328, -256, -256, 512, 3072, -1024, 768, -512, 1024, -4864, -256, 4608, 512, -768, -3840, -512, 2560, -1024, 256, -512, -1280, 5120, -1280, -1536, -1792, 2304, 0, -512, -6144, 1280, 3840, -512, -2816, 256, 0, -512, -3584, -512, -1024, 1792, 1024, -1024, -2304, 512, 1024, -2048, 2048, -256, 512, 2560, -3328, 1024, 2560, -1024, 6912, -5632, 4352, -4608, -512, 1280, 2048, -256, 1024, -1536, 512, -256, 2304, 256, -768, 4096, -5376, -4608, 512, 2560, -3584, 2304, 768, -3584, -2304, 0, -4096, 2304, -2560, 2816, -3072, -768, 256, -2560, 768, -512, 512, -3328, 3328, 2560, -256, 1024, 1024, 256, -768, 2304, 0, 1024, 2048, -3584, 2560, -1024, 0, 2048, 2816, -512, 512, -2816, 768, -3328, -2048, 2816, 1024, 256, -1792, 1024, -5376, 0, 256, -1024, -5632, 4352, -2048, -4096, 2560, 1024, -512, 0, -1024, 512, -512, 512, -1536, 2560, 768, 768, 1280, -256, 1536, 1280, 512, -1536, -768, -512, 1792, -1024, -1024, 3072, 256, -7680, 3072, -1792, 768, 1024, -1536, -1792, -2304, 2304, -256, 1792, -2560, 3072, -4096, 512, -2048, 5888, -1280, -1280, -256, -2048, 2560, 768, -3584, -3072, 6400, 1792, -3328, -1536, 1024, 3840, -768, -5888, 2304, 3072, -2304, -3328, 4608, -2304, 1280, 256, -4352, -1024, 3328, -2560, 2816, -2560, -256, 1536, 0, -1792, -512, 2304, -1024, 2304, -6144, 1792, 1536, -1280, 1024, 3840, -3840, 2816, -1280, -6144, 2304, 2816, -4096, 512, 0, -2304, -512, 2560, 1792, -3072, 2048, -3072, -1536, 2560, 1536, 2560, -3584, -1280, 5120, -4096, 1792, 2048, -256, -4864, 6144, 512, -2560, 3840, 1536, -1536, -5376, 768, -768, 3840, -2304, -768, 768, -512, -1024, -768, -2304, 1280, 0, -1280, -768, -3840, -1024, -256, 256, -3584, 8448, -3072, -4608, 2304, -512, -2560, 2304, 2304, -256, -256, -1280, 2560, -768, 512, 1024, 512, -2304, -256, 6400, -512, -768, 3840, -4352, -1792, 2048, -1792, 0, 2560, -3328, 2304, -2816, 0, -768, 4608, -3840, -2816, 1280, 0, -3072, -512, 1792, -1536, -1024, -2304, 2816, -1536, 2048, 256, -3584, 768, 4096, -2560, -768, 512, 1536, 1024, 2304, -2304, -512, 0, 512, -768, 3840, 768, -2560, -1024, -2048, -256, 2560, -3328, -2304, 4096, -2304, -768, -512, 1280, -1536, -1536, -2304, 2560, 2048, -1024, 3584, -1792, -4864, 3072, 256, 512, 256, 1024, -256, -1536, -768, -768, 1280, 1792, -512, 0, 0, -1280, 0, -1536, 256, 1536, -1280, -1024, 1280, -1536, 1280, -1024, -2048, 3840, -1280, -1792, 0, 768, -2048, 0, 768, -2048, -1024, 1536, -1024, -1024, 3840, -1280, -2048, -1792, 1024, 1792, -2560, -1536, 3840, -1024, -3328, 1792, 512, 512, 256, -1024, 1280, 0, 0, 256, 1024, -1792, 1024, 1024, -512, 1024, 1280, 256, -4608, 3072, 1024, -768, -1536, 2816, 0, -3328, -256, 256, -3072, 768, 3328, -2304, -3840, 1792, 0, -1024, -2048, 0, 1280, 0, -2304, 256, 256, -768, 0, 768, 1280, -2560, 1536, -256, -1024, 1024, 3840, -3840, -1280, -2304, 4608, -512, 0, 3840, -2816, -2304, 0, 1536, -512, 2048, 256, -2048, -2304, 1792, 768, -1792, -768, 1536, 256, -1280, 0, -1280, -1280, 0, -768, 2816, 256, -768, -2048, -1024, -1024, 1280, 2304, -1536, -1792, 1024, 3840, -3328, 1280, -1024, 512, -1536, -512, 0, 1280, 1024, -1024, 0, -1536, 2048, 768, -512, -1024, -1024, -2816, 1024, 2560, -256, -1024, -512, -256, -768, 256, -1024, -512, 768, 256, -1024, -2816, 3072, -1024, 1280, -512, 1792, -3072, -512, 1024, -1024, 1280, 2048, 256, -2048, 3584, -2816, -256, 256, 1024, 0, 1280, -1280, 512, -1792, -1792, 2560, 768, 256, -3328, 0, -1024, 1280, -2304, -256, 256, -2816, -1280, 1280, 512, -1536, 1280, -1280, -2048, 3072, -512, 1792, -256, -2560, -1280, -1792, 3584, 2304, 768, -1280, -512, 1280, 1024, -512, 0, -1280, 512, 768, 768, -3072, 1536, 768, 512, -2304, -256, 6144, -3328, -2304, -256, -512, 0, 1792, -1536, -4352, 3584, -3072, -1280, 2560, 256, -1024, -256, -256, 256, -768, 512, -512, -2816, 256, -256, -256, 256, 2560, -768, 512, 256, 1280, -1792, 256, -256, -1280, 1792, 256, 1792, -1024, 1280, -2816, -2048, -2048, 1792, 2048, 1536, 0, -3840, -256, 1792, 0, -1536, -768, 1792, -1024, -768, -512, 256, 1280, 2048, -1536, -1024, 2816, 768, -3584, -1536, -768, -1536, 2304, -1280, 1024, -1280, 512, 768, -3328, -768, 256, -1024, -768, 2816, -256, 0, 1792, -4096, -1536, 2816, 1280, 0, 1024, 1280, -512, -768, -512, 2048, 1792, -4096, 256, 512, 1536, 768, -4352, 2816, -512, -512, -2304, 1536, 0, -1792, 1536, -5632, -512, 3584, 768, -2816, 0, -1536, -512, -1792, -1792, 256, 1024, 3584, -256, -1536, 0, 1792, 768, -3584, 1024, 3840, -1024, -2304, -512, 3072, 3584, -2560, 1280, 2304, -2816, -512, -2304, 512, -2304, 2816, 512, -5376, 1792, 1536, -2816, -256, 0, 0, 256, -2304, 1024, 0, -2560, 256, 768, -768, -1792, 3072, -2304, -512, 1024, 1536, 768, -2048, 0, 256, -512, -3584, 3072, 2816, -1280, 2560, -768, -256, 768, -1536, 256, 0, -768, 2048, -256, -4608, 3072, 1280, -3328, -1024, 4352, -256, -1536, 256, -2816, 0, -1536, 512, -512, -512, 1280, 768, -4352, 512, -1280, 2816, -1024, 2048, 2048, -4864, -1536, 3584, -1536, -1536, 0, 1280, 0, -2048, 1792, 3328, -1536, -1280, 1536, -512, -2304, -256, 2048, 768, -1024, -1024, 2560, -2560, -2304, 1792, 512, -1536, 3584, 0, -3840, 768, 1280, -1024, -2560, 2048, 0, -1536, -2816, 768, 2560, -2304, 256, 2048, -1792, 512, -256, -1536, -2048, 1536, 512, -2048, -512, 4096, -768, -768, -256, 1280, -768, -2048, 1536, 2304, -1536, 256, -256, -256, 512, -1536, 1536, -256, -2304, 768, 2304, -2560, 256, 1280, -1024, -3584, 512, 256, 1792, -1280, 768, -512, -3328, 1280, 2560, -2304, -2048, 3584, -1536, -4864, -768, 4864, -768, -768, 1536, -1024, -2560, 768, -256, -1024, 1280, 1280, 256, 0, -256, 2816, 1024, -2560, 768, -1280, 1024, -1792, 256, 2048, -768, 256, 512, 0, -2560, 512, 1280, -3840, -768, 2048, -2048, -1536, 1280, -512, -1280, -1280, 2816, 0, -3072, -1792, 1280, 512, -1280, 512, -256, -1024, 512, 1792, -3072, 1280, 1536, -768, 1280, -256, 3072, 1792, -3328, -768, 0, 768, 0, 3328, -256, -1024, 0, -2304, 1280, -1536, 1280, -512, -2560, -1536, -512, 2304, -2048, 1280, -1536, -2560, 1280, 1024, -1536, -512, 256, 256, 1536, -3584, 2560, -768, -1024, -1280, 256, 2048, -4096, 1792, 1792, -256, 0, 768, -1280, 512, -256, -768, 2816, -2816, 2304, 2048, -4608, 768, 2048, 3328, -1024, -1280, -2304, 1024, -512, -1024, 2304, 1280, -1536, -1280, -3840, -768, 4352, -1536, 512, -2048, 1024, 1024, -1024, -3072, -768, -512, -512, -1024, 1280, -1024, 256, 1792, -3072, -1536, 2048, 1536, -512, 256, -768, 768, 2560, -768, 1792, -2816, 3072, 1024, -256, -256, 256, 0, -2816, 2816, 1024, 0, -512, -2304, -512, -512, -2048, -256, 1280, -1024, -1280, -1280, 256, 2560, -2048, -2816, -1280, -1024, 1280, -256, 256, 1536, -512, -1280, -1280, 768, 1536, -512, 1536, -768, 0, 1024, 1280, 512, 1024, -512, 256, 1280, -512, -1536, 2816, -256, -1280, 2048, -3584, 1536, -512, -1536, -2816, 1024, 512, -3584, 1536, -2304, 1280, -1024, -768, 1024, -3072, -512, 512, -1280, 1024, 1792, -1280, 768, 1536, -256, -768, -1536, 0, 1792, 0, 256, 1536, 2304, 1024, -512, -1792, -1024, 1792, 1024, 1024, -1280, -1280, 0, 768, -1536, -256, 1792, -512, -4608, -256, 768, -3840, 1280, -512, -512, 0, 1024, -2560, -1024, 768, 1024, -2560, 1024, -256, 1280, 1024, -1792, 2048, -1792, 0, 768, 512, -1792, 3328, 0, -512, -1536, -1536, 1280, 2560, -2560, 1024, -256, 512, -256, -1280, 1792, 1280, -768, -1792, 256, -1280, 2560, 256, -2816, 1792, 1536, -2560, -3840, 3072, 512, -1024, 256, 0, -1280, 768, 0, -512, 1536, -1280, -1024, -3328, -512, 768, 256, 1024, 768, 768, -2560, -1792, -1792, 2816, -512, 512, 512, -1792, 1024, -256, 1536, 512, 0, 2048, 768, 0, -1792, 2048, 768, 1280, -2048, -768, -512, 512, 768, -3072, -1024, -768, 3072, -3072, -1024, 1792, -768, -2560, -2560, -1024, 1536, -512, -2048, 2304, 256, 256, 256, -768, -1536, 3072, -1280, -1536, -256, 2816, -1792, 1280, 1536, 512, 2304, -2816, 1536, -512, 2048, 256, -1536, 1024, 768, -1536, -768, 1280, -1024, 1024, 256, -4864, -256, 768, 1024, 0, 0, -2560, -256, -768, -1280, -768, 0, 2816, -256, -3072, -512, 1536, 0, -768, 768, 1024, -256, -1792, 256, -512, -256, 512, -256, 0, 512, -512, 1024, -1280, -1024, 2816, -1024, -1280, -768, 1792, 1280, -2048, 768, 1536, -2304, 0, 2304, -1280, -512, 1280, -1024, -1536, 0, 1792, -256, -512, 0, -256, -1536, -2304, -1536, -256, 2048, 1024, -256, -2304, -1280, 3328, 512, -2816, -1280, 2304, 0, -2048, -256, 1280, -512, -1280, -768, -512, 1792, 1280, -1024, -3328, 768, 2816, -2048, 768, 0, 512, 1280, -3072, -1536, 1536, 768, -1024, -256, 2048, 256, -1280, -1792, -1536, 512, 2048, 1280, -512, -2304, 1792, -1536, -512, 3328, -1792, 512, 256, -256, -1280, 768, 1792, -256, -2816, 2304, -1536, -1024, -512, -1280, -256, 512, -256, 768, 2048, -1792, -256, -2304, 0, 0, -256, 512, 1280, -512, 256, -512, -768, 1536, 1536, -768, -1536, -1280, 1024, -256, 256, 1280, 256, -256, -512, -768, -1024, 1024, 768, 256, -1792, 1280, -256, 0, -2048, -1536, 256, 1792, -768, -1536, -512, 768, -256, -768, 512, 512, 0, -2304, 256, -512, 1024, 1024, -1280, 256, -256, 256, 1536, -512, 512, -1280, -1024, -256, 3584, -768, 512, -2304, 256, -512, -1024, 256, -256, 1792, -2304, 1280, 512, -768, 512, -512, -2304, -512, 1024, -256, 512, -512, -512, 0, -256, -256, -512, 768, 256, -256, -768, -1536, 768, 1792, -1280, -768, 2304, -1280, -1024, -1280, 2048, -1024, 512, 512, 2048, -2560, -256, 2048, -3584, 0, 1536, -1792, -256, 512, -768, 512, -1024, 1280, 512, -1280, -1024, 1280, 256, -1536, 768, 1536, -1024, -256, -768, 768, -1792, 0, 256, 0, -1024, 1792, 1536, -3328, -768, 768, 512, -3840, 2048, 768, -768, -1536, 2304, -1024, -256, 2304, 256, -1536, -1536, 1792, 256, 256, -512, 1536, -256, -1024, -256, -256, -1792, 1280, 768, 0, -1280, -512, 2048, -512, -2048, 1536, 1792, -4096, -1280, 1536, -1536, -256, 256, 1792, -1024, -768, -1536, 768, -2560, -768, 2048, -2304, -256, 1280, -256, -1792, 1280, 512, -256, 256, 1280, 256, 512, -1024, -1280, 256, 256, 768, 256, -1280, -512, 768, 512, -1792, -256, 1792, 1280, -1280, -1792, 1280, 0, 768, -256, -1024, -1024, 1024, 0, -1024, 256, 1536, -768, -1792, 0, -768, -768, -256, 0, -512, -1024, 512, 256, -512, 768, -256, 0, -256, -1536, 2304, -1280, 1024, -256, -256, 1024, -512, 1280, -2048, 512, -768, -512, 512, -768, 2560, 512, -768, -1280, 512, -1024, -256, -768, -1792, 2304, 256, 0, 0, -1280, 256, -512, -3072, 1536, 2048, -4608, 1024, -256, 1024, -256, 1280, -1280, -768, 768, -256, 1024, -1280, 2304, -1280, -1024, -1280, 512, 1280, -256, -1024, 0, -768, -512, 2048, -1280, 512, 256, -3328, 768, 256, 1024, 1280, -2048, 512, 2048, 256, -256, 256, -2304, 256, -512, -1024, 256, 1024, -768, 1024, -1024, -1280, 1536, 1280, -1536, -768, -768, 256, 256, -1792, 256, 512, 256, -1280, -1024, -512, 512, -1536, 1536, 768, 1792, -2560, -2304, 1024, 256, -1280, 1536, 2304, 768, 256, -512, -1024, 768, 1024, -256, -1536, 768, 256, -512, -2304, 1024, 1024, -1280, 1024, -2560, 512, -1024, -1280, -256, 256, 512, 0, 512, -2048, 256, 768, -1024, -3328, 0, 2560, -256, -1024, 1280, 0, -1024, 1280, -768, 512, -1280, 512, 256, 512, 1024, 512, 512, -2560, 1280, 768, -2816, -512, 768, 768, 0, -1536, -512, 256, 256, 512, -256, -2048, -256, -1280, -1024, -768, 1280, 2048, -1024, -1024, 512, 0, -512, -512, 256, -1280, 0, 3328, -2048, -1536, 1024, 2048, -1536, -256, 1536, -512, 1024, -1280, 768, 1280, -1792, -2048, -512, -768, 1792, 2048, -2048, -768, 256, 1280, -1280, -1280, 2304, -1024, -1792, -1280, 1024, 768, -1536, 1280, 256, -256, 768, 0, -1536, -2304, 0, -1536, 256, 1024, 2560, 1280, -3328, 0, 1536, -512, -1024, 512, -512, 1536, -256, -1024, 0, -2816, 1536, 768, -256, -768, 3584, -256, -3840, 256, 512, 768, -256, 1024, -768, -1536, 0, 768, 0, -1536, 2560, -768, -3584, -512, 2560, -768, -2304, -1024, 0, 1536, -256, 1792, -768, -1280, -1536, 256, 0, -1280, 2816, -512, 256, -512, 1280, -256, -1024, -256, -768, -1024, 512, 2816, 512, -1024, 256, 512, -3072, 1792, 768, -256, -2816, 768, 3840, -2048, -2816, 0, 0, 512, -1792, 256, -768, -1024, -768, -1280, -1024, 1536, 2816, -1792, -2048, -256, 1536, -1280, -768, 1536, 2048, 768, -1536, 256, -256, -256, -256, -1280, -768, 2048, 1792, 1024, -2304, 256, -512, -1024, -1536, 2304, -1024, 768, -2048, 0, 1536, -512, -1024, -512, -512, -1536, 2048, -1792, 768, 256, 768, -256, -768, 512, 256, -1536, -2304, 768, -1280, 2048, 1280, -2560, 1792, 1280, -768, -512, -256, -768, -256, -1024, -1792, 1536, 1536, 768, -1792, 0, 0, 256, 0, -1792, 768, -256, 0, 256, 512, 512, 512, -2816, -2048, 2304, 1536, 512, -1536, -256, 256, -768, 768, 256, -1536, 512, -768, -512, -256, 512, -1024, 0, -1024, -512, 0, -768, -512, -1536, 1280, 512, 0, -256, -768, -256, 768, 256, -512, 0, 512, 512, 0, 256, 1792, 256, -1024, -512, -1536, 1024, 768, -256, -1024, -256, 768, 768, -2304, -512, 0, -512, -256, -1280, 1536, 256, -1280, 256, -1280, 2304, -2560, -1024, 0, -1024, 1536, 256, -768, -1280, 2304, -512, -1280, 512, 0, 1536, -1536, 512, 1280, 2560, -2048, -768, -512, -256, 1024, -768, -256, -1024, 0, -256, 256, -1024, 0, 1280, -2048, -256, -1280, -256, -256, 768, 768, 768, 512, -3584, -1280, 256, 512, 768, 256, -256, 512, 1280, -512, 512, -1280, 512, 768, -512, -512, -768, 1024, 1024, 1024, -1536, 768, 256, -2560, 256, -1536, 1536, -512, -768, 0, -768, 256, -768, 256, -256, -1024, -1280, -1024, 1792, -512, -512, -768, 1536, -1280, -1280, 512, -1536, 256, 1024, 768, -2048, 2816, 1024, -1024, -256, 512, 768, -1280, -512, 256, 1792, -1024, 512, 1024, -2560, 1792, -1792, -256, 0, -768, 1280, -1024, -256, -1024, 1280, -1792, 768, 768, -2816, -512, -256, 1280, 256, -256, 0, 1536, -2816, 0, 256, -512, 256, 0, -256, -1024, 512, 2304, -512, -2304, -1024, 512, 0, 512, -256, 256, 256, -1792, 1280, -768, 1024, -256, -768, -2048, 1280, 1792, -256, -256, -768, 768, -1792, 0, 1024, -768, -768, 256, 1536, 0, -256, 0, -1280, -256, 0, -1024, 0, 0, -768, 256, -1024, 256, 1792, -768, -3328, -512, -512, -256, 768, 1280, 512, -1536, 256, 1536, -512, -1536, 2048, -256, -1536, 0, 1024, 1536, -512, 0, -512, -1024, 768, 1280, -1024, -1792, 512, 1280, -768, -768, 768, 256, -2560, -1792, 768, 256, -768, 512, 1024, -1792, -768, 0, 512, -1280, -768, 768, -512, 0, 768, 1280, -1536, -256, 1024, -512, 0, 1280, 256, -512, -512, 768, 512, -256, -768, -768, -1792, 1792, 768, -256, -512, 0, 0, 256, -512, 256, 0, -3840, -256, 768, 512, -768, 1024, 0, -1792, 0, -256, -256, -1024, -768, 512, -256, -256, 2816, -768, -256, -1280, -256, 512, 512, 0, 256, 512, 768, 1024, -1536, -768, -512, 256, 0, -1024, 512, 256, -256, -1280, 256, -256, -1792, 512, -512, -1280, 0, 512, -512, 768, 1280, 0, -512, -1536, 1536, -1792, 768, -1024, -1536, 256, 1536, 768, 256, -512, -768, -1024, -1536, -256, 1792, -512, 0, -768, 0, 2304, -768, -1280, -256, 768, 0, -256, -768, 1536, 256, -1536, -768, 768, 1536, 0, -1536, -1024, 512, 256, -256, 512, -1280, 1024, 256, -512, -1280, 0, 1792, -2304, 768, -256, 256, -1536, 0, -1280, -256, 256, -256, 0, -1024, 512, -512, -512, 256, 1536, -256, -1280, 0, 0, 0, 256, 768, 512, 512, -256, -768, 0, 256, 1280, 256, -1280, -1792, 512, 1536, -768, -768, -768, 512, -1792, -1280, 1280, 0, 0, -768, -1024, -256, 768, -1024, -1280, 256, 1280, -256, -512, -1024, 0, 1280, 512, 0, 512, 512, -256, -256, -1280, 1280, 768, -256, -1024, 256, 0, -256, -512, -256, 512, 512, -1024, -1024, 512, -512, -768, -1024, -768, 0, 768, -768, -512, -512, 1024, 256, -512, -512, 256, 512, -1536, -256, 512, 1536, 256, -512, 0, 1024, -768, -256, -512, -256, 1280, 256, -2816, 1024, 768, -256, -1536, 512, -512, 768, -1024, -2048, -512, -256, 1024, 0, 768, -512, -256, -512, -512, 256, 768, 768, -1792, 0, 512, 2560, 0, -1024, 768, -768, 0, 0, 768, -1024, 1536, -1024, -2048, 512, 256, 768, -3584, 256, -256, -512, 0, 0, -1280, -256, 512, -1536, -256, 768, 0, -1280, -768, 768, 256, 1536, -512, 0, 1536, 512, -1792, 256, 768, -1280, 1280, 2048, 0, -256, 256, -1024, -1536, -512, 1536, 1024, -1024, -256, 256, -2560, 0, -1024, 0, -768, 512, 0, -2048, 768, -768, 0, 512, -256, 256, -2048, -256, -256, -768, -256, 1024, 256, 1536, 256, 0, 0, -512, 0, -512, 1792, -1024, 768, -256, 512, 0, -512, -512, -2048, 768, 512, -256, -1024, 768, 0, -768, -1280, 512, -768, -768, -512, 1280, 512, 256, 256, -1024, 256, -256, 1024, 1536, -1024, 0, -1536, -1024, 256, 768, 768, -256, -512, -1792, -256, -768, 1536, -1536, 512, 256, 1280, -2048, -1280, -256, 512, -256, -768, -256, -256, 1280, -1792, 768, 768, 256, 1024, -1024, -768, -768, 2048, 256, -512, 1024, 1024, -512, -2048, 512, 256, 0, 512, 0, -1536, 768, -512, -2048, -512, 1280, -256, -1536, 0, 512, -256, -1280, -512, -512, 1536, 0, -1280, -512, 768, 0, -1280, -256, 1536, 1792, 512, -2048, -1024, 1536, 512, -1536, -1024, 3072, 512, -1280, -512, -1536, 256, 256, -768, -1792, -768, 2816, -768, -1536, -256, 768, -512, -1024, -1024, 1024, -768, 1024, -512, -768, 256, 1792, 0, -2048, 1792, 256, -512, -1024, -1536, 3328, 0, -768, 256, 512, -256, -1024, -768, 256, 768, -512, -768, -256, 0, 768, -256, -2560, -256, 512, -2048, -768, 768, 512, 256, 1024, -1536, -512, 256, -768, -256, -1024, 1536, 1280, -256, -1280, -256, 2304, -512, 0, -1024, 0, 256, -768, 1024, -1280, 256, 768, -1024, -1536, 0, 1024, -512, -1536, 2304, -256, -768, 512, -1024, 0, 1024, -1792, -1024, -256, 256, 1024, 0, -256, 1536, -512, -512, 1024, -768, -256, -1536, -512, 512, 768, 256, -768, 2048, -2560, -2560, 1792, 0, -512, -256, -1024, 768, -1536, 0, -1280, -1280, 1280, 768, -1536, 256, 1280, 0, -256, 256, -256, 0, 0, 0, -1280, 1792, -512, -256, 512, -256, 768, 0, -1536, 1024, -768, -512, -768, -512, 256, 768, 768, 0, -512, -256, -2304, 512, 512, -256, 1024, -1024, 1024, -2560, 1792, -2048, 512, 256, -256, 0, -256, 1024, 512, -1792, 1792, -1536, -1024, 768, 2816, -1280, -1536, 256, 768, -1024, -1536, 512, 512, -512, -768, -1792, -1024, 1536, 0, 1792, -3328, 1536, 512, -2304, -512, -1280, 768, 2048, 0, 0, 1280, -1280, -1024, 768, 0, 512, 1024, -1792, 0, -256, 2560, -768, -1536, 1792, 512, -256, 0, 1536, -512, -1792, 1024, -512, -256, -512, 256, -768, -2304, 1536, 0, -1024, 0, 768, 768, -2816, -1024, 1792, -4096, -512, 0, 512, 256, -512, 512, -1280, -256, 3072, -1536, 512, -1792, 512, 1536, 0, -1024, -256, 256, -768, 512, -256, 0, 1792, -512, 512, -1536, 512, 1792, -2304, -1024, 2048, 512, -2304, -768, 2048, 256, -256, 1024, 1280, -2816, 512, 256, -256, 0, 0, -1536, -512, 512, 1536, -3328, 512, -768, -2048, 256, 256, 768, -512, -768, -512, -1792, 1024, -1536, -512, 768, -2560, 1280, -512, 256, -768, 1280, 2048, -1024, -256, 512, -256, 1536, 512, 768, 512, -512, 0, -256, 0, 1024, 256, -256, -512, 1792, 256, -1792, -1280, 1792, -1280, 512, -1280, -1024, 0, 768, 768, -512, 0, -256, -2304, -1024, -2304, 2560, 256, -3584, 0, -256, 1536, -2048, -768, 768, -256, -1536, -256, 1280, 768, -1280, -256, 768, -1536, 1280, 1792, -2560, 1280, 1280, 512, -1024, -768, 2304, 1024, -2816, 0, 1280, -2816, 1792, -1536, 512, 512, 3072, -3840, -2048, 512, -768, 1792, -1280, 768, 768, 256, -2560, 0, -2304, 4352, -2816, 1792, -1536, 512, 256, -768, 0, -256, 1280, -512, -2560, -1024, 4096, -256, -1792, -256, -768, 256, 2816, -768, 256, -768, 512, -3072, -512, 3072, 768, -256, -2560, -512, 1536, -768, 256, -256, -1024, 3072, -256, -512, -1792, 1536, -256, -256, -4096, 1280, 2816, -768, -1792, 256, -256, -512, -1536, -1024, -1280, 768, 1024, -768, -2048, -256, 768, -1280, 768, 256, 512, 1536, -2560, 256, 1792, 0, 5376, -3840, 2816, -3072, 0, 256, 1024, 256, 1024, -1024, -256, 768, 1792, 0, -1280, 2560, -3840, -3584, 512, 1536, -2816, 1280, 768, -2560, -1536, -256, -2816, 1024, -2304, 1536, -2304, -512, 512, -2048, 768, 0, 512, -2304, 1792, 1792, 512, 512, 0, 768, 256, 1536, 0, 768, 1536, -2560, 1536, -1024, 256, 1792, 2304, -256, 0, -1792, 256, -2816, -2048, 2304, 1024, 0, -1536, 512, -4096, 0, 256, -512, -4096, 2560, -1792, -3072, 1792, 1024, -256, -256, -1024, 512, -256, 512, -1280, 2048, 768, 768, 1024, -512, 1024, 768, 512, -1024, -512, -256, 1280, -1280, -768, 2304, 512, -5632, 2048, -1536, 256, 768, -1280, -1024, -1536, 1792, 0, 1280, -2048, 2304, -3328, 0, -1536, 4608, -768, -768, -256, -1536, 1792, 768, -2816, -2304, 4864, 1536, -2560, -1536, 768, 3072, -512, -4608, 1792, 2048, -1792, -2560, 3584, -2048, 1280, 256, -3840, -1024, 2816, -1536, 2304, -2048, -256, 1280, 256, -1536, -512, 1792, -768, 1792, -5120, 1536, 1280, -1024, 768, 3072, -3072, 2816, -1024, -5632, 1792, 2304, -3328, 256, 0, -2048, -256, 2304, 1536, -2560, 1280, -2304, -1280, 2048, 1280, 2048, -3072, -1024, 4096, -3584, 1792, 1536, -256, -4096, 5376, 512, -2304, 3328, 1280, -1024, -4864, 512, -768, 3072, -1792, -512, 768, -512, -1024, -768, -2048, 1024, 256, -1024, -1024, -3584, -768, -256, 256, -2816, 7680, -2816, -4096, 2048, -512, -2304, 2048, 2048, -256, -256, -1280, 2560, -1024, 256, 1024, 768, -2048, -256, 5888, -512, -512, 3584, -3840, -1792, 1792, -1792, 0, 2304, -3072, 2048, -2560, 0, -768, 4096, -3328, -2816, 1280, -256, -2560, -512, 1536, -1280, -1024, -2304, 2560, -1536, 1792, 256, -3328, 512, 3584, -2304, -768, 512, 1536, 1024, 2048, -2048, -512, 0, 512, -768, 3584, 768, -2560, -1024, -2048, -256, 2560, -3328, -2048, 3840, -2304, -768, -512, 1280, -1280, -1536, -2304, 2304, 1792, -1024, 3584, -1792, -4608, 3072, 256, 512, 256, 1024, -512, -1536, -768, -512, 1280, 1792, -512, 0, 0, -1024, 0, -1536, 256, 1280, -1280, -1024, 1280, -1536, 1280, -1024, -2048, 3840, -1280, -1536, 0, 768, -2048, 0, 768, 0, -256, 0, -1024, 1536, -4096, 5632, -1792, 768, -1280, 512, 512, 256, -768, 1024, -2048, 1024, 1024, 0, -1280, -2304, 1024, -1280, -1024, 768, 512, 256, 768, -1024, 1536, -3840, -256, 1024, 256, -2304, 768, 256, -2048, 768, -1536, 2816, -1280, 1536, -2816, 4352, -3840, -512, -4864, -2816, 256, -1024, 2048, 0, 1280, 4608, -2816, 0, 3328, -1024, 1536, -3328, 1024, -2816, -256, -1792, -1792, 2816, 2560, -2304, 4352, -2816, 5120, -1536, 1792, -3584, 5888, -1792, -512, -512, 1792, -2560, 512, 0, 512, 1280, 1536, -2048, 1280, -1024, -2560, 2304, -1024, 1536, 0, -1792, 2048, -1792, 256, -5120, -1024, -256, -768, 1536, -2560, -1536, -3840, -2816, 2560, -1280, 4864, 768, 256, -4864, -2816, -256, -2304, 2304, 5632, 6144, 2560, -1280, -4608, -2048, -5888, 3584, 2816, 0, 7936, 11008, -2304, 0, -1792, -3840, -7168, -8960, -7680, 768, 1280, -1280, 2816, 13312, 14080, 1792, -1280, -2560, -3072, -6400, -11008, -3072, 1024, -9472, -12032, -5376, -1280, 1024, -2816, 256, 7936, 6912, 8704, 11776, 12288, 15616, 2560, 4096, 2048, 1792, -3584, -10240, -12032, -9216, -13056, -10752, -3840, 1024, 3072, -8192, -10752, -2560, -1024, 2560, 256, 3840, 12800, 7936, 1280, 3840, 9728, 9472, 7424, 3840, 5632, 2816, -1024, -8960, 2560, 768, -4608, 256, -3584, -8448, -1280, -12032, -6400, -3328, -512, 3840, -1536, 1280, -7424, -4352, -4864, -256, 768, 1792, 512, 4352, 7168, -2048, -5888, 1792, 1792, 9216, 3840, 512, 256, -512, -2304, 256, 1536, 5120, 1536, 3584, -768, 5376, -2816, -3072, -8960, 2816, -5120, -4608, -9216, -5888, -6912, -4864, 256, 2560, 3584, 6912, 1536, 11264, 3584, -2304, 768, 5120, 6912, 11520, -2048, -3328, 4096, -4096, 6144, -2560, -2304, -768, -9728, -4864, -3584, -9728, -9728, -10496, 3328, 10240, -9472, 1280, -1792, -1792, -1024, 1024, -7936, 8192, 5632, 3840, 2304, 3328, 2560, 2560, -4352, 5632, 7680, 2304, -1536, 6912, 16896, 12032, -4352, -5376, -5120, -2304, -9216, -18688, -768, 5632, -8960, -3072, 1536, 1792, 1024, -4352, -11520, 5632, 4352, -4352, 768, -2304, -1024, 2816, -2560, 3328, -1024, 2048, 9728, 768, 5120, 10752, -5632, 2304, 5888, -7168, -5376, 768, 2560, 256, 6656, -7168, -4608, -2304, 1792, -7680, -10496, -6144, -2304, 2560, -1536, 7936, -1280, 512, 7424, -2304, 256, -6912, -6144, 1792, -4864, -1280, 2560, -3328, 5376, 5376, 768, 7680, -2816, -4352, 8704, -2816, 2048, 1792, -2048, 256, 2816, -256, 1792, -3328, 256, -768, 5888, -3072, 2048, -4864, -768, 5120, -19968, 10752, -5888, 1024, -7424, -4096, -1280, 9728, -12544, 7680, -6656, 6656, 4096, 2048, -8448, 13568, 4864, -5120, 3072, 1280, 5888, -2816, 1024, -1536, 10752, -28416, 17152, -10240, 7424, -8192, -5120, -19712, 28928, -11776, -3072, 2048, -1280, -3584, 8960, -13312, 24064, -1280, -15616, 14848, -9216, 10496, -21248, 5376, -4864, 15616, -17408, 9472, -9472, 3072, 16896, -17664, -4096, 25600, -22528, 12288, 5376, -9984, 18688, -6144, -512, 11520, 16640, -15104, 13568, -26368, 24320, -24832, 256, -3584, -1024, -10496, 2304, -3328, -4608, 4096, -6656, 2304, 6656, -3840, 6400, -4096, 1536, 2048, 6656, -13312, 8960, -5376, 1024, -512, -2816, -1024, 5632, 0, 5376, -10240, 16640, -1536, -3328, -2816, -1792, 8192, -11776, -12288, 4096, -6656, -768, 0, -10752, 22272, -17408, 8704, 4352, -3584, 11008, 5888, -3840, 7680, 5120, 12032, -4864, -8448, -3072, 3840, 256, -9472, 3840, -3072, -2816, -1792, 3840, -19200, 9216, -10496, 6912, -2048, -1792, -3072, 2560, -1024, 12544, -1536, 10752, -8192, 1024, 5120, 8448, -16640, 6144, -13312, 2560, 3328, -4352, -3840, 15360, -3584, -14080, 8960, -4096, 12800, -21248, -768, 7424, 14848, -19200, 18176, -11776, 12032, -8192, 11264, -14592, 2560, -11008, 8448, 5632, -12288, 13056, -10496, 1536, 1792, 9984, -768, -10496, 1792, -2304, 9472, -16896, 5632, 6656, -3328, 18944, -22272, 32512, -9984, -4096, -7424, -2816, -2048, -14592, -3840, -11520, 13312, -18944, -1280, -512, 26368, -32256, 21760, 5120, 7168, -1792, 13568, -9728, 14848, -2560, -2816, 8448, -17920, 5120, 256, 10240, -9216, 6656, -14848, 14848, -5888, 15616, -18176, -1792, -9984, 11008, 5632, -4608, -256, -15616, 23040, -9472, 8960, -14848, 7680, -15872, 6912, -11520, 12032, -15104, -1536, -8960, 17920, -12544, 2304, -7680, 23552, -3840, 5376, 256, 6656, 1536, -4864, 23040, -11008, 12544, -11776, 2560, 1536, 3840, -23040, 17152, -13056, -2816, 1024, 7168, -9216, 6144, 10496, -17408, 6144, -8704, 16128, -10240, 4352, -7680, 4608, -9984, 3584, -9728, 3840, 2304, -13824, 13824, -5120, 9216, -5376, -3584, -3328, 2816, 5888, 2816, -13824, 14336, -6400, 9472, -11776, 12544, -18944, 20736, -10240, 13056, -11264, 14592, -17664, 13056, -12800, 15616, 6912, -28672, 28416, -29184, 27136, -21760, 12544, -15616, 19200, -4608, 6656, -17408, 8192, -3840, -6400, 5376, -3840, 9728, -11776, 20480, -30464, 32256, -21760, 10496, -10240, 19712, -16640, 7168, -1536, -9984, 11520, -22272, 9984, -16128, 20736, -8192, 1024, -8192, 11264, -6400, 10752, -3072, -3840, 5376, -256, -14336, 5376, 5888, -7680, 8448, -7168, -768, 8192, 1024, -9216, 15360, -5120, 3328, -768, 5632, -11008, 25856, -22528, 15104, -13568, 4608, 2048, 5632, -8448, -13312, 8704, -8192, 8960, -23040, 28672, -27392, 14336, -15104, 11008, -15360, -4608, -1024, -5376, 11520, 2816, -12288, 2816, 9728, -6912, 14848, -12544, 16640, 4864, 13824, -9728, 8960, -9472, 6144, -2816, 11264, -15872, 10496, -4096, -12288, -2048, 7936, -17408, 4352, -768, -1280, 13312, -13056, -2560, 4096, -6656, 4608, -7424, 14336, -10496, 768, 1280, -2560, -9472, 15616, -3584, -2560, -2304, 5120, -2048, 2048, -512, -4096, 11264, -4352, 3584, -8448, 7680, -512, -6912, 4096, 768, 0, 13056, -10752, 8192, -5120, 2048, -2816, -6144, 2560, 3072, -3840, 1536, -8192, 2560, 5376, -9728, -2816, -3072, 5888, 3328, -16384, 4864, 8704, -5888, -5888, 4096, 2560, 9984, 512, -9216, 14080, -7936, 0, -7424, 4608, 2048, 3072, -15616, 18688, -7168, 13824, -8704, 5376, 2304, 1792, 13568, -8704, -7424, 4864, -1792, -11264, 1792, 3840, -4096, -4608, -7936, 2560, -7424, 9216, -17664, 1792, 1024, 8448, -18432, 11520, 3584, 0, -2048, 8960, -3328, 6656, 4096, -7168, -768, -8192, 11520, -1024, 2048, -5120, 16640, -6144, 512, -6144, 10240, -4096, -4096, 5120, 2048, 512, -768, -512, 5888, -3840, -2816, -7680, 4864, -13056, -4864, -1280, -9216, 4608, 6144, -1024, -256, 11776, -23040, 15360, 1024, 5888, -4352, 4096, 15360, -6144, 0, 4608, 0, 1280, -1536, -6144, 6912, -8704, -7168, -1792, -1024, 5632, -7680, -2816, -768, -256, -11264, 9216, -9728, -1536, -2304, 14080, -8704, 4096, 6912, 7168, -16640, 15872, 5632, -8192, 9216, 1792, 512, 6912, -4864, 12800, -18176, 11264, -4864, -17152, 3328, -768, -3584, -7680, 8448, 1280, -3072, -12288, 15360, -12032, -7168, 2304, -1536, 6144, -2816, -256, 3328, 15872, -13568, 6656, 1792, -2304, 1536, 14848, -9728, -2560, 0, 1280, -5888, 5888, 2048, -3584, -4864, 5376, -2304, 8960, -4352, -7168, 3584, 6912, -4352, -3584, -7424, 6144, 1536, -21760, 18944, -4096, -4608, -512, -4864, 12032, -7424, -4608, -3840, 13312, 0, 1792, -2560, -5888, 11520, 3328, -2816, 3072, -7168, 6912, -6656, 4864, -17664, 18944, -14080, 8960, -5376, 10496, -6144, -2816, 9984, -4864, 1792, 0, 1792, -7936, 2560, 1792, -11520, -4352, 6400, -3072, 2304, -4864, 768, 7168, -13568, 19456, -4864, -6400, 12544, -512, 1536, -2816, 6144, -3072, -5888, 4352, -256, -3840, -2560, -9216, 6656, -6400, 0, -11264, 15104, -17152, 11520, -7936, 1280, 3840, 14336, -3072, -3584, 3072, 2560, 6144, -13312, 9472, 1280, -8960, 13312, 5888, -14080, -1536, 6144, -12544, 6656, 7936, -6144, 2560, -8448, 8448, -2816, 256, -12544, 2048, 1792, 1536, -19968, 3072, -5632, 2560, -2816, 3328, 3328, -4608, 9728, 12800, -4608, -1280, 16384, -13312, 15104, 8448, 768, -2304, -1536, -1536, 6656, -16384, 4608, -9728, -12032, 4608, -8448, 1024, -9984, 10240, -7936, -256, -5888, 12288, -7680, 4608, 4352, 8192, -5120, 8192, 4864, 6144, -14848, 12544, -9728, -2304, 3840, -7168, 4096, -768, -512, -7168, 8448, -5632, 5888, -256, -8704, 8448, -12288, 17152, -14080, 5376, 13056, -16896, -512, 5376, -1280, -4352, 6144, -16128, 13568, 2048, -4864, 2304, -2816, 9216, -9472, -8960, 11008, -8960, -768, -11264, 17408, -11008, 13568, -6144, -1280, 11520, -4096, -1792, 3584, 12544, 768, -4096, 5632, -2560, 512, -7168, -2304, -1536, -1280, 8192, -19456, -5632, 8960, -6656, -8960, -3072, 0, 768, 3328, 1536, 9216, 1792, -8192, 17664, -3840, 11520, -5120, -5376, 8960, 8960, 256, -6400, 2816, 8704, -6144, -8448, -2304, 1280, -6400, -12544, 7936, -10496, 3840, -10752, 6400, -7680, 10752, -20480, 8192, 512, -4608, 8448, -3072, -2304, 11008, -256, 1024, -3072, 13824, -13056, 5632, -256, 4608, 7168, -7424, 4608, 1792, 2560, -4864, 2048, -256, 3072, -5376, -1536, -2816, 1024, 1024, -7168, -2048, 5632, -6912, -1280, 2304, -6400, 5120, -4864, -9216, 10496, -2048, 5120, -8192, 4096, -7424, 7424, -3328, 3328, 1024, 256, 4352, 2048, 0, 2304, 5632, -256, -768, 7168, -2816, -9984, 9216, -7936, 1280, -2816, -6912, 5632, -9984, 1792, 3840, -6144, 4864, 2048, -9472, 19200, -13312, 13824, -16640, 5632, -3328, 5888, -6656, 8192, -4864, 2560, -2048, -768, 3072, 4096, -11264, 6400, -5888, 3584, 2304, -11776, 5120, 512, -1024, -2048, -1536, 4608, 1024, -512, -768, -3840, 1024, 4096, -2304, -1280, 8704, -7424, 6912, -13824, 25088, -16640, 2816, -4608, 4096, -3328, 0, -512, 0, 5632, -11008, 7936, -11776, 14848, 512, -6400, -512, 4096, -512, -7424, 4352, 4608, -6656, 5376, -4352, 1280, -1024, -2304, 0, -8704, 12800, -6912, -768, 1024, 7936, -768, -12032, 8192, -6400, 9216, 1536, -12032, 8448, -7168, 9984, -9216, 10752, -7168, 1280, -768, -512, 6400, 6912, -12032, 5120, 5632, -1280, -3840, 256, -2304, 4096, -6400, -2560, -11008, 10240, -3072, -4864, 5632, -6144, -1280, 3584, -11264, 10752, -8192, 8192, -11520, 10240, 10496, -4352, 6912, -11264, 9728, -4096, 3840, -9216, 9984, -3328, -4864, -1024, 8704, 256, -2304, 2304, -4096, -512, -7424, 7936, -7936, -1024, 8960, -5376, -13312, 16128, -10496, 512, -1792, 7680, -8960, 3328, 2304, 3840, -1024, 3584, -9216, 4608, -3584, 14080, -12800, -1536, 5632, -5888, -2816, -1280, 3072, 4352, -3328, -11008, 11264, -8448, 10496, -10752, 11520, 768, -3072, 6656, 2816, -2816, 8960, -19456, 9984, 512, 0, 768, -1024, 3840, -4864, -1536, -8448, 2816, 1280, 4096, -6400, -512, 4864, -1792, -11008, 7680, 5120, -6912, -4608, 3072, 3584, 8448, -12800, 3584, -3840, 5888, 2048, 512, -2560, -1024, 13568, -22016, 6144, -2304, 10496, -8704, -5376, 5632, 6144, -13824, 6912, 3328, 512, -2304, 3584, -7424, 5376, 10240, -11008, -2304, -768, 6912, -768, -5632, 4608, 2560, -5888, -3840, 256, 3584, -3072, 768, -7680, 7680, -5632, -7168, 9216, -3840, 9984, -14592, 5376, 768, -768, 8448, -3328, -512, 1536, 5120, -1536, 1024, -3328, -1280, -4608, 3328, -1792, 1792, 6656, -6656, 4096, 1792, -16384, 9472, -1792, 2560, -5120, 3072, -2816, 1792, -8704, 9472, -3072, -6144, 8704, -4608, -4608, 9984, 2304, -10752, -6144, 11008, 512, -4096, 6400, 3072, -4096, 2048, 3072, -11264, 8192, -2304, 5888, 256, -9472, 10240, -5888, -4352, 4608, -10752, 5888, -3072, -1792, 2560, -1536, 1536, -3328, -3328, 7680, -5888, 9216, -1024, 1792, 4352, -4608, 4608, -768, 2048, 1280, -256, -3328, -3840, 512, -1280, -4096, 1792, -13312, 5888, -9728, 7680, -7680, 4096, -6656, 5376, -5632, 6144, 768, 5120, -7168, 5632, 5632, -7936, 10752, -4096, -2816, 8192, -6656, 0, 7936, -3584, 2816, -3840, 3584, -4352, -2304, 2560, 2816, 6912, -9728, -1024, 3584, -4608, 9216, -11264, 0, -2816, 4096, -3584, -512, 4096, -8704, -5888, 5632, 1024, -6144, 3584, -3328, 4096, 7936, -7168, -2560, -1536, 13056, -6912, 3328, -12544, 768, 17408, -9728, 256, 2048, -6912, 6656, -4096, 0, 3840, -9216, 1792, -1536, 9728, -2816, 0, -3584, 2560, -1024, 5632, -12288, 7936, -256, 5888, -9728, 256, 3840, -1792, 2560, -256, -768, 1024, -256, 2560, -512, -3072, 768, -5632, 1280, 2304, 2048, 1024, -3584, 3072, -768, -1792, 5632, -5120, 768, -1536, 3328, -3840, -2048, -1792, 4096, -3584, -256, -768, 1536, -4352, 3072, 5632, -11264, 17408, -17152, 12800, 3328, -5120, -2816, -1024, -5120, -768, 5632, -3328, -5120, 7168, -1792, 512, 2816, -2304, -5888, 1280, 1280, -6656, 6144, -7936, 512, 5120, 3840, 512, -1792, 1024, 4864, -1536, 10496, -13056, -768, 6144, 6912, -7680, 6400, -9472, 256, -1792, -512, -1024, -6656, -256, 3072, 1280, -3072, 2304, -7680, 1280, 2816, 6656, -4608, -8192, 10752, 1792, 0, -5888, 2560, 2560, -5120, 13568, -12544, 1536, -9984, 4608, 768, -6912, 10496, -5376, 4096, 7168, 3584, -6144, -3840, 4864, 1280, 4096, -7936, -256, 11520, -6400, -1536, -4096, -1024, -4864, 9472, -12032, 5376, 512, -3584, -1792, 7680, -8960, 3328, -7680, 3584, 5376, 2816, -4608, -7168, 9472, 3072, -4608, 2304, 1280, -256, 8448, -10496, 768, -1792, -4864, 2048, -3584, 3072, 3840, -4608, -1024, 11264, -6400, 5632, -11776, 4864, 10240, -6400, -3072, -1280, 4352, 1792, -13568, 6400, 1024, -2560, 3584, 4096, -7936, 10240, -6912, -2816, -1024, 7168, -10240, -1280, -2304, -768, 8704, -12032, 8448, -1280, 2816, -8448, 8448, 0, -3584, 8960, -4608, -6912, 2816, 3584, -9472, 8960, -5120, 1792, 3840, 512, 6912, -4352, 3840, -7936, -256, 2816, -6912, 6144, -6656, 3584, 3328, -8960, 5120, -3328, -512, 4096, 4096, -1536, 512, 3840, -1792, -5632, 13056, -9216, -512, 5120, -4864, 5888, -5120, -4864, -2304, -3584, 2048, -1024, -3328, 8960, -16896, 9216, -9472, 768, 4864, -256, 3840, 8192, -11520, 18176, -3840, -1280, 3072, 8704, -8448, 6144, -1280, 5120, -11008, 10752, -15104, 3328, -3072, -17664, 16896, -7424, -8704, 4352, 1792, -7168, 6144, 1280, -6912, 13056, -10240, -2304, 11776, 768, -4352, 9216, -14336, 16128, -1792, -7936, -4864, 13568, -3072, -2560, 1024, 4864, -12032, 8960, 0, -10240, 4352, -3584, 3328, -2816, 2816, 768, -9984, 5632, 1280, 5376, -4864, -2816, 6400, -1024, -1280, 5120, -3328, 6400, -1536, -4096, -4096, 7424, -15616, 6400, -8448, 3072, -4352, 1792, -4864, 8704, -6912, 3840, -4864, 8192, -6656, 13824, -11776, 1536, 2304, 3584, -1536, -1536, 5888, -8192, 14848, -4864, -1280, 3840, 11776, -10752, 9984, -1792, -5888, -1792, -3584, -5632, 10752, -16896, 0, 1024, -2048, -2816, -1024, -768, -1792, 1792, -5888, 7680, -3584, 4864, 2048, -2304, 5120, 9216, 1280, -6144, 6400, 3072, -5120, 4096, -13568, 15360, -12544, -6656, 6144, -22272, 17152, -12544, 3328, -1792, 1280, -3584, 1280, 2816, 9728, -768, -3840, 6912, 6656, -9216, 5120, 7680, -12032, 7424, -1280, 2304, -2560, 9728, -16640, 12032, -12544, -1024, -2560, -1536, 256, -256, -7168, 4096, -3584, 768, -3584, 6912, -2048, 256, 512, 5888, 5376, -13568, 10240, 6144, -4096, -3072, -512, 2816, 4352, -2048, -4608, 2048, -6400, 7168, -2560, -3072, 3328, -13056, 2560, 8960, -2560, -2048, -2304, 2048, 2560, 3584, -5120, 1024, -2304, 9472, -1280, -512, 512, 1024, -2304, -1280, 4096, -4096, -5888, 3328, 1792, -2304, 3584, -12544, 3328, 2048, -768, -3328, -2304, 5632, -2048, 3072, -3328, 9216, -9216, 8960, -4352, 5888, -3072, 0, -9472, 12800, -7936, -2048, -7936, 11008, -1024, -2816, 0, 768, -1792, -4864, 4096, -4096, -7168, 11776, -7168, 6912, -3328, 8448, -5376, -256, 9984, -3328, 768, -1024, 1024, -9984, 18944, -7680, -4352, 8448, -768, -5120, -3072, 6144, -24064, 19200, -16128, 13824, -15872, 5888, 1024, 3072, -8448, 5632, -8960, 4096, 3072, -7168, 8704, 512, -3072, -768, 5632, 5888, -7936, -1536, 6656, 1024, -10496, 2048, 9472, -3840, 5376, -1792, 4608, -13056, 10752, -6912, 8960, -11520, 8960, -7680, 4608, 2304, -5120, 256, 4608, -3072, -13056, 15616, -15616, 6144, -5120, 256, 2816, -1280, -512, -3072, 2816, 5120, -8960, -512, 9472, -5376, 5888, -3840, -512, 4864, -13056, 20992, -12800, 5120, 7424, -6656, -8704, 12544, -512, -4096, 2816, -4352, -1024, 1536, 3840, -8960, 3328, -3840, -2560, -4352, 3840, 1024, -10752, 11008, -7936, 8704, -7680, 13568, -11008, 10240, -5632, 2304, 2304, -6144, 16384, -10496, 7424, -4352, 2048, -3840, 2048, 512, -6912, 1792, 2560, -7168, 0, 7680, -12800, 1536, -3328, -3584, -5376, 2816, 2304, 3328, -12032, 8960, -2816, 8192, 7168, -7168, 256, 8192, 512, -4864, 7168, -6144, 2304, 0, 4864, -1536, 4096, -8448, 1536, -5888, 8448, -7936, -256, -1024, 6656, -5632, -5632, -2560, -2816, 4608, -6656, 4864, -2048, -1024, 5376, -3584, 9216, -512, 3072, -12288, 12544, -256, -3328, -1280, 2048, -768, 2304, -1024, -4608, 3840, 7168, -12800, 2560, 1024, -1792, 1024, -9984, 9472, -9984, 2816, 512, -5120, 3328, 1024, -1536, 0, 8960, -4352, -2304, 1536, 9728, -5376, -256, -256, 3072, -512, -4096, 3840, 1792, -5632, 4608, -5888, 2816, 768, -2304, -9984, 7424, -7936, 11264, -10496, 0, 1280, 5376, -2304, -6400, 6400, -1536, 9728, -14080, 9728, -3584, 1536, -6656, 9728, -6144, 9984, -9984, -3840, 4352, 4096, -5120, -6912, 4352, 6144, -5120, -5120, 8448, 2048, -7936, 512, 512, 6912, 2816, -1024, -1792, 7936, -5120, -2304, 1024, -1024, 4352, -8192, 512, -4608, 7936, -8960, 9728, -13312, 10752, -256, -7168, -6656, 6400, 768, -13056, 10752, -8960, 8960, -9984, 11264, -9728, 5120, 5120, -13056, 8704, 11520, -2560, -1792, 6912, -4864, 8448, -12544, 5632, 512, -1792, -1280, -6912, 15104, -6144, -5120, 5376, -2048, -3840, 6144, -13056, 768, 2304, -5888, 6144, -7680, 512, 7424, -6656, -512, 1024, 2560, 0, -4608, 12800, 768, 2304, -3584, 4352, -4608, 6144, -3328, -8448, 1792, 6400, -12800, 512, -512, 7680, -14848, 7936, -2048, 5888, -2816, -256, -6144, 5376, 256, -10496, 12032, -7680, 7168, -9984, 14336, -4096, -5120, 13056, -11520, 8448, 1536, 5888, -3072, -4864, -512, 1792, 256, -3584, -1280, -2816, -5120, 6400, -4352, 1792, -5632, 5376, -4864, 8704, -12032, -512, 256, 8448, -7680, 3584, 5120, 1536, -2304, 4352, 3328, -5632, 4864, -14848, 5888, 6656, -3840, -13312, 512, 4608, 2560, -3328, 11776, -1280, -2048, -1536, 1024, -3584, 1280, 2816, -3328, -1792, 10752, -6400, 2048, -9472, 8960, -2560, 1536, -6400, 4096, 3840, -3840, -2304, -5120, 4608, -5888, 6656, -8704, 8960, -5632, -2560, 2304, 3584, -1536, -5376, 6912, -2048, 1024, 256, 768, -4864, 7168, 512, -1792, 7680, -2048, -3328, 2816, -2304, -2304, -4864, 3072, 0, -5888, -256, -5888, -1536, 6912, -7936, 10496, -7168, 3328, 1280, 2304, -5376, 1536, 512, -512, 4608, -4096, 7936, -6400, 10240, -9728, 9984, -3328, 2048, 3584, -768, 2304, -7680, 1536, -3072, -1792, -3840, 7680, -16384, 1536, -5632, 3328, -2048, 3584, -10240, 2304, 8192, -8960, 3584, -256, 3072, -6400, 16128, -6400, 8960, -512, 4864, -1280, -768, 5120, -7424, -256, 8960, -9472, 13568, -11776, 1024, -3584, 5632, -6912, 5888, -16384, 2048, 1280, -6400, 10496, -4608, 3584, -10752, 13568, -14336, 8960, -10752, 18176, -16128, 11520, -9728, 7424, -3072, 8448, -5632, 0, 6144, -3328, 768, 3328, 256, -2560, -4864, 2816, 4864, -9728, 1280, -512, -4608, -5376, 8448, -13824, 10496, 2304, 1024, -256, -5376, 768, 768, 9472, -7936, 8704, -10240, 8704, -4864, 7680, -6656, 5888, -13568, 14080, -2048, -3328, -4096, 1792, -3328, 11776, -9728, 512, -768, 4352, -256, -6656, 4608, -14592, 17408, -6912, 5888, -4864, 8192, -9984, 512, 512, -4608, 3072, -4096, 1024, -5888, 9728, -16640, 10240, -1280, 3328, 4864, -6656, -3328, 15360, -6400, 1792, 256, 2560, 5632, -6144, 5888, -5120, -4096, -4352, 3584, -8192, 6656, -1024, 4352, -3840, 2304, -7424, 1024, -7424, 2816, 9216, -4608, -4864, -512, 1280, 7168, -5888, 7936, 1536, 1024, 4608, -3584, 1024, -1792, 0, -11520, 15616, -7936, 1280, -3840, -5888, -5376, 13312, -15872, 1024, 5632, 256, -2304, 3840, -6144, -6912, 15360, -12544, 9728, 0, -1536, 256, 3328, 1792, 1024, 4864, 1536, 0, 6912, -7168, -3584, -5376, 4352, -256, -7680, 5888, 2560, -9216, 4608, -4864, 512, -4608, 0, 1536, -256, 1792, -256, -9472, 6656, 3840, -8960, 10496, -6144, 2560, 2560, -2304, -3072, 3072, 1792, 768, 2560, -2816, 2816, -3584, 6912, -12544, 18176, -14080, 6400, 2048, -2816, 2816, -1280, -5632, 1792, 3840, -4352, -2816, 4608, 1024, -13824, 11008, -9728, 6912, -256, 1792, -3328, 4864, 2560, -10496, 12800, -10496, 3328, 2304, 2560, -10496, 9728, -3328, 3328, -512, -512, -1024, 2304, -9216, -1280, 5632, -7936, -4608, 2048, 5376, -5632, 5376, -6144, 3072, 768, 4096, -6144, 6400, -4096, 5632, -8960, 3584, 768, 2816, 3072, -5632, 10240, -2816, -6400, 3584, 0, 3584, -512, 512, -2560, -3072, 3584, -13056, 2816, -5376, 14080, -6912, 2304, 768, 9728, 1792, -6400, 1280, -4864, 1536, -3584, 0, -2560, 5376, -14592, 8960, 4608, -5376, 5376, -10240, -3328, 6144, -6144, -3072, 2560, -256, 2816, 2560, -3072, -1280, 9728, -11520, 5888, 6656, -3328, -2304, 8192, 1536, -768, 7680, -7168, -7168, 6912, 768, -2560, -2816, -2560, 4096, -7168, 5376, -3072, -768, -256, -8448, 3584, -7680, 3072, -5120, 10240, -3840, 1792, 4864, -4608, -256, -256, 2304, 1024, -5888, 8192, 4352, -4864, 3072, 4096, -11520, 1024, -1536, 4608, -7168, 9216, -11264, 11264, -7424, 2560, 1024, 3584, -2048, -3328, 2304, -7680, 9984, -4352, -1280, 2560, -2560, 1280, -256, -4096, 4352, -1792, -2304, -2560, 3840, -5376, 2304, 2560, 2048, -2560, -1536, 768, -5376, 8704, -768, 1536, -1024, 3840, 768, -512, 1024, 6656, -11264, 7680, -11008, 512, 2304, -1280, -1792, -4608, 4096, -7168, 0, 1280, -1792, 0, 1792, 0, -1792, 5376, -3584, 4352, 3840, 512, -10240, 1792, 11264, -7680, 14080, -8448, -4864, 10240, -7680, 4352, -256, -5120, -5120, -5120, 1280, 3584, 256, -1792, -8192, 6656, -2816, -2816, 6144, -5888, 4352, 4352, 2048, -4864, 4608, 2816, -1536, 4352, -1024, -3328, 3584, -2304, 5376, 2304, -4096, -2048, 512, -4096, 768, -2304, -8192, 1536, -9216, -1024, 0, 2560, -9216, 6656, -2816, 768, 7936, -5120, 256, 1792, 1024, 11520, -8960, 9984, 0, 1024, 7168, -5376, 7424, -9984, 6912, 3840, -1536, -3584, 4352, -6400, -8448, 4096, -3840, 4608, -11008, 7168, -15616, 8448, 256, -6912, 3328, -4864, -5120, 6656, 2816, -6912, 4096, -5376, 8448, -3328, 11008, -11264, 3328, 6144, -2560, 8960, -9984, 9216, 5120, -9984, 17408, -17408, 5888, -4096, -1792, 0, 9216, -7680, -3328, -6912, 10752, -5376, -1024, -5888, -512, 5888, 0, -768, -768, 512, 1024, -3840, -1280, 7168, -2560, -5120, 6144, -1792, 6912, -14848, 7936, -1792, -7424, 9984, -10240, 10496, -8960, 2048, -6400, 7680, 7936, -4352, -2304, 768, 9216, -2048, -4608, -2816, 7424, -512, 1536, -6400, 5376, -1280, -2048, -4352, -6144, 5120, -6656, 5120, -5888, 11776, -6656, -3328, 2048, 3328, 512, -3840, 1024, -2304, 7168, -6400, -4864, 12544, 4608, -12800, 11520, -2816, -4352, 1280, -15616, 3840, 1024, -5632, -256, 5632, 5888, 8448, -14080, 11776, -6400, 9472, 4608, 512, -2304, 2816, -12032, 5888, -2048, -6400, 9472, -8192, 512, 1280, 3072, -4608, -1280, 4864, -6912, -1792, 5120, -10240, 8192, -11264, -5376, -7424, 14848, 2048, -2304, 14592, -7168, 7424, -8192, 3584, -3584, 1024, 5888, -8448, 4096, -1024, -4096, 5376, 9728, -9472, 5888, 2560, -8192, 4352, 4352, -3072, -15104, 2304, -768, -3072, 5632, -3328, -2048, -6656, 4096, 256, 8448, -2304, -4352, 4096, -1792, 5376, -11264, 6656, 1280, 8960, -9216, -256, 3328, 9216, -9216, 9984, -9216, 4352, -3328, 512, -8448, 5120, -3328, -13056, -512, 2304, -512, 8960, -5376, 4864, -5120, 4608, -4864, -1280, 7680, -9984, 7680, 5632, -8960, 18944, -13312, 8448, -3840, 4352, -5376, -3328, 2816, 1536, -6400, 6400, -7936, 7424, -4608, 4608, -13312, 10240, -2816, -4352, -6656, 14336, -14336, 17664, -13568, -3584, 8192, -2560, -2048, -512, 4608, -3584, 5120, -4608, 5120, 5632, -6912, 0, -6400, 14336, -11776, 4096, -7168, 13312, -1280, -8448, 19456, -19200, 9216, -256, -10752, 10752, -11776, 3328, -3328, 6400, -1792, 8960, -14080, 1280, 16128, -14336, 2816, -6144, 3328, -2048, -2560, -6912, 3840, -3840, 11264, -16896, 13312, -768, -1536, 0, 5888, -8448, 20224, -14080, 7680, -6912, 9472, -4608, -1536, -512, -4864, 13312, -5632, -12800, 15360, -8192, 7168, -14336, 11264, -7168, 3840, -9472, -2304, -7168, 16128, -19200, 2304, 9984, 7168, -5376, 1280, -4352, 3840, 512, -3328, 7680, 3328, -3584, 2560, -3072, 7680, -5632, -2560, 1024, -2048, -2304, 3584, 1536, -9984, 8704, -1536, 1024, 256, -1280, 0, 8448, -18688, 8704, -3072, 5888, -2304, 13568, -12032, 4352, 768, -4608, -1536, 512, -4864, -3072, -1792, -11520, 18432, -2304, -18176, 14080, -14848, 12800, -4608, -9216, 9472, 4864, -2816, 3328, -8960, 8192, 1536, 1280, 4608, -1536, 4864, -6656, 8192, 4096, 5120, -11008, 5120, -2560, -1792, 4096, -1792, -17408, 5376, -9216, 1792, 4864, -5632, 4864, -768, -8960, -9472, 6400, 5376, -14592, 17152, -2304, 2304, 8192, -2816, 7168, -4608, 8960, -10496, 15360, -4864, 7424, 0, -9728, 7424, -1536, -8960, 0, 6400, -9472, -256, -7936, -10752, 7680, -4864, -5376, 9216, -16896, 13568, -8448, 3840, 4096, -3328, 5120, -8960, 18688, -1024, 4608, 9984, 1024, 256, 768, 5376, -512, -3072, -4608, -13056, 11264, -4352, -12800, 12288, -7680, -4096, -3328, -8960, -1792, 6400, -8448, -3584, 3584, 0, 2048, -7680, 11520, -3328, 12800, -13568, 7168, 15360, -8448, 5888, -1792, -512, 3840, 9216, -2816, 2304, 4864, -11264, 1024, -5376, 4864, -1280, -6912, -11520, 12288, 2304, -12032, -5888, 3072, 768, -6400, -2048, -5376, 16128, 256, -7424, 7936, -4608, 4864, 4096, -6144, -4352, 12800, -16640, 16640, -14336, 23808, -11520, -4352, -6400, 11520, -4608, 5888, -13568, 12800, -3840, -3072, -9984, 13056, -2816, 2816, 3328, -7936, 13824, -3584, -7424, 5632, -2816, 2560, -10496, -4864, 13312, 2560, -13056, -15360, 18432, -3328, 3072, -9728, 4864, -512, 7936, -14336, 9472, -1024, -2560, 5632, -3584, -8448, 12288, -10240, 9728, -3584, 6912, -6144, 4864, 7424, 4352, -7936, -512, -10496, 8704, -4352, 512, 1280, 1280, -3328, -7680, 3584, 2304, -2304, 1792, -2816, 3840, 1280, -7168, -512, 0, 11520, -7680, -6400, 256, 2560, 7424, -14080, -6144, 13312, -1280, 1280, 5120, -6400, 5120, -3840, 3584, -16384, 24320, -13568, 8192, 3328, -6656, 7936, -2048, -6912, 4608, 12288, -14592, -768, -2560, 6400, -6144, -8192, -2304, 4608, 4608, -8448, -3840, 6912, -5632, 3584, -1280, 2560, 13056, -5376, -6400, 4864, 1280, -3840, -7424, 4096, 256, 8448, -9984, -3072, 14336, 3584, -16128, 9216, -512, -4352, 13312, -2816, -9472, 1280, 4864, -13312, 9728, -5888, -15360, 23808, -19200, 13312, -7680, -512, -2816, 12544, -2816, -6400, 256, 10752, -8960, 6656, -8960, -2304, 6144, -256, 2560, -1536, -3072, 1792, 1024, 5632, -2560, 10496, -6400, -2048, -1024, -512, 7168, -11008, 4864, -8192, 1024, -6912, 2304, -12032, 13056, -4096, 3072, -13312, 12544, 2048, 1792, -9472, 6912, -8448, 20480, -11264, 1536, 1280, 7168, -3840, 4096, 3840, 512, -3072, 12800, -19712, 9728, -9728, -11520, 7680, 2048, -9472, -3328, -2048, -4608, 12800, 768, -13824, 7424, 7424, -5120, 1024, 13312, -14592, 15872, -13312, -512, -2304, 15872, -16384, -1280, 6144, 5888, 0, -1792, -5888, 12288, 6400, -19968, -2304, 9728, 4608, -11776, 7680, -13056, 9984, 1024, -12288, 5632, 3840, 3328, -9984, 2048, 2560, 7936, -5120, -5632, 5376, -4352, 4352, -5888, 5632, 5632, -6144, -9216, 2816, 7936, -4096, -7168, 8704, -1024, 0, -5120, 1536, -512, 8960, -3328, -15360, 9216, 6144, -11520, 5376, -512, 9216, 0, -18688, 16896, -9472, 9984, -16896, -4608, 5632, 4352, -4352, -6400, 6144, 9216, -12032, 768, 6400, 1792, 2048, 0, 256, 3584, 5120, -5376, 1024, 5376, 3072, -19712, 4352, -1024, -3072, 7936, -14592, 9728, -2816, -1024, -7936, -1536, 7424, -8704, 2816, 3328, -5120, 20992, -9216, -9216, 10240, -7168, 19712, -17408, 3072, 512, 8704, -5888, 1280, -7936, 2816, -1280, 11264, -26880, 20224, -7936, -7424, -4096, 9472, 2048, 4608, -3584, -2304, 8192, -2560, -2816, -1792, 0, 10496, 8704, -14336, 1792, 3328, -512, -7936, 8448, -17152, 10752, -7936, -512, 5632, -12544, 4608, -8704, -2816, 9728, -10240, 14336, -4096, 3584, -512, 6144, 0, 0, 10496, -5376, -2048, 1536, -2816, 2816, 2816, -11520, 6656, 1024, -4352, -1792, -6656, -7680, 1792, -5376, -7424, 14336, -7424, 9472, -768, 512, -2048, -768, 5632, 2816, 10240, -3328, 14848, -1536, -9728, 12288, -5888, 3840, -13312, -3584, -1536, 12544, -16896, -5120, -2816, 8704, -8192, -11264, 10496, 1024, 5120, -15104, -6144, 19712, 5888, -6144, -4352, 10752, 4864, -768, -4864, -8704, 13824, 4352, -5632, -4352, 11776, -6144, -2304, 768, -5632, 10240, -12032, -12544, 18432, 1024, -4608, -12288, -8448, 14080, -1024, -10496, -13056, 26880, -6656, -768, -5632, 16384, 7168, -13056, 7936, 512, 3840, 6912, -15872, 4608, 5376, 1536, -3840, -13824, 13312, -3584, -11776, 1792, -7680, 8192, -256, 1536, -9472, 9984, -768, -5888, -5120, 6144, 5888, 4352, -6400, -1536, 17152, -9216, -2816, -9472, 14336, -20224, 768, 7680, 11520, -9984, -4352, -512, 5376, 512, -1024, -768, 768, 256, 4096, -4096, 2304, 7680, -9472, 2048, -1536, 11776, -16640, 768, 3584, -15104, 26624, -15360, 512, 11776, -7424, -7680, -512, -2560, 6144, -13312, 16128, -7936, 20736, -21760, 4608, 8960, 4096, -8192, -4608, -6144, 11520, -4096, -3840, -3328, 9472, -3840, -5120, -10752, 23296, -11520, -3840, -2304, -4096, 16384, -2816, -5888, 7936, -4608, 9728, -10752, 768, 3072, 256, 1280, -1280, 5632, -11264, 17664, -7936, -4608, 3840, 5376, -16384, -3328, 8704, -9472, 7680, -6656, -3840, 1536, -768, 11264, -7168, 2816, -768, -256, 4096, -4608, 6400, -3584, -6656, 17664, -14336, -1280, 7936, -13056, 6144, 768, -9216, 2304, 13312, -8704, 7936, 5376, -2816, -17408, 7936, -6144, 13568, -6400, -7424, 7936, 5888, -5120, 2304, -3840, -2816, 4864, 3072, -12032, 21504, -15360, -4096, -2816, 4352, -1024, -3840, 7680, -11520, 8192, 8704, -16128, -1792, 17408, 0, -8960, 4352, 1792, 8448, -7936, -2048, 1792, -8192, 11008, -3328, -4608, 3840, 7936, -8192, -8704, 1280, 2048, -4096, 5120, -6656, -7424, 8192, -2304, -5120, 4352, 8448, -7936, -3328, -1280, 22016, -13312, 5888, -4864, 512, 3328, 3584, -1792, -5120, 9216, -4096, -768, 2048, 0, 3584, -17664, 19456, -19712, 6400, -3584, -4352, 768, 9984, -3584, -11776, 7936, -512, -1792, 9472, -11520, -1536, 6144, 7168, -9472, 5632, 3328, -8960, 1024, 2048, 5888, 1792, -11008, 13568, -15104, 5888, 4096, 1024, -6400, -3840, 5888, -2304, -5120, 6656, -4608, -256, 6400, -768, -12288, 13568, 512, -11008, 1792, 3584, -8704, 3840, 7168, -8448, 13568, -512, -15104, 7936, -8704, 10240, 4864, -6912, 5120, -512, 2048, 512, 768, -2048, -2048, 1024, -14592, 15872, 6144, -18432, -1024, 4352, -4352, -768, -2560, -6656, 10752, -7680, 3072, -7424, 7936, -2560, 768, 6144, 512, 5376, -256, -9216, 13312, -1792, 5376, 3584, -8192, -4608, 18688, -11520, -1536, 2048, -3072, -16896, 5376, 6400, -4352, -1536, -8960, -3584, 6912, 6656, -12032, 10240, -13056, 14336, -4864, -6144, 7936, 1536, 1024, 2816, -768, 9472, -12032, 10496, -8192, 12800, 0, -18432, 6400, 4096, -4864, -256, -512, -1024, -10496, 5120, 1536, 2304, -768, -11264, 8192, -13824, 21248, -7680, -6656, -2048, 11776, -12032, 7424, 1280, -4864, 9472, -2304, -5120, 16640, -3584, -5376, -1024, 2560, 7168, -7168, 4608, -7424, 8960, -6400, 768, -4352, -7936, 1024, -1024, 0, -2304, 10496, -10752, -8704, 10240, -3840, 2048, -6144, -2048, 9216, 5632, -4608, -6912, 17920, -9984, 9984, 256, -1280, 14592, -13824, 3072, 9216, 768, -3328, -256, -8192, 17664, 1536, -16384, -12800, 3328, -3328, -8704, 5632, -3328, 0, -2560, -9728, 10496, -2816, -5632, -768, 2816, 1024, 9728, 5632, -2560, 6144, 8192, -5888, 5888, -1536, 2048, -1024, 5376, -15616, 16896, -8960, -10496, 1792, 1280, -7424, -4864, -11520, 5888, -512, 11776, -21504, 19968, -15104, 10240, -2560, -4608, 20224, -8960, -1280, -256, 9216, 4096, 3328, -5376, -7936, 13312, 512, -12800, 8704, -1280, -9216, -9472, 16640, -10752, 256, 4096, -10752, 8960, -2048, -12800, -1536, 10496, -4096, 6912, -10496, 5632, 16384, -12800, -2816, 7936, -4608, -4352, 1280, -768, 8704, 8704, -10240, -10496, 16896, -9472, 5120, -2816, -5120, 7424, -1280, -3584, -3840, 11520, -8448, -9472, -2816, 9216, -6400, 4608, -2048, 5120, 256, -5888, 15360, -8192, 0, 8704, -6144, -8192, 16384, -9984, -8960, 12288, -1792, -3328, 1024, -9984, 8192, 0, 256, -7936, 512, -3072, 11008, -9728, -2048, 6656, 0, -14592, 13568, 4864, -5632, -2560, 4352, -7680, 14592, 1536, -7936, 8448, 2560, 0, -12288, 7424, -1024, -5888, 1536, -1792, 7936, -9984, 3840, -10496, 9728, -4864, 1280, -9472, 5888, 2816, -7168, -3584, 15104, -12288, 2048, 5632, -5120, 12800, 3840, -8704, -6656, 17152, -2048, -3840, -5376, 13568, -6912, -2304, 3328, -6144, -8960, -2560, 2304, -3840, -3328, 4608, -9728, 7168, 5632, -3584, 512, -5632, 10752, -5120, 5632, 3072, -5120, 11520, -4096, 4352, -4096, 5632, 8704, -6912, -3328, -1792, 256, -5376, -256, 3328, -11264, 9216, -13056, -2048, 4096, -1792, -7680, -11776, 23040, -13824, 8960, 256, 2816, 2304, 1280, 256, -4864, 5120, 2816, 5376, -256, -12544, 10496, -1536, 0, 9472, -18944, 2304, 5120, -3072, -12032, 16640, -17408, 7168, -1280, -6656, 3840, 3584, -768, -5888, 2048, 4608, -5632, 3328, 768, 7936, -5376, -1280, 2048, 6144, -5376, 12288, -5120, -5376, 10496, -11008, 1024, 4608, 5376, -15360, 2304, -6912, 256, 3328, -3840, -8448, 3840, 5888, -12288, -2048, 13568, -12800, 256, 1536, -10240, 23040, -2560, -3840, 13056, -13312, 13568, 7424, -17408, 12800, 13312, -7680, -5376, 1792, -256, -2048, -7424, 2816, -12032, 1536, 4608, -3072, -6400, 13568, -8704, -5888, -1536, 4864, -1792, -3328, 1792, 1280, -512, 3584, 2816, -3840, 13056, -7424, 1536, 3072, 5120, -6912, 7424, -3072, 1024, -4608, -1280, 512, -4352, 2560, -4864, 512, -2048, -1280, 14336, -20992, 12544, 0, -10752, 12288, -6400, 4864, 1536, -10496, 4352, 8960, -4608, -4352, -7424, 6656, 2560, 1024, -6144, 6656, -8960, 12032, -9216, 512, 512, -5888, 6912, -10752, 14080, 0, -5376, 4864, 5376, -2048, 256, -768, -3840, 1792, 3072, -5888, -7424, 12032, -3072, 1024, -7168, 4352, 4096, -1792, -7936, -2048, 6400, -1536, 0, 3328, -5120, 1536, 768, -1792, 4864, -5376, -9472, 6912, 10496, 1792, -3584, 3072, -15104, 14592, 1536, -12544, -512, -2048, 0, 4864, 3328, -5120, -1280, 4096, 5888, 1024, -3840, -8448, 3584, 512, 3840, -6656, -7168, 2560, 11520, -4352, -6144, 3584, 4352, -9984, 5632, -2048, 12288, -13056, -256, -4096, 13312, -8704, -5376, 2816, 3328, 4608, -14592, 6656, 3840, 6912, -9216, -3072, 10240, -1792, -3584, 3840, -22016, 23296, -5120, -3328, -1792, 13568, -11008, 8448, -6400, 3328, 768, -9728, -4864, 7168, 7168, -4608, -18944, 14848, -768, 10240, -6912, -8704, 7680, 7168, -256, -5632, 512, 2304, -2048, -3072, 3072, 5376, -8960, -512, -4352, 4352, 512, -6912, 5632, -9216, 9728, -2816, 512, -5120, 1792, 5120, -7424, 9984, 2816, -768, 2304, -6144, 12032, -9216, 7168, -3584, -4096, 9728, -9472, 3072, -3840, 4608, -17664, 14336, -7936, 4352, -4096, -4608, -3328, 5376, -1536, -2304, -6400, 9472, 1536, -256, -512, 1280, -256, -6656, 9984, 1536, -768, -2560, 0, 3072, 7680, -3072, -7936, 6144, 3328, -3584, 2304, -5888, 7936, -11008, -4352, -512, 3328, -5888, -3584, -5376, 5376, 4864, -5632, -3072, 6144, 10496, -6656, 2560, 3072, 4864, -768, 2304, -3072, 6656, 3072, -13312, -1024, 4096, -768, 0, -11008, 1792, 1280, -3584, -2304, 3072, -7168, 3840, -5888, -512, 8960, -3072, -2048, -2560, 6144, 14592, -14080, 6656, -4608, 4864, 11264, -7680, 0, -1280, 12800, -14336, -256, 2048, -1280, -9984, 2304, 4864, -9984, 9728, -18688, 7680, -256, 512, 4096, -6144, 1536, 7424, -18176, 17920, -4608, -1536, 2048, 7936, 1024, -3328, 5888, -2816, 7936, -14336, 14592, -6400, 2560, 3840, -11264, -2560, 4096, -4352, -11264, 4608, -7168, 2560, 2048, -5376, -1024, -2304, 7168, 5120, -4096, 4352, -4352, -1536, 7680, 0, 2816, -5376, 6400, 6400, -256, 7936, -14336, 7936, 3584, -8192, 512, -4864, 1024, -4352, -6656, -3328, 10752, -15104, 3840, -7424, 13568, -1024, 256, -5888, 3328, 7936, 1280, -5632, 768, 7680, -7168, 512, -6144, 9472, 256, -768, -4608, 4608, 10496, -10240, 768, -10240, 12288, -7936, -1280, -5120, 1280, 2304, 0, -7680, -256, 6656, -3840, -1280, -1536, 13056, -6400, -6912, 1792, 11264, -2816, 2560, -8192, 3584, 11776, -7936, 1536, -2816, 9472, -8448, -3584, 4864, -1024, 5632, -12800, 6656, -11520, 5376, 256, -5888, 2560, -3840, 4352, -16128, 13568, -3584, -4608, 14336, -12544, 5376, 6400, -1792, 1024, -5376, 13312, -8448, 4864, 768, 2816, -2304, -1792, 0, -12544, 5632, -4352, 6400, -2560, -2816, 1280, -4864, 8960, -6656, 5120, -1792, -5376, 9472, -6400, 7424, -5888, 768, 1536, 4352, -6656, 6912, 1280, -4096, 2560, -2304, -6144, 2816, -1024, -4352, 2304, -1280, -3328, 256, -512, 2560, 1280, -3328, 5376, 0, 2048, 2304, -5632, 3072, 3328, -6144, -768, -5632, 10752, -4608, 768, -1024, -3840, 256, -512, 2048, -4352, -3328, -512, 256, 5888, 2560, -512, -7936, 5888, 4352, -3840, -2304, -6144, 7936, 512, 4864, -6144, 1024, -5632, 7168, -1280, -5120, 8704, -14592, 6656, 18176, -13056, 7168, -6144, -3072, 7168, 2560, -8960, -1024, -1536, 1792, -1792, 2048, -13312, 15616, -13312, 1792, -2304, -5376, 2304, 4608, -4864, 768, 8704, -13568, 14336, -7424, 5120, -2816, 5632, 1024, -256, 5888, 512, 256, 6144, -3840, 768, -8192, 3328, 5376, -9472, 1536, -2816, -6400, 5632, 1792, -512, -10496, 1024, 2560, -7680, 9984, -6144, -1792, 2048, 3072, 2304, -256, -8960, 3328, 768, 2304, -4608, 5376, 6656, -3584, 10496, -2048, -8960, 7936, -7424, 4352, -5120, -3072, 5120, -7680, 6912, -6656, 5376, -2304, -1536, 1280, -3584, 768, -2816, 3840, 512, 2048, -3584, -1280, 5120, 1024, 0, -7936, 2304, 1024, 6400, -6144, 1280, -1280, -3328, 6912, -1792, -8192, 256, -1280, -2560, 7168, 1792, -1024, 2816, 2560, 5632, -768, -5632, -3840, 1536, -768, -768, -6912, -6400, 1280, 2048, -2560, -4352, 4608, -4608, 3072, 8192, -4608, 256, 6400, -6400, 12800, 1792, 512, 0, -768, -768, 4096, -5120, 2304, -3584, -3840, 5376, -6912, -768, -4352, 5888, -7936, -1024, -4608, 7936, -5376, 1536, 0, 4608, -4096, 6912, 768, -1792, -4352, 4352, -3840, -2816, 4864, -4096, 1536, 256, 3072, -4608, 1280, -1536, 6144, 0, -4864, 5632, -5888, 11008, -8960, 4608, 5632, -10240, 256, 3072, -1024, -4608, 6656, -13568, 8704, 256, -2560, 256, -4608, 6912, -6400, -6144, 8448, -7936, 2304, -11008, 13568, -7424, 8448, -4352, 1280, 5888, -1792, 512, 5888, 7424, 256, -2048, 5120, -2560, -256, -5632, -768, -4352, 1024, 5632, -15616, -5888, 7936, -6656, -7424, -3072, 512, -768, 3072, 2560, 6656, 1280, -7424, 15616, -2304, 8192, -4608, -3584, 7424, 7936, 512, -4864, 2304, 7936, -5120, -7936, -1792, 1280, -5632, -12032, 7936, -10240, 3840, -9984, 5632, -6912, 10240, -19968, 7936, 1024, -4864, 8448, -3328, -2048, 10496, -256, 1280, -3072, 13568, -13056, 5632, -256, 4608, 7168, -7424, -256, 0, 0, 2816, 3328, -512, -1792, -1280, -768, -768, 256, 512, -1536, 0, 768, 2048, 2304, 1280, 0, 3584, -1280, -7168, -9984, -9984, -9216, -9472, -6912, -11008, -12544, -3328, 1024, 1536, -1792, 0, -256, 768, 5888, 9984, 7424, 8960, 10496, 5376, 8960, 0, 0, 5376, 15104, 17152, 7936, 5376, 3328, -768, 4608, 8704, 7168, 1280, 768, 3328, 768, 0, 3072, -1792, -8448, -6912, -9984, -3584, -8704, -12800, -7680, -9472, -8960, -13568, -18944, -17920, -15616, -15872, -15872, -12800, -11264, -15616, -9216, -768, -5888, -3840, -3072, -4352, -5120, -1536, 2816, -1536, -3072, -1536, -4352, 1792, 11776, 18176, 22272, 20224, 17920, 19712, 26624, 27904, 16896, 9472, 8704, 6912, 7936, 10240, 11008, 7936, 5888, 4352, 512, 2560, 6144, 8192, 16896, 14336, 4352, -3328, -14080, -13824, -5376, 4864, -4864, -14336, -19712, -9472, -6912, -2560, -1536, -9728, -9216, -9472, -768, 5888, 6400, 6400, 4864, 8960, 8704, -1792, -1280, 7168, 15360, 16896, 16640, 13056, 8704, 5632, 13568, 13056, 3840, 5120, 2816, 5376, 5376, 4096, 6144, -512, -5888, -9216, -8960, -5376, -7424, -13056, -13056, -12032, -14592, -21760, -20480, -17920, -25600, -24832, -20992, -19968, -19456, -16384, -13056, -14336, -13824, -12544, -17920, -15872, -13568, -13824, -15360, -14592, -16640, -19968, -19456, -15872, -9984, 0, 7936, 3328, 1536, 7936, 13824, 14080, 11008, 7680, 3328, 2304, 7936, 5888, 11008, 7168, 6144, 9216, 9216, 6144, 7680, 13824, 17920, 28928, 26368, 19200, 1024, -768, 10240, 14080, 12800, 5888, 2304, 6400, 7424, 12288, 10496, 7424, 3584, 1536, 10240, 16128, 12544, 9984, 18176, 20480, 16384, 5376, 3072, 4352, 7424, 17408, 18176, 13312, 9216, 6144, 9472, 6144, 256, 1280, 768, -1536, -1024, 256, 3328, -768, -5632, -8960, -7936, -6912, -14848, -15104, -11008, -14080, -18176, -19456, -18176, -22528, -26368, -24320, -25088, -21760, -19712, -17408, -18176, -14848, -12800, -12032, -13312, -11776, -10240, -12032, -11264, -12288, -14336, -15360, -23296, -24576, -17408, -3840, -1536, -4096, 2304, 768, 7424, 7936, 7424, 2048, 2560, -1536, 1280, 2560, -1536, -1024, -1536, 3840, 1792, -512, 512, -1280, 7680, 23296, 27392, 18944, 2048, -768, 3584, 6912, 8192, 6656, 4352, 5376, 4608, 8704, 12544, 5120, -768, 512, 7680, 10752, 5120, 9216, 17408, 20224, 20736, 13312, 6912, 5632, 9472, 20480, 24320, 19712, 19712, 18432, 18944, 14592, 14080, 14336, 10496, 8960, 5632, 10240, 14848, 8192, 5888, 6144, 6656, 0, -1792, 1536, -512, -4096, -6656, -7936, -11520, -11776, -16384, -19712, -20224, -18688, -18432, -19200, -15104, -12544, -14336, -8960, -12288, -11264, -12800, -11008, -15104, -14848, -10240, -19968, -30464, -31488, -24320, -18688, -10240, -13312, -11520, -7424, -4608, -768, -256, -2816, -5376, -7168, -3072, -6144, -7424, -5376, -7424, -4096, -768, -1280, -7680, -10240, 256, 17664, 24576, 19968, 7936, 3584, 5888, 4352, 4864, 8448, 5120, 2304, 2304, 11520, 12800, 3584, 768, 3072, 3328, 4096, 1792, 3584, 8960, 13824, 19200, 14336, 6144, 256, 4608, 12032, 12032, 15360, 15872, 16896, 17664, 11776, 13824, 13568, 9728, 2816, 4608, 11264, 10496, 7168, 8448, 9472, 5632, 3584, 3840, 3328, 3328, 256, -256, -3328, -1536, -2816, -9728, -8448, -12032, -10240, -11776, -7936, -7424, -5632, -2304, -1280, -2304, 2304, 1024, -5888, -3584, -1024, -768, -6656, -17664, -22272, -18944, -15360, -10752, -12544, -8448, -7168, -4096, 2304, 512, -4096, -5632, -6400, -6400, -8448, -8192, -11264, -14848, -10496, -2816, -4864, -13056, -19712, -11008, 6144, 12032, 12544, 8704, 5376, 1280, -2304, 1280, 4608, -2560, -3584, 512, 5888, 6656, -768, -1792, -1024, 512, -768, -2560, -1024, -1536, 9728, 16384, 12800, 6400, 256, 2816, 4352, 5376, 9216, 14848, 15872, 11776, 11776, 15616, 14336, 6912, 2816, 5120, 4608, 6912, 3840, 7936, 6656, 5888, 4352, 1792, 4096, 0, -2304, -2560, -768, -2048, -3584, -6400, -9216, -14336, -10496, -9984, -12800, -7680, -3072, -5888, -2048, 2560, 5888, 4352, -512, 768, 3584, 6656, 1792, -8448, -12288, -13568, -13312, -8960, -7680, -7680, -5888, 768, 5376, 4352, 2048, 1792, -2048, -256, 0, -1536, -7424, -12800, -6656, 2560, 1280, -9728, -16384, -10496, 1280, 5632, 12544, 16128, 9728, 5120, 3328, 6656, 3840, -1792, -2304, -256, 7168, 2304, 256, -1024, -3072, -256, -1280, -5120, -9728, -8192, 1536, 9728, 9216, 4096, 2560, 0, -2048, -3328, 3840, 10496, 6400, 7680, 7680, 13312, 8960, 4352, 2048, 768, -1280, -1280, -1536, 1024, 1792, 1024, 1024, 768, 768, -5120, -6400, -5888, -7168, -5632, -4608, -12032, -12800, -13824, -15872, -17152, -15872, -12288, -11008, -11264, -7936, -2560, 4352, 2560, -2048, 256, 5632, 6144, 4352, -256, -5376, -10240, -9984, -6656, -9728, -8192, -5376, 512, 4352, 6656, 7424, 4608, 1280, 3840, 8960, 4864, -2816, -9472, -2304, 8448, 4352, -1536, -7680, -5888, -2560, 5632, 16640, 18688, 18176, 12032, 14592, 16896, 9728, 3840, 4096, 5888, 8704, 8960, 6912, 2560, 2816, 5376, 8192, -1024, -6656, -7424, 1024, 7424, 7168, 9728, 8192, 4352, -1536, -1536, 4352, 8192, 5376, 7936, 9984, 12544, 9216, 6912, 6400, 3328, -256, -2816, -2048, -256, -3840, -2816, 1024, -1792, -2304, -3584, -9728, -11776, -8960, -7936, -11008, -13568, -13824, -18432, -21504, -22528, -22016, -20224, -18688, -22016, -17664, -10240, -4096, -5888, -7168, -3328, -2304, 1280, 1280, -2560, -8704, -11520, -12288, -13312, -15616, -15104, -10752, -9728, -2304, 3328, 4864, 2048, -3584, 4608, 10752, 7168, -4608, -7936, -768, 2816, 5376, 3328, -2304, -4352, -5632, 2304, 14592, 18176, 15872, 17408, 21248, 20992, 16640, 9728, 9728, 7936, 13312, 14592, 11520, 5888, 6400, 13056, 14336, 5376, -512, -2048, 1792, 5376, 7168, 14080, 14080, 9472, 3840, 4352, 7680, 7680, 7680, 12288, 14080, 16640, 14080, 13824, 15616, 10752, 6144, 5632, 3328, 1536, 1536, 1024, 1024, 4352, 4864, 256, -5120, -5888, -6400, -6912, -6656, -11264, -11264, -15872, -20224, -23296, -21248, -19456, -25344, -26624, -22272, -16128, -13056, -10240, -10752, -10240, -7424, -4096, -1536, -7936, -10240, -12032, -16128, -17408, -20736, -19456, -20736, -19200, -12544, -3840, -1280, -8704, -9728, 512, 3840, 2048, -7424, -11008, -8448, -4608, -2816, 2048, -2304, -10752, -11520, -3584, 6400, 8448, 10496, 13824, 17152, 19200, 18176, 11776, 7680, 5888, 13312, 14080, 9728, 5120, 6400, 13568, 15104, 8960, 4352, 1536, 768, 1280, 6912, 16384, 15616, 12544, 10240, 10240, 11520, 9216, 9728, 16128, 17664, 17664, 19712, 21760, 19968, 19456, 16128, 12288, 9728, 10752, 7168, 3840, 7680, 8960, 10496, 6912, 3584, 0, -1024, -512, -3584, -4096, -3840, -8960, -16640, -16128, -14336, -16384, -20480, -24064, -19712, -18176, -11776, -8704, -10752, -9472, -5376, -1536, -1280, -4096, -5120, -8960, -11264, -15872, -16896, -16896, -24576, -24064, -14848, -6656, -8192, -11264, -12800, -3584, 512, -2304, -6656, -10496, -13568, -12544, -6912, -1280, -7168, -15104, -16640, -12032, -5120, -2816, 1792, 3840, 7168, 13056, 14592, 8192, 1792, 512, 7680, 8192, 3840, 0, 1792, 7680, 7680, 6144, 5376, -512, -4864, -5120, 1536, 9472, 10240, 7936, 10240, 11520, 7680, 7424, 8960, 12544, 13312, 17664, 18944, 19968, 22784, 20224, 18432, 15872, 15360, 13056, 9472, 7424, 7424, 10752, 13056, 11776, 7680, 8192, 4608, 512, 2048, 3328, 3840, -3328, -8960, -8960, -9728, -10240, -13568, -18176, -17920, -14848, -8704, -9728, -8192, -7168, -2304, 2560, 2560, 1792, 2816, -1792, -7168, -5376, -6656, -12032, -20480, -21504, -12544, -4608, -7168, -9728, -8192, -2048, -1024, 1024, 768, -5888, -11776, -11264, -4864, -1280, -5632, -10752, -14080, -14336, -8960, -6400, -3072, -2048, 2816, 11008, 13056, 8448, 256, 0, 6144, 4608, 256, -1280, 0, 256, 2304, 3840, 5376, -512, -9728, -9216, -4864, 512, 512, 4864, 6656, 4864, 5120, 2560, 2816, 5120, 7936, 9472, 12544, 15872, 16384, 15616, 15360, 15616, 12800, 13056, 8192, 2560, 4096, 6912, 7936, 8448, 8448, 9216, 1792, -1536, 768, 3584, 3072, -2560, -5376, -10240, -8704, -8448, -12032, -16640, -17152, -15360, -10240, -10240, -11264, -6400, -2560, -1024, 3584, 6656, 5632, 1024, -1792, 2048, 2048, -5632, -17152, -16640, -8448, -4864, -6144, -5120, -4608, -2048, 256, 6656, 7680, -512, -5632, -6400, -1536, 1280, -256, -3328, -9728, -11008, -7936, -5376, -4096, -4096, 2304, 12032, 15616, 8960, 5632, 5632, 7936, 6144, 2560, 3328, 1280, -512, 0, 7168, 8704, 256, -5376, -7680, -7168, -4608, -1280, 1280, 4608, 5120, 3584, 1536, 1536, 3072, 2304, 5120, 8448, 9984, 13056, 13056, 10752, 13056, 13056, 12288, 5120, 2304, 1792, 1280, 1792, 3840, 7168, 4864, -256, -4096, -3840, -1024, 1024, -4096, -7680, -10496, -11520, -10496, -12800, -20224, -19712, -17664, -16640, -16384, -14336, -11520, -10240, -7168, -1024, 5376, 4352, -2048, -2304, 5376, 4096, -4608, -14336, -14848, -11264, -9984, -6144, -5632, -7168, -5632, -1024, 7424, 7936, 3328, -2304, -4096, -768, 2816, 3328, 256, -4608, -8448, -3840, -2816, -5888, -5632, 2816, 13312, 14848, 12800, 11776, 12800, 12544, 9216, 10240, 10240, 4352, 1536, 5120, 9472, 11520, 7424, 2304, -1792, -3072, -2816, -1536, 2304, 7680, 6400, 6656, 6656, 4352, 4864, 3840, 5376, 6144, 11776, 14080, 12032, 11008, 14336, 16384, 13312, 8448, 6400, 3328, -768, 512, 2560, 5376, 6656, 1024, -3840, -4096, -3328, -512, -2816, -8192, -11008, -9472, -11264, -15616, -19712, -19968, -20992, -20992, -20480, -18176, -15616, -18432, -15104, -5376, 1280, -512, -6912, -2560, 3840, 1792, -3584, -11264, -15104, -17152, -14080, -9472, -9728, -12800, -11520, -5888, 1280, 5888, 2304, -1536, -4864, -3840, 1280, 3584, 512, -5632, -5632, -2560, -4352, -8960, -9728, -768, 8960, 9728, 11008, 14592, 13056, 11264, 12544, 14592, 11776, 6400, 3584, 6144, 8960, 13824, 10496, 7936, 5632, 256, -1792, -1024, 3072, 5888, 8704, 9472, 8960, 8960, 9216, 6656, 6144, 8448, 14080, 15872, 13568, 14848, 17920, 17920, 18688, 15872, 13056, 9728, 3584, 1536, 5120, 7936, 8192, 6912, 1024, -2304, -256, 2304, -2048, -5376, -5632, -6912, -8448, -13568, -16384, -17152, -20992, -22016, -21248, -17152, -19200, -24832, -19712, -9216, -3840, -6912, -8192, -4608, -256, -256, -1536, -7936, -15872, -18688, -17408, -13312, -13312, -17408, -17664, -12800, -5376, -512, 1024, -2560, -8448, -7424, -1024, 512, -2560, -7424, -5632, -2048, -6912, -14080, -12544, -6912, -1536, 3072, 7936, 11008, 7936, 9728, 11264, 13824, 12288, 6400, 2816, 4864, 7680, 9216, 10496, 10496, 7424, 2816, -256, -2304, 0, 3840, 6912, 8704, 9216, 11776, 11776, 6656, 6912, 9984, 13056, 15104, 15872, 15872, 18688, 19456, 19712, 21760, 19968, 14848, 8960, 5888, 5376, 9472, 13568, 9472, 5632, 3840, 4096, 5120, 768, 0, -512, -512, -3584, -8448, -8960, -11520, -17664, -19712, -15104, -13568, -19456, -24576, -18944, -10496, -7680, -6400, -6656, -4864, -1024, 1792, 2816, -2048, -10240, -15872, -15872, -13056, -14080, -17664, -18944, -18176, -11264, -3840, -512, -3584, -9216, -9728, -2048, -1792, -6912, -8448, -4352, -3072, -9728, -13056, -14592, -14848, -10496, -3584, 2048, 4864, 3840, 3840, 7936, 11776, 10240, 5376, 2304, 1792, 2560, 5120, 6400, 8448, 7168, 4096, 256, -4608, -3328, 0, 1536, 3072, 7680, 9984, 9984, 6656, 5120, 8192, 10496, 11520, 13568, 16384, 16128, 15872, 20480, 21504, 22272, 20736, 13056, 7424, 5376, 11264, 13312, 10496, 8448, 7424, 7936, 6912, 3072, 2048, 4096, 2560, -1024, -1792, -1792, -7424, -15872, -14592, -9472, -11264, -17408, -20736, -17920, -12288, -8448, -5888, -5632, -4352, -1280, 4096, 7936, 3584, -3840, -8448, -10752, -10496, -9472, -13568, -16640, -18944, -13824, -4096, 512, -3072, -8448, -4864, -256, -2560, -5632, -4352, -2048, -2048, -4608, -8448, -12288, -15872, -14592, -7936, -256, 1792, 0, 2304, 5632, 10240, 10240, 6912, 3584, 1024, 768, 2560, 3584, 5376, 7936, 5120, 0, -3328, -4864, -4352, -3840, -1792, 3072, 7424, 7168, 3328, 5120, 4608, 4608, 7936, 9728, 12032, 12544, 13056, 14336, 17152, 22272, 21504, 14336, 7680, 5120, 7936, 10496, 7936, 6144, 8192, 8448, 5120, 1792, 3584, 3840, -512, -256, 3328, 1024, -7168, -13568, -11520, -8704, -9728, -15104, -19200, -18432, -14848, -11264, -6656, -6656, -7424, -2048, 3584, 8704, 7168, 2560, -2304, -5632, -6656, -6144, -7680, -13824, -19968, -14336, -3328, -1024, -4352, -4096, -1280, 256, -1536, -2304, -2048, -256, 768, -512, -1024, -7168, -13568, -14848, -9472, -2560, 256, -256, 1536, 5120, 8704, 11776, 10240, 6400, 4864, 2816, 1792, 2560, 5888, 8448, 7168, 4096, -768, -768, -4352, -7936, -3584, 1024, 3840, 5120, 5120, 4096, 2560, 3584, 4864, 5888, 9472, 11520, 8960, 9472, 13568, 19456, 21248, 15872, 8704, 5120, 6912, 7168, 3328, 4352, 7424, 5376, 1792, 2304, 3328, -1024, -4352, -1024, 3328, 512, -6912, -13568, -12032, -9984, -11776, -14336, -19712, -22272, -19712, -14848, -11520, -11776, -12032, -8448, -1536, 4352, 5632, 4096, 256, -5120, -6400, -2560, -5376, -14592, -20224, -14592, -8192, -6144, -5888, -4608, -768, -256, -1536, -1024, -1024, -1280, 768, 3328, 3584, -1536, -9728, -13056, -9984, -5632, -1024, -256, 768, 3584, 8192, 11520, 11776, 11776, 8448, 6400, 3840, 2304, 7168, 9728, 8192, 7168, 6656, 3584, -2304, -5376, -3840, -1280, 2560, 6144, 5632, 5632, 5376, 3840, 3840, 5888, 9216, 10752, 8960, 7936, 10496, 18432, 22272, 17408, 11776, 10752, 8704, 4864, 3584, 6400, 6400, 2816, 3584, 4608, 3584, -1792, -6144, -1792, 3072, 1024, -4864, -10496, -12032, -11264, -10496, -13312, -18944, -23552, -22528, -18432, -15104, -16128, -17408, -13568, -8704, -2816, 3072, 4864, -1792, -6912, -3840, -1280, -5632, -13824, -19456, -16896, -13312, -12032, -10496, -7424, -4352, -3072, -3072, -2560, -2816, -4864, -1792, 3072, 4864, 768, -5888, -10752, -12288, -7936, -4864, -3584, -1536, 256, 5120, 8960, 9984, 12800, 13056, 8448, 4096, 4352, 7680, 7936, 8192, 10496, 9984, 7168, 3584, -1792, -3584, -1280, 2048, 4608, 6912, 8704, 7424, 5632, 5376, 6656, 9728, 13056, 9984, 6912, 11008, 19200, 21504, 18688, 19200, 17408, 11776, 8192, 7936, 8960, 6912, 3840, 5888, 9216, 6656, 0, -3328, -1024, 3072, 3584, 256, -5888, -9216, -9216, -8192, -9216, -15360, -21248, -21504, -17920, -17152, -17920, -16896, -17152, -15872, -6912, 2048, 3328, -2816, -5632, -1792, 1024, -4096, -11264, -16128, -17152, -16128, -16128, -13568, -10752, -8448, -6400, -3840, -2560, -5632, -6912, -4608, -256, 4096, 2304, -3328, -8192, -11776, -10752, -7936, -7680, -6144, -2048, 1280, 2816, 6400, 12544, 12800, 8448, 6400, 5120, 5376, 6144, 7424, 8704, 10496, 10496, 6656, 1280, -1280, -1792, -1024, 3072, 5888, 8448, 9472, 7424, 4864, 6144, 12544, 13568, 8448, 8448, 12544, 16640, 18688, 20480, 22784, 21760, 16128, 12288, 12800, 11776, 7680, 5120, 8960, 11776, 9984, 4352, 0, 512, 3840, 5888, 4608, -512, -5120, -6144, -3072, -4864, -11520, -15360, -16896, -17920, -16896, -14336, -15616, -18944, -18944, -9728, 0, 1536, -2048, -3840, 768, 3328, -256, -6144, -10752, -13312, -16640, -16384, -13824, -13824, -12032, -7936, -4864, -3072, -5376, -8192, -6912, -3072, 1792, 3328, -512, -6144, -9216, -9472, -11264, -12032, -8192, -5120, -4608, -2304, 3072, 7680, 9728, 8960, 6656, 4608, 4352, 4096, 3328, 6400, 9216, 9472, 8192, 4608, 512, -2816, -2560, -1280, 768, 7168, 9728, 5120, 2048, 6400, 10752, 10240, 7168, 7680, 10240, 11776, 13824, 17920, 22272, 20992, 16896, 15616, 15104, 12288, 7168, 5120, 8192, 11008, 11008, 6144, 2048, 256, 1792, 5888, 6400, 768, -3328, -2304, -2048, -3840, -7168, -10240, -14848, -18176, -15360, -12544, -14848, -20480, -20992, -12800, -4352, -1280, -3328, -3072, 1536, 3328, 2048, -768, -6144, -10752, -13824, -15104, -14592, -15360, -15104, -11008, -6144, -3840, -5120, -7680, -8960, -6400, 256, 2816, -512, -3072, -4608, -8448, -12288, -12544, -10496, -9472, -8192, -5376, -2048, 3328, 6912, 6912, 6912, 5888, 4096, 2048, 1792, 3840, 5632, 8192, 8960, 5632, 2304, 0, -4608, -6656, -2048, 5120, 6400, 2816, 1024, 4608, 8192, 7424, 5632, 7424, 7680, 6912, 9728, 15360, 19200, 17920, 17408, 17664, 17152, 13312, 7680, 4864, 6912, 9216, 10240, 8704, 2560, -512, 1536, 5376, 5120, 1024, -512, -1024, -1792, -2304, -3072, -6400, -13312, -16896, -13568, -10752, -13568, -20224, -22016, -14848, -8448, -5888, -4096, -3072, 0, 3072, 4352, 3328, -1280, -6144, -9728, -11264, -12800, -15104, -15616, -13056, -8448, -3840, -2816, -7168, -9216, -5888, -1024, 1280, 1280, 1792, -768, -4352, -7936, -10240, -9728, -9472, -9216, -7424, -3584, 1024, 3840, 6400, 8704, 7680, 6144, 4864, 2304, 2048, 5632, 8448, 7936, 7680, 7936, 4096, -3584, -6656, -3328, 3584, 4352, 1792, 2048, 4608, 6144, 5888, 7168, 7936, 5888, 4608, 7680, 12800, 15872, 15616, 16128, 19200, 18688, 15104, 10240, 5888, 5120, 7680, 11008, 8960, 2816, 0, 2048, 3840, 3072, 1536, 768, -1536, -2560, -768, -256, -3840, -11776, -15872, -12032, -9728, -13824, -19712, -21504, -17920, -13568, -10240, -7680, -5376, -3072, 256, 4096, 5120, 1280, -3072, -5376, -8448, -11264, -13312, -16384, -16384, -11264, -4352, -3840, -6912, -7680, -6656, -3840, -768, 1536, 3072, 2304, -512, -4352, -6656, -7424, -9216, -10496, -8192, -5376, -2560, 1536, 4608, 6912, 8704, 9472, 6400, 2816, 3584, 5376, 6656, 6912, 9472, 12288, 8448, -256, -4864, -2048, 1792, 2048, 2048, 4096, 4096, 4352, 6400, 8704, 9216, 5888, 4096, 7168, 11264, 13568, 13824, 15616, 18944, 20224, 19200, 14336, 7680, 4864, 7936, 11520, 8960, 3840, 2304, 2304, 2304, 2816, 2304, 1280, -2048, -3584, 0, 2304, -2560, -10240, -13568, -11264, -9728, -13056, -18432, -21504, -20480, -17664, -14848, -11520, -9728, -7680, -3328, 1280, 3328, 2048, 0, -3584, -6400, -7680, -11776, -17152, -18432, -14080, -8704, -6656, -7168, -7936, -7936, -6656, -4352, -1024, 2304, 2816, 512, -1024, -3072, -5632, -8448, -9728, -10240, -8704, -4608, -1792, 512, 4352, 8448, 9728, 7424, 4864, 5120, 5632, 4352, 4864, 9728, 14592, 11008, 3840, 512, -256, 256, 768, 2560, 4608, 3840, 3584, 6400, 9728, 10240, 6912, 5376, 7168, 9728, 11776, 12800, 14080, 16896, 20736, 23040, 18176, 10240, 7680, 9472, 11264, 9984, 6656, 4608, 3072, 2048, 3584, 4864, 2048, -2816, -3328, 1280, 3840, -512, -7168, -10752, -9216, -8704, -11520, -15360, -19456, -21248, -19712, -16640, -15104, -14080, -11008, -7168, -3328, 1280, 2816, 512, -2304, -2816, -4352, -9472, -15616, -18176, -16640, -12544, -9728, -9216, -8704, -8960, -9216, -8192, -4096, -512, 256, 768, 0, -1792, -3328, -6400, -9984, -11776, -10752, -7680, -5632, -3840, 512, 5376, 7680, 6144, 5632, 7168, 4864, 1280, 2816, 8448, 12800, 11520, 7936, 4352, 1536, -256, 0, 2048, 4096, 3072, 2816, 5888, 9472, 10240, 8448, 7424, 7424, 8448, 11520, 12288, 11776, 14848, 21248, 24832, 21504, 15104, 11520, 11776, 12032, 11776, 10752, 7936, 4096, 3072, 5888, 7424, 4096, -1280, -2304, 2560, 5376, 2560, -3072, -6144, -6400, -6400, -7424, -10752, -16384, -18688, -17920, -16896, -16128, -14848, -13312, -10752, -5632, 0, 2048, 1024, 256, 768, -256, -4864, -11264, -15616, -16128, -14592, -12800, -9984, -8448, -9472, -9984, -9216, -6912, -3584, -1024, 0, 0, 0, -256, -3328, -7680, -10752, -11008, -9472, -9216, -7680, -2560, 2048, 3072, 3840, 6656, 7936, 4096, 256, 1024, 5376, 9472, 10496, 9728, 7424, 3328, 0, -256, 1536, 2048, 768, 1792, 4352, 6656, 8704, 8960, 6912, 6144, 8192, 10240, 9472, 8192, 11520, 18432, 22784, 22016, 17920, 14592, 12288, 11520, 12544, 12800, 9472, 4096, 2816, 6400, 8704, 5120, -768, -1792, 1792, 4608, 3840, 512, -3584, -5120, -3840, -4352, -8192, -12544, -15616, -17152, -16640, -15360, -15616, -16128, -13824, -8448, -3072, -256, 256, 512, 2560, 3072, -768, -6656, -11008, -14592, -15360, -13824, -11520, -9728, -9728, -9984, -9984, -8960, -5888, -3328, -1536, -768, 512, 1792, -512, -5120, -7680, -8704, -10752, -12032, -9728, -4864, -2304, -1280, 1792, 6144, 7936, 4864, 768, 0, 2560, 5888, 8448, 10240, 9216, 4608, 1280, 1024, 1024, 0, 0, 0, 1280, 4096, 7424, 7680, 5632, 5632, 7936, 9216, 6912, 5376, 8192, 13824, 18944, 20736, 19712, 16640, 12544, 11264, 12800, 14080, 10240, 4096, 2560, 6144, 7936, 5120, 768, -1536, -256, 2816, 4096, 1280, -2304, -3328, -3072, -3584, -5632, -9216, -13568, -16128, -15872, -15104, -16128, -17664, -17152, -12288, -6400, -3584, -2560, -256, 2560, 4096, 2560, -1536, -6656, -11520, -13824, -14080, -12800, -10752, -9984, -9984, -10240, -9984, -7424, -4864, -3840, -2048, 1024, 2816, 768, -1536, -2816, -5376, -9728, -12288, -10240, -6656, -5376, -4096, -768, 4608, 7680, 6144, 3072, 1536, 1024, 2816, 7424, 10496, 9984, 7168, 4608, 2816, 2048, 1280, 256, -1024, -512, 2816, 6400, 6400, 4864, 5888, 8448, 8960, 6400, 4352, 5888, 9984, 14592, 18944, 20736, 18432, 13568, 12032, 14336, 15360, 11264, 5888, 4096, 5632, 7424, 6400, 2560, -1024, -768, 1792, 2816, 1536, -768, -2304, -2816, -2304, -3072, -6656, -10752, -14336, -15104, -14080, -15616, -18688, -19200, -15360, -10752, -8192, -5888, -3072, 0, 3072, 3840, 1792, -2560, -7680, -11776, -13568, -13568, -11776, -10496, -11008, -11520, -10496, -8192, -7680, -6656, -3584, -256, 1280, 512, 768, 768, -2304, -7680, -11008, -10240, -7936, -7936, -7168, -3072, 2048, 5120, 6400, 5632, 2304, 0, 1536, 5376, 8704, 9984, 8960, 6656, 4608, 4096, 3584, 1024, -1792, -1280, 2304, 5376, 4864, 4096, 5888, 8960, 9472, 7168, 5120, 5120, 6656, 11008, 17152, 20992, 18944, 14592, 13824, 15872, 16128, 13312, 8448, 5376, 5888, 7680, 7168, 3584, 256, -256, 768, 2048, 1792, -256, -1792, -2304, -1536, -1280, -3840, -8704, -12544, -13056, -13056, -15360, -18432, -19456, -17920, -14592, -11776, -9472, -6400, -3328, 768, 3584, 3584, 768, -3840, -8448, -12288, -13312, -12032, -11520, -12544, -12544, -10496, -9472, -9984, -8960, -5376, -2560, -1280, -512, 1536, 3072, 256, -4864, -8192, -8704, -9216, -9984, -8704, -5888, -2304, 2304, 5888, 6400, 3584, 768, 512, 3072, 6400, 9216, 9472, 7680, 6144, 6400, 6144, 2560, -1280, -1024, 2304, 4608, 3840, 3584, 5888, 8704, 9728, 9216, 7680, 4864, 3840, 8192, 15616, 19968, 19200, 16128, 15360, 17152, 18176, 15872, 10752, 7424, 7680, 8448, 8192, 5120, 2048, 1024, 1536, 2048, 2048, 768, -1280, -2304, -512, 768, -1792, -6400, -9472, -10752, -11520, -13824, -16896, -18944, -18944, -17152, -14848, -12544, -10240, -6912, -2304, 1280, 3328, 3328, 0, -5376, -9984, -11520, -11264, -12544, -13824, -12800, -11264, -11264, -12032, -10752, -7424, -5376, -4864, -2816, 1280, 3072, 1024, -2048, -4608, -7168, -9216, -10240, -10240, -9216, -6144, -1024, 3584, 5376, 4352, 1792, 0, 768, 4352, 8192, 8704, 7424, 7168, 8704, 8448, 4352, 0, 0, 2304, 3328, 3072, 3584, 5120, 6912, 9728, 11776, 9984, 5376, 2816, 6144, 13056, 18176, 18944, 16896, 16384, 18688, 19968, 18176, 13824, 10240, 9728, 10496, 9728, 7168, 4352, 2816, 2304, 3072, 3584, 1792, -768, -1280, 768, 2304, 512, -3072, -5888, -7168, -8960, -11520, -14080, -16640, -18176, -17408, -15872, -14592, -12800, -9472, -5632, -1792, 2560, 5120, 3072, -2048, -6144, -8192, -9984, -12288, -13312, -12544, -11520, -12544, -13312, -11264, -8704, -8448, -7680, -4608, -768, 1280, 1280, 256, -2048, -4864, -7424, -9472, -11008, -11520, -9472, -4608, 0, 3328, 4608, 2560, -256, -768, 2560, 6144, 6656, 5888, 7424, 9728, 9472, 5376, 2048, 1280, 1536, 2048, 2560, 3072, 2816, 4096, 8704, 12544, 11776, 6912, 2560, 3840, 9728, 15104, 17152, 16128, 16128, 18432, 20736, 19712, 15616, 12288, 11520, 11520, 10752, 8960, 5888, 3328, 2816, 4352, 4608, 2304, -768, -1280, 768, 2560, 1536, -768, -3072, -4864, -6144, -8704, -11776, -14592, -16384, -16640, -16896, -16128, -14336, -12288, -9984, -5632, 256, 4352, 4096, 768, -2048, -4352, -7680, -11264, -12032, -11264, -12032, -13568, -13312, -11264, -10496, -10496, -9728, -7168, -3584, -768, 768, 768, -512, -2304, -4352, -7168, -10752, -12544, -11776, -8704, -4352, 768, 3584, 2304, -768, -1536, 1280, 3840, 3328, 3840, 6656, 9216, 8960, 6400, 4096, 2048, 512, 1024, 2304, 1536, 256, 1024, 5632, 11008, 12288, 7936, 2816, 1792, 6144, 11520, 14080, 13824, 14080, 17408, 20224, 19712, 16896, 13824, 12288, 12032, 12032, 10496, 6912, 3584, 2816, 4608, 5120, 2560, -512, -1536, 0, 1792, 2048, 512, -1536, -3072, -3584, -5888, -9728, -12544, -14080, -15872, -16896, -16128, -15360, -15104, -13568, -9472, -3072, 2048, 3328, 2560, 1792, -1024, -5376, -8960, -9472, -9984, -12032, -13568, -13056, -11520, -11264, -11264, -10752, -9216, -6144, -2560, 0, 512, 256, 256, -768, -3840, -7680, -10752, -12544, -11520, -7680, -1536, 2560, 1792, -512, -768, 1280, 2304, 1536, 2816, 5888, 8192, 8960, 8448, 6400, 3584, 1536, 2304, 3072, 2048, -512, -1024, 3328, 9216, 12288, 9984, 4608, 1792, 4352, 8704, 11008, 11520, 12800, 15872, 18944, 19968, 18176, 15104, 13056, 12544, 13312, 12288, 8192, 4096, 3072, 4864, 5376, 3328, 256, -1536, -1280, 512, 1536, 512, -1024, -1536, -2304, -4608, -7424, -10240, -13056, -15360, -16640, -16128, -16128, -17408, -17408, -13568, -7680, -3072, 0, 2560, 3328, 768, -3584, -6400, -7424, -8960, -11520, -13312, -13312, -12544, -12032, -12032, -12032, -11776, -8960, -5120, -2560, -1280, -256, 1024, 1024, -1024, -3840, -7680, -12032, -13824, -10496, -3840, 256, 0, -512, 512, 1536, 1024, 768, 1792, 4096, 6656, 8960, 9728, 8192, 5120, 3072, 3584, 4608, 3072, -256, -2048, 768, 6912, 11776, 11264, 6656, 3584, 4352, 7168, 8960, 9728, 11264, 14080, 17664, 19968, 19712, 16896, 14080, 13824, 15360, 14848, 10496, 6144, 4352, 4864, 5888, 5120, 1792, -1024, -1024, 0, 512, 256, 0, -512, -1024, -2560, -4352, -7168, -10752, -14080, -15104, -14336, -15616, -18432, -18944, -16128, -12032, -8192, -3584, 1280, 3328, 1792, -1024, -3072, -4864, -7168, -9728, -11776, -13056, -12800, -11776, -12032, -13056, -13312, -11008, -7680, -5120, -3328, -1280, 0, 1024, 1024, 512, -3328, -10240, -14080, -12032, -6400, -3072, -2048, -768, 768, 1280, 1024, 512, 768, 1792, 4608, 8192, 10496, 9216, 6400, 4608, 5376, 6400, 5376, 1280, -2304, -768, 4864, 10496, 11520, 8704, 6144, 5888, 6912, 7680, 8448, 9728, 12032, 15872, 19968, 20992, 18432, 15616, 15616, 17152, 16896, 13824, 9472, 6144, 5888, 7168, 6400, 3840, 1280, 0, 0, 0, 256, 512, 512, -256, -1024, -1280, -3840, -8704, -12032, -12544, -12544, -14848, -17664, -18688, -17920, -16128, -13056, -7680, -2048, 1280, 1792, 768, -1024, -2816, -5120, -7424, -10496, -12544, -12800, -11776, -12544, -13824, -14336, -12800, -10752, -8448, -5632, -3328, -2560, -1536, 1280, 3072, -256, -7680, -12800, -12800, -9728, -6912, -4608, -2560, -768, 256, 512, 512, -512, -1024, 1536, 6144, 9216, 9216, 6912, 4864, 5632, 7680, 7168, 2560, -2048, -2560, 2304, 7680, 9984, 8960, 7680, 6656, 6656, 7168, 7424, 7424, 8960, 13568, 18688, 20480, 18944, 16640, 16128, 17664, 18432, 16384, 12032, 8448, 7168, 7424, 7168, 5376, 3072, 1536, 512, -512, 256, 1024, 256, -512, 512, 1536, -1024, -5888, -8960, -9728, -10752, -13056, -15360, -16896, -17920, -18176, -16128, -11520, -5888, -1280, 1024, 1536, 768, -512, -1792, -4608, -8192, -10752, -11008, -11008, -12032, -13312, -13824, -13568, -13056, -10752, -6912, -5120, -5376, -3584, 1024, 4352, 2560, -3328, -8960, -11520, -11264, -9472, -6656, -4352, -2816, -768, 768, 768, -768, -2304, -1024, 3328, 7936, 8960, 6912, 4864, 5888, 8704, 9216, 4864, -768, -2560, 512, 4864, 7936, 8960, 8448, 7424, 7680, 8192, 7168, 5632, 6656, 11008, 16128, 19456, 19200, 17152, 16640, 18176, 19200, 17920, 14592, 11008, 9216, 8704, 7680, 6656, 5376, 3584, 1280, 256, 1024, 768, -512, -512, 1536, 2816, 768, -2816, -5632, -7424, -9216, -11008, -12800, -14592, -17152, -18944, -18432, -15360, -10240, -4864, -1280, 512, 1024, 1536, 768, -2048, -5888, -8192, -8960, -10240, -11520, -12032, -13056, -14592, -14848, -12032, -8448, -7680, -8192, -6144, -1280, 3328, 3584, 256, -4608, -9216, -11520, -10752, -8960, -6912, -5120, -2816, 0, 768, -768, -3072, -3072, 256, 5376, 7936, 6400, 4096, 5120, 8704, 10240, 6656, 1280, -1792, -1536, 1792, 5376, 6912, 6656, 6912, 7936, 8448, 6912, 4352, 3840, 7168, 12800, 16640, 17408, 16384, 15872, 17408, 18944, 18432, 15616, 13056, 11264, 8960, 7424, 7168, 6400, 3840, 1792, 1280, 1280, -256, -2048, -1280, 768, 2048, 1024, -1024, -3072, -5632, -8192, -9728, -10752, -12800, -15616, -18432, -19712, -18688, -14592, -9216, -5120, -2816, -512, 1792, 2048, -768, -3584, -5632, -7680, -9728, -10496, -10752, -12544, -15360, -15872, -13312, -10496, -10240, -10496, -8704, -4608, 0, 2816, 2560, -768, -5888, -9728, -10752, -10240, -9216, -7936, -5120, -1536, 512, -256, -3328, -4864, -2304, 3072, 6400, 5120, 3072, 4352, 7680, 9984, 8704, 4352, -512, -2048, 256, 3328, 4864, 5376, 5888, 7936, 9472, 8192, 4608, 2560, 4608, 9216, 14080, 15872, 15360, 15360, 17152, 18688, 18432, 17408, 15616, 13056, 10496, 8960, 8704, 7168, 4608, 3072, 2816, 2048, -512, -2304, -1792, 0, 1024, 1280, 768, -768, -3584, -6144, -7936, -9216, -10496, -12800, -16384, -19712, -20480, -17408, -13056, -9472, -6656, -2816, 768, 1536, 512, -768, -3328, -6144, -8192, -8448, -8704, -11776, -15360, -15872, -13824, -12032, -11776, -12032, -11008, -7936, -3328, 1024, 3072, 1536, -2304, -5888, -8704, -9984, -10240, -9728, -7424, -3584, 0, 512, -2816, -5632, -3840, 1024, 4352, 4096, 2816, 3328, 6400, 9984, 10496, 7168, 2304, -768, 0, 2304, 3840, 3840, 4864, 7680, 10240, 9984, 6656, 3072, 2816, 7168, 11520, 13824, 14336, 15360, 16896, 17920, 18688, 18944, 17664, 14848, 12544, 11520, 10752, 8192, 5632, 4608, 4864, 3584, 768, -1536, -1792, -1024, 0, 1280, 1536, 768, -1280, -3584, -6144, -7680, -8192, -9728, -13568, -18176, -19968, -18432, -16128, -13824, -9984, -5632, -2048, 256, 1536, 1536, -1024, -4608, -6400, -5888, -6400, -9984, -13824, -14848, -13824, -12544, -12544, -12800, -12544, -10752, -6656, -1792, 1792, 2304, 512, -2304, -5120, -7680, -9728, -11008, -9984, -5632, -512, 768, -2304, -5120, -4096, -512, 2816, 3584, 2560, 2560, 5120, 9216, 11776, 10240, 5632, 2048, 1536, 2816, 3328, 3072, 3840, 6656, 10496, 11776, 9216, 5120, 3584, 6144, 9728, 12032, 13824, 15360, 16384, 17664, 19456, 20736, 19456, 16896, 15360, 14848, 13568, 10240, 7680, 6912, 6912, 5632, 3072, 768, -768, -1024, -256, 1024, 2048, 2048, 1280, -1024, -3840, -5376, -5376, -6400, -10496, -14848, -17664, -18176, -17920, -16384, -13056, -8960, -5888, -2304, 1280, 2560, 256, -3328, -4352, -3840, -4864, -8192, -11776, -13824, -13824, -13056, -12800, -13312, -14080, -13568, -10240, -5632, -1536, 768, 1024, -512, -2560, -4864, -8192, -12032, -12544, -8192, -2816, -768, -2560, -5120, -5120, -2560, 512, 1792, 1280, 512, 2560, 7168, 10752, 10496, 7424, 4096, 2560, 2816, 2816, 1792, 1536, 4352, 8960, 11520, 9984, 6656, 4608, 4864, 6656, 9472, 12032, 13568, 14336, 15616, 18688, 20736, 19456, 17408, 16640, 16640, 15104, 11776, 9216, 7936, 7168, 6400, 4864, 2304, -256, -1536, -1024, -256, 512, 2048, 2304, 0, -2560, -3840, -3584, -4608, -8192, -11776, -14592, -17408, -18944, -18176, -15616, -13056, -10496, -5888, -512, 2048, 512, -2048, -2816, -2560, -3328, -5888, -9472, -12288, -13568, -13056, -12544, -13568, -15104, -15360, -13568, -9472, -4864, -1792, -768, -512, -256, -1536, -5632, -11008, -13312, -10752, -5376, -2304, -3072, -5120, -5888, -4096, -1024, 768, -256, -1536, 0, 4608, 8704, 10240, 8448, 5632, 4096, 4096, 3328, 1280, 0, 2304, 6912, 9984, 10240, 8192, 6144, 4608, 4864, 7424, 10240, 11264, 11776, 14080, 17664, 19712, 19200, 18176, 17920, 17920, 16640, 14080, 11520, 9472, 8192, 7680, 6656, 4352, 1792, 0, -1280, -1536, -256, 2048, 2816, 1024, -1280, -1792, -1792, -3328, -5376, -7680, -11264, -15104, -17664, -17664, -16640, -16128, -14336, -9216, -3328, 256, 256, -1024, -1536, -1280, -1536, -3072, -6400, -10240, -12032, -12032, -11776, -12800, -14336, -15872, -15616, -12288, -7680, -4608, -3072, -1536, 1024, 1536, -1792, -8192, -12544, -11776, -7680, -4096, -3072, -4864, -6400, -5120, -1792, 0, -768, -2304, -1792, 2048, 6656, 9216, 8704, 6912, 6144, 6144, 4864, 1792, -512, 1024, 4608, 7936, 9728, 9728, 7680, 5120, 4608, 6656, 8704, 8960, 9728, 12288, 15872, 18176, 18688, 18432, 18688, 18432, 17920, 16384, 13568, 11008, 9728, 8960, 7680, 5888, 4096, 1792, -1024, -2560, -1024, 1536, 2048, 768, -256, -512, -1024, -2304, -3072, -4864, -8448, -13056, -15616, -16640, -17664, -18688, -17920, -13312, -7680, -3328, -1536, -1280, -1792, -1280, -512, -1280, -4352, -7936, -10496, -11520, -11264, -11520, -13568, -16384, -17152, -14848, -11008, -7936, -6656, -4352, -256, 2560, 768, -4864, -10496, -12288, -9984, -5888, -4096, -5376, -6912, -6144, -3072, -768, -1280, -3328, -3840, -768, 4096, 7168, 7424, 6656, 7168, 7936, 6144, 2560, 0, 0, 2048, 5120, 8448, 9728, 8192, 5632, 4864, 6144, 7168, 7168, 7680, 10240, 13312, 15616, 17408, 18176, 18432, 18688, 18688, 17664, 15104, 13056, 11520, 9984, 8192, 7168, 6656, 3840, 0, -2304, -1280, 512, 1024, 512, 256, -256, -1024, -1536, -1280, -2560, -6144, -10496, -12800, -14336, -16896, -19456, -19712, -16896, -12032, -6912, -3840, -2816, -2560, -1280, 0, -256, -2048, -5120, -8448, -10240, -10240, -10240, -12288, -15872, -17920, -16384, -13056, -11008, -9984, -7424, -2816, 1792, 2560, -1280, -7168, -11008, -10496, -7168, -5120, -5632, -7424, -7168, -4352, -1536, -1280, -3584, -5120, -3072, 1536, 4864, 5632, 5888, 7680, 8960, 7936, 5120, 2048, 0, 256, 3328, 7424, 9472, 8448, 6656, 6400, 6912, 6912, 6400, 6656, 8448, 11008, 13824, 16128, 17152, 17920, 18944, 19456, 18432, 16896, 15616, 13824, 11264, 9472, 9216, 8704, 6144, 2048, -768, -1024, -512, 0, 512, 768, -256, -1280, -768, 512, -512, -4096, -7424, -9216, -11264, -14592, -17920, -20224, -19456, -15360, -10496, -6912, -4864, -3584, -2048, -256, 768, 0, -2560, -6144, -8448, -8448, -8192, -10240, -14080, -16640, -16128, -14336, -13056, -12288, -10240, -5888, -256, 3072, 1792, -3328, -8192, -9472, -7424, -5376, -5376, -7168, -7424, -4864, -1536, -512, -3072, -5120, -3584, 0, 2816, 4096, 5632, 7680, 9472, 9728, 8448, 5376, 1792, 0, 2304, 6656, 9216, 8960, 8192, 8192, 8192, 7936, 7168, 6912, 7680, 9728, 12800, 14848, 16128, 17920, 19968, 20224, 19456, 18944, 18432, 16384, 13568, 11776, 11520, 11264, 8704, 5120, 2304, 768, -256, 256, 1792, 1792, 0, -1024, 512, 2048, 1280, -1280, -3840, -5888, -7680, -10496, -14848, -18688, -19712, -17408, -13568, -9728, -7168, -5376, -3584, -1280, 1024, 1792, -256, -3840, -6400, -6400, -6144, -8192, -12288, -15104, -15616, -15104, -14592, -14592, -13824, -9984, -4096, 1024, 2048, -1280, -6144, -8448, -7680, -6144, -6144, -8192, -8960, -6656, -2816, -1536, -3584, -5120, -4864, -2560, -512, 1280, 3328, 5376, 7424, 9472, 10240, 7680, 2816, 0, 1024, 4352, 6912, 7680, 7936, 7936, 8192, 8192, 7424, 5888, 5888, 7936, 10240, 11520, 13312, 16128, 18432, 18944, 18688, 19200, 19200, 17152, 14336, 13056, 12800, 11776, 9728, 7424, 4608, 1536, -768, -256, 1280, 768, -1024, -1792, -512, 1024, 1280, -512, -2816, -4352, -5376, -7680, -12032, -16896, -19968, -19712, -16896, -13568, -10752, -8704, -6912, -4096, -768, 1536, 256, -3072, -5376, -5376, -5376, -7168, -10752, -13824, -15360, -15360, -15616, -16640, -17152, -14592, -8960, -2816, 256, -768, -4608, -7680, -7680, -6400, -6912, -9216, -10496, -8192, -4864, -3328, -4352, -5632, -5632, -4864, -3584, -1536, 512, 1792, 4352, 7936, 10496, 8704, 4352, 768, 256, 2048, 4352, 5888, 6400, 6656, 7680, 8192, 7168, 5632, 5376, 6400, 7680, 8704, 10752, 13824, 16128, 16896, 17920, 19712, 19712, 17664, 15616, 14592, 14080, 12544, 11264, 9984, 7168, 2816, 512, 512, 1280, 768, -768, -2048, -1024, 768, 1536, 512, -1024, -2304, -2816, -4096, -7936, -13312, -17408, -19200, -18176, -15616, -12800, -11008, -9728, -6656, -2048, 1280, 1024, -1536, -3328, -3584, -3328, -4864, -7936, -11264, -13056, -13312, -14080, -16384, -18176, -17152, -12544, -6144, -1024, -256, -3072, -5632, -5376, -4608, -5632, -8448, -9984, -8448, -5632, -4096, -4096, -4352, -4864, -5120, -4096, -2304, -1024, -512, 1280, 4608, 7936, 9472, 8192, 5376, 2816, 2304, 3072, 4352, 5120, 6144, 7168, 8192, 7936, 7168, 6656, 6656, 6656, 7168, 8704, 11008, 13056, 14592, 16640, 18944, 19712, 19200, 18432, 17408, 16128, 15104, 14336, 13568, 11264, 7936, 4864, 3072, 2816, 2048, 768, -512, -768, 0, 1024, 1280, 512, 0, -256, -768, -2816, -6400, -10752, -14848, -16896, -16640, -15104, -13824, -13056, -10752, -6912, -2816, -512, -768, -1536, -1792, -1792, -2304, -4096, -6912, -9216, -10240, -11264, -13312, -16128, -17920, -16896, -12544, -7168, -3840, -3328, -4096, -4096, -3328, -4096, -6144, -7936, -8448, -7424, -6144, -4864, -4352, -4864, -5120, -4608, -3584, -3328, -3072, -1536, 1792, 5632, 8448, 8960, 7168, 4608, 3072, 3072, 3584, 4352, 5376, 6912, 7936, 7936, 7680, 7680, 7168, 6400, 6400, 7680, 9216, 10752, 12544, 14848, 17152, 18944, 19456, 19200, 18176, 16896, 15872, 15360, 15104, 13568, 10496, 7424, 4864, 3584, 2816, 1792, 256, -768, -512, 256, 768, 768, 256, 0, 0, -768, -2816, -6656, -11264, -15104, -16640, -16128, -15360, -14592, -13312, -10496, -6400, -2816, -1024, -1024, -1536, -1536, -1536, -2304, -4352, -6912, -8960, -9984, -11264, -13568, -16640, -18176, -16640, -12032, -7168, -4096, -3840, -4096, -3840, -3584, -4352, -6400, -8192, -8448, -7424, -6144, -4864, -4352, -4864, -5120, -4608, -3584, -3328, -3072, -1536, -512, 256, 1536, 1280, 5376, 11776, 10752, 3840, 0, 1280, 8704, 12288, 7424, -1024, -7936, -8448, -4352, 6656, 12544, 8192, 0, -5376, -3840, 3584, 6144, 6144, 4096, 0, 768, 2816, 2816, 2816, 1280, 2304, 2304, 2048, 2816, 7680, 6912, 5632, 1792, -768, -768, 2560, 512, -512, -1024, -3328, -1024, -1024, -512, -512, -768, -1792, -1536, -3584, -3840, -3584, -3584, -3328, -768, -3584, -4096, -4608, -3328, -3840, -4096, -5632, -5120, -3584, -768, -1536, -1024, -3584, -2816, -1536, -2560, -3840, -3840, -4096, -2304, -2560, -4864, -768, -1280, -4352, -3840, -4608, -4096, -3584, -3584, -3072, -3840, -1792, -5632, -4864, -4352, -5120, -2816, -4352, -3584, -2816, -2048, -2560, -3328, -3072, -2816, -1536, -1536, -2304, 256, 256, -768, 0, 1536, -512, -2304, 1792, -2048, 2048, 1024, 768, 256, -1536, -512, -512, 512, -1280, -1792, -1024, -1792, -2048, -2304, -1536, -1536, 0, -2048, -3072, -3072, -3328, -2048, -1024, -1792, -768, -2816, -1536, -3840, -1792, -2304, -2304, -768, -2560, -2048, -2304, -3840, -2560, -512, 512, -1792, -4096, -4352, -3840, -3328, -2304, -1536, -1280, -1792, -2304, -3840, -4352, -3072, -4864, -3072, -2048, -2048, -1024, -1536, -768, 0, -1024, -2816, -3328, -1792, -1536, -512, 1024, 1024, 2048, 2560, 1024, 768, 768, 1024, 1792, 3072, 2816, 3584, 3840, 5120, 5120, 4608, 4096, 4352, 3840, 3584, 3840, 5632, 5888, 7168, 8704, 7424, 7168, 4352, 5632, 6144, 5888, 6400, 7168, 7168, 7680, 6144, 4864, 4096, 3328, 4608, 5120, 3840, 2048, 512, 768, 0, 512, 0, -768, -512, -2304, -5120, -5888, -6400, -6144, -5888, -6912, -8448, -9728, -9984, -11264, -9216, -10752, -11264, -12288, -13568, -13824, -14336, -13312, -12800, -10240, -8960, -11264, -11008, -11264, -9984, -7168, -6144, -5888, -5632, -3840, -2304, 512, 2816, 4864, 7168, 7936, 7936, 8192, 8960, 11008, 15616, 17920, 19968, 20736, 18688, 19968, 19968, 19968, 21760, 20992, 21760, 22528, 22272, 21504, 21248, 21248, 20224, 18944, 15872, 12544, 11520, 10752, 11008, 11264, 9728, 7680, 4608, 1536, -1280, -3840, -4352, -3840, -5632, -7168, -9728, -11776, -12288, -12800, -14848, -15104, -18432, -20480, -21248, -22784, -22528, -22784, -22272, -20736, -21504, -23808, -26880, -28160, -27904, -28160, -26112, -24576, -20992, -16640, -15872, -15360, -15360, -15360, -13056, -11008, -9472, -7168, -4096, 256, 3840, 7168, 8960, 10496, 11776, 13568, 14336, 15360, 16896, 19712, 23296, 25856, 26112, 25856, 25344, 26624, 26368, 24832, 23296, 22016, 23040, 23296, 22016, 21760, 20224, 19200, 18176, 15104, 12288, 9984, 8960, 8448, 8192, 7168, 5632, 3840, 3328, 1792, 768, -1792, -3840, -4096, -4608, -4864, -5888, -7168, -7424, -8448, -9472, -12032, -13312, -14336, -16128, -15616, -17920, -17152, -17920, -18432, -18432, -20480, -23808, -23296, -25344, -26368, -24576, -27648, -26880, -27904, -28672, -24064, -20736, -18688, -17152, -18176, -19712, -17664, -16128, -14592, -9728, -6912, -3840, 0, 1024, 1536, 4864, 6656, 10496, 13568, 12544, 14336, 14848, 17664, 21504, 23296, 24320, 25856, 26368, 25088, 23808, 21760, 22272, 26112, 26112, 26368, 24320, 20736, 19968, 19968, 18176, 16896, 15360, 13056, 12800, 11264, 9984, 8704, 8704, 8192, 6912, 3840, 0, -1536, -2048, -768, -768, -2816, -2560, -4608, -5376, -6656, -8960, -9984, -9728, -11264, -12288, -13568, -16128, -15616, -15616, -18176, -16128, -22016, -22784, -22016, -27392, -25344, -27904, -27648, -27904, -27648, -30976, -32768, -26880, -26112, -21248, -17152, -22528, -20992, -19456, -19968, -15872, -12032, -10496, -4864, -1536, 256, 1792, 3328, 8448, 11264, 16384, 15616, 15104, 17408, 18688, 23808, 25088, 27392, 29184, 27904, 31488, 27392, 25600, 26880, 25600, 28416, 29952, 25600, 23808, 23552, 22016, 21760, 20480, 17920, 15104, 14848, 12032, 9728, 10496, 8448, 10240, 9728, 6400, 4096, 256, -512, -768, -768, -1024, -2560, -4096, -3072, -5376, -7168, -7168, -9216, -9728, -9984, -13312, -15616, -15616, -17152, -16128, -16640, -19456, -19712, -22016, -24320, -24320, -27392, -27904, -28672, -28672, -30976, -30976, -31232, -26880, -20224, -20480, -18176, -20480, -21504, -18688, -17920, -14336, -11008, -7168, -2560, 1536, 2816, 4352, 7936, 11008, 16128, 17664, 17664, 16640, 19712, 22528, 25856, 28928, 28672, 32512, 31232, 31232, 29440, 26624, 28672, 29696, 31232, 29952, 27136, 25344, 24832, 24576, 24064, 22016, 19200, 17920, 15616, 13568, 11264, 10496, 11776, 12032, 11520, 7168, 4864, 2304, 1280, 2304, 256, -2048, -3584, -5120, -6144, -6656, -7168, -7424, -9216, -9984, -10752, -11520, -10496, -10752, -11520, -11776, -12544, -12032, -12800, -14080, -13568, -15616, -16128, -17152, -21248, -19968, -22784, -23296, -22528, -25600, -23808, -27648, -28160, -28160, -29440, -23040, -25600, -23296, -20480, -23296, -18688, -15872, -15360, -10496, -8448, -9216, -6400, -4096, -2304, 2048, 4608, 8960, 10240, 14592, 15616, 16896, 24320, 24064, 27136, 29184, 26880, 29952, 28416, 29952, 30208, 29440, 30720, 28416, 27904, 28416, 26624, 26112, 27136, 23808, 22528, 19456, 16896, 16128, 13312, 13568, 7936, 6912, 6400, 1280, 3072, 256, -1280, 0, -3840, -4352, -5888, -6912, -6912, -7936, -7936, -9472, -11264, -10496, -11008, -11008, -8960, -11520, -11008, -10496, -12800, -12544, -13056, -14592, -14848, -15872, -18432, -19456, -20224, -20736, -20992, -22016, -23552, -24064, -25600, -27904, -28160, -26112, -25344, -24576, -21248, -24576, -21248, -17152, -18688, -11520, -10496, -10752, -6912, -6912, -4864, -1280, 1792, 3584, 7680, 11264, 11776, 14592, 19200, 21504, 25088, 27648, 26112, 28672, 29184, 28160, 30720, 29440, 29696, 29952, 27648, 28672, 27392, 26624, 27648, 25344, 24576, 23040, 18688, 17664, 16896, 14592, 12288, 9216, 6656, 4608, 3328, 1536, -768, 768, -2048, -3584, -3840, -6656, -6400, -6656, -8448, -8448, -10240, -11520, -11520, -11520, -10752, -11008, -11264, -11520, -12288, -11776, -14080, -14592, -14848, -15872, -17152, -18688, -19968, -20480, -20736, -20992, -22784, -23808, -25344, -27136, -27648, -29440, -25600, -24320, -26368, -19712, -23296, -21760, -15104, -16128, -12288, -8192, -9216, -8448, -4608, -3584, -1536, 2816, 5376, 6912, 12032, 14080, 14336, 20736, 23552, 24576, 29184, 27136, 28416, 29696, 28160, 30976, 28928, 29440, 29440, 26880, 28416, 27136, 25856, 26368, 25600, 23552, 21504, 18944, 16896, 15360, 14848, 11008, 7424, 7424, 3328, 2304, 2560, -1536, -512, -1536, -4096, -4608, -5632, -6912, -7680, -7680, -8960, -11264, -11008, -11776, -11776, -10752, -11264, -12288, -11520, -11776, -12800, -13824, -13056, -15616, -16128, -15616, -21760, -19456, -20480, -24064, -19200, -25088, -24832, -23808, -28416, -26368, -27136, -24832, -24832, -23040, -20224, -23808, -18688, -16384, -17152, -9984, -9728, -10496, -5120, -5120, -3072, 2816, 2560, 7680, 10240, 12288, 15872, 15872, 21760, 23296, 25344, 28416, 25856, 28672, 28416, 28928, 30720, 28672, 30464, 28416, 27648, 29184, 25856, 26112, 26624, 22784, 23296, 20224, 16128, 17152, 14336, 13312, 10496, 7424, 6656, 3072, 3584, 768, -1280, 256, -3584, -3840, -4864, -6912, -6144, -7680, -7936, -8704, -11008, -11008, -11520, -12288, -10240, -12288, -12288, -11520, -13056, -12544, -13568, -14336, -14592, -16128, -17664, -19456, -22016, -20480, -22016, -23040, -22272, -25088, -25856, -25856, -27648, -26368, -22528, -24576, -22528, -19712, -22784, -17920, -15360, -14336, -9984, -8704, -7680, -6656, -2816, -1024, 1536, 6656, 6912, 10752, 13824, 14592, 18432, 22016, 24320, 26880, 27392, 27648, 28672, 27904, 29696, 30208, 28672, 29952, 27648, 27904, 27392, 26624, 26368, 25344, 24832, 21248, 19712, 18176, 14592, 15360, 12544, 8960, 7680, 5376, 2816, 2816, 1024, -512, -768, -3328, -4352, -5632, -6144, -7168, -7424, -7424, -9984, -9984, -11264, -11264, -10496, -11520, -11264, -12800, -12544, -12544, -14336, -12800, -15360, -15872, -14080, -20992, -17920, -20992, -23040, -20480, -24320, -24320, -25600, -26880, -28672, -28672, -23808, -26112, -23296, -20736, -23296, -19712, -15360, -16640, -11520, -8448, -10240, -6400, -5376, -3584, 1280, 2560, 7680, 8960, 12544, 15616, 15616, 22272, 24064, 26112, 27904, 27904, 28672, 28672, 29696, 29952, 29696, 30208, 29696, 27136, 28928, 27648, 25856, 28160, 24576, 23296, 21504, 17664, 16896, 14848, 13824, 9728, 7424, 6656, 3072, 2816, 1536, -512, -512, -2048, -4096, -5120, -5888, -6912, -7168, -8448, -8704, -11264, -11008, -11008, -12032, -9984, -11264, -12032, -11008, -12032, -12544, -12800, -13312, -14592, -14848, -17408, -19200, -19456, -21248, -22016, -22016, -23296, -24832, -25088, -26368, -27904, -26112, -23296, -25344, -21504, -20736, -23808, -16640, -16896, -15360, -9472, -10752, -8448, -6400, -4608, -2304, 1536, 4096, 7168, 10496, 12544, 14592, 17408, 21504, 23808, 26112, 27136, 27136, 28160, 27392, 29696, 29184, 28416, 30464, 27136, 28416, 27648, 25856, 26624, 25344, 24064, 21760, 19456, 17408, 15616, 14336, 12544, 8704, 7168, 5376, 2560, 2560, 512, -768, -768, -3328, -3840, -6144, -6656, -7168, -8704, -7936, -10752, -11520, -11008, -12288, -11264, -11008, -12032, -12032, -12032, -12288, -13056, -14592, -14592, -16128, -17920, -18432, -20480, -22016, -20736, -23552, -22528, -24576, -26368, -25600, -28928, -28160, -24576, -25856, -24576, -20224, -23296, -20992, -15104, -17408, -12032, -8704, -9984, -7424, -4608, -3328, -1280, 4608, 5632, 8192, 13824, 13312, 16384, 21248, 23040, 25600, 27648, 27904, 28160, 28928, 28928, 29696, 28928, 29952, 28928, 27136, 28416, 26368, 25600, 25856, 25088, 22016, 20992, 18688, 15104, 15616, 13568, 9216, 8704, 6144, 3072, 2560, 1280, -1280, -768, -2048, -4352, -4608, -6144, -6912, -7424, -7680, -8960, -10240, -10496, -11520, -11008, -11008, -10752, -11520, -11776, -11264, -12800, -12544, -14080, -14848, -14080, -18176, -17920, -20224, -22272, -19712, -23552, -22528, -24320, -26624, -25600, -29440, -27392, -23296, -26880, -21760, -21248, -24832, -17152, -17408, -16640, -9472, -11008, -8448, -7424, -5376, -2304, 0, 4608, 5888, 8960, 14080, 12288, 17664, 22272, 22016, 27648, 27392, 26368, 29952, 27136, 29952, 30208, 28928, 31232, 27904, 28416, 28416, 26112, 28160, 25856, 25088, 23552, 19712, 18688, 15872, 15104, 13824, 8704, 8704, 5376, 2816, 3840, 512, 512, 512, -3584, -3072, -5888, -6656, -6656, -8448, -7680, -10240, -11264, -10752, -12544, -10496, -10496, -11264, -11008, -11776, -12544, -13056, -15104, -13824, -16128, -17152, -16384, -21504, -20224, -19456, -23296, -20992, -22272, -25600, -25600, -25856, -30208, -25856, -22784, -27392, -20736, -20992, -23808, -16640, -14592, -14592, -9216, -6656, -9984, -4352, -2304, -3328, 3584, 5376, 6656, 11520, 13568, 13824, 19456, 22528, 24320, 28416, 27136, 28416, 29184, 27904, 30720, 29440, 29440, 29696, 28160, 26880, 27904, 26624, 25088, 26880, 24064, 21248, 20736, 17408, 15360, 15872, 12544, 8192, 8448, 4608, 2304, 3072, 0, -768, -768, -3328, -4608, -5120, -6144, -6912, -6656, -7936, -9472, -10240, -10752, -10752, -11008, -10752, -11264, -12288, -12288, -12032, -13056, -13824, -13312, -14336, -16384, -17408, -19200, -21504, -20224, -22784, -23296, -23808, -26624, -26880, -28160, -29184, -24832, -24832, -24576, -19968, -22784, -20736, -14848, -16896, -12032, -8704, -10240, -7936, -5888, -3584, -1536, 3584, 5632, 7936, 13824, 14080, 16128, 22272, 23296, 26368, 28928, 26880, 28416, 28928, 27904, 30464, 28672, 29952, 29184, 27136, 28928, 27136, 26880, 26880, 25344, 23808, 20736, 18944, 15616, 14848, 14080, 9216, 7680, 6400, 2560, 2816, 1536, -1280, 256, -2048, -4096, -4864, -6400, -6912, -8192, -8192, -9472, -11264, -10496, -12032, -11008, -9984, -11008, -11264, -11520, -11776, -11776, -14336, -13568, -14080, -18432, -16384, -18944, -23296, -18432, -22528, -24832, -20480, -25600, -26880, -25600, -28416, -28416, -22528, -25600, -25344, -18944, -24832, -20224, -13824, -17408, -11008, -8192, -10496, -6656, -2560, -4096, 1536, 5632, 4864, 10496, 13056, 12544, 17664, 22016, 22528, 26368, 27392, 25600, 30464, 28160, 28416, 32000, 28160, 29440, 29440, 26624, 27648, 27136, 25344, 25088, 25088, 20992, 19456, 18176, 15360, 15360, 13312, 8704, 7680, 6400, 2304, 2816, 768, -1536, 0, -3840, -4608, -5376, -6912, -6912, -7680, -7936, -9728, -9984, -11008, -11008, -9984, -11008, -11264, -11776, -12032, -12032, -13824, -13568, -15104, -14848, -16640, -18176, -19200, -20736, -19200, -23040, -21248, -23040, -25600, -24320, -28416, -27904, -25856, -24832, -25600, -21504, -22016, -22784, -15872, -16384, -12800, -8704, -9472, -7680, -5376, -2816, -2048, 2560, 4864, 6656, 12032, 12544, 15104, 19456, 22784, 25344, 27392, 27904, 28160, 29440, 28928, 30464, 29440, 29184, 29440, 27136, 28416, 26368, 26368, 25856, 25088, 24064, 20736, 19968, 16640, 16128, 15104, 11008, 8704, 6400, 4352, 2560, 1792, -1024, -768, -1536, -3584, -4096, -5888, -6144, -7168, -7424, -8448, -10496, -10496, -11776, -11008, -10240, -11264, -11264, -11776, -11776, -12032, -12800, -13824, -14336, -14848, -17664, -17920, -19456, -21248, -19200, -22272, -22272, -23296, -25600, -25600, -27904, -27648, -24832, -25088, -23808, -21248, -22528, -19456, -15616, -15104, -11008, -9216, -8448, -7168, -4608, -2816, -1024, 3584, 5376, 7936, 13312, 13056, 16128, 21504, 23040, 25856, 28416, 26624, 28928, 28928, 28416, 30208, 28672, 29184, 27904, 27648, 27904, 26112, 27136, 25856, 25088, 24064, 20224, 18944, 16896, 14848, 14080, 9984, 7424, 6144, 3328, 2816, 1280, -1024, 0, -2560, -3840, -4352, -6144, -6400, -7168, -7424, -8704, -10496, -10496, -12032, -10752, -11264, -11776, -11520, -12800, -11520, -12800, -14080, -12288, -15360, -15360, -16640, -19456, -19712, -21248, -21504, -23296, -23552, -24064, -27136, -26368, -27904, -27136, -22784, -25856, -20992, -20736, -22528, -16128, -16896, -13824, -9216, -10240, -7936, -6400, -4096, -1792, 1536, 4352, 7680, 10496, 14080, 14336, 18688, 22784, 23552, 27904, 26624, 27136, 29184, 26624, 29952, 28928, 28160, 29696, 26880, 27648, 27136, 25600, 26112, 25088, 24064, 21760, 18944, 17152, 15104, 14080, 12288, 7936, 7168, 4864, 2560, 3072, 0, 512, -512, -2816, -2816, -5376, -5376, -6656, -7680, -7680, -10240, -11008, -11008, -11264, -10240, -9984, -10496, -11008, -10752, -11776, -13312, -13312, -14848, -16128, -16640, -19200, -20224, -21248, -20480, -22784, -21760, -22528, -25856, -24064, -26624, -29184, -23808, -24832, -26624, -19968, -23552, -22784, -15360, -17408, -12288, -9216, -9216, -6656, -5376, -2048, -1280, 3072, 5888, 6656, 12032, 12800, 13824, 19712, 21760, 24576, 27904, 26112, 29184, 28672, 27904, 32000, 28672, 29184, 30208, 26112, 28160, 26368, 25344, 25856, 24576, 23552, 20224, 19456, 16896, 15104, 15616, 11008, 8192, 7936, 3584, 2560, 2304, -1280, -512, -2304, -4352, -4608, -7168, -6400, -7936, -7936, -7936, -10752, -9728, -11008, -10496, -9984, -11008, -11264, -12032, -11520, -12288, -13056, -13568, -13824, -15616, -16384, -17152, -19712, -19456, -20992, -20736, -22784, -23808, -24832, -27136, -27648, -26880, -24576, -25344, -22528, -20992, -23552, -17152, -16384, -15360, -9728, -9728, -9216, -6144, -5120, -4096, 1024, 2816, 5376, 9216, 11776, 13568, 16896, 21760, 22528, 26368, 27648, 26112, 29440, 27392, 28672, 29440, 27904, 29184, 26624, 27136, 27136, 25344, 26112, 25856, 23552, 22784, 20736, 17152, 16896, 14848, 12032, 9984, 7168, 5376, 2816, 3072, 512, -512, 512, -3072, -3072, -4352, -6400, -6144, -7424, -7680, -9216, -9984, -10496, -10496, -10496, -9984, -10496, -11264, -11264, -12032, -13056, -13312, -13824, -15104, -16128, -16640, -19200, -20224, -19200, -23040, -20736, -22784, -25344, -23552, -27904, -27904, -26880, -25344, -24832, -23552, -20480, -23040, -18176, -14848, -15360, -9472, -8192, -9472, -4864, -3840, -3584, 2304, 3584, 5888, 10752, 11776, 14336, 17152, 21248, 24576, 25600, 28416, 27136, 28416, 29184, 28416, 29952, 28416, 28672, 27904, 26368, 27392, 25600, 25344, 26368, 23552, 22528, 20992, 16640, 16896, 15104, 12288, 9984, 6912, 5632, 3072, 2304, 1280, -1280, 0, -3072, -4096, -4352, -6656, -6400, -6656, -7936, -8704, -10240, -10496, -10496, -10496, -10240, -10752, -12032, -11008, -11776, -11776, -13312, -12800, -13312, -15616, -15104, -18944, -19200, -19712, -21248, -21504, -23296, -23552, -26880, -25600, -27136, -27904, -20736, -26368, -22016, -18688, -24576, -16384, -15872, -15104, -9728, -9984, -9216, -7168, -3840, -2816, 768, 4608, 6400, 9472, 13568, 13568, 17152, 22784, 21760, 27136, 26368, 25088, 29440, 25344, 29184, 29440, 26368, 29696, 26368, 26624, 27904, 25088, 25856, 25088, 23296, 21504, 19200, 17152, 15360, 14080, 12800, 7936, 7168, 5120, 1792, 3840, 0, -768, 512, -3840, -3072, -4864, -6400, -6144, -8192, -8192, -9728, -11264, -11264, -11520, -10752, -10496, -11264, -11008, -11776, -11264, -11264, -14848, -12288, -16128, -17152, -16128, -22272, -19200, -21248, -23040, -20736, -24064, -24320, -24320, -27392, -27904, -25344, -24320, -25344, -21760, -21760, -23040, -17408, -15872, -15360, -9216, -8704, -9984, -3840, -3328, -2304, 3584, 3840, 7424, 10752, 12800, 14080, 17408, 22272, 23296, 25856, 27392, 27136, 28160, 28928, 29184, 29440, 29184, 28672, 27648, 26880, 27136, 25088, 25088, 25600, 22528, 21504, 19200, 16128, 16128, 14592, 11776, 8704, 7168, 4608, 2560, 2048, 0, -1280, -1280, -3840, -4864, -5120, -6656, -6656, -6656, -7936, -9216, -10240, -10752, -11008, -10752, -9984, -11264, -11264, -10752, -11264, -12032, -13056, -13312, -13824, -16640, -16128, -19456, -20736, -17408, -23808, -21504, -21760, -26624, -23552, -26880, -27904, -24320, -24320, -24576, -21504, -20992, -21504, -16384, -16384, -13312, -9984, -9472, -8448, -5888, -2816, -2304, 2560, 5120, 6400, 12544, 11776, 15360, 19456, 20992, 25088, 25856, 26624, 28160, 27648, 27648, 29696, 28416, 28416, 28928, 26624, 27648, 27136, 25856, 25088, 25344, 23552, 20480, 20224, 16128, 15616, 15104, 10496, 8960, 6912, 4608, 3328, 2304, 512, 0, -1280, -3072, -3840, -5120, -5632, -6656, -6912, -7680, -9728, -9984, -10752, -10240, -9984, -10240, -10240, -11520, -11008, -12032, -12544, -13824, -13568, -14592, -17920, -15104, -20480, -19712, -18432, -23808, -19200, -23296, -25344, -23808, -26880, -27648, -24832, -23552, -25344, -20480, -21504, -21504, -15616, -15104, -12544, -8960, -7168, -8704, -3584, -2304, -2560, 4864, 4352, 6912, 12032, 12032, 15616, 18432, 22272, 24320, 26880, 26624, 28160, 28416, 27904, 29952, 27904, 28416, 27904, 26368, 26368, 26112, 24832, 24320, 25600, 21760, 20736, 19712, 15616, 16384, 14080, 10752, 8704, 6656, 4352, 2560, 2304, -768, -512, -1280, -3328, -3840, -5120, -5888, -6912, -6912, -8192, -9472, -9728, -10496, -10240, -10496, -9984, -11008, -11008, -10240, -12288, -12032, -12544, -14080, -15616, -15104, -17920, -20480, -17664, -22272, -21248, -20224, -24832, -22784, -25088, -25856, -27392, -24576, -23808, -25856, -19712, -23040, -21504, -15872, -16128, -12544, -9216, -8704, -7680, -3840, -3072, -512, 2816, 5120, 8192, 9984, 13568, 14336, 18176, 22272, 22784, 26368, 25856, 27904, 27904, 27904, 30208, 27136, 29184, 28416, 25856, 27392, 26112, 23808, 25344, 24064, 21504, 21760, 18176, 16640, 15872, 13824, 11520, 8192, 7680, 4096, 3072, 2048, -1280, -512, -2304, -3584, -4096, -6144, -5632, -6912, -7424, -7936, -9728, -10496, -9728, -11264, -10752, -10496, -12032, -11520, -11264, -12288, -12800, -12800, -13312, -15872, -14592, -17664, -20224, -17664, -21248, -22528, -19968, -25344, -24832, -23552, -27904, -27136, -23296, -25600, -23808, -19456, -23296, -20480, -15360, -16896, -12288, -9472, -9728, -8192, -4608, -3840, -1024, 2816, 3584, 7936, 10752, 12288, 15360, 17664, 21760, 24064, 24576, 26112, 27392, 26368, 27904, 29440, 26624, 28672, 27904, 25600, 27136, 26368, 24320, 24832, 24576, 21504, 20992, 18688, 15360, 15872, 13824, 10496, 8448, 6912, 4352, 3584, 1792, 0, 0, -2048, -2816, -4096, -5888, -5888, -7424, -7424, -8192, -9984, -10240, -10240, -10240, -10496, -10240, -11776, -12288, -11520, -12800, -13056, -13824, -14336, -16384, -16128, -18176, -19968, -18688, -21504, -20992, -22272, -24320, -23808, -26112, -26112, -27648, -24320, -24576, -24320, -19456, -23040, -19712, -14592, -15616, -10752, -8448, -8960, -6656, -3328, -3584, 768, 3840, 4352, 9216, 11520, 13824, 15360, 20480, 22784, 24576, 27648, 25856, 28416, 28160, 27904, 30208, 27392, 28160, 27904, 26112, 26368, 26368, 24320, 24832, 24576, 21248, 20992, 17920, 15360, 15616, 13056, 9728, 7168, 5888, 2816, 2048, 1024, -1792, -768, -2560, -4096, -4352, -5632, -6400, -6912, -7424, -8960, -9728, -11008, -10752, -10496, -10240, -9984, -11008, -10752, -11264, -11520, -11776, -13568, -13056, -14080, -17408, -16640, -19200, -20224, -19712, -22528, -21248, -24064, -23808, -25856, -26880, -24576, -24576, -23552, -21760, -21760, -21248, -18176, -16384, -14592, -10496, -10496, -7936, -6912, -4352, -1792, 512, 4608, 5888, 9728, 12288, 13056, 17408, 19968, 23296, 25088, 26112, 27136, 27648, 28160, 28672, 29440, 28160, 29440, 27392, 27392, 27648, 25344, 26112, 24832, 24064, 22272, 19456, 17920, 16128, 15360, 12544, 9984, 7680, 5632, 4096, 2048, 1024, 0, -1024, -2560, -3584, -5120, -6144, -6400, -7936, -7680, -9472, -10496, -10240, -10496, -9728, -9984, -10240, -10752, -10496, -11008, -12288, -11264, -14080, -14848, -14592, -18176, -18176, -18688, -19968, -20224, -20480, -22528, -22784, -24320, -25344, -26368, -25856, -22528, -25088, -21760, -20224, -23040, -15872, -15360, -13824, -8960, -8960, -6912, -5376, -2304, -768, 1792, 5632, 6656, 9728, 13312, 13824, 17152, 22272, 22784, 25856, 26880, 26368, 29184, 27392, 29952, 28672, 27392, 29696, 25600, 26880, 26368, 24064, 25088, 23808, 22272, 20480, 18688, 16640, 15104, 14336, 11520, 7936, 7168, 4864, 1536, 2560, -768, -1280, -1024, -4352, -4096, -5632, -6144, -6400, -7680, -7168, -9984, -9472, -10240, -11264, -10240, -11264, -11776, -11776, -12032, -13056, -12800, -14080, -14080, -15360, -17152, -16640, -20736, -19200, -19968, -23808, -19968, -24832, -25856, -24064, -28928, -26624, -23552, -24576, -23296, -20224, -22016, -20224, -14848, -14848, -12544, -8704, -8704, -8448, -3584, -3072, -1280, 5120, 4864, 8704, 12544, 12544, 16896, 19456, 23296, 25088, 25088, 26880, 26624, 27392, 28416, 28160, 27904, 27648, 27648, 26368, 25856, 26112, 24832, 24320, 24576, 20480, 19200, 18176, 14336, 14848, 12544, 8448, 7168, 5120, 3328, 1792, 1024, -1024, -1792, -2304, -4608, -5632, -5632, -7168, -7680, -7680, -9728, -10496, -10496, -11008, -10240, -10496, -10240, -11264, -11008, -11520, -12288, -12544, -14080, -14080, -15104, -17152, -16896, -20992, -17920, -20736, -22016, -19968, -25856, -23552, -25088, -28416, -25088, -24320, -24320, -22784, -19456, -23296, -17920, -14336, -15616, -9728, -8704, -8448, -6400, -3072, -2560, 256, 5376, 3840, 9984, 12032, 12288, 17408, 19200, 23040, 24832, 25856, 26368, 27136, 27136, 28160, 28416, 26624, 28416, 25856, 25344, 26368, 24576, 24064, 24320, 23552, 19200, 20224, 16384, 14080, 16384, 11008, 9216, 7680, 4352, 3328, 2304, 768, -1024, -768, -3072, -4096, -4608, -5888, -6400, -6656, -7424, -8960, -9728, -10752, -10240, -9984, -10496, -9728, -12288, -10752, -11520, -12800, -12544, -13312, -14592, -16128, -14592, -19968, -19456, -17152, -24064, -19200, -22528, -25600, -23552, -26368, -27136, -24832, -22528, -24576, -20736, -19712, -21760, -15360, -14080, -13056, -8960, -7680, -8448, -4864, -2304, -2560, 4352, 4096, 7680, 11776, 12288, 16384, 18432, 22016, 24576, 25856, 26624, 26880, 28416, 26624, 29696, 27904, 27392, 28160, 26624, 25856, 26624, 25600, 23808, 25600, 22016, 19712, 19968, 15104, 15360, 13824, 10240, 8192, 5888, 4608, 2304, 2304, 0, -1280, -1536, -3584, -4352, -5120, -5888, -6400, -6656, -7936, -8960, -9984, -10240, -9216, -10240, -9472, -10240, -11520, -10752, -11520, -12288, -13056, -12800, -14592, -16384, -15872, -19456, -19968, -18176, -23040, -21504, -22528, -25856, -24832, -26880, -27648, -24064, -24832, -23552, -20736, -22272, -19456, -16128, -14848, -10752, -9216, -8448, -6912, -3840, -2560, -512, 4608, 4864, 8704, 12544, 12032, 16896, 19968, 22016, 26112, 26624, 26624, 28416, 27904, 28672, 29440, 28672, 28160, 27648, 27136, 25856, 26112, 25088, 24576, 24832, 22016, 20224, 18432, 15872, 15616, 13056, 9984, 8192, 5120, 3840, 2560, 512, 256, -1024, -2304, -3328, -4608, -5632, -6144, -6400, -7424, -8448, -9472, -10496, -9984, -9472, -9984, -9984, -11008, -11776, -11776, -12544, -12544, -14336, -13824, -14592, -17408, -16896, -18688, -19712, -20224, -21248, -23040, -24576, -24320, -27392, -28160, -25088, -24832, -25088, -19456, -22272, -21248, -14336, -17408, -12544, -8704, -11008, -7168, -6656, -4608, -2048, 768, 3584, 5632, 9984, 12032, 13824, 17920, 21248, 23040, 25856, 25600, 26624, 27392, 26112, 28928, 26368, 27136, 27904, 24320, 27136, 25344, 24320, 25856, 23552, 23808, 21248, 18944, 16896, 15360, 14336, 11264, 8448, 6656, 4352, 3072, 2048, 256, 512, -1024, -2816, -2560, -5376, -4864, -6400, -7424, -7168, -9984, -9728, -10496, -10496, -9472, -10240, -10752, -11008, -10752, -11520, -12032, -12288, -14336, -13312, -15104, -17664, -17152, -19968, -19968, -20224, -22528, -22016, -24320, -25600, -25344, -28672, -24320, -23552, -25856, -19712, -22016, -22016, -15872, -16640, -13056, -9984, -8960, -7936, -6656, -2048, -2816, 1792, 6656, 5376, 11520, 13568, 12800, 19456, 22016, 23040, 26880, 26112, 26880, 27904, 27648, 29440, 27392, 28672, 28160, 25600, 27648, 25600, 24576, 25600, 23808, 22784, 20224, 18432, 16384, 14848, 14336, 10752, 7936, 7168, 3584, 2560, 2304, -1280, -512, -1536, -3584, -3840, -5632, -5632, -6912, -7168, -7936, -10496, -9472, -10496, -10752, -9472, -10496, -11520, -11008, -11520, -12032, -12288, -12544, -14848, -13568, -16384, -18176, -17408, -20992, -19200, -21248, -23296, -22272, -26368, -24832, -26624, -28416, -23040, -25088, -24320, -19712, -23296, -19456, -15616, -16128, -11008, -10496, -8960, -7424, -5888, -1792, -1792, 3328, 5632, 6144, 12800, 12800, 15104, 20992, 20992, 25344, 26112, 25600, 28160, 26880, 28416, 28928, 26624, 29184, 26368, 26624, 27392, 24576, 26112, 24832, 23552, 23040, 19712, 18688, 16384, 14848, 13568, 9728, 7936, 5888, 3328, 3072, 768, 0, -512, -2816, -2560, -4352, -5376, -5120, -7424, -6912, -8448, -10240, -9728, -11264, -9984, -9984, -11008, -10496, -10752, -10752, -11776, -10752, -13568, -13568, -13312, -18176, -17152, -18688, -21248, -20480, -20736, -22784, -23808, -23296, -25600, -27136, -24832, -24576, -23808, -22528, -20736, -21760, -20224, -15104, -14848, -12288, -7680, -9216, -7168, -2816, -2304, -512, 5376, 5632, 8192, 12800, 13312, 14848, 20224, 22784, 23040, 26624, 26624, 25600, 28928, 28416, 27904, 29184, 27904, 27392, 26368, 26624, 25344, 24064, 24832, 23296, 19968, 20224, 16640, 14848, 15616, 12032, 9472, 7680, 5888, 3584, 2560, 1792, -1792, -1024, -2048, -5376, -4352, -5888, -7680, -6656, -7680, -9216, -9472, -9984, -9728, -9728, -9216, -9728, -11520, -10496, -11520, -12544, -13056, -14336, -14592, -16128, -16384, -17664, -19968, -17920, -20480, -21504, -21504, -23296, -25600, -25088, -27136, -27648, -23040, -26368, -23040, -20480, -23808, -16640, -16384, -13312, -9728, -9472, -6912, -6656, -3072, -1536, 768, 4608, 5632, 9216, 12288, 13824, 17664, 21504, 22784, 26880, 26368, 27136, 29952, 26880, 29952, 28928, 27136, 28928, 25856, 26880, 25856, 25344, 25088, 23808, 24064, 21248, 19200, 17920, 15360, 14080, 12544, 8448, 6912, 4864, 2560, 2048, -512, -512, -1792, -3328, -3072, -5632, -5120, -5888, -7168, -7168, -8960, -9984, -10240, -10496, -10240, -10752, -10240, -11008, -10752, -10752, -11264, -11776, -12544, -13312, -15104, -15360, -17920, -18944, -18176, -21504, -20992, -22528, -24576, -25088, -25600, -26880, -26112, -22528, -24320, -21248, -20224, -22272, -15872, -15872, -13312, -10240, -9984, -7936, -6912, -3584, -2560, 1792, 4352, 6400, 10752, 12544, 15104, 18432, 21760, 23552, 26368, 26368, 26112, 28416, 26624, 28928, 28160, 26624, 28672, 26112, 27392, 26368, 25856, 25344, 24832, 23552, 20736, 19456, 16384, 15616, 13824, 10752, 8448, 6144, 4352, 2816, 2048, -512, -512, -1280, -3328, -3072, -5632, -5888, -6656, -7936, -8192, -9728, -10240, -11008, -9984, -10240, -10496, -10240, -11264, -10496, -11264, -12032, -13056, -12544, -15872, -14080, -17408, -19968, -17408, -22784, -20224, -20736, -24576, -21760, -25856, -25600, -26368, -25088, -23296, -24832, -20224, -21248, -22272, -15616, -16384, -14080, -7936, -10496, -7424, -3840, -4864, 768, 2304, 4608, 8448, 9216, 14336, 13824, 18176, 22272, 22272, 26368, 26368, 26368, 28160, 27392, 28928, 28672, 27648, 28416, 25856, 26624, 26368, 23552, 25856, 23552, 21504, 21504, 16896, 16640, 15104, 13056, 11520, 7936, 6912, 4096, 2560, 1536, -768, -768, -2304, -3840, -4096, -5632, -6144, -6400, -7680, -7168, -9216, -10240, -9216, -10752, -9728, -10496, -11520, -11264, -12032, -12032, -12544, -13056, -13312, -13824, -15872, -17408, -18688, -19968, -20736, -21504, -21248, -24832, -24064, -25856, -28928, -25600, -25344, -24576, -22272, -21248, -21760, -19200, -15360, -15360, -11008, -9216, -9728, -6912, -5120, -3840, 0, 3584, 4864, 8448, 12032, 12544, 17152, 19968, 23040, 25600, 26368, 26880, 27392, 27648, 28160, 28672, 27904, 27904, 27392, 26112, 26880, 25600, 25344, 25088, 24320, 21504, 20480, 17664, 15104, 15360, 12288, 9216, 7936, 4608, 3584, 2304, 768, -512, -1280, -2560, -3840, -4864, -6144, -6400, -7168, -7936, -8704, -9984, -10496, -10240, -9728, -10240, -9728, -11008, -11008, -10752, -12288, -12032, -13568, -13824, -14848, -17152, -16128, -20224, -18688, -19968, -23040, -20480, -25088, -24832, -25856, -27904, -26880, -23808, -25088, -23040, -19456, -23808, -16896, -15360, -15104, -8448, -10752, -8192, -6656, -4608, -2304, 0, 4352, 5376, 9728, 12288, 13568, 17664, 20992, 23808, 25856, 27392, 26112, 28672, 27648, 28416, 29440, 26880, 28672, 26368, 26880, 26624, 24576, 26368, 24320, 24320, 21760, 19456, 17408, 16128, 15104, 12032, 9728, 6656, 4864, 3328, 1792, 256, -768, -1024, -3584, -3072, -4864, -5888, -5376, -7424, -7424, -8960, -10240, -10496, -10752, -9984, -11008, -10752, -11776, -11008, -12032, -11520, -12288, -13824, -12032, -16896, -15616, -17408, -21760, -16896, -23040, -21504, -21504, -26368, -23296, -27136, -26880, -24576, -23040, -23552, -20736, -20224, -22016, -15104, -15104, -13568, -8704, -9216, -8448, -4864, -2560, -2560, 4352, 5120, 6656, 13312, 12288, 15360, 19200, 21760, 24320, 26112, 26624, 26112, 28416, 27392, 28928, 28160, 27904, 28416, 26368, 27392, 26112, 24832, 24576, 24320, 21760, 19712, 18688, 14336, 15360, 13312, 9472, 8448, 5632, 4096, 2816, 1792, -768, -1024, -1536, -4096, -3584, -5376, -6144, -6144, -7168, -8192, -9472, -9728, -10752, -9216, -9472, -9984, -9984, -11008, -10240, -10752, -12288, -12800, -12800, -16384, -14592, -17920, -21504, -16128, -23040, -20736, -19712, -25856, -21760, -25344, -26880, -26112, -25600, -23552, -25344, -20224, -22784, -22016, -14848, -16640, -12544, -7424, -10496, -6656, -2816, -4864, 1536, 3072, 3584, 9984, 9472, 13312, 15360, 17408, 23040, 23040, 26624, 26112, 27136, 28416, 27648, 30208, 27904, 27904, 28416, 25088, 27136, 25856, 23040, 25856, 23040, 20992, 22016, 16128, 16640, 16128, 12288, 12032, 7424, 6400, 4096, 2560, 1536, -1536, -768, -3328, -4608, -4096, -6656, -6400, -6400, -8192, -7680, -9984, -11008, -9472, -11008, -9984, -9984, -12288, -11264, -11776, -13568, -12800, -14336, -15104, -15104, -17152, -18432, -19712, -19456, -21504, -21248, -21504, -25600, -24320, -26368, -29440, -25088, -23808, -26368, -20992, -20992, -23296, -15360, -15872, -13824, -8704, -8960, -7936, -5888, -3328, -2816, 1792, 4864, 5376, 11008, 12288, 14080, 18688, 21760, 24064, 26624, 26112, 27904, 28160, 26880, 30208, 27392, 27904, 28928, 25088, 27136, 26368, 24576, 25344, 25088, 23040, 20992, 20224, 15872, 15872, 14848, 10496, 8704, 6656, 3584, 2560, 2048, -768, -512, -1280, -3584, -3328, -5120, -5120, -6144, -6656, -7168, -9728, -9984, -10752, -10752, -10496, -10496, -10752, -12288, -10496, -11008, -12800, -10496, -12544, -15104, -12800, -17408, -18944, -17152, -20992, -20480, -22784, -22272, -25856, -25856, -23808, -30976, -21760, -23040, -26880, -16640, -23808, -20992, -14080, -17664, -12544, -9728, -11776, -8192, -6912, -4864, -1280, 768, 4864, 6656, 10496, 13568, 13312, 20736, 20736, 24320, 26624, 23040, 28928, 25856, 26880, 30208, 25344, 28928, 27904, 25600, 27904, 26624, 25088, 26624, 24576, 22784, 21248, 18176, 16896, 14592, 14336, 9728, 7168, 7424, 2048, 4352, 1536, -512, 768, -6144, -3328, -20224, -26368, -30720, -29696, -26624, -22272, -19456, -16128, 16128, 20992, 24832, 27648, 30464, 25344, 17920, 17664, 20480, 23296, 23552, 25088, 29440, 31744, 32512, 28928, 20992, 10752, 1024, -11264, -17920, -20992, -25600, -22272, -15872, -14848, -18176, -16640, -20224, -15360, -26112, -28928, -15872, -11264, -7936, -7936, -5632, -4608, -768, 1024, 2816, 5120, 7168, 2816, 3840, 4608, 6912, 4608, 1792, 3328, 6656, 2816, -4864, -17664, -27648, -21504, -13056, -5376, -768, -1536, -4608, -4352, -7936, -8448, -4608, 512, 1024, 6656, 12032, 12288, 19712, 29952, 32512, 32512, 32512, 30976, 28160, 22016, 18432, 15872, 11776, 2816, 4352, -512, -1792, -3328, -11264, -15360, -15616, -15616, -16128, -18432, -20224, -25344, -29696, -32512, -32768, -32768, -31744, -20736, -13056, -1024, 1280, -1536, 1792, 2048, 2304, 7936, 7936, 4096, 8704, 7168, 8704, 8704, 11776, 19968, 21504, 23808, 17664, 12032, 10240, 16384, 11264, 6912, 5632, 0, -7424, -2048, 3840, -1536, -9216, -16896, -17408, -10752, 0, 1536, 256, 3328, 6144, 10496, 16384, 14848, 12800, 10240, 1024, 0, 768, -6144, -768, 5376, 7168, 6656, 2304, -7680, -10752, -15616, -21760, -23552, -23296, -24576, -22272, -18944, -7936, -5120, -9728, -3584, -11264, -4352, 4608, -6400, -2304, 1792, 256, 2816, -512, -4864, 3072, 12032, 19456, 18432, 14848, 17408, 17664, 20992, 22016, 19456, 14848, 2304, -5888, -3072, -1792, -5632, -512, 0, -2304, -512, -3840, -2560, -768, -5632, -4352, -9728, -11264, -8448, -6144, -6912, -4096, 0, -3840, 5120, 4864, 4608, 256, 2560, 10496, -256, -6400, -6400, -2816, 7680, 9472, 2304, 11520, 9472, -7680, -7680, 5376, 1280, -6656, -11008, -14336, -10752, -12288, -12288, -7424, -15872, -19456, -10752, -5888, -3072, -3584, 2048, 11520, 9216, 10240, 6400, 3584, 2816, 10240, 11776, 14080, 16640, 7680, 4352, 7680, 9216, 8448, 4608, 3328, 4096, 3840, 11776, 9472, 512, -256, -6656, -9216, -4864, -5376, -9216, -15872, -13056, -12288, -5120, -512, 768, -3072, -3072, -2560, -8960, -9472, -12544, -5632, 3584, 15616, 10240, 15360, 19200, 8448, 10496, 12288, 9728, 7424, -8192, -11520, -14336, -16384, -15616, -7680, -5120, 7680, 2560, -11776, -9472, -8960, -7680, -6144, -3072, -5888, -8704, -7424, -5632, -5120, -3584, 1024, 11264, 19712, 12544, 2560, 2048, 6144, 5120, 7168, 7936, 6912, 10240, 8960, 17664, 9984, 13824, 9728, 6656, 5632, 11008, 9216, 1792, 3584, 512, -6400, -12800, -13056, -14336, -10752, -14080, -11776, -9216, -11264, -9216, -8960, 256, 5888, 2816, -768, -8704, -16896, -8448, -3072, -7936, -6912, -3328, -256, 5376, 7936, 5888, 0, -2816, -768, -512, 2304, 6912, 1280, -2048, -512, -4352, -3328, 2560, 2304, 768, 8960, 8192, 11008, 6144, 3840, 512, -3840, -2304, -1280, 512, 1280, 6912, 6400, 10752, 19456, 15616, 4352, 6400, 3584, -1280, -4352, -6144, -1536, 2816, 5888, 1792, -2048, 1280, -2816, -5888, -6912, -12288, -7680, -3072, -6656, -9216, -9472, -9984, -11776, -15616, -14080, -5888, -5120, -5632, -3584, -2560, -4096, -4096, -5632, -2816, -768, -3584, -8704, -4096, 2304, 7168, 6400, 12800, 16128, 13312, 14336, 11776, 12800, 13824, 14336, 11520, 13824, 7424, 5120, 5376, 0, 0, 1536, 4096, 7168, 3584, -256, -2304, -2560, -1024, -2304, -3328, -1792, -5376, -6912, -7424, -10240, -10496, -8960, -10752, -16384, -2816, 2304, 512, -3072, -6144, -9472, -10240, -8704, -7424, -8704, -3072, -6656, -5120, -1536, -1024, 1280, 1280, 6912, 256, -4352, 512, 5376, 3072, 2048, 2304, 3840, 5888, 6144, 256, 1280, 5632, 6400, 7168, 14592, 14080, 10496, 8448, 9216, 6912, 1280, 256, 3840, 8704, 5888, 1024, 5120, 4608, -256, -5376, -5632, -3840, -4352, -2048, -1536, -1536, -3072, -3840, -6656, 256, 7424, -2048, -10240, -13312, -14080, -4864, -5376, -9216, -12288, -14336, -7424, -3840, -7424, -9984, -11776, -8960, -3584, -2816, -4096, 256, 6912, 5632, -2560, -3584, -1792, -3072, -3072, 5888, 14080, 12288, 16640, 10752, 5120, 11776, 11520, 12544, 10752, 9728, 8704, 6400, 8448, 5376, 2560, 9728, 10240, 6656, 5632, 9472, 8448, 3072, 1024, 1792, -3584, -12544, -10496, -9216, -13568, -10240, -8960, -11264, -7936, -5632, -4864, -12800, -19968, -20480, -19968, -12288, -7936, -4608, -6912, -7168, -1792, -4352, -2816, 1280, 8192, 9984, 4864, 3584, 5632, 8704, 9472, 5888, 5120, 10240, 10240, 6912, 3584, 2816, 1792, 7424, 8704, 4864, 8192, 1792, -3840, -3072, -6144, -3072, 2048, 1536, 5376, 8704, 7424, -1536, -5632, -3840, 256, -256, 6144, 6912, 5120, 9216, 10752, 11520, 6912, -3584, -12800, -8704, -3584, -6656, -6400, -2560, 2560, -1024, -7168, -7680, -8704, -17664, -23296, -21760, -18944, -13056, -9728, -6144, -4864, -2304, -1792, -7680, -8960, -7680, -9216, -3072, 6400, 8192, 11264, 12800, 11520, 13056, 17408, 24064, 23040, 18944, 15360, 13312, 16384, 12288, 7680, 2816, 2816, 2816, 512, 3584, 6144, 4096, 3328, -1792, -4352, -2304, -3072, -5120, -8192, -11520, -13824, -14848, -8960, -5888, -11776, -13056, -8448, -7168, -7424, -6144, -9216, -7680, -6144, -5632, -5120, -3328, -2304, -3584, -1792, 2560, 6656, 5632, 2304, 2304, 2560, -512, -2304, -3840, -2816, -256, 4864, 6912, 8448, 7168, 1280, 768, 1280, 1536, 2560, 3584, 6144, 8192, 9216, 10240, 10496, 9472, 4864, 2816, 768, -1792, -2560, -1792, 1536, 6912, 9728, 7168, 5888, 4096, 4608, 3840, -1792, -8448, -5120, -3328, -6144, -6400, -4864, -3840, -6656, -13312, -14336, -12288, -10496, -9216, -7680, -8192, -7680, -3840, -9728, -12544, -12032, -8192, -4352, -4352, -2816, -768, 768, 2048, 6144, 7168, 4096, 1536, 256, 1792, 7168, 10496, 10752, 17664, 22272, 19968, 18688, 15872, 7680, 3584, 2304, 1792, 3840, 8192, 5120, 2560, -2048, -5120, 512, 2304, -512, 1280, 3072, -1024, -3072, -4864, -8192, -9472, -7424, -6144, -7168, -9984, -11008, -10240, -11264, -7168, -6400, -8448, -9984, -9472, -8704, -7424, -7168, -6400, -4864, -256, -1280, -5632, -3072, 512, 1536, 9728, 11776, 6400, 7680, 10496, 12032, 9472, 5376, 1792, -1792, -2048, 2816, 9984, 12288, 11008, 8960, 6912, 6400, 5632, -256, -5632, -2816, 3328, -1024, -3328, -768, -2048, -1792, -2816, -4352, -1280, 1280, 2304, 2048, 3840, 6400, 4096, 5632, 5120, 1280, -4096, -6912, -7424, -7680, -2304, 2304, 2304, 768, -3584, -12800, -14336, -14336, -20224, -23552, -20480, -14592, -6144, 3072, 2560, 2816, 1024, -5632, -5376, -3328, -512, 1024, 2560, 3840, 2048, 8960, 18432, 13568, 11264, 6400, 6400, 12288, 14336, 17664, 13568, 12800, 19200, 21760, 18176, 8448, 3072, -4096, -8192, -6400, -3584, -1280, -4096, -5888, -4864, -5632, -9984, -10496, -12032, -11520, -8448, -8960, -9984, -9728, -8960, -8704, -7424, -7168, -7168, -5888, -2560, -1792, -2304, -2816, -4608, -1280, 3328, 256, -3328, -2048, -1280, 1536, 6912, 11776, 11008, 6400, 2048, 2816, 4096, 4608, 5888, 7680, 3072, 1280, 2560, 1792, 1280, -1536, -1024, -1280, 256, 2560, 2304, 3840, 5376, 4352, 2560, -2048, -4096, 2560, 8448, 8704, 5888, 3328, 4352, 4352, 2304, 2816, 1792, -1024, -2048, -2048, -5632, -6912, -6656, -4864, -1792, -4608, -4096, -4096, -12032, -15872, -14080, -9216, -4096, -6400, -8448, -7680, -8704, -10752, -12544, -10496, -11008, -7936, -5120, -768, 7168, 12288, 16896, 16384, 9216, 5120, 6656, 5376, 5632, 9984, 13056, 11520, 9984, 10240, 13568, 14336, 9984, 6144, 4096, 3072, 4096, 6144, 6912, 4096, 3328, 1792, -4608, -8448, -12800, -12032, -8448, -6144, -5120, -6656, -8192, -7936, -11776, -13568, -14848, -14336, -7424, -3328, -2816, -512, 2048, -2816, -6144, -2816, -2304, -1536, -512, -1536, 256, 1024, 1280, 2816, 1536, 1792, 4096, 7680, 7168, 4864, 3840, 1792, 1024, 2816, 6912, 5632, 1536, 2304, 2816, 768, 1024, 4352, 6912, 4608, 2816, 3072, 1280, 512, -512, -1536, -1792, -512, 2560, 3072, 2304, 256, -512, 768, 1024, 2816, 5376, 7680, 7168, 1536, -2304, -4608, -5632, -5632, -9728, -10496, -6912, -4608, -4608, -6912, -6912, -5888, -8192, -8960, -8192, -8704, -7680, -6400, -6144, -4608, -2304, -1280, 1280, -1280, -6656, -4864, -2816, -1024, 2816, 9472, 12288, 11776, 12800, 13568, 12800, 11520, 11520, 9472, 4608, 6144, 11264, 9728, 11008, 12032, 7424, 3840, 2816, 2560, 3072, 1024, -2048, -1536, -1024, -4352, -6912, -7168, -9216, -8704, -9472, -13568, -13568, -11776, -9728, -9728, -9472, -7168, -6144, -5888, -9472, -10752, -7680, 0, 5120, 4608, 3072, 3584, 2304, 512, 1536, 3840, 3328, 2560, 3584, 3072, 512, 3072, 7424, 5376, 256, 1792, 5376, 4864, 3584, 3840, 3840, 1024, -256, 1280, -256, -1024, 0, -512, 768, 1536, 1536, 3328, 5376, 3840, 1792, 768, 1280, 512, -768, 768, 768, 1280, 2048, 2560, 4096, 3584, -256, -1792, 512, 2816, 3072, -2560, -8960, -10752, -6656, -5376, -9472, -11264, -11264, -12032, -10752, -6912, -6912, -5888, -3840, -4096, -5120, -5376, -3584, -3072, -2304, -1792, -1536, 0, 3328, 7680, 8192, 9472, 9728, 7936, 6144, 6400, 11008, 13824, 12544, 11776, 11264, 10240, 10496, 7680, 2304, -256, 1536, 5632, 7936, 5632, 2304, 0, -3584, -5888, -7424, -7424, -7168, -8960, -9984, -9984, -9984, -8448, -6400, -7680, -11264, -12544, -11520, -11520, -8960, -4864, 512, 4096, 4096, 2304, 0, 0, 1536, 512, -256, 2816, 6912, 10240, 8192, 4096, -512, -512, 256, 768, 256, 1792, 3072, 1536, 2048, 2816, 1280, -256, -512, -256, 256, 2048, 2560, 1280, 1024, 3584, 4352, 1536, -256, 0, 1024, 1024, 4352, 5888, 4864, 6400, 5120, 1280, -2048, -2304, -512, -256, -1536, -768, 3328, 4096, 256, -3328, -4864, -5376, -6656, -8704, -9472, -5888, -3328, -3328, -6144, -10240, -10752, -10240, -9984, -7424, -5632, -5376, -4608, -3072, -512, 4608, 6144, 2560, 0, -1536, -1024, 3840, 8448, 8704, 8704, 11264, 10496, 7936, 8448, 11264, 11008, 7936, 5632, 5120, 4352, 4096, 5888, 5632, 4864, 5376, 2560, -1280, -1536, -2304, -2048, -512, -1280, -4096, -7168, -9216, -12032, -13568, -9984, -5888, -5376, -6144, -8192, -11008, -9984, -8704, -6144, -4608, -3584, -2816, -3072, -1536, 2560, 7424, 10496, 10240, 6912, 3584, 2560, 1024, 256, 768, 512, 2304, 4864, 5376, 2304, -2560, -4096, -2560, 2048, 4608, 5120, 3328, -768, -2048, -1024, -256, 512, 1280, 1280, -256, 768, 2304, 3072, 4096, 4096, 3584, 2304, 768, 1280, 2560, 1024, -1536, 256, 1536, 1280, 3328, 5120, 2816, 256, -1792, -5376, -7680, -6400, -3072, -2304, -3328, -4864, -6144, -7424, -8704, -7680, -8192, -9984, -8448, -6144, -5120, -5632, -6144, -3328, 768, 1536, 512, 256, 768, 1280, 4096, 7680, 8960, 8960, 6144, 4096, 3840, 4864, 7936, 9472, 8448, 7168, 7424, 7424, 7680, 6656, 5120, 3840, 3328, 2560, 2560, 3072, 2304, 1792, -768, -5376, -9984, -11264, -11008, -10752, -8704, -6656, -5888, -4608, -3072, -4608, -8192, -9216, -7936, -6912, -5120, -2560, -1792, -2304, -2816, -1280, 512, 3072, 4864, 4864, 6400, 6144, 2816, 768, 3840, 7424, 7680, 5120, 2304, 256, -256, 256, 1280, 512, -768, -512, 0, -1536, -4608, -6912, -5120, -768, 2048, 3328, 3840, 2816, 1792, 2560, 4608, 4096, 2560, 1536, 768, -256, 256, 2816, 4864, 4864, 3840, 3584, 1280, -512, -512, -1792, -3072, -3840, -5120, -4096, -2560, -1280, 512, 256, -3328, -7424, -8448, -6144, -2560, -1536, -3328, -4608, -5888, -7936, -8192, -6656, -5632, -4608, -3328, -768, 512, 768, 1792, 2048, 2560, 4864, 6912, 8192, 8448, 8448, 8960, 9728, 11008, 10496, 7424, 2304, -1024, -2304, 512, 4096, 4352, 3328, 3840, 4352, 3328, 2560, 1280, -256, -2048, -4608, -7424, -8192, -6912, -5376, -5632, -7680, -7936, -7936, -8448, -7936, -6912, -4608, -1792, -1536, -3840, -4096, -2048, -256, 1024, 3072, 4608, 5632, 5120, 4096, 2816, 2560, 3584, 4608, 4096, 3840, 3584, 2304, 1536, 1024, 768, 768, 0, -1280, -3328, -4608, -3840, -3328, -2304, -1792, -2048, -1280, -512, -1280, -256, 1280, 2048, 2560, 2816, 3072, 4352, 4864, 4096, 2560, 1024, 1024, 2048, 2048, 2048, 3328, 3584, 2304, 768, 0, -256, 0, 0, -1792, -4864, -6144, -5120, -3840, -3072, -3840, -5376, -5888, -6144, -6656, -7168, -7424, -7168, -5376, -2560, -256, 1280, 1536, -768, -3072, -3584, -2816, -256, 3072, 4096, 4352, 7168, 9216, 7168, 5120, 6400, 6912, 6144, 6400, 7168, 5376, 3840, 2816, 768, 1024, 3072, 2816, 0, -1792, -1280, -256, -256, -1280, -2048, -2816, -4352, -5888, -5632, -4864, -5376, -5120, -5120, -5632, -6144, -5632, -4352, -5120, -6144, -5120, -2560, 512, 2560, 3328, 3584, 3584, 2816, 2048, 2048, 3072, 4352, 4608, 5120, 5120, 3584, 1024, -256, -512, -256, 768, 2816, 3072, 1536, 0, -2304, -5120, -6400, -4608, -2304, -2048, -3328, -4608, -4864, -3584, -1536, 0, 1024, 2816, 4864, 5632, 5120, 4864, 3840, 3328, 3584, 4608, 4352, 3072, 1792, 2304, 3584, 2304, -256, -1024, -256, -1280, -2560, -3072, -4096, -5888, -4864, -1792, -1280, -2560, -2560, -2816, -4864, -6912, -6144, -3584, -1536, -768, -2560, -5376, -6144, -3840, -1536, 0, 2304, 3840, 3072, 2048, 1536, 2304, 2304, 2816, 5120, 6656, 7936, 8960, 7680, 5376, 4096, 4096, 3328, 1536, 512, 1024, 1280, 768, -512, -2560, -3328, -2816, -2048, -2304, -3328, -4096, -4608, -4608, -4864, -5632, -4608, -2048, -768, -256, 0, -1280, -2816, -2560, -2304, -2816, -2304, -512, 512, 1024, 2560, 3840, 4608, 4864, 5376, 5376, 5632, 5632, 3840, 1024, -1024, -2048, -1792, -1536, -2560, -3584, -4608, -5888, -5120, -3840, -2048, -256, 0, -1024, -1792, -2304, -2304, -1536, -512, 512, 1536, 1792, 1024, 256, 0, 1792, 3328, 2816, 3584, 5632, 5632, 3840, 2048, 512, 1024, 2560, 4096, 4352, 3328, 2560, 2304, 1536, -768, -3328, -5888, -6656, -5376, -4352, -3584, -3072, -3328, -4096, -3584, -2304, -2048, -2048, -2816, -4608, -4608, -3072, -1024, 0, 512, 1536, 1536, -256, -1536, 0, 2048, 2816, 3328, 2816, 1536, 1536, 2304, 3328, 4096, 4096, 3840, 2560, 1792, 2560, 2560, 1024, 0, -512, -768, -256, 512, 512, -256, -1280, -3328, -5376, -6912, -7680, -6656, -4096, -1024, 1280, 2048, 1536, 512, -768, -1280, -256, 1024, 2048, 2304, 2816, 2816, 1536, 0, 0, 1792, 3072, 3328, 2816, 1792, 256, -1024, -768, 0, 1280, 1536, 1280, -512, -2560, -3328, -3328, -2560, -1280, -1024, -2304, -4608, -7168, -7936, -6144, -3584, -2560, -1024, 512, 1280, 1024, 512, 1024, 3328, 5120, 5376, 4864, 3584, 2816, 2816, 3072, 3328, 3584, 3840, 4352, 4608, 4608, 3584, 1280, -768, -1280, -2048, -2816, -2816, -3072, -3840, -3840, -3328, -3328, -3840, -3328, -3072, -3840, -4096, -2816, -1792, -1536, -1024, -256, 1024, 1536, -256, -2560, -2816, -1792, -1024, -256, 1024, 2304, 2816, 3072, 2304, 1792, 2048, 2048, 1792, 2304, 3328, 3840, 3072, 1024, 256, 256, -512, -2304, -2560, -1792, -256, 768, 768, -256, -2304, -3072, -2304, -1280, 256, 768, -512, -2560, -2560, -1792, -1024, 512, 2048, 1536, 1024, 1536, 1280, -256, -256, 1792, 4352, 5120, 4352, 4096, 4864, 4096, 1792, -768, -2048, -2304, -2304, -2816, -3840, -6144, -6912, -5120, -3840, -3072, -2816, -1792, -768, -1024, -1536, -1792, -1536, -2048, -3584, -4608, -4608, -3840, -2560, -1280, 768, 3072, 4608, 5120, 4352, 2816, 2560, 4096, 5376, 5632, 5888, 5888, 5632, 4352, 2304, 0, -768, 512, 2560, 3840, 4096, 2816, 512, -2304, -4864, -5888, -5632, -3840, -2560, -2048, -2816, -3328, -3840, -4352, -4864, -4608, -3840, -2560, -768, 256, -512, -1536, -768, 0, -768, -768, 0, 1536, 2560, 2304, 1792, 1024, -256, -1024, 0, 2560, 4352, 4096, 2816, 1280, 0, -256, 512, 1280, 256, -1536, -2560, -2560, -2048, -1536, -1024, -512, -1024, -1792, -2304, -2304, -1536, 512, 3072, 4352, 4096, 2816, 2048, 1792, 1536, 1280, 1792, 2304, 3072, 3584, 3584, 2304, 768, -256, -768, -1280, -1024, 0, 1024, -256, -2560, -4608, -6144, -7424, -7168, -5120, -3584, -3328, -3072, -2048, -1280, -1280, -2304, -3328, -3584, -2816, -2560, -2304, -1024, 256, 768, 512, 768, 2048, 4096, 5120, 4608, 3328, 2560, 3584, 6144, 7424, 7424, 6912, 5888, 4352, 3584, 4096, 4352, 3840, 2304, -256, -1792, -2560, -3584, -4608, -4096, -2816, -2048, -1792, -2048, -3072, -4608, -6656, -7424, -6656, -4864, -2816, -1280, -768, -768, -512, 0, 512, 0, -768, -768, -512, -768, -1024, -512, -256, 768, 1792, 2304, 2048, 1792, 768, 256, 1024, 1280, 512, 768, 1280, 1280, 0, -1792, -2304, -1536, -256, 1280, 2304, 2048, 768, -512, -1536, -1280, 768, 2304, 3072, 2816, 2048, 1024, 768, 1024, 1536, 2816, 3328, 2048, 256, 0, 1024, 2304, 3328, 3072, 1280, 512, 768, 768, 0, -1536, -4096, -6656, -7680, -7168, -6656, -5632, -4608, -4352, -4864, -5632, -6144, -4864, -3072, -1792, -512, 256, 0, -512, -1024, -1280, -512, 1024, 2560, 3584, 3840, 3840, 4096, 4096, 4352, 4864, 5632, 6656, 6400, 4864, 3328, 2560, 1792, 2304, 2816, 2560, 1792, 1024, 256, -1280, -2048, -2048, -1024, 0, 256, -1024, -2816, -4096, -4352, -4096, -3584, -3072, -2560, -2816, -3584, -3840, -4096, -3328, -2304, -768, 256, 512, 256, 0, 0, -768, -2304, -3328, -2560, -2048, -1792, -1024, 0, 768, 1536, 2304, 2304, 1280, 768, 768, 1280, 2048, 3072, 3072, 1536, -256, -512, 512, 2048, 2048, 1024, -512, -1280, -256, 1024, 2560, 3328, 3584, 3328, 3328, 3584, 3584, 3072, 2560, 2048, 2048, 2048, 1536, 1536, 2304, 1536, -256, -2304, -3840, -4864, -5632, -6144, -5888, -6400, -6400, -5888, -5120, -4864, -4864, -5376, -5120, -5120, -5376, -4864, -2816, -512, 512, 256, 0, 768, 2304, 3328, 3840, 4096, 3584, 2560, 1280, 768, 2048, 3584, 4096, 4608, 5120, 5632, 6144, 5376, 3840, 2304, 1536, 2048, 3584, 4608, 3840, 2304, 1024, 256, 0, -512, -1024, -1024, -768, -768, -1024, -1792, -2816, -3328, -3072, -2816, -3840, -4864, -5632, -6400, -6400, -5376, -3584, -2816, -3840, -4864, -4608, -3584, -1792, -256, 1024, 512, -768, -1536, -1024, 0, 1280, 2560, 4096, 4352, 3072, 1792, 512, -256, -768, 0, 768, 1536, 2560, 3584, 3072, 1536, 512, 1280, 2560, 3840, 4608, 4608, 4096, 3584, 2816, 1536, 1024, 768, 256, 256, 512, 1536, 2304, 2304, 768, -512, -768, -1024, -1536, -2048, -2560, -3840, -4864, -5120, -4864, -4608, -4352, -3840, -4096, -4352, -4608, -5120, -5632, -5376, -4096, -2816, -1024, 256, 0, -1024, -1024, -256, 256, 512, 1024, 1024, 768, 768, 1024, 1792, 2816, 4096, 5376, 5120, 3840, 2816, 2304, 3072, 4096, 5376, 6144, 5888, 5376, 4352, 3328, 2816, 2304, 1024, 0, 0, 256, 768, 1024, 0, -1024, -1792, -1792, -2304, -3328, -4352, -5120, -5632, -5888, -5376, -4096, -3072, -3072, -3840, -4352, -4352, -3840, -3072, -2560, -2560, -2816, -3072, -3840, -3840, -2560, -1024, 0, -256, -256, 256, 1024, 1792, 3328, 4864, 5632, 5888, 5376, 4864, 4608, 4352, 2816, 1280, 512, 1280, 2560, 3328, 3840, 3840, 3584, 3328, 2560, 1280, 256, 0, 512, 1280, 2048, 2560, 2304, 1536, 1024, 512, -256, -1280, -1792, -2048, -1792, -2048, -2816, -3328, -3584, -4096, -4864, -5376, -5632, -5632, -6144, -5888, -5120, -4352, -4096, -4096, -3840, -4096, -4096, -3840, -3328, -2816, -2304, -1280, 0, 1536, 3072, 3840, 4608, 4608, 4352, 4352, 4864, 5120, 4864, 4864, 5120, 5888, 6400, 6400, 5888, 5120, 4352, 3328, 2816, 2304, 2304, 2048, 1536, 768, 256, -512, -1280, -1280, -512, -256, -768, -1792, -1536, -768, 0, -512, -2304, -5376, -7424, -8192, -8192, -7680, -6912, -6912, -7424, -7680, -7168, -6144, -5888, -5376, -4096, -1792, 0, 256, 512, 512, 1024, 1792, 2560, 3584, 4096, 3584, 3072, 3328, 3840, 4608, 5120, 5632, 5888, 5120, 3840, 2048, 768, 512, 1792, 3328, 3840, 3328, 1792, 512, 0, 0, -256, -512, -256, 256, 512, 256, 0, 512, 768, 1024, 1024, 1536, 1792, 1280, 0, -2560, -5376, -7680, -9216, -9216, -8448, -7168, -5888, -4608, -3840, -3584, -4352, -4864, -4864, -4352, -3072, -1280, -512, -512, -768, -256, 512, 1536, 2560, 3072, 3584, 3328, 3072, 3328, 4608, 6400, 7424, 7168, 6144, 4864, 3584, 2560, 1536, 1536, 2304, 3072, 3328, 3840, 4352, 4608, 4608, 3584, 1792, 0, -256, 256, 256, -512, -1536, -2048, -2560, -2816, -3328, -4352, -4864, -4608, -4352, -4096, -3584, -3584, -3840, -4352, -4864, -5632, -6656, -6656, -6144, -5120, -4352, -3584, -3328, -3072, -2560, -1792, -1024, 256, 1280, 1792, 2304, 2560, 3328, 3840, 4352, 4608, 5376, 6144, 5632, 5376, 4864, 4352, 3840, 3328, 3584, 3584, 4096, 4352, 4608, 4096, 3072, 2560, 2048, 1536, 1280, 768, 0, -768, -1536, -1792, -1280, -1024, -1024, -1280, -1280, -1024, -1024, -1024, -2048, -3328, -4864, -6144, -6912, -7168, -6912, -6400, -6400, -6912, -6912, -6400, -4864, -3584, -2048, -768, 256, 1536, 2304, 2048, 768, -768, -1536, -1024, -256, 1024, 2304, 3584, 4608, 5120, 5632, 5632, 5888, 5888, 5632, 5376, 5120, 5120, 5376, 5376, 4864, 3840, 2304, 768, -512, -1024, -768, 0, 512, 512, 512, 768, 768, 256, -1024, -2560, -3840, -4864, -4864, -4096, -2816, -1792, -1792, -2304, -3328, -4352, -5888, -7168, -7680, -7424, -6144, -5120, -4608, -4864, -5120, -4864, -4608, -4864, -4608, -3328, -1280, 256, 1536, 2304, 2816, 3328, 4096, 5376, 6656, 7424, 7680, 7424, 7424, 7168, 6656, 5888, 5120, 5120, 5376, 5376, 5120, 4608, 3840, 2304, 512, -1024, -1536, -1280, -768, -768, -1024, -1536, -1792, -2304, -2560, -2560, -2560, -2560, -2816, -3328, -3072, -2816, -2048, -1536, -1536, -2560, -4352, -6656, -8192, -8960, -8960, -8704, -8192, -6912, -4864, -2304, -768, -256, -512, -1280, -1792, -1536, -256, 1792, 3584, 4608, 5376, 5888, 6400, 6656, 6656, 5888, 5120, 5120, 5888, 6144, 6144, 5376, 4864, 3584, 2048, 512, -256, 0, 256, 512, 768, 1536, 2048, 2048, 1280, 512, -512, -1280, -1280, -1024, -256, 256, 256, -256, -1536, -2304, -2816, -3328, -4352, -5120, -6144, -6656, -6912, -6656, -5888, -5376, -5120, -5888, -6656, -6912, -6656, -6144, -5120, -3840, -2304, -512, 1024, 2048, 2560, 3328, 4096, 4864, 5376, 5888, 6400, 7168, 8448, 9216, 9728, 9728, 8960, 8192, 7424, 6144, 4096, 2816, 1536, 512, -512, -1536, -1536, -1280, -1024, -1024, -1792, -2816, -3584, -3328, -2560, -2048, -2048, -2048, -2304, -2816, -3072, -3072, -2816, -2816, -3072, -3584, -4352, -4864, -4864, -4608, -4608, -5120, -5632, -5888, -5376, -4608, -3584, -2816, -2048, -1024, -256, 1280, 2816, 3328, 2816, 2048, 1536, 1792, 2304, 2816, 3328, 3840, 4864, 5632, 5888, 6400, 6912, 6912, 5632, 4352, 2816, 1536, 1024, 1280, 2304, 3328, 3840, 3840, 2816, 1536, 0, -1024, -1792, -2048, -1536, -768, -512, -768, -1536, -2304, -3328, -4608, -5632, -5888, -5120, -3840, -2816, -2560, -2816, -3584, -4864, -6144, -6912, -7168, -7168, -6912, -6656, -5888, -4864, -3840, -2560, -1536, -256, 1024, 2048, 2560, 2816, 2816, 3328, 3840, 4352, 5120, 5888, 6144, 6144, 6656, 7168, 7168, 7168, 6912, 6656, 6144, 5632, 5120, 4096, 3328, 2560, 2048, 1536, 768, -768, -2304, -3840, -4352, -4096, -3840, -3328, -3328, -3584, -4352, -4864, -5120, -5120, -4352, -3584, -3072, -3328, -3584, -3328, -3328, -3584, -3840, -3584, -3328, -3072, -3072, -3072, -2560, -2048, -1792, -2048, -2304, -2304, -1792, -1024, 0, 768, 1536, 2048, 2560, 3072, 3584, 4608, 5632, 6400, 6656, 6912, 7168, 7168, 6912, 6144, 5120, 4096, 3328, 2816, 2304, 1536, 768, 0, -768, -768, -512, 256, 768, 1280, 768, 0, -1024, -2048, -3072, -4352, -5376, -5632, -5120, -4352, -3840, -3584, -3584, -3328, -3840, -4864, -5632, -5376, -4608, -3584, -3328, -3840, -4096, -4352, -4352, -4864, -4864, -4096, -2816, -1024, 256, 1536, 2560, 3328, 4352, 5120, 5888, 6144, 6144, 6144, 6400, 7168, 8448, 9472, 9728, 8960, 7680, 6144, 5120, 4096, 3328, 2304, 512, -1024, -2048, -2048, -2048, -1792, -1792, -2304, -3072, -4096, -4608, -4608, -4096, -3840, -4096, -4096, -4096, -3328, -2560, -2560, -2816, -3328, -3840, -3840, -3840, -3840, -4096, -4352, -4096, -3584, -3328, -3328, -3328, -3328, -3072, -2304, -1280, -512, 256, 768, 1536, 3072, 4608, 5632, 5632, 5376, 4608, 4096, 4096, 4864, 5888, 7424, 8192, 7680, 6144, 4608, 3328, 2304, 1536, 768, 0, -512, -1024, -1536, -2048, -2560, -2816, -2560, -1536, -768, -512, -768, -1280, -1280, -1536, -1536, -1792, -1536, -1280, -1024, -1280, -2048, -2560, -2816, -3072, -3584, -4096, -4608, -5120, -5376, -5376, -5632, -5888, -6144, -6144, -5632, -4608, -2816, -1024, 256, 1024, 1280, 1536, 2048, 2816, 3840, 5120, 6144, 6656, 6912, 7168, 7936, 8192, 7936, 7680, 7168, 6912, 6144, 5120, 4352, 3584, 3072, 2304, 768, -768, -2304, -3072, -3840, -4096, -4352, -3840, -3328, -2560, -2560, -2816, -3328, -3584, -3840, -4352, -4864, -5376, -5888, -6144, -5632, -4608, -3328, -2304, -2048, -2048, -2048, -2304, -2304, -2304, -1792, -1024, 0, 512, 768, 1280, 1280, 768, 768, 1024, 1280, 1536, 1792, 2560, 3584, 4352, 5120, 5120, 5120, 5376, 5632, 5120, 4608, 4096, 3840, 3584, 3072, 2304, 1792, 1536, 1024, 512, -512, -1280, -1792, -2304, -2304, -2048, -1280, -512, 0, 0, -256, -768, -1792, -3072, -4096, -4096, -3840, -3328, -3072, -3328, -3328, -3072, -2816, -2816, -3072, -3840, -4864, -5888, -6144, -5632, -4864, -4096, -3328, -2560, -1280, -256, 768, 1536, 1792, 2048, 2048, 2560, 3328, 4352, 5376, 6400, 6912, 7168, 7168, 6656, 6144, 6144, 6400, 6912, 7168, 7424, 7168, 6400, 4864, 3072, 1024, -768, -2560, -3840, -4864, -5632, -6144, -6400, -6656, -6400, -5888, -5376, -5120, -4608, -4352, -4096, -3584, -3072, -2816, -3072, -3584, -3584, -3328, -3328, -3840, -4096, -4096, -4096, -3840, -2816, -1024, 0, -512, 0, 0, 768, 3584, 8704, 6144, -768, -3584, -3072, 1536, 1536, -2816, -5888, -1280, 3840, 5120, 3840, -4864, -3072, 768, 4864, 2816, -1280, 256, 1024, 1792, -3328, -768, 1280, -3328, 0, -512, 2048, 0, -1536, 4096, 5888, 3328, 1536, 512, 3584, 6400, 512, 2816, 768, -1792, -2048, -6144, -1536, -1024, -4608, 1536, 7680, 3584, 2304, 0, 0, 3328, -1792, 0, -768, 2304, 2048, -1536, -3584, -3840, -5888, -4864, -1792, 0, -768, 256, -2048, -2560, -2560, -4352, -3072, -1792, -2560, 256, -3072, -3328, 0, -3840, -5120, -6400, -4096, -1536, -1792, -1536, -1536, -512, -1024, -3328, -3072, -1536, -1536, -1280, 512, 2048, -1280, -3328, -768, -1024, -2816, -4096, -768, 3072, -512, -2048, -1024, -1024, 1024, -3840, -4352, -1536, -512, 1280, -1024, 768, -512, -2560, -1024, -1280, -1792, -2048, 1024, 4352, 256, -768, -3584, -1024, -512, -1792, -1024, -1536, 2560, 1280, -1536, -1792, -2048, 2560, -1280, -768, 768, -2048, 2816, 1792, -1280, -768, -3328, -1792, 0, -1536, 1024, 0, -1792, 3072, -2304, -4352, -1792, 1280, 512, -768, -1024, -1792, 1792, -512, -3328, -1280, -512, 1280, 1024, 0, 1792, -768, 1024, 256, -512, -1024, 1536, 2048, 2048, 0, -512, 512, 768, 512, 256, -512, 1280, 3072, 1536, 768, 512, -768, 512, 768, 256, 2048, 1536, 1792, 512, -1280, -768, 256, 1280, 512, 0, -768, 512, 1792, 512, 0, -2304, 0, 1280, 256, 768, 256, 1024, 1536, -1280, -768, -512, 512, 1536, 1024, 1536, 256, 512, 1024, 1024, -512, 512, 1280, 1280, 1792, 1792, 512, 1536, 0, 768, 0, -768, 2048, 1024, 1024, 2304, -768, 512, 256, 256, 512, 256, 1280, 1280, 1024, 1536, 256, -1536, -512, 768, 1280, 1536, 1024, 768, 1024, 256, 512, -1024, 0, 1536, 512, 512, 1024, 768, 1280, -768, -512, -1280, -768, 1280, 512, 256, 768, 256, -512, -768, -1024, -1536, 768, 1280, 256, -512, 256, 512, -512, -512, -512, -768, 768, 1280, 768, 1024, 512, 512, 256, 0, 256, 1024, 2304, 2304, 1280, 512, 256, 1536, 1024, 1024, 1280, 1280, 1792, 2048, 1024, 1280, 256, 512, 768, 256, 256, 1024, 512, 768, 0, -1024, -1792, -1280, 0, -768, -768, -768, -1280, 0, -2048, -1792, -2048, -1280, -768, -1536, -768, -1024, -1280, 0, -1792, -1024, -1280, -768, 256, 256, -512, 256, -512, 512, 0, 0, -512, 768, 1280, 1024, 1280, 1024, 512, 1024, 512, 1024, 1280, 1536, 1280, 1536, 1024, 1024, 1024, 1024, 768, 1024, 512, 1024, 1024, 512, -512, -512, 0, -768, -768, -768, -1024, -512, -1792, -1536, -1792, -2304, -1792, -2560, -2304, -2560, -2560, -2048, -2816, -2304, -2304, -3072, -2560, -3328, -3072, -1792, -2048, -1536, -1536, -2304, -1536, -1280, -768, 0, 0, 256, 256, 1024, 768, 1024, 2048, 1536, 2048, 1792, 1536, 2560, 2304, 3072, 3072, 2816, 3072, 2048, 3328, 2560, 2816, 2560, 2048, 2304, 2048, 1536, 2304, 1024, 1280, 0, -768, -1280, -1280, -1536, -1792, -2304, -3072, -3840, -4352, -5376, -4608, -5632, -5376, -5888, -6400, -6144, -6912, -6912, -6656, -7680, -6912, -6912, -7168, -5120, -5632, -4864, -3584, -3840, -3072, -2560, -2560, -512, 768, 1024, 3072, 3072, 3584, 5120, 4352, 6400, 6912, 7424, 8448, 8960, 8960, 10240, 9728, 10496, 9984, 9216, 9728, 9216, 9216, 9728, 7936, 8448, 6400, 5376, 3584, 2048, 256, 512, 0, -768, -1280, -3840, -5888, -7168, -10240, -9984, -11008, -11776, -11008, -13312, -13568, -15104, -16896, -15872, -17664, -16128, -16384, -16384, -12800, -14336, -11264, -11520, -11008, -9728, -9216, -7936, -5120, -2048, 1024, 3072, 4864, 4608, 7168, 7936, 10240, 13312, 14592, 17408, 18688, 18688, 19712, 18688, 20736, 20224, 20992, 20992, 19712, 20992, 19712, 19200, 17664, 15104, 13568, 10752, 8448, 6144, 5632, 4352, 2816, 256, -4352, -6400, -9216, -10752, -11776, -14080, -15360, -16384, -18688, -19712, -22528, -23040, -23552, -24832, -25088, -25600, -25600, -23552, -21760, -20224, -20480, -19456, -20224, -17664, -14336, -12800, -8192, -6144, -3840, 0, -512, 2816, 3840, 7424, 11520, 14080, 17152, 18432, 20992, 22528, 24320, 25856, 26112, 27904, 27904, 28672, 27904, 28160, 28160, 27136, 26624, 23296, 20736, 19712, 17408, 16896, 13824, 10752, 8192, 3584, 1536, -1536, -3072, -5120, -7424, -11008, -14080, -16640, -19456, -19456, -21760, -22784, -24832, -26880, -27392, -29184, -29440, -29952, -29952, -28928, -28672, -26624, -25856, -23296, -21760, -21504, -17920, -18432, -14080, -10752, -8704, -3584, -2048, 1280, 4096, 5632, 8960, 11264, 14592, 17664, 19968, 22784, 24064, 25856, 26624, 27904, 27904, 30464, 30208, 29952, 30720, 28160, 29184, 29184, 25344, 26112, 21504, 18944, 18432, 14592, 13312, 11008, 8192, 5632, 2560, -1792, -5120, -7168, -8704, -12032, -13824, -15360, -17152, -18176, -20480, -22272, -23040, -26880, -26880, -28160, -30720, -29440, -30720, -31488, -28928, -28416, -27904, -24832, -25088, -23552, -21248, -20992, -19456, -16128, -15616, -12288, -9984, -7680, -4096, -768, 2560, 5632, 8192, 10752, 12544, 15616, 17152, 19456, 21504, 23296, 25856, 26880, 29440, 29696, 29952, 32000, 29440, 30464, 29696, 27136, 28416, 26112, 24832, 23552, 21504, 20224, 17920, 16384, 12800, 11520, 7936, 4864, 3584, -512, -2304, -4864, -7680, -8960, -12032, -13824, -15872, -17152, -18688, -20992, -22016, -24576, -25600, -26880, -27904, -29696, -30208, -30720, -30720, -29952, -28416, -28160, -24832, -24576, -23040, -21504, -19968, -18688, -16384, -14080, -12800, -9984, -6400, -5120, 256, 2816, 4864, 9472, 10240, 13056, 15616, 17408, 19456, 21760, 24064, 24832, 26880, 29184, 28672, 30720, 31232, 30464, 30976, 29952, 28160, 27136, 26880, 23552, 23040, 21504, 17664, 18176, 14592, 12288, 11520, 7424, 5632, 3584, -512, -2304, -5632, -7936, -10240, -12032, -15104, -15872, -17408, -19456, -20480, -22272, -24832, -24576, -28416, -28416, -29696, -31744, -30464, -31488, -30720, -27904, -27904, -25088, -24320, -23808, -21504, -20736, -19200, -16896, -14080, -13056, -9472, -7168, -4096, 256, 3072, 5888, 9984, 10240, 14080, 15104, 17408, 19712, 22016, 24064, 26368, 26624, 29696, 29952, 30208, 32000, 31232, 29952, 30720, 27392, 27648, 26624, 24320, 23552, 21760, 18432, 17920, 15360, 12288, 11008, 7424, 4608, 2560, -1792, -3072, -5632, -7680, -9728, -12544, -14848, -16128, -18432, -19200, -21504, -23040, -23808, -25600, -28160, -26368, -30976, -29440, -29440, -31744, -28160, -28672, -28416, -23552, -25088, -22016, -20736, -19712, -17664, -15616, -13568, -12288, -8704, -6912, -3328, 256, 2304, 7168, 9472, 11520, 14848, 15104, 19456, 19968, 21760, 24832, 25088, 27904, 29184, 28416, 31488, 30720, 30464, 30976, 29696, 28416, 28160, 25856, 23808, 23552, 20224, 18688, 17408, 14080, 13312, 10240, 7680, 5376, 2560, 0, -3328, -5888, -7424, -10496, -12032, -14848, -16384, -17664, -19200, -21504, -22784, -23808, -26368, -26880, -28160, -30720, -29440, -29952, -32768, -26880, -29184, -27904, -22528, -26112, -22016, -19456, -21504, -16384, -16128, -14336, -11008, -9472, -6400, -2560, 1024, 2816, 7936, 9216, 11776, 14336, 14848, 18944, 19968, 21504, 25600, 24320, 28160, 29184, 28160, 31744, 30720, 29696, 30976, 28160, 26880, 27648, 24832, 24576, 23296, 20224, 19200, 16896, 14592, 13056, 9728, 7424, 4352, 1280, -768, -3328, -5120, -7168, -10240, -11776, -14080, -16896, -17408, -19456, -21760, -22528, -24832, -26112, -27136, -28160, -29952, -29440, -30720, -31232, -27648, -29952, -26368, -25088, -24576, -22016, -20224, -19712, -16896, -15104, -13824, -11776, -8448, -7936, -2560, -512, 2816, 6912, 9216, 12032, 14848, 15872, 18944, 19968, 22016, 24064, 24576, 27136, 27904, 29440, 30720, 30208, 30976, 30464, 28672, 29184, 26624, 25088, 24064, 21760, 19712, 18432, 16128, 14336, 12544, 9472, 7936, 5120, 1536, -512, -3840, -6144, -8448, -11264, -12800, -14848, -16128, -17408, -19456, -20992, -22784, -24320, -26880, -26880, -29696, -30208, -29952, -32256, -29184, -28416, -30208, -23552, -26880, -23552, -21248, -22528, -18432, -18176, -16640, -13056, -12800, -7936, -6400, -2304, 512, 4096, 7424, 8960, 12800, 13568, 17152, 18688, 19200, 23552, 22528, 26624, 28672, 27648, 31232, 29952, 30464, 31488, 29184, 29696, 28160, 26624, 25088, 24064, 22016, 20480, 19200, 16128, 15104, 12032, 9216, 7424, 3328, 2304, -1280, -4096, -5376, -9216, -10240, -12800, -15616, -15616, -18688, -19712, -21760, -23808, -24320, -26368, -27648, -29952, -30720, -30208, -32000, -29952, -27648, -29696, -24576, -25088, -24832, -21248, -20992, -19968, -16896, -15616, -13824, -11008, -8192, -6400, -512, 768, 4096, 8448, 9216, 13312, 14336, 16896, 19200, 19968, 24064, 23296, 26368, 28928, 27648, 31232, 30464, 30464, 30976, 29696, 28672, 28160, 27136, 23808, 24576, 21248, 19456, 18944, 15104, 14848, 12032, 8704, 7168, 3584, 1536, -1536, -4352, -6912, -9216, -11264, -13824, -15616, -16128, -17920, -19456, -22016, -23040, -25344, -26112, -27648, -29952, -29440, -30976, -31488, -28416, -30720, -26112, -25600, -25856, -21504, -23296, -19456, -18944, -17920, -13824, -14336, -10496, -7680, -5120, -768, 2048, 5888, 7936, 11776, 12032, 15104, 17920, 18176, 21248, 22784, 23040, 27648, 27648, 29440, 30720, 30976, 31232, 30208, 30208, 27904, 28160, 26112, 23808, 23808, 20992, 19968, 18432, 15872, 14592, 11520, 9472, 5632, 3840, 1024, -2560, -4608, -7680, -9216, -10752, -13824, -14592, -16128, -17408, -19712, -22016, -23296, -26112, -26368, -27648, -29952, -29184, -30464, -29952, -29440, -28160, -27136, -25600, -23296, -25344, -20224, -20736, -19712, -15104, -15616, -12800, -9216, -8448, -4096, -1024, 2560, 4096, 8960, 9984, 12288, 15872, 16384, 19456, 21760, 22784, 25088, 26880, 28160, 28928, 30720, 30464, 30208, 31488, 28672, 28416, 28160, 25600, 25088, 23808, 20992, 19968, 17920, 14848, 13824, 11520, 7680, 6144, 3072, 0, -1792, -5120, -7168, -9216, -11520, -14080, -15616, -16896, -18688, -20224, -22528, -23808, -26368, -26880, -28672, -30464, -29440, -31744, -31488, -27904, -30464, -26368, -25088, -26112, -23552, -21504, -21248, -19200, -15872, -15104, -12800, -8704, -8704, -3072, 256, 1792, 6656, 8448, 10752, 12800, 15872, 17152, 19456, 22528, 23040, 25856, 28160, 27648, 30208, 30976, 30464, 31232, 30976, 28416, 28928, 28160, 25088, 25088, 23296, 20480, 19968, 16896, 14848, 13568, 10240, 7424, 5120, 2048, -1024, -2816, -5632, -8448, -9472, -12544, -14592, -15616, -17408, -19712, -20736, -23040, -24576, -25856, -28160, -28672, -29696, -30720, -29696, -30976, -30464, -26624, -28416, -24576, -23296, -24576, -20224, -20224, -19456, -15104, -14592, -11776, -8448, -6400, -3584, 1280, 2816, 6656, 9984, 10752, 14080, 15616, 17920, 20736, 22016, 24064, 25856, 26880, 29184, 29696, 30720, 30976, 30464, 30464, 29440, 28416, 27392, 26112, 24064, 23040, 20992, 18688, 17408, 15104, 12800, 10496, 7168, 5120, 1792, -1024, -3072, -5632, -7680, -10496, -12288, -14336, -15872, -17664, -19200, -21248, -23040, -25088, -25600, -27392, -28416, -30464, -28672, -31744, -30720, -27392, -30464, -25856, -23808, -26624, -20480, -21760, -21248, -15616, -16640, -14080, -10240, -9728, -6400, -1792, -768, 3328, 7424, 8704, 11520, 14592, 15104, 18944, 20224, 22272, 25088, 25088, 27648, 28416, 28672, 31232, 29952, 30464, 30464, 28416, 28160, 27392, 24576, 24576, 22784, 19456, 18944, 16128, 13824, 13056, 8960, 6912, 4864, 1280, -768, -3072, -6400, -7424, -11008, -13312, -14848, -16384, -18176, -19968, -20992, -23552, -25088, -25856, -27648, -28160, -29184, -30720, -30464, -30208, -29440, -28160, -27136, -24320, -24832, -20992, -21504, -19456, -15872, -16128, -13056, -10752, -9984, -5120, -3072, 512, 3840, 7424, 9216, 12032, 14848, 15872, 18944, 20480, 21760, 24320, 25856, 27136, 28416, 29696, 30208, 29952, 31232, 28928, 29440, 28416, 25344, 26368, 23040, 21760, 20480, 17408, 16128, 14336, 11776, 9216, 7168, 4352, 1280, -1280, -4864, -6400, -8960, -11008, -13312, -14848, -15872, -18432, -19200, -21248, -24064, -24064, -26880, -26880, -29440, -29440, -29696, -31232, -29184, -28672, -27648, -25088, -25344, -22784, -22016, -20992, -18432, -17664, -14848, -13312, -11264, -7936, -5376, -1536, 1024, 4352, 7168, 9984, 12288, 13568, 16896, 18432, 20480, 22528, 23552, 26624, 27648, 28928, 29696, 30464, 30976, 29696, 30464, 28672, 27648, 27392, 24064, 24064, 21760, 20224, 18432, 15872, 14592, 12288, 9472, 6400, 4352, 2048, -2048, -3840, -6656, -8960, -10752, -14080, -15104, -16640, -18688, -19200, -22272, -22784, -24832, -26624, -27904, -29696, -29696, -30976, -30720, -30720, -27904, -27648, -26368, -23040, -24832, -19968, -19968, -19712, -15360, -16384, -12800, -10496, -8704, -4096, -1792, 2304, 4864, 8448, 10752, 13312, 15360, 16640, 19712, 20224, 22272, 24576, 25344, 27904, 28928, 30208, 31744, 29952, 30976, 29952, 27904, 28160, 25344, 24064, 23808, 21248, 19712, 18688, 16128, 14080, 12800, 8192, 6656, 4608, 0, -1536, -5120, -7424, -8704, -12544, -13568, -14592, -16128, -18176, -19456, -21248, -23296, -24832, -27648, -28672, -29184, -31232, -29440, -31744, -28672, -26880, -28672, -22784, -25344, -23040, -19968, -22784, -18432, -16896, -15616, -12544, -10496, -7168, -4096, 512, 1536, 6400, 8960, 9216, 13568, 13824, 17152, 19712, 20224, 23808, 24832, 26880, 28672, 28416, 31232, 30208, 30464, 29952, 28672, 27904, 27648, 25344, 24320, 23552, 20992, 19456, 18176, 15104, 14336, 11008, 7680, 6144, 2560, 0, -2304, -4608, -6656, -9216, -11520, -14080, -15104, -17408, -19200, -20736, -22528, -24064, -25344, -27136, -27904, -28160, -30464, -29952, -30464, -29696, -28416, -26880, -25856, -23296, -23552, -21248, -19200, -19200, -15616, -13312, -13312, -8960, -7424, -4608, 0, 2304, 5632, 9216, 10496, 13056, 16384, 17408, 19968, 22528, 23040, 25856, 26368, 27904, 28928, 29440, 30976, 29952, 30208, 29696, 27904, 27904, 26112, 24064, 23040, 20480, 18176, 17152, 14592, 12032, 10752, 7680, 4864, 3584, -1024, -2304, -4864, -7936, -9216, -12800, -14080, -15616, -17408, -18944, -20224, -22272, -23808, -25856, -27392, -27392, -29440, -30208, -30208, -31488, -28672, -28160, -27904, -23552, -23808, -24064, -18944, -21248, -18176, -14592, -15616, -11520, -8704, -7936, -2560, 0, 3072, 6912, 9472, 10752, 14080, 15616, 17920, 19712, 22272, 24320, 24576, 27136, 28672, 28928, 31488, 31232, 29952, 31232, 28672, 27904, 28160, 24576, 24576, 23552, 19456, 18944, 17408, 14080, 12800, 10240, 7168, 5120, 1792, -1536, -2560, -5888, -7936, -10752, -13056, -15104, -16640, -17920, -19456, -20992, -22528, -23552, -26624, -26624, -26880, -31232, -28928, -31232, -32256, -27136, -30464, -26368, -23296, -25344, -20992, -20480, -19456, -16896, -15104, -13824, -11776, -8704, -7680, -2304, 256, 3328, 8448, 8704, 13056, 14592, 16128, 19456, 19712, 23296, 24320, 24320, 28160, 27648, 29440, 31232, 30720, 30720, 31488, 28672, 28160, 28160, 24064, 24320, 22272, 17920, 18944, 15872, 14080, 12800, 9984, 7424, 5120, 1792, -1280, -3328, -6656, -8960, -11264, -14336, -15616, -16640, -17664, -19200, -21248, -22016, -25088, -26624, -26624, -30976, -29440, -30464, -32768, -28160, -29952, -29696, -23552, -25600, -23040, -19968, -21248, -19200, -16128, -16384, -14080, -10496, -9984, -5120, -1792, 256, 5376, 7936, 10240, 13056, 14080, 17152, 18432, 19712, 23296, 23808, 25344, 28160, 27904, 30208, 32000, 30208, 31744, 30464, 27648, 29184, 25856, 23808, 24576, 20736, 19200, 18688, 15104, 14592, 12288, 8960, 6912, 3840, 256, -1792, -5120, -7424, -9472, -12544, -14336, -15616, -16640, -17664, -18944, -21248, -23296, -25088, -27392, -28928, -29952, -30720, -31232, -30208, -29440, -28416, -26368, -25856, -23552, -22784, -21760, -20480, -19712, -16640, -15616, -13056, -10496, -8448, -4096, -1024, 2048, 5376, 8704, 10240, 12544, 14592, 16128, 18688, 20992, 22784, 25088, 26624, 27904, 29952, 30208, 31488, 31232, 30464, 29696, 28160, 27648, 25600, 24832, 23808, 21248, 20480, 17920, 16384, 14080, 11520, 8704, 5632, 3072, -512, -2560, -5120, -7680, -8960, -12288, -14080, -15872, -17152, -18176, -19968, -22016, -23296, -25856, -26624, -28160, -29952, -29952, -30720, -31488, -28416, -28416, -28160, -23040, -25344, -23040, -19456, -21760, -18176, -14848, -16128, -11520, -9472, -8448, -3584, 256, 1024, 6912, 8704, 10496, 13568, 15104, 16896, 20224, 21504, 23552, 25600, 26368, 28160, 29440, 29696, 31488, 30208, 30208, 29952, 27392, 28160, 25856, 24320, 23808, 20224, 19456, 17408, 14592, 13312, 11008, 7680, 5888, 2816, -768, -2048, -5120, -7680, -8704, -12288, -14080, -15360, -17664, -18944, -20736, -22784, -23552, -25856, -26880, -27648, -29184, -29952, -30208, -31232, -28672, -28928, -27648, -24320, -25856, -22272, -20992, -21248, -17408, -15360, -14336, -11520, -9728, -7168, -4352, -512, 1536, 5888, 8448, 10240, 13824, 15360, 17408, 20480, 21760, 24064, 24576, 26368, 27904, 28160, 30464, 30208, 30208, 30976, 28928, 28672, 28160, 25600, 25088, 23040, 19712, 18688, 16896, 14080, 13056, 10496, 7424, 6400, 2048, 256, -2304, -5888, -7168, -10752, -13056, -15104, -16384, -17152, -19200, -20224, -22016, -24064, -25088, -26880, -28416, -29440, -29952, -30976, -31488, -28416, -30720, -26112, -24320, -25600, -20224, -21504, -20736, -15616, -17664, -14080, -11776, -10752, -6912, -3584, -768, 2816, 7680, 8960, 12544, 14592, 15360, 19456, 19456, 22016, 24320, 24320, 27904, 27648, 29696, 31232, 30976, 31488, 30720, 29696, 29184, 27136, 25600, 24064, 22528, 19968, 18688, 16640, 15104, 13312, 9728, 8448, 5120, 2560, -512, -3840, -5632, -8192, -10752, -13056, -14848, -15872, -17152, -19712, -20480, -22016, -24064, -25600, -27136, -28928, -29440, -30464, -31232, -30208, -29952, -27392, -27136, -25088, -22784, -22784, -19968, -19456, -18176, -14592, -14336, -11776, -9216, -6400, -3072, 0, 4096, 6656, 9984, 12544, 13824, 17152, 18432, 20480, 22528, 24064, 25856, 26624, 29440, 28928, 30976, 32000, 29696, 31488, 29696, 28160, 27904, 25088, 23808, 22528, 19968, 17664, 16640, 14336, 12032, 10752, 6912, 5120, 2048, -1536, -3840, -6912, -8448, -11008, -13568, -14848, -16384, -17408, -18944, -22016, -22272, -24576, -27136, -26368, -29952, -29696, -29952, -31488, -29952, -27136, -29184, -24832, -24576, -24576, -20736, -20736, -20480, -15872, -16384, -12544, -11520, -8704, -4864, -2048, 1024, 4352, 7168, 10240, 12032, 13824, 16896, 18688, 20224, 23808, 24320, 26112, 28928, 28160, 29952, 31488, 30464, 30976, 29952, 28928, 28416, 27136, 24576, 24320, 22528, 19968, 18432, 16128, 14080, 12032, 8960, 6656, 3584, 1024, -2304, -4864, -6144, -8960, -11008, -13056, -15616, -16640, -18432, -20224, -22528, -22528, -25344, -27392, -27392, -30720, -29184, -30720, -31232, -28928, -29696, -26112, -27136, -24320, -22784, -24320, -18432, -20480, -17920, -12800, -14848, -9472, -7680, -5120, -1280, 1536, 4608, 7424, 11264, 11520, 14592, 18432, 17408, 22784, 22784, 24832, 27904, 26624, 30720, 28928, 30208, 31744, 28672, 30720, 28672, 27392, 27136, 24576, 23296, 22272, 19968, 16896, 16640, 13312, 10240, 9984, 4352, 4352, 1024, -3328, -3328, -7680, -8960, -11264, -14848, -15104, -16896, -18432, -19968, -21760, -23808, -24832, -27136, -29184, -28160, -30720, -30720, -30208, -30720, -27904, -28160, -25088, -25600, -22784, -20736, -22272, -17408, -17408, -15104, -11264, -11776, -7424, -4608, -1280, 1280, 5632, 8192, 9984, 13824, 14336, 17408, 20224, 20224, 24064, 25088, 26112, 28160, 28672, 29952, 30464, 31744, 29952, 29696, 29696, 26624, 27136, 24832, 22784, 22016, 18944, 17152, 15360, 13568, 10496, 8704, 6144, 3072, 1024, -2304, -4864, -7168, -9728, -12032, -14848, -15360, -17408, -18688, -19712, -22528, -23808, -24576, -28416, -27904, -29440, -31744, -30208, -31232, -30720, -27392, -27904, -26112, -23296, -24320, -20992, -19968, -19968, -15360, -15104, -13056, -9216, -8960, -3584, -768, 1536, 6144, 8704, 10496, 14336, 15104, 17152, 20736, 20992, 23552, 26368, 26112, 28672, 30464, 29184, 31488, 31488, 29696, 30976, 28672, 27136, 27392, 23808, 23296, 21504, 18944, 17664, 15616, 13312, 11008, 8192, 5376, 3328, -512, -2560, -5632, -7936, -9728, -13056, -14336, -15104, -17664, -18176, -19456, -22272, -23040, -25600, -27392, -28160, -30464, -30208, -30720, -31488, -27648, -30208, -25856, -23552, -26112, -19712, -21760, -21248, -16128, -18176, -14848, -11520, -11264, -6912, -3840, -512, 2560, 7680, 8192, 11776, 14592, 14336, 18944, 18688, 21504, 23808, 24320, 27904, 27648, 29952, 29952, 31744, 30464, 30464, 30464, 28672, 27904, 25600, 24576, 23040, 20736, 19200, 16640, 15104, 13056, 10496, 8448, 5632, 3072, 0, -3072, -5888, -7680, -10240, -13056, -14592, -16384, -18176, -18688, -21248, -21504, -24320, -26112, -26112, -29696, -29952, -30208, -32768, -29696, -29184, -29696, -26112, -25344, -24320, -22016, -20480, -20480, -18176, -14848, -15616, -11776, -9728, -7680, -2560, -1024, 3072, 6656, 9472, 12032, 13824, 17152, 17408, 20224, 22784, 22016, 26624, 26624, 28416, 30208, 30208, 31488, 30976, 30464, 29696, 28672, 27904, 25344, 24576, 22528, 20480, 19200, 16896, 14848, 12544, 10496, 7424, 4864, 2560, -1280, -2560, -6400, -8960, -9984, -13568, -14848, -16384, -17664, -19200, -20736, -22272, -25600, -25344, -28672, -29696, -30208, -32256, -31488, -29440, -30720, -28416, -26112, -25600, -23808, -22016, -21760, -19456, -17664, -16384, -14336, -12032, -9728, -6400, -2560, 1024, 4096, 7936, 10240, 11776, 15616, 16640, 17920, 21248, 22016, 23808, 26368, 26880, 29184, 32000, 30208, 31744, 32000, 28672, 30720, 28416, 25088, 26368, 23296, 22016, 21248, 18176, 16896, 15616, 12544, 9728, 8192, 4096, 1792, -1024, -4352, -6656, -9216, -11264, -13824, -15360, -15104, -18176, -19200, -20224, -24064, -24320, -26368, -29952, -28672, -30720, -32512, -30720, -30208, -29952, -26624, -26112, -25344, -22528, -21504, -22016, -18688, -17920, -16384, -13056, -12032, -9472, -4352, -2560, 1792, 4864, 8192, 10240, 13312, 14336, 17152, 18688, 20480, 22272, 23552, 26368, 27904, 28160, 31488, 30464, 30976, 32256, 28416, 28928, 28672, 25088, 25088, 23296, 20480, 20480, 18176, 15360, 15616, 12032, 9216, 7680, 3328, 1280, -1280, -4864, -6912, -8960, -11008, -13312, -14848, -15872, -18176, -19456, -21504, -24576, -25600, -26880, -30208, -29440, -30976, -31488, -30976, -29184, -29952, -28160, -25088, -26880, -23296, -21248, -23040, -18176, -17408, -16384, -12288, -11008, -8448, -4352, -1280, 768, 5888, 8192, 9728, 13824, 15104, 16896, 20224, 20992, 23552, 25600, 26880, 27648, 29696, 30464, 29952, 32256, 29696, 29440, 30208, 27136, 26880, 25344, 23296, 21760, 19968, 17152, 15360, 13824, 10496, 8448, 6144, 2816, 0, 768, 2560, 3584, -2048, 11776, 1792, -5120, -5888, -7168, 4352, 2304, 12032, -1792, -3840, -8960, -256, -6656, 11264, 8704, -7936, 7936, -12032, -8192, 7680, -512, 8192, 3840, -3840, -4352, -9984, 4096, -512, 6656, 5888, 768, -11008, 2816, -9472, 3584, 9472, 1792, 1024, -5376, -7680, -2304, 3584, 4608, 9728, -3328, -4096, -5376, -6144, 2048, 9728, 768, 4096, -7424, -2816, -6656, 5120, 3840, 6144, -2304, 0, -8704, -5376, 8192, -4096, 10496, -256, -5120, -1792, -1792, -1792, 6912, 0, -512, -512, -2816, -2816, 4864, -4096, 8192, -4864, -1024, 2816, -10240, 12544, -3328, -3072, 3072, -8192, 3072, 4352, 256, 5888, -8704, -5120, 3584, -5120, 8448, 11264, -13056, 1792, -5376, -9728, 11776, 4864, 9472, -7168, -7424, -4352, -10240, 16128, 9216, -8448, 10752, -11520, -14592, 4096, 9472, -768, 13824, 0, -16384, -6400, -1792, 3840, 9472, 8704, -512, -16640, -3072, -768, -1792, 19456, -512, -1536, -7168, -5632, -7680, 10240, 2816, 3072, 5376, -11008, -1536, -256, -7936, 18688, -8960, 8448, -256, -17152, 7424, -6144, 4096, 10752, 1024, -6656, 4352, -18176, 8192, 0, 0, 18432, -14336, 1024, -512, -19200, 19456, -6400, 9984, 6144, -10752, -1536, -5120, -7936, 14336, 256, 768, 12544, -16128, -3072, -4096, -2560, 12544, 3072, 7424, -8192, -15104, 8960, -9984, 8960, 11520, -8448, -5376, 11776, -17408, 3328, 4096, 3072, 0, 512, 8192, -17920, 3072, 7680, -15872, 16384, 1280, -7936, 5632, -7680, 2816, -7680, 11008, 512, -2048, 4096, -768, -15360, 9984, -2816, -3328, 16128, -8192, 2048, -1536, -11520, 9984, -9728, 7680, 12544, -22784, 24576, -21504, 0, 11008, -13056, 13312, -1024, -1536, 1792, -7936, -2560, 3072, -5632, 15872, 2048, -14592, 16640, -25856, 256, 17664, -11776, 19456, -4608, -8704, -6144, -8448, 12800, -1536, 14080, 4096, -17920, -4864, 512, -8448, 15104, 15616, -10240, 1792, -11264, -8448, -1792, 15616, 7936, -3840, 1280, -8192, -17920, 12032, 8704, 2048, 5632, -4096, -11264, -12032, 14336, -1536, 3072, 14336, -11776, -8192, -768, 1792, -1024, 10752, 4864, -10496, -8960, 10496, -15104, 11008, 11520, -11264, 2304, -2304, -1792, -4864, 9216, 512, -12800, 12544, -1536, -8704, 8448, -256, -9728, 4352, 11264, -8448, 1280, 7168, -17408, -3328, 15872, -6400, 3840, 11520, -14592, -8192, 5888, -3584, 9472, 2816, 7424, -14336, -12288, 11776, -14080, 12288, 24064, -18944, 5632, -10240, -15104, 9216, 2304, 19200, -4864, -7936, 1536, -26624, 9984, 20480, -5888, 15104, -3072, -26624, 2560, -3072, 6144, 15104, 1280, 2304, -19968, -3072, 6144, -12032, 29696, -1536, -13056, 8704, -18176, -6656, 14080, 768, 2816, 9728, -7936, -2304, -11520, 5376, -2816, 1024, 23552, -20224, 4096, -4096, -10496, 7424, 6912, 4864, -1280, -4864, -3328, -8960, 7424, 5632, -1792, 5120, -8960, 1536, -5376, 7680, -512, 1536, -2048, -5120, -3072, 7680, -3328, 2048, 5888, -13312, 5376, 2048, -4096, 10240, -5120, -1792, -3840, -9728, 15872, -8448, 12288, 1280, -16896, 7168, -6400, 3840, 9984, 1280, -11776, 2048, -11776, 8192, 3072, 9472, -2304, -12544, 11008, -19968, 11008, 11776, -11008, 9984, -10496, -9216, 3328, 4864, 12288, -5376, 2304, -9472, -13824, 11520, 8192, -3584, 10496, -8192, -16896, 10752, -2048, 9472, 3072, -2560, -3072, -18944, 18176, -7680, 4096, 16640, -16384, -256, -3328, -3072, 4352, 6144, 2560, -4096, -7936, -256, -768, 256, 17408, -12032, -1792, -2048, -10496, 18944, -4096, 8192, -6912, -10752, 5632, -12544, 20480, -2816, 0, 5888, -21504, 8704, -6144, 7936, 12288, -9472, 5888, -14080, -6400, 5632, 3584, 5632, 15104, -19968, -2816, -256, -11520, 23040, -8960, 8192, 0, -19200, 16128, -16640, 8704, 13312, -18176, 17920, -14336, -3584, 7680, -5632, 2560, 14080, -18944, 10496, -4864, -12032, 22528, -15872, 12800, -2816, -14592, 11264, -13824, 15104, 4352, -5888, 3072, -10240, -10496, 15360, 768, 3840, 7168, -18176, -256, -4352, 2816, 15616, -7168, 12032, -15104, -12288, 8960, -4608, 13056, 6912, -5120, -8960, -9216, 3584, 1536, 11264, 5888, -7680, -8448, -4352, -256, 3584, 12544, -512, -8192, -3072, -5120, 1280, 7424, 8704, -8448, 2304, -8704, -6656, 9216, -512, 10240, -7168, 1280, -6656, -9984, 16640, -6912, 4864, 7936, -13824, 0, -2048, 3072, 512, 7680, -1280, -6400, -5632, 6144, -7424, 6656, 13312, -14592, 1792, 1280, -14336, 11776, 256, 2048, 1024, -1280, 256, -13056, 7168, 3584, -5376, 12288, -4352, -11776, 1024, 2816, -1536, 8960, 1792, -4096, -7936, -2560, 6400, -12544, 24320, -7168, -7424, 4864, -11776, -1280, 8192, 5376, 2048, -256, -6144, -9216, -4352, 15104, -1792, 8448, 2560, -19456, -3584, 4864, -256, 14336, 4096, -5888, -16384, -2048, 1792, 2048, 21760, 0, -14592, -5376, -8960, -1792, 18432, 5888, 7168, -16896, -4096, -12032, 512, 17408, 6144, 1280, 0, -17664, -6656, 5632, -1792, 18432, 0, -3072, -5120, -13056, 3840, -2816, 11264, 11264, -11776, 9216, -15104, -9728, 8192, 4864, -768, 18176, -11520, -7168, -7424, -4352, 9216, 2048, 20224, -12032, -13568, 4608, -16640, 9728, 19200, -6144, 5120, -9216, -8704, -6656, 9728, 9984, -1792, -768, 1792, -21760, 11264, 6656, -4352, 10752, -5120, -7424, -6656, 6656, 4608, -2048, 9216, -4352, -18688, 10240, 1024, -256, 13312, -4096, -12032, -3840, 3584, 1024, 7424, 7680, -10496, -11264, 3840, -512, 4096, 15360, -6656, -13824, 4352, -8448, 5632, 12288, -1280, -3840, -5120, -3328, -3840, 7936, 9472, -7168, 1536, -4352, -5632, -2560, 16384, -11008, 4096, 5632, -18176, 10496, 768, -256, 1536, -3072, 3072, -9728, 2816, 9728, -12544, 9472, 6144, -16384, 6912, 4608, -18688, 20736, -8448, 3584, -768, -8192, 11008, -15360, 13568, 6144, -19456, 17920, -7424, -8448, 12800, -4608, -8704, 12288, -9728, 9472, -3840, -1280, 6400, -20480, 17920, -1024, -11520, 22784, -18432, -768, 3328, -5888, 7168, 5376, -2304, -2304, -6400, -2816, 6144, -6656, 15872, -3584, -12544, 17152, -24832, 14592, 3072, -5888, 11776, -11776, 2304, -5120, -1024, 6400, -256, 1280, 4608, -7936, -6400, 9728, -11008, 11264, 4352, -10752, 9472, -16896, 9472, -4096, 6656, 4608, -4096, -4352, -1024, -4352, 1792, 9728, -2816, 1024, -768, -13056, 8192, -4352, 9728, 4608, -8704, 5888, -14848, 1024, 6400, 0, 6656, 768, -8960, -2816, -2560, 4096, 6144, 2048, 1024, -8448, -7680, 5632, -512, 3584, 13312, -15616, 2560, -5888, -1024, 5120, 2560, 8192, -11264, -512, 256, -9216, 9472, 8192, -6400, 512, 0, -10240, 3584, 6144, -1280, 3328, -7168, 5120, -13056, 10496, 3840, -5888, 6400, -3072, -10496, 7680, -512, -2816, 10240, -8704, 3584, -6144, 768, 5632, -7936, 11264, -5632, -7936, 14592, -14080, 7168, 0, -2304, 256, 2816, -2560, 2048, -3328, 768, -512, -5888, 15360, -12544, 5888, 2560, -15104, 9216, -768, -768, 8960, -5888, 1280, -10752, 3840, 1792, -512, 8960, 0, -11520, 2048, -1024, -6912, 16128, -1024, -3584, 2304, -9984, 256, 256, 6912, 4864, -6912, 6144, -12544, -1536, 8704, -1280, 2560, 4864, -8192, -5120, 3584, -3072, 4096, 6656, -2304, -4864, -2304, -2048, 2048, 1792, 10240, -7424, -3584, -1024, -6400, 1792, 14336, -3840, 1536, -5120, -9216, 768, 2560, 8448, 5120, -5888, -1280, -10752, -4608, 13824, -4352, 16128, -1280, -15104, 512, -11264, 3072, 14592, 4352, 3840, -8448, -11264, -4096, -4352, 16640, 10240, -2304, 2560, -18432, -13056, 9984, 2560, 16640, 4864, -6400, -12032, -13056, 4352, 5120, 13568, 7680, -8960, -8960, -8704, -4096, 9216, 12288, 3072, -768, -8960, -10752, -2304, 7168, 8704, 3072, 3840, -10752, -9984, 1792, 2048, 6144, 7168, 256, -7936, -9216, 2304, -256, 7168, 7424, -3584, -8704, 3584, -11008, 5888, 8704, -1792, 6144, -11264, 2560, -7168, -1280, 13568, -7424, 7424, -1792, -8448, 512, -256, 1280, 4864, 2560, -4352, 512, -8448, 3584, 256, 2048, 8192, -9216, 4352, -7168, -4608, 9216, -5632, 7424, 512, -6400, 1280, -4352, 3328, 256, 4096, -256, -2560, -3072, 768, -2304, 2560, 4864, -5632, 4096, -768, -5120, 6144, -5632, 3840, -768, -3584, 5632, -7680, 7936, -3584, -2816, 3072, -2816, 2048, 4352, -2304, -1024, -3328, -3328, 1792, 2560, 4864, -1536, -1792, -512, -8192, 6144, 2048, 0, 4352, -5120, -2560, -3840, 3328, 2560, 2816, 1024, -256, -10240, 4864, -1024, -1536, 10752, -7936, -256, -1280, -3072, 4864, 1536, 1792, -1280, -6656, 2560, -3072, 3840, 5120, -2048, -4864, 3072, -10240, 7936, 3840, -768, 4096, -5888, -6912, 1792, -1280, 7936, 1536, 768, -1536, -10496, 3584, -512, 1792, 9728, -2560, -7424, 2816, -11264, 4352, 7424, 1536, 5120, -6656, 256, -11520, 2304, 7936, -4608, 10240, -256, -12032, 2048, -2560, -1024, 7424, 8448, -6400, 256, -7936, -3072, -2304, 8960, 7680, -6400, 7936, -12288, -7168, 5120, 4352, 2304, 7680, -4864, -9984, -3328, 1536, 2048, 9728, 3840, -2560, -10752, 0, -6144, 3840, 12544, -2304, -3072, 1280, -11264, -1280, 10752, 1024, 1536, 2048, -6912, -7424, 1280, 6144, -512, 2560, 7168, -14336, 256, 5888, -7424, 7424, 3840, -4864, -2816, 256, -1024, -2048, 6144, 1536, -3840, 512, 1792, -6912, 3072, 5376, -10240, 9216, -3840, -3072, 5632, -4096, 4352, -4352, 3840, -1536, -4608, 5888, -768, -6656, 9984, -6912, -1280, 6656, -5120, 2048, 1280, -2816, 1792, -5376, 4864, -2816, -2048, 8960, -6400, 512, 4608, -8960, 2304, 4096, -5376, 7424, -4096, 256, -3328, -3328, 7168, -4608, 5888, 3328, -9216, 1536, -256, -5888, 6656, 3072, -3840, 4352, -5120, -512, -1792, 768, 5632, -5632, 6912, -2816, -8704, 9216, -7680, 2816, 4352, 512, -3072, 3328, -5632, -2816, 2816, -1280, 6656, -4352, 6656, -6400, -8192, 11264, -12032, 9984, 6400, -7936, 4096, -8960, -256, -1024, 6656, 4096, 768, -4096, -2560, -5888, -2048, 14080, -6912, 6656, 0, -16128, 10496, -6656, 7168, 5632, -5888, 3584, -10752, 1280, 5120, -3328, 7168, 768, -10752, 5120, -1536, -4352, 13312, -8192, 1536, -512, -9472, 10752, -6912, 7424, 3840, -13056, 10240, -9728, 512, 8448, -4864, 1536, 2816, -11008, 6400, 0, -4864, 14592, -13824, 7936, -2304, -11008, 14848, -13312, 9216, 2816, -11264, 12800, -11264, 2048, 5888, -6144, 3072, 1536, -8704, 6400, -2304, -3840, 12800, -14080, 8960, -1792, -6400, 12544, -12288, 8192, -5888, -4608, 9472, -7680, 7168, 2048, -6912, 1792, -512, -4864, 5632, 2560, -2816, 2560, -6912, 1024, -4096, 4608, 7424, -4864, 5120, -5632, -9216, 4096, -512, 4608, 3584, 768, -6144, -3840, -1280, 3072, 3328, 5120, 1024, -10240, 512, -5888, 2048, 7424, 1792, 2304, -5888, -2560, -3328, 1280, 4864, 2304, -768, -3584, -1792, -4864, 5376, 1536, 1280, 2560, -5120, 0, -3584, 3072, 0, 512, 1280, -3328, 256, -768, 3072, -3072, 5120, -3328, -1792, 1536, -2816, 1280, 0, 1280, -1280, -1024, 2560, -2560, 512, 1536, -1280, -3072, 4608, -3328, -2304, 4864, -4352, 2816, -256, 2048, -1280, -5632, 6656, -6656, 256, 7424, -4352, -1792, 4096, -5632, -2048, 5888, -768, 1024, -768, -512, -3840, -5120, 10752, -5376, 1024, 10240, -14080, 2048, 2048, -5632, 5376, 5120, -4352, 512, -3584, -1792, -512, 2560, 7936, -6400, 2560, -768, -13824, 10240, 1280, -3072, 10752, -4352, -9472, 3328, -3072, 1792, 6144, 2560, -1536, -9216, 3072, -2304, -6400, 18944, -6144, -4864, 9728, -16384, 1280, 6400, 0, 4096, 256, -2304, -6400, -5888, 9216, -2048, 1536, 12800, -14848, -3072, 5632, -13568, 13312, 4608, -3072, 4096, -13056, 3840, -7680, 6400, 11776, -9472, 7936, -6656, -12544, 7680, 2304, -256, 10752, -4864, -7168, -3328, -1280, 4096, 1024, 10752, -4608, -10240, 5120, -7680, 256, 12544, -1024, -3840, 0, -5376, -4864, 5376, 6656, 0, -2304, 2304, -11008, -256, 6656, -1280, 5376, -1792, -1536, -8192, 2304, 3072, -768, 8704, -4352, -3072, -4352, -1024, 2304, 1792, 7168, -4864, -768, -3328, -2816, 1792, 3840, 3840, -4864, 3840, -9728, -1280, 4352, -256, 7424, -5120, 3840, -9984, -2816, 10496, -8448, 11520, -2048, -5376, -2816, -768, 1792, 0, 7168, -1792, -4864, -2048, 1792, -5120, 5888, 6144, -10240, 6144, -4352, -4096, 6656, -2304, 5376, -6912, 3328, -2816, -5632, 7424, -1792, 0, 5632, -5632, -4096, 3584, -3072, 3072, 2816, -1280, -1536, -4352, 3584, -3840, 2304, 7680, -7168, 1280, 256, -6656, 2048, 4608, -1792, 256, 1536, -3072, -3840, 2304, 3328, -3328, 3328, 3328, -10752, 3584, 768, -4096, 5120, 1792, -768, -5632, 6400, -6656, 1024, 4096, -1792, 768, -2048, 4352, -8448, 3584, 2304, -5376, 6400, -768, -2816, -256, 256, -3328, 256, 5888, -5120, 6656, -4608, 0, -4608, 768, 6144, -6400, 9216, -3840, -7424, 5632, -5632, 768, 6144, -1280, -256, 0, -4608, 512, -2816, 5120, 2560, -4352, 7680, -9472, -3840, 7424, -8448, 9984, 2816, -5888, 1792, -8704, 2048, 0, 2816, 9216, -6912, -3072, 2304, -12032, 7424, 7936, -7424, 10240, -9472, -3584, 768, -4352, 11520, -2816, 2048, 3072, -15360, 5120, -512, -512, 10496, -3072, -4608, 768, -9472, 6912, 3072, -1024, 9472, -14336, 4352, -5376, -1280, 11264, -5120, 3584, -512, -10240, 5120, 0, 768, 5632, -3328, -2560, -1536, -4096, 7424, -3072, 3584, 3840, -12544, 6144, -2816, -1792, 9984, -4608, 768, -5120, -3072, 4864, -2560, 8192, 512, -8704, 2560, -3328, -3328, 9472, 256, -1792, 768, -8448, 1024, 512, 4608, 6400, -6400, 2048, -8448, -3328, 8704, -1792, 6144, 1024, -8448, -2560, -512, 512, 6400, 3072, -256, -6400, -3072, 768, -4608, 8704, 3072, -3840, 1024, -2304, -6400, 2560, 4352, -768, 2304, 512, -3328, -5888, 2304, 2048, -3328, 9472, -2560, -3840, 256, -3328, -256, 0, 7936, -3840, 0, 1280, -7424, 1536, 1280, 3840, -2304, 4096, -2304, -7424, 3840, -2560, 768, 3840, 2304, -2816, -3072, 2816, -7424, 4352, 3584, -1792, 1536, -1536, -1792, -6144, 7680, -2816, 2304, 4608, -5120, -2048, -1536, 1536, -2560, 5632, 2560, -7424, 3584, -3328, -2048, 3328, 4352, -3328, 512, 256, -6144, 1280, 1280, 3072, -2560, 3840, -1792, -7168, 5376, -512, -2048, 5632, -2304, -3584, -512, 1536, -1280, 1280, 3072, -1792, -3840, 3584, -1024, -4096, 6912, -2560, -3584, 3328, -1280, -2304, 2560, 1280, -2048, -1280, 4096, -5120, 512, 3328, -3584, -768, 4352, -4608, 512, 2560, -3072, 2304, -1536, -512, -4096, 3328, 2560, -3840, 8448, -6144, -4352, 2560, -1024, 3840, 256, 2304, -5888, -2304, 1536, -1280, 1280, 5376, -2560, -3328, 2816, -5376, -512, 4864, -2560, 5888, -5120, 2560, -4096, -5376, 8448, -4352, 4352, 4608, -7680, 256, -3584, -256, 5120, -512, 4608, -3840, -6144, 1536, -1280, 1536, 9216, -6656, 1536, -4608, -5888, 8704, -3072, 6400, 256, -7680, -256, -2816, 2560, 5632, -256, 1024, -4864, -7168, 5376, -2816, 5632, 6400, -8448, 1024, -5376, -1792, 5632, 1792, 4864, -5888, -3328, -768, -3328, 5376, 4352, -2816, 1792, -4864, -3072, 3072, -2560, 7680, -3328, -1280, 1024, -7680, 6912, -2304, 4352, -768, -6400, 3328, -5888, 3328, 6912, -3840, -1280, 768, -8960, 4352, 4864, -2048, 7424, -9472, 256, -3840, -2560, 12288, -5120, 6656, -1792, -12544, 5632, -5888, 5376, 8448, -2560, -2048, -4352, -8704, 2816, 4864, 3072, 10240, -9984, -3584, -3328, -9216, 16384, -1024, 5120, 2304, -14080, 768, -6144, 5376, 7936, 2560, -256, -5632, -7680, -1792, 3072, 4608, 7424, -2560, -1792, -7168, -5632, 5632, 768, 6656, 1024, -3328, -4608, -4096, 5376, -2304, 7168, -256, -5376, 0, -3072, 1280, 1536, 1280, 2560, -5120, 256, 768, -5120, 5376, 1792, -5888, 6144, -6400, -1536, 5376, -3328, 6400, -4864, -2048, 512, -3584, 5120, 3328, -5888, 6400, -7936, -1792, 6144, -4096, 5120, 1536, -6400, 2048, -6144, 3072, 3840, -2560, 6144, -6400, -512, 0, -3072, 3584, 2560, -3328, 1024, 256, -4352, 2304, 1536, -2304, 2304, 0, -768, -2048, 2816, -2560, -512, 1792, -256, -1536, 1536, 256, -3072, 256, 4608, -7936, 5888, -512, -5376, 5376, -1536, -2048, 3840, -3584, 1024, -1536, -256, 4352, -5632, 5120, -1536, -8960, 9472, -4352, -1536, 12032, -10496, 1536, -1536, -4096, 3072, 4096, 1536, 256, -9216, 4608, -6656, 1024, 15104, -9216, -256, 4096, -16384, 7680, 3584, 256, 4096, -3328, 0, -8960, 4352, 3328, -2048, 3072, 3584, -11520, 2816, 3072, -6144, 6912, 3072, -6912, 2560, -1536, -2304, 256, 3584, -1792, -1536, 2048, -1024, -2048, 2048, 2048, -6144, 3328, 1792, -6912, 7168, -256, -7168, 6912, -4864, -512, 4352, -1280, 1536, -2560, -1280, 1024, -6400, 8192, 512, -5632, 8192, -7168, -5120, 8960, -5120, 4096, 1792, -4608, 256, -5632, 5120, 0, 512, 5120, -3840, -6400, 6144, -6400, 3072, 6400, -5888, 2560, -4864, -1280, 2048, 512, 5120, -1536, -3328, 0, -5632, 3072, 3840, -768, 3328, -3328, -6400, 3072, -1536, 4608, 3328, -768, -3584, -5632, 768, -512, 3584, 6400, -2560, -4096, -1280, -3328, 512, 5632, 2304, -512, -2816, -3072, -5120, 3840, 5120, 256, 3584, -4864, -4352, -2304, 256, 4864, 1280, 0, 1024, -8960, 4352, -1792, 1280, 5120, -4096, 512, -2048, -2816, 2816, -512, 512, 1792, -4864, 3840, -2560, 512, 3072, -3584, -768, 512, -2304, 4352, -768, 512, -1792, -4096, 2560, 512, 2304, 2560, -3584, -2304, -1536, -2816, 5376, 1280, 1024, 1536, -6144, -1280, -1024, 1536, 4608, 0, 2048, -5376, -4608, 2048, -2048, 5376, 4096, -2816, -2304, -3072, -3840, 3840, 768, 6912, -2304, -4096, 1280, -7680, 3328, 5888, -2816, 5376, -4864, -3840, -768, -2304, 7680, -2304, 3584, -1536, -5632, -1280, 3840, -2816, 5888, -256, -3584, -1024, -2304, 2048, 1024, 256, 5120, -8704, 2304, 256, -4352, 6144, -1536, 256, -2304, 256, -1024, 768, 1536, 2048, -4096, 0, 512, -3328, 2816, 5376, -7936, 6144, -5376, -1024, 3328, -512, 1792, -2304, -768, 0, -4608, 7424, -1024, -2304, 4096, -4864, -3328, 6400, -1280, -256, 3840, -6144, 1024, -3840, 5632, 1024, -2816, 5120, -5376, -6400, 9984, -5888, 3584, 3584, -5888, 256, -2048, 768, 3072, -2304, 5888, -4864, -4608, 6144, -5632, 1280, 7680, -8192, 2816, 512, -5376, 4608, -1536, 1280, 256, -2304, 3328, -5632, 1024, 4864, -7168, 6656, 768, -7168, 5376, -1024, -6400, 8192, -3840, 1280, 0, -512, -1024, -2304, 3840, 0, -3328, 5376, -3584, -5120, 7936, -4864, 512, 4352, -3584, -2304, 3072, -1536, 1024, -256, 1024, -4352, -256, 3072, -512, 0, 5120, -7936, -2048, 3072, -2048, 4352, 3584, -3328, -4096, -2304, -1792, 5120, 2816, 4608, -3328, -7168, -768, -3072, 3328, 10240, -3072, 1024, -5120, -8192, 2048, 4352, 3584, 5376, -2560, -7168, -4608, -512, 2816, 5632, 4352, 0, -8704, -1536, -768, -4352, 12800, 256, -3328, 1024, -5632, -5376, 4352, 4096, 1024, 1792, 0, -6912, -2816, 1024, 2560, 512, 6144, -1536, -7168, 1792, -3072, -512, 8448, -768, -1536, 512, -9472, 768, 2304, 1792, 6144, -1024, -3584, -1536, -6144, 6400, -256, 2816, 4096, -9216, -2304, 3072, -6400, 11520, 1280, -5120, 2816, -9216, 2816, 1792, 0, 7680, -8192, -256, 1792, -8448, 9472, 0, -2304, 3840, -5376, -2560, 3072, -3840, 6144, -2048, 768, 1024, -5120, 1792, 768, -3840, 7168, -3584, -1792, 3328, -5888, 512, 2816, 0, 1024, 1792, -2304, -4096, 256, 1792, -1792, 4864, -768, -3072, -3584, 3840, -2560, 1792, 7680, -6656, -3328, 3840, -7680, 3840, 6656, -3072, -256, -2048, -2304, -1280, 3328, 5632, -3072, -3072, 1792, -9216, 4352, 7936, -6144, 6912, -5376, -6144, 3840, -2560, 6656, 1024, -3072, 1024, -9216, 3328, 3584, -1280, 6912, -3584, -5632, 1792, -3072, 1536, 5888, -3328, 1792, -4864, -512, 1792, -2048, 6400, -1280, -4352, 4608, -6400, 768, 3584, -2048, 1024, 0, -256, -2816, 1024, 3072, -4608, 3840, 512, -5888, 3072, -512, -1792, 3072, 256, -256, -3840, 2816, -768, -4352, 10496, -6144, -1792, 3328, -6400, 768, 5632, -2304, 3840, -3072, -2304, 0, -4352, 8192, -1280, -1280, 4864, -12544, 4864, 768, -2816, 11520, -7680, 512, -1024, -7168, 7424, 0, 1792, 3072, -8704, 1536, -2560, 256, 8448, -2304, -1536, 1024, -10496, 6400, 512, 1024, 7424, -10240, 2048, -4352, -2304, 10752, -4096, 4096, -2560, -8448, 2816, -1792, 5632, 3072, -1536, -1536, -6400, -1024, 4608, -768, 6400, -1024, -7424, 1280, -4352, 2048, 5632, 256, 1024, -5632, 256, -3328, 512, 7936, -4864, 2304, 512, -9216, 4352, 1280, -1792, 5120, -2816, -512, -3328, 1024, 2304, -4608, 6144, -768, -7680, 8448, -4864, -2816, 7936, -5376, 1536, 0, -1280, 768, -2560, 4352, -1792, -4864, 7680, -6144, 0, 6656, -5888, 768, 1792, -4352, 2304, -768, 2304, -256, -4352, 5888, -6400, -768, 8704, -6912, 2560, 3840, -8704, 2304, 256, 256, 1792, -256, 3072, -7936, 1024, 4096, -6912, 8192, 2560, -8448, 2560, -256, -6912, 7424, 2304, -2304, 0, -256, -4096, -1536, 6144, 512, -4352, 5888, -5120, -6144, 8448, -2816, -512, 4352, -1792, -5376, 3328, 256, -1792, 2560, 256, -3072, -2304, 3328, -256, -1280, 5120, -4096, -3840, 3840, -2048, 1280, 3328, -2560, -1792, -2304, 1280, 512, 2560, 1792, -1792, -5632, 3072, -3328, 1536, 6656, -3584, -1536, 0, -4352, 768, 4096, 1536, 0, -2816, 768, -6656, 3328, 3840, -1536, 1792, 1024, -7424, 1536, 1792, -768, 3328, 256, -2816, -2304, 512, -256, 768, 2304, -768, -2048, 256, -1024, 0, 1280, 0, 0, -512, 0, -256, 0, 0, -512, 2816, 5888, 5632, 6144, 6400, 5120, 5376, 3840, 10240, -256, -6144, -10752, -1280, -4864, -2816, -2048, 1024, -11776, -7936, -3584, -8448, -10240, -11264, -12288, -22784, -16128, -12032, -8448, -6912, -2560, -1536, 5632, 6400, 6656, 7168, 9472, 2816, 3840, 13056, 11264, 13824, 16896, 16896, 18176, 28416, 21504, 17920, 16128, 12032, 9984, 5632, 12032, -7168, -20224, -28416, -23040, -23296, -28672, -20736, -22272, -12544, -11776, -1280, -6144, 6656, 6144, 12032, 7424, 5888, 7680, 7680, 3328, -256, 1024, -3584, 4352, 8960, 15872, 7936, 13568, 15104, 18432, 16384, 6912, 6656, 2304, 2304, -15616, -11264, -22528, -18944, -20736, -21248, -31744, -24576, -9472, -19968, -12288, -14336, -17408, -15360, 1792, 11264, 9984, 13824, 19712, 26112, 28160, 27648, 22784, 25856, 25600, 26880, 16384, 5632, -256, 11264, 10240, -4864, -7424, -8960, -4096, -6912, -10240, -19712, -20992, -28928, -26624, -23808, -14592, -18432, -14336, -768, 256, 1792, -256, 12544, 9984, 7680, 7936, 5888, 2560, 7936, 2816, 1792, -4864, -512, -512, 7168, 15872, 23552, 19200, 8448, 8704, -5120, -12032, -15616, -21760, -26880, -23808, -30464, -28672, -13824, -17920, -17152, -8192, -256, 1024, 1024, 5120, 7424, 15872, 17920, 13824, 15872, 19968, 29440, 23552, 21760, 19968, 13312, 5376, 4864, 6912, 512, -2048, 3328, 0, 1280, 768, 2304, 4608, 0, -15104, -15616, -11520, -14592, -16640, -19456, -22784, -26112, -12288, -6144, 4352, 1536, 6656, 8448, 8960, 6656, 10496, 16128, 5120, 3072, 7424, 8704, 2048, 1792, 7936, 5376, 7936, 9984, 8448, -1280, -2048, -14080, -14592, -25088, -24064, -22528, -16384, -20992, -18944, -9984, -3584, 768, 4096, 5632, 2048, 512, 4352, 1280, 9216, 19456, 18944, 18176, 14592, 18688, 15872, 12032, 7680, 8192, 4864, 1024, 1792, -3584, -4608, -512, 4352, -1280, 3328, 5632, 7936, 2560, 2048, -3328, -12032, -20480, -21760, -22016, -18176, -18688, -15360, -8960, -2560, 2304, 4864, 12544, 13568, 12032, 15360, 18688, 11008, 8448, 5120, 3328, -256, -1792, -1792, 1792, 2304, -512, 1280, -3584, -10240, -17664, -15616, -16896, -17152, -21504, -14848, -14848, -8448, 512, -1792, -1280, 3072, 8192, 4608, 6400, 4864, 6144, 16640, 15104, 15872, 16384, 16128, 14080, 15360, 13312, 7936, 4864, -3072, -6656, -1024, -1792, -2560, -768, 1536, -5632, -3584, 3072, 4864, 1024, -6656, -9728, -10240, -14336, -15616, -16896, -15104, -16640, -13056, -5120, 7424, 10240, 13056, 13312, 15872, 15616, 13568, 6656, 5120, 1536, 2048, 1536, 2304, -3584, -3584, -3840, -512, -2816, -5888, -9216, -9728, -15360, -19712, -17664, -15360, -13056, -14336, -11264, -6912, 2560, -512, 3584, 2560, 5632, 4096, 10496, 15360, 9984, 8960, 15360, 15872, 11008, 11520, 16128, 13312, 4352, 3072, 3840, -256, -512, 0, -9728, -12288, -8192, -5632, -1792, 768, 3328, 2560, -512, -256, -2048, -3072, -6400, -12288, -11776, -13312, -12544, -9216, -4352, 2304, 4352, 6656, 12288, 14592, 14080, 17664, 15360, 8192, 1536, 1024, -1536, -5120, -6144, -2304, -5376, -6400, -3584, -4608, -9728, -9728, -8192, -13056, -13312, -15360, -8704, -1536, -1536, -4096, -2816, -512, -256, 4352, 4864, 768, 2816, 6400, 7936, 10496, 9984, 8448, 8448, 10496, 8704, 8704, 5888, 5376, 3840, 1536, -3328, -6144, -7168, -5120, -2048, -3072, -4864, -3072, -1280, 2304, 3584, 512, -3072, -6400, -7168, -5376, -7168, -5888, -5632, -4608, -6656, -1280, 6144, 11520, 11776, 12032, 9984, 8448, 9216, 10752, 7424, 1792, -1280, -2560, -5376, -7424, -9984, -9984, -7936, -6144, -7424, -9984, -13056, -11008, -6912, -5632, -4608, -6400, -6656, -5120, 2304, 4864, 4608, 1024, -512, 4864, 7680, 9728, 6400, 6144, 7168, 8448, 10496, 9728, 8704, 8192, 9728, 6144, 2048, 1024, -2048, -2816, -3840, -6400, -7936, -6400, -5120, -5632, -3840, -2816, -2304, -3072, -4352, -5120, -5120, -3840, -1536, -2816, -2048, 0, 2816, 7424, 4864, 4352, 4352, 4608, 7168, 7936, 6400, 4608, 5888, 4608, 2560, 256, -1792, -4608, -6656, -6144, -7680, -10496, -9728, -11264, -8192, -7936, -7936, -8960, -6400, -3072, -512, -2048, -2816, -3328, -3328, -512, 2048, 3840, 4864, 7424, 8960, 9472, 9984, 11008, 10752, 10240, 8960, 6912, 6400, 4608, 3840, 2304, 1024, -1024, -3840, -7168, -7168, -6656, -7168, -4608, -3840, -6400, -5888, -3072, -2816, -3584, -2560, -512, -1024, -256, 2048, 3840, 4864, 5632, 6400, 4096, 4096, 4352, 1280, 1792, 3328, 4608, 3328, 2304, 1536, 1536, 1024, -1024, -5376, -7936, -7168, -9472, -9984, -8704, -9728, -9728, -8192, -4352, -1536, -1024, -3584, -4864, -2304, 768, -512, 768, 1024, 1792, 2048, 3328, 5888, 8960, 9728, 11008, 10752, 7936, 6400, 5888, 4352, 2048, 768, 1024, -1792, -1792, -2560, -3328, -5120, -4864, -7168, -8448, -7680, -5888, -4608, -3328, -4352, -3072, 768, 3584, 5888, 7936, 6912, 5888, 5376, 5632, 4864, 3072, 1024, 512, 512, -512, 0, 1024, 2816, 2816, 1536, 1024, -512, -1280, -3584, -4352, -7680, -9728, -11264, -10752, -7168, -5376, -5888, -5376, -3840, -3840, -1024, 2048, 2816, 1024, -1792, -3840, -1792, 1280, 2560, 5376, 6656, 7168, 6912, 8704, 9472, 9216, 7168, 4864, 2560, 2816, 2048, -512, -4608, -4352, -4864, -4864, -5632, -6144, -5376, -6144, -4608, -4352, -3328, -4864, -3328, -256, 3072, 4864, 5632, 5376, 4864, 4864, 7680, 8704, 6144, 3328, 1792, 512, 256, 256, 512, -256, -512, -1536, 0, 0, -512, -3840, -5376, -4352, -5376, -7168, -8192, -7936, -7936, -8192, -6912, -6144, -4352, -1024, 256, -768, -256, 256, 1024, 1792, 2048, 3840, 4096, 3840, 3840, 5120, 8192, 9216, 9728, 8192, 4864, 3072, 768, 512, -512, -1024, -2816, -4864, -4352, -3840, -2816, -4096, -5120, -6912, -7680, -7168, -5632, -3328, -1536, -512, 512, 3072, 5888, 7424, 11520, 11264, 9216, 8192, 5376, 4096, 3584, 2560, 256, -2304, -2048, -512, -256, -1792, -3328, -3328, -3072, -2304, -2816, -4608, -6144, -6656, -7168, -7680, -6144, -5376, -5376, -5376, -2816, -2816, -2560, 0, -512, 0, 1024, 3072, 3328, 3584, 3072, 4352, 5632, 7168, 7680, 7168, 5120, 4096, 3328, 2048, 512, -512, -1536, -3840, -3584, -4608, -3840, -3840, -4096, -4608, -4608, -4096, -4864, -4608, -4352, -2560, 0, -256, 1024, 3328, 5632, 9472, 9984, 9216, 6912, 6912, 8192, 6656, 3840, 1536, -256, -1024, -1280, -1792, -2816, -2816, -2304, -3840, -3840, -3584, -4608, -5376, -4864, -4352, -5376, -4864, -3840, -3840, -2560, -3840, -3584, -3072, -2816, -1536, -512, 256, -512, 256, 1280, 3584, 5632, 8448, 8960, 5888, 4608, 4096, 3328, 2816, 1536, 256, -2304, -4608, -2816, -1536, -1792, -2048, -2304, -2816, -2816, -3072, -3328, -4352, -5376, -6144, -6144, -3840, -1024, 1792, 3072, 4352, 6400, 7680, 7168, 7936, 8192, 7936, 6912, 5632, 3840, 3072, 768, -512, -2048, -1536, -768, -2304, -3328, -5632, -6144, -5120, -4608, -5632, -6144, -4608, -3584, -3328, -2560, -2816, -2304, -768, -512, -768, -1280, -2560, -2560, -1280, -256, 1024, 2816, 3840, 4864, 5632, 6912, 5888, 5120, 4096, 3584, 1280, -768, -2816, -3840, -4096, -3072, -3072, -2816, -1280, 256, -768, -2560, -3328, -3840, -2816, -2560, -2560, -2816, -2048, -768, 512, 1792, 2304, 3840, 6400, 7680, 8448, 7936, 6400, 5376, 5120, 4096, 3328, 1792, -512, -2048, -1280, -1024, -2816, -5120, -5376, -5632, -5376, -4352, -5120, -5376, -5632, -4864, -4864, -2816, -1024, -512, -512, -512, 512, 1280, 512, 0, 0, -768, 256, 2048, 4096, 3328, 3584, 4352, 3840, 3328, 2048, 1280, -256, -1536, -2560, -3328, -3584, -3584, -3328, -2560, -1792, -2048, -2048, -1536, -1536, -768, -256, -256, -2304, -3072, -1792, 768, 3328, 4352, 3584, 3328, 4352, 5632, 5888, 6144, 4608, 3840, 4608, 4608, 4608, 3840, 2048, 0, -1280, -2048, -2816, -3840, -4352, -5376, -6656, -6656, -6144, -6656, -6144, -3328, -2304, -1536, -768, -512, 768, 1024, 1536, 1792, 1280, 512, 1024, 512, -512, -1024, -768, 1280, 3328, 4352, 2560, 768, -256, -512, -1024, -1280, -2816, -3584, -3328, -2816, -2048, -2048, -2048, -1536, -768, 0, -256, -1280, -1280, 0, 1024, 768, 256, 512, 0, 0, 1536, 3328, 5120, 4352, 4352, 4608, 5376, 4608, 3584, 3328, 2816, 2816, 1792, 2304, 768, -1280, -3072, -3584, -4608, -5376, -5888, -6656, -6656, -3328, -768, -1536, -3328, -3584, -1280, 1280, 2048, 768, 0, 256, 768, 1536, 1024, -256, -256, 256, 768, 1792, 1280, 768, 0, 256, -256, 768, 0, -768, -2816, -2816, -2304, -2560, -2304, -2048, -1280, -1792, -1792, -2560, -2304, -1536, -256, 1024, 1536, 1024, 512, 1280, 2560, 3328, 2304, 3072, 3328, 3584, 3840, 4096, 3328, 3072, 2560, 3328, 3584, 3328, 2048, 512, -256, -1024, -1536, -2304, -3840, -5120, -5376, -4864, -3584, -4096, -5632, -5376, -3328, -1280, -768, -768, -256, 768, 1280, 2560, 2304, 2304, 1536, 2048, 1792, 1792, 1792, 768, -1024, -1536, -1024, -256, -1024, -2048, -2560, -2816, -2048, -1024, -1536, -2560, -1792, -2048, -2816, -2816, -2048, -1280, -1024, 0, 768, 768, 2048, 2560, 2560, 3072, 3072, 2816, 2560, 3328, 3072, 2560, 1536, 2048, 2304, 2304, 2816, 3328, 2816, 2304, 2560, 1792, 512, -768, -2048, -2304, -3584, -4096, -4096, -4864, -4608, -3584, -3328, -2816, -2816, -2560, -1280, -256, 768, 1280, 512, 512, 2304, 3584, 2816, 2304, 2560, 1792, 512, 0, 512, -512, -2304, -3328, -3840, -4608, -4352, -3840, -3328, -2560, -1280, -1280, -1792, -1792, -1024, -256, 0, -512, -1024, -512, 256, 1024, 2304, 2560, 2560, 2816, 2816, 3328, 3584, 2560, 2816, 2304, 2304, 1024, 1536, 1280, 1024, 1280, 1792, 2048, 2560, 2304, 1024, -1024, -2048, -2304, -2560, -2816, -3072, -3584, -3840, -4352, -3840, -2304, -1024, -256, -1536, -1280, 512, 2048, 2048, 1536, 1280, 768, 1024, 1280, 2304, 2560, 2560, 1280, -256, -1280, -2560, -3072, -3584, -4096, -4608, -4352, -2816, -2560, -2816, -2048, -1280, -512, -512, 0, 768, 1024, 1280, 768, 512, 768, 1280, 2304, 3072, 3072, 2816, 2560, 3072, 3584, 3072, 2048, 1280, 0, -256, 256, 768, 0, 256, 768, 1280, 1536, 1280, 0, -1280, -2816, -2560, -3328, -3072, -3328, -3840, -3584, -2048, -1024, -768, -768, -1024, 0, 1024, 1280, 768, 1536, 1024, 1024, 1792, 2560, 2304, 2304, 2048, 1280, 1280, 512, -1024, -2560, -3840, -4352, -5120, -5632, -5632, -4864, -3584, -2816, -2560, -2048, -1536, 0, 768, 1280, 768, 1024, 2048, 2816, 2816, 3072, 3328, 3072, 3072, 3840, 3840, 4096, 4096, 3328, 2816, 1536, 768, -512, -1280, -1280, -768, -512, -256, 512, 0, -768, -1024, -1280, -1792, -2560, -3072, -2816, -3072, -2816, -2048, -1024, -512, 0, 256, 512, 512, 512, 1024, 768, 768, 1024, 1280, 2304, 2560, 1536, 512, 256, 512, 0, -768, -1792, -3328, -4608, -4864, -4608, -4096, -4608, -5120, -4864, -3584, -2048, -1024, -256, 768, 768, 1280, 1792, 2304, 2304, 2560, 3072, 3328, 3328, 3328, 3328, 4096, 3840, 3328, 2304, 1536, 768, 512, 256, 0, -768, -1280, -1536, -1024, -512, -512, -1024, -1024, -1280, -1280, -768, -768, -1024, -1536, -1536, -1792, -1024, 0, 512, 768, 512, 512, 256, 512, 512, 256, 1024, 1280, 1024, 256, 0, 512, 512, 0, -512, -1536, -2048, -1536, -1792, -2304, -2816, -3840, -4608, -4864, -4608, -4608, -4352, -3328, -2304, -512, 512, 768, 1280, 2560, 3072, 3328, 3584, 3584, 3840, 4352, 4352, 4096, 4096, 3840, 3328, 2816, 1792, 512, -1536, -2560, -2048, -1536, -2048, -2048, -1792, -1536, -1536, -768, -1024, -1536, -1280, -768, -512, -512, 0, 256, 0, 512, 512, 768, 512, 768, 512, 768, 768, 1280, 512, 0, 1024, 1536, 1280, -256, -1024, -512, -256, -512, -1536, -2048, -2304, -2560, -3072, -2560, -3584, -4352, -5632, -5632, -5376, -4864, -3840, -2048, -768, 256, 1792, 3072, 3072, 3840, 4864, 5632, 5376, 4608, 4096, 4096, 4096, 3328, 3072, 1536, 768, 768, 512, -768, -1536, -1792, -3072, -3072, -2816, -2048, -2304, -2048, -1792, -768, 0, 0, 0, 0, -512, -512, 0, 256, 512, 512, 1024, 1536, 1536, 1792, 1280, 1024, 768, 1024, 1280, 768, 0, -512, -512, -1024, -1536, -2560, -2048, -2048, -2560, -2816, -3072, -3072, -3072, -3328, -4096, -4096, -4096, -3584, -2816, -2048, -1024, -512, 256, 1536, 3072, 4352, 4864, 5120, 5120, 5376, 5376, 4864, 3328, 2560, 2304, 1280, 0, -768, -1024, -1024, -1280, -1536, -1536, -1024, -1792, -2560, -3072, -3072, -3072, -2560, -1792, -1024, -512, 1024, 1536, 2048, 1792, 1792, 1792, 1792, 2048, 2048, 1792, 1280, 1536, 1536, 1024, 256, -256, -256, 0, -768, -1792, -2560, -2560, -2048, -2816, -3584, -3584, -3072, -2816, -2304, -1536, -2048, -2048, -2048, -2816, -3328, -3072, -2304, -2048, -1280, 0, 1024, 2048, 2816, 3584, 4608, 4608, 5120, 5888, 5888, 5120, 3584, 2304, 1024, 0, -768, -1536, -2048, -2048, -2048, -2048, -2304, -2560, -2816, -2560, -2304, -2048, -2048, -1792, -1536, -768, 0, 768, 1536, 3072, 4096, 4096, 3584, 2560, 2048, 2304, 1792, 1024, 256, 0, 0, -512, -256, 0, 0, -768, -1792, -2560, -3328, -3328, -3072, -3328, -3840, -3584, -3328, -2304, -1536, -1280, -1280, -1792, -2048, -2304, -1792, -1536, -1280, -1792, -1280, 256, 2048, 3328, 4352, 4864, 5120, 5376, 5632, 5632, 4608, 3072, 2304, 1280, -256, -1280, -2304, -2816, -3328, -3072, -3072, -2816, -2560, -2048, -1792, -1792, -1536, -1792, -1536, -768, 0, 256, 768, 1792, 2560, 2816, 3072, 3840, 3840, 3584, 2304, 1536, 768, 256, 0, -512, -512, -512, -768, -1536, -2048, -2560, -2816, -3328, -3840, -3840, -3840, -3328, -3072, -3072, -1792, -1280, -1280, -1280, -1024, -768, -768, -1024, -1024, -256, -256, 256, 1024, 1792, 2560, 3072, 3584, 4352, 5120, 5632, 4864, 3584, 2048, 1280, 512, -512, -1280, -2560, -3584, -3328, -2816, -2560, -2560, -2560, -2560, -2048, -1536, -768, -768, -768, -256, -256, 512, 1536, 2560, 3328, 3584, 3840, 3840, 3840, 3328, 2816, 2048, 1280, 256, -256, -768, -768, -1536, -2560, -3072, -3072, -3072, -3072, -3328, -3840, -4608, -4864, -3840, -2816, -1536, -1024, -768, -1024, -1024, -512, 256, 1024, 512, -256, -512, 256, 1024, 1536, 2048, 1792, 1792, 2816, 3584, 3840, 3840, 3840, 3328, 2560, 1536, 256, -768, -1536, -2304, -3328, -3840, -3840, -3328, -2816, -2304, -2304, -2304, -1792, -768, 0, 512, 512, 1024, 1792, 2816, 3840, 4096, 3584, 2816, 3072, 3328, 3840, 3328, 2304, 1024, 256, -256, -1024, -1536, -2048, -2816, -3840, -4352, -4352, -4352, -4352, -3840, -3328, -3328, -3072, -2560, -1792, -1536, -1024, 256, 512, 512, 768, 1024, 1280, 1024, 1024, 768, 1280, 1536, 1536, 2048, 1792, 1792, 2304, 2816, 2560, 2304, 2048, 1280, 512, 0, -512, -1536, -2560, -3328, -3328, -3584, -3584, -3328, -2816, -2304, -1024, -256, -256, -256, 512, 1536, 2048, 2560, 2816, 3072, 3584, 3584, 3584, 3328, 2816, 2560, 1792, 1024, 512, 768, 256, -768, -1536, -2560, -3584, -4352, -4608, -4608, -4864, -4864, -4352, -3840, -3328, -2304, -1280, -256, 256, 0, 256, 768, 1280, 1536, 1536, 1536, 1792, 2048, 2304, 2048, 1024, 256, 0, 512, 1024, 1280, 1536, 1280, 1024, 1024, 1024, 768, 256, -768, -1792, -2304, -2816, -3072, -3072, -3072, -2816, -2560, -1792, -1024, -512, 256, 1024, 1280, 2048, 2816, 3328, 3584, 3584, 2816, 2816, 2816, 2560, 2560, 2304, 1536, 1280, 768, 256, -512, -1280, -2560, -3584, -4096, -4352, -4608, -4864, -5120, -4864, -4352, -3584, -2560, -1280, -256, 256, 768, 1280, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 2048, 1792, 1536, 1024, 512, 0, -256, 0, 0, 256, 512, 256, 256, 512, 256, -512, -1280, -2048, -2304, -2560, -2816, -3072, -3072, -2560, -1792, -1024, -256, 512, 2048, 2816, 3328, 3840, 3840, 3328, 3072, 2816, 2560, 2304, 2048, 1536, 1280, 1024, 1024, 768, 0, -768, -1536, -2560, -3584, -4608, -5376, -5632, -5376, -4608, -4096, -3328, -2560, -1536, -768, 0, 768, 1280, 1280, 1280, 1536, 1792, 2048, 2048, 2048, 1792, 2048, 1792, 1536, 1280, 1024, 256, 0, -512, -1024, -1024, -1280, -1024, -1024, -768, -512, -256, -512, -768, -1024, -1792, -2048, -2304, -2304, -2304, -2048, -1280, -512, 512, 1024, 2048, 2816, 3584, 3840, 3840, 3584, 3072, 2560, 1792, 1280, 1024, 1024, 512, 256, 256, 512, -256, -768, -1792, -2560, -3840, -4608, -4608, -4608, -4608, -4352, -3840, -2816, -1792, -768, 256, 768, 1024, 1280, 1536, 1792, 1792, 2048, 2048, 2304, 2560, 2560, 2304, 1536, 1024, 512, 0, -768, -1024, -1536, -1792, -1792, -1536, -1280, -768, -512, -512, -512, -512, -768, -1024, -1280, -1536, -1536, -1536, -1536, -1280, -1024, -256, 1024, 1792, 2304, 2816, 3072, 3072, 2816, 2560, 2304, 2048, 1792, 1280, 768, 768, 512, 256, 0, -256, -1024, -1792, -2048, -2560, -3328, -3584, -3840, -3840, -3840, -3584, -2816, -2304, -1536, -768, 0, 512, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2560, 2304, 2048, 1536, 1280, 768, 256, -768, -1536, -2048, -2048, -1792, -1792, -1792, -1536, -1024, -512, 0, -256, -512, -768, -768, -768, -768, -1024, -768, -768, -256, 256, 768, 1024, 1536, 1792, 2048, 2304, 2560, 2560, 2304, 1792, 1536, 1536, 1024, 768, 512, 256, -256, -512, -1024, -1536, -2304, -2816, -3072, -3072, -3072, -2816, -2816, -2560, -2304, -2048, -1792, -1280, -1024, -256, 256, 768, 1280, 1792, 2304, 2560, 2816, 2560, 2304, 2048, 1792, 1536, 512, -256, -768, -1024, -1536, -1792, -1792, -1792, -1792, -1536, -1280, -1280, -1024, -768, -768, -1024, -1024, -1024, -768, -512, 0, 0, 256, 256, 512, 1024, 1536, 1536, 1792, 1792, 2048, 1792, 1792, 1792, 1792, 1792, 1536, 1280, 512, 0, -512, -1024, -1280, -1792, -2048, -2048, -2048, -2304, -2560, -2560, -2304, -2048, -1792, -1792, -1792, -1280, -768, -512, 0, 256, 512, 1024, 1536, 2304, 2560, 2816, 3072, 2560, 2048, 1536, 768, 256, -512, -1024, -1536, -1792, -1792, -1792, -1792, -2048, -1792, -1792, -1536, -1536, -1280, -1024, -768, -768, -512, -256, 256, 512, 512, 768, 1024, 1280, 1280, 1280, 1536, 1536, 1536, 1280, 1280, 1536, 1536, 1536, 1024, 768, 512, 256, -256, -768, -1024, -1536, -2048, -2304, -2304, -2048, -2048, -1536, -1280, -1280, -1280, -1536, -1536, -1536, -1280, -1024, -512, 0, 512, 1024, 1536, 1792, 2048, 2304, 2304, 2304, 2304, 1536, 1024, 256, -256, -768, -1280, -1536, -1792, -1792, -1792, -1536, -1536, -1536, -1536, -1536, -1280, -1024, -768, -768, -512, -256, 256, 768, 1024, 1280, 1280, 1280, 1280, 1280, 1280, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 512, 256, -256, -768, -1024, -1280, -1536, -1792, -1792, -1792, -1792, -1792, -1536, -1280, -1024, -1024, -768, -768, -768, -768, -512, -256, 0, 256, 768, 1280, 1792, 2048, 2048, 2048, 1792, 1536, 1024, 512, 0, -512, -768, -1024, -1280, -1536, -1792, -1792, -1792, -1792, -1536, -1536, -1280, -1280, -1280, -768, -512, 0, 256, 512, 768, 1024, 1280, 1536, 1536, 1536, 1280, 1280, 1024, 768, 768, 768, 768, 768, 768, 512, 256, 256, -256, -512, -768, -1024, -1280, -1536, -1536, -1792, -1536, -1280, -1024, -768, -768, -768, -768, -768, -512, -256, -256, 0, 256, 256, 256, 512, 768, 1280, 1536, 1536, 1536, 1280, 1024, 512, 256, 0, -512, -1024, -1280, -1280, -1536, -1536, -1536, -1792, -1792, -1792, -1536, -1280, -1024, -768, -512, -256, 0, 512, 768, 768, 1024, 1024, 1280, 1280, 1280, 1024, 1024, 1024, 1024, 768, 768, 512, 256, 256, 0, 0, -256, -256, -512, -768, -1024, -1280, -1280, -1280, -1280, -1280, -1024, -1024, -768, -768, -512, -256, -256, -256, -256, 0, 0, 0, 256, 512, 768, 768, 1024, 1024, 1024, 1024, 1024, 768, 256, 0, 0, -512, -768, -1024, -1280, -1280, -1536, -1536, -1536, -1280, -1024, -1024, -1024, -768, -512, -512, -256, 0, 512, 768, 768, 1024, 1024, 1024, 1024, 768, 768, 768, 768, 512, 512, 256, 256, 256, 0, -256, -256, -512, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -512, -512, -512, -256, -256, -256, 0, 0, 0, 0, 256, 256, 256, 256, 256, 512, 512, 512, 512, 256, 256, 0, 0, -256, -256, -512, -768, -768, -768, -1024, -1024, -1024, -1024, -768, -768, -512, -256, -256, -256, 0, 256, 256, 256, 512, 512, 512, 768, 768, 512, 512, 256, 256, 256, 0, 0, 0, 0, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -1280, -10496, -6400, -9472, -2304, 7168, 3584, 1536, 256, 4864, 4096, -21248, -13568, -8960, -11264, -7424, 2048, -5888, -7424, -1536, -5120, -5632, -4864, -10240, -512, 3584, 8704, 19968, 15104, 18688, 23808, 18688, 21248, 31744, 24064, 22272, 15616, 25088, 20480, 7424, 6912, 1536, 2048, -2304, -2048, -6656, -8448, -8960, -8192, -6400, -8192, -7168, -15104, -11776, -7936, -4864, -3072, -3072, 3584, 3584, -10496, -15104, -11776, -8448, -8192, -13312, -7936, -7424, -12544, -13056, -13568, -21760, -13568, -15360, -25600, -21760, -21504, -16896, -9472, -6656, -2816, -2048, 5632, 10496, 8448, 9984, 6912, 7424, 19200, 15104, 11520, 13312, 17664, 16896, 18688, 23040, 23296, 26368, 20736, 11776, 4096, -5376, -8192, -3328, -8704, -5632, -10752, -13056, -8960, -13568, -15872, -11520, -8960, -8704, -7424, 6400, 15872, 15616, 9984, -2048, -5120, -1280, -1792, 512, 7168, 256, -6144, 2048, 7424, 2816, -2304, -13824, -8704, -8960, -14592, -10496, -16128, -12800, -4096, -4608, 6656, 5888, -512, 9728, 2304, 4352, 10496, 9984, 20992, 16384, 16384, 26368, 16384, 11008, 11008, 13056, 6656, -768, 7680, 256, 2304, 3584, -6656, 5120, -6912, -12800, -9984, -12032, -7936, -5888, -8448, 6400, 14336, 13056, 5120, -4864, -15360, -10496, -6912, -2560, 768, -9216, -7680, -5632, -11776, -1280, -3072, -1792, -1024, -13824, 768, -6400, -2560, -256, -10752, -19200, -6912, -21504, -15360, -22528, -27392, -18688, -7424, -17152, -13568, 2304, -2560, 4352, -7424, -8448, 14080, 3072, 1792, 30976, 17920, 10752, 31488, 24576, 32512, 18944, 7168, 13056, 5376, 15360, 5888, -2560, 6400, 26368, 28928, 16640, 11520, 3840, -256, 2560, 512, -6656, 256, -4096, 4864, 6912, -2048, -2048, -6144, -5120, -4352, -8960, -22016, -22272, -8192, -13056, -6656, -15360, -15360, -12800, -3840, -7936, -7680, -12800, -14080, -4864, 5632, 3584, 7680, 12544, 10752, 3840, -2816, -14592, -3840, -7424, -16640, -9472, -14336, -7424, 3840, 17920, 17664, 9216, 6144, 4864, 5376, 4864, 1024, 15360, 14080, 4608, -4352, 0, -512, -5376, 13056, 12544, -1536, 5632, 3584, -6144, -16128, -1280, 1024, -13568, -8448, -256, -9472, -8704, 10240, 7680, 3072, -1536, -256, 3072, 3072, 5888, 5120, 11008, 8704, 2816, -6656, -10240, 6400, 14336, -256, -10496, -12800, -9472, -2560, 5120, -14848, -16640, -11008, -6656, 10752, 14592, 19712, 14592, 6656, -1024, -2560, -14592, -11520, -5888, -12544, -256, -15104, -10496, -6656, -6912, 6144, 13312, -768, -3072, 4864, -11264, -7936, 8448, 2816, -3584, 11008, 7936, 1792, 14848, 21504, 11520, 8960, 4608, -1280, 1536, -5376, -1536, -5120, -1792, 10496, 13568, 7424, 6400, 14080, 17408, 9472, -7424, -4352, -10496, -17152, -19456, -23040, -28672, -26624, -15360, -5376, 6400, 4096, -5888, -2304, 7680, 12032, 4352, 768, 4864, 1024, -512, 7680, 6144, 256, 6656, 8448, 8704, 2560, 3584, 256, -1280, 4096, -512, -15360, -8192, -13056, -12288, -9728, -8704, -10752, -5120, 4096, 4352, -4096, -8192, -1536, 1024, -9984, -4608, 256, -5120, -5632, 14080, 17920, 8704, 1280, -256, 3328, 512, 256, 7168, 5120, -7936, -512, 13056, 6656, 6144, 4864, 2816, -256, 512, 7680, 3328, 512, 17920, 9216, 3840, 6144, 1280, 2304, 3584, 12288, 11008, 2048, 512, -2560, 4608, 8448, 5632, -6912, -4864, -4352, -5632, 2816, 4864, -1280, 0, -14080, -15360, -12544, -16128, -18432, -11520, -20480, -14080, -4608, -2048, 8192, 13312, 5632, 0, -10240, -10752, -7680, -17408, -13056, -2304, -17152, -13312, -2560, 1792, 8960, 3072, 9216, 16384, 5888, 3328, 16384, 9984, 8192, 18688, 768, 1536, -2560, -1536, 4096, 4608, 13568, 13056, 5376, -5120, -3840, 3328, -768, 512, -9984, -7680, -1792, -768, 1536, 2560, -1024, -6400, -1792, -2560, -2560, -4608, -7936, -5888, -9728, -12288, -768, -6656, -11008, -1792, 2816, 7936, 15872, 10496, -1792, -8704, -10752, -6144, 4352, 3072, 11264, 6400, 6144, 4608, 2816, 8192, 13056, 11776, 11776, 13056, 8448, 6144, 8192, 7680, 10240, 2048, -7680, -9984, -7680, -11264, -4864, -8448, -14080, -10496, -9216, -17920, -17152, -16384, -8704, -9472, -11776, 256, 4864, 6912, 20736, 5888, 3328, 2560, -1280, -4608, -4864, -13056, -3584, -12288, -19200, 2816, 13056, 11008, 16128, 9472, 5120, 4864, 1024, -5888, 6912, 12032, 18176, 7424, 4096, 3840, -4352, -2816, 8192, 10240, 5632, 1536, 4096, -1792, 1280, 8704, 15616, 3072, -5376, -6144, -3328, -9728, -10496, -9216, -8448, 512, 2304, -11520, -13824, -9216, 3072, -4608, -10496, -6400, -4608, 4864, 7936, -2816, -4096, -5632, -15872, -16640, -17408, -10752, -1024, -12288, -12544, 1024, 9728, 16640, 12032, 3072, -5120, -5120, -2048, 768, 8192, 17664, 21504, 11264, 7168, 7936, 4608, 9216, 14592, 18944, 8960, 4864, 1536, 6144, 7424, 9216, 8960, 1536, -3328, -6400, -11008, -11520, -8960, -8448, -11264, -5888, -10496, -14592, -13312, -10496, -8960, -5376, -4096, -5632, -2816, 8448, 10752, 3584, 4864, 4096, 0, -1536, -8704, -4352, -9472, -6400, -1792, 1536, 12288, 12032, 768, -3584, -4352, -4864, -2816, -2304, -2816, 10752, 10752, 4096, 256, 1536, 3840, 13056, 10752, 8448, 7424, 5120, -1280, -768, 1024, 13824, 10752, 2048, -7680, -4864, -3840, -3840, -5120, -1536, -1792, -6144, -8192, -6144, -4352, -256, -4096, -4608, -9216, -14080, -9728, -512, 2048, 4096, 1792, -5376, -8960, -14336, -17152, -4352, -14848, -17152, -9216, 5376, 17152, 12288, 3840, 2048, 3328, -2304, -2048, -256, 5376, 27392, 14336, 10240, 14336, 8192, 8448, 18176, 15360, 9216, 7680, 768, 7936, 3840, 1024, 5376, 512, -512, -6400, -7680, -6656, -3328, -2304, -6656, -5120, -8704, -8704, -13056, -7168, 1536, -2304, -6144, -12544, -17152, -13824, -13824, -13312, -10496, -10752, -14848, -9472, 4096, 9984, 7936, 4096, 4864, 2816, -1024, -5888, -1280, 6144, 256, 2560, 6144, 6656, 3840, 8704, 17920, 19712, 14336, 8448, 11008, 7168, 4352, 6400, 3072, 512, 0, -3072, -3840, -512, 2560, -4864, -7168, -11520, -10496, -7168, -4352, -768, -512, -2304, -768, -6400, -11520, -3584, 5888, 2560, -1280, -4864, -8192, -5632, -2560, -256, -3840, -4096, -1536, 3328, 12288, 17920, 14080, 5888, 5888, 2560, -2048, -3584, 1536, 2048, -3072, -1280, 3328, 2560, -3584, 0, 8448, 5888, 4608, 11008, 5376, 6656, 8448, 3328, -3584, -1792, -768, -7936, -7424, -1280, -1280, -6400, -6912, -8960, -14336, -11520, -5376, -4352, -10240, -3584, 512, -5888, -9728, -2304, 2048, -4096, -4096, -1792, -3328, -6400, -1024, -3072, -5376, -3584, 768, 3328, 11264, 16640, 15360, 10240, 3840, 1280, -5120, -5632, -768, 768, 5120, 9984, 9984, 2304, 1536, 5376, 12288, 6144, 6400, 6400, 2816, 0, 1024, -1280, -7936, -8704, -5632, -11520, -10240, -6144, -6144, -10496, -9728, -12032, -13824, -11520, -4096, -5632, -8192, -1792, 4096, -256, -2816, 5888, 7936, -256, -2560, -5120, -4864, -2304, 3840, -2560, -7168, -5376, 1024, 6144, 11520, 15360, 14336, 11776, 7680, 6656, 5888, 9216, 12288, 8448, 11776, 10240, 8704, 4864, 3072, 5888, 11008, 9472, 10496, 11008, 5632, 6144, 2816, -2816, -512, -1280, 2048, -7168, -8448, -2816, -1280, -6656, -7680, -6400, -11520, -5376, -2048, -6656, -8960, -9472, -9984, -13824, -14336, -5120, -5888, -10752, -13312, -12544, -16128, -12032, -7936, -7424, -4096, -5376, -1792, 3584, 6656, 12288, 8192, 3072, -2560, -5632, -6144, -1536, 0, 8448, 11264, 7936, 6400, 3840, 2560, 8704, 12288, 9728, 3584, 2304, 4096, 3072, -5888, -3840, -3840, -2048, -2304, -4864, -5632, -512, -2048, -2560, -8192, -6912, 1024, 3072, -1280, 256, -256, 1024, -1280, -768, -1280, 2560, 9472, 4608, -2048, -4864, -768, 0, -2560, -1280, -7936, -8192, -7424, -512, 4608, 8192, 8448, 3584, -3072, -3840, 1536, 2048, 9216, 16896, 12288, 9728, 9472, 10752, 7424, 12544, 12800, 10752, 7168, 6400, 8448, 3840, 512, 1024, 512, 1024, 512, -2816, -256, 1536, 768, 2304, -3584, -3072, -1280, -3072, -8448, -9216, -7424, -6656, -9728, -11264, -10752, -9728, -9728, -13312, -17152, -17920, -12800, -8192, -6912, -7424, -9728, -6656, -6912, 256, 5376, 5888, 4096, -4352, -8704, -6656, -4608, -5120, 512, 2816, 3328, 1280, 2560, 3328, 3072, 7168, 8448, 8960, 3584, 3584, 3584, -2048, -6144, -6400, -2048, -4096, -5888, -3584, 3072, 2048, 5376, 6400, 3328, 6400, 7424, 6400, 1536, 768, 9216, 6656, 8704, 2816, 7680, 7424, 8704, 5888, 0, 256, 1792, 2048, 256, -2560, -2304, -3328, 1280, 4352, 7680, 6656, 6400, 768, -2816, -1024, -1024, 2304, 3328, 4352, 1536, 1024, 4352, -256, -1024, 2304, 4096, 5632, 768, -512, -1024, -4096, -7168, -5632, -3328, -8704, -9472, -7936, -2304, -1792, -3072, -4096, -6656, -3072, -3584, -2816, -5888, -4096, -6144, -8448, -6144, -7680, -4352, -7168, -8704, -11264, -13056, -8704, -6144, -5632, -6400, -512, 3584, 5888, 9728, 11776, 11008, 7168, 2560, -1536, -2816, 256, 0, 1280, 4608, 4096, -768, 3072, 6912, 5888, 8192, 12288, 10752, 8704, 5376, 5376, 2560, -768, -2560, -2560, -5120, -9728, -8704, -7424, -5632, -4096, -3840, -4352, -2304, 1792, 1536, 1536, -1536, 256, 1792, 1536, 768, 2816, 7680, 7680, 3840, 2816, 2816, 2560, 4352, 5632, 5888, 6144, 2304, 3840, 1280, -512, 1024, 768, -4352, -5376, -1024, -5376, -1536, 2048, -2304, -256, 0, 2048, -1792, -4608, -4096, -768, -3584, -3328, -2048, -4352, -2560, -2048, -6656, -9472, -7168, -4352, -8960, -4352, -2560, 256, -1536, 256, 6400, 8192, 6656, 2304, -4608, -4864, 256, -3072, -5120, 512, 3072, 1280, -1024, 3840, 3584, 3840, 3840, 4352, 3584, 512, 1536, 768, -4608, -5376, -2304, -256, -3840, -2816, -3840, -5632, -256, 768, -1792, 0, 3584, 3584, -1024, -3328, 1024, 4608, 3072, 3840, 4864, 6400, 7168, 6912, 3072, 2304, 2304, -2560, -4352, -1024, -1280, -1024, -5120, -4864, 2816, 5120, 3328, 0, -4864, -2048, 1536, -2304, 1536, 6656, 4608, 3584, 4352, 5632, 6144, 4608, 5376, 9472, 5120, 1792, 2816, -2048, -2816, -1024, -768, -2048, -5632, -4096, -4608, -3840, -1024, -2304, -5376, -2560, 1280, -2048, -1792, -4352, -1792, -2304, -5120, -7168, -8960, -7936, -5888, -5888, -7424, -7168, -7168, -8448, -7168, -6144, -1536, 0, -1024, 1792, 7424, 6400, 3840, -1536, -4864, 256, -512, -5632, 1024, 2560, 256, 2304, 2560, 3328, 1024, 1536, 5376, 3840, 1280, 5376, 2816, -4608, -5376, -3840, -768, -1024, -3840, -3840, -4864, 1024, 4864, 2816, 512, 4352, 4096, 512, 3584, 3584, 4352, 5120, 5632, 5120, 2560, 4096, 6912, 3072, 2048, 2816, 1280, -2304, -2560, -1536, -256, -1792, -3072, -768, 768, 2048, 2304, -1280, -768, 1536, -1280, -1536, 5888, 3584, 2816, 3072, 5376, 5376, 1024, 4608, 7680, 1792, 3072, 6400, 768, -2816, -4096, -3840, -2560, -3328, -2048, -1536, -5376, 512, -512, -6400, -4608, -2048, -5632, -5632, -4352, -3072, -1792, -3072, -3840, -5120, -10496, -7168, -6144, -5888, -3072, -3072, -3840, -2560, -1792, 512, 256, 1536, 4608, 7424, 5888, 5376, 5120, 2304, -768, -2304, -2304, -2560, -3840, -2048, -2816, -512, 1536, 3584, 1792, 1792, 2816, 2304, 3584, 512, 768, 1792, 1536, 1536, -5376, -5120, -2560, -3072, -3840, -4096, -4608, -3584, -2816, -3584, 0, 0, -1280, 768, 3584, 3072, 2304, 0, -2816, 1280, 1280, 3072, 2816, -256, 1280, 768, 256, 1024, -256, -256, 3328, 4096, 2048, 3584, 2304, -512, -1792, -2816, -4352, -3072, -1280, -2304, -2560, -3328, -1024, 256, 0, 1024, 1280, 0, 512, 768, 1280, 3584, 4608, 2304, -768, 512, 3840, 3584, 1536, 512, 256, -256, -1280, -1536, 0, 0, 0, 1792, 5120, 5632, 5888, 3328, 3328, 4352, 5120, 8960, 6400, 5120, 5120, 3584, 4352, 4096, 768, 1792, 4608, 3840, 3328, 4352, 1536, -1280, -1536, -3328, -5888, -4864, -4864, -5632, -5632, -6144, -4352, -4608, -5632, -6912, -7936, -7680, -7424, -7680, -8448, -9216, -8704, -9472, -12032, -9728, -6144, -7168, -6912, -7936, -7680, -7168, -6656, -5120, -3584, -3584, -2304, 1024, 4352, 5376, 3840, 3072, 6400, 7424, 8448, 8448, 7680, 7680, 7936, 4864, 5120, 3584, 1024, 2560, 4352, 4608, 5376, 7168, 4864, 5120, 5120, 1280, -512, -768, -1792, -2560, -512, 256, 1024, 1536, 1024, 1280, 768, 512, -256, -1024, -1792, -2560, -768, -1536, -4096, -1280, -256, -2048, -1792, -1536, -2304, -2560, -2816, -1792, -1536, -2560, -2816, 512, 2816, 1792, 256, 1536, 3072, 4096, 4608, 3840, 2816, 3584, 4096, 2304, 2816, 1536, 1280, 3328, 3584, 3328, 2816, 0, -2816, -1024, -1024, -2048, -1792, -1280, -1536, -768, -256, 512, -256, -1536, -1792, -2304, -2304, -2304, -3840, -2816, -3584, -4352, -4096, -4608, -4352, -3072, -1792, -2048, -1792, -1536, -512, -768, -3072, -3840, -3840, -4608, -3328, -4864, -5888, -6144, -5376, -5376, -3328, -3072, -1792, -768, -1792, -1536, -1024, 512, 256, 256, 768, 2304, 5888, 7168, 5888, 4352, 6144, 6912, 5632, 4864, 4096, 4864, 2560, 2304, 2560, 2560, 4864, 2048, 2816, 4096, 3840, 2816, 3328, 3584, 1792, 1280, -768, -1792, -3072, -3840, -4096, -4352, -2560, -1280, 1024, -512, -512, -2304, -3328, -2304, -2048, -2560, -2560, -3072, -1280, 768, 1792, 768, 2304, 768, 1024, -256, -512, 512, -1024, -2304, -1024, 0, 1024, 1024, -1536, -768, 3072, 2560, 3840, 3072, 1792, 1792, 256, -256, 2048, 2816, 2304, 2304, 3328, 4352, 4352, 2304, 2816, 1024, 0, -768, -1536, -2048, -2304, -2560, -4352, -5120, -6144, -4352, -4864, -5632, -5120, -5376, -3840, -4096, -4864, -5888, -5376, -7168, -6656, -3840, -3584, -1024, -256, -1536, -768, -256, 1024, 2304, 512, 1024, 1792, 1792, 2816, 3840, 1536, 4352, 6144, 4096, 3840, 2304, 1536, 1536, 768, 256, 768, 512, -512, 1536, 1536, 1536, 768, -1536, -768, -2048, -1792, -2560, -3328, -4352, -4608, -4096, -4864, -3328, -2304, -768, 1024, 2560, 1792, 1792, 3072, 2816, 3328, 2560, 1536, 256, 512, 1024, 1024, 2560, 2560, 1792, 1024, 256, 1024, -1280, -3072, -768, 256, 2560, 1792, 1536, 1024, 4864, 5632, 5120, 5888, 4096, 3840, 4864, 4352, 3584, 2304, 1792, 1024, 1024, 512, 1280, 768, 0, 0, -1792, -1792, -2048, -1792, -3584, -3840, -4608, -6400, -5376, -5376, -4096, -3328, -3584, -4352, -4608, -5888, -5376, -5888, -7424, -8192, -8448, -7680, -5888, -3328, -2816, -2560, -2048, -1792, -512, 256, -768, -256, 1280, 3328, 4352, 3328, 2816, 3328, 4096, 3584, 2560, 2816, 2048, 4096, 3328, 1024, 0, 1792, 3328, 3584, 3840, 3840, 4352, 4352, 2304, 2048, 2304, 2304, 512, 1280, 2816, 3584, 1792, 1024, 2816, 2560, 1280, 1792, 512, -256, -1024, -2304, -4096, -3840, -3072, -2304, -3840, -5888, -5376, -5632, -5632, -5120, -5632, -5632, -5376, -5632, -5632, -3328, -1536, 1024, 512, -512, 512, 1792, 1536, 2560, 2048, 2304, 3072, 5376, 4096, 2816, 1792, 2816, 3328, 2816, 2560, 2816, 3328, 2304, 1536, 1536, 1280, 1024, -1280, 256, 1024, 1280, -256, -512, 1536, 768, 768, -768, -2560, -3584, -3584, -3584, -4096, -2048, -1536, -256, -1536, -1792, -1280, -1792, -1536, -2304, -2048, -2048, -1024, -1280, -2048, -1536, 768, 3072, 1024, -512, 768, 256, 256, -256, -1024, -1024, 1280, 1536, 256, -1024, -768, 1280, 2304, 2048, 4608, 5120, 5632, 3840, 2816, 2816, 3840, 3072, 2304, 2816, 2816, 2816, 1280, 2560, 3072, 1280, 768, -512, -1024, -2304, -2304, -4096, -4352, -3584, -3072, -3584, -5120, -3840, -4096, -4352, -4352, -4864, -5120, -4864, -3840, -4352, -3840, -3328, -512, -768, -3328, -2048, 0, 1024, 1792, 1536, 1024, 2816, 3328, 3584, 2816, 1280, 1536, 768, -256, -512, 512, 768, -256, -512, -1536, -1024, -256, -768, 0, 768, 256, -512, -1280, -1280, -768, -1536, -2304, -1792, -3840, -3328, -2560, -2048, -1024, 256, 2304, 1792, 512, 2048, 2048, 2304, 3072, 3584, 1792, 3072, 3072, 3072, 2048, 3584, 4864, 2816, 1792, 2560, 3328, 2560, 512, -512, -1536, -256, 512, 1536, 768, 256, 1024, 512, 512, 1280, 2048, 2048, 1792, 1792, 512, 0, -768, -1536, -768, -256, -1536, -3072, -2304, -1536, -1792, -2304, -2560, -3584, -4096, -3072, -3072, -2816, -3328, -4096, -4096, -5120, -4608, -3584, -2560, -2048, -2304, -3328, -2304, -2048, -2304, -1792, -2304, -2048, -768, -1024, -768, -1536, 0, 512, 768, -768, 512, 1280, 256, 1536, 1280, 1280, 2560, 2816, 4352, 3840, 5120, 6400, 5120, 3840, 4352, 3328, 3072, 2816, 1792, 1024, -256, -512, 1536, 1792, 1792, 2304, 2560, 1792, 2304, 1792, 1280, 1280, 256, -1536, -512, -1280, -1536, -768, -768, -256, -768, -1280, -768, -1536, -2048, -1792, -2048, -2816, -3072, -4096, -4864, -4864, -3584, -3584, -4352, -4352, -2816, -3072, -3840, -1536, -2048, -3072, -3072, -2304, -1792, -1536, 512, 2304, 1536, 2048, 2816, 3328, 3840, 3584, 2816, 1792, 768, 768, 1024, 1792, 2304, 2560, 1536, 1536, 1280, 1792, 2816, 2816, 1024, 256, 256, -768, -1280, -256, -256, -256, -1280, -512, -256, -256, 256, 256, -768, -1792, -1792, -2304, -3072, -2816, -768, -768, -1792, -1536, -1536, -1280, -1280, 0, -768, -1024, -512, 512, -256, 0, 1536, 1792, 1792, 1024, 768, 1280, -256, 0, -256, -1792, -2304, -2048, -2816, -1280, 0, -256, 0, 512, 512, 1280, 2560, 2560, 1792, 1792, 1792, 2048, 2048, 2304, 2816, 2304, 2048, 2304, 1536, 1024, 512, 0, -768, -1280, -2048, -2048, -3072, -2048, -256, -1024, -1024, -1280, -1792, -2304, -1536, -1280, -1536, -2048, -1536, -768, -1792, 0, 1280, 1536, 768, 256, 1536, 1536, 1024, 768, 256, -512, -1024, -1536, -1024, 768, 1792, 768, 0, -256, -768, -512, -256, -512, -1280, -2048, -2304, -1792, -2304, -2048, -1536, -2304, -1792, -2304, -1792, -1536, -1792, -1536, -1792, -1792, -1792, -1792, -2048, -512, 256, 512, 1024, 768, 1280, 1536, 2560, 2816, 2304, 2560, 3072, 2304, 2304, 2816, 2304, 2560, 2048, 1792, 1792, 1536, 1792, 1280, 1024, 1280, 1024, -256, -1024, -768, -1280, -256, -512, -1024, -1024, -1024, -1024, -512, -512, -768, -1024, -512, -256, 0, 256, 2048, 2048, 1024, 1024, 1024, 512, -512, -768, -1280, -1536, -2304, -2560, -2048, -1280, 512, 256, -512, -512, -512, -512, -512, -1280, -1280, -1792, -1792, -768, -1024, -1536, -1024, -768, -1280, -1792, -1280, -1024, -1792, -2304, -1536, -1536, -2304, -1792, -1536, -512, 768, 768, 1024, 1280, 768, 1024, 1280, 512, 0, 512, 768, 512, 1280, 1792, 2560, 2304, 1792, 1792, 1536, 1024, 256, -512, -1280, -1536, -2560, -2560, -2048, 512, 2048, 1792, 1536, 1792, 1280, 1280, 1792, 1536, 768, 1024, 768, 1024, 256, 768, 512, 1024, 512, 256, 256, -256, -768, -768, -1024, -1536, -2304, -2304, -2304, -1792, -1536, -1280, -1280, -1024, -1280, -512, -256, -512, -768, -256, -256, -768, -512, 512, 512, 768, 1024, 1024, 512, 0, -256, -768, -1024, -1024, -1280, -1792, -512, 512, 512, -256, -768, -256, -1024, -768, -512, -1024, -1024, -512, -256, -512, -1024, -512, -512, -256, -512, -512, -512, -768, -512, 0, 512, 0, -512, -512, 0, 512, 768, 1280, 1024, 1024, 1024, 1536, 768, 256, 0, 0, 0, 0, 1280, 1280, 1024, 1536, 1024, 512, 0, -512, -768, -1536, -2304, -2048, -2560, -2560, -512, 768, 1024, 1024, 1024, 1280, 1024, 1024, 1280, 1024, 1024, 1024, 1024, 512, 768, 512, 512, 512, 256, 256, 0, -512, -768, -768, -1024, -1536, -2048, -1792, -1024, -1536, -768, -768, -768, -512, 256, 0, -256, -512, -512, -256, -256, 0, 256, 0, 0, 256, 0, 0, 0, -256, -512, -768, -768, -1024, -1280, -1024, -768, -768, -768, -768, -768, -768, -512, -256, 0, -256, 0, 0, 256, 256, 256, 256, 256, 256, 0, 0, 256, 256, 256, 256, 0, 256, 512, 768, 768, 512, 512, 0, -256, -256, -512, -768, -768, -1024, -1280, -1024, 0, 768, 768, 768, 768, 512, 768, 1024, 1536, 1024, 1024, 768, 512, 256, 512, 256, 0, 0, -256, -512, -768, -768, -512, -512, -768, -768, -768, -768, -768, -512, -512, -512, -512, -512, -512, -512, -512, -768, -512, -768, -512, -512, 0, 0, 0, 0, 0, -256, -256, -512, -512, -768, -512, -1024, -1024, -768, 0, -256, 0, 0, 0, 0, 0, 256, 512, 256, 256, 256, 0, 0, 0, -256, 0, -256, -256, -256, -256, -256, 0, 0, -256, 0, 0, 0, 256, 256, 256, 256, 256, 256, 0, 0, 0, -256, 0, -256, 0, 0, 0, 0, 0, 0, -256, -256, -512, -512, -512, -512, -512, -768, -768, -256, 0, 0, 0, 0, 0, 0, 0, 256, 256, 256, 0, 0, 0, -2048, -8448, -6144, -6400, -6400, -6656, -6912, -8192, -7168, -9216, -7936, -9216, -5632, -8704, 2816, -18944, -3584, 24064, 10496, 7168, 8448, 7680, 10240, 8704, 5888, 10496, 10240, 15360, 14336, 15104, 15360, 11264, 9984, 13824, 11520, 13312, 4352, 11264, 15872, 8704, 8448, 4864, 4608, 11008, 8960, 5632, 9216, -3840, -2560, 8192, -1792, -3072, -1536, -2048, -12800, -12032, -11264, -1024, -6400, -12288, -19456, -14848, -19200, -24576, -21760, -30208, -29184, -16128, -27136, -26368, -21248, -28160, -25344, -21504, -19456, -14848, -16128, -15616, -13056, -13568, -9216, -8192, -10496, -6912, -2816, 2816, 2048, 6912, 4864, 7680, 8960, 7168, 14592, 13568, 9728, 18176, 13056, 17408, 28160, 19968, 22784, 27904, 24832, 20992, 24064, 29440, 29184, 20224, 17920, 20224, 24064, 21760, 19456, 21504, 24320, 21248, 20992, 14080, 13824, 13824, 10496, 10496, 6912, 5120, 1536, -2816, -5376, -4096, -3584, -8448, -8448, -13312, -13824, -15104, -15872, -18176, -20224, -22528, -22528, -19968, -19968, -18432, -18176, -24064, -25344, -23808, -23040, -19968, -22272, -26880, -26368, -20224, -15872, -18176, -19968, -16128, -15616, -16896, -12544, -5888, -2560, -2816, -6144, -5120, -1024, -5632, 2304, 2048, 6912, 11008, 8704, 9728, 13056, 21248, 16640, 14848, 18944, 19200, 17920, 18688, 18176, 16640, 25600, 22784, 24064, 16640, 21504, 12544, 12544, 15616, 13824, 11008, 13056, 14848, 13568, 8960, 10240, 9216, 9728, 8704, 5888, 3584, -3072, -2560, -256, -256, -2816, -3072, -4864, -8448, -16896, -13312, -10752, -9472, -14080, -10752, -7168, -8192, -7424, -8960, -10496, -7168, -6400, -11776, -21760, -16384, -15872, -14080, -12544, -17408, -14080, -13568, -13312, -12032, -11008, -6656, -8192, -10496, -8704, -8960, -10240, -6656, -2048, -256, -1536, -2816, 1280, -512, 2048, 768, 2048, 1536, 1024, 5120, 7424, 11008, 6144, 8448, 5120, 7680, 6144, 9984, 9728, 10240, 7424, 9472, 9216, 9984, 15616, 14848, 10496, 13056, 15104, 13056, 14080, 14848, 12288, 8192, 11520, 10240, 6912, 7680, 10496, 11264, 6656, 4864, 5888, -768, 1792, 0, -768, 512, 768, -1536, -1280, -3584, -1536, -2560, -6912, -11520, -12032, -10496, -9728, -12800, -13056, -11776, -11008, -11520, -16640, -16640, -20480, -24320, -20992, -18944, -16896, -17664, -17152, -8448, -7936, -13568, -12288, -13056, -11008, -4608, -6144, -6144, -8448, -6656, -2560, 0, -4352, -1536, 4352, 7936, 512, 5888, 11520, 11776, 3072, 19200, 9728, 16128, 17664, 7936, 9728, 20480, 14592, 12288, 15104, 20736, 18944, 8192, 13312, 18432, 6144, 15360, 11264, 14080, 10240, 7168, 12288, 8448, 6144, 2560, -512, 5376, 8704, 3328, 4608, 1792, -256, -3072, -5120, -4608, -7680, -2304, -1792, -7680, -6912, -6656, -9728, -5120, -13824, -14080, -16384, -13568, -9216, -15872, -9472, -18176, -12032, -10752, -18176, -11520, -14080, -12800, -13824, -14336, -9216, -9472, -13824, -9216, -3072, -9728, -8448, -6656, -1792, -5632, -11264, -2560, 512, 768, 3840, 2048, 4608, 1536, 3072, 2048, 3840, 7168, 5632, 12800, 8960, 14080, 10752, 9216, 12544, 13312, 16384, 12288, 15360, 12544, 15360, 15872, 10240, 12032, 17408, 13312, 15104, 15616, 11264, 13568, 11264, 8960, 7936, 7936, 12032, 5632, 1536, 1024, -1792, 1280, -1024, -5376, -3328, -2304, -2560, -6912, -11776, -8192, -11264, -11776, -15872, -11264, -13056, -17152, -13568, -15104, -16128, -18944, -17152, -15616, -15616, -16640, -12032, -14848, -14592, -11520, -10496, -11776, -10496, -9728, -5632, -6400, -8704, -4096, -2560, -4608, 0, 256, -1536, 1280, 4352, 3840, 2560, 5888, 9728, 7168, 7168, 13824, 10240, 4864, 14080, 14080, 10496, 11776, 13568, 10240, 12544, 13056, 13312, 10496, 14336, 9984, 13568, 9728, 8448, 8960, 4608, 3840, 9728, 7680, 5888, 6912, 3328, 2816, 1792, 4096, -256, 0, 0, 3328, -1536, -2560, -3840, -2560, -2560, -6144, -5120, -4096, -9728, -9216, -5376, -10240, -8192, -10752, -9728, -13312, -13568, -10496, -12288, -14848, -12800, -12032, -9472, -10496, -11520, -7424, -10496, -1536, -12288, -6144, -6400, -3840, -2304, -2560, -2560, -2560, -256, -4352, 1024, 768, 2560, -1024, 2304, 3840, 6400, 6144, 4864, 5888, 8704, 7168, 8448, 9472, 9728, 6656, 9216, 12032, 8960, 11776, 11520, 7168, 8960, 8192, 8192, 6144, 5376, 6656, 5888, 4864, 9472, 5120, 2304, 7424, -512, 6656, 6144, 2048, 1024, 3584, 5376, 2816, -2304, -2048, 1024, -2304, -7936, -2816, -3840, -5376, -6144, -7424, -5632, -8448, -6656, -7424, -12288, -8192, -11264, -7168, -5632, -8960, -7680, -9728, -7936, -11776, -11264, -9216, -6912, -5888, -7424, -6144, -2816, -5120, -7168, -3328, -8704, -4864, -256, 1792, -768, -256, 1536, -768, 1280, 1024, 2048, 4352, 6656, 4864, 8448, 6912, 4096, 8960, 3584, 9216, 9984, 5632, 8192, 7936, 4864, 8192, 5888, 7424, 5376, 7680, 7424, 5888, 7936, 3328, 6144, 4352, 2816, 6656, 4608, 3072, 1280, 5888, 4096, 2304, 3840, -2560, 768, 4608, -3840, -1024, -1024, 1536, -3584, -3840, -1280, -8704, -2816, -5120, -4608, -2048, -4352, -7424, -7680, -7424, -4864, -8704, -8960, -5120, -9216, -5120, -4096, -5376, -9728, -4096, -7680, -6144, -6400, -4864, -4608, -3840, -1792, -1280, -1280, -2560, -5888, -768, -3584, 0, -256, -3072, -2304, 1792, 1792, 512, 3072, 1280, 1792, 4864, 2560, 5376, 5376, 6912, 7680, 5632, 4608, 8704, 5632, 2816, 6656, 6144, 5120, 5376, 6400, 7424, 5632, 6912, 6912, 5120, 2560, 5120, 4096, 5632, 3840, 4096, 4096, 1280, 4864, 2560, 768, 5632, -1280, -1280, -1792, -4096, -1024, -2816, -5632, -1792, -4096, -2816, -5888, -4096, -7680, -6144, -7168, -5120, -7424, -6144, -8192, -5632, -5632, -7680, -4352, -5888, -7168, -5632, -5120, -5376, -5376, -4352, -7680, -3840, -3584, -5120, -2304, 768, 1536, 1280, -5120, 2560, 3328, -512, 2816, 2048, -256, 1792, 4096, 1280, 5632, 5888, 3328, 5632, 3328, 5632, 6400, 3840, 4096, 2816, 3840, 3328, 1792, 3072, 4864, 4608, 5120, 3072, 5888, 2816, 1536, 2560, 256, 2816, 4864, 1280, 5120, 0, 2816, 2816, 256, 3584, 3840, -768, -256, -1792, 1536, -1536, -2304, -2304, 1024, -768, -2560, -5120, -3584, -2304, -3584, -1792, -2560, -1280, -1024, -7424, -3584, -3072, -6656, -5376, -6912, -4608, -2560, -4864, -6912, -4608, -2048, -6400, -2048, -3328, -3840, -3584, -3840, 1280, -3328, -1792, -2816, -1024, -3072, 0, 3840, 1280, 1024, 256, 2816, 1536, 1024, 768, 1536, 5376, 4864, 2048, 3840, 3328, 1536, 3584, 4096, 4608, 4352, 5120, 3840, 2816, 3840, 6144, 3328, 2816, 4864, 1792, 4352, 3584, 1536, 4352, 1792, 1792, 1536, 1536, 1280, 2816, 0, 1536, 0, -1536, 1280, 256, -2816, -1536, -256, -2048, -2304, -3840, -1792, -1024, -4096, -4352, -3328, -3328, -4352, -3584, -3072, -3072, -7168, -3328, -4864, -6400, -7936, -6144, -4352, -4352, -4096, -1792, -3840, -3072, -2048, -3840, -2048, -4096, -2560, -1024, -256, -512, 768, 1280, 512, -512, 1280, 768, 1536, 2560, 2048, 2816, 3584, 3584, 3328, 3840, 5632, 4096, 3584, 4608, 3328, 4352, 4864, 4096, 2560, 4352, 2048, 4352, 3584, 768, 3584, 1792, 2560, 2560, 1792, 1536, 1536, -256, 1536, 256, 0, 3072, -1536, 1536, 3072, -1024, -1280, -1024, -512, -512, -256, -512, -2048, -2816, -2304, -2816, -2816, -4608, -1536, -1280, -4096, -2304, -3584, -2560, -3328, -2560, -2816, -3840, -3584, -3584, -3072, -4352, -4352, -4352, -1792, -2816, -3584, -3840, -3072, -1536, -3840, -1280, -3328, -2304, 0, 3072, -512, -512, 1536, 512, -1792, 1024, 2560, 512, 2304, 2048, 1792, 1024, 1280, 2816, 3840, 2816, 2560, 4608, 2304, 3328, 3328, 3328, 5376, 2816, 4608, 4864, 3328, 3584, 4096, 1536, 2048, 256, 4864, 2816, 2560, 2816, 256, 768, -256, -256, 1280, -2816, 1280, -256, -1280, -768, -3328, -2560, -1536, -1792, -1280, -3840, -2560, -2816, -4608, -2048, -4096, -5120, -4608, -2304, -3072, -4352, -5376, -5376, -3328, -5376, -2048, -2560, -2560, -1280, -4096, -1792, 512, -1536, -1536, -2304, -1792, -512, -2304, -1280, 1536, -1792, 256, 768, -256, 512, 256, 512, 2304, 2048, 1280, 3840, 3072, 256, 2816, 2304, 2048, 2560, 3840, 3584, 1280, 3328, 4352, 3584, 3840, 2560, 1792, 4096, 1280, 1280, 1280, 2048, 2304, 2560, 2560, 1792, 0, 1024, 1536, 2304, -2560, -1024, 1280, 512, -256, 0, -768, -1024, -1280, -2560, -1280, -2048, -2304, -2560, -768, -3328, -1536, -2304, -5120, -3840, -2816, -4608, -3584, -2560, -3072, -5120, -3584, -3584, -1792, -3072, -5376, -3584, -2304, -2048, -2816, -1280, -512, -1792, -1024, 1024, -512, -768, -256, 0, -256, 2048, 1536, 2304, 1792, 2560, 1536, 768, 1024, 1792, 2560, 2816, 1536, 2304, 4352, 2816, 2304, 1792, -512, 4096, 3328, 3072, 4608, 1280, 4096, 2304, 1024, 2304, 1536, 2048, 2304, 1024, 1024, 768, -512, -768, 512, -1536, -768, 256, -1792, -1536, -768, -1536, -3584, -2048, -2304, -1024, -3328, -2304, -2048, -4096, -2560, -3072, -3328, -2816, -1792, -2048, -3072, -2304, -2048, -1792, -2816, -1024, -2048, -1792, -2048, -768, -3328, -2560, -768, 1536, -1280, -1280, 0, -1280, -768, 1536, -512, -512, 1024, -512, 1536, 512, -512, 1280, 1280, -512, 1280, 3840, 3328, 1024, 1536, 1536, 3584, 2304, 1024, 2048, 1792, 768, 2816, 3072, 512, 2560, 1792, 2560, 2048, 1024, 1536, 512, 0, 768, 512, 1024, 512, -1536, -512, 512, -1024, 768, -1280, -1536, -1280, -1280, -1280, -1024, -2048, -1792, -1024, -1024, -1792, -2048, -1792, -3328, -2560, -2560, -2816, -2304, -2048, -2048, -1792, -2816, -1792, -768, -2304, -1536, -1792, -768, -1024, -1280, 768, -768, -256, -512, -1024, 256, 1024, 0, 768, 0, 1280, 512, 0, 1280, 1024, 256, 768, 256, 0, 256, 1792, 768, 0, 1024, 768, 1536, 1280, 0, 2304, 1280, 1792, 1536, 768, 1536, 512, 768, 1280, -1024, 2304, 0, 1024, 2560, 0, 1280, 256, -512, 1024, -768, -768, -512, 0, 512, -1792, 768, -2560, -256, -1536, -2304, -512, -1024, -2560, -768, -1792, -1536, -1024, -2560, -1536, -1536, -2816, -1536, 0, -1536, -2048, -1024, -256, -2304, -2560, 0, -1536, -1792, -512, -1792, 256, -1280, -1280, -256, 256, -1536, 512, 0, -768, -256, 1792, -1024, 0, 1792, 0, 2048, 512, 768, 1024, 1024, 512, 1280, -256, 1536, 1792, 1280, 1536, 1024, 512, 1024, 1536, 2048, 1536, 768, 256, 2048, 2304, 512, -256, 1024, 768, 1024, 768, -768, 1792, 1024, 768, -512, 512, -1024, -1536, -512, -1280, -512, -768, 0, -1280, -1536, -3328, -1280, -1536, -2816, -2304, -2560, -1280, -1024, -2304, -2304, -1792, -1792, -2048, -2048, -1536, -1280, -1792, -1280, -256, -768, -1024, -512, -512, 512, -768, 256, 512, -768, 256, 512, 256, 0, 256, 1280, 0, 512, 1280, 512, 0, 1024, 256, 1792, 768, 512, 1536, 0, 1280, 1792, 1280, 1280, 256, 768, 768, 1280, 2560, 768, 1024, 2048, 512, 1792, 768, -512, 768, 0, -256, -256, 256, 0, 256, -768, -512, -1280, -1024, -768, -256, -1792, -2048, -1024, -1024, -2560, -512, -2048, -2048, -2048, -2048, -2304, -1536, -2048, -2304, -1024, -512, -1792, -1280, -512, -1792, -1536, -2304, -512, 0, -1024, 1024, -1536, -768, -1024, -256, 512, 256, 512, 2304, 0, 768, 0, 1536, 1024, 0, 1280, 1536, 512, 1792, 1792, 1280, 1792, 1536, 2048, 1536, 1536, 1280, 1280, 256, 1536, 1280, -256, 768, 1024, -256, 1024, 256, 1024, 768, -1280, 0, 1024, 256, 1024, -512, -768, -1024, 0, -1024, -2048, -512, -1280, -1024, -2048, -1536, -1280, -768, -768, -1792, -2304, -1536, -2560, -2560, -1536, -1536, -1280, -1024, -1792, -1536, -1024, -2560, -768, -2560, 0, -512, -512, -1536, -256, 768, -768, -768, 256, 512, 256, 1024, 768, 1024, 768, 1024, 256, 512, 1536, 1280, 1280, 1280, 1792, 2304, 256, 1280, 1024, 1024, 1792, 512, 2304, 512, 1024, 2048, 512, 1280, 1536, 768, -512, -512, -256, -512, -256, 256, -512, -1024, 256, -1536, -512, -1280, -768, -1280, -1280, -1536, -1024, -768, -1024, -2560, -1024, -768, -2048, -1024, 0, -768, -1280, -1536, -1536, -768, -256, -1792, -768, 256, -256, -1024, -512, 256, -512, 0, -256, -512, 0, 0, 1280, -512, 0, 768, 768, 256, 1280, 512, 1024, 256, 1024, 256, 512, 768, 768, 768, 1024, 768, 768, 1280, 256, 1024, 512, 768, 256, 512, 0, 512, 256, -512, -512, -256, 0, -512, -256, -256, -768, -1280, -512, 0, -1280, -256, 0, -1280, -512, -512, -512, -768, -768, -256, -1024, -256, -512, -1024, -512, -256, -512, -256, 0, -768, -256, -256, 0, 256, -256, -256, 768, -1024, -512, -512, 1024, -512, -256, -256, -256, 0, 0, -256, -256, -256, -256, 512, 0, -256, 512, -256, 0, -256, 512, 0, 768, 1280, -512, 256, 512, 0, 1280, 0, -768, 1024, -768, 256, 512, 0, 1024, -256, -512, 256, 0, 0, 0, -256, 256, -512, 0, 256, 256, 0, -1280, 256, -512, -256, 0, -512, -768, -256, -768, 0, -512, -768, -1024, 256, -512, -768, -512, -512, -256, -256, -512, -256, -1024, -1280, 512, -1024, 0, 256, -256, 512, -512, -256, 0, 0, 256, -768, 768, 512, 0, -512, 512, 256, 512, -512, 1280, 768, -512, -512, -256, 256, 0, 0, 256, 768, 512, 0, 0, -256, -512, 256, 256, 512, 256, 256, -256, 0, -256, -256, -256, -768, 256, 256, 512, -512, -256, 0, 0, -512, 0, -256, -256, 512, -512, 256, -256, 0, 0, -256, -256, -512, 0, -256, 256, -256, -256, 512, -512, 0, -256, -256, 512, -256, 0, -768, -256, 0, 0, 0, -768, -768, -512, 0, 0, -256, -256, 0, -1024, 512, 0, -512, 0, 256, -768, -256, 512, 256, 0, -256, 0, 0, -256, 0, 512, -256, -256, 0, 0, -512, 256, 256, 0, 256, 0, 512, -768, -512, 512, -256, -256, 512, -512, 256, 256, 0, 0, 256, 256, 0, -1024, 768, -256, 512, 0, 512, -256, -512, 0, 256, 256, -256, -256, -256, -256, -256, -512, -512, -512, -512, -512, -256, -256, 256, 0, -1280, 0, -256, -256, -256, 256, -256, 256, -256, 256, 0, -512, 0, -512, 256, -256, 256, 0, -256, -512, 0, -256, 0, 0, 512, 0, 0, 0, 256, 0, 0, 512, 0, -256, 0, 0, 0, 512, -256, 256, 256, -256, -256, 0, 0, 256, 256, 0, 0, 0, 0, -256, 0, 0, -512, 0, 0, -256, 256, -512, -256, -256, -256, -512, -256, -512, 256, -256, 0, -512, -512, 256, -512, -256, 256, 0, 256, 256, -256, -256, 0, -256, 0, 0, 0, -512, 0, -256, 0, 0, -256, -512, -512, -512, 256, -256, 0, 0, -256, 256, 256, -512, -256, -512, -256, 256, -256, -256, -512, -512, 0, 0, 256, -256, -256, -256, -256, -512, 512, 0, 0, 256, 256, 256, -512, 0, -256, 0, -256, -256, 512, 0, -256, -256, -256, 256, -256, 512, 0, -256, 256, 256, 0, 256, 0, -256, -256, -256, -256, -768, 0, 0, -256, 256, 0, 0, -512, -512, -512, 0, -256, 0, 0, -256, 0, -256, -512, -256, -512, 0, -512, 0, 0, -256, -512, 256, -512, 0, -256, -512, 512, 0, -256, 512, -256, 256, -256, 0, 0, -256, 0, 0, 0, -256, 0, 256, 0, 0, 256, 0, -256, -256, 0, -512, -256, 0, 0, 256, 0, 0, 0, 0, -256, -256, 256, -256, -512, -256, 0, 0, -512, 0, -256, 0, 0, 0, 256, 0, 0, -256, 256, 0, -256, 0, 256, -256, 0, -256, -512, 0, -256, 0, -256, -256, -256, 0, -256, 0, 0, 0, -256, -256, 0, -512, 0, 0, 0, -512, -512, 0, -512, -256, -256, -256, -512, 0, -256, -256, -256, 0, 0, -256, -256, 0, 256, -256, -256, 0, -256, 0, 0, 256, 256, 0, 0, -256, 0, 0, 0, 0, 0, 256, -256, 0, 0, 0, 256, 0, 0, -256, 0, 0, -256, -256, 0, -256, -256, 0, -256, 0, -256, -256, 0, -512, -256, 0, -256, -256, -256, -256, 0, -256, 0, 0, 0, 0, -256, 256, 0, 0, 0, -256, -256, 0, -256, -256, 0, 0, 0, 0, 0, -256, -256, 0, -256, -256, 0, 0, -256, 0, -512, 0, -256, -256, -256, 0, -256, -256, 0, -256, 0, 0, 0, -512, -256, 0, -256, -256, 0, 256, -256, -256, 0, 0, 0, 0, -256, -256, -256, -256, 0, 256, 0, 0, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, -256, 0, 0, -256, 0, 0, -256, -256, -256, 0, 0, -256, -256, 0, -256, 0, 0, 0, -256, 0, -256, -256, 0, -512, -256, -256, -256, 0, -256, 0, -256, -256, 0, 0, -256, 0, -256, 0, -256, -256, -256, 0, -256, 0, -256, 0, 0, -256, 0, -256, 0, 0, -256, -256, 0, 0, 0, -256, 0, -256, 0, 256, -256, 0, 0, 0, 0, 0, -256, 0, 0, 0, -256, 0, 0, -256, -256, 0, 0, 0, -256, 0, 256, -256, -256, -256, 0, 0, -256, -256, -256, -256, 0, -256, 0, 0, 0, 0, 0, 0, -256, -256, 0, -256, -256, 0, -256, 0, -256, -256, -256, -256, 0, -256, -256, -256, -256, -256, -256, -256, 0, -256, 0, -256, 0, 0, -256, -256, 0, -256, 0, -256, 0, 0, -256, 0, -256, -256, -256, 0, -256, 0, 0, 0, 0, 0, -256, -256, 0, 0, 0, 0, 0, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, 0, -256, 0, -256, 0, 0, 0, -256, -256, 0, 0, -256, -256, -256, -256, -256, -256, -256, -256, -256, 0, 0, -256, -256, -256, 0, 0, 0, -256, 0, -256, -256, 0, -256, 0, 0, -256, -256, -256, -256, -256, 0, 0, -256, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, -256, 0, 0, 0, 0, -256, 0, 0, 0, 0, -256, 0, 0, 0, 0, -256, 0, 0, -256, 0, -256, 0, 0, -256, -256, -256, 0, -256, -256, 0, -256, -256, 0, 0, -256, -256, -256, -256, 0, -256, -256, 0, 0, -256, 0, 0, 0, -256, -256, 0, -256, -256, -256, 0, 0, -256, -256, -256, -256, -256, 0, -256, 0, 0, -256, -256, 0, 0, -256, 0, 0, -256, -256, -256, 0, -256, 0, 0, -256, -256, 0, 0, -256, -256, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, -256, 0, 0, 0, -256, 0, -256, 0, -256, -256, -256, -256, -256, -256, 0, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, 0, -1024, 2816, 1536, 4096, 2560, -4096, -12288, -11264, 512, 17152, 10752, -4352, -13056, 3840, 18176, 3072, -5632, -3584, -11264, -8960, 2816, 4352, -4608, 512, -3840, 4864, 3072, -256, -11264, -3840, 12800, 11520, -6400, -15616, 4352, 2560, -2560, 7936, 4608, -18432, -6912, 14592, 6656, -3328, -4352, -512, 1536, -256, -5888, -13824, 4352, 9984, 2048, 7680, 7168, -1536, -18176, -1280, 8448, 6912, -1280, 4352, 2560, -5888, -1536, 3072, -6656, -1536, -1792, -2304, -3584, 2816, 9472, 10496, 2048, -8448, -3584, 2048, -7936, -9728, 3328, 2304, 3840, 8960, 8448, 2816, 4352, -10496, -12288, -8448, 7424, 6400, 4096, -2304, -2304, -4352, -4864, -7424, 11008, 16384, -512, -14080, -10752, -256, -5376, -1024, 7424, 8704, -6400, -17152, -7424, 256, 13056, 12544, 6400, -1536, -3840, -12288, -19456, -768, 15360, 19968, 8448, 4864, 3328, -9728, -8960, -8960, -512, 15872, 4864, -1024, -3072, -1024, -1024, -8192, -7680, 2048, 17408, -11008, -16896, -7168, 14080, 13056, 5120, -7168, -7424, -4864, 5120, -512, 2048, 5376, -3840, -11008, 6144, 5632, -1792, -512, 8960, 3840, -512, -6144, -3072, 768, 7936, 3328, -3840, -5120, -4352, -4352, 6656, -6656, 6144, -768, 1792, 5376, 6656, -768, -4352, -6656, -12800, -6656, 8448, 14848, 12544, -5632, -17152, -4352, 6144, 1792, -14592, 1280, 10752, -2816, -768, 8192, -768, 1792, 3328, -2816, -2304, 6912, 4352, 256, -1280, -2304, -4608, -4864, -768, -5888, -1280, 1792, -2048, 2304, 3328, 3072, -1280, 1792, -9472, 5632, 6656, 5376, 6144, -5120, -8960, 5888, 6144, -8960, -3840, 11776, -9728, -12288, -3584, -1024, 0, -5632, 768, 11008, 9728, -256, -3584, -2048, -1280, -3584, 256, 5376, 5888, 7424, -4864, -12032, -10752, -12544, -2560, 16896, 19712, 12288, -7424, -8192, 256, -2816, 2048, 4352, -4352, 768, 11008, 8448, -5632, -4864, -10496, 7424, 5632, -10752, 2304, 16128, 7168, -5888, -15104, -16640, 1792, 13568, -5632, -2560, -6912, -7680, 9216, 12288, -1024, -1536, -5632, -4096, 2560, 3584, -1792, 5632, 12800, -1024, -6400, -10496, -14080, -15872, 5888, 17408, -4096, -7936, 12544, 14592, 5376, -9728, 3584, 3072, -11008, -12544, -4096, 7168, 1792, -3072, -12800, -4352, 12544, 16640, 4608, 256, -2048, 7168, 512, -6912, -3328, 3072, -2816, -13312, 1024, 7936, -8192, -9984, 3840, 2048, -4864, 1536, 6400, -256, -5888, 3328, 8704, 15104, 9216, -4096, -1280, -1792, -7168, -7680, 256, -3584, -10752, 2560, 11008, 6656, -6400, -9472, -15616, 256, 16128, 15872, 256, -9216, -6144, 9728, -1792, -6656, 6912, 2560, 1024, 512, -4864, -5632, -6912, -6144, 0, 8448, -2048, -14592, -3072, 15872, 19712, 13056, -2560, -10752, -6912, -7168, -7936, -768, 1280, 5376, 2560, 3840, -6912, -4608, -4608, -2560, 768, 4352, 4864, 4608, -4096, -5120, 6400, -768, -4864, -1280, 8192, 4352, -768, -8192, -2048, 512, -2816, -6144, -4352, -2816, 768, 10752, 3840, -3072, -512, 6656, 2304, -1024, -7680, -768, 4096, 1792, 3328, 8704, 10240, 29184, 2816, -26624, -18176, 1792, -3584, -8704, -6656, 8960, 11520, 12032, 1792, -1792, -4096, 2816, -1536, -7424, -8192, 256, 6144, 8192, 2560, 7424, -2560, -18944, -20480, -5120, 4608, 2304, 4608, 15616, 9728, -6912, -11264, 3328, 4096, -6656, 5120, 17664, 3584, -3584, -11776, -1792, -1536, -8960, 0, 2304, 1280, 14848, 18176, -9216, -19968, -3840, 11008, 8704, -15616, -25856, -6912, 11520, 6656, -2560, 5888, 17664, 17664, 1280, -18432, -15872, 4864, 4096, -9472, -15360, 9472, 15360, 2560, -12544, -2560, -512, -256, 11008, 11264, 2560, -12800, -1280, 4864, 2048, -11008, -14848, -4352, 8192, 7168, 1024, -256, -4608, -2560, 3328, 2048, 256, 256, 5632, -768, -1024, 2304, -2048, -2304, 4352, 768, -3840, -2048, 3584, 2816, -3584, -2816, -1280, 3328, -6144, -8704, -256, -4096, -1024, 8192, 8960, -8192, 2304, 5632, 3072, -6912, -4096, 3584, 3840, 0, -512, -3072, -7936, -6144, 3584, 12288, 2560, -3584, -1792, -5632, 1024, -2048, -3584, 4864, 5376, -5376, -6400, -3072, 4864, 6144, 4864, 6912, -768, -3840, -4096, 2560, 5376, -3584, 768, 2048, 768, -2816, -8448, -4096, 1792, 1280, -2048, 512, -768, 3072, 1280, -8704, -4864, -1536, 6656, 4864, 0, -1024, -3072, 1280, 3072, 5120, 4096, 4864, 4608, -3328, -10752, -6656, -256, 0, -4608, -4096, 2560, 6912, 5888, -1280, -1792, 2304, -2048, 1792, 5632, 2560, -7168, -13056, -6656, 3328, 11264, 4352, 4096, 6400, 3584, -8192, -11520, -9216, -10240, -768, 5632, 10496, 8704, -3072, -8960, -7936, 4608, 768, 7936, 7168, 1024, -5376, 512, -3584, -6144, -5888, 4864, -1536, -1792, -2560, -256, -3328, -3328, 5376, 13312, 7168, 1792, 256, -6400, -9216, 512, 8704, 2560, -9472, -7936, -3328, 4864, 2816, -1024, -5120, 3840, -1280, -4608, 10240, -3328, 3840, -9216, 3584, 4608, 4352, -5376, 1536, -9984, 5376, 1792, -6656, 2048, -8448, 6144, 7680, 8192, -2816, -6656, -12032, -9984, 15872, 2560, 2816, 1280, -4352, -5376, 2560, 0, 4608, 3840, -5632, 1792, 3328, 3584, -2048, -2304, 7680, 8448, -8704, -10496, -8192, 9472, 6144, -4864, -3840, 256, 512, 2560, 2560, -6912, -11776, -3584, -2304, 2304, 12032, 256, -5632, -4608, 1280, 9472, 7424, -768, -4864, -4864, -4608, 2048, 4352, 256, -2816, -1536, -5120, 6912, 9472, -512, -7168, -8704, -768, 5632, 13824, 8704, -7936, -11008, -7168, -7680, -8448, 6656, 12544, 11520, 11008, -3840, -14848, -3328, -512, -6912, -1792, 10496, 2816, 4864, -12800, -18944, -7168, 7936, 19200, 9984, -11520, -1792, 25344, 11264, -21248, -12032, 11520, -256, -7680, 5888, 7424, -14080, -7680, 7936, 7168, -4864, 512, -11264, -11776, -12544, 7680, 5632, 14848, 7936, -12800, -5120, 2304, -9728, -13568, 12544, 9472, -2304, 3328, -6400, -4608, 4608, -6912, -1792, 4352, 768, 6144, 14592, 6656, -13056, -13312, -13824, -11008, 13568, 21760, 7936, -9216, -11264, 1792, 3328, 4864, -5888, -8448, 9216, 12032, -9728, -2816, 9472, -4864, -1536, 4608, 4352, 512, 7936, 13824, -7424, -18432, -20480, -256, 6912, 13312, 2560, -7424, -10240, -12288, -18432, 6144, 27648, 16896, -11264, -19456, -8192, -6144, 5376, 17664, 13824, 6144, -512, -2048, -7168, -11264, -12800, 8704, 24320, 11520, -10240, -18432, -8192, 1536, 7168, -256, 4608, -1792, 6912, 256, -3584, 5376, -2048, -13056, -15872, -6144, 16384, 14336, 3072, 4864, -9216, -5632, 2560, 5120, -2560, -256, -1280, -13056, 9216, 18432, -10752, -13056, 17920, 11520, -12288, -6912, 13824, 4864, -11776, 2048, 0, -11776, 2560, 9472, 8960, -5376, -8192, -5632, -11264, -20992, -8448, 15104, 26880, 12288, -8192, -9216, -7936, 4608, 15360, -3072, -12544, 2560, 22784, 7168, 3072, 2048, -11520, -5376, -1536, -4096, -8192, -4352, -4608, 768, 7424, -768, 0, -5120, -13056, -7936, 6144, 13312, 256, -4352, -5120, 256, 8960, 3840, 1280, 8960, 6912, 4608, -4864, 2048, -18176, -18944, -2048, 22528, 14592, -11520, -9472, 4352, 13056, -256, -3328, -1024, 768, -3328, -6144, -1792, 7680, -1792, -6400, -256, 4096, -2048, -11008, -17920, 2816, 21760, 19712, 3072, -15872, -14592, 8960, 13568, -8448, -24576, 2048, 20992, 5376, -9728, 6400, 9984, -256, -6912, -3584, 4608, -4096, -11520, -6144, 10752, 1792, -2304, 5632, 8192, -9984, -1280, -2048, -12544, -4352, 15360, 22528, 5376, -23808, -5120, 20992, 7936, -6656, -16128, -4352, 13312, -7168, -6400, 3328, -512, -8192, -11776, 14080, 14336, -9472, 1536, -14592, -8448, 16640, 16128, 1280, -6400, -7936, 17664, 22016, -8192, -8704, -14336, -5888, -12032, 3584, 11264, -5888, 4864, 1536, 15360, -6912, -17664, -9472, 5120, -3584, -1280, 12800, 11264, 3840, 3328, -5888, -15360, -11776, 5888, 10240, -1280, -6400, 1536, 11776, -1024, -2560, -6912, -3072, 7168, 11520, 2560, -3328, -8448, -4864, -9984, 10752, 8192, -5888, -6400, 6144, -4352, 3328, 6400, 3328, -8192, 3328, 12288, 1024, -23808, -1280, 10240, -1792, 9472, -9984, -9472, 10496, 256, -3328, -8448, 11008, -13568, 27136, 2048, -14592, -23808, 14080, 10240, 14336, -6144, -1024, -4864, 1792, -5888, -16640, -4608, 8704, -7680, 1792, 16896, 23552, 768, -11008, -9472, -5888, 3072, -1792, -4352, 3584, -3840, -2304, -4608, 4608, 13056, -256, -14592, -4352, 5888, 4864, 3840, -10240, -256, 0, -2048, 9984, -3328, -11008, 18432, 14592, -256, -13824, -4352, 8192, -4864, 2816, 0, 9216, 6400, -5888, -22016, 5376, -768, 3584, -4352, 19456, 9472, 5888, 512, -5888, -13824, -10752, -20480, 15616, 15360, 16128, -3072, -14592, -11264, 3840, 8960, 6656, 2816, -11264, -5632, 2048, 8448, -6144, -4352, 5376, 9728, -6400, -9984, 4096, 11008, -9216, -7168, 13824, 2560, -13312, -4608, -8704, -3584, 19456, 15360, 6144, -8192, -4864, 4096, -3328, -17408, -1280, 7680, -3328, -5888, -3584, 15616, 6144, 8960, 9984, 1024, -12800, -14848, -9984, 0, 11008, 11008, 5376, 6144, -5120, -11776, -9216, 9728, 2048, -17152, -2048, 15616, 9728, 2560, -3072, 1280, -1024, -4096, -12032, -1280, -4608, -5120, 9472, 10496, 6144, 1024, 1792, -4864, 2816, -13312, 0, 4352, 5120, -7680, -8448, -4096, 15360, 8704, -3840, -11776, -19712, 3584, 7424, 6656, 5376, 6400, 2048, 1792, 9216, 5888, -9984, -4096, 5376, 2816, -5888, 2816, -1024, -1536, -8960, 3328, -2048, -12544, -4352, 11264, 4864, -6400, -4352, 2304, -1280, -1280, -256, -7936, 2816, 3840, 4352, -2048, -7936, -13056, 3072, 13824, 21760, 8192, 1024, -14848, -8960, -7936, 0, 2560, 5376, -5120, -5120, -7424, 3840, 6656, -1792, 2048, 1024, 0, 7680, 512, -6656, 512, 4864, 3840, -4608, -3328, -5120, -4864, 12032, 8448, -1536, -13056, -7680, -3072, 3072, 7680, 8704, 7936, 1024, -11520, -20736, -1792, -5632, 256, 18688, 25088, 6144, -17152, -3328, 4864, -8192, -22016, 1536, 24064, 1024, -12032, 5376, -2816, -12800, 5632, -768, -512, 12800, 5120, -9472, -15104, 8960, 7168, -4096, -9216, -7680, -2816, 1024, 17664, 25088, -16640, -21504, 18688, 6912, -23040, -4352, 21504, 2560, -13056, -3584, 10240, -6144, -2816, 4096, -8704, -6656, 9728, -11008, -8704, 14848, 21760, -8448, -13056, 4352, 1792, 1024, 13312, 6400, -8960, 0, 11264, -5376, -12032, 10240, 11264, -17664, -16640, 9472, 8960, -5376, 1024, 8192, -15360, -19200, 5376, 16384, 15360, -1536, -2816, 1536, 512, -10496, -8704, 4864, 7936, 2304, 1792, -256, 2816, 1536, -2816, -6656, -5888, 4096, 8960, -9984, -17408, 1536, 14336, -768, -10752, 7424, 7168, 768, 7168, 3584, -9472, -4096, 2816, -2048, -4608, 3840, -256, -2048, 11008, -5120, -17152, -3072, 8704, 1792, -3072, -2304, 1280, -1024, 1792, -3072, 6912, -768, -17408, 6656, 24576, 7680, -8448, -7168, -6400, 4864, 6912, -8448, -12288, -768, 9472, -256, -8960, -2816, 1280, 10752, 9216, 1536, -12288, -9728, 6656, 13824, -5888, -10496, 13312, 11264, -8192, -5632, 7168, -5888, -8192, 3072, 10496, -4096, -1536, -1536, -4352, -4608, -3584, -3072, -1280, 4608, 13312, 11520, -2560, -4096, 7424, 2816, -9216, -6656, 1792, 9216, 3072, -14592, -12288, 12288, 17920, 4096, 5376, -3328, -11776, -8448, -15872, -16128, -5376, 24064, 24064, 5120, -28160, -12032, 10496, 17152, -4096, -14592, -10240, 21760, 18176, 1792, -9984, 3840, -7424, -12800, -10496, 4608, -10240, -10752, 9728, 17664, 5376, -2048, -14848, -4864, 5888, 6144, -5120, -2560, 2816, 10496, 1792, -1536, -7680, -5888, 512, 4096, 14592, 9728, -2816, -12800, 9216, -4096, -13056, -13056, 20736, 6144, -17408, -21504, 9984, 28672, 15872, -20224, -26624, 6144, 26112, 3840, -9728, 5120, 5632, -12544, -23296, 3840, 13056, 7680, -256, -3840, -7680, -3072, 4352, 10752, -4352, -12288, 0, 12544, 8960, 512, -4864, -4096, -7680, 2304, 4352, -3072, -1024, -3840, 1280, 8704, -256, -14336, -16384, 1792, 12288, 13824, -4096, -13056, 5120, 15872, -4352, -6912, -2304, -2560, -7424, -256, 8960, 11264, -5120, -5888, -512, -3072, -1024, 7936, 6144, -6144, -3584, 512, -7168, -6912, 12544, 15616, -13824, -15616, 1536, 5888, -5120, 512, 10496, 6656, 512, 3840, -1280, 1536, -4096, -9216, -4096, 512, -13824, -13568, -4608, 15872, 16384, 2560, -768, 23296, 9984, -13824, -26368, -1280, 4096, -7936, -7168, 19200, 26880, -8192, -29184, -13312, 17408, 8192, -13312, -4864, 6400, 13824, 15616, 3584, -10240, 3072, 256, -14336, -7936, 18944, 10240, -18688, -16896, 0, 12544, 9216, 6144, -5120, 0, 3328, -10240, -25344, -2816, 14080, 7936, -8448, 9984, 6144, 768, -4608, 1792, 2560, 1024, -7424, 4352, 4864, 6912, -7680, -10496, 2304, 8448, -6144, -6400, 7680, 7168, -8704, -14592, 2048, -1792, -11776, 1280, 12288, -5632, -1536, 14592, 14848, -7936, -18432, -512, 18432, 11264, -13568, -10752, 10496, 256, -13824, 7680, 13824, -1536, -20224, -3584, 8448, -1536, -5632, 3584, 2560, -1280, -2048, 3328, 5888, 5376, -12032, -18944, 5632, 6144, -2560, -1792, 9984, 512, 3072, -1792, -512, 1024, 8448, -5120, -8448, 4608, 5632, -22528, -18176, 6656, 20736, 3584, -9472, 768, -6144, 1536, -2048, 2816, 10240, 4608, -1792, -4352, 5120, -2048, -3840, -10496, -2816, 6912, 13312, -6912, -11776, 8448, 5376, 11776, -7680, -3328, 6656, -23296, -27136, -12032, 13824, 27904, 17152, -22272, -23040, 9728, 23552, 7936, -2560, -17664, -18688, -6912, -1536, 6144, -1536, 5120, 7680, 11520, 8448, -3328, -6400, 2560, 14592, -4096, -8192, 0, -3584, -14080, -5120, 1024, 1792, -1024, 768, 4608, -2816, 8704, 2816, -11520, -11520, -32000, -9728, -512, 4864, 18432, 20992, 25344, 25088, 8960, -13056, -20736, -13568, 768, -9984, 5888, -1024, -14848, -16128, -6144, 10240, 21504, 12288, -1792, -4608, -512, -2048, -5120, -2560, 768, 5376, 4352, -9984, -16896, -5120, -512, 9472, 7680, 9984, 8704, -1280, -10496, -6656, 8448, 10240, 4608, -512, 2816, 3328, -5120, -15360, -5376, 8448, -6400, -8960, 7680, 16640, 5632, 3328, -3840, 512, 4096, 2816, -17408, -4608, 18944, 2560, -18944, -8704, -9984, -4352, 2048, 15104, 9984, -5632, -9728, -2048, 2304, 7680, 5888, 2816, -768, -3072, 2560, -256, 15104, 2304, -7168, -18432, -6912, 8192, 17408, -2816, -768, 6912, 1024, -8448, -9984, 1792, -256, -1280, -1792, 6656, -3584, -6656, -10240, -3072, 1280, 1280, 256, -3072, 16384, 16128, -10496, -14336, 2560, 6656, 10240, -6656, -11264, -10752, 6400, -1536, 768, -256, 2560, 2304, -256, 2304, 256, -7168, 2560, 6144, 6656, -8448, -9216, 11776, 5120, -11008, -13312, -8960, 5632, 13568, 7680, -1536, 4608, -4096, -12544, -9216, 11520, 2560, 5376, 1792, 2304, -8448, -12800, 5376, 18688, 8448, -10752, -11776, 10752, -3072, -4608, 1280, -12800, -6400, 17408, 14080, -7936, -20224, -1792, 19712, 6400, -1536, 7424, 19968, 6144, -22272, -10496, -7680, -10496, -5888, 19200, 8960, -8192, -16640, -1792, -3328, 768, 10496, 8704, -6144, -8448, 6400, 3584, -13312, -7168, 4864, 19456, 11520, -11520, -12032, -1280, 6144, 2304, -3584, -10496, -1280, 12544, 5632, 2560, -7936, -8960, -256, -1536, 768, 2560, -256, -3072, -5120, -13056, 2304, 20224, 13568, -9216, -9728, -3328, -3584, -3840, 12800, 12800, -9216, -8448, 0, 1280, 5632, 5888, 6144, -13056, -20736, -6912, 14336, 10752, -2560, -4096, 0, 0, -1280, 4096, 3072, -4864, 2816, 2560, -3840, -256, -8192, -4352, 256, 2816, 15872, -4096, -5376, 2304, 5376, -7424, -12800, 4096, 20992, 4352, -8960, -1024, 2816, 768, 2048, 2048, -2304, -3328, 2560, -9984, -16128, -4864, 13824, 14848, -4096, -6400, 4608, 9728, -2048, -12800, -13824, -4352, 4608, 12032, 4352, -8448, -11520, 0, 13312, 14592, -1280, -8704, -4352, 8192, 2560, -7168, -2560, -5376, -768, -2304, -5120, 5120, 12032, 5632, 1280, -1024, -3840, -9472, -5632, -7168, 2304, 9472, -4608, -3328, 768, 3840, -8448, -12032, 5120, 18688, 0, -9216, 8448, 15360, -2816, -19712, -3328, 10752, 3328, -5120, 2304, 12032, 5632, -6912, 7424, 1536, -18176, -19968, -5120, 5376, 1024, 6912, 5888, 4864, 7936, 11520, -7424, -13824, -2560, 9472, -19968, -11776, -3584, 17152, 27648, 14592, 3072, -15872, -27648, -3840, 29696, 14336, -14848, -28160, -8448, 8448, 7680, -9984, -6656, 2816, 7424, 5632, 2048, 13312, 19456, 7936, 0, -7936, -12800, -2560, 15104, 13824, -3328, -21504, -16640, -15360, 0, 8960, 26880, 15616, -7680, -29952, -15872, 8960, 22528, 14592, 12288, -9728, -21760, 10496, 3072, -5376, -1536, 1792, 3840, 18688, -7680, -18432, -9472, 6400, 0, -1280, 16640, 19456, -23040, -19968, 6144, 12032, 512, -3584, 10240, 21248, 0, -8192, -11776, -15872, -6656, 12800, 9472, -1024, -11264, -10240, 14080, 7936, -9728, -3328, -4352, -7680, -1024, 1792, 17408, 9984, 256, -5888, -9728, -7680, 1536, -8960, 3584, 13312, -2304, -15872, -12032, 11520, 11264, 2816, -4352, -2304, 1536, 4096, 8704, -768, -8192, -5376, -8448, -768, 5376, 6656, -9984, 2816, 16640, 8448, 4864, -256, -12544, -21760, -24832, 16896, 14848, -23808, -3840, 3840, 1280, 20736, 19456, 7424, -512, -13312, -13056, -7680, 16640, 9728, -11520, -3584, 256, 7168, 5632, 11008, 4864, -15104, -27904, -7424, 7424, -3584, -5632, -10496, 0, 13824, 19456, 4096, 2048, 5888, 3840, -12032, -9984, -2048, 1280, 9216, -1536, -768, -1024, 3328, 3328, 5376, -12032, -13568, -1536, -2304, -6912, -11264, 2048, 22016, 16384, 3072, -1280, -8192, -2560, -5120, -6912, -5888, 2048, 7680, 256, 4096, 10752, -8960, -2048, 1024, -9984, -2816, -15872, -7424, 27648, 22272, -5120, -26624, -4608, -14080, 2048, 12032, -4096, 7424, 9728, 1024, -11264, -9984, -5120, 9728, -3328, 5888, 20992, 7680, -17152, -23808, 6656, 20224, 5120, -20224, -18944, -5888, 8448, 15104, 20480, 9984, -10752, -25600, 0, 4864, 9728, 2304, -14080, 2304, -3840, 5632, 17408, -4352, -14080, -5888, 256, 22272, 4864, -14336, -15360, 8192, 9472, 9728, -17152, -8448, -256, 7936, 6144, 3840, -7680, -1280, -9216, -7424, -6912, 2048, 6912, -2304, 3072, 7424, 9728, 8448, 0, -9984, -4608, 1536, 4864, 4608, 2048, 256, -8448, 2304, -256, 512, -7424, -16896, 0, 10496, 1536, -12800, -3328, 2304, 18688, -7168, -12032, -5376, 7680, 17408, 7936, 8192, 7424, -11776, -3584, 3328, -11264, -19200, -768, 15872, 14080, 2304, -12544, -256, 13824, 4864, -1536, 1792, 4096, 9728, 3328, -6656, -14080, -19456, -5888, 4096, 5376, -8448, -5632, 4096, 15616, 6400, -3584, -8960, 3072, 5888, -1792, -4352, -8192, -2560, -4096, -256, 1792, 4608, -256, 4864, -512, -256, 5376, -3584, 256, -11264, -11264, -5888, -7424, -256, 7168, -7168, 12032, 16384, 3072, -1024, -3840, -9472, -1792, 6144, 12800, 1536, -3840, -6656, -1280, 5120, 3072, -6400, -5376, -512, -4608, -5888, 2304, 4096, 6144, 9216, -7680, -8960, -3072, 8192, 4864, -3328, 4864, -1536, 512, -512, -5632, -2816, 3584, 12800, 2560, -5376, -14080, -3584, 5888, 1536, 1536, -1536, -6656, -6400, -2048, 6400, 3584, 6144, 3584, -3328, 4608, 2816, 5888, -8704, -12544, -11520, 1536, 9984, 9472, 768, 0, -7424, 2048, 6656, -1536, -1792, -5376, 512, -2816, 1536, 4096, -256, -4352, 1536, 8192, -1024, -13824, -2304, 5632, -3584, 1536, 6912, -256, -512, 8704, 8448, 2048, 256, -2048, -3584, -8192, 5888, -5632, -5888, -7424, -3072, 1280, 6400, 5632, -1024, 3584, 1280, 6144, -9984, -7424, 4352, -5376, -20480, -15360, -2304, 19968, 25344, 20736, -10496, -13568, 5632, 2816, -17664, -5632, -512, 17920, 20480, 4608, -14336, -13824, -20224, -6912, 14336, 11776, 7168, -256, 3072, -9472, -19456, 5888, 16384, -1024, -1280, 1024, 0, -512, -1280, 2560, -1024, -2304, 1280, 768, 768, -512, 1536, -512, -256, 0, 512, 0, 256, -512, 512, -768, -512, 0, 256, -256, 0, 0, -256, -256, -256, 0, -256, -256, -256, -256, 0, 0, -256, 0, -256, -256, -256, -256, -256, -256, 0, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, -512, -768, -1280, -1536, -1280, -1280, -768, 0, -256, -768, -256, 1792, 4096, 5120, 2048, -2048, -6144, -8960, -9984, -9216, -8960, -10752, -12032, -8960, -3584, 0, 2048, 4352, 7168, 11520, 15360, 16640, 16384, 16896, 17152, 15360, 12800, 9984, 6656, 3584, 1280, -3584, -10240, -13824, -14336, -14336, -14080, -12032, -9216, -5120, 256, 3328, 3840, 4096, 3072, 512, -2560, -5120, -8448, -11008, -10752, -9728, -11008, -10240, -7168, -4352, -1792, 1536, 5376, 8704, 12288, 15360, 16128, 16384, 16896, 15616, 13824, 13056, 10496, 5888, 2560, 256, -4608, -9472, -11776, -13824, -16128, -15360, -11776, -7680, -3328, 1280, 3840, 4096, 4352, 2816, -512, -2816, -5376, -8704, -11264, -11520, -11008, -10752, -8448, -5376, -4352, -2560, 1280, 5888, 9984, 13824, 15872, 15616, 15872, 16128, 15104, 13568, 12032, 9728, 5888, 2560, -1280, -5888, -9216, -10752, -13056, -15616, -15616, -12288, -6656, -512, 3584, 4096, 3328, 3328, 2304, -256, -3584, -6912, -9216, -10752, -11264, -12288, -11264, -7936, -4352, -2560, -2048, 256, 5376, 12032, 16640, 17152, 14848, 13824, 14848, 15616, 13824, 10496, 7936, 5888, 2816, -2304, -7680, -10496, -11264, -11520, -13824, -15616, -13312, -5376, 2816, 6400, 4864, 2048, 1024, 1792, 512, -3840, -8448, -9984, -9984, -11264, -13056, -12288, -8704, -3072, -512, -1024, -512, 4864, 13824, 18944, 18432, 14848, 12032, 13056, 15104, 13824, 10240, 6656, 5120, 1792, -4096, -9472, -11776, -11264, -10752, -13056, -14848, -12032, -3840, 4864, 7936, 6400, 2304, -256, -256, -1024, -3840, -7680, -9472, -10496, -13056, -14080, -12288, -7168, -2816, -1024, -512, 1536, 7168, 14848, 18688, 18944, 16128, 12800, 11520, 11776, 12544, 10752, 7936, 4864, -1536, -7680, -11008, -11264, -10752, -13056, -13824, -12544, -8448, -768, 4608, 7680, 7936, 4352, 512, -3328, -3840, -3840, -6400, -7936, -11520, -15872, -15360, -11520, -6144, -4096, -2560, 1536, 5120, 10240, 14848, 17408, 18944, 17664, 14080, 10496, 9472, 11264, 11008, 8704, 3840, -4352, -10496, -12288, -11776, -13056, -15104, -13056, -8704, -4096, 768, 4352, 7424, 8448, 5888, 512, -3840, -4608, -4608, -5632, -7936, -12800, -16384, -15616, -10752, -7680, -6144, -2048, 3328, 8960, 12800, 14592, 16640, 17920, 17920, 14848, 10752, 10240, 10496, 10240, 8192, 1536, -5888, -11520, -13568, -14080, -16384, -15360, -11520, -6144, -256, 2560, 4864, 6912, 7168, 5888, 1024, -2304, -4352, -5632, -5888, -9216, -13568, -15616, -15360, -12032, -9216, -5632, -768, 4864, 11264, 14336, 15360, 16640, 16640, 16640, 15360, 13312, 11520, 9984, 9472, 5888, -512, -6656, -12544, -16128, -16896, -16128, -14080, -10752, -4096, 768, 3584, 6400, 6400, 5632, 4864, 2816, -512, -4352, -5120, -7424, -11264, -12800, -14848, -16384, -13568, -8192, -3328, 0, 6400, 11520, 13568, 16640, 17408, 15616, 15360, 16128, 15360, 12032, 10752, 8448, 1792, -2560, -6656, -14336, -18688, -17408, -14592, -13568, -9472, -3072, -256, 3584, 8192, 6656, 4096, 4352, 4096, 256, -3072, -4864, -9728, -13312, -12032, -14080, -16640, -12800, -5888, -2304, 1024, 6912, 10240, 12288, 17408, 18432, 15104, 14848, 17152, 16384, 13312, 10752, 5376, -1280, -4096, -7936, -15360, -18688, -15872, -13824, -12544, -8704, -4352, -1024, 4352, 8192, 6144, 3328, 4608, 5120, 1536, -2816, -7424, -11776, -12288, -11776, -13824, -15104, -10496, -4352, -1280, 1536, 5120, 8960, 13824, 18176, 17408, 14080, 15360, 18944, 18176, 13568, 6912, 1280, -1536, -4096, -8960, -15872, -17920, -14592, -12544, -11520, -10240, -6400, 1024, 6400, 7424, 3840, 1792, 5888, 6912, 2560, -5120, -11776, -12032, -10496, -9984, -12032, -14080, -8704, -2816, -256, 1024, 2816, 9728, 17152, 18432, 15872, 12288, 15616, 21248, 19456, 12544, 2304, -2304, -1792, -3840, -7936, -15104, -17920, -14080, -12288, -11776, -11008, -5376, 4096, 7424, 5632, 1536, 256, 6400, 8192, 2560, -7168, -14592, -12032, -8704, -7680, -9728, -12544, -8448, -3072, -1024, 768, 4352, 12800, 18432, 17408, 14080, 11264, 15616, 22016, 19712, 10496, -512, -4096, -2560, -3328, -7168, -14336, -17664, -14848, -13312, -12032, -8960, -1792, 5632, 6400, 3328, -1024, -512, 6400, 8448, 1792, -8960, -14848, -11776, -7424, -5632, -8192, -11264, -8704, -4096, -1280, 2048, 7680, 15104, 18432, 16640, 11776, 9984, 15872, 22272, 19456, 8448, -2048, -5120, -3328, -2560, -7168, -14592, -17920, -15872, -13056, -10752, -6144, 768, 5888, 5888, 1024, -3840, -1024, 6400, 8704, 768, -9728, -14080, -11520, -5888, -4352, -8192, -11008, -8704, -3840, -256, 3584, 10496, 16384, 18688, 15104, 8960, 8960, 16384, 22784, 18688, 6656, -2816, -5888, -3584, -2816, -8448, -15360, -17664, -15104, -12288, -9984, -3584, 2816, 6400, 4352, -2816, -6144, -768, 7680, 8960, -768, -10240, -13824, -10496, -4608, -4864, -9216, -10496, -7168, -2560, 0, 5376, 13056, 17920, 18176, 12032, 6144, 9216, 18432, 23808, 16640, 4352, -3584, -5632, -3328, -4352, -11008, -15872, -16128, -13312, -12288, -9216, -1280, 4864, 6656, 1280, -6656, -6912, 1280, 10240, 7936, -3072, -10752, -12800, -8704, -5120, -7168, -9472, -8448, -4352, -2048, -256, 7424, 15616, 19200, 16384, 7936, 4864, 11264, 21760, 23808, 13056, 2304, -3840, -4608, -4096, -7680, -12800, -14592, -13312, -12288, -13312, -8192, 768, 6400, 5120, -2560, -8704, -5376, 4864, 10752, 5120, -4352, -10240, -11008, -8960, -7680, -8192, -8192, -5376, -3072, -3072, 768, 9472, 17152, 18432, 12800, 6400, 6144, 14592, 23552, 20736, 10752, 1536, -3072, -4608, -6400, -9984, -13568, -13312, -11264, -12544, -13056, -7168, 1536, 6400, 3328, -4352, -8192, -2816, 7424, 9984, 2048, -6144, -9728, -9472, -8448, -9216, -9984, -7680, -2560, -768, -2304, 768, 9728, 17408, 18176, 11776, 5888, 8192, 17408, 23552, 18176, 7936, 1280, -1792, -4096, -7936, -12800, -14080, -11520, -9472, -12544, -13568, -6912, 2048, 5888, 2048, -5120, -6144, 768, 8704, 7168, -1536, -7168, -8192, -7680, -8960, -11776, -11008, -5888, 0, 0, -2560, 1280, 10496, 17152, 16640, 10752, 7680, 12032, 19712, 21248, 13312, 5888, 2560, 512, -4096, -11008, -15360, -14080, -9728, -9216, -13568, -13568, -6400, 2048, 4864, 768, -3584, -2048, 4352, 7424, 2304, -4352, -6144, -5632, -6656, -11008, -13568, -10752, -3584, 1024, -768, -2304, 2560, 11264, 16128, 14848, 11008, 11008, 16128, 19712, 16384, 9728, 6144, 5120, 1792, -5888, -13312, -15872, -12544, -9728, -11520, -14592, -12544, -4864, 1536, 2816, 512, -256, 3072, 5632, 3328, -1792, -4608, -3840, -4352, -8192, -12800, -13312, -8192, -2816, -1024, -2048, -768, 5376, 11264, 14080, 13568, 13312, 16128, 17920, 16384, 12544, 8960, 8704, 6144, 0, -7424, -13568, -13824, -12800, -13056, -14336, -14592, -9472, -4352, -512, 1792, 2304, 5120, 5376, 3072, 256, -3328, -2816, -3328, -6144, -9216, -12544, -10240, -7680, -5632, -3072, -2304, 2560, 6400, 9728, 13056, 14592, 17920, 18176, 15872, 14592, 11264, 10752, 8704, 3840, -1024, -7680, -10752, -13568, -16640, -15616, -15616, -12544, -8960, -5632, -512, 2560, 6400, 6912, 3840, 2816, -256, -2048, -3584, -5632, -6912, -9472, -9472, -9472, -10240, -6656, -3584, -512, 2560, 6144, 10752, 13824, 17408, 18688, 16640, 16640, 15360, 12544, 9216, 6912, 3840, -1792, -6400, -11008, -16128, -17664, -16640, -15616, -13824, -9216, -3328, 768, 4608, 6656, 5888, 5120, 4096, 256, -4096, -5376, -5120, -7936, -9472, -9728, -10240, -9728, -6400, -3840, -1792, 2816, 8704, 12288, 14336, 16896, 18176, 18432, 18688, 15616, 11008, 8704, 7424, 2816, -3584, -7936, -11776, -16128, -17664, -18432, -17664, -13568, -7168, -1792, 768, 4096, 6912, 7680, 7168, 3840, -768, -3584, -4864, -6400, -9984, -10752, -9472, -9728, -8960, -7680, -4864, -512, 4608, 9984, 12032, 14336, 17664, 19200, 19968, 18176, 15360, 12544, 8960, 5632, -256, -5120, -8192, -12800, -16640, -19456, -19200, -16128, -12544, -6912, -2304, 1536, 5632, 7168, 7936, 6912, 4096, 1536, -3328, -6656, -9216, -11008, -10496, -10752, -10752, -9216, -6912, -2560, 512, 4608, 9728, 13312, 16384, 17920, 18688, 20224, 19456, 17920, 12800, 6912, 2816, -1280, -5376, -10496, -15872, -17664, -18432, -17408, -15616, -12800, -6656, -1024, 3328, 5376, 5888, 8192, 8960, 6912, 1536, -5376, -8448, -9472, -10752, -12288, -13568, -11520, -7936, -4864, -2048, 768, 5888, 11520, 15104, 16640, 16640, 18688, 22528, 22528, 17664, 10240, 4864, 2560, -1536, -7680, -13824, -17664, -17664, -17408, -17152, -15104, -11008, -4608, 512, 2560, 3840, 5632, 9984, 11776, 6912, -768, -7168, -8704, -9472, -12288, -14336, -15360, -12288, -7424, -4096, -256, 3584, 8960, 13312, 14848, 15360, 16384, 20480, 24576, 22528, 16384, 8704, 4096, 1536, -2816, -9216, -15872, -19712, -19200, -17408, -14848, -12032, -8448, -3584, -256, 1792, 3840, 7168, 11008, 11264, 6144, -1536, -7680, -9728, -10240, -12544, -16128, -17408, -14336, -7680, -1280, 3840, 6912, 10240, 13056, 15104, 16128, 18432, 21504, 23296, 21248, 15360, 8192, 3072, 256, -3584, -11520, -18688, -21504, -19968, -15872, -11776, -9216, -7168, -4352, 0, 2816, 5120, 7936, 9728, 8960, 5120, -1536, -7168, -10240, -11776, -14848, -18432, -18176, -13312, -6656, 1024, 6656, 9472, 11520, 13824, 16384, 17664, 18944, 20736, 20480, 18688, 15104, 8960, 3328, -1280, -7168, -13824, -19200, -20224, -18944, -16128, -11008, -7680, -5376, -2816, 0, 3584, 5888, 7424, 8448, 5888, 3584, -512, -6400, -10496, -14848, -17664, -18176, -16384, -11008, -6144, 768, 8448, 12032, 14336, 15360, 16384, 18688, 18944, 19200, 18688, 15872, 14336, 9728, 3328, -3072, -10752, -14592, -17664, -19712, -18176, -16128, -11264, -6400, -3840, -768, 512, 3328, 6656, 5888, 6144, 4864, 2048, -512, -6144, -11264, -16384, -18944, -16384, -15360, -11520, -4096, 2304, 8704, 13568, 16128, 17408, 16896, 19200, 18688, 16128, 16896, 15872, 12544, 8704, 2816, -4352, -11008, -13824, -16896, -20992, -18432, -13312, -11008, -7168, -2560, 0, 1024, 4608, 6912, 4096, 3328, 5120, 2048, -2816, -6656, -12032, -16896, -16128, -15104, -16128, -12032, -1792, 5120, 8704, 14336, 17664, 16640, 18688, 20736, 17152, 13824, 15616, 16128, 11264, 6400, 1536, -5888, -9472, -11264, -17664, -21760, -17664, -12288, -9984, -6656, -1792, -1024, 1280, 6912, 6400, 2304, 2560, 3840, 1280, -4352, -8704, -13312, -15872, -13824, -13824, -15360, -10240, -1280, 5376, 10496, 15104, 17152, 16896, 19968, 20736, 16384, 13568, 14848, 14336, 9984, 4608, -768, -6144, -8704, -11520, -16384, -19456, -17152, -13056, -9472, -5376, -2048, -768, 2816, 5632, 5120, 2816, 2304, 2816, -1024, -5888, -9728, -14336, -14592, -13568, -12800, -10752, -7936, -1280, 5376, 10496, 16128, 17152, 18432, 19712, 17664, 17152, 14848, 14336, 12544, 7168, 4096, -2048, -7168, -8960, -12800, -13568, -15872, -16640, -13568, -11264, -5120, -512, 512, 3584, 2560, 3584, 4352, 1792, 1280, -3328, -6912, -9472, -15360, -14848, -14080, -10752, -5632, -4608, -512, 3328, 9216, 17664, 18688, 19456, 18176, 15872, 17920, 15360, 13568, 10752, 5888, 4096, -3328, -8960, -11520, -13056, -10240, -11776, -14848, -15360, -13312, -4352, 1024, 2048, 2816, 1280, 3584, 3840, 1024, -1024, -5120, -5888, -9472, -15872, -17152, -15104, -6912, -512, -768, -768, 768, 9216, 17920, 19712, 19200, 16896, 17152, 17920, 14592, 11776, 8192, 7424, 4864, -4352, -12544, -15872, -11776, -6400, -8448, -13824, -17408, -13056, -3840, 1024, 2048, 1536, 2816, 4608, 2048, -1792, -4864, -4096, -3072, -8960, -17408, -21248, -14336, -2304, 3328, 1792, -1792, 1024, 10240, 16896, 18688, 17664, 18688, 20480, 17664, 11776, 6912, 7936, 10752, 6144, -5888, -17408, -17664, -9216, -3584, -6400, -14592, -16896, -11008, -4096, -768, -512, 2816, 7168, 5888, -512, -7936, -7424, -1024, -256, -8704, -21248, -22784, -11520, 768, 5632, 1536, -768, 4096, 10496, 14336, 14080, 17408, 23808, 23808, 16640, 5888, 3072, 9728, 13568, 6912, -9728, -20480, -16384, -7424, -3072, -7936, -13824, -12544, -8704, -5632, -6144, -2816, 7168, 12032, 6400, -6144, -13056, -6912, 1280, 1280, -11008, -23040, -20224, -8704, 1536, 2816, 1024, 4352, 7936, 9984, 8704, 9728, 20224, 29184, 26880, 12800, 768, 3072, 11264, 14336, 4096, -12544, -18432, -13824, -7168, -7424, -11264, -9472, -6912, -7168, -10496, -11520, -1280, 11776, 15616, 4352, -11264, -13568, -5120, 1792, -1536, -13568, -19968, -15872, -6912, -1792, -1536, 3584, 10496, 11520, 6656, 2816, 9728, 23808, 32512, 25856, 8704, 256, 5120, 12288, 10752, -256, -10496, -13568, -11520, -10240, -13056, -11264, -4608, -2304, -8704, -15616, -12032, 1792, 14592, 14848, 512, -11776, -11008, -3584, -1280, -6912, -13312, -14848, -11776, -7936, -6656, -3072, 7168, 15104, 11520, 2560, 1536, 12800, 26624, 31744, 22272, 7680, 2816, 7680, 10240, 4864, -2304, -6656, -8960, -11264, -14848, -15872, -9728, -1024, -1536, -11776, -17152, -9472, 5376, 14336, 11008, -1024, -9472, -7680, -3840, -6400, -10240, -11264, -9728, -9728, -11008, -9728, -2304, 10240, 16384, 9472, 1280, 3584, 16640, 27136, 27392, 19200, 9216, 6656, 8704, 6144, 1024, -2048, -2560, -6144, -13568, -17920, -16384, -7680, 0, -4096, -13568, -15616, -5632, 7168, 11008, 7424, -512, -5376, -5120, -6656, -9984, -11008, -8704, -6656, -11008, -13824, -10240, 0, 11776, 14336, 7680, 3072, 7680, 19200, 24832, 23040, 17664, 12032, 9728, 7424, 3328, 512, 0, -256, -6912, -15616, -18176, -14080, -6400, -3584, -8192, -12800, -10496, -1536, 5632, 6400, 4352, 1024, -2048, -4864, -7936, -9728, -8960, -7168, -8960, -13568, -13824, -7424, 1792, 7936, 8192, 5888, 7168, 13056, 18432, 19968, 18432, 16640, 14080, 10752, 7680, 4864, 3840, 2816, -2048, -9216, -14848, -14848, -10752, -8960, -8960, -11008, -10240, -4608, 0, 3072, 3584, 2816, 2304, -1024, -3840, -6400, -7936, -7168, -9216, -12544, -13568, -11520, -4608, 256, 3072, 4864, 5888, 11008, 14848, 16384, 17408, 16384, 16384, 14592, 11776, 10240, 7168, 5632, 2304, -4352, -8960, -12288, -12032, -11264, -12032, -11520, -11264, -7936, -3072, -512, 1792, 2560, 2304, 1792, -512, -2048, -4864, -7168, -8192, -11264, -13056, -12288, -9472, -5376, -2304, 1280, 4096, 6656, 11008, 14080, 15360, 16384, 16128, 15616, 14848, 14080, 12288, 8704, 5376, 1536, -3328, -6912, -9984, -12544, -13568, -12800, -11776, -10496, -8192, -4096, -768, 1280, 2816, 2304, 1536, 1280, -1024, -4352, -8192, -10240, -10752, -11264, -10752, -10240, -8192, -3072, 1280, 4352, 6144, 8960, 12800, 14848, 16384, 16384, 15360, 16640, 15616, 12800, 8704, 4608, 2560, -512, -4608, -9728, -14848, -14336, -12544, -11520, -10496, -9728, -5632, -1024, 2048, 3584, 2048, 2816, 2560, -1280, -5120, -9728, -10496, -9216, -9472, -10240, -12288, -9472, -3072, 1024, 3584, 4864, 6912, 11776, 15104, 16896, 16128, 15872, 17920, 16384, 12800, 8704, 5632, 4352, 2048, -2816, -9728, -15104, -14592, -12800, -12544, -12032, -11008, -7168, -1536, 2560, 4096, 2560, 3584, 2048, 256, -1280, -1280, -1024, -1280, 1280, 512, 512, 256, -256, 0, 256, 0, 512, 0, 0, -512, -256, -256, 512, 256, 256, 0, 0, -256, 0, -256, 0, 0, 0, 0, 0, 0, -256, -256, -256, 0, 0, 0, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, -256, -256, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, -256, 0, 256, 0, 0, 0, 256, 0, 256, 0, -768, -2560, -2816, -2048, -3328, -6400, -5376, -2560, 0, 512, 4608, 10496, 11264, 10752, 16896, 15872, 7168, 2560, 4352, 4352, -4096, -2560, 6400, 7168, 7424, 8704, 12032, 8704, -1792, 1792, 6400, -3072, -11008, -11264, -10240, -15616, -21760, -19968, -14080, -10752, -8448, -2560, 4352, 7936, 11008, 15104, 13056, 6400, 6400, 10240, 6912, -256, 512, 6400, 7680, 3840, 3072, 6912, 6656, 3328, 4096, 2304, -6144, -11008, -9472, -12544, -21248, -23552, -15872, -10240, -10752, -9216, 256, 8448, 8704, 11520, 15616, 11776, 6912, 8192, 8448, 2560, -1536, 3840, 9728, 6656, 1024, 3840, 8960, 4864, 1792, 4352, 768, -6656, -10496, -12800, -17152, -23296, -20992, -12288, -10240, -11776, -6144, 4608, 8448, 8192, 13824, 15872, 11776, 7680, 5632, 5120, 1792, 1024, 7168, 8448, 3840, 2560, 5632, 6400, 2304, 3328, 4608, -512, -7424, -13824, -16640, -18944, -22016, -17408, -12544, -11776, -8192, -2048, 4352, 7424, 11520, 16640, 15360, 11008, 5888, 3328, 4352, 3072, 4608, 7168, 5632, 4864, 4096, 3328, 3584, 4096, 6144, 3328, -3328, -10240, -16896, -18432, -19200, -18944, -16384, -14080, -9216, -5120, -2304, 3840, 11008, 16128, 16640, 13056, 9472, 4352, 2304, 4864, 5888, 5376, 4864, 6144, 5376, 768, 1024, 6144, 7936, 4608, -512, -5120, -12544, -19712, -18944, -16640, -18176, -17664, -12032, -6912, -6912, -2560, 9728, 16896, 15104, 13312, 13056, 8704, 1024, 2816, 9216, 6656, 3072, 5632, 6656, 512, -2816, 6400, 11520, 4608, 0, -256, -5888, -18432, -21248, -14080, -16640, -21248, -15616, -8704, -9472, -9216, 5888, 18176, 14080, 11008, 15360, 14080, 2816, 256, 10240, 9472, 2048, 4096, 7936, 1536, -5632, 3584, 14080, 6912, -768, 2048, 512, -13312, -21248, -14592, -14336, -22784, -20224, -11008, -11008, -14080, -1024, 16896, 15616, 8960, 14336, 17408, 7936, 1024, 8192, 11776, 3328, 1792, 7936, 4096, -6144, -1024, 12800, 10752, 512, 1792, 4096, -6400, -17152, -15360, -13824, -22016, -24320, -14080, -11264, -16128, -8192, 10240, 15872, 10240, 12032, 17152, 12288, 5632, 8192, 10752, 4608, 1024, 6400, 6400, -3840, -4096, 7424, 11264, 5376, 2816, 3840, -1280, -9984, -12544, -15104, -21760, -24576, -18432, -13312, -15872, -12800, 1792, 11520, 12544, 12800, 14336, 14336, 11008, 10752, 9984, 4864, 2304, 4096, 5376, 256, -4096, 2304, 8192, 7936, 6144, 3584, 1280, -3584, -8704, -13312, -20736, -24064, -21760, -18176, -15872, -14080, -5376, 5376, 10496, 13568, 14080, 14080, 14592, 13056, 11264, 6656, 3328, 3840, 2816, 768, -768, 0, 4864, 6912, 7424, 6656, 2816, 0, -4096, -10496, -17920, -23040, -22528, -21760, -20480, -14592, -8704, -768, 6656, 10752, 14592, 14592, 15360, 16384, 12800, 8448, 5120, 4352, 2304, -1536, -256, 1536, 2560, 5888, 6656, 7168, 5632, 2560, 256, -6912, -15360, -19968, -22272, -23040, -24064, -18944, -10752, -5120, 2560, 8704, 11264, 14592, 16640, 18176, 14848, 8960, 7680, 5888, 2048, -1280, -1792, 1024, 1792, 4864, 8448, 5888, 4864, 6144, 4352, -3328, -13568, -16640, -19200, -24576, -25088, -21248, -15616, -10240, -1792, 8192, 9728, 9728, 16896, 21248, 16640, 9216, 9216, 9472, 2048, -1792, 256, 0, -1280, 2816, 9984, 8704, 2560, 5376, 9216, 1024, -11520, -15104, -15104, -22784, -27136, -21504, -17152, -15872, -8192, 5376, 10496, 7680, 12032, 21760, 20480, 10496, 8704, 11520, 5120, -2048, 0, 2304, -1792, -1536, 7936, 11520, 5376, 3072, 8192, 6400, -6912, -14080, -13312, -19456, -26624, -24320, -17920, -16384, -14592, -1792, 8448, 8704, 9728, 17152, 21504, 14592, 8960, 11776, 7424, -256, -1024, 1792, 1792, -2048, 3072, 10496, 7936, 5376, 6144, 6400, -1280, -11008, -11520, -16640, -25088, -25088, -20992, -15872, -14848, -8960, 3328, 6912, 9728, 15104, 17920, 17152, 11520, 12544, 9984, 512, -768, 512, 2304, 2304, 1536, 7680, 7680, 6144, 7936, 5120, 768, -6656, -9472, -12288, -23296, -25600, -22528, -19200, -13568, -10496, -2304, 3072, 5888, 14080, 16640, 15616, 13824, 13056, 13056, 3584, -1536, 256, 256, 3840, 4608, 6656, 7424, 4096, 7680, 7168, 1024, -3584, -7424, -9216, -18176, -25600, -23808, -22272, -16384, -9728, -4096, 512, 1536, 8448, 15616, 15104, 14336, 13824, 14080, 8192, 256, -768, -1024, 1280, 6400, 9216, 9216, 4352, 3584, 6400, 3584, -1024, -4864, -7680, -13568, -21504, -24064, -24320, -20992, -12544, -4096, 1024, 512, 2560, 9472, 14336, 15616, 14848, 13824, 10752, 4864, 768, -2304, -2048, 3584, 10496, 13568, 8192, 2560, 1792, 2560, 2560, -1792, -6400, -11008, -16640, -20736, -24832, -25344, -18432, -7424, 2304, 2816, 768, 2560, 8448, 15616, 16640, 14080, 11776, 7680, 4864, 0, -4352, -1280, 7424, 15872, 14592, 6144, -256, -1536, 2560, 2048, -4096, -8960, -13824, -16384, -20480, -26880, -25344, -14592, -512, 6656, 3328, -512, 1536, 10752, 17152, 15360, 12544, 9216, 7936, 5632, -2560, -6144, 256, 12544, 19712, 13568, 2304, -3584, -1024, 2560, -1024, -6656, -12032, -14336, -14848, -22784, -29440, -23808, -8704, 5888, 8448, 1536, -1536, 4096, 12800, 15872, 13568, 9984, 8704, 10240, 4096, -6144, -6656, 3840, 18176, 20992, 9728, -1280, -3328, -256, 768, -3328, -9984, -13568, -12288, -15616, -26368, -30464, -20480, -1536, 10752, 6912, -256, 512, 6656, 13056, 14336, 11008, 8448, 11008, 10752, 1024, -8704, -5888, 9472, 22272, 17920, 5120, -1536, -2560, -768, -1280, -6912, -12544, -12288, -11264, -18432, -29440, -30208, -14336, 5632, 11008, 4352, 768, 3072, 8448, 13056, 11520, 8704, 9728, 13056, 9728, -2816, -10752, -2304, 15104, 22016, 13568, 3328, -1280, -1280, -768, -4864, -10752, -12800, -11008, -11520, -21760, -32512, -26880, -7168, 8704, 9472, 3840, 2048, 5888, 10496, 10752, 8704, 8448, 11520, 14080, 6656, -6912, -9728, 3072, 17664, 19712, 10240, 2304, 256, 0, -3328, -8448, -12288, -12544, -9984, -14080, -26112, -31744, -21248, -2048, 9472, 7936, 3584, 4864, 8960, 9984, 8704, 7680, 8960, 13056, 12800, 2304, -7936, -6400, 6912, 18432, 16640, 7680, 3072, 2304, -512, -5888, -10752, -13312, -11776, -11008, -18176, -27904, -28672, -16128, 1792, 9216, 6400, 5120, 8448, 10752, 8960, 7424, 7424, 10240, 13312, 8960, -512, -7168, -3072, 10240, 17664, 13056, 6656, 4608, 3328, -2048, -8448, -12288, -12800, -11776, -14592, -21504, -27392, -25088, -11008, 3584, 7424, 6144, 7680, 11264, 11008, 7680, 6656, 8704, 11264, 10240, 4864, -2048, -5120, 1024, 11776, 15104, 10752, 7424, 6400, 2560, -4608, -10240, -11776, -12032, -14592, -18688, -23296, -25600, -19968, -7680, 3328, 6400, 7680, 11264, 12288, 9984, 7424, 7936, 10496, 8960, 5888, 2304, -2304, -1280, 4096, 11008, 13312, 10240, 9472, 6400, 0, -5888, -10496, -11008, -13824, -18944, -20992, -23808, -22016, -15360, -6656, 3072, 6656, 10496, 13568, 11264, 10240, 8448, 9216, 9728, 4864, 3072, 512, -768, 2304, 4608, 10240, 12288, 10752, 10496, 4096, -1536, -5888, -10496, -11520, -17408, -21504, -22016, -23040, -18176, -13312, -5632, 3840, 8192, 13312, 13824, 11520, 11520, 9216, 9216, 6400, 1536, 1536, 0, 1280, 3840, 5376, 10496, 11776, 11776, 9472, 2560, -1792, -6144, -10752, -14592, -20736, -22528, -22528, -21248, -15872, -11008, -3584, 4096, 10496, 15104, 14080, 12288, 12288, 10240, 6912, 2560, 512, 512, 0, 2048, 5632, 7680, 9216, 11520, 12800, 8192, 1280, -2304, -5888, -12288, -19200, -22016, -22016, -22528, -20736, -13824, -6656, -2816, 4096, 13312, 16640, 14080, 12800, 13568, 9984, 2304, -512, 1024, 512, -1024, 2816, 9216, 8704, 6912, 12032, 13056, 6656, 0, -2304, -5888, -16128, -23296, -21760, -20736, -22784, -20224, -9728, -3328, -2816, 5888, 15872, 17152, 14080, 13312, 14336, 7424, -2048, -1792, 1792, 0, -1280, 4864, 11264, 7680, 7168, 12544, 11776, 5376, -512, -2560, -8192, -20224, -24576, -21248, -20736, -22272, -17152, -6912, -2816, 0, 9216, 16640, 17152, 14848, 13824, 12288, 3584, -3840, -1792, 768, 256, 1536, 6656, 8960, 7680, 9728, 11776, 9472, 4608, -512, -4608, -12288, -21760, -24576, -22784, -20736, -17920, -13312, -7680, -2048, 5120, 12288, 16128, 16896, 15104, 12800, 8448, 1536, -3584, -3840, -512, 3328, 5120, 5376, 6400, 9216, 11520, 10752, 7936, 3072, -2560, -7936, -14336, -21504, -26368, -24576, -17920, -12800, -11008, -7936, 0, 8960, 14848, 17408, 16640, 13056, 9472, 6656, 2048, -4864, -6400, 512, 6912, 6912, 4352, 5120, 9216, 11520, 11520, 7424, 0, -6912, -10496, -14080, -22272, -28416, -23808, -14592, -9472, -8448, -5888, 1280, 10496, 17920, 19712, 15104, 9216, 6656, 6144, 1024, -6144, -5632, 1792, 7936, 8448, 4864, 3584, 7424, 12544, 12800, 5632, -4096, -9984, -12288, -16128, -23552, -26624, -22016, -13056, -6400, -4864, -4096, 2560, 13568, 20992, 18944, 12032, 6656, 4864, 4096, -256, -4608, -4096, 1792, 8960, 9472, 4608, 2560, 7936, 14080, 10496, 1024, -6400, -11520, -14592, -18688, -23040, -24320, -20992, -10752, -2304, -2048, -2816, 5120, 18176, 21504, 14592, 9984, 6912, 3328, 512, -1536, -2304, -3072, 2048, 11520, 10496, 2048, 1280, 10752, 14336, 5120, -2560, -6144, -12800, -18688, -21248, -21248, -22272, -19456, -6400, 2560, -1280, -2304, 9984, 21504, 18176, 11264, 9728, 6656, 512, -2304, -512, -1024, -2816, 4352, 13312, 9216, 0, 2816, 12800, 11008, 768, -4864, -7936, -14592, -21504, -21504, -19712, -20992, -15104, -2304, 3584, 256, 1792, 14080, 20736, 15616, 9728, 7424, 5120, -512, -2560, -256, -1024, 0, 6656, 10752, 7680, 2048, 5120, 10496, 7168, -1024, -7936, -11776, -16384, -21504, -20992, -20224, -16896, -9472, -1792, 3840, 4608, 7680, 14848, 17408, 14592, 8448, 4352, 2304, 0, -768, -1792, 0, 3840, 5888, 7936, 7424, 5888, 6144, 5632, 3584, -3072, -11008, -16128, -18432, -18688, -21248, -19200, -12032, -6656, -512, 5120, 9472, 12288, 12800, 14592, 13312, 7680, 1536, -256, 2816, 0, -2304, 1792, 4096, 6144, 7168, 8192, 8448, 3840, 1792, 512, -5376, -14080, -20224, -16896, -17152, -20736, -16128, -9728, -3072, 2304, 7424, 13568, 12288, 10752, 13056, 12032, 5632, -1536, 1280, 4608, -1024, -1792, 1536, 5632, 7168, 6656, 9984, 7168, 512, -512, -2048, -8960, -18688, -19456, -14336, -17152, -19712, -14080, -5120, 1024, 4096, 10240, 13824, 10752, 10496, 13056, 9472, 1792, 0, 4352, 3328, -3072, -2304, 5120, 7936, 6400, 7424, 8448, 3840, -1280, -2048, -5632, -14592, -18944, -15872, -14592, -18944, -18176, -8448, 0, 2816, 6656, 11264, 11520, 10496, 12032, 11520, 5632, 768, 3072, 4864, 0, -3840, 1024, 7680, 8192, 6912, 6656, 4352, 768, -1024, -3584, -11264, -17664, -16896, -14336, -16128, -18944, -13312, -2816, 3072, 5376, 7424, 8960, 10496, 12544, 13056, 7936, 2304, 2816, 4864, 2816, -2048, -1792, 5120, 9216, 8704, 5632, 2560, 1536, 1280, -1024, -8448, -16384, -16896, -14848, -14848, -17152, -16128, -7424, 1024, 5120, 5376, 5376, 8960, 13312, 14592, 9984, 3072, 2560, 4608, 4096, 768, -1792, 2048, 7936, 9984, 6400, 1280, 768, 2560, 1280, -5632, -14848, -17152, -14848, -14336, -15360, -16384, -11520, -2816, 3840, 4864, 3072, 6144, 12800, 15872, 11776, 4352, 2304, 4608, 5120, 3072, 0, 512, 5376, 9472, 7936, 1792, 0, 2816, 3584, -3072, -13056, -16896, -14848, -13568, -13824, -15104, -13824, -7424, 768, 4096, 2304, 4352, 11264, 15872, 13056, 5632, 2048, 4352, 6144, 5376, 2304, 256, 2816, 7680, 7936, 3584, 768, 2816, 4096, -1024, -11008, -16640, -14848, -12544, -12800, -13568, -14080, -11008, -4096, 1280, 2560, 4096, 9728, 15104, 13824, 6656, 1792, 4608, 7424, 6144, 4608, 2048, 1280, 4096, 6912, 5888, 2816, 3584, 4608, -256, -9216, -16128, -14336, -11008, -12288, -12032, -12544, -13312, -9216, -3072, 2048, 4352, 8960, 14080, 12800, 7168, 2304, 4352, 8448, 6400, 6144, 5120, 1280, 1024, 3840, 6912, 5888, 5120, 5632, 0, -8192, -14848, -14080, -10240, -12032, -11264, -9984, -13312, -13824, -8704, -512, 4864, 8960, 13568, 11776, 6912, 3072, 4608, 8704, 6656, 6656, 8448, 3328, -1536, 0, 5632, 8704, 8192, 7168, 768, -7936, -13568, -13056, -9984, -12032, -11520, -7680, -11520, -16896, -14336, -4864, 3840, 9728, 13312, 11008, 5632, 3328, 5632, 8960, 6656, 6656, 10496, 6400, -1792, -3328, 2560, 8960, 11776, 9984, 2560, -7424, -12800, -11776, -9472, -12032, -11776, -6912, -8960, -16640, -18432, -10752, 512, 9728, 14080, 11008, 4864, 2816, 6144, 9216, 6912, 6656, 11008, 9472, 512, -4864, -1536, 6400, 13568, 14336, 5120, -6144, -11776, -11008, -9216, -11776, -12288, -7424, -7168, -14336, -19712, -16384, -5632, 7936, 15616, 11520, 4096, 2560, 5888, 8960, 7680, 6656, 10496, 10752, 4096, -3584, -5376, 1792, 13056, 17920, 9216, -3840, -9728, -10240, -8960, -10752, -12544, -8960, -7424, -11264, -18176, -20736, -12544, 3584, 15360, 12800, 4608, 2560, 5376, 8704, 8704, 6656, 9472, 11008, 7680, 0, -6912, -3328, 9472, 18944, 13824, 512, -7424, -8960, -8192, -9472, -12544, -10752, -8192, -9216, -14592, -21760, -18688, -3072, 11776, 14592, 6912, 2304, 4352, 8192, 9728, 7168, 7680, 10496, 9984, 4608, -5120, -6912, 3840, 15872, 17408, 6656, -4352, -7680, -7168, -7424, -11520, -13056, -10240, -8704, -11520, -19712, -22016, -10752, 4608, 13824, 11008, 3584, 3072, 7424, 10752, 8704, 6400, 8448, 10496, 7680, -512, -6144, -1280, 9216, 16640, 12800, 768, -6144, -6144, -4864, -8448, -13824, -13312, -10752, -11520, -15616, -19200, -14848, -3840, 8192, 12288, 6400, 2560, 6144, 11520, 11520, 6912, 6656, 8192, 7168, 3328, -1024, -1536, 3584, 11264, 14080, 6144, -2816, -4608, -3072, -5120, -11776, -14592, -13568, -13824, -14592, -16128, -14592, -8448, 1024, 8960, 8192, 4096, 5632, 10240, 12544, 9216, 6656, 7168, 5888, 4352, 2048, 256, 2560, 6912, 11008, 8448, 1280, -1536, -2048, -3584, -8448, -13568, -14592, -15616, -15872, -15616, -15104, -9728, -2560, 3840, 6656, 5120, 6656, 10240, 11264, 10496, 7680, 6912, 6400, 4608, 3072, 768, 2304, 6656, 8448, 7168, 3328, 1280, 1280, -2048, -6400, -11520, -14592, -15360, -16384, -16896, -16640, -12544, -4352, 1536, 3328, 4096, 6656, 11008, 12032, 9984, 8192, 6912, 6912, 6400, 3328, 768, 1536, 5632, 8960, 6656, 3328, 2560, 3072, 1280, -4352, -10240, -13824, -14848, -14848, -17408, -18944, -15616, -7936, -256, 2304, 2560, 5888, 10240, 12800, 11520, 7936, 6144, 6912, 7936, 5120, 768, 512, 4352, 8192, 7936, 4096, 3072, 3840, 3072, -1024, -7936, -13056, -14080, -13824, -15872, -19456, -18688, -12032, -4352, 512, 2048, 4864, 9472, 13056, 12800, 8704, 6144, 6656, 7936, 6400, 2304, 1024, 3328, 6656, 8704, 6400, 2304, 3328, 5120, -512, -8448, -11264, -11008, -14848, -19968, -19712, -15104, -11264, -8448, -2560, 4352, 1536, 3072, -2304, 8192, 3328, 1024, -1024, 1536, -2304, 6912, 2048, 512, -256, -768, -512, 768, -1024, -768, 512, 0, -512, 256, -512, 256, -1024, 512, 256, 0, -512, -256, -768, 512, 0, -256, -512, -512, -512, -256, -512, -512, -256, -512, -512, -512, -512, -256, -512, -256, 0, -256, -512, -512, -512, -256, 0, -512, -512, -512, -512, -256, -256, -512, -256, -512, -512, -512, -768, -256, -256, 0, 0, -256, -768, -512, 256, 768, 0, 0, -512, -2048, -5376, -4352, -512, 3072, 5120, 4864, 1536, -3328, -7168, -18688, -17152, -16384, -14848, -9984, -2816, 4864, 9728, 15360, 24576, 20480, 9728, 3072, 1536, -5120, -16640, -21248, -16640, -15616, -14336, -4352, 5632, 8960, 12544, 18944, 24064, 14080, 4096, 5120, -1280, -13312, -22784, -20736, -13568, -16640, -9216, 5376, 9472, 12288, 13056, 21760, 20992, 6400, 5888, 2304, -9216, -20480, -26880, -14848, -14592, -13824, 1792, 9216, 13824, 11264, 14848, 24832, 12288, 6656, 4096, -5376, -15616, -29440, -21248, -11520, -14592, -3072, 5888, 14592, 13824, 9216, 22016, 19712, 9472, 5376, -4096, -10240, -26368, -28160, -13824, -11776, -6144, 1536, 11008, 17408, 9216, 15872, 22016, 15360, 7680, -3072, -8704, -20480, -30464, -19456, -11264, -6144, -1280, 6144, 16384, 13056, 12800, 19456, 18432, 12288, 0, -8704, -17408, -27136, -24064, -14336, -6656, -1792, 2816, 11520, 15104, 14848, 16896, 18176, 15360, 5888, -6912, -17408, -23808, -23808, -18432, -9472, -2048, 2560, 6400, 12800, 17920, 17408, 15872, 15872, 11520, -2560, -17920, -22528, -21248, -20224, -14592, -3840, 3840, 3328, 7936, 18688, 20480, 15104, 13568, 15616, 3840, -17152, -22784, -18688, -19200, -19200, -8448, 5376, 2816, 2560, 16896, 23552, 16640, 10752, 16128, 10752, -14336, -23552, -16896, -16896, -21504, -14592, 4096, 4864, -1280, 12800, 25088, 19456, 9984, 14336, 15360, -8960, -24320, -16384, -13568, -21504, -20224, 0, 7168, -2048, 7424, 24576, 22784, 10752, 11776, 17664, -2560, -23040, -17664, -10496, -18944, -24320, -6400, 7168, -256, 3328, 20736, 25856, 13568, 9472, 17664, 2816, -19712, -19200, -9728, -13568, -26368, -14080, 5632, 2048, 1536, 15616, 26624, 19200, 7424, 15104, 7936, -15616, -19456, -11008, -9216, -23296, -22528, 1536, 4352, 256, 11776, 24576, 24064, 8704, 10240, 12288, -10240, -20480, -12032, -6912, -17664, -27392, -6912, 6656, 1024, 7424, 22272, 26880, 13056, 6144, 11776, -2560, -19456, -14848, -5376, -12544, -27392, -15872, 4352, 4096, 4352, 17920, 28160, 17152, 5632, 9728, 2560, -15360, -18176, -6144, -7168, -24832, -21760, -1536, 6400, 4608, 12800, 27136, 21504, 7168, 7936, 4096, -9728, -18176, -9728, -4352, -19968, -24064, -7680, 3840, 7680, 10496, 22016, 23552, 11264, 7936, 3840, -6400, -13824, -13568, -6656, -14592, -22528, -13056, -512, 8448, 11520, 17408, 22528, 15104, 8960, 4352, -3840, -10752, -14080, -10496, -12288, -18688, -15360, -4864, 6144, 12800, 15616, 18944, 17152, 11776, 5376, -2048, -8192, -12288, -13824, -13568, -14592, -14592, -8704, 2304, 12800, 16128, 15104, 16640, 14848, 7424, -256, -6144, -9728, -15872, -17152, -12288, -12032, -10240, -2048, 11008, 17408, 12288, 14848, 16896, 9728, 1536, -4864, -6656, -15872, -21760, -11520, -8960, -9984, -5376, 7168, 18432, 10496, 12032, 18944, 11520, 3840, -3584, -4352, -13568, -26112, -12800, -6144, -9216, -6656, 2560, 17664, 10752, 8192, 20736, 13312, 5376, -1024, -3840, -9984, -27904, -16384, -3072, -8960, -6656, -256, 13824, 12032, 5376, 20224, 16640, 5120, 1792, -3072, -8448, -25600, -20992, -2048, -6912, -8192, -512, 9216, 12032, 5376, 16896, 19712, 6400, 3072, -512, -9216, -22528, -22272, -4608, -4096, -9216, -2048, 6912, 9216, 7680, 14336, 19712, 9984, 3072, 1536, -8448, -21504, -20224, -7680, -2816, -7424, -5120, 4864, 6912, 7936, 14848, 16896, 12800, 5376, 1280, -6400, -20736, -19200, -8192, -4352, -4352, -6912, 512, 6144, 7168, 15616, 15616, 12288, 8960, 1024, -5632, -18176, -19712, -7936, -4864, -3072, -5888, -4608, 4096, 7424, 15104, 16640, 11520, 10496, 2560, -5888, -15104, -19456, -9472, -3584, -2816, -4608, -7424, -512, 7424, 14592, 17408, 13056, 9472, 4096, -5376, -14080, -17152, -11264, -3072, -1280, -5376, -7424, -4864, 4864, 15104, 17408, 15616, 9216, 3584, -3072, -14080, -15616, -11264, -4096, 768, -5376, -7424, -6400, 0, 14080, 18432, 17664, 11008, 2048, -1536, -12544, -16128, -9984, -4608, 1280, -3840, -7936, -6656, -4608, 9984, 19968, 19200, 13568, 2048, -2048, -10240, -17152, -9472, -3840, 512, -2048, -7680, -6656, -7424, 4096, 20224, 21504, 15104, 3584, -2816, -8448, -16896, -10752, -2304, -512, -1536, -5888, -6656, -8448, -1792, 16896, 24064, 17152, 5632, -2304, -8192, -15872, -12288, -2048, 0, -2304, -4096, -5120, -8960, -6144, 11776, 24576, 19968, 7936, -512, -7424, -15104, -13056, -3328, 256, -2560, -3328, -2304, -7936, -8960, 5888, 22016, 22528, 10752, 1280, -5632, -14592, -13568, -4608, -768, -2560, -3328, 0, -4864, -11264, 512, 17664, 23040, 14592, 3072, -3328, -12800, -14592, -5376, -2304, -3328, -3328, 256, -768, -10496, -4352, 13056, 20992, 17664, 5888, -2304, -9472, -14592, -6400, -3072, -5632, -3840, 0, 2560, -6400, -8192, 8192, 17664, 18176, 9472, -1024, -6400, -12288, -7680, -3072, -8192, -5888, -768, 3584, -512, -8448, 2816, 14336, 16128, 12544, 768, -4608, -8192, -7936, -3328, -9472, -9728, -2304, 2816, 4352, -4096, -1536, 10496, 13568, 13056, 2816, -4352, -3840, -5888, -3584, -8960, -13824, -5632, 1024, 6656, 2560, -2560, 6656, 11008, 11776, 4864, -4864, -1536, -1280, -2560, -7680, -16640, -10752, -2304, 6144, 8960, 768, 3072, 8192, 9472, 6144, -5120, -2048, 3584, 512, -5888, -17408, -15872, -6656, 2560, 12800, 7168, 2816, 5632, 6912, 6144, -4864, -4864, 6144, 5376, -2048, -16128, -19968, -11520, -2816, 12032, 13568, 5888, 5376, 4864, 5632, -4352, -8704, 5376, 10240, 3840, -12288, -22784, -16640, -8704, 7680, 17408, 11264, 6912, 4096, 4096, -2816, -12032, 768, 12544, 9984, -5632, -22784, -20992, -14080, 768, 17408, 15616, 11264, 5376, 2816, -1536, -13568, -5376, 11520, 14336, 2816, -18944, -24576, -18432, -6656, 13312, 18688, 15360, 9984, 2560, -768, -12288, -11264, 6912, 15616, 10752, -11008, -25856, -22528, -13312, 6912, 18688, 17920, 15104, 5376, -256, -10240, -15360, 512, 13312, 15360, -1024, -23040, -25600, -18944, -512, 15872, 18432, 19456, 10752, 1280, -7680, -16896, -5632, 8704, 16128, 8448, -15872, -26624, -23552, -7936, 11264, 17408, 21504, 16896, 5376, -5376, -16384, -10496, 3328, 13824, 14080, -6656, -24064, -26624, -14592, 5120, 14336, 20992, 21504, 11008, -1536, -14592, -13824, -2560, 9216, 15360, 1792, -17920, -27392, -19968, -1536, 10240, 18688, 23552, 16896, 3072, -11520, -14592, -6912, 4096, 13312, 7424, -10496, -24576, -23040, -8192, 5120, 15360, 23296, 21248, 8704, -6912, -13312, -9472, -768, 8704, 9216, -3840, -19712, -23296, -13312, -256, 11008, 21248, 23808, 13568, -1280, -10752, -10240, -4352, 3584, 8192, 256, -13824, -20736, -16640, -5376, 5888, 18176, 24576, 17152, 4096, -6400, -9472, -6144, -1280, 5376, 1536, -9216, -16384, -17664, -9472, 768, 13824, 23808, 18688, 8960, -1536, -7168, -6400, -4864, 2048, 1024, -6912, -11776, -16640, -11776, -3584, 8704, 22016, 18688, 12544, 3840, -4352, -4864, -7168, -1024, -768, -7168, -8192, -14336, -12288, -6144, 3840, 18944, 17152, 14080, 9216, -512, -2560, -7168, -3584, -2304, -9216, -6400, -10752, -12800, -7424, 256, 15360, 15104, 12800, 14080, 4096, -768, -5632, -5120, -3584, -11776, -7424, -7168, -12288, -8448, -1280, 12032, 12800, 10240, 16384, 10240, 1024, -3584, -4352, -4864, -13568, -10240, -4608, -10240, -10496, -1536, 9984, 9984, 7168, 15616, 15872, 4352, -2560, -1792, -5376, -15104, -13568, -5120, -7168, -12032, -2816, 9728, 7424, 3840, 13312, 19712, 9216, -1536, 256, -3072, -16128, -16896, -6400, -5120, -11776, -4864, 9472, 7168, 0, 9728, 21248, 13824, 1280, 1280, -512, -14592, -20736, -8704, -3840, -11264, -5632, 7424, 7936, -1024, 4096, 21760, 17408, 4352, 3840, 256, -11264, -22272, -13824, -2048, -10752, -6912, 6400, 6144, 512, 0, 17664, 22528, 6144, 6400, 2816, -10752, -19456, -19200, -3584, -6400, -10240, 5888, 4608, -768, 768, 10752, 24576, 11520, 5632, 7424, -9984, -17920, -19200, -10240, -2048, -9984, 1792, 6144, -4352, 2048, 8448, 20224, 19456, 5632, 8960, -5376, -19200, -16384, -15360, -3840, -4352, -3584, 5376, -5376, -1024, 10240, 15104, 22528, 11520, 6144, -768, -18176, -15616, -15104, -9728, 256, -3584, 0, -4352, -4608, 10496, 13824, 20992, 18944, 5632, -768, -13568, -15616, -13568, -13824, -512, 768, -4864, -6400, -5632, 7680, 14592, 18688, 23552, 9728, -3840, -10240, -13056, -12800, -14848, -4352, 4352, -5888, -11264, -5632, 4864, 14080, 18432, 24832, 15360, -5632, -10240, -8960, -11520, -14080, -8192, 3584, -4352, -15360, -6656, 2816, 11776, 19200, 24832, 19968, -4352, -11776, -5888, -9728, -11520, -9472, -256, -3584, -16896, -7936, 768, 8704, 20480, 25088, 21760, -1024, -12032, -4864, -8448, -8448, -7680, -5120, -6400, -16128, -8704, -1024, 4608, 20224, 26624, 21504, 2304, -9728, -4608, -7424, -6912, -3584, -7680, -11776, -16128, -8192, -1280, 768, 17408, 28416, 21504, 4608, -5888, -3072, -6400, -7168, -512, -6400, -17152, -19200, -7424, 256, -1536, 11776, 28672, 23296, 5632, -2816, 0, -4608, -8448, -256, -2304, -19456, -24576, -8704, 2304, -2048, 5632, 25856, 26112, 6912, -512, 3584, -1792, -9216, -2304, 1024, -17408, -29184, -12288, 3328, -768, 1280, 20480, 27904, 10240, 1024, 6656, 1536, -8448, -4608, 1536, -13312, -30720, -17152, 1792, 1024, -256, 14080, 26368, 14848, 3584, 7936, 4352, -5376, -6144, -1024, -9984, -28160, -21504, -2560, 1536, 512, 8704, 22272, 18176, 7424, 9216, 6400, -1792, -5888, -4096, -8448, -24576, -23040, -7424, -256, 1536, 5632, 17408, 19200, 11520, 11520, 7936, 1024, -3840, -6144, -9472, -21504, -22272, -11008, -3840, 768, 4608, 13568, 17408, 14592, 14848, 9728, 2816, -1792, -5632, -11520, -20736, -20224, -12288, -7424, -2560, 4352, 11520, 14592, 15616, 18176, 12800, 4352, 0, -3840, -12544, -21760, -18944, -11520, -10240, -6400, 2560, 10752, 12544, 14080, 20992, 16640, 5632, 1792, -2304, -11008, -22784, -20480, -8704, -12032, -10240, -256, 8960, 13312, 11008, 21760, 21504, 6400, 4352, -1024, -9728, -21760, -23552, -7168, -11264, -14080, -2304, 5376, 13568, 10752, 19200, 25600, 8960, 5632, 1536, -9728, -18944, -25344, -9728, -8704, -16640, -4608, 3072, 10752, 13056, 16128, 26112, 13312, 6400, 5376, -9216, -17920, -23040, -14336, -7680, -16384, -7680, 1792, 6912, 14080, 16128, 23040, 17664, 8448, 6656, -6656, -17664, -20224, -16896, -11008, -13824, -9472, -256, 4352, 12544, 17664, 20224, 18432, 12800, 7680, -3840, -15616, -19200, -17408, -14848, -13312, -8448, -3072, 2304, 10752, 17664, 19968, 16384, 15360, 10752, -2304, -12544, -18176, -17664, -17408, -15616, -6400, -4352, -256, 9728, 16384, 19712, 15104, 15872, 14848, -768, -9472, -15872, -18432, -18432, -18688, -6144, -3072, -2816, 8960, 14080, 18688, 15104, 14848, 17664, 2048, -7424, -12288, -19200, -19456, -20992, -7936, -1024, -3584, 7168, 12544, 16128, 15616, 13824, 18688, 5632, -5376, -9216, -18176, -20992, -22528, -10752, 0, -2304, 5376, 11008, 13568, 14592, 14336, 18688, 8448, -3072, -6400, -15872, -22784, -24320, -12544, -512, -512, 4608, 9472, 11008, 12544, 15360, 19200, 9728, -512, -4096, -12544, -22784, -26880, -13824, -1792, 256, 4864, 7936, 9472, 9728, 15104, 20736, 9984, 1024, -1792, -8960, -21248, -29440, -15872, -2560, 0, 5120, 6912, 8192, 7680, 13568, 22272, 11008, 1024, 0, -6144, -17920, -30208, -19200, -3072, -512, 4864, 6144, 6912, 6912, 11520, 22784, 13312, 1024, 256, -3584, -14080, -28928, -22272, -4608, -768, 3328, 5120, 6144, 7168, 10496, 21760, 15360, 1792, -768, -2304, -10240, -25600, -23296, -7168, -1024, 1792, 2560, 5376, 7680, 11008, 20992, 15872, 3328, -2048, -2816, -6656, -21760, -22272, -9216, -2560, 512, -1024, 3584, 8960, 12032, 20736, 15872, 4608, -2304, -5376, -5120, -16640, -19968, -9728, -4864, -1024, -4096, 0, 9984, 13824, 21760, 16640, 5120, -1792, -7936, -6144, -12032, -15872, -8448, -6656, -3840, -6400, -4864, 8960, 16128, 23040, 18688, 5632, -768, -9984, -9984, -8960, -11008, -5120, -6656, -7680, -8704, -9216, 6144, 18176, 24064, 21760, 7424, -768, -10240, -14848, -8704, -6144, -1024, -4096, -11776, -12032, -12032, 1536, 18688, 25600, 24832, 10752, -1024, -9984, -18688, -11520, -2048, 3072, 0, -13056, -16384, -14336, -3328, 16896, 26624, 27136, 16384, 512, -10240, -20992, -16128, -768, 6912, 4608, -11008, -20992, -17408, -7168, 13056, 26624, 28672, 22016, 4864, -10752, -22016, -20736, -2560, 10240, 8704, -6656, -23040, -22016, -10496, 7936, 25088, 29696, 26624, 11776, -9728, -23552, -24320, -6400, 11776, 12288, -1536, -21504, -26880, -14080, 3328, 21504, 29952, 29184, 19456, -5120, -24320, -26880, -11520, 10496, 13824, 2048, -16640, -28672, -17920, -256, 16640, 27904, 29440, 25600, 3584, -21760, -27136, -15872, 5376, 12800, 3328, -11264, -26624, -21504, -3584, 11520, 25088, 28672, 28416, 13568, -15872, -26880, -19200, -768, 11264, 3072, -7936, -21760, -23808, -6912, 6912, 20992, 28160, 28160, 20736, -6912, -24320, -20736, -6912, 7936, 2816, -7936, -16896, -23040, -9984, 3072, 15616, 27136, 27392, 24064, 3072, -18688, -20224, -12288, 2816, 3328, -8192, -14592, -19968, -11776, -256, 9728, 24832, 27904, 24576, 11008, -10496, -17664, -15872, -3328, 3328, -7680, -14848, -17408, -11776, -2816, 4352, 20736, 28672, 24832, 15104, -1792, -13056, -17152, -9472, 1536, -5888, -15872, -17152, -10752, -3584, 512, 15360, 28160, 25344, 16640, 5120, -6144, -16128, -14336, -1792, -3840, -16128, -19200, -10240, -3072, -2048, 9984, 26112, 26368, 17152, 8960, 1536, -12288, -17408, -6400, -2816, -14336, -21760, -11776, -1792, -2560, 5632, 22016, 27392, 18432, 10496, 7424, -6400, -17920, -10752, -3584, -10752, -23296, -15872, -1280, -1536, 2304, 17152, 26880, 21504, 10240, 10240, 768, -16384, -14336, -5888, -7680, -21248, -21760, -3072, 768, 256, 12800, 24832, 24576, 11264, 9216, 7168, -11520, -17664, -8448, -5632, -17152, -25856, -8704, 3328, 512, 7936, 22528, 26624, 14336, 7168, 9472, -4096, -18176, -13056, -4608, -12544, -26368, -15872, 2304, 3584, 4608, 17920, 27904, 17408, 6656, 9216, 1536, -14848, -17408, -5888, -7168, -24832, -21504, -1792, 5888, 4864, 12800, 27136, 21504, 7168, 7936, -5376, -6656, -4608, -7680, -6144, -19712, -19456, -12288, -11776, 7936, 0, -256, 0, 0, 512, 0, 256, -512, 256, 0, -1536, -1792, -1280, -768, 0, -768, -1024, -512, 512, 0, -2048, -2816, -3584, -2560, -2048, -1024, 1536, 3328, 3584, 2304, 512, -1536, -2560, -2304, -1536, 2304, 4352, 3840, 2048, 0, 256, -1024, -3072, -4864, -3584, -2048, -1024, 768, 1536, -512, -1024, -1536, -1792, -2560, -2048, -3072, -2816, 768, 5888, 6912, 2816, 1024, -768, -1280, 0, -2304, -768, 1536, 2816, 4864, 1024, -2048, -4352, -5120, -5376, -768, 1280, 2048, 512, 768, 1280, 512, -768, -768, -3072, 1024, 256, 768, -1792, 0, 1280, 1536, 0, -1792, -2048, -1280, -1792, -1280, -768, 1024, 2304, 1280, -1280, -1280, -1280, -4352, -1792, 768, 4352, 3840, 1792, -512, -1280, -768, 768, -2048, -1280, -768, 768, 2048, 3072, 1280, -2560, -6912, -5120, 256, 1280, -1024, -2304, -4352, 1024, 2560, 2304, -512, -3072, -4096, -3072, -512, 2048, 4096, 3328, 2816, 4096, 4864, 2560, -512, -4096, -5376, -2816, 3584, 3840, 5376, 2816, 1536, -2560, -2048, -2816, -6144, -8960, -7936, -3328, 2304, 6144, 4352, -512, -2816, -5120, -2816, -4864, -1792, 768, 2048, 5632, 5376, 5376, 512, -1792, -2560, 3072, 6144, 4608, -768, -4864, -1536, 0, -1280, -4608, -4352, 1536, 3072, 1792, -4096, -5120, -5632, -6912, -4864, -3584, 3072, 3584, 768, 0, 512, 2048, -768, -1280, -768, 5376, 7424, 4352, 1536, -2048, 768, 768, 2560, 2560, 768, 3072, 1024, -2304, -4608, -5120, -5120, -2304, 1536, 768, -2304, -1792, -3584, -2304, -2048, -2304, -5888, -4864, 1792, 4352, 5120, 2304, 2048, 1280, 2304, 4608, 2304, 2048, -2560, -2560, -1024, 2304, 6400, -1536, -4864, -4864, -1280, -1024, -1792, -1792, -4352, -3840, -1792, -1024, 0, 512, -512, -4352, -1024, 3584, 5888, 3840, 512, -1792, -1280, 2304, 2816, 256, 0, -768, 0, 0, 3840, 3584, -1024, -3840, -5120, -6656, -5632, -3328, 0, 1536, 3072, 1280, -2560, 512, 2048, -512, -4608, -2048, 1536, 5120, 7168, 5888, 0, -4096, -1792, 2304, 1792, 2560, -3072, -5376, -4864, 1792, 3072, 1024, -4352, -7168, -6144, -768, 3584, 1024, -4864, -4608, -2304, 2816, 5632, 4096, -3328, -5888, -3840, 4608, 8192, 8192, 4352, -1024, 256, 3584, 2816, 256, -5120, -4864, -768, 2304, 3328, -1024, -3328, -4096, -4608, -5888, -3072, -4352, -4096, -5120, -3840, -3584, -1024, 2048, 3072, 0, 2048, 1280, 3072, 4352, 6656, 6400, 3584, 2560, 2816, 2816, 4608, 3840, 1024, -2304, -3328, -2048, -2304, -3584, -5120, -7168, -8192, -3072, -2304, -4096, -4352, -6144, -4608, -3072, 1280, 2560, 1024, 1536, 2048, 4608, 8960, 7936, 4352, 256, 3072, 5376, 8448, 4608, 1536, -2560, -2816, -1024, -2304, -3328, -4864, -6144, -6144, -6144, -4608, -5120, -4608, -5120, -3328, -3840, -2560, -2304, -1280, 2048, 2560, 3328, 5888, 6656, 7424, 3584, 3328, 3328, 3328, 4096, 6400, 4864, 4352, 1024, -3840, -4608, -3840, -3584, -4352, -8704, -5888, -4096, -3072, -4096, -6656, -8448, -5888, -3840, -1024, 1024, 2560, 4096, 4864, 5632, 7424, 7168, 1792, 256, 512, 4608, 6656, 7680, 5376, 2304, 768, -1024, -2560, -4096, -7424, -7936, -6912, -1024, -2304, -2816, -7168, -5888, -4352, -3840, -3328, -2816, 1024, 2816, 2304, 3328, 4096, 6400, 4608, 2048, 2560, 4608, 4352, 2048, 4608, 4352, 2816, -1280, -4864, -4352, -3072, -4864, -9728, -6912, -2048, 0, -768, -3584, -4864, -5120, -3584, -2560, -3328, -768, 1536, 3072, 6656, 9728, 8704, 3584, 512, -512, 2816, 4864, 3584, 2048, 1280, 4096, 2304, -1792, -4864, -6144, -7424, -9216, -6656, -3328, -3072, -5632, -7168, -5120, 1280, -768, -2560, -4864, 1792, 5120, 4608, 4352, 6144, 6400, 3584, 4608, 4864, 7424, 5376, 2816, 2560, 2304, 3328, -3328, -7424, -6912, -5120, -6144, -7680, -5632, -3072, -1792, -3840, -5632, -5376, -3328, -3584, -5120, -2048, 3072, 6656, 6400, 5376, 8448, 6912, 6400, 4096, 3328, 4096, 4096, -512, 512, 2816, 2304, -512, -4352, -4608, -4096, -6400, -6400, -6656, -6912, -7680, -8960, -7680, -3072, -1536, -1536, -1536, -1280, 4864, 4864, 2816, 3840, 4352, 6144, 5888, 8704, 7168, 5888, 3328, 512, 2304, 4608, 4096, -3584, -4608, -3072, -1792, -2304, -7936, -9472, -8448, -6144, -3584, -6144, -5120, -4096, -5376, -3840, -1792, 1280, 2304, 3840, 5120, 7168, 9728, 7424, 5376, 3840, 5632, 4352, 1024, 3072, 1536, 3072, -1024, -2304, -3840, -4096, -4864, -10240, -9728, -8704, -5888, -4608, -4352, -2048, -2560, -768, -1792, 256, 768, 1024, 2816, 3328, 9216, 10496, 9216, 6144, 2304, 4352, 5120, 5376, 3584, -1280, -2304, -2816, -2048, -4864, -3584, -6144, -7680, -5888, -4608, -6400, -7680, -6144, -4352, -5120, -2304, -768, 1536, 2048, 5632, 5888, 5120, 6912, 4608, 2560, 2560, 3584, 4608, 3584, 5888, 4352, 1536, 1280, -1024, -2048, -6656, -4864, -6144, -6400, -6144, -5376, -6912, -7168, -3840, -4864, -4096, -2304, 0, 1792, 2304, 4352, 3584, 3840, 6144, 7680, 7424, 7424, 8192, 4096, 2560, 2048, 0, -768, -2560, -1792, -4352, -5632, -6400, -7680, -9216, -8192, -6400, -6656, -5632, -3072, -4096, -2816, -768, 1280, 1792, 3328, 5376, 5376, 6656, 8192, 7168, 6656, 7168, 7936, 4352, 3840, 3840, 1280, -1024, -3584, -4608, -7168, -6400, -6144, -7168, -8192, -8448, -8192, -7424, -4608, -4352, -5120, -2560, -1024, 1536, 1536, 4608, 5632, 5632, 9472, 9728, 7936, 6912, 6656, 5888, 5632, 5888, 3072, 1024, -1280, -512, -2816, -4864, -6400, -8960, -8960, -9216, -9216, -11008, -8192, -6144, -5120, -3072, -1792, -768, -1792, 768, 3328, 5888, 7424, 8960, 9472, 8960, 10752, 8448, 6656, 5632, 4352, 3072, 1536, 1024, -2304, -5888, -7168, -8704, -8704, -8448, -7936, -10240, -9216, -6912, -6400, -5632, -7680, -5120, -2816, 512, 3072, 5632, 5632, 6656, 7168, 8960, 12032, 11264, 6912, 7424, 7424, 7424, 4864, 512, 256, -2304, -3840, -5376, -8704, -8960, -8704, -10240, -11264, -10752, -8704, -7936, -6656, -5376, -2304, -3072, -768, 2560, 4352, 7424, 6656, 6912, 8704, 12288, 12800, 8704, 8448, 6400, 5376, 4096, 2048, 768, -2048, -2816, -6400, -7680, -9472, -9472, -10752, -13056, -8704, -7168, -5376, -6656, -6400, -4864, -3328, 1024, 2304, 4352, 7424, 10496, 8448, 8448, 11264, 11520, 8192, 7936, 7168, 5632, 4096, 1280, -2560, -3328, -4096, -5888, -9728, -9984, -9984, -11520, -13824, -10240, -8192, -6144, -5632, -4352, -3584, 0, 1536, 2304, 4608, 10496, 11008, 8704, 8192, 10240, 10240, 7936, 7680, 6912, 5632, 4864, 3584, -512, -4096, -5376, -8704, -12288, -11520, -10496, -10496, -10496, -11520, -9728, -6400, -5376, -4352, -5120, -1792, 2816, 4352, 4864, 9216, 10240, 10752, 11264, 12032, 11776, 9984, 8448, 6656, 3840, 2816, 2048, -1280, -4864, -6144, -7424, -10240, -11264, -12288, -11264, -9472, -9472, -11008, -11008, -6656, -4864, -3584, -512, 3328, 5888, 7936, 9216, 9216, 11008, 10496, 12032, 11776, 11264, 10240, 6144, 3840, 3584, 768, -3072, -5376, -5888, -7680, -9216, -12032, -13056, -12800, -12032, -11264, -11776, -7936, -4864, -4096, -2816, 512, 4096, 5120, 6400, 7424, 10240, 13568, 13056, 12544, 11520, 10496, 8960, 6400, 4608, 1792, 1280, -3072, -4608, -5888, -8704, -9984, -14336, -14848, -13824, -12544, -12800, -11520, -8960, -6656, -3072, -1280, 1536, 4352, 7424, 10496, 10752, 12032, 12800, 11776, 12544, 12800, 12800, 9984, 7680, 4096, 512, -2048, -3840, -5376, -7680, -10496, -12544, -12800, -11776, -14592, -16128, -14592, -10496, -7424, -6144, -3072, -768, 1280, 3072, 5632, 8448, 10496, 12800, 13056, 13568, 14592, 14080, 11776, 9216, 7424, 4096, 512, -1024, -2816, -5376, -8448, -10240, -12544, -12032, -13568, -15360, -14848, -13056, -10752, -8704, -5888, -3328, -512, 1280, 4352, 6912, 9984, 12544, 12288, 13056, 14336, 13824, 14848, 11264, 9472, 7168, 4608, 1024, -768, -3840, -7424, -9984, -12544, -12544, -13056, -15872, -16640, -16384, -12032, -10752, -9216, -6656, -3584, -1280, 2560, 6144, 8192, 11520, 12800, 12544, 15872, 16640, 16128, 12032, 10752, 10496, 9216, 5888, 1792, -1792, -5632, -7936, -10496, -13568, -14848, -15872, -15104, -15872, -14336, -13824, -12800, -11264, -8192, -4096, 0, 2816, 6400, 8960, 12800, 13824, 14080, 14336, 16896, 16640, 15872, 13824, 11520, 9216, 5888, 3584, -1024, -5632, -11264, -14080, -13312, -15872, -15616, -16896, -17920, -17408, -15360, -13824, -11520, -7424, -3840, 1024, 5376, 8704, 9216, 11264, 13824, 15872, 17920, 18688, 17408, 17152, 15104, 12800, 9472, 5376, -1280, -3072, -6400, -9984, -12288, -13568, -16128, -19456, -18688, -18176, -18176, -17152, -14592, -11520, -7424, -3072, 512, 3328, 7680, 10752, 13056, 15616, 19456, 18176, 16128, 16896, 18176, 15360, 12800, 10240, 5888, -512, -2304, -5120, -10496, -13824, -15104, -18432, -20224, -18176, -16384, -18688, -17408, -15360, -13056, -9216, -3328, 512, 3328, 6912, 12032, 13824, 18176, 19968, 18176, 15360, 18432, 18944, 16640, 13824, 9984, 7168, 1792, -1536, -5888, -12800, -15104, -16384, -17664, -19200, -17920, -19968, -18944, -18688, -16384, -13312, -9472, -3328, 1536, 4608, 10240, 13056, 14848, 16384, 19968, 20224, 19200, 17408, 16384, 17408, 14592, 11520, 5376, 1024, -4096, -8704, -12800, -16640, -19200, -21248, -20480, -18176, -17664, -17408, -18688, -16128, -14592, -9216, -4096, 1536, 6656, 11520, 15360, 17920, 18176, 20224, 20224, 20736, 19968, 20480, 16384, 14080, 9216, 4096, -1024, -5888, -9728, -13824, -16128, -17664, -20736, -21760, -22272, -19456, -18432, -16896, -15616, -13312, -7680, -3072, 3072, 6144, 11264, 14080, 17664, 19968, 21760, 21504, 18944, 17920, 18176, 18176, 15872, 10496, 4352, -2816, -6400, -10752, -14080, -16896, -19200, -22272, -22272, -20736, -18944, -19456, -19456, -16128, -12288, -8192, -3328, 1792, 7680, 13056, 16384, 19456, 20480, 20992, 21248, 20736, 20480, 20992, 17920, 15616, 10752, 4864, 0, -7168, -12544, -15616, -18432, -19968, -22272, -23040, -22784, -22528, -22272, -20992, -17664, -13824, -8448, -3328, 3840, 9216, 14848, 17408, 20224, 23040, 24576, 23040, 21504, 22016, 22784, 20224, 15872, 9728, 5632, -768, -7424, -14080, -17664, -20736, -22784, -24064, -24064, -24064, -24064, -22784, -18944, -15872, -13312, -8960, -4608, 3584, 9984, 13824, 16640, 19456, 22272, 25088, 24320, 24064, 23040, 20992, 19200, 17664, 12032, 6656, -1536, -8448, -14592, -18432, -20992, -22528, -24832, -23040, -23296, -22528, -21248, -20480, -19200, -15104, -8448, -2304, 5120, 10752, 14848, 17408, 20992, 23040, 24064, 23808, 24064, 22528, 21760, 19712, 16640, 11008, 4096, -2560, -9472, -15360, -18176, -21504, -22784, -24320, -24832, -26112, -24320, -21504, -20480, -18432, -14592, -6656, -1024, 4864, 10752, 15872, 20480, 22784, 24064, 24832, 25600, 25344, 23040, 21248, 18176, 16640, 9984, 3584, -2304, -11008, -16640, -21248, -23040, -24320, -25088, -24576, -25600, -24576, -22528, -19456, -16896, -13056, -6144, -3072, 5376, 11520, 17920, 21760, 23808, 24320, 24832, 25856, 26880, 23552, 21504, 17664, 14848, 8960, 4096, -3584, -11264, -17408, -22016, -22528, -24576, -25856, -25856, -26112, -24832, -23040, -18944, -17664, -12800, -4864, 2304, 8960, 14336, 19456, 21504, 23552, 25088, 24576, 25344, 24832, 23808, 21504, 19712, 15104, 6144, 512, -7680, -13312, -19456, -22272, -23808, -25088, -25600, -26112, -25600, -24576, -22784, -20736, -18688, -11776, -4608, 3072, 9216, 15872, 20992, 22528, 24576, 26624, 27392, 26880, 26112, 23552, 21504, 19712, 13568, 6656, -1536, -8960, -14592, -19200, -20736, -23552, -26368, -29184, -28416, -27648, -25088, -22528, -21248, -17152, -8960, -1792, 5120, 9984, 15360, 17920, 22784, 27136, 29696, 27392, 26368, 25344, 22016, 23040, 20992, 13568, 4608, -3328, -7936, -13312, -18688, -23552, -26112, -27136, -26624, -24832, -27136, -25344, -25856, -23552, -18432, -10752, -1280, 4096, 9728, 16896, 22016, 25856, 25344, 25856, 24320, 28672, 27392, 25344, 24320, 20736, 13568, 4096, -768, -7424, -15360, -20736, -26112, -25088, -26112, -26112, -28672, -29184, -25856, -26624, -22528, -17664, -8704, -2048, 3584, 10496, 17152, 23552, 24064, 25344, 26368, 26624, 29440, 27904, 26368, 23040, 19968, 13312, 5632, 0, -9984, -16640, -23552, -24320, -23296, -26368, -26624, -30208, -28160, -26112, -23808, -21504, -18176, -9216, -3840, 4864, 13312, 20736, 24064, 22784, 25088, 26368, 29440, 29952, 26112, 23552, 21248, 20480, 12544, 5888, -2816, -11008, -17152, -23040, -23808, -26112, -26880, -28160, -30208, -26624, -25600, -22784, -21248, -16384, -9216, -1792, 7168, 12800, 18944, 22528, 24320, 26624, 26368, 29440, 27392, 27136, 24832, 22272, 18944, 12800, 5120, -4352, -12032, -19200, -22784, -23808, -25856, -26112, -29440, -29952, -27136, -24832, -22528, -23040, -18688, -9728, 512, 9216, 15360, 19200, 21504, 24576, 26624, 29440, 29440, 26112, 25088, 24576, 24576, 21504, 13312, 2560, -3072, -8192, -13568, -18176, -22272, -25856, -27904, -28672, -27904, -27136, -26880, -26112, -23552, -18944, -12288, -4864, 1792, 8448, 14336, 19456, 23296, 25856, 27648, 28416, 28416, 27648, 26368, 24576, 21760, 16128, 8448, 256, -6912, -13056, -18688, -23040, -26112, -27904, -28672, -28160, -27392, -26368, -25600, -23808, -19456, -12800, -4864, 2560, 9216, 14848, 19456, 23296, 25856, 27648, 28416, 28416, 27648, 26368, 24576, 21760, 16128, 8448, 256, -6912, -13056, -18688, -23040, -26112, -27904, -28672, -28160, -27392, -26368, -25600, -23808, -19456, -12800, -4864, 2560, 9216, 14848, 19456, -256, -512, -3840, 5376, -4352, 5888, -7680, 256, 8704, -8704, 1536, 1280, -3840, 4864, 256, -6400, 1536, 5120, -512, -7168, 3840, 2560, -3840, 0, -1792, 2560, 1792, -1280, -2304, -1536, 4864, -768, -5376, 768, 5120, -1024, -5120, 256, 4096, -768, -2048, -512, 1280, 256, -2048, -1536, 768, 2304, 512, -3328, -1024, 3840, -1792, -2304, 0, 768, 1536, -1792, -1792, 1280, 2048, -2048, -1024, 0, 256, 256, -1536, -1024, 1792, 512, -512, -1792, 0, 1024, -768, -1024, 0, 512, 0, -512, -1024, 256, 1024, -512, -1024, -768, 256, 768, -1280, -1024, 1024, 768, -1536, -1280, 1024, -256, -512, -768, 0, 768, -768, -256, -1024, 768, 768, -1280, -768, 256, 256, -512, -768, 256, 512, -512, -1024, 0, 0, 0, -256, -768, 256, 256, -768, -512, 256, 0, -512, -512, 0, 0, -512, -256, 0, -256, 256, -512, -512, 256, 0, -512, 0, -256, 0, -256, -256, -256, 0, 0, -256, -768, 256, 256, -512, -512, 0, 256, -256, -512, -256, 0, 0, 0, -512, -256, 256, 0, -768, 0, 512, -256, -512, 0, 0, 0, -512, 0, -256, 0, -256, -256, 256, 0, -256, 0, -256, 256, 0, -3328, 1280, 1792, -2816, 6144, -12800, 10496, 1024, -7424, 3584, -2816, 2048, 2816, -3840, -3072, 3840, 4608, -5376, -3584, 5632, -512, -2816, -768, -768, 4608, -768, -1280, -3584, 2304, 5632, -6144, -4096, 5888, 3072, -5888, -2048, 2304, 2560, -1024, -2048, -768, 2816, -1024, -3584, 0, 2048, 2048, -1280, -3584, 2048, 2560, -3072, -1024, -512, 2560, 0, -2816, -768, 2816, 0, -1792, -512, -256, 1792, -1536, -2048, 768, 1536, 0, -768, -2048, 1792, 512, -1792, -512, 512, 256, -512, -1024, -256, 768, 768, -1024, -1280, 256, 768, -768, -1536, 512, 1280, -256, -1792, -256, 768, -256, -1024, -768, 1280, 0, -768, -512, -256, 1024, -256, -1280, -256, 768, -256, -1024, -256, 768, 256, -1024, -512, 256, 0, -512, -768, 0, 512, -256, -1024, 256, 256, -256, -512, -512, 256, -256, -768, 0, 0, 0, -256, -512, 0, 0, -512, -256, 0, -256, 0, -512, -256, 0, -256, 0, -256, -512, 512, -256, -512, -256, 0, 256, -512, 0, -256, -256, 0, -256, -512, 0, 256, -256, -768, 0, 256, -256, -768, 0, 256, -512, -256, 0, 0, -256, -256, 0, -256, -256, -256, -256, 0, 0, -256, -256, 0, 0, -512, 0, 0, 0, 0, -512, 256, -256, 0, -256, 0, 0, 0, -256, 0, 0, 0, 0, -256, 0, 0, -256, 0, -256, 256, 0, 0, 0, 256, -256, -256, 0, 0, 0, 256, -512, 1024, -768, 768, -10240, 18176, -18688, 17152, -6912, -17408, 32512, -20480, 768, 1280, 256, 4352, -3584, 256, -7680, 13568, -768, -10752, 3840, 4864, -2304, -4352, -256, 3328, 4096, -4352, 1024, -8192, 11008, 3840, -17408, 4608, 13824, -9728, -1792, -256, 2816, 1792, -768, -4608, 1280, 6400, -6912, -2304, 2304, 4864, -1536, -3072, -2048, 5120, -256, -3840, -256, 256, 4352, -2560, -4096, 3072, 3072, -3328, 0, -1536, 2560, 512, -4096, -256, 3584, -1024, 1024, -2816, -512, 3072, -1536, -2048, 1024, 1024, -512, -1024, 256, -512, 1024, 768, -1792, -1280, 2048, 0, -2560, 256, 1024, 512, -1024, -1536, 1024, 256, -256, -1792, 256, 2048, -2304, 512, -1280, 768, 768, -1024, -768, 0, 768, -768, -1280, 1024, 768, -768, -1024, 0, 512, 0, -768, -1024, 1280, 0, -1280, -256, 512, 0, -768, 0, -256, 512, -512, -1024, 768, 0, -256, -512, -256, 512, -512, -512, 256, -256, 0, -256, -768, 256, 256, -512, 256, -768, 256, 256, -768, -256, 256, 0, -256, -512, 256, -256, -256, 256, -512, 256, -256, -256, -256, -256, 0, 256, -768, 0, 0, 256, -1024, 0, 256, -512, 0, -512, 0, 0, 0, -512, 256, -256, 0, -512, 0, 512, -512, -256, 0, -256, 512, -512, -256, 256, -512, 0, -256, 256, -256, -256, -256, 256, -512, 256, -256, -256, 512, -768, 0, 0, -256, 256, -256, 0, 256, 0, -512, 0, -256, 256, -512, 0, 0, -256, 256, 0, -512, 0, 256, -512, 256, 0, 0, -256, 0, 256, -256, -256, -256, 256, 256, -256, 0, 0, 0, -256, 256, 0, -256, 256, 0, 0, 256, 0, -256, 256, 0, 768, -10240, 14848, -9984, 3072, 10752, -29952, 27648, 256, -16896, 5632, 4352, 0, -2304, 2560, -9984, 10752, 1024, -5888, -3072, 7168, 768, -8704, 2304, 4352, 768, -2304, 2560, -7424, 3328, 13568, -20224, 768, 16384, -6656, -6144, 4096, -2304, 3584, 512, -2048, -3840, 7936, -2304, -7680, 2816, 7424, -3840, -1792, 0, 768, 1536, -1024, -2304, -1536, 5632, 256, -6144, 2304, 2816, -2048, 0, -512, 512, 2048, -3072, -1536, 2560, 512, 512, -2304, -1024, 2816, -512, -2560, 768, 512, 768, -1280, -256, 256, -256, 1536, -1024, -2048, 2304, 512, -2048, -768, 1536, 768, -1024, -768, -256, 1536, -512, -2048, 0, 2304, -1024, -768, -512, 512, 1024, -1024, -256, -256, 1024, -512, -1536, 1024, 512, -256, -1024, 0, 256, 512, -768, -1280, 768, 768, -768, -1024, 768, 0, -256, 0, -512, 512, 0, -768, 0, 768, 0, -768, -256, 512, 0, -768, 256, 0, -256, 512, -512, -512, 512, -256, 0, -256, -256, 256, -256, -512, 0, 0, 256, -768, 256, 0, -256, 256, -512, -256, 512, -512, -256, 0, -256, 512, -768, -256, 256, 256, -512, -512, 512, 256, -512, -256, 0, 0, 256, -768, 256, 0, 0, 0, -512, 768, 0, -512, 0, 0, 256, 0, -256, 256, -512, 0, 0, 0, -256, 256, 0, 0, 0, -256, 256, -256, 256, 0, -256, 256, -512, 0, 256, 256, 0, 256, -512, 256, 0, 256, 0, 0, 768, -256, 0, 256, 0, 0, 768, -7424, 8960, -3072, -4096, 14336, -22528, 9984, 15872, -20224, 1280, 7424, 256, -3328, 3072, -7424, 6656, 4352, -7168, -768, 3072, 1280, -2816, -4864, 7168, 256, -1280, 2304, -5376, -1792, 15360, -14336, -5120, 14592, -2560, -6912, 5376, -5376, 4096, 3072, -3072, -5376, 6144, 1536, -7424, 1024, 4864, 512, -1792, -1280, -768, 1792, 1536, -2816, -2304, 2816, 3328, -4608, -1024, 3328, 256, -768, -1536, -256, 2560, -2048, -1536, 1280, 768, 1280, -768, -2816, 1024, 2304, -2816, 0, 1024, 768, -1024, -256, 0, 0, 1792, 0, -3584, 1792, 1280, -1792, -1024, 1024, 1280, -256, -1024, -1024, 1024, 256, -1024, -1024, 1792, -256, -256, -768, 0, 1280, -256, -1024, -256, 512, 0, -768, 256, 256, 512, -512, -1024, 256, 512, 0, -1280, 512, 768, -512, -512, 256, 256, -512, 512, -768, 0, 0, -256, -256, 0, 256, 0, -768, 0, 0, -256, 256, -256, -512, 256, -256, 0, -512, 512, 256, -512, -256, 256, 0, -256, -256, 0, 256, -256, 0, -512, 256, 256, -256, 0, -256, -256, 0, 0, -256, -256, 0, -256, -256, 512, -512, -256, 256, 0, 0, -256, -256, 256, 0, -256, 256, -256, 0, 256, -768, 256, 256, -256, -256, 0, 256, 0, 0, 0, -256, 0, 0, -256, 0, 256, 0, 0, 512, -512, 0, 256, 0, 0, 0, 0, 256, 0, 0, 256, 0, 256, -256, -256, -1792, -2304, 8960, -13312, 15104, -8448, -8192, 16384, -3840, -10496, 4864, 5632, -5120, 2304, -2816, -768, 8448, -6912, 512, 1792, -2304, 4864, -9472, 6144, 1792, -2816, 2816, -256, -7680, 9472, 2048, -14592, 9216, 4864, -8448, 3584, 0, -4352, 6656, 256, -5120, -1280, 6656, -4608, -3328, 3584, 1792, -1536, 1024, -2304, -1024, 2816, 768, -3584, -1792, 5120, 0, -4608, 2560, 256, 1024, -1280, -1792, 1536, 0, -768, -512, -512, 2048, 1280, -2816, -1536, 2560, -256, -2560, 1536, -512, -256, 256, -768, 0, 768, 1280, -2304, -1280, 2304, -768, -1024, 256, 256, 768, -256, -1024, -256, 512, -512, -1280, 1280, -768, 0, 256, -1280, 1024, 512, -768, -768, 0, 0, -512, 256, 0, -512, 768, -512, -1280, 512, 512, -512, -1024, 768, 0, -512, 256, -512, -512, 1280, -512, -1536, 256, 512, -256, -256, 0, 256, -256, -512, -256, -256, 512, 0, -1024, 0, 256, 0, -768, 0, 512, 0, -768, 0, 0, 256, -256, -256, 256, 0, -256, -512, 256, 0, 0, -256, 0, -512, 256, 0, -256, 256, -256, 0, -512, 256, 256, -512, -256, 512, -512, 256, -768, 256, 256, -256, 0, 0, -256, 256, 0, -512, 512, -256, -256, 0, 0, 256, 0, 256, 0, -512, 256, 0, 0, -256, 256, 0, 0, 0, 0, -768, -5120, 11520, -14336, 10240, -1280, -8704, 6912, 6144, -10752, -256, 7424, -3584, -1024, 512, -1792, 6144, -5120, -256, 4608, -6400, 6400, -7424, 2304, 5376, -6656, 3584, 1024, -5120, 1792, 6912, -10752, 1280, 7936, -6144, -512, 4864, -7680, 5376, 2048, -2816, -4352, 5120, 256, -5632, 2816, 1792, -1792, 1536, -1280, -1792, 768, 2816, -1536, -4608, 2816, 4096, -5120, 256, 1280, 512, -768, -768, 0, -768, 1024, -256, -1792, 512, 2560, -2304, -2048, 1792, 512, -2304, 1280, -256, -1280, 512, 256, -768, -512, 2304, -1280, -2048, 1024, 256, -1280, 0, 256, 512, -256, 0, -1280, 1024, -256, -1280, 1024, -768, 256, 256, -1280, 768, 0, 0, -768, 0, -256, -512, 256, 512, -1280, 512, 256, -1280, -512, 768, -256, -1280, 512, 256, -1024, 512, -256, -1024, 512, 768, -1792, -256, 512, 0, -512, 256, 0, -512, -256, 0, -768, 256, 512, -768, -512, 768, 0, -768, -256, 256, 0, -256, -512, -256, 256, 0, 0, -256, 0, 0, -512, 0, 0, 256, -512, 512, -768, 256, 0, 0, -512, 256, 0, -256, 0, 0, -256, -256, 512, -768, 0, 0, -256, 0, 0, -256, 256, 0, -1024, -3328, 8192, -10496, 7936, -2560, -2560, 1024, 5632, -6400, -2048, 5376, -768, -3584, 1280, 256, 3072, -5888, 2048, 4608, -7936, 6400, -6656, 2560, 4352, -5888, 2048, 1280, -2304, 0, 4096, -6400, 512, 5888, -5632, -512, 5632, -7680, 3840, 1792, -1536, -3328, 3072, 256, -4352, 2304, 1280, -1536, 1024, -768, -1792, 1280, 1792, -1536, -3328, 1792, 2560, -2816, 0, 0, 1024, -768, -768, 512, -1792, 1024, 512, -1280, 0, 1536, -768, -2048, 1024, 512, -2048, 1792, 0, -2048, -256, 1536, 0, -2048, 1536, 0, -1280, 256, 0, -1280, 768, 512, -768, -512, 1024, -1280, -256, -256, -512, 768, -1024, 256, -256, -768, 768, -256, -512, -512, 256, -512, -512, 256, 256, -1024, 256, 512, -1280, -768, 1280, -768, -1024, 1024, -256, -1024, 512, -256, -1024, 768, 256, -1280, -512, 512, 0, -512, 512, -256, -1024, 768, -256, -768, 0, 256, -512, -512, 256, -256, -256, -256, 0, 0, -256, -256, -256, 0, -256, 256, -256, -256, 0, -512, 256, 0, -256, -256, 0, -256, -256, -256, 512, -512, -256, 256, -256, -512, 256, -256, -256, 256, -512, 256, -1792, -768, 3840, -5888, 5120, -4096, 2304, -3072, 4096, -3072, -2048, 2816, 1280, -4608, 1536, 2048, 0, -4608, 4096, 1024, -4864, 4096, -4352, 2560, 1280, -2048, -512, 2304, -1280, -1024, 2560, -4352, 1280, 3328, -4608, 512, 3072, -4352, 2560, 0, -512, -2048, 1792, -1024, -1792, 1536, 256, -768, 256, 768, -2304, -512, 2560, -1792, -2048, 1024, 1536, -1536, 256, 0, 0, -512, 256, -256, -2048, 1536, 256, -1280, 512, 1024, -512, -1024, 256, 256, -1792, 1280, -256, -1024, -512, 1024, 0, -1024, 1024, -768, -1024, 256, 0, -768, 0, 512, -256, -512, 512, -512, -256, -768, 0, 768, -1024, 768, -768, 0, 512, 0, -768, -256, 256, -768, -256, 512, 0, -256, 0, 0, -768, 0, 256, -1024, -256, 512, 0, -512, 0, 256, -768, 256, 256, -768, -512, 512, -256, -256, 512, -256, -512, 256, 0, -256, -256, -256, -768, -2048, -4096, -5120, -1792, 3584, 5120, 4864, 4608, 4096, 2816, 768, -2304, -5376, -9216, -11008, -9984, -6144, 1536, 9728, 14592, 14080, 6656, 0, -1792, -2560, -3328, -3072, -2816, -7424, -14336, -15104, -9472, 0, 11008, 18944, 22272, 19200, 9472, -512, -7936, -13056, -15104, -11520, -3840, -4096, -8704, -5120, -2560, -1280, 7424, 15616, 18432, 13056, 4608, -512, -5376, -9984, -8960, -6144, 256, 0, -7936, -7424, -5888, -11264, -3328, 12288, 20992, 20224, 11776, 4096, -1024, -11264, -14848, -6656, 768, 1536, -9728, -13312, -6144, -10752, -8960, 12032, 24320, 22528, 14080, 4864, 3072, -5632, -18432, -9728, 1024, 768, -7936, -17152, -7424, -6144, -15360, 5888, 28672, 28416, 18432, 5632, 1792, -5120, -23040, -18688, -256, 4864, -1024, -14592, -9216, 768, -13824, -8192, 25088, 32000, 18176, 3584, 3584, 0, -20992, -27136, 0, 10752, 2560, -12288, -8192, -512, -13824, -16128, 18432, 32000, 20992, 6144, 3584, -2048, -14592, -26624, -5632, 13312, 8704, -8704, -11776, -4096, -8960, -21248, 8192, 32512, 25344, 6656, 4864, 1024, -14080, -28160, -12288, 11520, 9216, -3072, -6656, -5632, -10496, -16384, -1792, 27392, 28928, 14336, 1536, 1024, -10496, -23552, -18944, 8960, 14592, 3072, -10496, -5376, -9984, -17152, -10240, 22016, 29184, 18176, 2560, 5632, -7936, -21248, -21248, 4096, 11776, 8704, -7168, -4608, -10752, -14848, -15360, 14080, 27648, 24832, 768, 5376, -2048, -19712, -26112, 2560, 11520, 10752, -6656, -512, -6912, -17408, -18688, 11520, 21248, 23552, 7424, 6400, -2048, -14336, -26624, -3328, 8960, 13312, -1536, -1792, -5632, -11776, -23296, 2560, 20480, 24320, 8960, 6656, 2048, -9728, -27136, -8704, 8704, 10752, 1280, 256, -5888, -9984, -18688, -7168, 15616, 22784, 15360, 5120, 512, -1792, -18688, -22016, 6144, 13312, 6656, -3072, -2816, -4864, -14848, -22016, 11776, 23296, 15872, 4352, 5632, -3840, -9984, -27136, 2048, 14080, 11520, -3328, -1536, -7680, -5376, -26112, 1024, 20992, 22272, 1792, 7168, -768, -2304, -29440, -8192, 12800, 16128, -5888, 2048, -4864, -4608, -24064, -7168, 15616, 24576, 3584, 9984, -1024, 256, -21760, -15360, 5888, 20224, -768, 512, -5120, -2560, -20992, -16640, 6400, 27648, 7168, 7936, 4864, 2304, -16640, -18944, -1280, 19968, 4096, -768, -2304, -3584, -16640, -19456, -768, 23808, 15360, 7424, 5632, 3328, -11008, -23040, -7680, 15616, 12544, -2304, -256, 1024, -13312, -25088, -4096, 17408, 18432, 5376, 9728, 3840, -7936, -24064, -8704, 8192, 17152, 1280, 2304, 0, -7168, -28416, -8448, 10240, 21760, 6144, 9472, 5888, -1536, -26624, -11264, 3328, 17664, 2304, 3584, 2048, -2816, -28160, -13568, 5120, 20480, 8192, 12288, 7680, 1280, -22272, -16896, -1792, 16128, 8448, 3072, 512, 1280, -22016, -24064, -512, 20224, 11776, 6656, 11264, 5632, -15104, -22528, -4864, 13824, 12288, 3328, 3584, 1024, -13056, -28672, -9472, 17152, 18176, 5376, 9728, 7424, -7424, -26624, -12800, 11264, 16128, 2816, 2560, 3584, -6144, -26368, -17152, 12544, 22528, 5120, 6912, 11008, -2560, -23040, -20224, 6144, 17664, 5376, 1792, 4608, -2048, -20992, -26368, 4352, 24064, 9728, 2560, 13824, 3072, -17920, -24832, 256, 17408, 9472, -1024, 6912, -1536, -14336, -26624, -5376, 20992, 17152, -768, 11776, 5888, -9472, -27648, -7936, 14592, 14848, -3328, 7424, 2816, -8192, -27136, -12800, 13568, 23552, -1536, 9728, 9728, -3840, -26880, -13824, 8704, 20224, -3072, 5120, 5632, -2816, -25088, -17920, 5632, 25344, 1024, 4096, 12288, 3584, -25344, -19200, 3840, 20992, 512, 0, 11264, 2048, -23808, -20480, 0, 21504, 7424, -768, 14592, 8192, -20224, -24064, 256, 16896, 6912, -4864, 12544, 7424, -18688, -27904, -1792, 13824, 13312, -4352, 15872, 13568, -11776, -28928, -1024, 11008, 13056, -7680, 11776, 9472, -10752, -32768, -5888, 6656, 17664, -4608, 13056, 15104, -512, -31232, -7680, 6144, 16896, -6912, 7936, 13056, 256, -32768, -12288, 3328, 18176, -2816, 8448, 16896, 5632, -28160, -14592, 2048, 17408, -2304, 3072, 13568, 7168, -26624, -22272, -1024, 17152, 2048, 2048, 18432, 13568, -20480, -23296, -1024, 15104, 2560, -3328, 16128, 11264, -20736, -27904, -4864, 11776, 8448, -1536, 19456, 14592, -11008, -26624, -6144, 9216, 10752, -6656, 14080, 13056, -8704, -32256, -9984, 4864, 14848, -5376, 17408, 18176, -2048, -29184, -8192, 512, 15872, -6144, 13312, 13824, -1024, -30720, -13568, -5632, 18176, -2048, 12544, 15872, 7936, -26112, -13312, -6400, 17920, -1280, 6144, 14080, 8960, -27904, -17664, -10240, 15104, 4096, 6400, 16640, 14080, -20480, -17920, -9472, 12032, 5888, 1792, 12288, 13056, -18688, -24832, -12288, 7680, 11776, 1536, 14592, 18944, -9472, -25088, -8704, 5376, 12288, -2560, 11264, 14848, -8704, -31488, -11776, -512, 15616, 512, 12800, 17664, 2560, -28160, -10240, -1280, 15104, -2304, 7936, 13568, 4864, -32256, -15104, -5120, 15872, 2048, 8192, 16384, 12544, -26880, -15104, -4096, 14848, 512, 4352, 12800, 11520, -26112, -21248, -7936, 11776, 6144, 3840, 13568, 17664, -16640, -22016, -6144, 10752, 6400, -1024, 11520, 16384, -14848, -28672, -9472, 7680, 10496, -1536, 13056, 19200, -6144, -26880, -8192, 6656, 10496, -4864, 9984, 15872, -3584, -29952, -13056, 1792, 13824, -3328, 8960, 19968, 4864, -26880, -12032, 2304, 14848, -4864, 5376, 17664, 4608, -28928, -16896, -2560, 13312, -2560, 3584, 19200, 10752, -21248, -15360, -1280, 13312, 0, -768, 17664, 11008, -21248, -21248, -5376, 8960, 4352, -3328, 18432, 14592, -13824, -20992, -2560, 7424, 7168, -7424, 16640, 13312, -11520, -25088, -5376, 256, 10240, -7680, 16384, 16128, -1792, -24064, -2304, 256, 13056, -9216, 13056, 13824, -2048, -29440, -5888, -5632, 12032, -7680, 12288, 16640, 6144, -23040, -3328, -3840, 11776, -6656, 7680, 14080, 5376, -25600, -9472, -6656, 7936, -2560, 6144, 16640, 10496, -18176, -8960, -2560, 6400, -512, 1024, 14848, 8192, -17664, -15616, -4096, 512, 2048, 256, 17152, 10752, -8448, -14336, -256, -256, 5120, -3328, 15104, 8448, -7168, -20992, -2560, -5120, 5632, -3840, 16384, 10240, -256, -17920, 0, -4352, 7424, -5632, 13568, 8448, 256, -21504, -3840, -7424, 5632, -4864, 13568, 11008, 5632, -16384, -1792, -4864, 6400, -4608, 9472, 9728, 4096, -18688, -7680, -8448, 2816, -3584, 8192, 12800, 7936, -11520, -4352, -3840, 4096, -1024, 4096, 11008, 5888, -12544, -11008, -7680, -512, -256, 2048, 13312, 9216, -6400, -8192, -3328, -256, 2816, -256, 10752, 7680, -6400, -12544, -6400, -4608, 2560, -1792, 11264, 10240, -512, -8704, -2816, -3840, 5376, -1536, 7424, 8448, -1280, -13824, -7424, -7680, 3328, -1536, 7424, 11776, 3840, -8192, -2560, -4608, 4096, -256, 3328, 9216, 2304, -11520, -7680, -8192, 0, 256, 3072, 11008, 7168, -5888, -4096, -4096, 1536, 2304, 512, 8448, 5632, -8448, -8704, -6912, -2816, 512, 256, 8960, 9216, -3584, -4096, -2816, -1280, 2048, 768, 6144, 8192, -4864, -7680, -7424, -4352, -1024, 256, 5120, 11008, -1280, -3584, -3328, -1024, 0, 1792, 2816, 9984, -2304, -5888, -7168, -4352, -4096, 256, 2304, 11264, 768, -1792, -3840, -1024, -1024, 1792, 1280, 9728, 768, -5120, -7680, -4864, -4864, -2048, 0, 10240, 4352, -1536, -1792, -768, -512, -256, 1024, 8192, 4096, -5120, -5376, -6656, -4352, -4608, -768, 7168, 8192, -1792, -256, -2304, 1024, -2304, 768, 5632, 8704, -4864, -3584, -6912, -3328, -6912, -2560, 4096, 11264, -2048, 1280, -1536, 768, -3072, 256, 3328, 10240, -3072, -2816, -6400, -4352, -6912, -3840, 1280, 11520, 1024, 512, 0, 0, -2304, -1280, 1536, 9728, 512, -4352, -3584, -5120, -6144, -5888, 0, 9728, 4864, -1024, 2816, -1024, -1792, -2560, 1024, 6912, 5120, -5120, -2304, -5888, -5632, -7680, -1536, 6656, 8960, -2048, 3072, 512, -1024, -3840, 512, 5120, 8192, -4096, -1792, -3840, -5632, -9472, -3584, 4608, 9984, -768, 1280, 2048, -1280, -4608, -512, 4608, 8704, -1024, -3584, -1024, -5376, -8960, -6400, 3840, 9216, 2048, -1024, 5376, -1280, -4352, -3584, 5888, 6656, 2304, -5632, 1024, -6400, -8192, -10240, 3584, 6912, 6144, -3072, 7680, 256, -2048, -6656, 6144, 5376, 4864, -7168, 2304, -5120, -7168, -13056, 1792, 5888, 7680, -3840, 6912, 2304, -1792, -8192, 4096, 6400, 5888, -5376, 1024, -2048, -6912, -12800, -2560, 6400, 7424, -2304, 3328, 6144, -1792, -7168, -768, 8704, 5120, -3072, -2304, 2560, -7936, -11008, -7424, 7680, 5888, 512, -768, 9728, -2304, -4864, -4864, 9984, 4608, -256, -5120, 6400, -7424, -9216, -10752, 6656, 4352, 3072, -3584, 11008, -768, -3840, -7424, 8960, 4864, 1536, -7168, 6912, -4608, -9216, -12288, 4096, 4352, 3840, -3840, 9984, 3072, -3328, -7424, 6144, 6144, 2304, -6400, 4864, -256, -9984, -12800, 256, 4608, 2816, -2816, 6400, 6656, -3584, -6656, 3072, 8192, 2560, -4352, 1536, 4352, -8448, -12288, -3584, 5120, 1536, -1792, 2816, 9216, -2304, -6656, -256, 8704, 2816, -2304, -1024, 6400, -6400, -12544, -6656, 4864, 1024, -1024, 1280, 10496, 768, -5376, -2048, 7936, 3072, -1792, -2816, 5888, -3328, -12032, -9472, 3328, 1536, -768, 256, 10240, 3584, -4352, -3584, 6656, 4096, -512, -3072, 5120, -768, -10240, -11264, 512, 1536, -512, -1024, 8960, 6144, -2304, -4864, 4864, 4352, 512, -3328, 4096, 1280, -7424, -12288, -1792, 1024, 768, -1792, 7168, 7168, 512, -5376, 3328, 3584, 2304, -3584, 2816, 2304, -3840, -12544, -4352, -768, 1536, -2816, 5120, 7680, 3584, -5888, 1792, 3072, 3584, -2816, 1536, 2560, -1024, -11776, -6144, -2560, 1536, -2048, 2816, 7424, 6144, -3840, 0, 2816, 3584, -1024, -512, 2816, 768, -9472, -9216, -3328, -768, -512, 512, 7168, 6912, -512, -2560, 3584, 2304, 1792, -2048, 3328, 768, -5376, -10752, -3584, -3584, 1024, -1536, 6144, 6144, 3328, -4096, 3072, 768, 3584, -2048, 3072, 1024, -1792, -11264, -4608, -5120, 1280, -1536, 4608, 5632, 5888, -3328, 1536, 512, 3328, -1024, 1280, 1280, 256, -9216, -6656, -5120, -256, -256, 2560, 5888, 6400, -768, -1024, 1280, 2304, 1280, -512, 2048, 256, -6144, -9216, -4608, -2560, 1024, 256, 6144, 5888, 2816, -2304, 2048, 1024, 3072, -1792, 2304, 256, -3072, -10240, -4864, -4096, 1024, -1024, 5376, 5376, 4096, -2304, 1536, 512, 3328, -1024, 1536, 1536, -1024, -8448, -6144, -4608, -512, -512, 2560, 5376, 4608, 0, -768, 768, 2048, 1536, -256, 2048, 0, -4608, -7936, -4864, -2560, 256, 0, 4864, 5120, 3328, -1280, 1024, 1280, 3072, -1024, 1280, 512, -1792, -8704, -6144, -4352, 256, -1024, 3328, 5120, 5376, -768, 512, 1280, 3584, 0, 512, 1024, 0, -6656, -7168, -5120, -1536, -1024, 1024, 4608, 5888, 1536, -768, 1280, 2304, 1792, -256, 1536, 768, -3584, -8448, -5632, -3584, -256, -256, 4096, 5632, 4352, -1024, 1024, 1024, 2560, -512, 1024, 768, -1024, -7680, -6400, -4864, -512, -512, 2816, 5120, 5888, 0, 0, 512, 2560, 768, 256, 1024, 256, -5888, -7680, -5632, -2048, -256, 1024, 4864, 5888, 2560, -768, 1024, 1536, 2048, -512, 1280, 512, -3328, -8448, -5888, -3840, 0, -256, 4096, 5376, 4096, -768, 768, 1024, 2816, 0, 1280, 1536, -768, -6912, -6400, -4864, -1024, -512, 2304, 4864, 4864, 512, -768, 512, 2048, 1536, -256, 2048, 0, 0, 512, 8448, 10752, 14848, 18176, 20224, 21760, 22528, 23296, 24064, 20224, 24320, 20992, 27136, 22016, 26880, 12032, 4096, -1536, 3328, 11264, 7936, -3840, -9728, -9216, 5120, 17920, 10496, 12288, 14848, 6144, -14592, -32512, -30464, -26112, -32256, -32768, -28416, -19968, -20992, -22528, -22272, -15360, -16896, -25088, -26624, -25344, -24832, -25344, -26624, -25856, -22528, -22272, -23296, -15616, -6912, -8704, -13824, -14080, -11520, -6144, -2560, -1280, -1024, 1280, 8704, 16128, 25856, 24064, 19968, 13312, 13056, 13312, 18944, 20736, 19712, 15104, 11776, 4352, 1792, 9984, 13568, 12032, 10752, 16896, 21248, 18688, 13312, 7168, 5632, 2816, 2048, 2816, 0, -3840, -5888, -3840, -3584, -1536, 4096, 11776, 15872, 18176, 19456, 23040, 26112, 26368, 26368, 25856, 25600, 23040, 19200, 16128, 17152, 12544, 9472, 7168, 3072, 1280, 1536, 3840, 3840, 2048, -1792, -3072, -1024, -2560, -7168, -6144, -4352, -6400, -12800, -16384, -20736, -26368, -29696, -29696, -28928, -24320, -18432, -13824, -10496, -12032, -16640, -16640, -12800, -8448, -6144, -1792, 2816, 2048, -1024, -3328, -7168, -13056, -19200, -23040, -23296, -23040, -23040, -22272, -22528, -21248, -21504, -20992, -20736, -20736, -19456, -16640, -18176, -21760, -21504, -20224, -21248, -20736, -19712, -18432, -17920, -16640, -16896, -16896, -16640, -16896, -17408, -15616, -14336, -13056, -9216, -3328, -768, -1280, -2048, -3072, -3072, 768, 4096, 5376, 7936, 12800, 17664, 19712, 20992, 23040, 26112, 28160, 29184, 29696, 29952, 30208, 30464, 29696, 28672, 27904, 26880, 25088, 25344, 26368, 26112, 23296, 18688, 16384, 16128, 15616, 14592, 13056, 10240, 6144, 8960, 14592, 19200, 21504, 20224, 16640, 9472, 1024, -6656, -11520, -14592, -13824, -11776, -11520, -13824, -17152, -17152, -12288, -4096, 3840, 8960, 11264, 11520, 11264, 11520, 11776, 9728, 5888, 512, -3840, -8704, -13312, -15360, -17920, -19712, -20480, -20224, -18944, -19712, -21504, -22016, -20480, -18432, -17408, -18432, -20480, -22272, -23552, -24576, -25856, -26624, -26624, -25856, -23808, -23040, -22784, -22016, -21760, -21504, -21248, -20992, -20736, -20224, -19712, -19456, -18688, -18176, -16896, -15872, -14080, -9984, -7936, -6912, -6400, -7936, -9472, -11776, -13056, -13568, -13824, -12288, -11520, -9728, -5120, 768, 6144, 8960, 9984, 8192, 4096, 1280, 768, 0, -1536, -3328, -3328, -2816, -512, 3584, 7168, 10240, 12800, 13568, 12800, 14080, 16384, 18944, 23040, 26880, 27648, 28672, 27136, 26624, 27904, 28672, 31488, 32512, 32512, 32512, 32512, 32512, 32512, 30208, 28928, 27392, 28160, 29184, 28416, 26624, 25856, 25856, 26112, 26368, 25344, 25344, 22784, 18688, 13568, 8960, 5120, 0, -5632, -11008, -16128, -19712, -20992, -19456, -16640, -12288, -9216, -7424, -6144, -6400, -7424, -9472, -10240, -12544, -15104, -17152, -18688, -19456, -19968, -20224, -19200, -18688, -18944, -19200, -17408, -13312, -11264, -7680, -4864, -2304, -1536, -2304, -3328, -6144, -8448, -8960, -7936, -7680, -8960, -10240, -11264, -11520, -13056, -13568, -13824, -12800, -12800, -12032, -10752, -12800, -14080, -13824, -14336, -14336, -13824, -13824, -12544, -12288, -10496, -8192, -7168, -4608, -3328, -1280, 1536, 4608, 8448, 12544, 15360, 18176, 19968, 22528, 24320, 24832, 23808, 22528, 23296, 23808, 24832, 25088, 24832, 24064, 23296, 21760, 20736, 18432, 17920, 16896, 15616, 15360, 16384, 16896, 18944, 21248, 23552, 26112, 27648, 27904, 27392, 26112, 24832, 24320, 23296, 22272, 20480, 18944, 17152, 15872, 15616, 14848, 15616, 15616, 14592, 13568, 11008, 8960, 6912, 6400, 6144, 5120, 5120, 5632, 6912, 8704, 9216, 8192, 5376, 2048, -768, -2560, -4096, -4608, -4096, -4096, -4864, -3840, -2816, -2816, -3072, -5120, -8704, -11520, -15104, -18432, -20480, -22784, -24064, -24320, -26112, -28416, -29184, -28416, -28416, -27648, -27136, -26624, -25856, -25088, -23808, -23040, -22016, -22016, -21248, -20992, -20736, -20224, -19456, -18688, -17920, -18432, -19968, -20736, -20224, -20224, -18432, -15360, -11008, -7936, -6400, -6912, -8704, -9472, -10240, -10752, -10496, -9984, -9216, -8704, -6400, -3072, -1024, 1280, 3072, 4096, 4352, 3840, 3328, 1536, -1024, -1792, -2048, -1536, -256, 1024, 1792, 2304, 3072, 4096, 4864, 4864, 5632, 7168, 7424, 7168, 7424, 7680, 8704, 10240, 12544, 14592, 18176, 19968, 21760, 23552, 24576, 24320, 22784, 21760, 22016, 23808, 25344, 26624, 26112, 25600, 24064, 21760, 19712, 18688, 17664, 16896, 16128, 15360, 15360, 15104, 14592, 13312, 12032, 10496, 7936, 4608, 1536, -768, -1792, -2816, -3072, -3584, -4608, -5632, -5888, -5632, -6144, -7680, -9472, -10496, -11264, -12800, -14336, -16384, -17152, -16640, -15872, -14848, -14848, -14848, -15104, -15616, -15872, -16896, -18432, -19968, -20224, -19712, -18688, -17408, -16384, -15616, -14336, -13568, -13824, -13312, -13312, -14592, -16128, -17664, -17920, -17408, -16640, -15872, -15104, -14592, -14336, -14848, -15360, -15616, -16128, -16384, -15872, -15616, -15360, -14848, -13824, -12544, -11520, -10752, -9984, -9216, -8192, -7168, -5632, -3328, -1792, -768, 512, 3328, 7168, 10496, 13312, 16384, 18176, 18688, 18688, 17920, 16384, 15616, 15360, 16384, 16896, 16640, 16896, 16384, 15616, 15360, 15872, 16640, 16384, 16896, 17152, 17152, 17408, 16896, 16384, 16896, 17408, 18688, 19456, 18944, 18432, 16896, 14848, 13312, 11776, 10752, 9728, 9728, 10496, 12032, 13312, 13312, 12288, 11520, 10752, 10240, 9728, 8704, 7424, 6912, 6656, 7168, 7424, 7168, 7424, 7680, 7936, 7168, 6144, 5376, 4864, 4352, 3584, 2560, 1536, 768, -1024, -2304, -3840, -4864, -6656, -8448, -10240, -12544, -14080, -15360, -16640, -17920, -18688, -18432, -18432, -18176, -17920, -18176, -19200, -19968, -20736, -21248, -22016, -22016, -21760, -21504, -20992, -20480, -19712, -18432, -17664, -16896, -16128, -15616, -15616, -15616, -15616, -15616, -15360, -14848, -13568, -12288, -10752, -9216, -7680, -7168, -7680, -8192, -8448, -8192, -7936, -7168, -5632, -4608, -2560, -1280, 0, 768, 1536, 2816, 4096, 4864, 5632, 6144, 6656, 6912, 7424, 8704, 10240, 11776, 12288, 12288, 12288, 11520, 10240, 9216, 8448, 7936, 8448, 8960, 10240, 12288, 14080, 15872, 17408, 18688, 19456, 19968, 19968, 19712, 20224, 20992, 21760, 22272, 22272, 22272, 22016, 22016, 22016, 21248, 19968, 18176, 16128, 14080, 12288, 11264, 9984, 9216, 9216, 9216, 8960, 8192, 7168, 6144, 4608, 3328, 2304, 1536, 1024, 256, -512, -1280, -2816, -4352, -5120, -5376, -5120, -5376, -6144, -7168, -8192, -8704, -8448, -8448, -8960, -9472, -10240, -11008, -12032, -13312, -14848, -16128, -17664, -18944, -19712, -20480, -20736, -20992, -20736, -20480, -19712, -18944, -17664, -15872, -13824, -12288, -12288, -13056, -13824, -14592, -14592, -14592, -14336, -14080, -14080, -14336, -14592, -14336, -14080, -13824, -13824, -13824, -13824, -13312, -12544, -11520, -10496, -9728, -8704, -7936, -7424, -6912, -6144, -5120, -4352, -2816, -1792, -768, 0, 1280, 2560, 4096, 5632, 6912, 7936, 8704, 9728, 10752, 11264, 11520, 12288, 12800, 13312, 14592, 15616, 16384, 16384, 16640, 16640, 16128, 15360, 14592, 14080, 14080, 14848, 15616, 16128, 16640, 17152, 17664, 18176, 18944, 19712, 20224, 20224, 19712, 18944, 18176, 17408, 16896, 16128, 15360, 14592, 14080, 13056, 11776, 10240, 9216, 7680, 6400, 5120, 4352, 4096, 4352, 4096, 3584, 3072, 2560, 1792, 768, -256, -1280, -2816, -3840, -4352, -4608, -4608, -4864, -5376, -6400, -7424, -8192, -8448, -8448, -9216, -9984, -11008, -11776, -12800, -13568, -14336, -14848, -15104, -15360, -15616, -15872, -16128, -16640, -16896, -17152, -17408, -17920, -18432, -18432, -17920, -17152, -16128, -15616, -15360, -15360, -14848, -14336, -13824, -13568, -13312, -13312, -13312, -13056, -12800, -12544, -12032, -11520, -11008, -10240, -9472, -8960, -8704, -8192, -7424, -6400, -5376, -4608, -3584, -2304, -1024, 0, 1024, 1792, 2816, 3840, 4608, 5376, 6400, 7168, 8448, 9472, 10496, 11264, 11776, 12032, 12032, 11776, 11776, 11520, 11008, 10752, 10752, 11008, 11776, 12288, 12544, 12800, 13312, 14080, 15104, 15872, 16640, 16896, 17152, 17408, 17664, 17664, 17920, 18432, 18944, 18944, 18688, 18432, 18176, 17664, 16640, 15616, 14592, 13568, 12800, 11776, 11008, 9728, 8960, 8192, 7168, 5888, 4864, 4352, 4352, 3840, 3328, 2816, 2304, 1280, 256, -768, -1536, -2304, -3072, -3584, -4352, -4864, -5888, -6912, -7936, -8960, -9728, -10240, -11008, -11776, -12288, -13312, -14080, -14592, -15616, -16384, -16896, -17152, -17408, -17664, -17920, -17920, -17920, -17664, -17664, -17920, -18176, -17920, -16896, -15872, -15104, -14080, -13312, -12800, -11776, -11008, -10496, -9728, -9216, -8960, -8960, -8704, -8448, -8448, -8448, -8448, -7936, -7680, -7168, -6656, -6400, -6144, -5376, -5120, -5120, -4864, -4864, -4608, -4352, -4096, -3840, -3328, -2816, -2048, -768, 512, 2304, 3840, 5376, 6912, 8448, 9728, 10496, 11520, 12288, 13056, 13568, 14080, 14336, 14336, 14336, 14336, 14336, 14336, 14336, 14080, 14592, 14848, 15360, 15616, 15872, 15872, 16384, 16896, 17408, 17664, 18176, 18432, 18688, 18944, 18432, 17920, 17152, 16128, 15360, 14592, 13824, 12800, 11776, 10496, 9216, 7936, 6912, 5888, 4864, 4096, 3584, 3072, 2816, 2304, 2048, 1280, 512, -256, -1024, -2048, -2560, -3840, -4608, -4864, -5120, -5632, -5632, -5888, -5888, -6144, -6656, -7424, -7936, -8448, -8960, -9216, -9472, -9728, -10496, -11264, -11776, -12288, -12800, -13312, -13824, -14336, -15104, -15616, -16128, -16128, -16384, -16640, -16384, -16128, -15872, -15616, -15360, -15104, -14848, -14592, -14848, -14592, -14592, -14080, -13568, -12800, -12544, -12032, -11776, -11008, -10240, -9472, -8448, -7936, -7168, -6656, -5888, -5120, -4096, -3584, -3072, -2304, -1280, -512, 256, 1280, 2304, 3328, 4352, 5376, 6144, 6656, 7424, 8192, 8960, 9472, 9472, 9728, 9984, 10496, 11008, 11264, 11520, 11776, 12288, 12800, 13056, 13568, 13312, 13312, 12800, 12288, 12032, 11776, 11776, 11776, 11776, 12032, 12288, 12544, 13056, 13824, 14336, 14848, 15360, 15616, 15872, 15872, 15872, 15616, 15104, 14592, 14080, 13824, 13568, 13312, 13056, 12544, 11776, 10496, 9216, 7936, 6912, 5632, 4608, 3584, 2816, 2304, 1536, 768, 0, -512, -1280, -2048, -2816, -4096, -5120, -6400, -7168, -7936, -8704, -9472, -9984, -10496, -10496, -10752, -10752, -10752, -11008, -11520, -11776, -12032, -12544, -12800, -13312, -13824, -14336, -14592, -14848, -15360, -15616, -16128, -16384, -16384, -16384, -16128, -16128, -15616, -15104, -14848, -14592, -14080, -13824, -13568, -13312, -13312, -13056, -12800, -12544, -12032, -11776, -11520, -11264, -10752, -10240, -9728, -8960, -8192, -7680, -7168, -6400, -5632, -4864, -4352, -3840, -3072, -2304, -1280, -256, 768, 1792, 2816, 3840, 4864, 5888, 6400, 6912, 7680, 8704, 9216, 9472, 9728, 9984, 10240, 10752, 11264, 11520, 11776, 12032, 12544, 12800, 13312, 13568, 13312, 13056, 12544, 12032, 12032, 11776, 11776, 11776, 12032, 12032, 12288, 12800, 13312, 14080, 14592, 15104, 15616, 15872, 15872, 15872, 15616, 15360, 14848, 14336, 13824, 13824, 13568, 13056, 12800, 12032, 11264, 9984, 8704, 7424, 6400, 5120, 4096, 3328, 2560, 1792, 1024, 512, -256, -768, -1536, -2304, -3584, -4608, -5632, -6656, -7680, -8448, -8960, -9728, -10240, -10496, -10496, -10752, -10752, -11008, -11264, -11776, -12032, -12288, -12544, -13056, -13568, -14080, -14336, -14592, -15104, -15360, -15872, -16128, -16384, -16384, -16128, -16128, -15872, -15360, -15104, -14592, -14336, -14080, -13568, -13312, -13312, -13056, -13056, -12800, -12288, -11776, -11520, -11264, -11008, -10496, -9984, -9216, -8704, -7936, -7424, -6656, -6144, -5376, -4096, -256, -512, -256, -768, 256, -512, -512, -1024, 512, 1536, 512, -512, -512, 0, 1792, 2048, 1024, -512, -512, 1536, 1280, 1536, 0, -512, 1280, 3072, 2560, 0, -1280, -768, 1280, 2560, 2304, -1792, -2048, -1792, 1280, 2048, 768, -2304, -3328, -1280, 768, 1280, -1280, -2304, -1024, 0, 1536, 0, -1024, -2816, -1792, 768, 1024, 0, -1280, 0, -256, 1280, 256, 1024, -1536, -1280, -768, 3072, 2304, -512, -2560, 1024, 2816, 2048, -1024, -1280, -2304, -1536, 256, 4864, 3328, -512, -5632, 1024, 2304, 1536, -6656, -1024, 768, 3072, -2304, 0, 512, 0, -3840, 1024, 2048, -2048, -5120, 0, 3840, 2048, -3328, -512, -1024, -1024, -512, 3072, 768, -3584, -4608, 256, 5376, 3328, -2304, -6400, -2048, 4352, 3840, 1280, -3584, -4352, 1280, 4864, 3328, -3840, -4352, -768, 2560, 5120, 2560, -6912, -4864, 1280, 2816, 3072, 768, -3328, -4352, -256, 1536, -768, -512, 256, -256, -2816, -4352, 1792, 1792, -1792, -1792, -3328, 2304, 0, -1280, 2304, -1280, -2304, 1536, 1280, -512, -4096, -1280, 3840, 4352, -2560, -5120, 256, 2816, 3584, -256, 256, 2560, -2816, -2048, -256, 4608, 3328, -512, -3072, 256, -4096, -512, 8704, 6912, -7168, -10752, -768, 10752, 6656, -3584, -9984, -4864, 1792, 6656, 6400, -4096, -14080, -6656, 8192, 14592, 1024, -17664, -12288, 1536, 19200, 7424, -13056, -17152, -8192, 13056, 14336, 1792, -14592, -19200, 3584, 16128, 11008, -7424, -20992, -6912, 7936, 14336, 7168, -11008, -20736, -7936, 15104, 21760, 256, -25600, -15104, 2048, 26112, 10496, -10752, -23552, -13312, 18432, 20224, 7424, -26368, -21760, -256, 29952, 12544, -13824, -28928, 1792, 6144, 24064, -7168, -9984, -21504, 9984, 7168, 15616, -11264, -7168, -17152, 15616, 5888, 8960, -10240, -5888, -9472, 1536, 9728, 17664, -10752, -15616, -13568, 14848, 22016, 512, -23808, -6144, 4864, 18432, 4352, -4864, -22272, 11520, 2560, 16384, -3328, -11520, -14592, 9728, 12288, 9216, -13056, -8960, -9472, 11776, 6656, 9472, -18688, -7168, -3072, 11264, 5632, 6912, -21504, -5632, 1536, 17920, 4352, -6144, -20992, -1792, 6656, 20224, 2304, -16128, -19968, 1536, 23040, 17408, -14080, -30208, -768, 23552, 15872, -2560, -18688, -12800, 3584, 28160, 3840, -1280, -30208, 1280, 17664, 13568, 5632, -20736, -11520, 7424, 12032, 20480, -17664, -7168, -13312, 14848, 16896, -256, -6400, -15104, -5632, 27392, 512, 11008, -27648, -3328, 5120, 15104, 14336, -14848, -16896, -1792, 8704, 29184, -10752, -16128, -12800, 10752, 17664, 11264, -16128, -9472, -12800, 29184, 6912, 4608, -12544, -20736, 5120, 18944, 13056, -3584, -26112, -1024, 10240, 17920, 9728, -16384, -18688, 2816, 15360, 19456, -10496, -7680, -19968, 10752, 11776, 17408, -16128, -12288, -14336, 22784, 11008, 7168, -25600, -13568, 10496, 15360, 2816, -1536, -19456, -4096, 11264, 13312, 2304, -17152, -12288, 2560, 17664, 7680, -256, -21504, -1024, 9216, 18432, -5888, -5632, -6912, -8448, 14080, 18944, -2816, -22016, -256, 6912, 9216, 7936, -1792, -25856, 12544, 1280, 16896, -1792, -11776, -9984, 2304, 16384, 11264, -16128, -8448, -5632, 14080, 5888, 11008, -20224, -6144, 1280, 7424, 13824, -3584, -15104, -13568, 16128, 8192, 5120, -8704, -8192, -9216, 23808, -512, 5120, -8960, -9728, 4608, 13056, 15616, -24064, 3840, -3584, 4352, 17664, 1280, -22272, 4096, 7168, 8704, 256, 8704, -14592, -13568, 30208, -5632, 8704, -2560, -18176, 5888, 17920, 6400, -7424, -1792, -4864, -768, 29952, -8448, -3072, -5376, -4864, 11008, 21504, -9728, -14592, 8448, 0, 8192, 10496, -1792, -26368, 21760, 512, 512, 14848, -3584, -26368, 26368, 1792, -4352, 8704, -8192, -15104, 18176, 13056, -19968, 19456, -16640, -7680, 16128, 12288, -16896, 2304, -2816, -7168, 13312, 12800, -18432, -9472, 18688, -15616, 19200, 1792, -13056, -11264, 18688, -768, -2816, 10240, -19968, 1792, 16128, -3840, -4096, 7680, -13568, 3072, 9728, 3072, -10752, 9984, -16128, 12032, 5888, 0, -5888, -2816, 2048, -6400, 15360, -9472, -3840, -768, -2304, 3072, 6912, -3584, -10240, 5632, 3072, 3584, 3840, -7936, -3584, 3840, 5888, -3072, 3584, -7936, 4864, 3328, 8192, -9984, 6912, -13056, 11008, 2048, 0, 1280, -6656, 4096, 1024, 4864, -6144, 4352, -4608, 1536, -512, 12544, -17152, 9984, -256, -7680, 11776, -3328, -4096, -2304, 5376, -4352, 6912, 512, -8704, 4864, -768, 6144, 2048, -9728, 3328, -2560, 5632, 3840, -8704, 512, 1024, -2560, 4608, 3584, -3840, -3840, 6656, -3072, 7168, -5376, 0, -1536, 0, 1792, 0, -3840, 1536, -512, -4608, 2304, 2048, -4608, -3840, 15104, -24064, 20736, -10240, -6144, 3584, -4608, 6400, -3840, 1024, -5376, -2304, 6144, -5120, 768, 768, -13312, 14336, -7424, 1024, 1280, -13056, 11520, -12800, 18688, -19200, 3328, 4352, -12288, 9728, -2560, -4096, 1280, 1024, -5632, 768, 4352, -6912, -5888, 10752, -7680, -1280, 10496, -13568, 2560, 5888, -7168, 256, 7424, -12032, 2304, 3328, -768, -4608, 2304, -3328, -2816, 4608, 3072, -13568, 7168, 256, -10496, 10496, 1792, -15616, 8192, 0, -8704, 4096, 2304, -18944, 11520, -5888, -8448, 5632, 9984, -26624, 12544, 5888, -24576, 21248, 1280, -11776, 9216, -1024, -11520, 13824, -6400, -6656, 5376, 512, -9984, 13056, -6400, -6400, 11008, -5632, -6400, 7680, -512, -8192, 9984, 3584, -17664, 10752, 5632, -19968, 15360, 5888, -21248, 8448, 11264, -18944, 4864, 17664, -28928, 11008, 13568, -22528, 13056, 4352, -18944, 10752, 256, -9728, 1024, 9984, -17152, 3072, 8960, -9984, -5888, 18688, -20992, -1280, 17152, -18176, -1280, 10752, -9216, -12288, 19968, -16384, -1024, 10240, -12288, -1792, 12800, -20480, 4352, 7936, -14336, 2304, 1536, -4608, -9216, 11008, -9472, -7424, 12032, -12032, -4608, 8448, -7424, -6912, 10240, -7680, -9472, 13056, -11776, -6400, 15616, -16896, 1792, 7168, -12288, 7680, -3840, -2048, -1536, 4352, -3584, -2304, 6656, -5888, 1024, 2304, -3840, 3072, -2304, 4096, -5632, 1792, 5632, -13056, 15104, -7424, -5888, 13824, -12544, 1536, 5120, -4864, -2816, 4352, -768, -7680, 8192, -6912, -1280, 4096, -7168, 1024, 1024, -6912, 8192, -11776, 6912, -4608, -2048, 2816, -6400, 4608, -1536, -4352, 2560, 256, -4608, 6144, -8448, 2560, 2048, -3072, -2560, 5376, -4864, 0, 2048, -4608, 3584, 2816, -11264, 9984, -5632, -1024, -1536, 2816, -3840, -3328, 4352, -4352, -1536, 3328, -5632, -256, 1792, -1280, -2048, 0, 1024, -6144, 7424, -5888, 0, 5120, -6400, -2048, 7680, -8704, 7936, -7424, 2816, -2304, 5376, -3840, -256, 2560, -2304, -2816, 8192, -5888, -512, -3584, 6912, -4864, 2560, -1024, -5888, 3584, 3328, -11520, 12288, -11264, 2816, -1024, -1792, -768, 1024, -512, -8704, -2048, 9472, -10496, 5120, -6144, -1024, -2560, 512, 1024, 3072, -7168, -7680, 2304, 8192, -4096, 1536, -11776, -5888, 15360, 0, -5632, -768, -5888, -3840, 12288, 3072, -8704, -4352, -4608, 2560, 11776, -256, -14336, -2048, 3072, 2304, 4608, 3328, -18432, -768, 6656, 2304, 7168, -3584, -22784, 3840, 17152, -4608, 256, -4864, -13312, 11520, 6656, -2048, -1280, -6400, -6400, 9216, 9728, -3328, -9216, -4608, -1536, 14080, 5888, -13056, -3584, 1024, 1536, 6400, 6144, -10496, -11264, 9728, 4864, 2560, 2560, -15104, -3584, 10752, 256, 1536, -2048, -11008, -256, 11008, 2560, -7680, -2560, -9216, 4608, 8960, -5120, -3584, -2816, -4864, 2304, 5120, -1280, -5632, -2304, -1536, 3328, 6656, -7680, -5888, 1024, 256, 5120, 2304, -5120, -5632, 768, -256, 4352, 7168, -6656, -6400, 4096, -512, -1024, 3072, -2560, -4096, 6144, -512, -4608, 4352, -6912, -256, 9216, -1536, -1792, -1024, -6656, 1536, 7424, -768, -4352, -1536, -1024, 4608, 4608, -6656, -2560, -1024, 1536, 7680, -256, -1536, -6144, 0, 6144, 3072, 512, -4096, -6400, 3328, 8192, -768, -1024, -768, -6144, 3840, 4096, -1792, 2048, -5120, -3328, 9216, 2304, -6144, -2816, -2560, 2560, 5120, -256, -3328, -2560, -2304, 5120, 4352, -3072, -2304, -3840, 2304, 5120, -2816, -3584, -1536, 1280, 2560, 1536, 1280, -1792, -2816, 1792, 4864, 256, 768, -2816, -2560, 6144, 3584, -4096, 512, -2304, 2816, 3584, 1792, -256, -2816, -1024, 3840, 6144, 768, -6144, -1024, 1024, 3840, 3328, -768, -3840, 0, 3840, 2048, 512, 0, -4864, 4096, 3072, -256, 1792, -3328, -512, 4608, 768, -768, 1280, -2304, -2560, 3072, 2304, -512, 2048, -2304, 1024, 2304, 1536, 256, -2048, 2560, 1024, -512, 2816, -3584, 768, 1280, 256, 2304, 1024, -3840, 0, 2560, 256, 1280, -1024, -2560, 768, 1792, -256, 2048, -3328, 256, 1024, 2560, 1536, -2304, -768, 256, 1536, 3584, -768, -1024, 1024, -2560, 2560, 3328, -256, -1024, 1280, -768, 2560, 3328, -3328, 1024, 1792, 256, 2048, -256, 256, 1024, 1280, 1024, 2816, -1280, -512, 256, 2048, 1536, 256, 768, -256, -1280, 2816, 768, -768, 1024, -1280, -256, 4352, -1024, -512, 1536, -2560, 2560, 2560, -1024, 512, 768, -2560, 2560, 1280, -512, -512, -256, 1024, 768, -256, -512, -1024, 256, 1536, -1024, 1536, -1024, -2560, 2048, 512, -1024, 1536, -1024, -1024, 3072, -512, 512, 1536, -2304, 768, 512, 0, 1792, -1280, -768, 768, 512, 1024, -1024, -512, 1792, 768, 1280, 2304, -768, 256, 3072, -768, 1792, 1536, -2304, 1024, 2304, -1024, 3072, 256, -1792, 2304, 512, 256, 2560, -768, 256, 0, 0, 2048, 0, -256, 1280, -512, 2048, 256, -768, 2560, 512, 0, 2816, -1024, -256, 1536, -768, 512, 768, -1280, 1024, 0, -1280, 1280, -768, 256, 768, 0, 1024, -768, -768, 1024, -512, -512, 1280, -512, -256, 1536, -1280, 512, 768, -1024, 1024, -512, -768, 2816, -2048, 0, 1280, -256, 256, 0, -768, 1024, 512, 512, 1536, -512, 1024, 1280, -768, 1024, 1792, -1024, 2816, -256, 0, 768, 0, 768, 1792, -512, 1280, 256, 0, 1536, 768, 512, 1024, -256, 512, 1536, 0, 768, 1280, -1024, 1536, 0, 512, 1792, -1024, -256, 512, -512, 1792, 256, -256, 256, -512, 512, 1024, -1280, 0, 1024, -256, 512, -256, -512, 256, -512, 768, 512, -768, 768, -256, -1024, 1280, -512, -512, 768, 0, -256, 512, -1280, 512, 256, -1024, 0, 256, -768, 1280, -512, 512, 512, -768, 256, 768, -512, 768, 256, -512, 1024, 256, 512, 1280, -512, 768, 256, 512, 1280, 0, -256, 1024, 0, 256, 1024, 512, 1024, 1024, -512, 0, 512, 768, 1280, 0, 0, 0, 256, 1280, -512, -768, 1024, 0, 256, 512, -512, -1024, -1024, -1280, -1536, -1792, -2048, -2304, -2560, -2816, -3072, -3328, -3328, -3584, -4096, -4608, -5376, -6400, -7424, -8704, -9216, -9728, -9984, -10240, -10752, -11264, -12032, -12800, -13568, -14336, -14848, -15104, -14848, -14080, -12800, -11264, -9728, -7936, -6144, -4608, -3328, -2304, -1536, -768, 0, 768, 1536, 2304, 3328, 4352, 5376, 6912, 8448, 10752, 13568, 16128, 18944, 21248, 23296, 25088, 26624, 27648, 28416, 28928, 29440, 30208, 30464, 30976, 31488, 32000, 32256, 32512, 32512, 32512, 32512, 32256, 32256, 32256, 32256, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32256, 32000, 31488, 30976, 30208, 29184, 28416, 27392, 26624, 25856, 25600, 25344, 25088, 25088, 25088, 25088, 25088, 25344, 25088, 25088, 24832, 24320, 23552, 22528, 20736, 18688, 16128, 13824, 11776, 9984, 8448, 7424, 6912, 6400, 6144, 5632, 5120, 4608, 3584, 2560, 1280, 0, -1280, -2048, -2048, -1792, -768, 512, 2048, 3584, 4864, 5888, 6656, 7168, 7424, 7680, 7936, 8192, 8192, 7936, 7680, 7168, 6144, 5120, 3584, 2304, 1024, -256, -1024, -1792, -2304, -2560, -3072, -3328, -3840, -4352, -4864, -5632, -6144, -6400, -6400, -5888, -5376, -4864, -4352, -3840, -3840, -3584, -3840, -3840, -4096, -4352, -4352, -4352, -4096, -4096, -4096, -4352, -4864, -5632, -6400, -7680, -8960, -9984, -11264, -12032, -12800, -13568, -14336, -14848, -15616, -16128, -16384, -16640, -16640, -16128, -15360, -14080, -12544, -11008, -9728, -8704, -8192, -7936, -7936, -8192, -8448, -8960, -9216, -9472, -9472, -9216, -8960, -8704, -8704, -8704, -9216, -9984, -11008, -12544, -14080, -15616, -17152, -18432, -19712, -20736, -21760, -22528, -23040, -23552, -24064, -24064, -24320, -24064, -24064, -24064, -24064, -24320, -24576, -25088, -25600, -26112, -26624, -26880, -27392, -27648, -27648, -27904, -28160, -28160, -28160, -27904, -27904, -27904, -27648, -27648, -27904, -27904, -27904, -27904, -27648, -27648, -27392, -27136, -27136, -26880, -26880, -26880, -26880, -26880, -26880, -26624, -26368, -25856, -25088, -23808, -22528, -20992, -19456, -17920, -16384, -14848, -13312, -12032, -10752, -9728, -8704, -7936, -7424, -6912, -6400, -5632, -4608, -3328, -1792, -256, 1536, 3328, 5120, 6656, 8192, 9472, 10496, 11520, 12288, 13056, 14080, 14848, 16128, 17408, 18688, 19712, 20992, 21760, 22784, 23296, 24064, 24576, 24832, 25088, 25344, 25344, 25344, 25600, 25600, 25600, 25856, 25856, 25856, 25856, 25856, 25856, 25344, 24832, 24320, 23808, 23040, 22272, 21504, 20736, 19712, 18688, 17152, 15360, 13056, 10240, 7424, 4352, 1536, -1280, -3584, -5888, -7936, -9728, -11520, -13312, -14848, -16640, -17920, -19200, -20480, -21504, -22272, -23040, -23552, -24064, -24320, -24576, -24832, -25088, -25600, -25856, -26112, -26112, -26368, -26368, -26624, -26624, -26368, -26112, -25600, -24832, -23808, -22784, -22016, -20992, -20224, -19712, -19200, -18432, -17920, -17152, -16128, -15104, -13568, -12032, -10240, -8448, -6656, -5120, -3584, -2304, -1536, -768, 0, 768, 1536, 2304, 3328, 4352, 5376, 6656, 7936, 9472, 11264, 13056, 14848, 16384, 17920, 19200, 20224, 21248, 22016, 22528, 23040, 23552, 23808, 24320, 24576, 24832, 25088, 25600, 25600, 25856, 26112, 26112, 26112, 26112, 26112, 26112, 26112, 26112, 26112, 26368, 26368, 26368, 26112, 26112, 26112, 25856, 25600, 25088, 24576, 24064, 23552, 23040, 22784, 22528, 22528, 22272, 22272, 22272, 22272, 22272, 22016, 21760, 21504, 20992, 20224, 19456, 18432, 17152, 15616, 14080, 12544, 11008, 9984, 8960, 8192, 7680, 7424, 6912, 6400, 6144, 5376, 4608, 3840, 3072, 2048, 1280, 768, 768, 1024, 1536, 2304, 3072, 3840, 4608, 5376, 5888, 6400, 6912, 7168, 7680, 7936, 7936, 7936, 7680, 7168, 6400, 5632, 4608, 3584, 2560, 1792, 1280, 768, 256, 0, -512, -1024, -1536, -2304, -2816, -3584, -4096, -4352, -4352, -4096, -3584, -3072, -2816, -2304, -2304, -2304, -2560, -2816, -3072, -3328, -3584, -3840, -3840, -4096, -4096, -4352, -4864, -5632, -6656, -7680, -8704, -9728, -10752, -11520, -12288, -12800, -13312, -13568, -13824, -14080, -14336, -14336, -14080, -13568, -12800, -11776, -10752, -9728, -8960, -8192, -7936, -7680, -7936, -7936, -8448, -8704, -8960, -9216, -9216, -9216, -8960, -8960, -8960, -9216, -9728, -10496, -11520, -12544, -13824, -15104, -16384, -17408, -18688, -19456, -20480, -21248, -22016, -22528, -22784, -23040, -23296, -23296, -23296, -23552, -23552, -23808, -24320, -24576, -25088, -25600, -25856, -26112, -26368, -26624, -26880, -26880, -26880, -26880, -26880, -26880, -26880, -26880, -26880, -26880, -26880, -26880, -26880, -26624, -26624, -26368, -26112, -26112, -25856, -25600, -25600, -25600, -25344, -25344, -25344, -25088, -24576, -24064, -23296, -22016, -20992, -19456, -18176, -16640, -15104, -13568, -12288, -10752, -9472, -8192, -7168, -6400, -5632, -4864, -4096, -3328, -2048, -768, 768, 2304, 4096, 5632, 7168, 8960, 10240, 11520, 12544, 13568, 14336, 15360, 16128, 17152, 18176, 19456, 20480, 21760, 22528, 23552, 24064, 24832, 25344, 25600, 26112, 26368, 26368, 26624, 26624, 26624, 26624, 26880, 26880, 26880, 26880, 26880, 26624, 26368, 25856, 25344, 24832, 24064, 23296, 22272, 21504, 20480, 19456, 18176, 16640, 14592, 12288, 9984, 7168, 4608, 2048, -512, -2816, -4864, -6912, -8704, -10496, -12032, -13824, -15360, -16640, -17920, -19200, -20224, -20992, -21760, -22272, -22784, -23296, -23552, -24064, -24320, -24576, -24832, -25088, -25344, -25600, -25600, -25600, -25600, -25600, -25088, -24576, -24064, -23040, -22272, -21504, -20736, -19968, -19456, -18688, -18176, -17408, -16640, -15616, -14592, -13312, -11776, -10240, -8448, -6912, -5376, -3840, -2816, -1792, -1024, 0, 768, 1792, 2816, 3840, 5120, 6144, 7424, 8960, 10496, 12288, 13824, 15616, 17152, 18432, 19712, 20736, 21760, 22528, 23040, 23552, 24064, 24320, 24832, 25088, 25344, 25856, 26112, 26368, 26624, 26624, 26624, 26880, 26880, 26880, 26880, 26880, 26880, 26880, 26880, 26880, 26880, 26880, 26880, 26624, 26624, 26368, 25856, 25344, 25088, 24576, 24320, 23808, 23808, 23552, 23552, 23296, 23296, 23040, 23040, 22528, 22272, 22016, 21504, 20736, 19968, 18944, 17664, 16384, 15104, 13824, 12544, 11520, 10752, 9984, 9472, 8960, 8448, 7936, 7424, 6912, 6144, 5376, 4608, 3840, 3328, 2816, 2816, 3072, 3328, 3840, 4352, 5120, 5632, 6144, 6400, 6912, 7168, 7424, 7680, 7936, 7936, 7936, 7680, 7168, 6656, 5888, 5120, 4352, 3584, 2816, 2304, 2048, 1536, 1280, 768, 256, -256, -1024, -1536, -2048, -2560, -2816, -2816, -2816, -2560, -2304, -2048, -2048, -2048, -2304, -2560, -2816, -3328, -3584, -3840, -4096, -4352, -4352, -4608, -5120, -5632, -6400, -7168, -7936, -8960, -9728, -10496, -11264, -11776, -12032, -12544, -12800, -13056, -13312, -13312, -13312, -13056, -12544, -12032, -11264, -10240, -9728, -8960, -8448, -8448, -8192, -8448, -8448, -8704, -8960, -9216, -9472, -9728, -9728, -9728, -9728, -9984, -10240, -10752, -11520, -12544, -13568, -14592, -15616, -16640, -17664, -18688, -19456, -20224, -20992, -21760, -22272, -22528, -22784, -23040, -23296, -23296, -23552, -23808, -24064, -24320, -24832, -25088, -25344, -25600, -25856, -26112, -26368, -26368, -26624, -26624, -26624, -26624, -26624, -26624, -26624, -26624, -26624, -26368, -26368, -26368, -26112, -26112, -25856, -25600, -25344, -25344, -25088, -24832, -24832, -24576, -24576, -24320, -24064, -23552, -22784, -22016, -20992, -19712, -18432, -17152, -15616, -14336, -12800, -11520, -9984, -8704, -7424, -6400, -5376, -4608, -3584, -2816, -1280, 1024, 2048, 3584, 4864, 6400, 7936, 9472, 10752, 12032, 13312, 14592, 15616, 16640, 17664, 18432, 19456, 20224, 21248, 22016, 22784, 23552, 24320, 24832, 25344, 25856, 26112, 26624, 26624, 26880, 27136, 27136, 27136, 27136, 27136, 27136, 26880, 26624, 26624, 26368, 25856, 25344, 24832, 24320, 23552, 22784, 21760, 20736, 19712, 18688, 17408, 15872, 14592, 12800, 11008, 8960, 7168, 4864, 3072, 1024, -1024, -2816, -4608, -6400, -8192, -9728, -11264, -12800, -14080, -15616, -16640, -17664, -18688, -19712, -20480, -20992, -21760, -22272, -22784, -23296, -23552, -23808, -24320, -24320, -24576, -24832, -24832, -24832, -24576, -24576, -24320, -23808, -23552, -23040, -22528, -22016, -21504, -20992, -20224, -19712, -18944, -18176, -17408, -16384, -15360, -14080, -13056, -11776, -10496, -9216, -7936, -6656, -5376, -4096, -2816, -1792, -512, 768, 2048, 3584, 4864, 6400, 7680, 9216, 10752, 12032, 13568, 14848, 16128, 17408, 18432, 19456, 20224, 20992, 21760, 22272, 22784, 23296, 23808, 24320, 24576, 25088, 25344, 25856, 26112, 26368, 26368, 26624, 26880, 26880, 26880, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 26880, 26880, 26880, 26624, 26368, 26368, 26112, 25856, 25600, 25344, 25344, 25088, 24832, 24576, 24320, 23808, 23552, 23296, 22784, 22272, 21760, 20992, 20224, 19456, 18688, 17920, 17152, 16128, 15360, 14848, 14080, 13568, 12800, 12288, 11776, 11264, 10496, 9984, 9472, 8704, 8192, 7936, 7424, 7168, 7168, 6912, 7168, 7168, 7168, 7168, 7424, 7424, 7424, 7424, 7680, 7680, 7680, 7424, 7424, 7168, 6912, 6656, 6400, 5888, 5632, 5120, 4864, 4352, 4096, 3840, 3328, 3072, 2560, 2048, 1536, 1024, 512, 256, -256, -512, -1024, -1280, -1536, -1792, -2304, -2560, -3072, -3328, -3840, -4352, -4864, -5376, -5632, -6144, -6656, -6912, -7424, -7936, -8192, -8704, -9216, -9728, -10240, -10752, -11008, -11520, -11776, -12032, -12032, -12288, -12288, -12544, -12544, -12288, -12288, -12032, -11776, -11520, -11264, -11264, -11008, -11008, -11008, -11264, -11264, -11520, -11776, -12032, -12288, -12544, -12800, -13056, -13312, -13568, -14080, -14592, -15104, -15616, -16384, -17152, -17920, -18432, -19200, -19968, -20480, -20992, -21504, -22016, -22528, -23040, -23296, -23552, -24064, -24320, -24576, -24832, -25088, -25088, -25344, -25600, -25856, -25856, -25856, -26112, -26112, -26112, -26112, -26112, -26112, -26112, -26112, -26112, -26112, -25856, -25856, -25600, -25600, -25344, -25088, -24832, -24576, -24320, -24064, -23808, -23552, -23296, -22784, -22528, -22272, -21760, -21248, -20736, -19968, -19200, -18176, -17152, -16128, -14848, -13824, -12544, -11264, -9984, -8448, -7168, -5888, -4608, -3328, -2048, -768, 512, 1792, 3328, 4608, 5888, 7424, 8960, 10240, 11520, 13056, 14080, 15360, 16384, 17408, 18176, 19200, 19968, 20992, 21760, 22528, 23296, 23808, 24576, 25088, 25600, 25856, 26368, 26624, 26880, 26880, 27136, 27136, 27136, 27136, 26880, 26880, 26624, 26624, 26368, 25856, 25600, 25088, 24320, 23808, 23040, 22016, 21248, 20224, 19200, 17920, 16640, 15360, 13824, 12032, 10240, 8448, 6400, 4608, 2560, 512, -1280, -3072, -4864, -6656, -8192, -9728, -11264, -12800, -14080, -15360, -16640, -17664, -18688, -19456, -20224, -20992, -21504, -22272, -22784, -23040, -23552, -23808, -24064, -24320, -24576, -24576, -24576, -24576, -24576, -24320, -24064, -23808, -23296, -23040, -22528, -22016, -21504, -20736, -20224, -19456, -18944, -17920, -17152, -16128, -15104, -13824, -12544, -11264, -9984, -8704, -7424, -6144, -4864, -3584, -2560, -1280, -512, -256, 768, -512, 256, -768, 1024, -512, 0, 0, 2048, 0, 2560, -2304, -1792, -32768, -18432, 3328, -11264, -3328, -4608, 1024, -1024, 3072, 768, 7936, 1024, 16896, 18944, 9728, 9728, 9216, 7680, 6400, 5632, 4608, 3328, 1792, 1280, 512, 256, -1280, -1792, -2304, -2304, -2816, -3584, -3072, -3584, -3072, -4096, -3328, -4096, -3328, -3584, -4096, -2816, -3584, -2560, -3328, -2816, -3328, -2048, -2048, -1536, -1536, -1280, 0, -1536, -768, -768, 768, -1024, 1536, -3328, 4352, -1280, -1280, 3840, -256, -5888, 1536, 5888, 7168, 8960, 3328, 10496, -768, 6144, 6400, -1024, 1536, 7680, 1024, 4608, 2560, -8192, -16384, -30720, -16384, -23296, -19456, -8448, -11520, -14848, 512, 256, -4864, -3584, 4608, 12288, 12800, 15104, 13056, 13568, 12032, 11776, 10496, 9472, 8960, 6656, 7168, 4864, 5376, 2560, 3328, 2304, 768, 1280, -1024, 512, -1280, -768, -2048, -1280, -2048, -2048, -2560, -2304, -2560, -2560, -3072, -1792, -4352, -2048, -2816, -3584, -1280, -3840, -1280, -1024, -2560, -3328, 2816, -5632, 768, -768, -1024, -1280, -2816, 3328, 512, -4096, -2304, -1280, -3072, 6912, 3840, 4352, 5376, 5120, 5120, 2048, 3584, 3328, 0, 2560, 8960, 2560, -256, -3072, -13312, -22784, -19968, -14848, -21760, -18944, -13056, -6400, -6400, -7168, -7680, -3584, 3072, 7424, 11264, 11264, 13056, 11776, 12800, 12544, 11008, 9728, 9216, 8192, 7424, 5888, 4864, 4352, 3584, 2560, 1536, 1536, 512, 1024, -2048, 768, -1792, -768, -1536, -1792, -2816, -1024, -3072, -1792, -1536, -5120, 256, -3840, -3584, -2048, -1792, -2560, -2560, -2560, 512, -3584, -3072, 1792, -2560, -2048, -1280, -1536, 256, 1536, -512, -3072, -4864, -768, 768, 512, 4864, 4864, 3584, 4864, 6144, 3328, 1280, 3072, 3072, 3328, 5376, 7424, 1280, -4608, -11008, -12288, -16384, -20992, -20992, -18176, -11264, -9472, -9472, -10240, -8448, -5888, 1280, 5120, 8448, 9728, 11520, 12288, 13056, 11776, 11264, 10496, 9728, 9216, 6912, 6656, 6144, 4864, 3328, 4096, 1280, 2816, 1024, -256, 768, -1024, -768, 256, -2304, -1792, -512, -2304, -1536, -3328, -1024, -1536, -4352, -2048, -1536, -3840, -2560, -1280, -2560, -2048, -2560, -1280, -1792, -1280, -512, -3584, -2560, 768, 1280, -1024, -768, -2560, -4352, -2560, 768, 1024, 1280, 4608, 4608, 4608, 4096, 4096, 2560, 1280, 2816, 5888, 6656, 5632, 1792, -2304, -4096, -9472, -15872, -20480, -19456, -16640, -11776, -11008, -11008, -13056, -10496, -6144, -1024, 2816, 6144, 8192, 10496, 12032, 11008, 12544, 11520, 10496, 10240, 8448, 7936, 7936, 5120, 5888, 4608, 2816, 4096, 2304, 1280, 768, 512, 1280, -512, -1792, 512, -1024, -2560, -768, -1280, -2048, -2560, -1792, -2048, -3584, -2560, -2048, -2816, -2304, -1536, -3584, -2560, -512, -768, -3072, -2560, -1792, -2304, 0, 1536, -256, -2816, -3072, -2816, -2560, -1792, 1024, 1792, 3072, 4352, 5120, 4608, 3328, 1536, 2048, 4864, 5632, 6144, 4352, 3584, 1280, -2048, -7424, -13824, -19712, -18176, -14080, -12800, -11264, -13824, -14592, -9984, -8192, -3840, 768, 3840, 7936, 8704, 9984, 12032, 11520, 11264, 11264, 9472, 9472, 8448, 7168, 6912, 4608, 5120, 5376, 2560, 1792, 2560, 1792, 256, 512, 512, 0, -1280, 0, -512, -1792, -768, -1280, -2048, -2048, -1280, -3328, -3328, -1280, -1536, -3584, -2816, -2048, -2048, -1280, -1280, -2304, -4352, -2560, -512, 0, -512, -256, -2304, -3072, -3584, -3072, -1536, -256, 768, 2816, 4864, 4864, 3584, 1792, 2304, 3328, 4352, 5888, 5632, 4864, 5376, 3072, 512, -5376, -14080, -16640, -15104, -13312, -12032, -14336, -14336, -12800, -13568, -9728, -5632, -1792, 2560, 4608, 7424, 9216, 10240, 11520, 11008, 9728, 10496, 10240, 8192, 6912, 6656, 6656, 4864, 4352, 4352, 3072, 2304, 2304, 1536, 512, 1024, 1024, -256, -512, 512, -768, -768, 0, -512, -2048, -2304, -1792, -1792, -1792, -1536, -2048, -3072, -1536, -1024, -1792, -3072, -3328, -2560, -1280, -512, -512, -768, -2048, -3072, -3840, -4096, -3584, -3328, -1792, 512, 2048, 2816, 2048, 1024, 1280, 2048, 3328, 5120, 5632, 5888, 6144, 5888, 4864, 1536, -3328, -5888, -7424, -8192, -9472, -10752, -11776, -13568, -14592, -13568, -12544, -9984, -6400, -3072, -256, 2560, 5376, 7168, 8192, 8960, 9216, 8704, 8704, 8192, 7168, 6400, 6144, 5376, 4608, 4864, 4096, 2560, 1792, 2048, 2304, 2048, 1536, 1280, 512, 768, 1536, 1792, 1280, 512, -512, -1024, -768, -256, -768, -1024, -768, -256, -768, -2048, -3328, -3584, -2816, -1024, -256, -512, -1024, -1536, -2816, -4096, -4864, -5376, -5376, -4352, -2304, -768, 0, 0, -768, -1280, -512, 1024, 2816, 4608, 5888, 6400, 6656, 6144, 4352, 2560, 1280, -256, -1792, -3072, -5120, -7424, -9472, -11264, -13056, -14080, -13824, -12032, -9984, -7168, -4096, -1024, 2304, 4608, 5888, 6912, 7936, 7936, 7680, 7680, 7168, 5888, 5120, 5632, 5888, 5120, 3584, 2560, 2304, 2304, 2560, 2304, 1536, 1024, 1024, 1536, 2304, 2560, 1792, 512, 0, 256, -256, -512, -512, -256, 256, 512, -512, -2560, -3584, -2816, -2048, -1280, -512, -256, -768, -1536, -2304, -3584, -5120, -5888, -5888, -4608, -2816, -1280, -768, -1024, -1536, -2048, -1024, 512, 1792, 3584, 5376, 6400, 6400, 5888, 4864, 3328, 2048, 1024, -256, -2304, -3840, -5888, -7936, -9984, -12288, -13568, -13056, -12288, -11264, -8704, -5120, -2048, 768, 3072, 5120, 6144, 6912, 7680, 7936, 7424, 6144, 5632, 5632, 5888, 5632, 4608, 3328, 2560, 2560, 2816, 2816, 2304, 1280, 768, 1280, 2560, 2816, 2304, 1792, 1280, 1024, 512, 0, -768, -256, 768, 1280, 512, -768, -2048, -2816, -2560, -1792, -1280, -768, -512, -512, -1024, -1792, -3584, -5120, -6144, -6144, -4864, -3072, -1536, -1536, -2048, -2048, -2048, -1792, -512, 1280, 3072, 4864, 5888, 6144, 5632, 5120, 4096, 3072, 1792, 256, -1280, -2560, -4352, -6912, -9216, -10752, -12032, -13312, -13056, -11520, -9216, -6656, -3072, 0, 2304, 3840, 5376, 6912, 7680, 7424, 6656, 5888, 5632, 5888, 5888, 5376, 4352, 3072, 2304, 2560, 3072, 2560, 1536, 768, 1024, 1792, 2560, 2816, 2304, 2048, 2304, 1792, 512, -256, 0, 512, 1536, 1536, 768, -512, -1792, -2304, -2048, -1536, -1024, -768, -256, -256, -512, -1536, -3328, -5376, -6656, -6144, -4608, -3328, -2560, -2304, -2560, -2816, -2816, -2560, -1280, 768, 2560, 4352, 5376, 5632, 5632, 5376, 4864, 3584, 2048, 1280, 256, -1792, -3584, -5376, -7424, -9728, -11520, -12544, -12800, -12288, -10240, -7168, -4096, -1536, 768, 2816, 4864, 6656, 6912, 6656, 6144, 5632, 5632, 6144, 6144, 5120, 3584, 2816, 2816, 3072, 2816, 2048, 1024, 768, 1536, 2048, 2304, 2304, 2560, 2816, 2560, 1536, 512, 0, 512, 1280, 2048, 1792, 768, -512, -1280, -1536, -1792, -1536, -1024, -768, -256, 256, 256, -1280, -3328, -5376, -6144, -5888, -4608, -3584, -3072, -2816, -3072, -3328, -3584, -3328, -2048, 0, 2048, 3584, 4352, 5376, 5632, 5376, 4608, 3840, 3072, 2048, 512, -768, -2304, -4096, -6144, -8192, -10240, -12032, -13056, -12544, -10496, -7680, -5376, -3072, -256, 2304, 4352, 5888, 6400, 6144, 5376, 5376, 6144, 6144, 5632, 4352, 3072, 2816, 3328, 3072, 2048, 1024, 768, 1024, 1536, 1792, 1792, 2304, 2816, 3072, 2560, 1536, 768, 768, 1536, 2304, 2560, 2048, 1280, 256, -512, -768, -768, -512, -256, 256, 768, 768, 256, -1280, -3072, -4608, -5120, -5120, -4608, -4096, -4096, -4096, -4352, -4864, -5120, -4352, -2816, -1280, 256, 2048, 3328, 4352, 4608, 4608, 4352, 4096, 3584, 2816, 1792, 512, -768, -2048, -3584, -5632, -8704, -11008, -11776, -10752, -8960, -7168, -5120, -2816, -512, 1792, 3840, 4864, 4864, 4864, 4864, 5120, 5120, 4352, 3584, 2816, 2560, 2304, 1792, 256, -1024, -1536, -1024, 0, 512, 1024, 1536, 1792, 2048, 2304, 2048, 1792, 1792, 2560, 3328, 3840, 3840, 3328, 2304, 1536, 768, 512, 1024, 1792, 2304, 2816, 2816, 1792, 256, -1280, -2560, -3328, -3584, -3584, -3584, -4096, -4864, -5888, -6656, -7168, -6912, -5888, -4608, -3328, -1792, -256, 1536, 2816, 3584, 3840, 3584, 3584, 3840, 3840, 3072, 1792, 512, -256, -1024, -2816, -5632, -8704, -10496, -10240, -8704, -6656, -4864, -3072, -1024, 1024, 2560, 3584, 4352, 4352, 4608, 4864, 4608, 3840, 3072, 2560, 2304, 2048, 1536, 0, -1536, -2816, -2560, -1536, -256, 768, 1280, 1536, 1536, 1536, 1792, 1792, 2048, 2560, 3328, 4096, 4608, 4352, 3328, 2304, 1280, 768, 1024, 1792, 2816, 3328, 3584, 2816, 1280, -512, -1792, -2816, -3072, -3072, -3328, -3584, -4352, -5632, -6656, -7168, -7424, -6912, -5632, -4352, -2816, -1280, 256, 1792, 3072, 3584, 3584, 3328, 3584, 3840, 3584, 2816, 1280, 0, -512, -1536, -3840, -6912, -9472, -10752, -9728, -7936, -6144, -4352, -2304, -256, 1536, 3072, 3840, 4352, 4608, 4864, 4864, 4352, 3328, 2816, 2304, 2304, 2048, 1024, -512, -2048, -2816, -2304, -1024, 256, 1024, 1280, 1536, 1536, 1536, 1792, 1792, 2304, 2816, 3584, 4352, 4608, 4096, 3072, 2048, 1024, 768, 1280, 2304, 3072, 3584, 3328, 2304, 512, -1024, -2304, -3072, -3328, -3072, -3328, -3840, -4864, -5888, -6912, -7424, -7168, -6400, -5120, -3840, -2304, -768, 768, 2304, 3328, 3840, 3584, 3328, 3840, 3840, 3328, 2304, 768, -256, -768, -2304, -4864, -7936, -10240, -10496, -9216, -7168, -5376, -3584, -1536, 512, 2304, 3328, 4096, 4352, 4608, 4864, 4608, 4096, 3072, 2560, 2304, 2304, 1792, 512, -1024, -2560, -2816, -2048, -512, 512, 1280, 1280, 1536, 1536, 1792, 1792, 2048, 2304, 3072, 4096, 4608, 4352, 3584, 2560, 1536, 1024, 1024, 1536, 2560, 3328, 3584, 3072, 1792, 0, -1536, -2560, -3072, -3328, -3328, -3584, -4096, -5376, -6400, -7168, -7424, -7168, -6144, -4608, -3328, -1792, -256, 1536, 2816, 3584, 3840, 3328, 3584, 3840, 3840, 3072, 1792, 512, -256, -1280, -3072, -5888, -8960, -10496, -10240, -8704, -6656, -4864, -3072, -768, 1024, 2560, 3584, 4352, 4608, 4608, 4864, 4608, 3584, 2816, 2304, 2304, 2048, 1536, 0, -1792, -2816, -2560, -1536, 0, 512, -256, -512, -2304, -6144, 1024, -768, 768, -768, 2560, 1792, 1024, 3328, -1024, 256, 768, 768, 0, 512, 2048, -2304, -2304, 512, 256, -256, 1792, 4352, 5376, 9472, 6400, 3328, 3584, -512, 3840, 5120, 1280, 0, -768, -1792, -6912, -3584, -4608, -4864, -7424, -5120, -1024, -4608, -8192, -7680, -7680, -7424, -8192, -5632, -6656, -4864, -4864, -256, -1536, 1024, 1792, 1280, 512, 0, -2048, -4096, -3072, -3328, -4352, -4352, 4864, 5120, 6144, 4096, 2048, -1024, 2048, 0, 3328, 7168, 8448, 4096, 2816, 1280, -768, -256, 1024, 3072, 3072, 10240, 5120, 2816, 1024, 1280, 2048, -256, 512, 1280, 1280, 5632, 3328, 5376, 2048, 2304, 4608, 5120, 3328, 5120, 6656, 2816, 6144, 4352, 2560, 6912, 7680, 5632, 7168, 7680, 10496, 12032, 14592, 9216, 9216, 5120, -4096, 1024, 1536, -4864, -5376, -10496, -9984, -8448, -9728, -10496, -11776, -10752, -9216, -4608, -9472, -16640, -19200, -19712, -19968, -15872, -16128, -15872, -17408, -16128, -16128, -11264, -12800, -7680, -10496, -11008, -6656, -8704, -8960, -9216, -11520, -12544, -6912, 256, -1536, -1024, -1792, -5120, -4096, -5120, -5376, -3328, 512, -1536, -256, -3072, 0, -256, 3840, 4864, 5120, 6656, 9472, 10240, 11776, 9472, 12800, 8960, 8704, 10496, 11008, 13056, 13824, 14080, 12800, 14336, 12032, 15104, 13056, 13056, 19200, 17152, 16896, 18176, 15104, 15360, 18432, 19200, 18432, 20480, 20224, 20992, 25088, 25344, 22272, 23808, 15872, 12544, 14848, 10496, 10752, 7168, 1280, -1536, -1536, -4608, -6144, -5888, -7680, -6400, -5120, -9728, -15360, -19200, -19712, -20480, -19200, -18176, -19200, -17920, -18688, -17664, -19456, -15360, -16896, -18176, -16896, -14592, -15872, -15616, -15616, -22272, -23040, -17664, -16128, -11776, -7936, -8960, -12032, -10752, -13568, -16128, -13568, -11520, -8448, -9216, -9984, -9472, -11008, -9984, -8704, -7680, -4864, -2304, 512, -2304, -256, -768, 256, -768, 1280, 1792, 3840, 6144, 5632, 5888, 5120, 8192, 11008, 8448, 12288, 16128, 17152, 17920, 17408, 13312, 15104, 18688, 18688, 19712, 21760, 18688, 20736, 26368, 25088, 29696, 29440, 22272, 20480, 19456, 18432, 17664, 15360, 9472, 6912, 7424, 3072, 4864, 1024, -3072, 256, 768, -768, -7936, -10752, -14592, -17152, -17152, -15616, -15616, -15616, -12288, -14848, -13056, -10496, -11776, -12288, -10240, -8960, -8448, -6656, -9216, -17152, -17408, -16640, -15104, -12032, -7168, -8704, -9472, -9216, -13312, -15616, -15616, -12032, -8704, -9984, -9984, -10752, -10752, -12288, -9216, -9728, -9472, -5120, -4864, -4096, -4096, -4608, -5120, -5632, -6656, -5632, -4096, -3840, 256, -1024, -1536, 2560, 3072, 3328, 5632, 8192, 10496, 13824, 13312, 11264, 13824, 16896, 15616, 19968, 20736, 18176, 22272, 22784, 25344, 30464, 27392, 23296, 19712, 19456, 17664, 19456, 17408, 12032, 12544, 8960, 8448, 9472, 5632, 3584, 6144, 9472, 6656, 3328, -2560, -6656, -10496, -11008, -8704, -10240, -8704, -8448, -11008, -9984, -6400, -6912, -6912, -4608, -6400, -3840, -256, -2560, -7424, -10752, -9984, -9984, -4864, -1792, -2560, -2560, -2816, -5120, -8960, -11264, -8448, -7680, -7168, -9216, -8704, -12032, -10496, -9216, -11776, -10752, -8704, -6912, -7424, -6400, -8704, -7680, -8192, -10240, -9216, -9216, -7936, -4096, -6400, -6400, -3840, -5376, -3584, -2304, -2816, 256, 4352, 3840, 2304, 6400, 5120, 6400, 11776, 9984, 11776, 12800, 13056, 17408, 21760, 22272, 18432, 16640, 13312, 12800, 15104, 11264, 10752, 7424, 5888, 5632, 5888, 2816, -1280, 2048, 3584, 4864, 2048, -1536, -5888, -9728, -11008, -10752, -12288, -10496, -8704, -10752, -9728, -4864, -5888, -4096, -3840, -4864, -2560, 2048, 2048, -2304, -4608, -6912, -7680, -2560, -1024, 1792, 1536, 3840, 2048, -2048, -4352, -3840, -2048, -2816, -768, -3840, -4352, -3584, -4096, -6912, -7680, -6656, -5632, -4864, -5376, -5632, -4864, -7680, -6912, -6656, -9216, -5632, -2304, -3328, -2560, -2560, -2048, -2304, -1536, -3072, -256, 4096, 1536, 2816, 4096, 1536, 4864, 6144, 6912, 9728, 9728, 9728, 12288, 18176, 18432, 19968, 16896, 13056, 13824, 13312, 12544, 10752, 8192, 5376, 6400, 6656, 3328, 256, -256, 2560, 3840, 2048, 256, -5632, -9728, -12032, -14336, -14848, -11776, -11008, -11776, -8448, -6400, -4352, -2816, -2304, -4864, -2304, 4096, 4608, 3072, 256, -4352, -4608, -2304, 768, 2304, 4352, 6144, 6656, 2304, -1024, -256, -1536, 512, 2304, 0, -512, 512, -768, -3328, -4096, -3840, -2048, -2048, -2048, -256, -1536, -4352, -2816, -5632, -6144, -4096, -3072, -2304, -2304, -2304, -2304, -1536, -2048, -4096, 512, 1536, 512, 3328, 2304, 1792, 2560, 4352, 4864, 7680, 7936, 5632, 9472, 12544, 15616, 17920, 14336, 11008, 9472, 9216, 7936, 8192, 3840, 1024, 2816, 2304, 1024, -3584, -4096, -1792, -1280, -256, -2048, -7168, -11776, -14336, -19200, -18944, -17152, -17920, -17152, -15872, -14080, -12032, -9216, -8192, -10752, -7168, -2304, 256, 1024, -1024, -4352, -7680, -4608, -3072, -512, 1024, 3840, 5376, 1792, 256, -1792, -1536, -256, 1792, 0, 0, 768, -768, -2048, -3840, -4608, -1536, -2304, -1536, 1280, -512, -512, 0, -1792, -3072, -1792, -768, 512, 1792, 768, 1024, 3584, 512, 256, 3072, 2816, 4352, 5120, 4864, 4096, 4864, 5120, 6144, 9984, 9216, 9472, 10752, 14080, 18176, 21504, 19456, 16128, 14336, 12032, 12544, 11776, 7424, 4608, 3584, 4608, 2816, -1280, -2816, -2048, -768, 1024, 1024, -4096, -6912, -11264, -15360, -16384, -15104, -15872, -15872, -14080, -14080, -12032, -7168, -8192, -8960, -7424, -3840, -768, 1024, 768, -3840, -6400, -6144, -3328, -2816, -768, 2560, 3584, 3072, 1024, -1280, -2304, -256, 512, -256, 256, 256, -256, -1792, -4352, -4096, -3072, -4352, -2048, 0, -256, -256, -512, -2048, -3328, -2304, -2304, 0, 2304, 256, 3584, 4096, 1536, 1792, 2560, 3072, 4608, 6656, 5120, 5632, 5632, 4096, 6400, 8192, 9216, 8704, 9216, 11008, 15360, 19200, 18432, 17152, 13312, 11264, 12800, 11520, 9728, 4352, 3584, 4352, 2816, -512, -2304, -3584, -2560, 0, -1024, -3072, -6144, -10496, -15104, -17152, -16128, -17920, -17664, -15872, -17920, -14080, -10240, -9728, -10752, -9728, -7424, -4096, -768, -768, -2304, -7424, -7936, -6400, -6656, -5120, -1792, 0, 512, -256, -3584, -4608, -3584, -3584, -3072, -2560, -2560, -1024, -3328, -5376, -4864, -5632, -6144, -4096, -2560, -1536, -512, -512, -2560, -3072, -3840, -4352, -1024, -1024, -1280, 1792, 2304, 768, 1024, 1792, 1280, 4608, 5888, 5632, 7168, 6400, 5632, 6912, 8704, 9984, 11008, 9728, 10496, 15872, 18176, 20224, 19968, 15872, 14080, 14080, 14592, 12544, 7936, 5888, 7680, 5376, 3840, 1792, -1280, 256, 2048, 2304, 2048, -768, -4096, -9984, -11776, -12800, -15360, -14080, -14848, -15872, -13568, -9216, -8448, -8704, -8704, -7424, -4608, -1536, 1280, -512, -4352, -5888, -5632, -6144, -4352, -2048, 256, 2304, 2560, -1024, -1792, -2048, -2304, -1536, -2304, -1536, 0, -2816, -3584, -3584, -5376, -6144, -5376, -4096, -2560, 256, -768, -768, -1280, -3584, -2816, -1792, -1792, -1280, 1536, 2304, 1024, 2048, 256, 768, 2816, 4096, 5120, 6656, 6144, 5120, 6400, 7424, 9216, 10496, 8192, 10240, 13056, 16384, 19712, 19968, 17152, 14080, 13824, 14592, 13568, 8448, 6912, 6400, 5632, 5120, 2304, -768, -768, 768, 1792, 1536, 1024, -4096, -8192, -10752, -14080, -15360, -15616, -16384, -17920, -15872, -12544, -9984, -10496, -10240, -9472, -8448, -4608, -1280, -2048, -4096, -6144, -7424, -7936, -7168, -6144, -3840, -256, 256, -1792, -2816, -3584, -3328, -3584, -4608, -2816, -2048, -3584, -4096, -4096, -6400, -7936, -7424, -7936, -5120, -3072, -3328, -1536, -2816, -4864, -4864, -3584, -4352, -3072, -256, 512, 1536, 1792, 512, 1024, 2048, 2816, 4608, 6144, 5376, 5632, 4864, 5376, 8448, 8448, 8192, 8192, 10240, 14080, 18176, 19456, 18432, 14848, 14080, 15872, 14336, 10752, 8704, 7168, 7424, 6656, 4352, 1024, 512, 1536, 1024, 3328, 3072, -1024, -4608, -7680, -11520, -12800, -13056, -15104, -16128, -15616, -12032, -9472, -8448, -8192, -8704, -8192, -4864, -1024, -768, -1280, -3328, -5376, -5888, -5632, -6144, -3328, 256, 1280, 1280, -768, -1536, -256, -1792, -2304, -512, 256, -512, -512, -1024, -3328, -4096, -5632, -5632, -3840, -2560, -1024, 512, -256, -2816, -2048, -1792, -3072, -1536, 256, 1536, 3072, 2816, 2048, 2304, 2304, 2304, 5120, 5888, 6656, 6400, 5120, 6144, 8192, 8704, 8960, 8448, 8960, 12544, 16128, 18944, 18944, 14848, 14080, 15360, 13824, 11520, 8448, 6912, 6400, 6656, 4864, 1536, 1024, 256, 256, 2304, 3072, -256, -2560, -6656, -11008, -12800, -13824, -15616, -17920, -17664, -15616, -12800, -11008, -10240, -11264, -11264, -8704, -4608, -3072, -2304, -3840, -6144, -6400, -7168, -7936, -5632, -3072, -512, 256, -2048, -2048, -1280, -3072, -3584, -2048, -2048, -2048, -1280, -2304, -2816, -4608, -6912, -6656, -5632, -4864, -3072, -256, -1024, -2304, -2048, -2816, -3584, -3072, -2048, 0, 1792, 1280, 1280, 1536, 0, 768, 2048, 3328, 5120, 4608, 3328, 3840, 5632, 6912, 7424, 6400, 6656, 9216, 13056, 17920, 18176, 15104, 14336, 14592, 14080, 12032, 9472, 6400, 6144, 6912, 4352, 2304, 768, -512, -512, 2048, 2304, 1536, -512, -4096, -8704, -11264, -12032, -13824, -16128, -16896, -16128, -14080, -11264, -9984, -10752, -11264, -8960, -5888, -2816, -1024, -2560, -4096, -4352, -5888, -6400, -5632, -3328, 256, 1536, 256, 256, 1024, -512, -1024, 256, -256, 1024, 768, 512, 512, -768, -3072, -3840, -3584, -3840, -1792, 768, 1280, 768, 512, 256, -512, -1024, -1024, 768, 2304, 2560, 3328, 2816, 2304, 2048, 2304, 3840, 5632, 5632, 5120, 4864, 5376, 6912, 7680, 7168, 7168, 7168, 10752, 15616, 17664, 16640, 15360, 15360, 14848, 14080, 12032, 8960, 7680, 7680, 6144, 4608, 2560, 0, -256, 512, 1536, 1792, 768, -2048, -6144, -9216, -11008, -12800, -15104, -16640, -16896, -15872, -13312, -11008, -11008, -11264, -10496, -8960, -5376, -3072, -3072, -3328, -4352, -5888, -6656, -7680, -6144, -3072, -1024, -1280, -768, -512, -1280, -1536, -1536, -1280, -768, -512, -256, 512, 512, -1280, -768, 512, 2048, 4352, 6656, 8192, 10752, 12800, 14336, 17408, 18688, 16384, 16128, 16640, 12288, 14336, 18176, 12288, 12544, 12800, 6656, 7680, 7680, 4096, 6400, 5376, -512, 0, -3328, -3840, -512, -4864, -4352, -4096, -12800, -12544, -12544, -20736, -21760, -22528, -27648, -28672, -29696, -32512, -32256, -28928, -28928, -27136, -20224, -16640, -12288, -4352, 1280, 5120, 10496, 14848, 16128, 17664, 15104, 7168, 4352, 0, -8192, -10496, -13312, -17664, -16128, -15616, -15104, -10496, -6656, -4864, 1536, 7168, 8448, 13312, 17152, 17920, 20736, 22272, 21504, 23040, 23808, 21504, 18432, 17664, 15360, 11520, 14336, 14592, 10240, 11776, 9984, 6400, 7424, 6400, 4096, 5376, 3072, -256, -768, -2816, -2048, -1280, -4096, -3072, -5376, -10496, -9728, -12288, -17408, -17920, -19712, -23296, -23808, -25088, -27136, -26368, -23808, -23552, -20992, -15360, -12032, -7680, -1024, 3328, 6912, 11264, 14336, 15360, 15872, 12032, 5888, 3328, -2048, -8192, -10240, -13824, -16384, -15104, -15104, -13568, -9216, -6656, -3584, 3072, 6912, 9216, 14336, 16896, 18432, 21504, 22016, 22016, 23808, 23552, 20992, 18688, 17920, 14592, 12544, 15104, 13312, 11008, 12032, 9472, 7424, 7680, 6144, 4608, 4608, 1792, -512, -1536, -2816, -1792, -2560, -4096, -3584, -7424, -10752, -10752, -14592, -18176, -18688, -21248, -23808, -24576, -26112, -27392, -25856, -23808, -23040, -19200, -14080, -10496, -5632, 768, 4864, 8448, 12800, 15104, 15616, 15360, 10496, 5376, 2560, -3584, -8448, -11008, -14592, -16128, -15360, -15616, -13056, -9216, -6912, -2304, 3840, 6656, 10240, 15104, 16896, 18944, 21760, 21760, 22528, 24064, 23040, 20480, 19200, 17664, 14336, 13824, 15360, 12800, 12032, 11776, 9216, 7936, 7680, 5888, 4864, 3840, 1024, -768, -1792, -2560, -2304, -3584, -4352, -4864, -8960, -11264, -12032, -16128, -18688, -19712, -22528, -24576, -25088, -26624, -27392, -25344, -23552, -22016, -17664, -12800, -8960, -3584, 2304, 6144, 9728, 13824, 15360, 15616, 14336, 9216, 4864, 1024, -5120, -8960, -11776, -15360, -15872, -15616, -15360, -12288, -8960, -6400, -768, 4352, 6912, 11520, 15360, 16896, 19712, 21760, 22016, 23296, 24064, 22528, 20480, 19200, 17152, 14336, 14848, 15104, 12800, 12544, 11520, 9216, 8448, 7680, 5888, 4864, 3328, 512, -1280, -2048, -2560, -2816, -4096, -4608, -6400, -10240, -11520, -13568, -17408, -19456, -20736, -23296, -24832, -25600, -27136, -27136, -24832, -23040, -20736, -16128, -11264, -7168, -1536, 3840, 7168, 11264, 14592, 15616, 15616, 13312, 7936, 4096, -256, -6144, -9472, -12800, -15616, -15872, -15872, -15104, -11776, -8960, -5632, 256, 4608, 7680, 12288, 15616, 17408, 20224, 21760, 22272, 23552, 23808, 22016, 20480, 19200, 16896, 14848, 15360, 14848, 13056, 12800, 11264, 9472, 8448, 7424, 5888, 4352, 2560, 0, -1536, -2304, -2560, -3584, -4608, -5376, -7936, -11008, -12288, -15104, -18432, -19968, -21760, -24064, -25344, -26112, -27392, -26624, -24320, -22528, -19456, -14336, -9984, -5632, 512, 5120, 8448, 12544, 15104, 15616, 15360, 12032, 6912, 3072, -1792, -6912, -10240, -13568, -15872, -15872, -16128, -14592, -11264, -8704, -4608, 1280, 4864, 8448, 13056, 15616, 17920, 20736, 21760, 22528, 24064, 23552, 21760, 20480, 18944, 16640, 15360, 15872, 14592, 13312, 12800, 11008, 9472, 8448, 7168, 5632, 3840, 2048, -512, -1792, -2560, -3072, -4096, -5120, -6144, -9216, -11776, -13312, -16384, -19200, -20736, -22784, -24832, -25600, -26624, -27392, -26112, -23808, -21760, -17920, -12800, -8448, -3584, 2048, 6400, 9728, 13568, 15616, 15616, 14848, 10752, 6144, 2048, -3072, -7680, -11008, -14336, -15872, -16128, -16128, -13824, -11008, -8192, -3328, 1792, 5120, 9472, 13568, 15872, 18432, 20992, 21760, 22784, 24064, 23040, 21504, 20480, 18688, 16384, 15872, 15872, 14336, 13568, 12544, 11008, 9472, 8448, 6912, 5120, 3584, 1280, -768, -2048, -2816, -3328, -4608, -5632, -7168, -10240, -12544, -14592, -17664, -19968, -21504, -23552, -25344, -26112, -26880, -27136, -25344, -23040, -20736, -16384, -11264, -6912, -1792, 3584, 7424, 11008, 14336, 15616, 15616, 13824, 9472, 5120, 1024, -4352, -8448, -11776, -14848, -15872, -16384, -15872, -13312, -10752, -7424, -2304, 2304, 5888, 10240, 14080, 16384, 18944, 21248, 22016, 23296, 23808, 22784, 21504, 20480, 18432, 16640, 16384, 15872, 14336, 13568, 12544, 10752, 9472, 8448, 6656, 4864, 3072, 768, -1280, -2048, -3072, -4096, -5120, -6144, -8448, -11264, -13312, -15616, -18688, -20480, -22272, -24320, -25600, -26368, -27136, -26624, -24576, -22528, -19456, -14592, -9728, -5376, 0, 5120, 8448, 12032, 15104, 15872, 15360, 13056, 8448, 4352, -256, -5376, -9216, -12544, -15104, -16128, -16384, -15616, -13056, -10240, -6400, -1280, 2816, 6656, 11008, 14336, 16640, 19456, 21248, 22272, 23552, 23808, 22528, 21504, 20224, 18176, 16640, 16640, 15616, 14336, 13568, 12288, 10752, 9472, 8192, 6400, 4352, 2560, 256, -1536, -2560, -3328, -4608, -5632, -6912, -9472, -12288, -14080, -16640, -19456, -21248, -23040, -24832, -25856, -26624, -27136, -26112, -24064, -21504, -18176, -13056, -8448, -3840, 1792, 6144, 9728, 13056, 15360, 15872, 15104, 11776, 7424, 3328, -1536, -6400, -9984, -13312, -15360, -16128, -16384, -15104, -12544, -9728, -5376, -256, 3584, 7424, 11776, 14592, 17152, 19968, 21504, 22528, 23552, 23552, 22272, 21248, 19968, 17920, 16896, 16640, 15616, 14592, 13568, 12288, 10752, 9472, 7936, 5888, 3840, 1792, -256, -1792, -2816, -3840, -5120, -6144, -7936, -10496, -13056, -15104, -17664, -20224, -21760, -23808, -25344, -26112, -26880, -27136, -25600, -23296, -20480, -16640, -11520, -6912, -2048, 3328, 7424, 10752, 14080, 15616, 15616, 14336, 10752, 6400, 2048, -2816, -7168, -10752, -13824, -15616, -16384, -16384, -14592, -12032, -8960, -4352, 256, 4096, 8448, 12288, 15104, 17664, 20224, 21504, 22784, 23808, 23296, 22272, 21248, 19712, 17920, 17152, 16640, 15360, 14592, 13568, 12032, 10496, 9216, 7424, 5376, 3584, 1280, -768, -2048, -3072, -4352, -5632, -6912, -8960, -11520, -13824, -16128, -18688, -20736, -22528, -24320, -25600, -26368, -26880, -26624, -24832, -22528, -19456, -14848, -9984, -5376, -256, 4608, 8448, 11776, 14848, 15872, 15616, 13568, 9728, 5376, 1024, -3840, -7936, -11520, -14336, -15872, -16640, -16384, -14336, -11776, -8192, -3328, 1024, 4864, 9216, 12800, 15616, 18176, 20480, 21760, 23040, 23552, 23040, 22016, 20992, 19456, 17920, 17408, 16640, 15360, 14592, 13312, 11776, 10496, 8960, 6912, 4864, 3072, 768, -1280, -2304, -3584, -4864, -6144, -7424, -9728, -12288, -14592, -16896, -19456, -21504, -23296, -24832, -25856, -26624, -26880, -26112, -24064, -21504, -18176, -13312, -8448, -3840, 1280, 5888, 9472, 12800, 15360, 15872, 15360, 12800, 8704, 4352, -256, -4864, -8960, -12288, -14848, -16128, -16640, -15872, -13824, -11008, -7168, -2560, 1792, 5632, 9984, 13312, 15872, 18688, 20736, 22016, 23296, 23552, 22784, 22016, 20992, 19200, 17920, 17408, 16384, 15360, 14592, 13312, 11776, 10240, 8704, 6656, 4352, 2304, 256, -1536, -2816, -3840, -5376, -6656, -8192, -10752, -13312, -15360, -17920, -20224, -22016, -23808, -25344, -26112, -26624, -26880, -25600, -23296, -20480, -16640, -11776, -6912, -2304, 2816, 7168, 10752, 13824, 15616, 15872, 14848, 11776, 7680, 3328, -1536, -5888, -9728, -13056, -15360, -16384, -16640, -15616, -13312, -10496, -6400, -1536, 2304, 6656, 10752, 13824, 16384, 19200, 20992, 22272, 23296, 23296, 22784, 21760, 20736, 18944, 18176, 17408, 16384, 15360, 14336, 13056, 11520, 9984, 8192, 6144, 4096, 1792, -256, -1792, -3072, -4352, -5888, -7168, -9216, -11520, -14080, -16384, -18688, -20992, -22528, -24320, -25600, -26368, -26880, -26624, -24832, -22528, -19456, -15104, -10240, -5632, -512, 4352, 8192, 11520, 14592, 15872, 15872, 14336, 10752, 6656, 2304, -2560, -6912, -10496, -13568, -15616, -16640, -16640, -15360, -12800, -9728, -5376, -768, 3072, 7424, 11264, 14080, 16896, 19456, 20992, 22528, 23296, 23296, 22528, 21760, 20480, 18944, 18176, 17408, 16128, 15360, 14336, 12800, 11264, 9728, 7680, 5632, 3584, 1280, -768, -2304, -3584, -4864, -6400, -7936, -9984, -12544, -14848, -17152, -19712, -21504, -23296, -24832, -25856, -26368, -26880, -26112, -24320, -21504, -18176, -13568, -8704, -4096, 1024, 5632, 9472, 12544, 15104, 16128, 15616, 13568, 9728, 5632, 1024, -3584, -7680, -11264, -14336, -15872, -16896, -16640, -14848, -12288, -8960, -4352, -256, 3840, 8192, 11776, 14592, 17408, 19712, 21248, 22528, 23296, 23040, 22528, 21504, 20224, 18944, 18176, 17152, 16128, 15360, 14080, 12544, 11008, 9472, 7168, 5120, 3072, 768, -1280, -2560, -3840, -5376, -6912, -8448, -11008, -13312, -15616, -17920, -20224, -22016, -23808, -25088, -26112, -26624, -26624, -25600, -23552, -20736, -16896, -12032, -7168, -2560, 2560, 6912, 10240, 13568, 15616, 16128, 15104, 12544, 8704, 4608, -256, -4608, -8704, -12032, -14848, -16128, -16896, -16384, -14336, -11776, -7936, -3584, 512, 4608, 8960, 12288, 15104, 17920, 19968, 21504, 22784, 23296, 23040, 22272, 21248, 19968, 18944, 18176, 17152, 16128, 15104, 13824, 12544, 10752, 8960, 6912, 4608, 2304, 256, -1536, -3072, -4352, -5888, -7424, -9216, -11776, -14080, -16384, -18688, -20992, -22784, -24320, -25600, -26112, -26624, -26368, -24832, -22528, -19456, -15360, -10496, -5888, -1024, 3840, 7936, 11264, 14080, 15872, 15872, 14592, 11776, 7680, 3328, -1280, -5632, -9472, -12800, -15104, -16384, -16896, -15872, -14080, -11008, -7168, -2816, 1280, 5632, 9472, 12800, 15616, 18176, 20224, 21760, 22784, 23296, 22784, 22272, 20992, 19712, 18688, 17920, 16896, 16128, 15104, 13568, 12032, 10496, 8448, 6144, 4096, 1792, -256, -2048, -3584, -4864, -6400, -8192, -10240, -12544, -14848, -17152, -19456, -21504, -23296, -24576, -25856, -26368, -26624, -26112, -24320, -21760, -18432, -14080, -9472, -4608, 256, 4864, 8704, 12032, 14592, 15872, 15872, 14336, 11008, 7168, 2560, -2048, -6400, -9984, -13312, -15360, -16640, -16896, -15872, -13568, -10752, -6400, -2304, 2048, 6144, 9984, 13056, 15872, 18432, 20480, 22016, 23040, 23040, 22784, 22016, 20992, 19712, 18688, 17920, 16896, 15872, 14848, 13568, 12032, 10240, 8448, 6144, 3840, 1536, -512, -2048, -3584, -4864, -6400, -8192, -10240, -12544, -14848, -17152, -18432, -26368, -4608, -19456, 0, 0, 0, 0, 256, 512, 768, 1280, 1536, 0, -1792, -2048, -3840, -2304, 2560, 2048, 4352, 8448, 3584, 1280, 9728, 11264, 7936, 16128, 17920, 13056, 18688, 20992, 17408, 21760, 25600, 24576, 24832, 26368, 29440, 29184, 28672, 32512, 31232, 28160, 29696, 28928, 27904, 30720, 30720, 30208, 28928, 23296, 23808, 27904, 24832, 25088, 29440, 28160, 27904, 30720, 28672, 24064, 19200, 16128, 17664, 18432, 16384, 16384, 15104, 11520, 9984, 9216, 8960, 10752, 10752, 6144, 1280, 512, 768, 1024, 1792, 2304, 2816, 3584, 4352, 4864, 3584, -768, -5120, -6656, -7680, -6656, -6144, -7936, -8192, -8704, -10240, -9984, -8448, -8704, -11520, -14336, -15360, -16896, -16384, -14080, -15360, -15872, -14336, -15104, -14848, -12800, -14336, -17920, -18688, -19456, -22016, -19712, -17920, -20480, -19456, -18176, -19712, -18176, -16896, -19456, -21760, -20992, -23040, -24320, -20480, -20992, -23552, -21760, -22016, -24064, -21760, -20224, -22016, -23552, -23040, -24064, -25856, -23552, -21760, -23040, -21504, -19712, -19968, -18944, -18688, -21760, -22016, -21760, -24320, -21760, -19712, -23040, -22528, -21248, -24064, -23808, -21248, -20736, -20736, -22016, -22784, -22784, -24064, -22528, -19712, -19712, -18176, -15104, -14848, -15104, -16128, -18432, -18944, -19712, -18688, -15616, -17152, -18432, -17152, -18688, -20480, -18944, -17408, -15360, -14336, -16640, -17920, -17152, -18432, -16896, -13312, -12544, -10240, -6912, -6912, -8192, -9984, -12032, -12800, -10752, -7680, -7936, -8704, -8192, -9728, -11776, -11776, -11008, -8960, -5120, -4096, -6144, -7680, -7680, -7936, -6144, -3328, -1536, 1024, 3328, 2816, 768, -1280, -2304, -512, 3072, 3840, 3840, 4096, 2304, 768, -512, -1280, -256, 3072, 6144, 7680, 7424, 5120, 4352, 5632, 6400, 7680, 10496, 12032, 12544, 11776, 9472, 8192, 10496, 13312, 13824, 15360, 15616, 13312, 12288, 11520, 9216, 8960, 11008, 13056, 15360, 17152, 17664, 15360, 14592, 16128, 16128, 16384, 18688, 19200, 18432, 17664, 16128, 17152, 19968, 19968, 20992, 22784, 20480, 18688, 19456, 17152, 15360, 16384, 17152, 18688, 20224, 21248, 22528, 20992, 19200, 20480, 20736, 19712, 21248, 21248, 19456, 18944, 19712, 21248, 21760, 22016, 24064, 22784, 20480, 20992, 19968, 17664, 17408, 17408, 17664, 19968, 20480, 20736, 23040, 21248, 18688, 20224, 19712, 17920, 18688, 17920, 15872, 16640, 18688, 19200, 19456, 21504, 20992, 17920, 18176, 17664, 15104, 14592, 13824, 12288, 13568, 16128, 16384, 17408, 19456, 16896, 14592, 14848, 13056, 10752, 10240, 8448, 7168, 9472, 11776, 12544, 14080, 14336, 10752, 9472, 9472, 6912, 5632, 5120, 2560, 1024, 2048, 3840, 6144, 7680, 7936, 6144, 3584, 2048, -768, -3584, -5376, -6656, -6656, -3840, -1024, -256, -1024, -3328, -5376, -6656, -8704, -9984, -10752, -12800, -14592, -16128, -16896, -15360, -12032, -11008, -12288, -13056, -14592, -16896, -19200, -20992, -22528, -23296, -22528, -19968, -18944, -20736, -22016, -21760, -23552, -25856, -25600, -26112, -27904, -27904, -28160, -28672, -28928, -29440, -27904, -27136, -28928, -28928, -27392, -28160, -28160, -27136, -27648, -28672, -27904, -28160, -29184, -28416, -25088, -24320, -25088, -23808, -23808, -25088, -24064, -22784, -20736, -17664, -16640, -18176, -18688, -18688, -19712, -18688, -15872, -14336, -12288, -10240, -10496, -11520, -12032, -12032, -9472, -5120, -2816, -1024, 1280, 1024, 768, 1536, 2304, 4096, 7680, 9984, 12032, 13056, 11264, 10240, 11520, 12032, 12800, 15104, 16384, 16896, 17408, 16640, 16640, 19200, 20480, 19968, 22272, 24320, 23296, 23808, 25088, 24576, 25088, 26624, 25600, 24576, 25344, 26624, 25856, 25600, 27136, 27392, 26880, 27648, 27904, 27904, 28160, 28416, 28160, 25856, 22272, 20992, 21504, 20736, 20992, 22528, 22784, 23040, 23296, 21760, 18176, 14592, 12544, 12288, 13056, 13312, 14080, 15104, 14848, 14848, 15360, 15616, 15616, 14592, 10752, 6144, 3584, 1792, 1280, 2304, 2816, 3840, 5120, 5376, 4864, 2816, -768, -4608, -6912, -8448, -7936, -6400, -6144, -5376, -4096, -4096, -3584, -2816, -4352, -7424, -10240, -12544, -15104, -15616, -14080, -13824, -13312, -11520, -10752, -10496, -10496, -12288, -15104, -16640, -18432, -20736, -20224, -18432, -18688, -17664, -15872, -15616, -15104, -15360, -17664, -19456, -20224, -22272, -23552, -21504, -20736, -20992, -19456, -18432, -18176, -17152, -16896, -18432, -20224, -20736, -22272, -24064, -23552, -22272, -22016, -20992, -19456, -19200, -19200, -19968, -21760, -22272, -23296, -24576, -23296, -20992, -21248, -20480, -18944, -18944, -18176, -16384, -16384, -17408, -18688, -19712, -20736, -22272, -22528, -20992, -20224, -19456, -17920, -17664, -18432, -19456, -20480, -21504, -22272, -20992, -18176, -17152, -16384, -14848, -14592, -14080, -12544, -11008, -9984, -10240, -12032, -13824, -14848, -16384, -16896, -15616, -14848, -13824, -12544, -12800, -14080, -15104, -16128, -16640, -14848, -11520, -9728, -8192, -6400, -6144, -5888, -4608, -3328, -1280, 768, 1024, -512, -2816, -4352, -5888, -6656, -5888, -5120, -4608, -3840, -4608, -6144, -7168, -7168, -5376, -1792, 768, 2816, 4608, 5120, 4864, 5632, 6144, 7680, 10240, 12032, 13056, 12544, 10240, 8192, 7168, 6144, 5888, 6400, 6400, 5888, 5120, 3840, 3840, 5888, 8704, 11008, 13056, 15104, 15104, 14848, 15104, 14848, 15360, 17152, 18688, 19968, 21504, 21760, 19968, 18176, 17408, 16128, 15360, 15360, 14592, 13568, 12800, 12800, 14336, 16640, 17920, 19456, 21504, 21504, 20736, 20736, 20224, 19456, 20224, 21504, 22272, 23296, 24576, 25088, 24064, 22528, 21760, 20736, 19456, 18688, 17920, 16896, 16896, 17920, 19456, 20480, 21504, 23296, 23552, 22272, 22016, 21248, 19968, 19456, 19968, 20736, 21760, 22528, 23296, 24576, 23808, 22016, 21248, 19968, 18176, 17408, 16384, 15616, 16384, 18176, 18944, 19968, 21504, 22016, 20480, 19456, 18432, 16384, 15104, 14336, 14080, 15104, 16896, 17664, 18944, 20224, 19456, 17664, 16384, 14592, 12288, 11008, 9984, 9984, 11520, 13312, 14336, 15872, 16128, 14080, 12032, 10496, 7936, 5376, 3840, 2048, 1280, 2304, 4096, 6144, 7936, 8960, 8448, 6656, 4864, 2560, 0, -1536, -2304, -1792, -1792, -3328, -4352, -5632, -6656, -7936, -8704, -9472, -10240, -10752, -11264, -11776, -12288, -12800, -13056, -13824, -14336, -14848, -15616, -16384, -17152, -17920, -18944, -19968, -20992, -22016, -23040, -23808, -24832, -25344, -26112, -26624, -27136, -27648, -27904, -28160, -28416, -28672, -28928, -28928, -29184, -29184, -29440, -29440, -29440, -29440, -29440, -29184, -28928, -28416, -27904, -27392, -26624, -25600, -24832, -23808, -23040, -22272, -21504, -20992, -20480, -19968, -19456, -18944, -18688, -18176, -17664, -17152, -16640, -15616, -14848, -13568, -12288, -10752, -8960, -7168, -5376, -3328, -1536, 256, 2048, 3840, 5376, 6656, 7936, 8960, 9728, 10496, 11264, 11776, 12288, 12800, 13312, 14080, 14848, 15616, 16384, 17408, 18432, 19456, 20480, 21248, 22272, 23040, 23552, 24064, 24576, 25088, 25344, 25600, 25856, 26112, 26112, 26368, 26368, 26368, 26368, 26624, 26368, 26368, 26368, 26112, 25856, 25344, 24832, 24064, 23552, 22528, 21760, 20736, 19968, 18944, 18176, 17152, 16384, 15616, 14848, 14080, 13568, 13056, 12544, 12032, 11776, 11264, 10752, 10240, 9472, 8704, 7680, 6656, 5632, 4352, 3072, 2048, 768, -256, -1280, -2304, -3328, -4096, -5120, -5888, -6656, -7424, -7936, -8448, -8960, -9472, -9728, -10240, -10752, -11264, -11776, -12288, -13056, -13824, -14336, -15104, -15616, -16384, -16640, -17152, -17664, -17920, -18432, -18944, -19200, -19712, -19968, -20480, -20736, -20992, -21248, -21504, -21760, -22016, -22016, -22272, -22528, -22784, -23040, -23040, -23296, -23552, -23552, -23552, -23552, -23552, -23552, -23296, -23296, -23552, -23552, -23552, -23808, -23808, -24064, -24064, -24064, -24320, -24320, -24320, -24320, -24320, -24320, -24320, -24320, -24320, -24064, -23808, -23552, -23296, -23040, -22784, -22272, -22016, -21760, -21760, -21760, -21504, -21504, -21760, -21760, -21760, -21760, -21760, -21760, -21760, -21760, -21760, -21504, -21248, -20992, -20736, -20224, -19712, -19200, -18688, -17920, -17408, -16640, -16128, -15872, -15360, -15104, -15104, -15104, -15104, -15104, -15104, -15104, -15360, -15104, -15104, -15104, -14848, -14592, -14080, -13568, -12800, -12032, -11264, -10240, -9216, -8192, -7424, -6400, -5632, -5120, -4608, -4352, -4096, -3840, -3840, -4096, -4096, -4096, -4096, -4096, -4096, -3840, -3328, -2816, -2304, -1536, -512, 512, 1536, 2560, 3840, 4864, 5632, 6656, 7424, 7936, 8448, 8960, 9216, 9216, 9216, 9216, 8960, 8960, 8960, 8960, 8960, 9216, 9728, 10240, 10752, 11520, 12288, 13312, 14080, 14848, 15616, 16384, 17152, 17920, 18432, 18688, 18944, 19200, 19456, 19456, 19456, 19200, 19200, 18944, 18944, 18944, 18944, 18944, 19200, 19712, 19968, 20480, 20992, 21248, 21760, 22272, 22784, 23040, 23296, 23552, 23808, 24064, 24064, 24064, 24064, 24064, 23808, 23808, 23552, 23296, 23296, 23040, 23040, 23040, 23040, 23296, 23296, 23552, 23552, 23808, 23808, 24064, 24064, 24064, 24064, 24064, 24064, 24064, 24064, 23808, 23808, 23552, 23552, 23296, 23040, 22784, 22528, 22272, 22272, 22016, 22016, 21760, 21760, 21760, 21504, 21504, 21248, 21248, 20992, 20736, 20480, 20224, 19968, 19712, 19712, 19456, 19200, 18944, 18432, 18176, 17920, 17408, 17152, 16640, 16384, 16128, 15616, 15360, 14848, 14592, 14080, 13568, 12800, 12288, 11520, 11008, 10240, 9728, 9216, 8704, 8192, 7680, 7424, 6912, 6400, 5888, 5376, 4864, 4352, 3584, 3072, 2304, 1536, 768, 0, -1024, -2048, -3072, -4352, -5376, -6400, -7424, -8448, -9216, -9984, -10752, -11520, -12032, -12544, -13056, -13568, -14080, -14848, -15360, -16128, -16640, -17408, -18176, -18944, -19712, -20736, -21504, -22272, -23296, -24064, -24832, -25344, -26112, -26624, -26880, -27392, -27648, -27904, -28160, -28416, -28416, -28672, -28672, -28928, -28928, -28928, -28928, -28928, -28928, -28672, -28416, -27904, -27392, -26880, -26112, -25344, -24576, -23808, -23040, -22272, -21504, -20992, -20224, -19712, -19200, -18688, -17920, -17664, -16896, -16384, -15360, -14848, -13568, -12544, -11264, -9984, -8192, -6912, -4864, -3584, -2048, -768, 768, 2816, 5632, 2560, 2048, 256, 256, 256, 256, 256, 512, 512, 512, 512, 768, 768, 768, 768, 1024, 1024, 1280, 1280, 1536, 1280, 1536, 1536, 1536, 1536, 1536, 1536, 1792, 1280, 1792, 1280, 1536, 1024, 1536, 1024, 1024, 1024, 1024, 768, 768, 512, 768, 256, 768, -512, 512, 0, 0, 0, 0, -512, -256, -512, -768, -768, 0, -1280, -256, -512, -512, -512, -256, 0, -768, -256, -256, 0, 256, -256, 0, -256, 0, 0, 256, 0, 0, 256, -256, 256, -256, 256, -512, -256, -768, 0, -512, -256, -512, -512, -512, -768, -512, -768, -1024, -1280, -1536, -1280, -2304, -2048, -2304, -2304, -2304, -2816, -2560, -3328, -3584, -3584, -3840, -4096, -3840, -4352, -4864, -4864, -5376, -4608, -5376, -5120, -5632, -5120, -6144, -5376, -5632, -4864, -5120, -5376, -4352, -4864, -4096, -4352, -3840, -4352, -3328, -2816, -2560, -1792, -1280, -768, 512, 1536, 1024, 2048, 2304, 4608, 3584, 7936, 6400, 6144, 6400, 6144, 5376, 3328, 3840, 3840, 2816, 2304, 256, 1024, -5120, -4608, -9728, -11264, -14592, -14592, -14080, -14080, -13312, -14080, -11776, -12032, -10240, -8192, -6656, -4864, -4096, -512, 768, 3328, 4864, 7168, 7680, 9472, 10240, 11264, 9984, 9728, 8960, 8704, 9472, 10496, 12288, 13056, 13568, 14848, 15616, 17920, 18944, 19456, 19456, 20480, 20736, 22016, 21248, 21248, 19968, 19968, 18688, 17664, 16640, 14080, 12032, 10240, 9216, 7424, 5888, 4096, 3584, 2048, -512, -1024, -2816, -2816, -4864, -5632, -6656, -6400, -8704, -9984, -10240, -10496, -11520, -12544, -13056, -14592, -14336, -14848, -15104, -16896, -17920, -17920, -18432, -16640, -16384, -15104, -13568, -12544, -11520, -8704, -7424, -5376, -3840, -2560, -1536, -1536, -768, -1024, 512, 768, 768, 768, -256, -768, -2816, -2816, -3328, -4096, -5632, -6144, -6912, -8192, -8704, -9472, -8960, -7936, -7680, -6656, -6400, -5632, -5376, -3840, -3328, -3840, -2560, -3072, -3072, -1792, 512, 3840, 5632, 6912, 6144, 7168, 5632, 5632, 5376, 5632, 4352, 3328, 3584, 2304, 1280, 512, -2048, -3072, -4096, -3584, -4352, -4352, -4352, -4352, -3584, -2048, -768, -768, 0, 1280, 768, 1280, 1536, 768, -512, -1536, -2304, -2816, -3328, -4608, -4864, -7424, -10752, -15616, -18432, -20224, -20736, -21248, -20992, -20224, -19456, -16640, -13824, -10752, -8448, -6144, -3584, 0, 4608, 8448, 12288, 15872, 19200, 22272, 23808, 25344, 25600, 26112, 26112, 26624, 26112, 25600, 25600, 24576, 23808, 24320, 24576, 26880, 27904, 28672, 28416, 28160, 27136, 27136, 26624, 26112, 24832, 23808, 21760, 20480, 18176, 15360, 12288, 9216, 6656, 3072, 0, -1280, -3328, -5376, -7168, -7936, -9216, -10752, -12544, -13568, -14336, -15104, -15616, -16128, -16384, -16384, -16128, -17152, -17920, -19712, -19200, -19712, -19968, -20224, -20480, -20736, -20480, -19200, -17664, -16384, -14592, -12800, -11008, -8960, -6656, -4096, -1536, 1536, 3328, 4352, 5632, 6656, 6400, 6912, 6912, 6656, 5888, 4864, 2816, 1280, -1280, -3072, -4864, -6144, -7936, -9472, -10752, -11520, -12800, -12544, -12288, -12032, -11008, -10496, -9728, -9728, -9472, -8960, -8960, -9472, -10752, -10240, -8448, -6912, -5120, -3072, -2816, -3328, -2560, -2304, -2560, -2560, -2560, -3328, -2816, -2304, -2048, -2816, -3328, -4096, -4608, -4352, -3840, -3840, -3584, -3072, -2048, -768, 768, 2048, 4096, 5632, 6400, 7936, 8704, 9216, 9216, 8704, 7936, 6400, 5888, 6144, 6656, 5888, 3328, -256, -4096, -7424, -9728, -11520, -13056, -14336, -14592, -13824, -12288, -9984, -8704, -7424, -5120, -2560, 0, 3328, 6912, 9984, 13824, 17408, 20224, 22272, 23552, 24064, 24576, 24064, 23552, 22784, 22272, 20992, 19456, 18432, 18176, 18944, 19456, 20736, 21248, 21248, 21504, 21504, 21760, 21760, 20992, 20736, 20992, 20480, 19200, 18176, 16896, 14592, 11776, 8704, 6144, 3840, 1280, -512, -2048, -3328, -4864, -6656, -7936, -9472, -10496, -11264, -12288, -13568, -13824, -13568, -13824, -13824, -14592, -15616, -16384, -17152, -17920, -18432, -19200, -19712, -20224, -20224, -19456, -18688, -17920, -16128, -14848, -13568, -12032, -9728, -7424, -5376, -3328, -1536, 0, 1024, 1792, 1792, 2048, 2048, 1536, 1280, -256, -2048, -3840, -5632, -7680, -9216, -10496, -12032, -13056, -13824, -14336, -14848, -15104, -14336, -12800, -11520, -10752, -9472, -7936, -6656, -5888, -5888, -5888, -6144, -5376, -3584, -1536, 512, 2048, 3072, 3840, 4608, 5376, 5120, 5120, 5120, 5120, 5376, 5888, 5632, 4608, 3328, 2560, 2048, 1536, 1280, 1024, 768, 512, 512, 1024, 1792, 2560, 3328, 4608, 5632, 6144, 6656, 7168, 6912, 5376, 3584, 2048, 1280, 1024, 512, -768, -3072, -6144, -9472, -12800, -15104, -17152, -19456, -20480, -20224, -19200, -17664, -15616, -14080, -12032, -9728, -6912, -3840, -512, 2816, 6912, 11008, 14848, 18176, 20992, 23040, 24064, 24576, 25088, 25088, 25088, 24320, 22784, 21504, 20736, 20224, 20736, 21760, 22528, 22784, 23296, 23552, 23552, 23040, 22784, 22784, 22528, 21760, 20992, 20224, 19200, 17152, 14848, 12288, 9472, 6400, 3584, 1024, -1024, -2560, -4352, -6144, -7936, -9472, -10752, -12032, -13056, -14336, -15104, -15104, -15104, -15104, -15616, -16128, -16640, -17152, -17920, -18432, -18944, -19456, -19968, -19968, -19968, -19200, -17920, -16896, -15616, -14336, -12800, -10496, -8448, -5888, -3584, -1536, 512, 2560, 4096, 4864, 5376, 5888, 6144, 6144, 5632, 4864, 3328, 1792, 0, -1536, -3584, -5120, -6400, -6912, -8192, -9472, -9984, -9984, -9728, -9216, -8448, -7680, -6912, -5632, -4864, -4864, -5120, -5888, -6144, -5632, -4608, -3328, -2048, -1024, 0, 512, 1280, 1536, 1280, 768, 512, 1024, 1536, 1536, 1280, 256, -512, -1536, -2048, -2304, -2560, -2816, -3328, -3072, -3072, -2816, -2304, -1024, 0, 1024, 2048, 3328, 4608, 5120, 4864, 3584, 2560, 1536, 1024, 1024, 1024, 0, -2048, -4352, -7168, -9728, -12544, -15360, -17408, -18432, -18432, -17920, -16640, -15104, -13824, -11776, -9472, -6912, -4352, -1280, 2048, 5632, 9472, 13056, 16896, 19712, 21504, 22528, 23296, 23808, 24064, 24064, 23296, 21760, 20224, 19200, 18944, 19456, 19712, 20480, 21248, 21760, 21760, 21760, 22016, 22016, 21760, 21760, 21760, 21248, 20736, 19712, 17920, 16384, 14080, 11264, 8192, 5632, 3328, 1536, -256, -2304, -4096, -5632, -6912, -8192, -9728, -11008, -11776, -12032, -12032, -12032, -12288, -12544, -12544, -12800, -13312, -13824, -14336, -15104, -15872, -16384, -16896, -16640, -16384, -15616, -15104, -14336, -13568, -12288, -10496, -8448, -6400, -4352, -2560, -512, 1024, 2304, 3328, 3840, 4096, 4352, 4352, 3840, 2816, 1792, 256, -1792, -3840, -5632, -6912, -8448, -9728, -11008, -12032, -12544, -12800, -12800, -12544, -11776, -10752, -9472, -7936, -7168, -7168, -7424, -7680, -7424, -6656, -5632, -4352, -3328, -2048, -768, 512, 1536, 1792, 1536, 1280, 1536, 2048, 2560, 3072, 2816, 2048, 1280, 768, 256, -256, -512, -768, -1024, -1536, -1792, -1536, -768, 0, 256, 1280, 2560, 4096, 5120, 5376, 4864, 3840, 2560, 2048, 1536, 1536, 1024, 0, -1280, -3072, -5632, -8448, -11520, -14592, -16640, -17920, -18432, -17920, -17408, -16384, -14848, -13056, -11264, -9216, -6144, -3328, -512, 2816, 6912, 11008, 14848, 17920, 19968, 21248, 22528, 23552, 24576, 24832, 23808, 22784, 21760, 20736, 20480, 20736, 21248, 22016, 22528, 23040, 23296, 23296, 23296, 23296, 23296, 23296, 23296, 22784, 22016, 21248, 20224, 18432, 16128, 13312, 10496, 7680, 5376, 3328, 1024, -1280, -2816, -4352, -5888, -7936, -9728, -11264, -12032, -12544, -12800, -13312, -13824, -14080, -14592, -14592, -14848, -15360, -16128, -16896, -17664, -18432, -18944, -18688, -18432, -17920, -17664, -17152, -16384, -15104, -13568, -11520, -9472, -7680, -5632, -3584, -1792, -512, 768, 2048, 2560, 3072, 3072, 3328, 3072, 2048, 768, -1024, -2560, -4096, -5376, -6912, -8448, -9472, -10496, -11264, -11776, -12288, -12288, -11520, -12288, -11008, -9472, -8448, -7936, -8192, -8448, -8192, -7424, -6656, -5632, -4608, -3072, -1280, 256, 1536, 2304, 2304, 2304, 2304, 2816, 3584, 4096, 4096, 3584, 3072, 2048, 1280, 768, 512, 256, -256, -768, -1024, -1024, -512, -256, 512, 1280, 2816, 4608, 6144, 6912, 6912, 6144, 5120, 4352, 3840, 3328, 2816, 2304, 1280, -256, -2560, -5632, -8960, -12544, -15616, -17920, -19200, -19712, -19456, -18688, -17664, -16128, -14336, -12032, -9216, -6400, -3328, 0, 4096, 8704, 13312, 17152, 20224, 22528, 24320, 25856, 27136, 27904, 27648, 26880, 25600, 24320, 23552, 23040, 23296, 23808, 24576, 25344, 25600, 25856, 25856, 25856, 25856, 25856, 25856, 25600, 24832, 24320, 23296, 21760, 19968, 17152, 14080, 11008, 7936, 5376, 2816, 256, -1792, -3584, -5376, -7424, -9472, -11520, -13056, -13824, -14336, -14848, -15360, -15872, -16384, -16640, -16896, -17152, -17664, -18432, -19456, -20480, -20992, -21504, -21248, -20992, -20480, -20224, -19712, -18688, -17152, -15360, -13056, -10752, -8704, -6400, -4096, -2048, -512, 1024, 2304, 3072, 3328, 3584, 3584, 3328, 2304, 768, -1280, -3072, -4608, -6400, -7936, -9472, -10752, -12032, -12800, -13568, -13824, -13568, -12288, -10496, -9216, -8192, -7936, -7936, -8192, -7936, -7168, -6400, -5632, -4352, -3072, -1280, 256, 256, -512, -256, -2304, -2304, -1536, 1280, 1536, -256, -2560, 2048, 6144, 2816, -512, -3584, -2304, -3840, -3328, 1280, 3584, 3072, -1536, -256, -3072, 256, -2304, 3072, 3072, 2560, 1280, -4864, -2816, -3328, -512, 2048, 1280, 256, -512, -768, 2304, -1536, 1536, 1280, 1536, -768, -4352, -1792, 768, 512, -256, 0, 1792, -1792, 1280, 1024, 1536, -4608, -6144, 1536, 5120, -256, -1024, -256, 2560, 768, -2560, 2048, 1792, -2816, -4352, -3840, 1280, 4608, 1024, 256, 2048, -4096, -1024, 0, 2816, 2304, -2560, -3840, 0, -5632, -3072, 4864, 8704, 4096, -2304, -4096, -1792, -3072, -2560, 3328, 5888, -256, -2560, -512, -768, -2816, 3328, 1792, -1536, -2304, 768, 2816, -2560, -4608, 3072, 5632, 1792, -6912, -7424, -1024, 5120, 5120, 2560, 2048, -4096, -6656, -1536, 5632, 5376, 1792, 3840, 2048, -12800, -12800, -1792, 8960, 5632, -3328, 8192, 10496, -8448, -11776, -2560, 5888, -1792, -6400, 5888, 5376, -9728, -9216, 3584, 11264, 512, 512, 8704, -3584, -13056, -7424, 2816, 4864, 1792, 5632, 3328, -5888, -5376, -2048, -2304, 256, 3584, 6656, 6656, -2048, -8704, -8448, 1024, 256, -1536, -512, 4096, -1792, -5888, 3072, 6912, 1280, 1536, 1536, 0, -2048, 0, -256, -4352, -3328, -3072, 768, 2304, 1024, 2816, 5888, 9216, 0, -11008, -4096, 1024, -5376, -6656, 6912, 4096, -6400, 768, 16640, 1024, -8704, 6144, -2560, -9728, -3584, 3328, 1024, -3840, 9216, 11264, -10752, -13056, 5120, -1280, -1536, 17408, 5120, -4608, -9984, -2816, 2304, 4352, 1536, -8448, -5120, -3328, 12288, 7680, 5632, -1024, -2304, -13568, -5120, 8192, 8192, -4096, 4352, -2816, -9216, -2048, -1280, 9984, 7168, 8448, 5376, -16384, -12288, 768, -5632, 3840, 15872, -6656, 0, 768, 1280, 18688, -3584, -12288, -5120, -15104, 1024, 17920, 15360, -1792, -512, -22528, -5632, -4352, 9984, 4352, 8448, -768, 3840, 7168, -12032, -20480, -9472, 1280, 1792, 26624, 4096, -25344, -23552, -9216, 27904, 19968, 6656, -3840, -23552, -5376, 15872, 12288, -13056, -20736, -6400, 14080, 16128, 8960, 5376, -29440, -13824, 25856, 18688, -10496, -28160, -16896, 12800, 27392, 11520, -2048, -27904, -9728, 3072, 26112, 768, 4352, -11520, -512, -9216, 9984, 11776, -3072, -7168, -6912, -4352, 4352, -4608, 20992, -1280, -768, -6400, -1280, -3584, 3840, 2304, -768, -4352, -1536, 512, 1792, -9216, -3328, 1536, 5376, -5888, -5120, 4096, -4608, 768, -512, 6656, 0, 3328, -5888, -512, -4864, -7168, -4608, 3840, 3072, 5632, -1024, 5888, -4352, -5632, -2304, -4608, -1024, 2816, 3328, 0, 8704, -4096, -5120, 6656, 5888, 3840, -1024, -6400, 1792, 2048, -2304, 2048, 11264, 256, -10240, 4352, -8192, 2304, -7680, -13312, 13312, 768, 512, -5376, 21248, 14848, -3584, -11776, -15616, -3072, -17152, -5120, 16384, 18432, 14592, -2560, 1280, 256, -19712, 7936, -12032, -9984, 3072, 5632, 14592, 7168, 0, 2304, -19456, 3840, -18944, 8448, -3072, 9984, 29184, -8960, -9216, -9728, -5888, 6912, -5376, 3584, 14336, 12032, 1536, -18432, -15616, -1024, 4608, -1024, 4864, 3328, 11520, 18176, 12288, -256, -32000, -13312, -14336, -5120, -4608, -3072, 13056, 19968, 17408, -11776, 8192, -10240, -7424, -7168, -20736, -6400, 19200, 10752, 14848, -9728, 256, -7424, -8704, 7936, -9216, -3584, 2560, 16384, 9472, 512, -7936, -18432, -4352, -8448, 7680, -13312, -13824, 6400, 11008, 17920, 20736, -2304, -18688, 1024, -16640, 3840, -7168, 6400, 0, 7168, 4864, 13056, -6656, 1536, 0, -9472, -3840, -5632, -5120, -4096, -1280, 12800, 14336, 17152, 6400, 4096, -8960, -7424, -3584, -9984, 4864, -6144, -13312, -3328, -8192, -2560, 9984, 8448, 15104, 1536, 9472, 14080, 2816, -2304, -8960, -3840, -14592, -14336, -9216, -8704, 4864, 4864, 1536, 5120, 4352, -2816, 1280, 6656, 4864, 4096, 1792, -5120, -6656, -14080, -15872, -9216, -4608, 4864, 9472, 12032, 6400, -1536, -3584, 256, -1024, -3328, 3072, 5888, 8704, 9728, 10496, 8448, 7936, -2560, -14336, -13312, -12544, -7936, -10240, -5376, -3072, 0, 1280, 3072, 5632, 5632, 5376, 7936, 3072, 512, -2048, -1024, -4608, -1792, 768, 256, -256, 2816, 3072, 4608, 4352, 2304, -512, -3072, -3328, -2816, -256, 2048, 768, 768, 512, 1280, -1280, -4096, -3840, -3328, -2048, -3072, -2304, -512, -256, 512, 1792, 2560, 1792, 2816, 3584, 1792, -256, -1024, 1280, -768, -512, 0, -1536, -2560, -256, -1280, 768, 2304, 0, -2048, -2304, -1536, -1536, 0, 1536, 768, 1536, 1792, 2560, 0, -2048, -768, -1280, -256, -2048, -1792, -1024, -768, -768, 0, -256, -1536, 512, 1792, 1792, 1280, 1024, 2560, 1280, 2048, -256, -2816, -3840, -2816, -3840, -2560, -256, -2048, -3072, -1280, 256, 768, 1536, 2048, 2816, 4608, 5632, 6656, 2560, -2560, -256, -3840, -768, -5376, -4096, -3584, -3072, -1792, -2048, -4608, -5120, -2816, 2304, 5120, 6912, 6656, 2816, 256, 5376, 1536, 768, -2304, -3840, -2304, -5120, 768, 1280, 5376, 3584, 1536, 2816, -5376, -5632, -1536, -5376, -5888, -4608, 2816, 1536, 1280, 5376, 2304, 5888, 4096, -768, -7680, -1792, -6912, -1024, 1280, 4608, 5632, 4096, 512, 1792, -256, -512, -2560, -3584, -2560, -4352, -2560, -3840, -4096, 768, 3072, 7680, 4608, -256, -1536, -3840, -768, 1280, 2816, -4608, -512, 2048, 5376, 2816, -3328, -1024, -7680, -1792, 0, 3072, 6400, -768, 4352, 3584, -5120, -1536, -6912, -10496, -2816, -3072, 5888, -2048, 3328, 6144, 4608, 6912, -2816, -2048, -3072, -512, 4352, 5888, 3328, -5120, -5376, -512, -5376, -8704, -11776, -5888, 7168, 12288, 2304, -2560, 2048, 7424, 6912, 1280, -7424, -3072, 3328, -1280, -512, -8960, 256, 768, 6144, 3328, 4352, -4608, -7680, -5376, 3584, -256, 1536, -2048, 12288, 11520, -1792, -8704, -12544, -8192, -1536, -6656, 5120, 7424, 19456, 7680, -5376, -16896, -9216, -3840, 10240, -1280, 7424, 768, 2560, -9984, -6400, -512, 6144, 4864, 4864, -1024, -2048, 768, -5632, -5888, -4608, 3328, 4352, -768, -6400, 5888, 16896, 6656, -4608, -6912, -8704, -7680, -7680, 9216, 6400, 7168, -5632, -4352, -1792, -5632, 5376, 4608, 10752, 2048, -6400, -7168, -7936, -2560, 3840, 4608, 0, -256, -1280, 4096, -3072, 3328, 3328, 3072, -2048, -9472, -2304, 3328, -1280, 2048, -768, 3328, -2048, 1024, 6144, -4096, -11008, -4608, 6656, 6656, -2816, -2304, 4864, 2304, -3840, 2304, 3840, -3072, -7936, -6912, 2048, 7424, 1280, 1792, 4352, -8448, -3584, 3584, 5888, -256, -4608, -4608, -1024, -8960, -4352, 12032, 18176, -4096, -5120, -2816, -4096, -6400, 1536, 9472, 3584, -4608, 256, -2048, -3584, 2560, 3584, 512, -5120, 0, 5120, -2560, -6400, 3584, 8192, 1792, -9984, -9728, -768, 8704, 6400, 3328, 768, -6144, -8704, 1280, 9728, 4608, 1792, 7424, -7680, -18944, -10496, 9216, 10240, -3072, 6656, 14080, -4352, -15104, -6656, 7168, -512, -7936, 6144, 6400, -11264, -9984, 5376, 11264, -256, 2560, 8448, -8704, -12800, -3072, 4608, 3328, 5120, 4352, -1536, -7936, -2560, -1536, -256, 1792, 3072, 3584, 1536, -4096, -6144, 1536, 2304, -4096, -4096, 1536, 512, -2560, 3328, 3072, -2560, 0, 2816, 2816, 2560, -768, -5632, -5632, -3072, -1792, 4864, 4352, -512, -3072, 1536, 4096, 1792, -2816, -256, -5120, -5632, -2048, 6656, 4096, -768, 3072, 256, -8448, 512, 7680, -5888, -1280, 7168, -4352, -4864, 5376, 2304, -7168, -3584, 6400, -256, 1024, 6144, 0, -6656, -2304, 1792, 512, -512, 5120, -2560, -2816, 1280, -768, -1024, 2048, -2304, 3584, 4608, 6400, -5632, -3840, -5632, -768, -3072, 6912, 7680, 3840, -2816, -6656, -1024, 3840, -1792, -3584, 5888, -5888, -1024, 8704, -512, -9728, 3584, -2816, -6144, 4096, 8704, 2816, -3328, 768, -768, -4864, -8704, 0, -768, 6144, 11008, 256, -3072, -9728, -6400, -2816, 5888, 8960, 3072, -7168, -6400, -4096, 1792, 5632, 256, -2560, 2048, 2048, -768, 1536, -6144, -5120, -3328, 2304, 7936, 3072, -4096, 1792, -7424, 1280, 2048, -7168, 768, 1024, 3072, 6656, -2304, -3840, -1280, -5120, 2304, 5376, 0, 256, -2304, 0, 2048, -768, -1792, -2304, -768, 5632, 2048, 768, -2816, -2304, -2816, 768, 3840, 2304, -2560, 256, -768, -768, -512, -1280, 2304, 0, 3072, 1792, -3840, -1792, 0, -2048, 1280, 2304, -1280, 1792, -1792, 2560, 1024, -2816, -512, -2048, -1024, 2304, 2304, 0, -512, -2816, -768, -1024, 768, 1024, 768, -512, 768, 768, -2048, -2304, -512, 0, 768, 1280, -256, -2560, -1792, 512, 2048, 768, 0, -1280, -1280, 512, 1024, -512, -1280, -768, 512, 768, 0, 512, -1280, -768, 768, 512, -512, -1024, -512, 256, 512, 256, 0, 0, 0, 0, -256, -1792, -2304, -1280, 0, 512, 512, 1280, 1536, 0, -2816, -3328, -1280, 768, 256, 0, 0, 256, -768, -2304, -1536, -256, 1280, 768, -768, -1280, -768, -256, -1024, -768, -256, 512, -512, -2304, -1792, -512, -1280, -4608, -7936, -9216, -9216, -10496, -9728, -7424, -5376, -6912, -7936, -6656, -1024, 9472, 16640, 17152, 11264, 5632, 2560, 512, -1024, 2048, 8192, 11264, 9728, 6144, 4352, 2304, 1024, 768, 3072, 6656, 8192, 8192, 5888, 4096, 1792, 256, -1792, -3328, -2048, 256, -1280, -9984, -18432, -20224, -16384, -12544, -10240, -6144, -256, 3072, 0, -6400, -11264, -11008, -7680, -3584, 256, 3328, 3328, 1024, 1024, 4096, 8704, 11776, 14080, 16640, 18688, 17152, 13568, 13824, 14848, 15872, 15360, 13056, 9728, 8448, 5120, -1792, -6912, -10240, -11776, -14080, -14848, -10496, -2304, 1792, 2048, 512, -6656, -12544, -18176, -23552, -25856, -23808, -20480, -17920, -18176, -18688, -16640, -17152, -17664, -15616, -10752, -3840, 3840, 4608, -1280, -8448, -13824, -13824, -10240, -4608, 512, 5376, 5376, 768, -7168, -13312, -8448, 2304, 8960, 8448, 7680, 8704, 11520, 11776, 11008, 13824, 16128, 16640, 15616, 14336, 11008, 11520, 15104, 19712, 24576, 26624, 28672, 29440, 25600, 19968, 13568, 5632, -768, -1536, 1280, 6144, 9472, 9728, 8960, 6400, 768, -4864, -9728, -13056, -11776, -8448, -8704, -10752, -12032, -12288, -9728, -6912, -7680, -10240, -12288, -11520, -7680, -6144, -9728, -11264, -11008, -12032, -8704, -3328, 1792, 6912, 7680, 2304, -4608, -9728, -5632, 4864, 12032, 17920, 21248, 17408, 7168, -3328, -10496, -10496, -4864, -256, 2560, 2048, 1024, 1024, -1792, -3072, 1536, 8192, 10752, 7936, 0, -9984, -18176, -25344, -29440, -28416, -21760, -14336, -11776, -15616, -18944, -16896, -11520, -5632, 1024, 5376, 6912, 6400, 256, -7680, -13056, -9472, 1024, 9472, 10240, 6656, 4352, 3072, 3072, 1280, 256, 512, 3072, 7424, 11008, 11264, 11520, 13824, 11520, 7168, 2560, 3328, 6656, 8192, 11008, 15104, 17152, 15872, 15360, 16896, 18432, 15616, 8704, 2816, 0, 256, -1536, -4608, -3072, 4864, 12032, 13056, 8192, 2304, -2048, -5632, -6656, -6912, -7680, -7424, -3072, 1792, 4608, 3328, -256, -2816, -2816, 1280, 4096, 3584, 2816, 1280, -4864, -12032, -13824, -7424, 3328, 9472, 10752, 8448, 2304, -4352, -7936, -5376, 3584, 15616, 20736, 17408, 9984, 1024, -6656, -11776, -9728, -4352, -256, 256, -1024, -3584, -6400, -5888, -1024, 6144, 11008, 12544, 9472, 1024, -12288, -24832, -31488, -29696, -22784, -16896, -16640, -18688, -17152, -16384, -16896, -17664, -11776, 768, 9216, 6912, -768, -6400, -9984, -9728, -9984, -9216, -6144, -2304, 1280, 3328, 3328, 1024, -256, -3328, -3840, 0, 5632, 12032, 16640, 19456, 17152, 8960, 768, -1024, 1536, 6912, 12032, 14848, 17408, 18432, 18688, 18432, 16896, 15104, 15872, 15616, 12544, 7168, -1280, -7680, -6912, 2304, 10240, 13056, 11776, 10240, 7168, 256, -7680, -14336, -14592, -10496, -3328, 1280, 3072, 1792, -2816, -9728, -13824, -10240, -4096, 3072, 5888, 3328, -4096, -12544, -15872, -14080, -7424, 1024, 9728, 11520, 7168, -1280, -9216, -9216, -1280, 9984, 17408, 19712, 18688, 14080, 2048, -8960, -11776, -7424, -3840, -3840, -4096, -3072, -2304, -5888, -7680, -4608, 4096, 12288, 13056, 6144, -4608, -11520, -18432, -24576, -28416, -25856, -20480, -17152, -18176, -20224, -19712, -17920, -11776, -5632, -1792, -1024, -1280, -1024, -512, -3840, -9472, -11008, -10752, -6912, -1280, 2304, 6912, 9728, 6912, 1024, -3584, -3840, 1536, 7680, 15616, 23808, 23040, 13312, 4096, 512, 256, 1280, 2816, 8704, 16384, 20224, 18176, 12288, 8960, 11008, 15616, 15104, 11776, 6912, 256, -5632, -8448, -6400, -2304, 3840, 9472, 14336, 13824, 7168, -2560, -11264, -14848, -12544, -6912, -2048, 5120, 7424, 0, -10752, -16896, -15360, -8704, -1792, 4096, 7680, 3840, -5120, -12800, -16384, -12544, -2816, 5376, 8704, 8704, 4352, -1792, -7936, -7424, 768, 11008, 17664, 19968, 18688, 11520, 2560, -5120, -8192, -8448, -6656, -3072, -1536, -4608, -10496, -11264, -6912, -1536, 2560, 4352, 4864, 4608, -1024, -12544, -22272, -27648, -25600, -21504, -22272, -23808, -21248, -17152, -13824, -11520, -11520, -8960, -5888, -3328, 1536, 4352, 3584, 256, -5632, -10240, -8960, -4608, 512, 7168, 14592, 16128, 8448, -1792, -5376, -1024, 5888, 14592, 22784, 26112, 24064, 17408, 9472, 2048, -1024, 1024, 9472, 18176, 22528, 20224, 13824, 11776, 14080, 15872, 14080, 13568, 13824, 11776, 5120, -3584, -10240, -10496, -4096, 3840, 11264, 15360, 15104, 7680, -5376, -15616, -17920, -13824, -6656, 2560, 7424, 4864, -4096, -12544, -16128, -14848, -8448, 1024, 7424, 6656, -256, -8448, -12544, -12800, -8704, -2304, 4096, 8704, 8704, 2304, -5120, -6400, -2304, 3328, 7424, 13824, 22272, 23296, 14336, 2816, -3072, -2816, -3072, -5120, -5632, -4352, -2816, -3072, -5632, -6400, -3840, 768, 4864, 4864, 2304, -2816, -9728, -15872, -19456, -23552, -27392, -27904, -24320, -17408, -13568, -12544, -12544, -14848, -16128, -12288, -6400, -1280, 3072, 3072, -1792, -9216, -14336, -14336, -8192, 2048, 12800, 16384, 9216, 1536, -2560, -3840, -2816, 2304, 12032, 24064, 30208, 25600, 14848, 3584, -768, 768, 4864, 11264, 18432, 21248, 19968, 19200, 16896, 13568, 11520, 13312, 16896, 17920, 13312, 5632, -2048, -9216, -9216, -3584, 5376, 16128, 21504, 16128, 3584, -7424, -14080, -13824, -10752, -3072, 7168, 10240, 3584, -6144, -13312, -14848, -10752, -5632, 1536, 4864, 4096, -1280, -8704, -12544, -11008, -6144, -3072, 512, 3584, 5632, 2560, -2560, -5120, -4096, 768, 7168, 15360, 18432, 15616, 10752, 6400, 256, -6656, -11264, -11776, -7936, -6400, -6656, -8192, -7680, -6144, -3072, -3072, -3840, 0, 1536, -768, -5888, -12032, -20224, -28672, -32768, -29440, -21504, -15616, -11520, -10752, -13056, -16384, -17408, -15616, -8448, 2304, 7424, 3072, -7168, -13824, -16384, -14336, -7680, 2304, 9216, 10496, 8704, 2560, -4608, -9728, -7424, 3328, 17920, 26880, 27136, 20224, 12288, 7936, 3072, -256, 3072, 13056, 19968, 22784, 22272, 19200, 16896, 12544, 11264, 14336, 18688, 20224, 16896, 5888, -5888, -10752, -9984, -2304, 7936, 16640, 19200, 13312, 1792, -8192, -13824, -14592, -7680, 768, 6144, 4864, 512, -4608, -9984, -12800, -9984, -2560, 2048, 2560, -512, -3072, -4608, -5376, -7424, -8448, -4096, 2816, 7168, 4352, 256, -1024, 768, -768, -1536, 3328, 10752, 16384, 17152, 14336, 7424, 512, -5376, -9216, -10752, -10240, -6400, -3840, -2560, -1792, -2560, -6912, -9728, -6144, 512, 4864, 3584, -1536, -11264, -22016, -29440, -30976, -27904, -20736, -11520, -6912, -9216, -14848, -19456, -20736, -13568, -3328, 2816, 2048, -2816, -6144, -10240, -14848, -15872, -7680, 2816, 10752, 11264, 4352, -3840, -9216, -9728, -5632, 3840, 13568, 21504, 22528, 18688, 13312, 4864, -1536, -2304, 3328, 11264, 18176, 22528, 23808, 20224, 13824, 10752, 11776, 17152, 20992, 20224, 13824, 5120, -2560, -7168, -6912, 0, 11776, 17920, 15616, 7424, 512, -4608, -9728, -11520, -5888, 1792, 4096, 2560, -2048, -5632, -6656, -7680, -8192, -5888, -3328, -512, 1536, -1536, -3840, -4096, -4608, -5120, -2304, 0, 512, 2816, 4864, 4352, -512, -5376, -3072, 3584, 8448, 12800, 16640, 15616, 11008, 4864, -4352, -11264, -12800, -10752, -5376, 256, 2816, 256, -7936, -14336, -11520, -5632, -256, 4352, 4608, -1024, -11264, -24320, -32256, -31488, -24320, -14336, -9216, -10496, -13056, -15104, -17408, -15360, -9728, -3840, 1280, 3584, 1792, -4352, -12032, -15616, -9472, 256, 6912, 8448, 6144, 1792, -3328, -7680, -11008, -6656, 3328, 12032, 17920, 18944, 17408, 12288, 3072, -4864, -3584, 3584, 11776, 18944, 20736, 19200, 16384, 13312, 12288, 14336, 17152, 20992, 19968, 11264, 2304, -3072, -5120, -2048, 4608, 10496, 14592, 11776, 5888, 0, -5888, -8448, -5376, -2560, -2560, -512, 768, 1280, -512, -4864, -8448, -8192, -6144, -4096, -2816, -3584, -1536, 1792, -512, -5120, -6400, -4096, -1536, 1536, 4352, 6912, 5632, 512, -2560, -2816, 0, 6144, 13056, 17408, 20224, 16640, 6400, -4864, -12544, -12288, -7680, -2304, 2048, 2560, -3072, -10240, -14592, -14592, -8704, -256, 6400, 6144, -1792, -14336, -24320, -28416, -26112, -21504, -17664, -14592, -11264, -10752, -15104, -18944, -18176, -12032, -4352, 0, 768, -1536, -5376, -9472, -9728, -6912, -1536, 3840, 5888, 5632, 3072, -1024, -5888, -8192, -6656, 256, 9216, 16128, 20992, 19968, 11776, 3072, -256, 512, 5120, 10496, 16384, 20736, 20224, 16896, 15104, 15616, 17152, 19200, 19456, 16896, 12544, 6912, 1280, -1792, 512, 6144, 10496, 11264, 9728, 7168, 3328, -1280, -4864, -5376, -4352, -2816, -512, 1024, 1024, -512, -3584, -7168, -8192, -6912, -5376, -4096, -3328, -256, 1536, -1024, -5376, -6400, -4352, -1792, 1536, 0, 0, -1024, -1024, -1280, -2048, -1024, 768, 2048, 1536, 256, 256, 512, 768, 768, -512, -1792, -2816, -2560, -1280, -512, 1024, 1536, 0, -512, -1280, -1024, -1024, -2304, -2304, -1792, -2816, -2816, -2560, -1792, 1024, 0, -1024, -1024, -256, 1024, 0, -1024, -768, -1280, -1536, -1280, -1024, 1024, -256, 512, 2816, 1280, -3328, -5120, -7680, -12544, -12800, -8704, -5632, -8448, -6912, -5120, -4352, 0, 8704, 17920, 18688, 10752, 768, -6656, -9472, -6400, -256, 6400, 12288, 18176, 19200, 11264, 5632, 11520, 17664, 14592, 11264, 13312, 14848, 6144, -5888, -10496, -12800, -14848, -17152, -20992, -16896, -7424, -7424, -10496, -8704, -4864, -1024, -1024, -256, 5120, 12800, 14336, 8960, 3072, 1024, -2048, -3840, 1024, 7168, 11264, 11776, 8704, 4352, 512, 0, 2816, 7168, 10752, 5632, -7168, -13056, -11520, -8704, -9984, -9472, -4864, -4352, -7680, -8192, -4608, -1024, 2304, 4864, 9728, 8960, 768, -6144, -8960, -10240, -5888, -2816, -6400, -12032, -13312, -13056, -14848, -15616, -13312, -12032, -9472, -4352, -1280, -1280, -4096, -7936, -6144, -2816, -256, -768, -5888, -10240, -12288, -10240, -3072, 3840, 6400, 4352, -1280, -512, 3584, 5376, 3840, -3072, -6656, -4608, -512, 7168, 12288, 14080, 13312, 10752, 8960, 8960, 10752, 9728, 9216, 10240, 13568, 14080, 13312, 11264, 9216, 12544, 14592, 14336, 14592, 14080, 12800, 9984, 6912, 7936, 7680, 3840, 2816, 3072, 1536, 1024, 3584, 7168, 5888, 256, -1536, -4352, -8960, -11264, -10496, -8448, -5632, -2304, -1536, -3072, -3840, -3328, -6912, -7424, -1792, 3584, -1280, -14080, -18176, -12544, -8448, -9472, -11776, -8448, -4608, -11008, -22784, -24576, -16640, -5888, 512, 2048, 5120, 6144, -2816, -12800, -13056, -3072, 3840, 1024, 256, 5120, 12032, 13568, 11008, 13312, 19712, 25088, 29184, 28160, 25600, 22528, 13568, 2560, -7424, -14080, -18176, -21248, -19712, -14848, -14080, -14592, -13312, -12288, -12032, -11776, -3072, 8704, 15104, 13312, 6400, -2560, -8448, -5376, 4608, 12544, 13824, 11776, 4608, 3328, 7680, 10496, 12288, 13824, 13568, 11264, 6144, 256, -3328, -6400, -11008, -9728, -7168, -8960, -14080, -18176, -16384, -10240, -3328, 2560, 6144, 9728, 10496, 5376, -256, -2816, 256, 3840, 1792, -1536, -3328, -9984, -14592, -16384, -13056, -5120, -3072, -6144, -9472, -7680, -1024, 4352, 5376, 3072, -1792, -4096, -3840, -1792, 1536, 256, -5120, -8704, -7680, -256, 8192, 11264, 9216, 5632, 6400, 5376, 1536, 256, -512, -3328, -1280, 4864, 7168, 6144, 3072, 2816, 4096, 4864, 9728, 13824, 12544, 9728, 7168, 7168, 9984, 13312, 12544, 8192, 6400, 8448, 11520, 12544, 9984, 10240, 11776, 5120, -2304, -1536, 1536, 256, -5632, -7424, 2560, 12288, 8448, -4352, -13056, -14080, -11264, -12544, -12800, -9216, -8448, -14592, -21504, -18176, -5376, 2816, 3328, 1024, -256, -2048, -8192, -11520, -8192, -2560, 512, -3328, -9472, -9984, -10752, -14592, -16640, -16128, -9216, -2816, 2560, 8448, 5632, -3072, -8704, -7168, -3072, 512, 2048, 1536, -512, -1024, 0, 2560, 5632, 9216, 14592, 20992, 26624, 31232, 32512, 27904, 17920, 4352, -7168, -11520, -9216, -5120, -8448, -17408, -26112, -29184, -26368, -19456, -11520, -5120, -1792, -2816, -2560, -512, 1536, 0, -3584, -1280, 7680, 12288, 7424, 768, -2048, 2560, 9984, 17152, 22016, 21248, 15104, 8192, 4352, 8192, 11776, 10240, 2816, -7424, -12288, -14592, -17408, -17664, -14592, -11008, -6656, -3328, -512, 256, 256, 768, 1024, 2048, 5376, 5120, 2816, 768, -512, -1536, -6656, -9984, -8448, -8704, -9216, -7168, -5888, -6912, -7168, -4352, -256, 0, -1536, -2560, -2304, -1792, -3072, -6656, -11264, -13824, -9728, -4096, 0, 4608, 6912, 4352, -768, -4608, -768, 4864, 2816, -2304, -1792, 2560, 3584, 1280, 1280, 4608, 7424, 7424, 3072, 4096, 9728, 11008, 3584, 512, 6144, 14080, 15104, 8448, 4352, 6144, 11264, 16640, 19200, 19712, 14080, 3840, -4096, -5120, 1536, 7936, 6912, 4352, 4608, 4864, 4352, 1792, 0, -1280, -5120, -5632, -6400, -12544, -17664, -18688, -14848, -11520, -7424, -1024, 2304, -256, -5888, -13056, -13312, -6144, -512, 2816, 3072, -4096, -13056, -19200, -19712, -17152, -15104, -15104, -13824, -8960, -3840, -2304, -2304, -2304, -1792, -2048, -3072, -256, 3840, 5632, 2560, -3584, -8704, -7168, -3584, 2816, 16384, 28928, 32512, 29952, 24832, 22272, 21504, 17408, 12800, 9472, 9216, 6144, -3840, -14848, -19968, -21504, -18176, -10240, -3584, -3072, -8704, -12288, -10496, -3584, 5120, 9472, 8960, 4096, -1536, 256, 3584, 3840, 5120, 5888, 6144, 9728, 14848, 17664, 14592, 10240, 13824, 18688, 19200, 16640, 10240, -768, -12544, -17408, -14336, -10752, -10752, -13568, -15104, -11264, -5888, -2304, -768, -2816, -4608, -3328, -2816, -1280, 768, 3328, 1024, -6400, -9984, -5632, -3584, -4096, -6912, -9728, -9472, -10752, -14080, -13056, -5376, 2048, 2560, -2048, -3072, -1024, -2560, -9984, -14080, -9728, -3328, -1024, -2816, -3840, -768, 3840, 3072, 512, 2816, 7168, 8704, 3840, -1280, 768, 2816, 1536, 3072, 6400, 6400, 3328, 2560, 3840, 6912, 12288, 14080, 9728, 5888, 4352, 5888, 8192, 5888, 8192, 14592, 19200, 19200, 13312, 5632, 2560, 1280, 3072, 7168, 8448, 5888, 512, -3584, -1024, 4864, 7680, 6400, 3840, 256, -6912, -16384, -19968, -17152, -12544, -11520, -12288, -10752, -7936, -6400, -10240, -12800, -9984, -4608, -1024, 3328, 4864, 3072, -2560, -11008, -15104, -13568, -12032, -13824, -15616, -13056, -5120, -512, -3072, -5888, -6400, -4608, 1280, 8448, 13056, 11520, 4096, -4096, -11776, -13568, -9728, -1536, 8448, 14592, 18944, 20736, 19200, 19712, 22784, 26880, 29184, 28160, 21248, 9984, -1536, -6400, -7168, -9984, -12288, -13312, -14080, -15104, -17152, -17152, -14592, -10752, -5888, -768, 2560, 768, -4864, -8448, -7680, -2048, 5120, 5888, 512, -4608, -4352, 3072, 10240, 14848, 16640, 16640, 16896, 18176, 16384, 13824, 9728, 256, -10496, -15872, -12032, -6656, -7936, -12544, -14080, -10752, -5376, -4352, -4864, -2560, -512, -768, -2560, -3328, 512, 3328, -2560, -9728, -6912, 768, 2048, -4608, -11776, -15616, -16640, -13568, -9216, -4608, -1280, -1536, -3584, -5632, -4608, -3072, -4864, -7424, -7168, -5376, -2560, -3840, -6144, -4608, -1024, 4096, 5888, 4352, 3584, 2560, 2304, 3328, 3840, 7168, 8960, 4864, 1024, 512, -512, 2304, 8704, 15872, 16896, 11008, 3328, -512, 3840, 10752, 12800, 12288, 13056, 14336, 14336, 11520, 11264, 11520, 12288, 10240, 8448, 7936, 6912, 2560, -2560, -1024, 4096, 10496, 13312, 12288, 7936, -256, -9216, -14336, -12800, -6912, -3584, -6400, -11008, -15360, -17152, -12032, -7936, -9728, -12032, -10240, -4352, 3328, 8192, 7168, -2560, -12800, -17408, -15872, -10240, -5376, -5120, -8448, -14848, -18432, -16128, -11520, -7168, -2816, 4608, 12288, 10752, 3840, -3584, -11008, -13824, -10240, -3840, 1024, 512, -1280, 0, 5120, 14080, 23296, 28928, 30720, 27904, 22784, 19712, 16128, 11008, 6656, 5120, 3072, -3328, -12032, -17664, -17408, -13568, -12544, -12544, -9216, -7168, -6912, -6912, -7168, -3072, 1280, 256, -2304, -512, 3584, 2560, -6400, -9984, -1536, 5376, 8960, 10496, 13568, 18688, 20992, 18944, 16384, 13824, 9984, 2304, -5888, -9472, -7680, -5632, -7680, -13312, -15872, -13824, -8192, -2304, 512, 1280, -768, -4352, -6400, -4352, -256, 3328, 2048, -1792, -3072, -1792, -1792, -5376, -10240, -13056, -13056, -9728, -5376, -4096, -5632, -7424, -8448, -5888, -2560, -512, -2304, -6144, -8448, -8448, -7424, -5376, -2048, 768, 512, -2560, -4608, -2816, 2048, 6656, 8192, 6912, 5376, 3584, 1792, 256, 768, 3072, 5632, 8960, 11520, 11008, 7424, 3328, 2560, 5120, 9472, 13824, 15104, 11520, 7168, 7168, 9472, 12288, 14080, 15360, 15360, 11008, 4352, 0, -768, 2304, 6144, 7936, 7936, 7168, 7168, 6656, 3584, -1280, -5632, -7936, -7680, -5376, -1792, -2048, -8704, -16128, -20992, -20480, -16128, -11520, -7168, -3584, -1280, 768, 512, -2816, -6912, -9984, -8448, -2816, 512, -2048, -9984, -18688, -24320, -23296, -13824, -2048, 4864, 4096, 1024, 1280, 3584, 3584, 512, -2048, -3584, -4864, -8448, -11520, -9728, -4864, 512, 5376, 13824, 23808, 27136, 23040, 18944, 20480, 24832, 25088, 19456, 13312, 8704, 2560, -4608, -9472, -9216, -6912, -8960, -13312, -15872, -14336, -11264, -9984, -9472, -7424, -4352, -2048, -512, 768, 1024, -1024, -4096, -6912, -8192, -4864, 256, 4864, 10496, 15360, 17920, 18176, 17152, 16384, 15616, 13568, 9728, 3584, -2048, -5376, -7424, -8704, -9728, -9984, -7424, -3840, 0, 1280, -1280, -4864, -6400, -4096, 1280, 4864, 4352, 1536, -768, -1792, 0, -256, 256, -512, -1280, 0, 0, 512, 0, -768, -512, 0, 256, 0, -512, -512, -512, 0, 768, 768, -512, -1280, -256, -256, -256, -1024, 768, 2304, 256, -256, -512, -2816, -1792, 256, 2304, 2816, 2048, -1024, -2816, -3072, -2304, -1024, 4608, 3840, 3584, 256, -5632, -7424, -3584, 768, 7680, 7424, 3584, -512, -8960, -11008, -2816, 3328, 9216, 10752, 3840, -4096, -12544, -11264, -2560, 7168, 12032, 9728, 2816, -6400, -16896, -9984, 1024, 9216, 14848, 8448, -768, -11264, -16640, -7424, 4864, 13312, 13824, 5888, -3328, -15104, -16640, -3840, 8192, 17664, 12544, 2048, -7680, -18944, -13056, 768, 11008, 18176, 10240, -1280, -12288, -19712, -7936, 4096, 14592, 17152, 6144, -3840, -17152, -18432, -3072, 9216, 16896, 15104, 1280, -7936, -20480, -13056, 768, 12544, 19200, 9472, -512, -15104, -20736, -7168, 5120, 17152, 16896, 5632, -5888, -19456, -16640, -2560, 10496, 19968, 12288, 1024, -9216, -21760, -12032, 1536, 15104, 20480, 7936, -2048, -17664, -20992, -5632, 7424, 18688, 16128, 4352, -7936, -20736, -16128, -256, 12032, 20224, 12032, 768, -14336, -23040, -10240, 4864, 19200, 18688, 7168, -6400, -22016, -18944, -2560, 12288, 21760, 14336, 1536, -13056, -23808, -12288, 2816, 17152, 22016, 8448, -2816, -19968, -22272, -7424, 9216, 22784, 16896, 3328, -9728, -23296, -15360, 512, 12800, 21248, 12288, 0, -14336, -23040, -10496, 4096, 18176, 19968, 7680, -4352, -20480, -19200, -5120, 7936, 20992, 15872, 3840, -8192, -21760, -16896, -1792, 12288, 21504, 12800, 1024, -13568, -22272, -11264, 2048, 15872, 19968, 8960, -2048, -16640, -21248, -7680, 5888, 17920, 18176, 6144, -5120, -19456, -19200, -3072, 8192, 18688, 15872, 3840, -7680, -21760, -15872, -512, 10496, 19456, 13056, 2304, -9984, -22016, -13312, 256, 11520, 20224, 11776, 2048, -12544, -22784, -11776, 768, 13824, 20480, 11008, 1792, -14080, -21248, -12800, 0, 13568, 19456, 13824, 2816, -13312, -21248, -14080, 0, 10240, 17152, 14848, 5632, -8192, -20224, -17152, -2816, 7168, 16128, 13312, 9472, -2304, -17920, -16128, -7168, 2560, 10752, 12544, 13568, 2048, -11776, -16384, -10496, 256, 5632, 9728, 13056, 9984, -4096, -16128, -11776, -5888, 1280, 8448, 9728, 12288, 3584, -10752, -14592, -7424, -1280, 5632, 9472, 10240, 7168, -5888, -13568, -9984, -2560, 3584, 7680, 10240, 7936, -256, -12288, -10240, -4608, 2816, 4864, 7936, 6656, 3584, -5120, -12800, -6400, -1280, 2816, 7936, 7680, 3584, 0, -8960, -9984, -1024, -256, 4864, 6912, 4352, 2304, -2560, -9984, -5376, -2048, 2304, 6144, 6656, 3328, -1280, -4864, -7680, -3072, -256, 4352, 6400, 4096, 768, -4864, -6656, -3328, -1536, 4352, 5632, 5120, 1280, -4096, -8192, -4864, -256, 5888, 6912, 5888, 1024, -7680, -8448, -5888, -256, 8960, 8960, 6144, -512, -10496, -11520, -5376, 2304, 11520, 10496, 5632, -3072, -12800, -11776, -4608, 7168, 14080, 11520, 2560, -6912, -19968, -10752, 0, 13568, 16896, 8192, -256, -15616, -18944, -7168, 6912, 16384, 16384, 6144, -7168, -20480, -16896, -3840, 13568, 21504, 12288, 1280, -15104, -24064, -10496, 4352, 19200, 20480, 6656, -5376, -23296, -20224, -3072, 12288, 22272, 14080, 2560, -14848, -24576, -11776, 2304, 20480, 20736, 7680, -5888, -21504, -20480, -3840, 12544, 23040, 12544, 2304, -14592, -24320, -11520, 4352, 19456, 20224, 6656, -5120, -23296, -19200, -4608, 13312, 23040, 13312, 1536, -15104, -23552, -10496, 3840, 17408, 20480, 7936, -5376, -22272, -19456, -3328, 11520, 22272, 12544, 2816, -15360, -24064, -8960, 3584, 20480, 17408, 5632, -5888, -22784, -16896, -1792, 12032, 23808, 11264, -2048, -15616, -24320, -7936, 6144, 22016, 19200, 2560, -8960, -24576, -16896, -256, 15616, 25600, 11264, -3072, -19712, -26880, -8448, 8192, 24832, 23552, 4096, -11264, -28416, -23040, -1280, 16640, 30976, 16640, -768, -20480, -31488, -15104, 4352, 25088, 28416, 11776, -6400, -28672, -27904, -8448, 10752, 28672, 23040, 7680, -14080, -29440, -21504, -4352, 16896, 26880, 18176, 3328, -18688, -28928, -15616, 0, 19712, 24576, 14336, 1024, -20480, -27648, -12800, 2048, 19968, 23808, 12032, 768, -22528, -25088, -10240, 1792, 16640, 19456, 13568, 4608, -18176, -23040, -11264, 0, 9984, 14592, 11008, 8704, -4864, -17664, -13824, -4864, 4608, 8192, 7936, 8704, 1792, -10240, -9216, -5376, -256, 3072, 3072, 6400, 6912, -2304, -8192, -3584, -3584, 512, 0, 256, 5120, 4864, -512, -3328, -2816, -4608, -3072, -512, 4608, 6144, 3072, -512, -3584, -4864, -4864, -3072, 4608, 6144, 5632, -512, -3840, -8192, -5120, 768, 5632, 6656, 4352, -3328, -7936, -6912, -3328, 4352, 8448, 8192, 1280, -7424, -12032, -7424, 512, 8448, 10752, 8192, -1536, -13568, -13312, -6144, 5632, 13056, 10496, 6912, -8192, -18944, -11520, 0, 11520, 15104, 8448, -256, -15872, -16896, -7936, 6656, 18688, 12544, 4352, -10752, -20480, -10752, -2048, 16128, 18432, 7168, -2560, -19200, -18432, -5888, 8192, 22528, 12032, 3328, -14336, -23808, -9728, 2560, 19456, 17664, 6656, -5120, -24576, -16896, -2560, 12288, 23040, 12032, 0, -17664, -26368, -7424, 6400, 22272, 18688, 4608, -8960, -26624, -17408, -512, 15616, 23808, 12032, -1280, -21248, -25088, -7936, 7680, 23552, 17408, 4352, -9984, -24832, -16128, -1280, 16384, 22528, 8960, -2304, -18944, -22016, -5632, 7936, 21760, 13824, 3328, -11264, -23808, -11776, 2304, 16640, 19200, 5888, -4352, -19200, -19968, -3840, 9984, 21504, 13824, 768, -13312, -24576, -11776, 3072, 18176, 23040, 7424, -4608, -22784, -22272, -6656, 9216, 22016, 18432, 6656, -9472, -27136, -19712, -3072, 11520, 25344, 17408, 5632, -11776, -27648, -18688, -2560, 11008, 22272, 17664, 4864, -6912, -23552, -20224, -3072, 6912, 16128, 14592, 6656, 1024, -13568, -19200, -8960, 3072, 8448, 9472, 7936, 6656, -2304, -13568, -9984, -4096, 1536, 5120, 5888, 5632, 3328, -2048, -5632, -5888, -4608, -768, 2304, 6400, 4864, 1024, -2048, -5120, -4352, -2560, 1536, 4096, 4352, 3328, -2048, -8704, -5376, -1536, 4352, 8448, 5888, 1536, -8192, -13056, -5888, 2816, 9216, 11776, 7936, -2816, -11776, -16640, -7936, 3840, 15104, 14080, 7168, -5120, -18688, -16384, -6656, 10752, 19968, 13056, 3584, -13568, -21760, -12288, -1024, 17920, 20480, 9728, -4096, -20480, -19456, -8192, 9984, 23040, 14848, 4864, -15104, -25344, -12800, 3584, 18176, 19200, 9216, -5376, -24064, -17920, -5888, 13056, 22528, 13568, 2304, -17408, -24832, -10240, 4096, 21248, 18688, 7424, -8448, -25600, -15616, -3328, 14848, 22272, 10496, 0, -18944, -20736, -8960, 6144, 22272, 14080, 5120, -10496, -22528, -14848, 0, 17664, 18688, 8704, -1280, -22016, -19200, -5120, 9728, 20224, 12544, 3328, -12288, -23040, -9984, 512, 18176, 17408, 7936, -4096, -21504, -17152, -3840, 9728, 20224, 10752, 3072, -12800, -21760, -9472, 512, 15872, 18176, 8704, -1280, -21248, -19200, -6144, 6912, 20992, 13056, 6912, -7680, -22528, -13824, -3840, 11264, 18688, 12800, 4096, -12544, -20736, -12032, -1536, 9728, 14848, 12800, 6912, -7936, -17664, -13312, -3328, 3840, 9216, 11520, 8448, -1280, -10496, -11264, -5888, 512, 3584, 6912, 8448, 2560, -6400, -5120, -4608, -1536, 256, -256, 4352, 5632, 768, -3328, -2560, -4352, -3328, -1536, 3328, 6144, 3840, 256, -2816, -4864, -4864, -4096, 3072, 6144, 6144, 768, -3072, -7424, -6656, -256, 4608, 6912, 4864, -1024, -7936, -7168, -4864, 2816, 7680, 8960, 3072, -5376, -11776, -8960, -1536, 7168, 10752, 9216, 1280, -11776, -14592, -7936, 2560, 12800, 11008, 8448, -4096, -18176, -14080, -2304, 8960, 15872, 9728, 2560, -13056, -18176, -10240, 2816, 17664, 14848, 6144, -6656, -20736, -12800, -4608, 12288, 20224, 9472, 256, -15872, -20736, -8192, 4096, 21504, 15104, 5120, -9472, -24576, -12800, -512, 16128, 19968, 8448, -1024, -21760, -20480, -5120, 8448, 22528, 15104, 2560, -12800, -27392, -12032, 3584, 19200, 21760, 6912, -4864, -24320, -21248, -3840, 12032, 24064, 15360, 2048, -16896, -26880, -11776, 3840, 21248, 20736, 6656, -5888, -23296, -19456, -4608, 12288, 23552, 12032, 256, -15104, -24064, -9216, 4608, 19968, 16896, 4864, -6912, -23296, -15360, -768, 13568, 20480, 8960, -2048, -15872, -22016, -7168, 6912, 20224, 16896, 3328, -9728, -24064, -15872, 256, 14336, 24320, 10752, -1536, -19200, -24576, -9984, 5632, 20480, 20480, 9216, -5120, -24832, -23552, -6144, 7680, 23808, 20224, 8192, -6912, -26112, -22272, -5632, 7936, 20736, 20224, 7424, -3584, -20736, -23296, -6400, 4864, 14336, 16128, 7936, 2816, -9984, -19712, -12032, 768, 7936, 9472, 8448, 6912, 768, -12288, -11776, -5120, 0, 4608, 5632, 5888, 4096, -768, -5120, -4864, -3840, -1024, 512, 2048, 1280, 0, 0, 0, 0, 512, 512, 1280, 2304, 3072, 3584, 3072, 1792, 1536, 1024, 0, -256, -256, 256, -512, -512, -2816, -4352, -8192, -10496, -12544, -14080, -14848, -15616, -15616, -16640, -15616, -14592, -12032, -9472, -6912, -5632, -3840, -1280, 1536, 3072, 4096, 5376, 6912, 7168, 8192, 8448, 8960, 10496, 11264, 11520, 12032, 12800, 13824, 14592, 14336, 13568, 13568, 13824, 12800, 12800, 13312, 13824, 14336, 13312, 13568, 13824, 12800, 12544, 11776, 11008, 9728, 8448, 6912, 4864, 2048, 512, -2816, -5120, -6912, -7424, -7680, -8192, -8960, -10752, -13312, -14592, -14592, -15104, -12288, -10240, -6912, -3328, 1024, 3328, 5120, 4608, 3584, 2816, 1792, 768, -256, -768, -2560, -2816, -5120, -7168, -11776, -15360, -18432, -20992, -23552, -24832, -24832, -24832, -24064, -23040, -20736, -18176, -15616, -14080, -14080, -13568, -12032, -9728, -7424, -5888, -2816, -1536, -768, 256, 512, 1280, 1536, 768, 768, 1280, 3840, 6144, 7168, 7680, 7680, 8960, 9472, 9216, 9984, 9984, 11264, 12032, 12288, 14336, 15872, 18688, 21504, 23296, 24576, 24320, 23296, 21760, 19456, 18432, 16128, 14080, 12032, 11264, 11008, 10496, 9728, 7936, 4864, 1792, 0, -2304, -1792, -1024, 2048, 5632, 10240, 13824, 17152, 18176, 17920, 16384, 14336, 11520, 8192, 6144, 3840, 3072, 768, -768, -5376, -10752, -16896, -21504, -26112, -29952, -31744, -32768, -32512, -31744, -30208, -27392, -24576, -22016, -22016, -22528, -22016, -20480, -17920, -16128, -12800, -10240, -8448, -6400, -5888, -5120, -4608, -4608, -5376, -6400, -5632, -3584, -2048, -768, -768, -256, 256, 0, 256, -768, -256, 512, 1024, 3328, 6144, 8960, 12544, 15104, 17152, 17920, 17664, 17408, 15104, 13824, 11776, 10240, 7936, 7424, 6912, 6400, 5888, 5120, 3072, -256, -2304, -4864, -5632, -5376, -2816, 768, 5888, 10496, 15360, 18176, 19456, 18688, 18176, 16640, 14336, 12800, 11264, 10752, 8960, 8448, 6144, 2304, -3328, -7936, -12288, -16640, -19456, -21248, -21248, -20992, -19712, -17664, -15104, -11776, -10240, -10240, -10496, -9728, -7680, -6144, -3328, -512, 2048, 4352, 5632, 6144, 6400, 5888, 5120, 3328, 2304, 2816, 3840, 4864, 4096, 3072, 2304, 1024, 256, -1536, -2560, -2816, -3584, -3072, -1280, 768, 3840, 6656, 8960, 10240, 10496, 10496, 8960, 7168, 4864, 3072, 768, -512, -1536, -1792, -2560, -3328, -4864, -7936, -9984, -12800, -14336, -14848, -13312, -10496, -5632, -768, 4608, 8704, 11776, 12288, 12032, 11520, 9728, 8192, 6656, 6144, 5120, 4864, 3840, 1280, -3584, -8192, -12544, -16640, -20224, -22528, -23296, -23296, -22528, -20992, -19200, -16128, -13312, -12032, -11776, -11776, -9728, -7936, -5376, -2048, 1024, 4352, 6656, 7936, 9216, 9984, 10752, 10240, 8960, 9216, 9984, 12032, 12288, 11520, 11008, 9728, 9216, 7680, 6144, 5632, 4864, 4608, 5888, 7424, 10240, 12800, 15616, 17408, 18432, 18944, 18176, 16896, 14592, 12800, 10240, 8192, 6144, 5376, 4096, 3072, 1792, -768, -3584, -6656, -9728, -11520, -11776, -11008, -7936, -4096, 768, 4608, 8448, 9984, 9984, 9216, 7936, 5632, 3328, 2048, 768, -256, -1024, -2304, -6144, -10752, -15360, -19712, -24064, -27392, -29440, -30464, -30720, -29696, -28672, -26368, -23296, -20736, -19968, -20480, -19200, -17664, -15616, -13056, -9984, -6400, -3328, -1280, 512, 2048, 3584, 4352, 4096, 3840, 4096, 6144, 7936, 8192, 8192, 7424, 7424, 6912, 5632, 5376, 5120, 4864, 5632, 6656, 8960, 11776, 15104, 17920, 19712, 21248, 21760, 21504, 20224, 18944, 16896, 15104, 12800, 11776, 10496, 9728, 8960, 7424, 5376, 2816, 0, -2304, -3584, -4096, -2816, 0, 4096, 7680, 12288, 14848, 15872, 15616, 14848, 13056, 10240, 7936, 6400, 4864, 3840, 3328, 1024, -2816, -7168, -11264, -15616, -19456, -22272, -24320, -25600, -25600, -25344, -24320, -22016, -19200, -17408, -17664, -17408, -17152, -15872, -14336, -12544, -9728, -6912, -4864, -3328, -2304, -768, 512, 256, -256, -768, 0, 1792, 2560, 2560, 1536, 1280, 1024, 0, -1024, -1280, -1792, -1792, -1792, -512, 1280, 4096, 6912, 9216, 11264, 12544, 13312, 12800, 11776, 10240, 8960, 6656, 5632, 4608, 3840, 3840, 3328, 2304, 1024, -1280, -3584, -4864, -5888, -5376, -3584, 0, 3840, 8448, 12544, 15360, 16128, 16128, 15616, 13568, 11264, 9728, 8192, 6912, 6912, 5888, 3584, 0, -3584, -7424, -11264, -14848, -17152, -18944, -19456, -19456, -18688, -17152, -14080, -11520, -10496, -10496, -10496, -9984, -8960, -7680, -5888, -3072, -768, 1024, 2304, 3584, 5120, 5376, 5120, 4352, 3840, 4864, 6144, 6656, 6144, 5376, 5120, 4608, 3072, 2304, 1536, 768, 0, 256, 1024, 2816, 5376, 7680, 9728, 11008, 12032, 12288, 11520, 9728, 8192, 5888, 3840, 2304, 1280, 768, 256, -512, -1280, -3328, -5632, -7680, -9472, -10496, -10240, -7680, -4608, -768, 3840, 7680, 9728, 10496, 10496, 9472, 6912, 4864, 3072, 1536, 768, 512, -512, -3328, -6400, -9984, -13568, -17152, -19968, -22528, -23552, -23552, -23296, -22016, -19712, -16128, -13824, -12800, -12288, -12032, -11008, -9728, -8192, -5888, -2816, -256, 1536, 2816, 4864, 6400, 6912, 6656, 6144, 6656, 7936, 9216, 9728, 9216, 9472, 9472, 8704, 8192, 7424, 6912, 6144, 5632, 5888, 6912, 8960, 11520, 13568, 15616, 17152, 17920, 18176, 16896, 15360, 13056, 10752, 8704, 7168, 6144, 5376, 4608, 4096, 2816, 512, -2048, -4096, -6144, -7168, -6400, -4352, -1280, 2560, 6656, 9984, 11520, 12032, 11520, 9472, 6912, 4608, 2304, 768, 0, -512, -2560, -5632, -9216, -13056, -17152, -20736, -23808, -26112, -27392, -27648, -27392, -26112, -23040, -19968, -18176, -17152, -16896, -16128, -15104, -14336, -12544, -9984, -7168, -4864, -3328, -1536, 256, 1792, 2048, 1536, 1280, 2048, 3584, 4864, 4864, 4864, 5120, 5120, 4864, 4096, 3840, 3328, 3072, 2816, 3328, 5120, 7680, 9984, 12544, 14592, 16128, 17408, 17408, 16640, 14848, 13056, 11008, 9472, 8192, 7424, 6912, 6656, 6144, 4864, 2816, 512, -1280, -3072, -3584, -2304, 0, 3328, 7680, 11776, 14336, 15872, 16640, 15616, 13568, 11264, 8960, 6656, 5632, 5120, 3840, 1536, -1536, -5120, -9216, -13056, -16896, -19968, -22272, -23296, -23552, -23552, -21760, -18944, -16640, -14848, -14336, -14080, -13312, -12800, -11776, -10240, -7680, -5120, -3584, -2048, -512, 1280, 1792, 1536, 768, 512, 1280, 2560, 2816, 2560, 2304, 2304, 2048, 1280, 512, 0, -512, -1280, -1280, -768, 1280, 3584, 5888, 8192, 9984, 11776, 12800, 12544, 11520, 9728, 7936, 6144, 4352, 3584, 2816, 2560, 2304, 1792, 512, -1280, -3072, -5120, -6400, -6400, -4864, -2048, 1792, 6144, 10240, 12800, 14848, 15360, 14336, 12544, 10496, 7936, 6144, 5632, 5120, 3840, 1536, -1280, -4864, -8704, -12288, -15616, -18432, -20224, -21248, -21760, -20736, -18432, -15872, -13312, -12032, -11264, -10496, -9984, -8960, -7936, -6144, -3328, -1280, 256, 1792, 3584, 5120, 5632, 5376, 4864, 4608, 5632, 6400, 6400, 6144, 5888, 5888, 5120, 4352, 3840, 3072, 2560, 1792, 1280, 2304, 4096, 6144, 8448, 10240, 12032, 13568, 14336, 13824, 12288, 10496, 8448, 6400, 5120, 3840, 2816, 2304, 2048, 1280, -512, -2560, -4864, -6912, -8192, -7936, -6400, -3840, 0, 4352, 7680, 10240, 11776, 11776, 10752, 8960, 6400, 3840, 2560, 2304, 1280, -512, -2816, -5888, -9472, -13312, -16640, -20224, -22784, -24320, -25344, -25600, -24320, -21760, -18944, -16640, -15360, -14080, -13312, -12288, -11264, -10240, -7424, -4608, -2560, -1024, 1024, 3072, 4608, 5120, 4864, 4352, 5120, 6144, 6912, 6912, 6656, 6656, 6400, 5888, 5376, 4864, 4352, 3840, 3072, 3328, 4352, 6400, 8704, 10496, 12544, 14592, 15872, 16640, 16128, 14592, 13056, 10752, 8960, 7680, 6400, 5632, 5376, 4864, 3840, 2048, 0, -2304, -4352, -5376, -5120, -3584, -768, 3328, 6656, 9728, 12288, 13568, 13312, 12032, 9984, 7168, 4864, 3840, 3328, 2048, 0, -2560, -5632, -9472, -13056, -16640, -20224, -22528, -24320, -25600, -25344, -24064, -21504, -18944, -17152, -15616, -14848, -14080, -13056, -12544, -11008, -8448, -5888, -4352, -2560, -512, 1536, 2560, 2816, 2304, 2304, 3072, 3840, 4352, 4096, 4096, 4096, 3584, 3072, 2816, 2304, 2048, 1280, 768, 1024, 2560, 4608, 6656, 8704, 10752, 12800, 14592, 15104, 14592, 13312, 11520, 9728, 8192, 6912, 5888, 5376, 5120, 4864, 3584, 2048, 256, -2304, 512, 1280, 1792, 2048, -256, 1536, 3840, 256, 5120, 7168, 256, 9472, 10496, 7936, 7424, 6912, 15616, 10240, -3072, 9728, 13312, -4096, -5120, -256, -5888, -12288, -14336, -16128, -15616, -19712, -25600, -22528, -19456, -26368, -28928, -25088, -26368, -30208, -30720, -27648, -27392, -26624, -28160, -30208, -26624, -27904, -32768, -27392, -21248, -27136, -22016, -24064, -25600, -19712, -28928, -22528, -11008, -19712, -11776, -11264, -17664, -8704, -13824, -9984, 1024, -7680, 2816, 4608, -6400, 5120, 4096, 2560, 13312, 8960, 13312, 18944, 8448, 14080, 18944, 15104, 17920, 20736, 21760, 23296, 20736, 18432, 22784, 24064, 20992, 20480, 25344, 25600, 21760, 22016, 23296, 25600, 23296, 20736, 23296, 26112, 21248, 18944, 23552, 24320, 16128, 15872, 19200, 18176, 16128, 9984, 13824, 18944, 3840, 256, 7936, 1536, -1280, -3328, -5120, -2048, -11264, -15104, -9728, -17664, -18688, -17152, -22016, -23040, -17408, -18688, -19712, -12544, -20992, -17920, -11008, -19456, -6912, 0, -7424, 5632, 6400, -1280, 11264, 11520, 7424, 16896, 18176, 12544, 21504, 23552, 18688, 23552, 18944, 18432, 23296, 9472, 12288, 25344, 12032, 7936, 11264, 9216, 8448, -1280, -2816, 6656, 1536, -8448, -5632, -1536, -8192, -14080, -11264, -11520, -13312, -16128, -18688, -14080, -13056, -19712, -20224, -15616, -18688, -23296, -21248, -17920, -19712, -18944, -20992, -21760, -17408, -22528, -25088, -14592, -17152, -19712, -14848, -19200, -16896, -16384, -19968, -8448, -9472, -12800, -4864, -12032, -9728, -5888, -10496, 768, 1536, -1792, 7680, 0, -1024, 6144, 3840, 7936, 11520, 11264, 16896, 11264, 8704, 14848, 13824, 15104, 17152, 18176, 22272, 19968, 15360, 18688, 21504, 19968, 19456, 22016, 24320, 22784, 19456, 21760, 24064, 22784, 18688, 20992, 25344, 21760, 16896, 19200, 23808, 19200, 12800, 14336, 17664, 15104, 7936, 7936, 15616, 7424, -3840, 3840, 1280, -3840, -3584, -9216, -6400, -7424, -17664, -14080, -13568, -20992, -19968, -19456, -24320, -22528, -17664, -20480, -16640, -16128, -22016, -14848, -17152, -15104, -3072, -7168, -2304, 7424, -2048, 3328, 11264, 5632, 11264, 17408, 13568, 15872, 23296, 18944, 20736, 22784, 16384, 21504, 19968, 8960, 19968, 22016, 11264, 11008, 12032, 11520, 5632, -1280, 4352, 5376, -4096, -6144, -3584, -3584, -8704, -12800, -10240, -9216, -16128, -18176, -14848, -15360, -17664, -19968, -19968, -17152, -20736, -25088, -19968, -18176, -22784, -21760, -21504, -22016, -20992, -25344, -20992, -15360, -19456, -19200, -18944, -19456, -18176, -22016, -17408, -9472, -13056, -8704, -10496, -14592, -9472, -13056, -7936, -1792, -4352, -768, 256, 1792, 5632, 7936, 11776, 14592, 10496, 11008, 14336, 16128, 15872, 17408, 21760, 22016, 20480, 21504, 23552, 24576, 23808, 23808, 26624, 26880, 24576, 25344, 27648, 27136, 26112, 25088, 26112, 28416, 25344, 22272, 27136, 28160, 21760, 20480, 22528, 22784, 20224, 17408, 17920, 20736, 12288, 6400, 9984, 8192, 4608, 2304, 3072, 0, -7424, -7936, -9728, -15360, -13312, -16128, -20224, -18176, -16896, -15872, -15104, -15872, -18944, -18432, -18688, -20736, -11008, -5376, -7168, 2048, 2560, -2560, 4096, 7168, 6912, 10752, 12800, 12032, 16896, 19456, 17408, 20736, 18688, 17152, 18432, 9984, 10240, 17152, 10496, 5888, 6400, 5632, 3072, -4096, -5632, -1280, -6912, -13056, -11264, -11520, -14592, -17408, -18688, -18176, -18944, -23296, -22784, -21504, -23040, -24832, -25088, -25088, -26112, -26880, -27648, -26368, -24832, -26880, -27904, -25856, -27392, -28928, -27136, -23552, -22272, -23040, -23552, -23552, -23552, -25600, -23552, -14592, -14336, -13824, -10240, -15104, -14848, -13824, -15616, -5888, -2304, -3072, 4096, 0, -3584, 1024, 1280, 4352, 8192, 10496, 14592, 14080, 11008, 13824, 16896, 17152, 17408, 21504, 22784, 22272, 22272, 23296, 25088, 25600, 24576, 26624, 27904, 26880, 26368, 27648, 28416, 27904, 26880, 26880, 28928, 28416, 25344, 26112, 29440, 26624, 22528, 23040, 24832, 23808, 20480, 19200, 22016, 19200, 9472, 10240, 11008, 8448, 5120, 5120, -3584, -6656, -9216, -13568, -13312, -16640, -19200, -19200, -17664, -17664, -17664, -18944, -19712, -19456, -18944, -15104, -8704, -6656, -2304, 2304, 1280, 3328, 8192, 9984, 10752, 13568, 14848, 15616, 18688, 19712, 19712, 18688, 15616, 14592, 11776, 7424, 9472, 9472, 4352, 1536, 512, -2560, -6912, -9728, -10496, -11776, -14848, -17408, -17664, -19200, -21760, -22784, -23552, -24832, -25856, -26368, -27136, -27392, -27648, -28672, -28416, -28672, -29440, -29440, -29440, -28928, -28416, -29696, -29440, -28672, -29696, -29952, -28160, -25856, -25088, -25856, -25856, -25088, -25856, -25856, -22016, -17664, -16640, -15104, -14592, -15872, -14848, -13824, -9984, -4864, -3072, 256, 1792, -256, 1280, 4096, 6144, 9216, 11776, 14848, 16384, 15616, 16384, 18944, 20224, 20736, 23040, 24576, 24832, 25600, 25600, 26624, 27648, 27392, 28416, 29184, 28928, 29440, 29440, 29440, 30208, 29952, 29696, 30208, 30464, 29696, 29440, 29696, 29952, 28416, 26624, 26880, 27392, 25344, 23808, 24320, 23296, 18176, 14592, 13568, 12032, 9728, 7424, 5888, 3584, -2816, -7168, -9728, -12544, -14848, -17152, -18688, -20480, -21504, -21504, -21248, -20992, -20480, -19968, -18944, -17152, -14336, -10752, -7424, -4096, -1024, 1792, 4608, 7424, 10240, 12544, 14592, 16384, 17920, 18944, 19968, 20224, 19712, 18432, 17152, 15360, 13568, 12288, 10752, 8448, 5888, 3584, 1024, -1536, -4096, -6144, -8192, -10240, -12288, -14080, -15616, -17408, -18944, -19968, -21248, -22272, -23296, -24064, -24576, -25344, -25856, -26368, -26624, -27136, -27392, -27392, -27392, -27392, -27392, -27648, -27392, -27392, -27392, -26880, -25856, -25088, -24576, -24064, -23808, -23296, -22272, -20992, -18944, -17152, -15872, -14592, -13824, -12544, -11008, -8960, -6400, -4096, -1792, -256, 1024, 2560, 4352, 6400, 8448, 10496, 12544, 14080, 15104, 16128, 17664, 18944, 19968, 21248, 22528, 23296, 23808, 24576, 25088, 25600, 26112, 26624, 27136, 27392, 27392, 27648, 27648, 27904, 27904, 27648, 27648, 27648, 27392, 26880, 26624, 26112, 25344, 24064, 23296, 22272, 21248, 19968, 18688, 16896, 14336, 11776, 9472, 7168, 4864, 2304, 0, -2816, -5888, -8960, -11520, -14080, -16384, -18176, -19968, -21248, -21760, -21504, -21248, -20736, -20224, -19200, -17920, -15616, -12544, -9216, -5888, -2560, 512, 3072, 6144, 8960, 11520, 13568, 15616, 17152, 18432, 19456, 20224, 19968, 19200, 17920, 16640, 14848, 13312, 11776, 9984, 7424, 5120, 2816, 256, -2304, -4608, -6656, -8704, -10752, -12800, -14336, -16128, -17664, -18944, -20224, -21248, -22528, -23296, -24064, -24576, -25088, -25856, -26112, -26624, -26880, -27136, -27136, -27136, -27136, -27136, -27136, -27136, -27136, -26880, -26112, -25088, -24576, -24064, -23552, -23040, -22528, -21504, -19712, -17920, -16384, -15104, -14080, -13056, -11520, -9728, -7424, -5120, -2816, -1024, 512, 1792, 3328, 5376, 7424, 9472, 11264, 13056, 14336, 15360, 16640, 17920, 19200, 20480, 21504, 22528, 23296, 23808, 24576, 25088, 25600, 26112, 26624, 26880, 27136, 27392, 27392, 27648, 27648, 27392, 27392, 27392, 27136, 26624, 26368, 25856, 25344, 24320, 23296, 22272, 21248, 19968, 18688, 17152, 15104, 12544, 9984, 7680, 5376, 3072, 768, -2048, -4864, -7936, -10496, -13056, -15360, -17408, -19200, -20736, -21504, -21760, -21504, -20992, -20480, -19712, -18688, -16640, -14080, -10752, -7424, -4096, -1024, 1792, 4608, 7424, 10240, 12544, 14592, 16384, 17920, 18944, 19968, 20224, 19712, 18688, 17408, 15872, 14336, 12800, 11264, 9216, 6656, 4352, 1792, -768, -3072, -5120, -7168, -9216, -11264, -13056, -14848, -16384, -17920, -19200, -20224, -21504, -22528, -23296, -23808, -24576, -25088, -25600, -26112, -26368, -26880, -26880, -26880, -26880, -26880, -26880, -26880, -26880, -26624, -26112, -25344, -24576, -24064, -23552, -23040, -22528, -21760, -20224, -18432, -16896, -15616, -14336, -13312, -12032, -10496, -8448, -6144, -3840, -2048, -256, 1024, 2560, 4352, 6144, 8192, 10240, 12032, 13568, 14592, 15872, 17152, 18432, 19712, 20736, 21760, 22784, 23296, 24064, 24576, 25088, 25600, 26112, 26624, 26880, 26880, 27136, 27136, 27392, 27136, 27136, 27136, 26880, 26624, 26112, 25856, 25344, 24320, 23296, 22272, 21248, 20224, 18944, 17408, 15616, 13312, 10752, 8448, 6144, 3840, 1280, -1280, -3840, -6912, -9728, -12288, -14592, -16896, -18432, -20224, -21248, -21760, -21760, -21248, -20736, -20224, -19200, -17664, -15360, -12288, -8960, -5888, -2560, 512, 3328, 6144, 8960, 11520, 13824, 15616, 17152, 18432, 19712, 19968, 20224, 19456, 18432, 16896, 15360, 13824, 12544, 10496, 8192, 5888, 3072, 768, -1024, -4352, -3840, 256, -256, 0, 0, 256, 768, 1280, 2304, 3328, 4608, 6144, 8192, 9728, 8192, 4608, -2304, -12288, -18688, -10496, 512, -768, -6144, -8704, -11264, -18432, -28416, -31744, -15872, 10240, 10240, -13056, -8960, 11520, 11776, -5632, -20224, 8960, 19968, -12032, -25088, -22528, -17664, -14592, -11264, -7936, -4352, -2304, -768, 1536, 10496, 21760, 11008, -23296, -32768, -16640, -6400, -5376, -4864, -3072, 512, 4096, 7424, 9984, 12544, 12288, 2560, -17664, -12032, 12800, 2048, -13312, -11264, 1280, 5376, -10240, -10752, 8448, 20224, 16896, 9728, 6144, 6400, 6656, 4608, 5376, 17920, 29952, 25088, 7168, -256, 5120, 5632, 0, 256, 2304, -2560, -12544, -8448, 9984, 17408, 9984, -1280, -4352, -14848, -19456, 19968, 26624, 4352, 1536, -5888, -11008, -3328, 14848, 21760, 11008, 5376, 8960, 11776, 7936, 5632, 8960, 3584, -12288, -18944, -9728, 1536, 2560, -2048, -4352, -6144, -9472, -15360, -17664, -10496, 3840, 6912, -5376, -6656, 4608, 7168, -256, -10496, 1280, 13056, -2304, -13056, -12288, -9728, -7936, -6144, -4096, -2048, -512, 256, 1536, 5888, 13312, 10496, -9984, -21248, -12800, -4864, -3328, -3072, -2048, 256, 2560, 5120, 6912, 8704, 8960, 3840, -10240, -11776, 6912, 4096, -8960, -9728, -1536, 4864, -4608, -8960, 4352, 15616, 14080, 8448, 5376, 5632, 6400, 5376, 4608, 13312, 25088, 23552, 7936, -1280, 2304, 4352, -256, -512, 1792, -1792, -12032, -11008, 6144, 15872, 9984, -768, -5120, -12288, -22528, 11776, 28928, 6400, 1024, -5120, -11520, -6400, 10752, 20992, 12032, 4864, 7168, 10752, 8192, 4608, 7680, 4864, -9984, -19712, -13056, -1024, 2560, -1536, -4608, -6400, -9472, -14592, -17920, -12800, 1024, 6656, -3840, -8448, 2304, 6912, 1536, -9728, -3072, 12800, 1536, -12032, -12800, -10240, -8192, -6400, -4352, -2560, -768, 0, 1024, 4352, 11520, 12032, -5888, -20992, -15360, -6144, -3584, -3328, -2560, -512, 1792, 4096, 6144, 7680, 8448, 4608, -8192, -14336, 3328, 5888, -7936, -10496, -3840, 4864, -1536, -8960, 1024, 13312, 14080, 8960, 5376, 5632, 6400, 5632, 3840, 10496, 22784, 24064, 9728, -1280, 1024, 4096, 512, -512, 1792, -1024, -10496, -12288, 3072, 14848, 11008, 512, -5120, -9728, -22784, 3584, 30208, 9728, 768, -3840, -11008, -8192, 7168, 19968, 13568, 4864, 6144, 10240, 8704, 4608, 6656, 5888, -7168, -19200, -15616, -3584, 2560, -512, -4096, -6144, -8704, -13568, -17408, -14080, -1792, 6400, -2048, -9216, 256, 6912, 3072, -7936, -6656, 11520, 5632, -9984, -12800, -10496, -8192, -6400, -4352, -2560, -1024, 0, 768, 3328, 9728, 13056, -1280, -19712, -17664, -7936, -3840, -3584, -2816, -1024, 1280, 3328, 5376, 6912, 7936, 5120, -6144, -15616, -768, 7168, -5888, -11008, -5888, 3840, 1280, -8192, -1536, 11008, 13568, 9216, 5632, 5376, 6656, 6144, 3584, 8192, 20224, 24320, 11776, -768, 0, 3840, 1280, -256, 1792, -256, -9216, -13312, 512, 13568, 11776, 1792, -4608, -7680, -21504, -3840, 29184, 14080, 1024, -2560, -10240, -9472, 3840, 18432, 15104, 5632, 5120, 9216, 9216, 4864, 5888, 6656, -4608, -17920, -17408, -6400, 1792, 512, -3328, -5632, -8192, -12544, -16640, -15104, -4096, 5632, -256, -9216, -2048, 6400, 4352, -5632, -8960, 8704, 9216, -7424, -12288, -10752, -8192, -6400, -4608, -2560, -1024, 0, 768, 2560, 8192, 13312, 2816, -17152, -19456, -9728, -4096, -3328, -2816, -1536, 768, 2816, 4864, 6400, 7680, 5632, -3840, -15872, -4864, 7680, -3584, -11008, -7680, 2304, 3328, -6400, -3840, 8448, 13056, 9472, 5888, 5376, 6656, 6656, 3840, 6144, 17408, 24064, 13824, 0, -768, 3328, 2048, 256, 2048, 512, -7680, -13568, -2048, 12032, 12544, 3328, -4096, -6400, -19200, -10496, 26112, 18688, 1536, -1280, -9216, -10240, 512, 16640, 16384, 6400, 4608, 8448, 9472, 5376, 5376, 6912, -2048, -16128, -18688, -9216, 512, 1280, -2560, -5376, -7680, -11520, -15872, -15616, -6400, 4352, 1280, -8960, -4352, 5376, 5376, -3328, -9984, 5120, 11776, -4096, -11776, -10752, -8192, -6400, -4352, -2560, -1024, 0, 768, 2048, 6912, 12800, 6400, -13824, -20736, -11776, -4864, -3328, -3072, -1792, 256, 2304, 4352, 5888, 7168, 5888, -2048, -15104, -8960, 6912, -1280, -10752, -8960, 512, 5120, -4096, -5120, 6144, 12032, 9728, 6144, 5376, 6912, 7168, 4352, 4608, 14848, 23296, 15872, 1280, -1536, 2560, 2560, 768, 2304, 1280, -6144, -13312, -4352, 10240, 12800, 4608, -3328, -5632, -16384, -15360, 21248, 23040, 3072, -768, -7936, -10496, -2048, 14080, 17152, 7680, 4352, 7680, 9472, 6144, 4864, 6912, 256, -13824, -19200, -11776, -1024, 1792, -1792, -4608, -7168, -10496, -14848, -15616, -8192, 2816, 2560, -7936, -6144, 4352, 5888, -1024, -9984, 1280, 13312, -512, -10752, -10752, -8192, -6400, -4352, -2560, -1024, 0, 768, 1536, 5632, 12032, 8960, -9728, -20992, -14080, -5888, -3328, -3072, -2048, -256, 1792, 3840, 5376, 6656, 5888, -256, -13568, -12288, 5120, 1280, -9984, -9984, -1536, 5632, -1280, -5632, 3584, 11008, 9728, 6400, 5376, 6912, 7424, 4864, 3840, 12032, 22016, 17408, 3072, -1792, 1792, 2816, 1024, 2560, 1792, -4608, -12800, -6400, 8448, 13056, 6144, -2560, -5120, -13312, -18432, 14848, 26368, 5376, -256, -6656, -10496, -4352, 11264, 17152, 8960, 4096, 6912, 9216, 6656, 4608, 6400, 2048, -11520, -19456, -14080, -3328, 1792, -768, -4096, -6656, -9728, -14080, -15616, -9728, 1024, 3328, -6656, -7680, 2816, 6400, 1024, -9216, -2560, 13056, 3584, -9472, -10752, -8448, -6144, -4352, -2560, -1024, 256, 768, 1536, 4608, 10752, 10752, -5632, -20480, -16128, -7168, -3584, -3072, -2304, -768, 1280, 3072, 4864, 6144, 5888, 768, -11776, -14848, 2304, 3584, -8704, -10496, -3584, 5376, 1536, -5376, 1024, 9216, 9728, 6656, 5376, 6656, 7680, 5632, 3328, 9472, 19968, 18688, 5120, -1792, 1024, 2816, 1536, 2560, 2560, -2816, -11520, -8448, 5632, 12544, 7424, -1024, -4608, -10240, -19200, 5888, 27648, 10240, 256, -4608, -9984, -6656, 7168, 16640, 10752, 4352, 5632, 8704, 7424, 4608, 5888, 3840, -7680, -18176, -16640, -6912, 768, 512, -2816, -5632, -8704, -12544, -14848, -11520, -1792, 3328, -4096, -8960, -256, 6144, 3328, -5888, -6656, 9472, 9216, -5120, -9984, -8704, -6144, -4352, -2560, -1024, 256, 768, 1280, 3072, 8448, 11776, 1536, -16384, -19200, -10240, -4352, -3072, -2560, -1280, 512, 2304, 3840, 5120, 5632, 2560, -7680, -16640, -4608, 5120, -4864, -10752, -6912, 2816, 5376, -2048, -2048, 5632, 8704, 6912, 5632, 6656, 7936, 6912, 3584, 5632, 15360, 19200, 8704, -1024, -512, 2048, 2048, 2816, 3584, -512, -9216, -10752, 1536, 11264, 9216, 1024, -3840, -6656, -16896, -6144, 24320, 18176, 2048, -2560, -8448, -8192, 1792, 14336, 13056, 5376, 4352, 7424, 8192, 5120, 4864, 5120, -3072, -15104, -18432, -11520, -2048, 1280, -1280, -4352, -7168, -10752, -13824, -12800, -5376, 2304, -1280, -9216, -4096, 4864, 5376, -1792, -8704, 3072, 13056, 1024, -8448, -8704, -6400, -4352, -2560, -1024, 256, 1024, 1280, 2304, 5888, 11264, 7424, -9984, -20224, -14080, -6144, -3328, -2560, -1792, -256, 1536, 3072, 4096, 5120, 3584, -3840, -15872, -11776, 4096, -512, -9984, -9216, -512, 7424, 2304, -3072, 2048, 7168, 6912, 5888, 6400, 7936, 7936, 4352, 3328, 11008, 18432, 11776, 512, -1280, 1280, 2048, 2816, 4096, 1280, -6656, -11264, -2048, 9216, 10240, 3072, -3072, -4864, -13312, -13568, 17152, 24064, 5120, -1280, -6912, -8960, -1792, 11520, 14080, 6912, 3840, 6400, 8192, 5888, 4352, 5376, 0, -12032, -18688, -14592, -4864, 1024, 0, -3328, -6144, -9472, -12800, -13056, -7424, 768, 256, -8192, -6656, 3072, 5888, 768, -8192, -1536, 13312, 5632, -6656, -8704, -6400, -4352, -2560, -1024, 256, 1280, 1536, 2048, 4608, 9984, 9728, -5376, -19456, -16384, -7680, -3584, -2560, -2048, -512, 1024, 2560, 3840, 4608, 3584, -2304, -14336, -14592, 1792, 1792, -8960, -9984, -2560, 6912, 4608, -2560, 512, 5888, 6656, 5888, 6144, 7936, 8192, 5120, 2816, 8960, 17152, 13056, 1792, -1536, 768, 2048, 2816, 4352, 2048, -5120, -11264, -3840, 7936, 10496, 4096, -2304, -4352, -11008, -15616, 11264, 26112, 7936, -512, -5888, -8960, -3840, 9216, 14336, 8192, 0, -6912, 256, -256, -256, 768, -1024, -512, 256, -256, -512, 512, 768, -1536, 256, 512, -1536, 512, 512, -1024, -256, 512, -1280, 256, 1024, -1024, 0, -256, 0, -256, -512, 512, 512, -1536, 0, 1024, -768, -768, 1024, -512, -768, -512, 0, 256, 256, -512, -512, 768, -2048, 6912, -10752, 2816, 5376, -8960, 8704, -6400, 3072, 2304, -6144, 3584, 3328, -9728, 13568, -10752, -768, 11776, -18688, 14080, -4096, -2304, 7168, -12544, 9728, -3072, -5376, 12544, -13056, 5120, 8192, -18688, 16384, -7168, -1792, 8192, -12800, 10752, -2816, -7680, 12544, -5376, -7936, 11776, -6400, -1792, 5120, -5632, 4608, -4096, -2560, 5376, -5888, 1280, 7168, -8960, 2048, 0, 2048, -6656, 4864, 1536, -2816, -5120, 16384, -11776, -4608, 13056, -18688, 30464, -29952, 11776, 9216, -20480, 17152, -11776, 5632, 0, -6144, 14336, -15104, 3584, 6656, -10240, 6144, -2304, 5120, -5120, -3840, 11008, -6656, -2816, 2304, 3584, -768, -7936, 1536, 13824, -15872, 768, 17152, -19968, 5120, 5376, -6400, 7936, -10496, 4608, 6912, -13568, 8192, 3840, -12288, 9472, -2816, 1024, -3072, -768, 7936, -6144, -5376, 10752, -2560, -11520, 14080, -8192, 8704, -11008, -3584, 22016, -19968, 2048, 9984, -8960, -512, 3328, 512, 1280, -2816, -1024, 1792, 1280, -7936, 9472, -1024, -7168, 7168, -2304, -2816, 2560, -256, 1024, -4608, 4352, -2304, -3328, 6144, -4608, 5120, -4608, -7680, 15104, -6400, -7424, 12288, -3840, -7424, 5888, 1024, -768, -4608, 3584, 1536, -2048, -4864, 4864, 2048, -3328, 0, 3328, -4608, 1024, 256, 0, 0, 2560, -3584, -3072, 9984, -11776, 5888, 2304, -5632, 5888, -5120, -5632, 16128, -10752, -7168, 19712, -16896, 3072, 9728, -14336, 7936, 6912, -19712, 16896, -2816, -9984, 15104, -8448, -10496, 23552, -13824, -12800, 24576, -9216, -11776, 11776, -4352, 7936, -11008, -7168, 25088, -14592, -12800, 21504, -5632, -11264, 9984, -2048, 4352, -7168, -3328, 16128, -17152, 4096, 2560, 768, -3840, -1024, 9216, -8704, -256, 6656, -6912, -512, 3328, 1792, -5632, 0, 6912, -2816, -4864, 1536, 6656, -10752, 3584, 4608, -1792, -3584, -2560, 9472, -3584, -6144, 6400, -1024, -1280, -2560, 768, 8960, -9984, -1792, 7936, -2048, -5888, 3840, 1024, -256, -6400, 7168, 1792, -8960, 8704, -4096, -256, 2304, -8960, 11520, -5632, -4352, 12288, -13312, 6144, 5632, -16640, 12288, 1792, -11520, 12032, -4864, -8448, 18176, -17920, 11776, -1792, -13312, 17408, -6400, -8960, 12288, -3328, -4352, 3584, 512, -3072, 2048, -2560, 256, 5632, -8192, 1024, 8704, -6656, -4608, 7424, -1792, -4864, 3840, -1792, 3840, -2048, -7424, 12800, -5632, -8960, 13568, -4864, -9472, 12032, -2304, -10240, 10496, 256, -6912, 1792, 768, 0, 0, -1792, 3328, -1792, -5376, 6656, 3584, -11264, 2816, 10240, -13056, 2560, 6656, -7168, 4096, -3328, -768, 7936, -10752, 2816, 8704, -13312, 2816, 8704, -11008, 2560, 7424, -4864, -5376, 6912, -2560, -1280, 2560, -3584, 2816, 768, -8960, 11008, 768, -13312, 9472, 5632, -16896, 12544, -3072, -4864, 12800, -14848, 4096, 10752, -17920, 12800, -512, -10752, 15360, -17664, 11008, 2816, -14592, 13824, -2048, -7936, 5888, -2048, -1792, 6144, -8192, 2816, 5376, -13056, 15360, -11264, -1536, 17408, -22272, 8448, 11520, -20224, 12800, -1792, -3328, 5376, -10240, 7936, 3072, -10496, 4608, 6144, -9984, 3840, 1792, -4352, 6400, -5120, -3072, 11008, -12032, 4352, 1536, -4096, 2560, 1024, -2816, -256, 3584, -2560, -1792, 1536, 2304, -5888, 2304, 768, 3328, -7680, 4096, 4096, -8448, 4352, 1024, -4352, 5888, -7424, 768, 13824, -22016, 12800, 2816, -10496, 7680, -5888, 3840, 4608, -15360, 14336, 1792, -16640, 12544, -1024, -3072, 256, -1536, 4864, -1024, -8448, 8960, -2560, -3072, 3328, -512, -512, -512, 512, -2560, 4096, -2048, -2816, 4864, -1536, -4864, 6144, -3584, 2304, 768, -6144, 6144, -1536, -3328, 4864, -2816, -1536, 1536, -2304, 4096, -2048, -2560, 3584, -2560, -256, -1280, 4096, -2048, -6400, 9472, -2816, -6912, 9472, -3584, -3328, 4864, -4352, 3584, -1280, -3840, 6656, -6912, 2560, 2816, -5888, 5632, -1280, -4864, 6400, -1792, -7168, 11264, -8960, 0, 6400, -7936, 7936, -2560, -6656, 11776, -10496, 512, 8448, -10240, 6144, 2048, -11008, 11264, -3072, -6400, 9472, -6400, -1536, 7424, -6912, 1280, 6144, -10240, 6144, -256, -6400, 5888, -256, -1536, -512, -256, 3584, -6144, 2048, 3328, -2816, 0, -3328, 4096, 3840, -14336, 11008, 3072, -8960, 3584, -2304, 4608, -2560, -4864, 7168, -768, -6912, 5888, -512, -3584, 6912, -8960, 2560, 8960, -17408, 11264, 1792, -11008, 11776, -5376, -6400, 14336, -8960, -5376, 13056, -8448, -2048, 7168, -6912, 4864, -512, -6656, 9216, -6656, 768, 3328, -3072, 1536, -2560, 2048, -3584, 3840, -3072, 0, 3328, -2304, -4096, 8192, -6912, 768, 5888, -12544, 12544, -4352, -7936, 16128, -16384, 6400, 9216, -19456, 15616, -2816, -12032, 19200, -13824, -2304, 17664, -20736, 8192, 7424, -16128, 11776, -1792, -6656, 9984, -7936, 1536, 4608, -6656, 3328, -1280, 1280, -1280, -512, 1280, -3072, 4352, -4352, -512, 5632, -6400, 256, 5120, -4864, 768, 1536, -1536, 768, -2304, 2560, -1536, -768, 1792, -1792, -768, 3072, -1280, -1280, -2816, 6144, -1792, -5888, 6144, 0, -3584, 0, 3072, -2560, -512, 1280, 0, 256, -2560, 2560, -512, -4352, 6656, -2816, -4096, 7168, -5632, 1536, 1024, -4352, 7680, -6912, -1792, 11776, -13824, 3840, 7424, -10752, 6400, -1024, -3840, 6656, -7424, 2816, 3840, -7168, 4864, -1792, 256, 2048, -5120, 3584, 256, -3840, 2816, -512, -512, 0, -2560, 3840, -1280, -3072, 3840, -256, -3840, 3072, 1024, -3840, 2304, -256, -2304, 2304, -1280, -1536, 3328, -3072, 256, 1536, -1536, -768, 1536, -1024, 0, -1536, 2816, -2304, -512, 3328, -3072, -512, -256, 2048, -2816, 1024, 512, -1536, 1024, -1024, 1024, 0, -3328, 3840, 0, -5376, 5888, -1280, -3840, 3840, -512, -2304, 1536, -512, -1024, 512, 768, -256, -1792, 1792, -512, -2304, 1536, 512, -2304, 1024, 1280, -3072, 2560, -2304, 1024, 1280, -4096, 3072, -512, -3328, 5120, -3328, -1024, 4352, -5888, 3584, 512, -5120, 5632, -3328, -768, 3840, -5632, 3072, 1024, -4608, 4352, -1792, -1792, 3328, -3584, 1536, 1024, -2560, 2304, -1280, -1536, 1792, 0, -1792, 2048, -1024, -256, 0, -1536, 1024, 1792, -3584, 512, 3328, -4096, 768, 2560, -3840, 1792, -256, -2560, 3584, -2560, -512, 2816, -2304, -1024, 1792, -1536, 768, -768, -1280, 2304, -1536, -768, 1280, 256, -1792, 768, -512, 0, -512, 0, 1024, -768, -512, 1024, -1536, 1024, -512, -512, 0, 256, 0, -1792, 1792, -512, -1792, 2304, -1792, -1024, 2816, -3840, 2816, -512, -2304, 2304, -1024, -768, 512, 768, -1792, 1280, 0, -1280, 1536, -1792, 256, 1792, -2560, -512, 3328, -2304, -1024, 2048, -1024, -512, -256, 256, 256, -1792, 1024, 1280, -2048, 0, 1536, -1536, 0, 768, -1024, 0, 256, -512, 512, -1024, -1024, 2048, -1792, -256, 1536, -2304, 2048, -768, -1536, 3072, -3072, 256, 2560, -2816, 256, 1280, -1536, 768, -512, -768, 1792, -2560, 512, 1792, -3072, 1280, 512, -1280, 768, -1280, 0, 1536, -2560, 768, 1024, -2048, 512, 512, -768, 768, -2048, 2048, 512, -3584, 2560, 768, -3072, 2048, 512, -2816, 2048, -512, -1536, 2304, -1792, -1024, 2560, -2304, -256, 1792, -1792, 256, 768, -2048, 2048, -512, -2048, 2560, -768, -1280, 1280, -1536, 768, 256, -2048, 2560, -1280, -1280, 1792, -1024, -512, 512, -768, 256, -256, -768, 1024, -768, 0, 0, 0, 0, -1024, 768, -512, -768, 768, -1280, 768, 0, -1792, 1280, 256, -2048, 1280, 256, -1536, 1536, -1280, 0, 768, -1792, 768, 512, -1536, 768, 512, -1536, 768, 256, -768, -512, 1280, -1024, -256, 768, -1024, 0, 0, -768, 1280, -1280, -768, 1792, -1280, -768, 1536, -1024, 0, -256, -768, 768, -512, -256, 512, -256, -512, 256, -512, 256, -256, -1792, 2048, -256, 1280, -1792, 3328, -5632, 2048, -1792, 2048, -28160, -7168, 6144, 13824, 9216, 512, 15360, -11520, 14592, 10752, -11008, 5120, 10496, -16896, 6144, -2816, 4608, -4608, -9728, -16128, -9216, 7680, -2816, 8448, 6400, 7680, 4608, 2816, -4608, -1280, 1280, -11776, 10240, 256, -3328, -4608, -5120, -7936, 5120, 2560, 7424, -1792, -4608, 10240, -7424, -4352, 10752, -4864, 1536, -1024, 1536, -2048, 2560, -6656, -1280, 768, 256, -4352, 1536, 0, 4864, -256, 2048, 0, -1536, -2560, -256, -3072, -256, 256, -768, 2048, -1792, 1024, 2816, 1024, 3584, -3328, 4096, -4864, -1024, -3328, -3328, -3584, 1536, 1024, -256, 1024, 2816, -256, 2816, -256, 256, -1024, -256, -3840, 1536, -2304, 256, -256, 0, 768, 256, -2048, 768, -256, -256, 512, -512, 512, -512, 256, -1280, -1792, 768, -768, 1536, -768, 1024, -256, 0, -1024, 512, -1792, 768, -1536, -256, -256, 1024, 0, 768, -512, 512, -1280, 1280, -2048, -768, -768, 512, -1280, 1792, -256, 1024, -512, 1024, -2560, 1536, -1536, -256, -1024, 1280, -3328, 1792, -1536, 1280, -2048, 4352, -5120, 3584, -1536, 2304, -10240, 18176, -32512, 2304, -18688, 32512, 19456, -7168, 18944, -8192, 2048, -15872, -12544, -9728, 10240, -17408, 5632, -3072, 17408, 2560, 9984, -2560, 0, 8960, -5888, 0, -15104, -3840, -1792, -768, -5888, 256, -5120, 9472, 6912, 512, 7680, -512, 4352, 512, -1280, -1792, -6912, -7424, 4096, -768, -2816, 256, -4096, -1280, -2048, -2560, 1792, 8192, 2304, 1280, -1024, 4096, 1280, -2048, -4352, -4096, 1280, -3328, 2048, 2816, 3840, -2560, -2304, 0, -256, 512, 1792, -768, -5888, 2304, 512, 768, 256, -3328, -256, -1536, 2816, -1536, 2048, 256, 3072, -3072, 2304, -3584, 2048, -256, 0, -768, -3328, 1024, -1792, -1024, 2048, 1280, -1280, -1792, 1024, -512, -768, 512, 768, -1536, 2048, -768, 256, -768, -512, 512, -1536, 512, -1024, -768, -1024, 768, 256, 0, 0, 256, -256, -256, 512, -512, 0, -1024, -512, 256, 512, 0, -768, 256, -768, 0, -256, -768, -1536, 512, -512, 768, -1024, 2560, -2048, 2304, -1280, 3072, -4864, 11776, 9472, -32768, 15360, -23040, 26112, -16640, 10240, -14592, 9984, -1536, 5888, -2048, 4864, 6144, 3840, -4352, -12032, -6912, -9216, -4096, 5376, 768, 5888, 3584, 12800, -2048, 4864, 6400, 1792, -2304, -7168, -16128, -9472, 0, -10752, 13824, -4352, 17408, -768, 7680, -3072, -1024, 2816, -3840, 2304, -6400, -3840, -512, -6912, -6400, 9728, -2048, -3328, 8448, 6144, 3072, -9728, 9984, -3072, -768, -4352, -11264, 9728, 512, 6912, 768, -1280, -1024, -3328, -7680, -14336, -1024, 2816, 256, 2304, 4352, 11776, 6400, -3584, 1536, -768, -1792, -5376, 512, 4096, -1280, -5632, 512, -512, 1536, -3072, -6400, -3840, 2560, 2304, 2048, 2816, 11008, 2048, -1280, -5632, -4096, 3584, -7936, 4096, 1792, -1792, -6656, -5120, -512, 2304, 2816, 6656, 1792, 1536, -5120, -3328, 0, 1024, 4352, -4352, -4608, 2560, 512, -2560, 6912, -2048, 6144, -5888, -3584, 256, 0, 3328, -4864, 3584, 2560, -4096, 4096, -1024, -5120, 5120, -8448, 512, 512, 6144, 5376, -768, -6656, -6144, -4608, -4608, 2560, 2560, 6144, 4608, 512, 2304, -6144, 4096, -3584, -2048, 2304, -1280, -3584, 2048, -1280, 7680, -2816, 2816, -3328, -3840, -3072, 1792, 1024, -3328, -3328, 3328, -3328, 3072, 5888, 2304, 0, 3584, -2560, -2304, -8960, -512, -5376, 3072, -256, 4352, 4864, 2816, -1024, 0, -4608, -6144, 2816, -2560, 256, 2816, 3072, -3328, -4096, 2560, -5888, 5376, 2304, -2304, 768, 3072, -1536, 768, -1280, 3072, 0, -512, 0, -4864, -2304, 1280, -2816, -1792, 2560, 256, -768, 2304, 4608, -1536, 0, -256, 256, -3328, 512, 256, -768, -2048, 4352, -1024, -2304, 4608, -3840, 2048, -256, -2816, -1280, -3584, 2816, -1280, -1792, 3072, 4096, -1792, 1792, -768, -2816, -1280, -1536, 256, 1024, -768, -768, 3840, 1280, 0, 768, 1536, -4096, 1024, -3584, -1536, -2304, -1024, 512, 2816, 2816, 1792, -512, 1024, -3072, -1792, -3584, -1536, -1792, 2304, 1024, 1792, -512, 1536, 1280, 1536, -1024, -768, -1024, 1792, -1792, -2816, -2304, 0, -768, 1792, -512, -512, 768, 3328, -1024, -1536, -3840, 2304, -1792, -256, 1024, 1536, 1280, 2048, -1536, -2048, 0, -2816, -1024, 1536, -2048, 1024, 768, 1280, 3328, -1024, -2304, -768, 1024, -768, -768, 1024, -256, -3072, 1536, -3584, 512, 768, 3840, 512, 1536, -1792, -2048, 768, 256, -512, 768, -768, -3072, -1536, -3584, 1792, -512, 3328, 1536, 2560, 1536, 0, -512, -2560, -3072, -2048, -1536, -1792, -1536, 1536, 1024, -512, 1280, 512, 0, -256, 768, -2816, 1024, 0, 5120, -2048, -512, 0, -256, -768, 1792, -768, -1024, -512, -1536, -2560, -2560, -2048, 256, 512, 1280, 2048, 512, 1280, 2048, 768, 1024, 768, -512, -3840, 0, -256, -1792, -512, -1280, -2560, 2560, -256, 1280, 768, 1280, -256, -512, -2048, -1280, -2304, 256, -2048, 1536, 1280, 1024, 256, 256, 512, 768, -512, 1024, -1792, 256, -1792, -2304, -512, 0, 512, 768, 1536, -2048, 2048, 768, 0, -512, -2304, -768, -512, 0, 768, -256, -512, -768, 1792, -768, 2560, -2048, 256, -3072, 768, -1792, 512, -768, 1792, 1024, 1024, 0, 0, -1536, -256, -1280, -768, -1024, -1792, 0, 1280, 1792, 0, 512, -768, 2560, -256, 768, -1792, -1280, -1024, -2304, -768, -1792, 1280, -1024, 2304, 512, 256, 1024, 1280, 0, -1280, 256, -2048, 1024, -2304, 1280, -1280, 0, 768, -512, -256, 256, 256, -1792, 1792, 0, 768, -1280, 0, -768, -256, -256, -1280, -256, 256, -256, 256, -256, 0, 512, 0, 512, -1792, -1792, 1024, -256, 0, 768, 1024, -256, -768, -1024, -1536, 768, -512, 1024, -256, 1280, -512, -256, -1280, -512, -1024, 256, 768, 512, 512, 0, -768, 256, 256, -768, -768, -256, 256, -768, -512, -256, -512, -768, -256, 0, 1024, 768, 1280, 512, 256, -1024, -2304, -768, -1792, 256, -512, 1792, -512, 768, 768, 768, 256, 0, -256, -1536, -1792, -1536, -1024, -256, 256, 0, 1280, 512, -512, 512, -768, -256, 768, -256, 256, -1024, -1024, -1280, 0, -1792, 512, -1024, 768, 1024, 256, 512, -256, -256, -512, -512, 0, -256, 256, -256, -256, -768, 256, 256, 768, -768, -256, 256, 256, -512, -768, -2048, -1280, 0, -256, 1280, 512, 768, 256, -512, -256, -256, -768, 256, 256, -512, -768, -768, -256, 0, -256, 256, 512, 512, 1280, 0, -256, -512, -256, -512, 0, -1024, 0, -1280, -256, -256, 0, 256, 1280, 1024, -512, -256, -512, 0, -1536, -256, 0, 256, -256, -512, 256, 0, 0, 768, 256, -512, 256, -512, -1024, -256, 0, -256, -256, -1024, -512, -1024, 512, -256, 256, 0, 768, 512, 0, 1024, -256, 1024, -1536, 512, -1024, -768, -1280, -1024, -768, 0, 512, 0, 256, 1024, 512, 512, -512, -512, -1280, -1536, -1280, -768, -512, 256, -256, 0, 0, 512, 512, 512, 0, 1024, -512, 768, 512, -256, -512, -768, -768, -768, -1280, -1280, -1280, -256, -256, 0, 512, 512, 1024, 256, 512, 256, 512, -256, -256, -768, -1024, -1280, -768, -512, -512, -256, 256, 1024, 512, 512, 512, 256, -256, -512, -1536, -512, -768, 512, -256, 256, -512, 0, 512, 256, 512, -512, 256, 0, -512, -512, -768, 0, -512, -256, -256, 0, -512, -512, 256, 0, 512, -256, 256, -256, 0, -256, -256, 0, -256, 0, -512, 512, 0, 512, 512, 1280, 768, 1536, 2048, 3072, 3328, -1536, -28160, -1792, 13056, -25344, -32768, 2560, -7168, -9984, 6400, -8448, -6912, 10496, 8704, -1280, 4352, 5888, 6400, 6144, 5888, 5120, 6144, 6400, 6144, 5376, 5120, 5888, 5888, 4096, 5120, 2304, 5120, 4608, 2560, 3584, 1280, 3584, 2816, 1792, 1280, 768, 2560, 512, 1792, -1024, 0, 768, 0, -768, -1280, -1536, -256, -3072, -1024, -4352, -2560, 2304, -10752, -10240, 16640, 10240, -14848, 7424, 18432, 9984, 12800, 7936, -256, 7680, 6400, -1792, -1024, -8448, -12032, -7424, -12544, -18944, -17664, -18176, -20224, -15616, -13056, -14592, -13568, -8704, -5120, -5632, -4096, -2560, -1536, -512, 256, 768, 1024, 2048, 2048, 3072, 2560, 2304, 3584, 3328, 3072, 3072, 3328, 3072, 3072, 3584, 3072, 3072, 3072, 3072, 3328, 3072, 2304, 2816, 2816, 2816, 1792, 2048, 1792, 2048, 2304, 512, 1280, 2048, -1536, 512, 4352, -4352, -5120, 4608, 1280, -3840, 3840, 6912, 5376, 9472, 11264, 10496, 11776, 9728, 6656, 8192, 6656, -1024, -3840, -1536, -5120, -11264, -12800, -13824, -15360, -15104, -14848, -14848, -13824, -11776, -9728, -8192, -6656, -4864, -3584, -2304, -1280, -256, 512, 1280, 1792, 2048, 2560, 2816, 3072, 3328, 3328, 3584, 3584, 3584, 3328, 3328, 3584, 3840, 3584, 2816, 3328, 3584, 3328, 3072, 2560, 3072, 3072, 2560, 2560, 2048, 1536, 2816, 2304, -256, 1280, 2816, -256, -1536, 256, -256, -1024, 0, -256, 0, 3584, 6400, 6144, 7168, 9472, 9728, 9728, 9728, 7936, 5632, 3584, 1024, -1280, -3840, -6656, -9728, -12032, -13312, -13824, -14336, -14592, -14080, -13056, -11520, -9984, -8704, -7168, -5632, -4352, -3328, -2048, -768, -256, 512, 1280, 1792, 2048, 2560, 2816, 3072, 3328, 3328, 3328, 3328, 3584, 3584, 3328, 3328, 3584, 3328, 3072, 3328, 3328, 3072, 2816, 3072, 2816, 2304, 2816, 2304, 1536, 1792, 2048, 1280, 768, 512, 0, 0, 0, -512, -768, 0, 768, 1536, 2816, 4608, 5888, 6912, 7936, 8704, 8960, 8192, 6912, 5376, 3584, 1280, -1280, -3840, -6656, -8960, -11008, -12288, -13312, -13568, -13568, -13312, -12544, -11264, -10240, -8960, -7424, -6144, -4864, -3584, -2560, -1536, -768, 256, 768, 1280, 1792, 2304, 2560, 2816, 3072, 3328, 3328, 3328, 3328, 3328, 3328, 3328, 3328, 3328, 3072, 3328, 3072, 2816, 3328, 2816, 2560, 2560, 2304, 2304, 2048, 1792, 1792, 1280, 1024, 768, 512, 0, -256, -256, 0, 512, 1024, 2048, 3072, 4352, 5632, 6400, 7168, 7680, 7680, 7168, 6144, 4864, 3072, 768, -1280, -3584, -5888, -7936, -9472, -11008, -11776, -11776, -12288, -12032, -11008, -10496, -9728, -8448, -7424, -6400, -5376, -4096, -3072, -2048, -1280, -512, 0, 768, 1280, 1792, 2304, 2560, 2816, 3072, 3072, 3328, 3584, 3328, 3328, 3328, 3328, 3328, 3072, 3072, 3072, 2816, 2816, 2816, 2560, 2304, 2304, 2048, 1792, 1792, 1536, 1280, 1024, 1024, 768, 768, 768, 768, 1280, 1536, 2048, 2560, 3072, 3584, 4352, 4608, 4864, 5120, 4864, 4352, 3584, 2560, 1280, 0, -1536, -2816, -4352, -5632, -6656, -7424, -8192, -8704, -8704, -8960, -8704, -8192, -7936, -7168, -6656, -5888, -5120, -4352, -3584, -2816, -2048, -1280, -768, 0, 512, 1024, 1536, 1792, 2048, 2304, 2560, 2816, 2816, 3072, 3072, 3072, 3072, 2816, 2816, 2816, 2560, 2560, 2304, 2304, 2048, 2048, 1792, 1792, 1536, 1280, 1280, 1280, 1024, 1024, 1280, 1280, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3328, 3328, 3328, 3072, 2560, 2048, 1280, 512, -512, -1536, -2560, -3584, -4608, -5376, -6144, -6656, -7168, -7424, -7424, -7680, -7424, -7168, -6912, -6400, -5888, -5120, -4608, -3840, -3072, -2560, -1792, -1024, -512, 0, 512, 1024, 1536, 1792, 2304, 2560, 2560, 2816, 2816, 3072, 3072, 3072, 3072, 2816, 2816, 2816, 2560, 2560, 2304, 2304, 2048, 2048, 1792, 1792, 1536, 1536, 1280, 1280, 1280, 1280, 1536, 1536, 1792, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3328, 3328, 3072, 2816, 2560, 2048, 1280, 512, -256, -1280, -2304, -3328, -4096, -4864, -5632, -6144, -6656, -6912, -7168, -7168, -7168, -6912, -6656, -6144, -5632, -5120, -4608, -3840, -3328, -2560, -1792, -1280, -512, 0, 512, 1024, 1280, 1792, 2048, 2304, 2560, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2560, 2560, 2304, 2304, 2048, 2048, 1792, 1792, 1536, 1536, 1536, 1280, 1280, 1280, 1280, 1536, 1536, 1536, 1792, 2048, 2304, 2560, 2816, 2816, 3072, 3072, 3072, 2816, 2560, 2304, 1792, 1280, 512, -256, -1280, -2048, -3072, -3840, -4608, -5376, -5888, -6400, -6656, -6912, -6912, -6912, -6656, -6400, -6144, -5632, -5120, -4608, -4096, -3328, -2816, -2048, -1536, -768, -256, 256, 768, 1024, 1536, 1792, 2048, 2304, 2560, 2560, 2560, 2816, 2816, 2816, 2560, 2560, 2560, 2560, 2304, 2304, 2048, 2048, 1792, 1792, 1536, 1536, 1536, 1280, 1280, 1280, 1280, 1536, 1536, 1536, 1792, 2048, 2304, 2304, 2560, 2816, 2816, 2816, 2816, 2816, 2560, 2304, 1792, 1024, 512, -256, -1024, -1792, -2816, -3584, -4352, -4864, -5376, -5888, -6144, -6400, -6656, -6656, -6400, -6144, -5888, -5632, -5120, -4608, -4096, -3328, -2816, -2304, -1536, -1024, -512, 0, 512, 1024, 1280, 1792, 2048, 2304, 2304, 2560, 2560, 2816, 2816, 2816, 2816, 2560, 2560, 2560, 2304, 2304, 2048, 2048, 1792, 1792, 1792, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1792, 1792, 2048, 2304, 2304, 2560, 2816, 2816, 2816, 2816, 2560, 2560, 2048, 1792, 1280, 512, -256, -768, -1792, -2560, -3328, -3840, -4608, -5120, -5632, -5888, -6144, -6400, -6400, -6144, -6144, -5888, -5376, -5120, -4608, -4096, -3584, -2816, -2304, -1792, -1280, -512, 0, 256, 768, 1280, 1536, 1792, 2048, 2304, 2304, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2304, 2304, 2048, 2048, 2048, 1792, 1792, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1792, 1792, 2048, 2048, 2304, 2304, 2304, 2560, 2304, 2304, 2048, 1792, 1536, 1024, 512, 0, -512, -1280, -1792, -2560, -3072, -3840, -4352, -4608, -5120, -5376, -5376, -5632, -5632, -5376, -5376, -5120, -4608, -4352, -3840, -3328, -3072, -2560, -2048, -1536, -1024, -512, 0, 256, 768, 1024, 1280, 1536, 1792, 2048, 2048, 2048, 2304, 2304, 2304, 2304, 2304, 2048, 2048, 2048, 2048, 1792, 1792, 1792, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1792, 1792, 1792, 1792, 2048, 2048, 2048, 2048, 2048, 2048, 1792, 1536, 1280, 1024, 768, 256, -256, -768, -1280, -1792, -2304, -2560, -3072, -3584, -3840, -4096, -4352, -4608, -4608, -4608, -4608, -4352, -4352, -4096, -3840, -3328, -3072, -2816, -2304, -1792, -1536, -1024, -768, -256, 0, 256, 768, 1024, 1280, 1280, 1536, 1792, 1792, 1792, 2048, 2048, 2048, 2048, 2048, 1792, 1792, 1792, 1792, 1792, 1792, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1536, 1280, 1024, 768, 512, 0, -256, -768, -1280, -1792, -2304, -2560, -3072, -3328, -3840, -4096, -4352, -4352, -4608, -4608, -4608, -4352, -4352, -4096, -3840, -3584, -3072, -2816, -2304, -2048, -1536, -1280, -768, -512, -256, 256, 512, 768, 1024, 1280, 1280, 1536, 1536, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1536, 1536, 1280, 1024, 768, 512, 0, -256, -768, 0, 0, 0, 0, 0, 256, 256, 256, 256, 256, 256, 256, 512, 768, 1024, 1280, 1536, 1536, 1536, 1536, 1536, 1280, 1280, 1280, 1280, 1280, 1536, 1792, 2048, 2304, 2560, 2560, 2816, 3072, 3072, 3328, 3328, 3584, 3840, 4352, 4608, 4864, 5120, 5376, 5632, 5888, 6144, 6656, 6912, 7424, 7424, 7424, 7168, 7168, 7168, 7424, 7680, 7936, 7936, 7936, 7936, 7168, 4864, -2048, -10496, -13568, -14592, -15104, -15360, -15872, -15872, -16128, -16384, -16640, -16640, -16896, -17152, -17664, -17664, -17664, -18432, -18944, -18688, -18944, -19456, -19968, -20224, -20736, -20992, -20992, -21248, -20736, -21248, -21760, -20736, -20736, -22528, -23040, -20480, -16384, -12032, -8192, -5888, -4608, -3840, -3328, -3072, -3072, -3072, -3328, -3328, -3328, -3328, -3328, -3072, -3072, -2816, -2304, -1792, -1536, -1024, -512, -256, 0, 256, 512, 1024, 1280, 1792, 2560, 3072, 3584, 4096, 4608, 4864, 4608, 4864, 5376, 4864, 5120, 5632, 5632, 5632, 6400, 6912, 7168, 7424, 7424, 7424, 7424, 7424, 7680, 7936, 7936, 7936, 8448, 8704, 8704, 8960, 8704, 8448, 7936, 7680, 7424, 6656, 6400, 6656, 6400, 5632, 5632, 5376, 5120, 5120, 4864, 4864, 4864, 4608, 4608, 4608, 4352, 4352, 4352, 4352, 4096, 4096, 4096, 3840, 3328, 3328, 3584, 3584, 3840, 3328, 3072, 3328, 3328, 2816, 3072, 3584, 3584, 4096, 4352, 3840, 4096, 4864, 4864, 4864, 4864, 5376, 4864, 4352, 4608, 4864, 4608, 3840, 3840, 4352, 4608, 4608, 3328, 2816, 3584, 3840, 3584, 2816, 1536, 1280, 2560, 3328, 4352, 4608, 2816, 512, -512, -512, -768, 512, 3584, 6144, 7680, 9472, 12032, 13312, 13312, 14336, 16128, 16640, 16640, 16128, 16640, 18432, 19200, 18688, 18176, 18688, 19712, 20992, 20992, 19712, 19712, 20992, 23040, 25344, 26624, 25344, 22784, 21504, 22016, 24064, 27136, 30464, 32512, 32256, 29952, 26624, 22272, 16384, 10752, 6144, 2560, -512, -3840, -5632, -6400, -6912, -7680, -8960, -9472, -9216, -8704, -8448, -9216, -10240, -10752, -11264, -11008, -11264, -12288, -13568, -14592, -15104, -14592, -13568, -13312, -13568, -14592, -15872, -17408, -18688, -19200, -19200, -18176, -16128, -14336, -12288, -10240, -8704, -7424, -6656, -5888, -5632, -5376, -4864, -4864, -5120, -5376, -5632, -5632, -5632, -5632, -5632, -5376, -5376, -5376, -5120, -4864, -4864, -4608, -4608, -4352, -4352, -4096, -3584, -3584, -3328, -2816, -2304, -2304, -2304, -2304, -2304, -2048, -2048, -2048, -2048, -2048, -1792, -1536, -1792, -1536, -1024, -768, -512, -512, -768, -1024, -768, -768, -512, -256, 0, 0, -256, -256, 0, -256, -256, -256, -768, -1280, -1280, -2048, -2560, -2560, -2304, -2304, -2560, -2816, -2816, -2816, -2816, -2816, -2560, -2304, -2560, -2560, -2560, -2816, -3072, -3072, -3328, -3072, -2816, -3072, -3584, -3584, -2816, -2560, -3072, -2816, -2816, -3072, -3072, -2816, -2816, -3328, -3072, -2304, -1536, -1536, -1792, -1792, -1536, -1280, -1024, -1024, -1280, -2048, -3072, -2816, -2048, -1024, -768, -1280, -1536, -1792, -2304, -3072, -3328, -2048, -768, -512, -1024, -2048, -2816, -3584, -3840, -4352, -4864, -4864, -3840, -2048, -256, 512, 1024, 2048, 3072, 4352, 5888, 6656, 6400, 6144, 6400, 7680, 9216, 10240, 9984, 9216, 8448, 8192, 8448, 9472, 11008, 12544, 13568, 13568, 12544, 11520, 11008, 11008, 11776, 13312, 15360, 17152, 19456, 20992, 20992, 19968, 17664, 14848, 12032, 9472, 6656, 3584, 512, -2304, -4096, -5376, -6144, -7168, -8192, -8960, -9472, -9728, -9472, -9216, -9216, -9216, -9984, -11008, -11776, -12544, -13056, -12544, -12032, -11776, -11520, -11520, -12288, -13312, -14848, -15872, -16640, -16896, -16640, -15872, -14848, -13824, -12800, -11520, -9984, -8704, -7680, -7168, -6400, -5888, -5376, -5120, -5120, -5120, -5120, -4864, -4608, -4864, -5120, -4608, -4352, -4608, -4352, -4352, -4608, -4352, -4096, -3840, -3840, -3328, -3072, -2560, -2560, -2560, -2304, -2048, -1792, -1536, -1024, -1024, -1280, -1536, -1280, -1024, -1024, -768, -512, -512, -256, -256, -256, 0, 512, 768, 512, 512, 768, 512, 256, 512, 1024, 1280, 1280, 1024, 1024, 1024, 768, 512, 512, 256, 0, 0, -256, -1024, -1280, -1024, -512, -512, -768, -768, -768, -512, -256, -512, -768, -512, -768, -1024, -1024, -768, -1024, -1536, -1792, -1024, 0, 0, -512, -1024, -1024, -768, -512, -512, -768, -1024, -1024, -768, -512, -256, 768, 1536, 2048, 1536, 768, 0, 0, 512, 1024, 1280, 1024, 768, 512, 512, 512, 256, 0, -256, 512, 1792, 2816, 2304, 1536, 512, -256, -768, -768, -1280, -1792, -2048, -1536, -768, 512, 2048, 3328, 4352, 4608, 4608, 4864, 5888, 7168, 8704, 10240, 10752, 10752, 10240, 9984, 9984, 10240, 10752, 11776, 12800, 14080, 15104, 15104, 14080, 13056, 12288, 12288, 13056, 14592, 16128, 17920, 19456, 20992, 22016, 22528, 22784, 22016, 20480, 18176, 15616, 13056, 11008, 8704, 6400, 4608, 2560, 512, -1280, -2304, -3072, -3328, -3072, -3072, -3328, -3584, -4352, -5632, -6656, -7424, -7168, -6912, -6400, -6144, -6144, -6400, -6912, -7936, -8960, -10240, -11008, -11776, -12032, -12544, -12544, -11776, -11008, -10240, -9216, -8192, -7168, -6144, -5376, -4608, -4096, -3584, -3328, -3328, -3072, -2816, -2816, -3072, -2816, -2560, -2304, -2816, -2816, -2816, -3072, -3072, -3072, -2560, -2560, -2560, -2560, -2304, -2048, -1792, -1536, -1280, -1024, -1024, -1024, -1024, -1024, -768, -512, -512, -256, -512, -768, -512, -256, 0, 0, 256, 512, 768, 512, 256, 256, 512, 768, 768, 1024, 1280, 1024, 1024, 1280, 1536, 1792, 1536, 1024, 768, 768, 768, 512, -256, -768, -768, -256, -256, -512, -768, -768, -512, -256, 256, 0, -256, -256, -512, -1280, -1536, -1280, -1024, -1024, -1024, -1024, -1536, -1536, -1024, -256, 0, -512, -1536, -2304, -2560, -2048, -1280, -1024, -768, -768, -256, 256, 256, -256, -768, -1024, -512, 0, 512, 512, 0, -768, -1536, -1792, -1536, -1024, -768, -512, -256, -256, -256, 0, 256, 0, -768, -2304, -3584, -4608, -4608, -3840, -3072, -2304, -2048, -1792, -1280, -768, -512, 0, 1280, 2816, 4352, 5632, 6400, 6144, 5888, 5376, 5120, 5632, 6912, 8192, 9472, 10240, 10496, 10240, 9984, 9472, 8960, 8704, 8704, 8960, 9984, 11520, 13312, 15104, 16896, 18176, 18688, 19200, 18944, 18176, 16640, 15360, 14080, 12288, 9984, 7168, 4352, 1792, -256, -1792, -2816, -3328, -3328, -3584, -4352, -5376, -6144, -7168, -7936, -8192, -8192, -8192, -8192, -7936, -7424, -7424, -7680, -8448, -9216, -10240, -11264, -12032, -12800, -13312, -13824, -14080, -13824, -13312, -12544, -12032, -11008, -9984, -8960, -7936, -7168, -6656, -6144, -5632, -5376, -4864, -4608, -4352, -4352, -4096, -3840, -4096, -4608, -4352, -4096, -4096, -4352, -4608, -4608, -4352, -4096, -4096, -3584, -3328, -3328, -3072, -3072, -3072, -2816, -2560, -2560, -2304, -1792, -2048, -2304, -2560, -2560, -2048, -1536, -1280, -1536, -1536, -1280, -768, -768, -1024, -1024, -1024, -768, -512, -512, -256, -256, -256, 0, 512, 768, 768, 768, 512, 256, 0, -256, -256, -256, -512, -768, -1280, -1280, -1024, -512, -768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 256, 0, 0, 256, 256, 0, 0, 256, 256, 256, 256, 256, 0, 256, 768, 512, 0, -256, 256, 512, 256, -256, -256, 512, 512, 0, 256, 512, 512, -256, -1024, -2560, -5376, -7680, -9216, -10496, -11264, -10240, -7680, -4608, -2560, -2048, -2816, -3328, -2048, 768, 4608, 8192, 10496, 11264, 11520, 12288, 12544, 11008, 8192, 5888, 3584, 1792, 2048, 4096, 6912, 8960, 9472, 7680, 4608, 2304, 1280, 768, 512, 256, 256, -256, -1536, -2816, -3072, -1536, -512, -1280, -2816, -4608, -7168, -9984, -12032, -14080, -17664, -22016, -25344, -26112, -23552, -17920, -11776, -7168, -3840, -768, 1792, 4352, 6656, 7168, 6144, 5888, 7680, 10752, 13568, 14592, 12800, 9216, 5376, 1280, -1280, -1024, 1536, 5120, 7936, 8960, 8704, 7424, 6656, 6912, 9472, 14336, 19456, 21760, 20480, 18176, 16128, 14080, 12032, 8704, 3328, -3328, -8192, -9984, -10240, -11776, -16640, -23808, -29952, -32768, -32768, -32256, -30720, -28160, -24576, -19968, -14848, -9216, -3584, 768, 2560, 5120, 10496, 15360, 17408, 16128, 13824, 11520, 9984, 9216, 8192, 7168, 7424, 8960, 10496, 12032, 11776, 10496, 9984, 11008, 13568, 17408, 20480, 19968, 16384, 11776, 7168, 3328, 768, -2304, -8960, -16384, -20480, -20992, -18944, -16896, -18176, -23296, -28416, -30976, -30208, -26880, -22016, -17408, -14592, -12544, -9472, -5632, -1792, 1280, 3584, 6656, 10752, 14080, 14336, 11776, 8960, 6400, 3584, 1536, 512, 256, 768, 2816, 5632, 8192, 10240, 11008, 10752, 11776, 15360, 19712, 22528, 23040, 19968, 13824, 7680, 3584, 512, -3840, -9472, -15872, -20992, -23040, -22784, -22016, -23040, -25344, -27392, -27904, -25856, -20736, -13824, -7424, -3584, -1280, 1792, 6144, 10240, 12544, 14336, 17408, 21248, 23552, 23552, 22272, 18944, 13824, 8192, 3072, -1280, -4864, -6400, -6144, -4608, -1792, 256, -256, -1536, -1024, 3328, 10496, 17664, 21504, 20480, 16128, 11264, 8192, 7424, 6400, 2816, -2560, -6400, -7936, -8960, -10240, -12288, -16640, -22272, -26624, -27904, -26112, -22272, -17664, -14848, -13824, -10752, -5376, 0, 3328, 7424, 13056, 18176, 21504, 22784, 22016, 19200, 13824, 8448, 3584, -768, -4864, -7424, -6912, -5632, -4608, -2816, -2048, -4096, -6656, -4864, 512, 6144, 10240, 12288, 10752, 6912, 5376, 7424, 8704, 6144, 1792, -1280, -3584, -5888, -7168, -8192, -11520, -17152, -20992, -21760, -19968, -16128, -11776, -8704, -7424, -6144, -3328, 0, 3072, 6400, 11264, 16640, 20224, 21760, 22016, 19968, 15360, 10496, 6912, 3072, -1280, -3840, -3840, -3584, -3328, -2048, -1792, -4352, -6912, -5888, -768, 5888, 11264, 13056, 11008, 6400, 3072, 2816, 3584, 2048, -768, -2560, -3840, -5632, -7168, -7680, -9216, -14080, -18688, -19968, -18944, -18176, -16128, -13056, -11008, -9984, -8704, -6400, -4608, -2304, 2048, 7168, 11776, 14336, 15616, 15872, 14848, 12032, 9216, 7168, 5120, 3072, 2816, 4096, 4864, 5120, 5376, 3840, 0, -1536, 2560, 9472, 14592, 16128, 14080, 9216, 3840, 512, -768, -2304, -4864, -6912, -8704, -11008, -12544, -12544, -13312, -16896, -20992, -22016, -20736, -19712, -18176, -15616, -13056, -12032, -11008, -8960, -5632, -3072, 512, 6144, 12032, 14848, 16128, 17152, 16896, 14848, 13056, 11520, 8704, 4608, 2304, 1792, 1792, 1792, 2048, 256, -3584, -6144, -3072, 4608, 12032, 16384, 17408, 16128, 13568, 10752, 9472, 9728, 9216, 7424, 5376, 4096, 2816, 1280, -512, -4352, -9216, -12544, -13312, -14336, -15872, -16128, -15616, -15616, -16128, -15360, -14336, -12544, -9472, -4864, 512, 4352, 6400, 7680, 8704, 9472, 9472, 9472, 8704, 6400, 3840, 2816, 3328, 3584, 3584, 2048, -1792, -5376, -4096, 2304, 9472, 13568, 15360, 15616, 13568, 10240, 8448, 8704, 8192, 5632, 3584, 3072, 2560, 1536, -512, -3840, -8192, -12288, -14592, -15360, -16128, -17152, -16896, -16128, -16128, -16640, -16384, -14848, -12544, -8704, -3328, 1536, 4096, 5376, 7168, 8704, 9728, 10496, 11008, 9216, 6400, 4864, 5376, 6656, 6912, 5120, 1024, -2816, -2816, 1792, 7936, 13568, 16896, 17920, 16896, 14592, 12544, 12032, 11264, 8448, 5376, 4352, 4096, 2560, 256, -2304, -6656, -11776, -15360, -17152, -19456, -21504, -21504, -20480, -19968, -20224, -19968, -18688, -16640, -13312, -8192, -2816, 1024, 2560, 4352, 6400, 8192, 9216, 10240, 9472, 6144, 3328, 3840, 5888, 5888, 2816, -1280, -4864, -6400, -4096, 2304, 9728, 15104, 17920, 18432, 17152, 16128, 16128, 15360, 12800, 9984, 8192, 7168, 5632, 3584, 768, -3584, -8704, -13568, -16640, -19456, -22272, -24064, -23808, -23296, -24064, -24576, -23808, -22016, -19456, -14336, -7680, -2304, 1024, 4096, 7424, 10240, 13056, 16128, 16640, 13312, 9984, 9984, 11520, 10752, 7424, 2816, -1792, -5632, -6144, -2048, 4864, 10752, 13824, 15360, 16128, 15616, 14848, 14592, 13568, 11008, 9216, 9216, 8704, 7168, 5376, 2816, -1280, -6144, -9984, -13312, -16640, -19200, -19712, -19200, -19200, -19968, -20480, -19968, -18688, -15616, -11008, -5888, -2304, 256, 2560, 5888, 9984, 13312, 14336, 12032, 9216, 8960, 10496, 10752, 8448, 4352, -512, -6144, -8960, -6656, -768, 4608, 8192, 10752, 12800, 13312, 13568, 13312, 12032, 9728, 7936, 7680, 7936, 7424, 6656, 5632, 3584, -256, -4608, -8448, -11776, -14848, -16640, -16640, -16640, -18176, -20224, -20736, -20224, -19200, -15872, -10752, -6912, -5376, -3584, 256, 4864, 8704, 10240, 9216, 7424, 6912, 7936, 9728, 9984, 7424, 2304, -3072, -6912, -7168, -3584, 2048, 6400, 9472, 12800, 15872, 17152, 16896, 15872, 13568, 10752, 9216, 9472, 9216, 8192, 7680, 6400, 3072, -1792, -6144, -9984, -13824, -16640, -17152, -17152, -18432, -19968, -20736, -20992, -20736, -17920, -13056, -8960, -7424, -5888, -1792, 3840, 7680, 9472, 10240, 8960, 6400, 6400, 9216, 10496, 8448, 3840, -1536, -6656, -9216, -6912, -2304, 1792, 5120, 8960, 12800, 14848, 15104, 14848, 13312, 11008, 9472, 9472, 9472, 9216, 8704, 7936, 6144, 2048, -2816, -7424, -11264, -14592, -17152, -17920, -18688, -20224, -22016, -23552, -23808, -22272, -18432, -15104, -13568, -11776, -7424, -2304, 1792, 5120, 7168, 6656, 4864, 4352, 6912, 9728, 9728, 6656, 1792, -3072, -6400, -6656, -3840, 256, 3584, 7168, 12032, 15616, 17152, 17408, 17408, 16128, 13824, 13056, 13568, 13056, 12544, 12544, 12032, 8704, 3584, -1280, -5632, -9984, -14336, -16640, -17152, -18688, -22016, -24576, -24832, -23552, -22016, -19712, -17664, -15616, -12544, -7168, -1536, 2560, 5632, 6912, 6400, 6144, 8448, 12544, 14336, 12288, 8192, 3328, -1280, -3840, -3072, -512, 1792, 4608, 8960, 12800, 15104, 16128, 16640, 15616, 13568, 12288, 11776, 11264, 11008, 11776, 12544, 11008, 6912, 2560, -1536, -6400, -11520, -13568, -13568, -15360, -19200, -22272, -23040, -23040, -22528, -20736, -19200, -18432, -16640, -12288, -6400, -1536, 1280, 2560, 3328, 4608, 7936, 12544, 15360, 14848, 11264, 7168, 3072, -256, -1792, -1792, -256, 2048, 5888, 10496, 13824, 15616, 16640, 16896, 16128, 14336, 12288, 11008, 10496, 10752, 11264, 11008, 9472, 6400, 2048, -3072, -8192, -11264, -12544, -13568, -16384, -20480, -23296, -24320, -23808, -22784, -21760, -20992, -19968, -17408, -12800, -6912, -1536, 0, -256, 0, 0, 0, 256, 512, 768, 1536, 2304, 3328, 4352, 4864, 3328, -1024, -3840, -2560, 1024, 4864, 6656, 3840, -2304, -4096, 1536, -512, -4608, 9728, 16384, 5376, -12288, 7680, 20992, -5888, -16128, -12800, -6656, -1792, 3072, 6656, 12032, 21248, 25600, 768, -27648, -22272, -7680, -1536, 1280, 4608, 8448, 11776, 12032, 5376, -13312, -11776, 12288, 768, -13824, -8192, 5632, 6400, -1792, 3072, 2304, -4608, -8448, -6144, 512, 11264, 22528, 23552, 2560, -7168, -256, 256, 5120, 10752, 256, -4352, 13568, 18432, 3072, -4096, -18944, -7936, 32512, 13312, 256, -8960, -11776, 3328, 9984, -3328, -3328, 3328, 3072, 2816, 2048, -14592, -20480, -11264, -1280, 3584, 4608, 1536, -3328, -6656, -2816, -2048, -6144, 768, 7680, 3584, -7168, -3072, 10496, -512, -9472, -8960, -5888, -3072, -256, 1536, 4352, 8704, 13568, 4864, -14080, -17152, -8192, -3328, -1280, 512, 3072, 4864, 6144, 3584, -6144, -12032, 3072, 2816, -9216, -8960, -256, 4608, -768, 0, 1280, -3328, -6400, -5632, -1280, 4864, 13568, 17664, 5376, -7168, -2560, -1280, 1536, 7168, 2048, -6400, 5888, 14592, 4352, -4352, -12544, -16128, 21504, 17920, 768, -5888, -12800, -1536, 9216, -512, -5120, 2048, 3584, 2304, 3328, -9472, -20992, -14848, -4864, 2048, 4352, 2560, -2304, -6656, -4864, -1792, -6144, -2304, 6400, 5632, -4352, -7168, 8448, 4096, -8192, -9472, -6912, -3840, -1024, 1024, 3328, 6912, 12288, 8960, -8960, -18432, -11008, -4352, -1792, -256, 2304, 4096, 5888, 4352, -3072, -13056, -1792, 5376, -6912, -10240, -3072, 4864, 1536, -768, 1280, -2304, -5632, -5888, -2048, 2816, 10752, 17408, 9728, -5888, -4096, -1536, 768, 6400, 4864, -6144, 2048, 13824, 7936, -3328, -8448, -19456, 11776, 24320, 3328, -3328, -12288, -5120, 8192, 3328, -5632, 512, 3840, 2560, 3840, -4352, -19712, -17152, -7936, 768, 4352, 3840, -768, -5376, -5888, -1792, -5120, -4608, 4608, 6912, -1024, -8704, 4352, 8448, -5376, -9216, -7424, -4096, -1536, 1024, 2816, 5888, 10752, 12032, -3072, -17664, -13824, -5632, -2048, -512, 1792, 3840, 5632, 5120, -512, -11776, -6912, 5888, -3328, -10496, -5632, 3840, 4096, -512, 1024, -1280, -4608, -5376, -2560, 1280, 8192, 16384, 13568, -3072, -5376, -1536, 0, 5376, 6912, -4096, -1536, 12288, 10752, -1536, -5632, -18176, 512, 27136, 7936, -1536, -10496, -8192, 5632, 6400, -4608, -1024, 3840, 3072, 3584, -256, -16384, -18944, -10752, -1280, 4096, 4864, 1024, -4096, -6400, -2560, -3584, -5888, 2304, 7424, 2304, -7936, -512, 10752, -1280, -8448, -7680, -4608, -2048, 768, 2304, 4864, 9216, 13056, 2560, -14848, -16128, -7424, -2816, -512, 1024, 3328, 5120, 5376, 1536, -8960, -11264, 4096, 256, -9728, -7680, 1792, 5888, 768, 512, -512, -4096, -5120, -3072, 512, 5888, 14336, 15872, 768, -6144, -1792, -512, 4352, 7680, -1280, -4352, 9472, 12544, 1024, -4352, -14592, -9472, 25344, 14080, 0, -7936, -10496, 2304, 8448, -2560, -2816, 3328, 3584, 3072, 2304, -12032, -19968, -13568, -3840, 3072, 5120, 2304, -2560, -6144, -3584, -2816, -6400, -512, 6912, 4608, -5376, -5120, 9984, 3328, -7424, -7936, -5120, -2304, 256, 2048, 4352, 7680, 12544, 7424, -10496, -17920, -9984, -3840, -1024, 512, 2816, 4352, 5376, 2816, -5632, -13312, 0, 3584, -7936, -9216, -1024, 6400, 2816, 256, -256, -3328, -4864, -3328, 0, 3840, 11520, 16640, 5120, -6144, -2560, -1024, 3072, 7680, 2048, -5632, 6144, 13312, 4352, -3584, -9984, -15616, 18176, 20736, 2048, -5376, -11264, -1280, 8704, 512, -4096, 2304, 4096, 2816, 3584, -7424, -19456, -15872, -6912, 1536, 5120, 3840, -1024, -5376, -4864, -2304, -5888, -3072, 5632, 6400, -2048, -7680, 6656, 7680, -5120, -7936, -5888, -2816, -256, 2048, 3584, 6400, 11264, 10752, -4864, -17664, -12800, -5120, -1536, 256, 2304, 3840, 5120, 3840, -2816, -13056, -4864, 5120, -5120, -9984, -3840, 5888, 5120, 512, 0, -2816, -4352, -3584, -512, 2304, 8960, 16128, 9472, -4864, -3584, -1280, 2048, 7168, 4608, -5632, 2304, 12800, 7168, -2816, -6656, -17408, 8192, 25600, 5632, -3328, -11008, -4608, 7680, 3840, -4352, 1024, 4096, 3072, 3840, -3072, -17664, -17664, -9984, -512, 4608, 4864, 512, -4352, -5632, -2560, -4864, -5120, 3840, 6912, 1024, -7936, 1792, 10496, -1792, -7680, -6400, -3328, -768, 1536, 3072, 5632, 9728, 12288, 768, -15616, -15360, -6912, -2304, 0, 1792, 3328, 4864, 4352, -512, -11264, -9472, 4608, -1792, -9984, -6144, 3840, 7168, 1792, 0, -2304, -4096, -3584, -768, 1536, 6400, 14592, 12544, -2304, -4608, -1792, 768, 6400, 6656, -3840, -1024, 11520, 9728, -1280, -4608, -15616, -2048, 26368, 10752, -1536, -9472, -7680, 5376, 6400, -3328, -768, 4096, 3328, 3584, 512, -14336, -18688, -12544, -3072, 3840, 5376, 2048, -2816, -5888, -3328, -3840, -6144, 1024, 7168, 3584, -6400, -3072, 10752, 2304, -6656, -6656, -3840, -1280, 1280, 2816, 4864, 8192, 12288, 5632, -11776, -17152, -9216, -3072, -512, 1024, 3072, 4352, 4608, 1024, -8448, -12800, 1536, 1536, -8960, -7936, 1024, 7936, 3584, 0, -2048, -3840, -3584, -1024, 1024, 4352, 12288, 14592, 1024, -5376, -2048, -256, 5376, 7680, -1280, -3840, 9216, 11264, 1280, -3584, -11776, -10240, 22528, 17152, 512, -7424, -9472, 2304, 7936, -1536, -2304, 3584, 3840, 3328, 2816, -10240, -18944, -14848, -6144, 2304, 5632, 3328, -1536, -5376, -4352, -3328, -6400, -1536, 6400, 5376, -3328, -6400, 8448, 6656, -4864, -6912, -4608, -1536, 768, 2560, 4096, 6912, 11520, 9216, -6656, -17664, -11776, -4352, -1024, 512, 2560, 3840, 4608, 2304, -5632, -14080, -2816, 3840, -6656, -9216, -2048, 7680, 5888, 512, -1536, -3584, -3584, -1536, 1024, 2816, 9472, 15104, 4864, -5120, -2560, -1024, 4096, 7936, 1792, -5120, 5888, 12032, 3840, -3328, -8192, -14848, 14848, 22528, 3328, -5376, -10240, -1280, 8192, 1024, -3328, 2560, 4352, 3072, 3584, -5888, -17920, -16640, -8960, 256, 5120, 4352, 0, -4608, -5120, -3072, -5888, -4096, 4864, 6400, -256, -7680, 4096, 9984, -2048, -6656, -5120, -2048, 256, 2304, 3584, 5888, 9984, 11264, -1280, -16128, -14592, -6144, -1792, 256, 2048, 3328, 4352, 3072, -3072, -13312, -7680, 4352, -3840, -9728, -4608, 5888, 8192, 1792, -1536, -3328, -3584, -1792, 768, 2048, 6912, 14080, 8448, -4096, -3328, -1536, 2560, 7680, 4352, -5120, 2560, 11776, 6400, -2304, -5376, -15360, 4864, 25600, 7936, -3328, -9984, -4352, 6912, 3840, -3328, 1024, 4352, 3328, 3840, -2048, -15616, -17664, -11776, -2560, 4352, 5376, 1536, -3328, -5632, -3328, -5120, -5632, 2560, 6912, 2304, -6912, -1024, 11264, 1536, -6144, -5632, -2816, -256, 2048, 3328, 5120, 8448, 11776, 3584, -12800, -16640, -8448, -2816, 0, 1280, 3072, 3840, 3584, -1024, -11008, -11776, 2560, -512, -9216, -6912, 3328, 9216, 3840, -1024, -3328, -3584, -2048, 768, 1792, 4608, 12544, 11008, -1792, -4096, -1792, 1280, 6912, 6144, -3584, -768, 10752, 8448, -768, -4096, -13056, -4352, 24832, 13056, -768, -9728, -1280, -3328, 256, -1792, 1280, -5632, -8192, -8960, -8192, -11008, -8960, -14080, -10752, -16896, -12288, -20480, -14592, -4352, -32768, -15104, -19456, 0, -6656, 256, -8448, 5376, 768, 4096, 3840, 6656, 11008, 7168, 16896, 1536, 24832, 10240, 26368, 17152, 25856, 26112, 25088, 24064, 5376, 25088, 23040, 14592, 19968, 22784, 20736, 15616, -1536, 13824, 1024, 15872, 4864, 6912, 8704, 3072, 4096, 3584, -4352, 4864, -1280, -512, -3328, -9728, -6144, -768, -8448, -3584, -2816, -4096, 0, -3328, 1792, -6656, -3328, -4096, 1536, -14592, -5888, -7168, -3328, -2304, -8704, -8192, -5120, -22272, -15872, -7168, -9728, -19200, -9472, -6912, -10496, -18176, -12288, -7680, -11264, -21248, -17152, -13312, -12288, -11520, -11776, -11520, -16128, -12032, -10240, -8192, -11520, -6144, -8192, -11008, -5376, -4352, 0, 5376, 6656, 11008, 13056, 15872, 12032, 10496, 14080, 14592, 17408, 8704, 13568, 16128, 15872, 18176, 15360, 15616, 14336, 13568, 14336, 13824, 9728, 12800, 14848, 12800, 10240, 7168, 13824, 9984, 10496, 9728, 5632, 8192, 5120, -768, 4864, -256, -1792, -1536, -4096, -4096, -3584, -6912, -7424, -11776, -16896, -15616, -13056, -13824, -15616, -10496, -12800, -12032, -13312, -14080, -11520, -11264, -7168, -14848, -14336, -7936, -9472, -9216, -8192, -4608, -4096, -8704, -7424, -2304, -5376, -5120, -7680, -5632, -4352, -4864, -2048, -3072, -3584, -1536, -3584, -1536, -2816, -512, 1024, -1536, 2304, 2048, 4352, 5888, 3328, 7936, 3328, 6144, 7680, 7168, 7424, 7680, 11008, 8704, 9472, 13312, 10752, 11264, 12800, 17152, 15104, 12544, 13824, 12288, 11008, 13056, 11520, 10752, 15872, 12032, 9984, 9472, 9216, 6144, 7168, 3328, 768, 2304, -2816, -768, -2304, -3584, -4608, -8704, -6912, -7424, -9984, -10752, -9728, -11776, -9472, -11776, -11008, -10496, -8960, -9728, -7936, -9728, -8704, -9984, -9984, -8704, -12288, -11264, -12032, -12544, -13824, -13312, -11264, -13568, -9472, -12032, -9728, -7936, -9728, -6912, -4864, -4864, -3840, -4096, 0, 0, 512, 1792, 3328, 7424, 5632, 8192, 8192, 9984, 12032, 10496, 10240, 14080, 12288, 10496, 11264, 14592, 11008, 9216, 12032, 11008, 10752, 9472, 8192, 8192, 6912, 8448, 9216, 7680, 5888, 6400, 6400, 5632, 4608, 5632, 5120, 4096, 2048, 1536, 3072, 1792, 0, 256, 768, -1280, -3584, -2304, -1792, -2048, -4864, -3840, -4096, -5888, -5376, -5376, -8192, -7936, -7424, -6656, -6912, -7424, -8448, -6656, -7424, -7680, -9984, -7168, -10496, -11008, -8960, -8704, -8192, -7424, -7168, -7168, -6400, -6912, -6144, -6912, -6912, -6912, -5632, -5888, -4352, -2304, -2560, -3584, -2560, -2048, -1024, -512, -256, -768, 1280, 1024, 2560, 2816, 1792, 3328, 2816, 3584, 6912, 5632, 5632, 5632, 6912, 9216, 8704, 9216, 9472, 11520, 11264, 12032, 12288, 13056, 12544, 13312, 13056, 13312, 12288, 12800, 12032, 12288, 10752, 10240, 7424, 8448, 6144, 5632, 3072, 1280, 0, -768, -1280, -2304, -5376, -5376, -6400, -4864, -7168, -7168, -7680, -8448, -9984, -10752, -10752, -11776, -11776, -11520, -10752, -11008, -12032, -12032, -9216, -8192, -7680, -8704, -7936, -5632, -7424, -7424, -7680, -6656, -7168, -7680, -5376, -6656, -6912, -5376, -4864, -4096, -2816, -3072, -2048, -512, 256, -1024, 256, 0, 256, 2304, 2048, 1792, 3072, 2560, 3328, 5120, 4352, 4608, 5376, 6656, 7424, 7680, 7680, 7424, 8704, 8448, 8704, 8448, 7680, 8192, 8448, 7168, 8448, 7424, 8960, 8192, 7936, 7680, 7936, 7680, 6400, 6912, 6144, 5376, 5376, 5120, 4096, 4352, 3072, 1536, 1024, -768, 256, -1536, -1792, -2816, -3328, -2816, -2560, -2048, -3328, -3072, -2304, -4352, -3584, -4864, -6144, -5632, -6144, -7680, -8192, -7680, -8448, -9472, -9984, -10240, -10752, -9984, -10496, -9984, -10240, -10496, -8960, -8960, -8960, -9472, -9216, -8448, -7680, -6400, -6400, -4864, -4096, -4096, -2560, -1536, -1792, -1024, -512, 256, 768, 1536, 2560, 2304, 3840, 4352, 4608, 4352, 3328, 4864, 4608, 4352, 4864, 5120, 6144, 6144, 6912, 6912, 7424, 7680, 6656, 7168, 7168, 6912, 7168, 6656, 6400, 6144, 6400, 5120, 4864, 4352, 4608, 3840, 3072, 3328, 2560, 1536, 2048, 1536, 768, 1024, 768, 0, -768, 0, -256, -512, -1280, -1024, -1280, -1024, -1280, -1536, -2048, -2304, -2304, -3072, -2816, -4096, -4096, -3840, -3840, -3328, -4352, -4096, -4352, -4352, -5376, -5120, -6400, -6144, -6144, -6144, -6656, -7680, -7680, -6912, -7680, -6656, -6656, -6912, -6912, -6400, -6144, -4864, -5120, -4352, -3328, -3072, -2048, -2048, -2048, -1536, -1280, -512, -256, 0, 768, 2048, 2560, 3072, 4096, 4608, 6144, 6400, 6400, 7168, 7680, 7168, 8192, 8448, 7936, 8192, 7936, 8960, 8448, 7936, 7936, 6912, 7168, 6656, 5888, 5888, 5120, 5632, 4608, 4096, 3328, 2816, 2304, 1280, 1024, -512, -512, -768, -2048, -2304, -2816, -3072, -3328, -3840, -3840, -3840, -3840, -3840, -3584, -3072, -3072, -3328, -3328, -2048, -2816, -2560, -3072, -2560, -3072, -3072, -2048, -2048, -2304, -2304, -2304, -2048, -2304, -2560, -2816, -2816, -2560, -3328, -3584, -3328, -4096, -4096, -4352, -4352, -4608, -4864, -4608, -4352, -4096, -4096, -3840, -3840, -3328, -3072, -2560, -3072, -2560, -2304, -2048, -1536, -1536, -768, 0, 0, 256, 512, 512, 768, 1024, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3072, 3328, 3584, 3584, 3840, 3840, 3840, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 3840, 3840, 3584, 3328, 3328, 3072, 2816, 2560, 2304, 2048, 1792, 1536, 1280, 1024, 768, 512, 256, 0, -256, -256, -512, -768, -1024, -1280, -1280, -1536, -1792, -1792, -2048, -2304, -2304, -2560, -2816, -2816, -3072, -3072, -3328, -3328, -3328, -3328, -3584, -3584, -3584, -3840, -3840, -3840, -3840, -3840, -3840, -4096, -4096, -4096, -3840, -3840, -3840, -3584, -3328, -3328, -3072, -2816, -2560, -2304, -2048, -1792, -1536, -1280, -1024, -512, -256, 0, 256, 512, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3072, 3328, 3328, 3584, 3584, 3840, 3840, 3840, 3840, 4096, 4096, 4096, 4096, 4352, 4352, 4352, 4352, 4352, 4352, 4096, 4096, 3840, 3840, 3584, 3584, 3328, 3072, 2816, 2560, 2304, 1792, 1536, 1280, 768, 256, 0, -512, -1024, -1280, -1792, -2304, -2560, -2816, -3328, -3584, -3840, -3840, -4096, -4352, -4352, -4608, -4608, -4608, -4608, -4608, -4608, -4608, -4608, -4608, -4608, -4608, -4608, -4352, -4352, -4096, -4096, -3840, -3584, -3584, -3328, -3072, -2816, -2560, -2304, -2048, -1792, -1536, -1024, -768, -512, -256, 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2304, 2560, 2816, 2816, 3072, 3328, 3328, 3328, 3584, 3584, 3584, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3584, 3584, 3584, 3328, 3072, 3072, 2816, 2560, 2304, 2048, 2048, 1792, 1536, 1280, 1024, 768, 512, 256, 0, 0, -256, 0, 0, -256, 512, 256, 0, 256, 1024, 512, 512, 512, 1280, 512, 1280, 1280, 2048, 1024, 3328, 3840, 4864, -15872, -16640, 14336, -4608, -32768, -9984, 3840, -14592, -2560, 4864, -5632, -2816, 9216, 7680, 1280, 4864, 6400, 4352, 5376, 5376, 4096, 5376, 4608, 4352, 4352, 3840, 3584, 3328, 3072, 2560, 1536, 2048, 1536, 1536, -256, 256, -1024, 1792, -2560, -9216, 8960, 16384, -6400, -4608, 21248, 12800, 5632, 9984, 5376, 4864, -1024, -5120, 7168, 0, -22528, -14080, -1280, -14080, -21248, -16384, -14848, -19712, -15616, -5632, -9984, -14592, -3840, 512, -3584, -2304, -256, 256, 256, 512, 2304, 1280, 1536, 2816, 2304, 2304, 2560, 2816, 3072, 3072, 2560, 2304, 2304, 3328, 1792, 768, 3584, 1024, -768, 512, 512, 4352, 10240, 3072, 3584, 14080, 14848, 11264, 9984, 9728, 9472, 1536, 1024, 7936, -1536, -12800, -6400, -3840, -12544, -13312, -10496, -15360, -17408, -8192, -6400, -12032, -9216, -2304, -1280, -1792, -768, 768, 1024, 1536, 2048, 2816, 2304, 2560, 3584, 3584, 2816, 3328, 3840, 3584, 3328, 3584, 3072, 2816, 3072, 3072, 2048, 2048, 768, 1024, 1280, -256, 2048, 8192, 5376, 3584, 11008, 12800, 9984, 12032, 9984, 5120, 5888, 4096, 1280, -2304, -5888, -6656, -8704, -12288, -9472, -12288, -18176, -14336, -8704, -11008, -12544, -9216, -5120, -3584, -3328, -2304, -1024, -256, 256, 768, 1536, 1536, 1536, 2304, 2560, 2048, 2560, 2816, 2816, 2816, 2816, 2560, 2560, 2560, 2560, 1536, 1536, 1024, 768, 1536, -768, 512, 6400, 5888, 4096, 8704, 9728, 11008, 13056, 7936, 4864, 9728, 5632, -2560, -1792, 0, -6400, -11520, -8704, -8192, -13824, -15872, -12032, -9984, -11520, -12032, -9216, -6144, -4864, -4096, -2816, -1536, -768, 0, 512, 1024, 1536, 1792, 2048, 2560, 2816, 2304, 2816, 3072, 2816, 2816, 3072, 2816, 2560, 2560, 2048, 1792, 1536, 768, 1280, 1024, 0, 3328, 7168, 5888, 4864, 9216, 12800, 10752, 7680, 7936, 9984, 6144, -1536, -512, 1792, -5376, -10240, -6912, -8704, -13056, -13056, -11264, -10752, -11520, -11520, -9472, -6912, -5632, -4608, -3328, -2304, -1536, -512, 256, 512, 1280, 1792, 1792, 2304, 2816, 2560, 2560, 3072, 3072, 2816, 3072, 2816, 2560, 2560, 2304, 1792, 1792, 1024, 1280, 1792, 256, 1792, 6912, 6144, 3840, 8704, 12032, 9472, 8192, 9216, 9216, 6656, 1024, -256, 1024, -3328, -7680, -6912, -8704, -12032, -11776, -10752, -11008, -11520, -11264, -9728, -7936, -6400, -5376, -4352, -3072, -2048, -1280, -256, 256, 768, 1280, 1536, 2048, 2304, 2560, 2560, 2560, 2816, 2816, 2816, 2816, 2816, 2560, 2304, 1792, 1792, 1536, 768, 1536, 1280, 1536, 4352, 5888, 4864, 7424, 10240, 8960, 8448, 9216, 8704, 6656, 3584, 768, 0, -1536, -4608, -6656, -8192, -9984, -10240, -9728, -9984, -10496, -10240, -9216, -7936, -6912, -5888, -4864, -3840, -3072, -2048, -1024, -512, 0, 768, 1024, 1280, 1792, 2048, 2304, 2304, 2304, 2560, 2560, 2560, 2560, 2560, 2304, 2048, 2048, 2048, 1792, 2048, 2560, 2816, 3584, 4864, 5632, 6400, 7168, 7424, 7424, 7424, 6912, 5376, 3584, 1792, -256, -1280, -2816, -4864, -6656, -7424, -7936, -8192, -8448, -8704, -8448, -8192, -7424, -6656, -6144, -5376, -4608, -3840, -3072, -2304, -1536, -1024, -512, 0, 512, 768, 1280, 1536, 1792, 1792, 2048, 2048, 2304, 2304, 2304, 2304, 2304, 2304, 2560, 2560, 2816, 3072, 3584, 4096, 4608, 5120, 5632, 5888, 6144, 6144, 5888, 5120, 4352, 3072, 1792, 512, -768, -2048, -3328, -4352, -5376, -5888, -6400, -6656, -6912, -6912, -6912, -6656, -6400, -5888, -5376, -4864, -4352, -3584, -3072, -2304, -1792, -1280, -768, -256, 256, 512, 1024, 1280, 1536, 1536, 1792, 1792, 2048, 2048, 2304, 2304, 2560, 2560, 2816, 3072, 3328, 3840, 4096, 4608, 4864, 5376, 5632, 5632, 5632, 5376, 4864, 4352, 3328, 2304, 1024, 0, -1280, -2560, -3584, -4608, -5376, -5888, -6400, -6656, -6656, -6656, -6656, -6400, -5888, -5632, -5120, -4608, -3840, -3328, -2816, -2304, -1536, -1024, -512, 0, 256, 768, 1024, 1280, 1536, 1792, 1792, 2048, 2048, 2048, 2304, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4352, 4608, 5120, 5376, 5376, 5376, 5376, 4864, 4352, 3584, 2816, 1792, 512, -768, -1792, -2816, -3840, -4864, -5376, -5888, -6400, -6400, -6656, -6400, -6400, -6144, -5632, -5376, -4864, -4352, -3840, -3072, -2560, -2048, -1536, -1024, -512, 0, 256, 768, 1024, 1280, 1536, 1536, 1792, 2048, 2048, 2304, 2304, 2560, 2816, 2816, 3072, 3328, 3840, 4096, 4352, 4864, 5120, 5120, 5376, 5120, 4864, 4608, 3840, 3072, 2048, 1024, 0, -1024, -2304, -3328, -4096, -4864, -5376, -5888, -6144, -6400, -6400, -6400, -6144, -5888, -5376, -5120, -4608, -4096, -3584, -3072, -2304, -1792, -1280, -768, -512, 0, 256, 768, 1024, 1280, 1536, 1536, 1792, 2048, 2048, 2304, 2560, 2560, 2816, 3072, 3328, 3584, 3840, 4352, 4608, 4864, 5120, 5120, 5120, 4864, 4608, 4096, 3328, 2560, 1536, 512, -512, -1536, -2560, -3328, -4096, -4864, -5376, -5888, -6144, -6144, -6144, -6144, -5888, -5632, -5120, -4864, -4352, -3840, -3328, -2816, -2048, -1536, -1280, -768, -256, 0, 512, 768, 1024, 1280, 1536, 1792, 1792, 2048, 2304, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096, 4352, 4608, 4864, 4864, 5120, 4864, 4608, 4096, 3584, 2816, 2048, 1024, 0, -768, -1792, -2816, -3584, -4352, -4864, -5376, -5632, -5888, -5888, -5888, -5888, -5632, -5376, -4864, -4608, -4096, -3584, -3072, -2560, -2048, -1536, -1024, -512, -256, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2048, 2304, 2560, 2816, 3072, 3072, 3328, 3584, 3840, 4096, 4352, 4608, 4864, 4864, 4864, 4608, 4352, 3840, 3072, 2304, 1536, 768, -256, -1280, -2304, -3072, -3840, -4352, -4864, -5376, -5632, -5888, -5888, -5888, -5632, -5376, -5120, -4608, -4352, -3840, -3328, -2816, -2304, -1792, -1536, -1024, -512, -256, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096, 4352, 4352, 4608, 4608, 4608, 4352, 4096, 3584, 3072, 2560, 1792, 1024, 0, -768, -1536, -2304, -3072, -3840, -4352, -4608, -5120, -5120, -5376, -5376, -5376, -5120, -4864, -4608, -4352, -3840, -3584, -3072, -2560, -2304, -1792, -1280, -1024, -512, -256, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3584, 3840, 3840, 4096, 4096, 4096, 4096, 4096, 3840, 3584, 3072, 2816, 2048, 1536, 768, 0, -768, -1536, -2304, -3072, 256, -256, 512, -256, 1024, 512, 2048, 1280, 2560, -1280, 0, 1280, 4352, -2816, 0, 4864, -4352, 6656, 16640, 3840, 7424, 768, 8960, 17152, 12800, 22528, 15104, 29952, 7168, -1536, -4096, 7424, 16128, 15872, -10240, 15104, 5632, -24320, -12544, -14080, 4864, 9216, -3840, 6656, -29952, 15360, 2048, -25856, -29440, 5888, 15360, -8192, -27136, -21504, -22528, -32512, -25344, -29952, -28160, -14336, -10752, -13568, -20224, -11264, 11008, 2560, -2816, 18432, 5632, 15616, 2560, -23552, -27136, -28416, -8960, -17408, -32768, -17152, -9216, -30208, -24832, -24576, -1024, 19200, 17920, 28928, 9216, 18688, 29440, 9472, 1536, 20224, 24832, 22784, -2048, -9728, -2048, -18432, -2048, -7424, -8960, 18688, 25088, 16896, 3072, 10240, 28928, 27136, 22272, 32256, 28672, 32512, 22272, -768, -5376, -5888, 10240, 3584, -17408, -5120, 5376, -14592, -17152, -17152, -1024, 17664, 13568, 23040, 4352, 9216, 19968, -1792, -13824, -512, 8192, 5376, -18176, -27904, -22784, -31744, -26368, -29184, -28928, -9472, -1024, -7680, -22528, -21248, 3840, 3328, -8960, 10752, 7168, 8448, 3584, -23040, -23552, -26624, -9472, -8704, -29440, -18688, -2304, -19200, -22784, -21760, -7424, 17152, 13056, 24832, 14080, 12032, 29440, 11776, -2304, 10752, 23040, 24576, 6656, -9216, 2816, -11008, -6400, -1536, -9472, 15104, 26624, 22528, 7936, 5632, 24576, 29696, 17664, 28160, 30464, 30464, 27904, 2816, -3840, -6656, 4608, 9472, -11520, -8192, 8704, -3328, -15872, -15872, -7680, 15616, 12032, 19200, 11776, 3584, 18432, 3584, -14848, -8960, 4096, 7680, -9728, -27904, -19968, -27904, -29696, -26112, -31488, -14592, -512, -2816, -14848, -24320, -4608, 5632, -10496, -768, 9216, 5120, 7936, -17664, -24064, -25600, -18432, -5376, -23296, -23552, -2304, -8448, -20992, -20736, -14592, 12288, 13312, 17920, 20736, 8960, 24832, 17664, -2560, 2048, 16896, 24064, 14080, -6912, 1024, -1280, -10240, -256, -8448, 7680, 26112, 25856, 15616, 4864, 17920, 30976, 18432, 19712, 31488, 28672, 30976, 9216, -3328, -5376, -2560, 9728, -4608, -11008, 6912, 6400, -10240, -15104, -11520, 10240, 13824, 13312, 17408, 3840, 14336, 8960, -12288, -14848, -3072, 6400, -2560, -25088, -21504, -21248, -31232, -25856, -31488, -20736, -2048, -768, -7168, -21760, -12032, 5120, -7168, -9984, 5888, 4608, 7936, -9728, -25344, -23552, -24832, -8960, -16896, -26112, -6656, -768, -15360, -19712, -17664, 4608, 15104, 12032, 22272, 11776, 18688, 22016, 768, -3328, 8704, 20480, 17920, -2048, -3072, 4864, -8192, -3072, -5376, 768, 23296, 26880, 22272, 8704, 13056, 29184, 22784, 13568, 27136, 29440, 30464, 16640, -2560, -3328, -6400, 5120, 1024, -11520, 2304, 11264, -2048, -12544, -13056, 3584, 15616, 9984, 17408, 8704, 9984, 13056, -7680, -17152, -10496, 1792, 1280, -19456, -24576, -16640, -28416, -28160, -29440, -26368, -5120, -256, -2304, -14848, -16640, 2048, -2304, -14080, -1536, 4352, 6144, -2816, -24064, -22784, -26112, -16384, -12800, -25856, -13056, 1536, -7680, -16896, -18176, -3072, 15104, 10240, 18432, 17152, 14848, 23296, 6144, -5376, 1536, 14336, 18944, 3584, -5632, 5888, -2048, -6144, -3584, -3328, 18176, 27136, 25856, 15872, 10752, 25856, 26880, 12544, 19456, 29184, 29184, 22272, 768, -3072, -5888, -1536, 3328, -9472, -2816, 11520, 6144, -7424, -12544, -2048, 14592, 10240, 13568, 13824, 8192, 14336, -1536, -16640, -15616, -5376, 1536, -13312, -25856, -16640, -21760, -29440, -27904, -29696, -10752, 0, -256, -6912, -16640, -3072, 1792, -13056, -9472, 1792, 4352, 1536, -19456, -24320, -24064, -23296, -13312, -23040, -19456, -512, -1024, -11776, -16896, -8960, 11776, 11776, 12544, 19968, 14592, 21760, 12800, -4352, -3328, 6656, 16384, 8704, -5632, 2304, 4608, -5632, -3584, -4608, 10752, 26368, 26880, 22528, 12800, 21248, 29184, 16128, 12544, 24576, 28160, 25344, 6656, -3584, -3840, -5888, 1536, -6144, -7424, 8448, 11520, 0, -9728, -5888, 11264, 12800, 9472, 15360, 9728, 13312, 5376, -13824, -17920, -12288, -1792, -7936, -24320, -19968, -16128, -26624, -27648, -29952, -17664, -1024, -256, -1280, -12032, -7680, 3328, -8448, -14848, -3584, 2048, 2816, -12800, -25344, -22272, -25856, -17920, -19712, -23552, -5632, 2560, -5632, -13312, -11776, 5888, 14080, 9216, 17920, 16896, 18944, 17664, -512, -5888, 256, 11008, 11008, -2816, -2048, 7424, -1024, -4352, -4096, 4608, 23296, 26880, 26112, 18176, 18432, 28672, 21248, 10240, 17920, 25856, 26112, 12800, -2560, -2560, -6144, -2560, -3328, -9216, 3584, 13312, 6912, -4608, -7168, 6656, 14848, 8448, 13056, 12544, 11776, 10240, -8704, -17920, -16896, -7936, -5632, -20736, -23552, -14336, -21248, -26880, -28672, -23296, -4352, 0, 512, -5632, -9472, 1792, -3072, -15616, -9984, -1280, 1792, -6912, -23808, -23040, -24576, -23040, -18432, -24320, -12288, 2304, -256, -8448, -11776, 0, 14080, 9472, 12800, 18432, 17408, 19712, 5120, -6400, -3840, 4352, 10240, 768, -5120, 5632, 4864, -3072, -3584, 512, 17920, 26880, 27136, 23552, 18432, 26624, 25600, 12288, 11776, 21248, 25088, 17920, 768, -3072, -4096, -5888, -2816, -8704, -2048, 11776, 12032, 2816, -5376, 2048, 14592, 10496, 9216, 13568, 11520, 12288, -1536, -16384, -18432, -14592, -7168, -15616, -25088, -16640, -15360, -24064, -26880, -26368, -10496, 256, 0, -256, -7424, -1536, 1280, -12288, -15360, -6656, -768, -3072, -18944, -24832, -22016, -25600, -20480, -22784, -18944, -1536, 3328, -2560, -8960, -4608, 10496, 12288, 8448, 16384, 17408, 19200, 11776, -3840, -6400, -1792, 6144, 4096, -5120, 1024, 8448, 1280, -2816, -1280, 11008, 25088, 26880, 26880, 21760, 23808, 28160, 17152, 8960, 15104, 22272, 20736, 6400, -3328, -2304, -5888, -4608, -6912, -6400, 7680, 14080, 9472, -256, -768, 11776, 13568, 7424, 11264, 12032, 12288, 5120, -12288, -18432, -18432, -12032, -12288, -23808, -20992, -13056, -18688, -24576, -26112, -16896, -1536, 0, 1280, -2560, -4096, 2560, -6656, -16896, -12544, -5120, -2560, -13056, -25088, -22016, -23808, -23808, -21760, -22528, -8192, 3584, 2048, -4096, -5888, 5632, 13824, 8192, 11520, 17152, 17920, 15616, 1024, -6912, -5376, 512, 4352, -3328, -3328, 7424, 6656, -256, -1280, 5888, 21248, 26624, 27136, 25600, 23040, 28160, 22272, 10240, 9728, 17408, 20480, 11520, -1536, -2304, -3584, -6144, -5888, -8192, 2048, 13312, 13568, 6400, 256, 7936, 15360, 8960, 7680, 11520, 11520, 9216, -6144, -17408, -19456, -17152, -12544, -20480, -24064, -14592, -13824, -20736, -24320, -20992, -5888, 512, 256, 1024, -3072, 1024, -1280, -14592, -16640, -10240, -5120, -9216, -22272, -24064, -21248, -24832, -22272, -23040, -14592, 512, 4608, 512, -3072, 2048, 2560, -5120, 7680, 6400, 5376, 3584, 1024, 3840, -12288, -8448, 2816, -17920, 13824, -1280, -5376, -2048, -768, 18688, -13312, 16640, -14080, 20480, -7168, -17152, -768, -3328, 5376, -12544, -512, 2816, 9216, 15104, -15360, 8704, -7168, 5376, -6400, -11520, 13824, 1280, 0, -4864, -3072, 5120, 13824, -13056, -5888, 5632, 9216, -15104, -5120, 2048, 7168, -2304, -13824, 32512, -11264, 17664, -32768, 1280, 17664, -2048, -25088, 11520, 17664, 5120, -24832, 5888, -1792, 30976, -20736, -512, -5376, 13056, -17152, -3584, -6144, 32512, -15360, 11520, -29696, 32512, -7424, -23808, -5888, 27392, -1280, -5376, -15872, 9472, 10496, 7424, -18944, -16128, 26368, 6144, -15104, -11264, 15872, 11008, -7168, -11776, 1792, 18432, 4864, -17920, -12032, 10752, 13568, -17408, -3328, 9472, 15104, -9728, -15360, 9984, 16896, 6912, -32768, 9216, 19712, 3840, -18944, -3840, 19200, 9728, -12544, -2816, -9984, 4096, -2048, -7680, 8960, 10496, -256, -512, 4352, -17408, 25344, -24832, 15360, -12544, 8192, -11264, -7424, 20992, -6656, 9984, -8960, 2560, 9728, -5120, -5376, -23552, 21248, -6144, 3328, 7936, -8448, 5632, 11520, -7936, -6144, 2304, -6144, -8192, 10752, -4352, 8704, 1792, -6912, 1536, 15616, -2304, -8704, -1280, -2048, -4352, -1536, -8704, 4352, 11008, -2304, 8960, -8704, 4096, 6912, -6144, -4352, -4352, 1280, -4352, 10752, -7936, 5632, 4352, -6656, -5632, 8192, 10496, -6912, -6400, -2560, -1280, 4096, -512, 3328, -256, 12288, -8448, -6912, 1536, 4096, 3328, -9472, -2816, 4608, 6400, -10752, -2816, 11776, -1792, -3840, 2304, 3840, 1024, -768, -9216, -6144, 7936, -2048, 3584, 3072, 6912, -4864, -4352, -3584, -1792, 10752, -1280, -3840, 1280, 256, -3840, 3584, 11008, -4864, 256, -6400, -8960, 4096, 4096, 7424, -3072, 2048, -3584, 256, 5376, -2048, -3072, -5632, -1024, 6144, 6656, -4096, -5632, 9472, 768, -10496, 1792, 1024, 768, 7680, 1024, -6912, 2816, -1536, -6656, 8448, 5888, -5888, -3584, -5120, -1792, -1024, 9216, 0, 4608, 2560, -6912, 256, 256, 4096, -256, -1024, -11264, -1280, 4352, 2304, 3328, -1024, -768, 7936, 6144, -3584, -6656, 2304, -6912, -7168, 4864, 5632, 8192, -2816, -3840, 1280, 3840, -5888, -5376, 4096, 3584, 4608, -2816, -6656, 3328, 2560, -3072, -3072, 2816, 3584, -1536, -3328, -768, 1536, -1536, 768, 3072, 8192, 3584, -5632, -11520, -2560, 9472, 2816, -12800, -2816, 12800, 5632, -3328, -1024, -1024, 3840, -4096, -8448, 1792, 8704, -2304, -3584, -256, 5376, 3840, -3584, -3072, -1536, 1792, 2048, 512, 0, -1280, 1536, 3840, 1024, -2304, 3328, 768, -13056, -4608, 6912, 2560, 1280, -2816, 1536, -256, 1280, 5632, 512, -3584, -9984, -3072, 4864, 4352, 1024, 2816, 1280, -6400, 512, 5888, 2048, 512, -768, -9984, -5632, 1024, 4608, 1536, 3584, 6400, 5120, -4352, -5120, 4352, 1792, -11008, -9728, -4608, 4352, 6144, -1536, 7680, 11264, 1536, -9216, -5120, 1792, 6144, 256, -17664, -6400, 12032, 3840, -1024, 8960, 4864, -4608, -5632, -3072, 5120, 9984, -9216, -12544, 2304, 7168, -4096, 2304, 8704, 9216, -5632, -17664, -4096, 9984, 1792, -7168, -768, 8448, -4608, -1792, 4608, 13568, 6144, -9472, -15616, -2560, 9728, 512, -6144, -2816, 3072, 4352, 0, 7168, 12800, -1280, -15104, -14592, 5632, 3584, -3840, -1280, 5632, 2304, -5120, 4864, 8448, 7936, -8448, -15872, -3328, -512, 11520, -2304, -1024, -768, 4864, 2048, -2048, 10240, 2048, -4096, -11264, -4864, 4096, 768, 5888, -8192, 5632, 1280, -2304, 1280, 6656, 5376, -6912, -4608, -11520, 768, 3840, 0, 1792, 1792, 1792, 3328, 4608, -2560, 768, -1280, -7680, -7680, -768, 2304, 7936, 4352, -2560, 4864, 7168, -8448, -5120, 7936, 3584, -17152, -6912, 3328, 5120, 7424, 256, -512, 6144, -768, -6656, -3072, 8192, -1792, -7936, -4352, 1280, 5632, 2816, -1536, 1536, 1792, 512, 1792, 1280, -3072, -5632, -4352, -6144, 5632, 12032, 256, 512, 2560, 1280, -7424, -1280, 3328, 256, -7680, -7168, -1280, 5888, 6400, 1536, 1280, 256, 1792, 0, 1280, 768, -8448, -9472, -1536, 4864, 5120, 6656, -256, -3840, 5376, 2304, -3584, -3328, 0, -2816, -6144, -2304, 2304, 5888, 256, 256, 8192, 2816, -6400, -4608, 1280, -1280, -1536, -2304, -2560, 512, 4608, 1024, 3072, 1536, -512, -2048, 512, 512, -1792, 512, -5632, -1280, 4352, 6400, 3840, -1280, -256, -6144, -2048, -2560, -1280, 3072, 1792, -1024, -2560, 1024, 2048, 5632, 2816, -256, -3072, -7936, -4352, 1536, 3072, 2816, 1280, -768, -256, 5632, 0, -1024, 768, -4608, -4352, -768, 4096, 2304, 512, -1280, 0, 1024, -2304, 4608, 4352, -5632, -4864, -2048, -1536, 5376, 2816, -1536, -4096, 8448, 3328, -3840, -768, -3840, 256, -768, -2560, -1792, 2048, 4352, -2816, 2304, 4864, 0, 1280, 0, -4608, -3328, 512, -5120, 2560, 7424, -2816, -3328, 1280, 2816, 4096, 1024, -6400, -5376, 3328, -1280, 256, 768, -256, 1536, 3328, -1792, -256, 4352, -1536, -1536, -2304, -1536, -768, -256, 256, 4608, 2816, -5632, 512, 4608, -512, -3840, 256, 1280, -3072, -2560, -1792, 2304, 6656, 2560, -2816, 1280, 0, -1792, -768, -2816, -2304, -768, 512, -2560, 4864, 7168, -768, -768, -1024, 2304, -3584, -1280, -1792, 2048, -768, -6912, 1280, 9472, 2816, -512, 768, -6912, -3840, 3072, -512, 3584, 512, -2048, -4096, 5632, 2816, -256, 2560, -4352, -2048, -1280, -5888, 512, 7424, 2048, -5376, 2048, 3072, 1536, 2048, -4352, 768, -512, -3072, -6912, 4096, 6400, -1280, -1792, 512, 4864, 256, -3840, 1792, 512, -1280, -8704, 512, 4608, 4352, -2560, 512, 4608, -256, -3072, -2560, 1280, 256, -4096, -2304, 3072, 5376, 1024, -2560, 512, 3072, 256, -4864, -2816, 5120, 1280, -3584, -5376, 1280, 4352, -1280, 768, 4352, 1024, -6400, -1280, 1280, 1024, 0, -1280, 512, 512, -256, 256, 3328, 0, -2816, -2048, 768, 512, -256, -768, -768, 2816, 2048, -1536, 512, 1792, 1024, -1280, -5888, -512, 3584, -256, -3840, -512, 3840, 2560, 256, -1024, 4096, 256, -6144, -3072, 2048, 2048, -5120, -512, 3584, 3328, 2560, 512, 512, -2304, -1536, -2304, -768, 1280, 1792, -768, -2304, 0, 512, 2048, 768, -256, 512, -1024, 0, -256, -256, -256, -512, -2048, -3584, -4864, -7168, -13056, -13568, -12544, -12288, -12544, -11264, -9472, -7680, -5888, -3584, -2048, -2816, -1280, 768, 2816, 512, 0, 2048, 4864, 2560, 256, 1536, 4608, 3840, 1024, 1024, 4352, 4864, 3328, 2304, 5120, 6912, 6656, 6656, 8448, 10752, 11520, 13568, 15104, 17408, 17664, 21248, 22784, 23552, 21760, 22528, 23296, 20480, 14336, 9472, 7424, 2304, -6400, -13824, -16640, -18944, -24064, -28928, -28672, -26368, -25856, -26368, -23808, -20224, -16896, -15872, -12800, -10496, -8448, -6912, -4352, -2816, -3072, -2048, 0, 1792, -256, -512, 1280, 3840, 2048, -256, 768, 3840, 3328, 512, 512, 3072, 4352, 3072, 2048, 3840, 5888, 6144, 6400, 7424, 9728, 10752, 12800, 14336, 16640, 17408, 19968, 22272, 23296, 22272, 22272, 23296, 21504, 16384, 11008, 8448, 4096, -3584, -11264, -15360, -17920, -22272, -27392, -28416, -26880, -25856, -26368, -24576, -21504, -17920, -16384, -14080, -11520, -9216, -7680, -5632, -3584, -3584, -2816, -1024, 1024, 0, -768, 256, 2816, 2048, -256, 0, 2560, 3072, 768, 0, 2304, 3840, 2816, 1792, 3584, 5632, 5888, 6144, 7168, 9472, 10752, 12544, 14080, 16384, 17152, 19968, 22272, 23296, 22528, 22528, 23808, 22016, 17152, 12032, 9216, 5120, -2560, -10240, -14336, -17152, -21504, -26624, -27904, -26880, -25856, -26368, -24576, -21760, -18176, -16640, -14336, -11776, -9728, -7936, -5888, -4096, -3840, -3072, -1536, 512, -256, -1280, 0, 2304, 1536, -256, -256, 2048, 2816, 768, 0, 2048, 3584, 2816, 1792, 3328, 5376, 5888, 5888, 6912, 9472, 10496, 12288, 13824, 16128, 17152, 19712, 22016, 23296, 22784, 22784, 23808, 22272, 17920, 13056, 9984, 5888, -1536, -9216, -13568, -16384, -20736, -25856, -27392, -26368, -25600, -26112, -24576, -21760, -18432, -16896, -14592, -12032, -9984, -8192, -6400, -4352, -4096, -3328, -1792, 0, -768, -1280, -256, 1792, 1536, -512, -512, 1792, 2304, 512, -256, 1792, 3328, 2560, 1792, 3072, 5120, 5632, 5888, 6912, 9216, 10496, 12288, 13824, 16128, 17408, 19712, 22272, 23296, 23296, 23296, 24320, 22784, 18688, 13824, 11008, 6912, -256, -7936, -12544, -15616, -19968, -25088, -26880, -26112, -25344, -25856, -24576, -21760, -18688, -16896, -14848, -12288, -10240, -8448, -6656, -4864, -4352, -3584, -2304, -512, -1024, -1536, -768, 1280, 1024, -768, -768, 1280, 2048, 256, -256, 1536, 3072, 2560, 1792, 2816, 5120, 5632, 5888, 6912, 8960, 10496, 12032, 13824, 15872, 17408, 19456, 22016, 23296, 23296, 23552, 24576, 23296, 19456, 14848, 11776, 7680, 768, -6912, -11520, -14592, -19200, -24064, -26368, -25600, -25088, -25600, -24576, -21760, -18944, -17152, -15104, -12544, -10496, -8704, -7168, -5120, -4864, -3840, -2560, -768, -1280, -1792, -1024, 768, 768, -1024, -1024, 1024, 1792, 256, -512, 1280, 2816, 2304, 1536, 2816, 4864, 5376, 5632, 6656, 8960, 10240, 11776, 13568, 15616, 17152, 19456, 22016, 23296, 23552, 23808, 24832, 23808, 19968, 15616, 12544, 8448, 1792, -5632, -10496, -13824, -18432, -23296, -25600, -25344, -24832, -25600, -24576, -22016, -18944, -17152, -15360, -13056, -10752, -8960, -7424, -5632, -5120, -4352, -2816, -1280, -1536, -2048, -1280, 512, 256, -1280, -1280, 512, 1280, 0, -768, 768, 2560, 2048, 1280, 2560, 4608, 5376, 5376, 6400, 8704, 9984, 11520, 13312, 15616, 17152, 19200, 21760, 23296, 23552, 24064, 24832, 24064, 20736, 16384, 13312, 9472, 2816, -4608, -9472, -13056, -17664, -22528, -25088, -25088, -24576, -25344, -24320, -22016, -19200, -17408, -15616, -13312, -11264, -9216, -7680, -5888, -5376, -4352, -3328, -1536, -1792, -2304, -1536, 0, 0, -1280, -1280, 256, 1024, -256, -768, 512, 2048, 2048, 1280, 2560, 4352, 5120, 5376, 6400, 8448, 9984, 11520, 13056, 15360, 16896, 19200, 21760, 23296, 23808, 24064, 25088, 24320, 21248, 17152, 14080, 10240, 3840, -3584, -8448, -12288, -16896, -21760, -24576, -24576, -24320, -25088, -24320, -22016, -19200, -17664, -15872, -13568, -11520, -9728, -8192, -6400, -5632, -4864, -3584, -2048, -2304, -2560, -2048, -512, -256, -1536, -1792, -256, 512, -512, -1024, 256, 1792, 1536, 1280, 2048, 4096, 4864, 5120, 6144, 8192, 9728, 11264, 12800, 15104, 16896, 18944, 21504, 23296, 23808, 24320, 25344, 24832, 21760, 17920, 14848, 11008, 4608, -2560, -7680, -11520, -16128, -20992, -23808, -24320, -24064, -24832, -24320, -22272, -19456, -17920, -16128, -13824, -11776, -9984, -8448, -6656, -5888, -5120, -4096, -2560, -2560, -3072, -2304, -768, -768, -1792, -2048, -512, 256, -512, -1280, 0, 1536, 1536, 1024, 2048, 3840, 4608, 5120, 5888, 7936, 9472, 11008, 12800, 14848, 16640, 18944, 21248, 23296, 23808, 24576, 25600, 25088, 22272, 18432, 15616, 11776, 5632, -1536, -6912, -10752, -15360, -20224, -23296, -24064, -23808, -24832, -24320, -22272, -19712, -17920, -16384, -14080, -12032, -10240, -8704, -7168, -6400, -5632, -4352, -3072, -2816, -3328, -2816, -1280, -1024, -2048, -2304, -768, 0, -1024, -1536, -256, 1280, 1280, 768, 1792, 3584, 4608, 4864, 5888, 7680, 9216, 10752, 12544, 14592, 16640, 18688, 21248, 23040, 24064, 24576, 25600, 25344, 22784, 19200, 16128, 12544, 6400, -512, -5888, -9728, -14336, -19456, -22528, -23552, -23552, -24320, -24064, -22272, -19712, -18176, -16640, -14592, -12288, -10496, -9216, -7424, -6656, -5888, -4864, -3328, -3072, -3584, -3072, -1792, -1536, -2304, -2560, -1280, -256, -1024, -1792, -512, 512, 1280, 1024, 1536, 3072, 4608, 5120, 6144, 7680, 9728, 11520, 13312, 15616, 17920, 20224, 22784, 25344, 27136, 27904, 28928, 29440, 27904, 24576, 20736, 16896, 11264, 4096, -3072, -8192, -13312, -18944, -23552, -25856, -26624, -27392, -27648, -26368, -24064, -21760, -19968, -17920, -15360, -13312, -11520, -9728, -8448, -7424, -6400, -4864, -4096, -4352, -4096, -3072, -2304, -2560, -3072, -2304, -1280, -1280, -1792, -1280, 0, 768, 768, 1280, 2816, 4352, 5120, 5888, 7424, 9472, 11264, 13056, 15104, 17664, 19968, 22528, 25088, 26880, 28160, 29184, 29696, 28160, 25088, 21504, 17664, 12288, 5120, -1792, -7424, -12544, -18176, -22784, -25344, -26112, -26880, -27392, -26368, -24064, -22016, -20224, -18176, -15872, -13824, -12032, -10240, -8704, -7680, -6656, -5376, -4608, -4608, -4352, -3584, -2560, -3072, -3584, -2816, -1280, -2560, 11008, -24064, 11264, -3328, 6912, -25088, 256, 2304, 19712, 16128, 1024, 2048, -32768, 16128, -18688, 19968, -29696, 32512, -3584, 28416, -22272, -17152, -11008, -11520, 9728, 13568, 25344, -9472, 3584, -13056, -14848, -5888, -8192, 8704, 6912, 19200, 2304, 13056, -26624, -18176, -8448, 6912, 17152, 0, -256, 6400, 0, -8960, 256, -17920, 7168, -1024, 27904, 768, 1280, -10752, -1792, 10752, -3840, 9472, -15872, 17152, -3584, 12288, -21760, -11776, -24064, 9472, 8960, 5888, 3840, -20224, 8960, -12800, 23296, -16384, 10240, -17664, 11776, 5120, 11008, -5376, -13056, 2048, -256, 24320, -12032, 17664, -26624, 25088, -11264, 18944, -15616, -3584, -4864, 1792, 13312, -10240, 2048, -22784, 14848, -13568, 27136, -27136, 10752, -20992, 15616, -256, -2048, -2560, -15104, 13568, -4608, 21760, -21248, 16128, -18688, 22784, -8192, 12800, -15872, 2560, 3328, 5120, 15872, -20736, 10496, -21504, 22528, -8192, 10496, -19968, 6912, -7680, 13056, -1536, -10752, 1536, -12544, 18944, -10496, 10496, -22784, 6912, -8448, 14592, 0, -4096, -2048, -1024, 11520, 2048, 5120, -16128, 9216, -7424, 19200, -5888, -4352, -5888, -3584, 11520, -1792, 4352, -14336, 5120, -3072, 11520, -4096, -3328, -7936, 1536, 7936, -1792, 4352, -20736, 10240, -8960, 18688, -8704, 0, -7936, 2560, 8960, -1024, 4864, -15360, 11264, -7680, 21248, -16896, 10496, -22272, 15104, -1536, 5888, -1024, -15104, 8704, -8448, 19712, -17920, 12544, -22784, 22528, -11520, 16128, -15872, 1024, -5120, 4608, 11776, -12544, 11520, -25856, 23296, -14336, 19968, -20224, 8960, -13056, 17152, -3072, -512, -3584, -12544, 16896, -8960, 18432, -22272, 13056, -18944, 21248, -9728, 7424, -9216, -2560, 5888, 768, 7680, -15104, 6912, -15104, 23296, -11264, 10496, -16128, 3072, 512, 5888, 2048, -9216, 3584, -8960, 16896, -9728, 8192, -15104, 6400, -2816, 10240, -1536, -6400, -512, -6144, 14080, -6400, 7424, -14848, 7680, -4352, 10496, -4608, -4352, -768, -3328, 12800, -6400, 6656, -16128, 8960, -5888, 12800, -5632, -1280, -4608, 0, 8448, -4864, 5632, -17152, 14592, -9984, 16128, -11520, 1536, -6912, 3328, 5888, -1536, 3840, -14080, 11264, -10752, 17920, -15104, 9216, -15360, 14336, -3328, 3840, -2304, -12800, 12544, -9728, 18432, -16128, 9472, -16640, 17152, -12288, 14080, -13056, 2560, 512, -1280, 11520, -15616, 11776, -21248, 23296, -14848, 18432, -17664, 5888, -6912, 8960, -2048, -768, -512, -8448, 16896, -15616, 20224, -25600, 17152, -15360, 16896, -6656, 3328, -5376, -3328, 5888, -2816, 7424, -12544, 10240, -13568, 20480, -17152, 13312, -16128, 7168, 1536, -256, 5888, -11520, 6400, -7680, 10752, -6400, 5632, -10752, 8448, -6656, 9984, -6656, -2304, 2560, -7168, 15616, -12800, 8448, -11008, 4608, 512, 1536, 1024, -4608, 1024, -2048, 6144, -5376, 5632, -12544, 12800, -10240, 13312, -8960, -2560, 4352, -8704, 16384, -13568, 9728, -12032, 9472, -7168, 10240, -12032, 8448, -8192, 7168, 768, -5120, 7680, -17664, 20224, -19200, 22528, -18432, 9984, -8704, 5632, -1792, 2304, -4608, 256, 4864, -6912, 14848, -22784, 20736, -23040, 22784, -14848, 10752, -6912, -1280, 4096, -5376, 7424, -8704, 7168, -9472, 15104, -16640, 18432, -23040, 17664, -11520, 7936, 1536, -9216, 10240, -13568, 14336, -12032, 9984, -10752, 10240, -9728, 12800, -13312, 8704, -7936, 1792, 8192, -12032, 15872, -20224, 16896, -13056, 10496, -6912, 3072, -2560, 3072, -1280, 768, -1280, -4608, 8448, -11264, 17920, -19200, 15360, -13312, 6912, 1024, -4864, 5632, -7424, 6912, -3840, 4608, -7936, 6656, -9216, 12800, -10496, 8960, -7936, 768, 4864, -9472, 14080, -15872, 13056, -9728, 6400, -2816, 256, -3328, 3072, -1792, 3328, 1024, -8448, 9728, -14336, 18432, -16384, 13312, -11008, 5120, 1536, -5120, 6400, -10240, 8704, -6400, 9728, -10496, 11008, -17408, 17408, -15104, 13568, -7168, -1792, 6912, -11520, 16128, -17920, 14336, -15360, 15104, -10496, 12288, -14336, 9984, -11008, 8960, -768, -4864, 10240, -17920, 21760, -20736, 19456, -19200, 12288, -9216, 10496, -5120, 3072, -5888, 0, 4096, -5888, 13056, -19456, 19968, -20992, 20480, -14592, 7424, -5888, 768, 3584, -512, 2304, -7424, 4352, -7936, 14080, -13056, 13568, -16896, 12544, -6912, 4352, 768, -8960, 9216, -8448, 11264, -6912, 2816, -7680, 6144, -4608, 9472, -7424, 1024, -768, -3840, 11520, -12032, 10752, -14592, 11776, -4864, 4608, -2816, -5120, 2560, -768, 6144, -4608, 3584, -11776, 13312, -12800, 16384, -14592, 6400, -3584, 256, 8448, -10752, 7680, -13312, 12800, -7168, 12032, -13824, 8192, -12544, 13568, -6400, 3584, -1024, -8704, 14592, -13824, 17664, -19968, 11776, -11520, 13312, -5376, 5376, -9472, 1792, 256, 768, 7424, -14592, 14336, -18944, 23040, -16896, 12032, -13056, 4096, 1536, 2560, 2560, -7424, 2304, -8192, 14848, -12032, 15104, -21504, 16640, -12544, 13312, -6144, -4608, 3584, -7680, 15616, -9984, 7936, -14592, 9984, -9728, 17152, -14336, 9472, -11776, 6656, 2560, -3840, 4608, -12544, 11520, -6912, 10752, -9472, 2816, -6144, 7680, -3840, 5376, -8704, 3840, -1280, 2816, 1280, -6144, 2816, -4096, 7680, -4096, 1536, -5120, 1792, 768, 2816, -2304, -1280, -1536, 1024, 4096, -3840, 2304, -7424, 5632, -1536, 3584, -1536, -4096, 2304, -3072, 7168, -5632, 3840, -6912, 5632, -2816, 5376, -5888, 1280, -2560, 2048, 4352, -5632, 4864, -10752, 10496, -7936, 9984, -9472, 5120, -5120, 4864, -768, -1792, 512, -4352, 6912, -5120, 7680, -11008, 7680, -8704, 9728, -6144, 3328, -3328, -256, 4096, -4096, 4864, -9216, 7168, -5376, 7680, -5632, 1792, -4352, 2816, 512, 256, 256, -4864, 5632, -5376, 8192, -8704, 4608, -5376, 4352, 1536, -2048, 1280, -6400, 5376, -3328, 6144, -6144, 3072, -5632, 6144, -2816, 2560, -3584, -1792, 3840, -2816, 7168, -9216, 5376, -7680, 7680, -2560, 2560, -3328, -1280, 1536, -512, 3584, -5632, 3840, -6400, 8448, -5632, 5888, -7936, 2816, -1536, 2048, 2816, -5376, 3584, -7168, 8192, -5888, 6400, -7936, 4864, -3840, 4864, -1792, -1792, 256, -3328, 6656, -4864, 6144, -9472, 6400, -6144, 7680, -4608, 1536, -2304, -512, 4352, -4096, 4352, -8704, 6912, -4864, 7168, -5376, 1536, -3840, 2560, 1024, 0, 512, -5120, 5632, -4864, -5376, 0, -768, -768, 512, 256, -256, 512, -512, -256, 1024, 768, -768, -3840, -5376, -5120, -5888, -10752, -11520, -7936, -6912, -4352, -2048, 2304, 7424, 10496, 11264, 8448, 5120, 3328, 1536, 3072, 4096, 6400, 11008, 11264, 8448, 8448, 8960, 3840, -1280, -768, 2048, 4096, 2048, -2560, -1536, 2048, 1024, -1024, 256, -4608, -9728, -11008, -13056, -13824, -14080, -18176, -21760, -17408, -14848, -15616, -12800, -8448, -6912, -3840, -1280, 5632, 17152, 25600, 27904, 29184, 28160, 23296, 17664, 12800, 9472, 8960, 11776, 12288, 9472, 9216, 3584, -6144, -9728, -10752, -9728, -9728, -15104, -23296, -22016, -14592, -11264, -8192, -3840, -6656, -11264, -7680, -7680, -7680, -4096, -7936, -12800, -8704, -11008, -15104, -12544, -11264, -13312, -15872, -17664, -12800, -1024, 12032, 21248, 26880, 30720, 28416, 22528, 18432, 14080, 14592, 19456, 17664, 15104, 14080, 10496, 2560, -4608, -8192, -7168, -4864, -9216, -17408, -19456, -18432, -18176, -11776, -8960, -12032, -11008, -11008, -15616, -12288, -7168, -6400, -5632, -4864, -5888, -3840, -1792, 768, 1024, -2048, -7168, -9472, -1280, 10752, 18432, 27392, 32512, 31232, 29952, 23040, 12288, 9472, 12288, 13056, 13824, 14336, 11008, 6144, -2048, -9472, -8448, -2816, -7168, -14080, -15616, -19200, -19200, -13056, -14848, -14080, -8448, -8448, -10496, -8960, -7680, -5376, -4096, -4352, -6144, -6656, -5120, -4608, -4352, -3072, -9216, -18432, -16640, -11520, -1536, 13568, 22528, 27136, 30464, 27392, 18176, 13312, 12800, 15104, 19200, 22272, 21760, 19456, 11008, -256, -1792, 2304, -256, -3328, -8704, -17664, -20480, -18944, -20480, -18688, -16640, -17152, -16640, -14336, -11264, -8448, -5888, -4608, -6144, -6400, -4096, -5120, -2304, -256, -5376, -9728, -14080, -16384, -10240, 768, 9984, 20992, 28928, 29184, 24320, 18176, 13824, 14336, 17408, 19456, 22272, 24064, 14592, 2560, -2304, -4352, -4352, -3840, -8960, -15360, -19200, -22784, -23552, -21760, -19456, -18176, -18944, -17920, -13568, -10496, -5120, -2304, -2304, 1024, 1024, 2560, 8448, 9728, 6400, 3840, -4352, -11008, -8448, -3840, 768, 10240, 19712, 24064, 23296, 17664, 9472, 7936, 8448, 9472, 17408, 24576, 20992, 13568, 6400, 2048, 5632, 7168, 2304, -2304, -6912, -11776, -14336, -16640, -15872, -15616, -15360, -13056, -13056, -9984, -6400, -5888, -2816, -768, -3840, -2560, 1280, 3072, 5120, 4608, -2816, -10496, -13312, -12032, -8704, -512, 8448, 16640, 20992, 17920, 13056, 11520, 7168, 5376, 12544, 18944, 22016, 18944, 8448, 1280, 2560, 3584, 1792, -2560, -7168, -11520, -17152, -17408, -18688, -19456, -16896, -16896, -16640, -11776, -9984, -7936, -2304, -768, -1536, 256, 2048, 5632, 10496, 12544, 8448, 2048, -4096, -8704, -7680, -4352, 1792, 12544, 18688, 16384, 16128, 12800, 4864, 1280, 3328, 8192, 15872, 16640, 9472, 2048, -1280, 1024, -256, -2048, -3840, -9216, -12800, -14592, -18176, -16640, -13568, -14848, -12544, -9472, -10240, -7168, -2560, -768, 0, 512, -512, 1280, 7680, 10496, 9216, 5632, -1792, -8448, -9984, -11776, -7680, 3840, 11264, 14336, 18432, 16640, 11264, 5376, 512, 3840, 10752, 15104, 12544, 4608, 512, -768, -1024, 0, -2560, -6400, -8704, -13312, -16640, -15104, -14336, -12800, -9472, -8448, -8448, -6400, -3072, -512, 2560, 3072, 768, 1536, 6912, 10752, 13312, 11008, 4096, -768, -6144, -12288, -10496, -2816, 4096, 12288, 17152, 19968, 19200, 12544, 5376, 3328, 9216, 16384, 16128, 12032, 6400, -256, -512, 512, -3072, -4608, -7168, -13568, -16640, -18176, -19456, -17920, -14080, -13568, -12544, -10496, -8960, -6144, -256, 1280, 256, 1024, 2048, 7168, 13056, 11008, 6656, 4608, -3584, -10752, -13056, -12544, -5888, 1280, 7936, 14080, 17152, 14848, 6656, -512, 2816, 8960, 12544, 14080, 8960, 2048, 768, -512, -1280, -1536, -3328, -7680, -9728, -12544, -15616, -14336, -11520, -11008, -9216, -7936, -9472, -6400, -1792, 256, 1536, 256, -2560, 2816, 8448, 7424, 6912, 4352, -1536, -8704, -14848, -17152, -14592, -8704, -1024, 5376, 12800, 16128, 9472, 2816, 2048, 4352, 11520, 16128, 14080, 9984, 6656, 3072, 2816, 2560, -256, -2816, -4864, -8960, -13056, -13312, -13312, -11520, -8960, -9216, -10496, -7936, -6144, -2304, 2304, -768, -3072, 512, 4864, 8448, 10240, 9472, 6400, -768, -7680, -13056, -15104, -10752, -6144, -768, 9728, 14848, 13056, 8192, 2048, 512, 6400, 11520, 12800, 12544, 8960, 4608, 4096, 4864, 2560, 2304, 1024, -3328, -6912, -9216, -11520, -9216, -6144, -8192, -7424, -7936, -8448, -2560, 1536, 256, -1024, -1536, 1024, 4864, 7680, 9472, 7680, 3072, -3328, -12288, -15104, -14592, -14336, -8960, 512, 7936, 12288, 10496, 3072, -512, 1792, 6400, 10496, 13312, 11264, 7424, 6400, 5632, 4608, 5120, 3840, 256, -1536, -6656, -9728, -7168, -6656, -5376, -4352, -7936, -8448, -4864, -1024, 0, -2048, -4096, -3840, -2816, 2304, 4864, 5632, 6144, -512, -8704, -12544, -15616, -17920, -14592, -8192, 1024, 9728, 11776, 6656, 1280, -256, 1792, 7424, 11520, 11264, 9728, 8192, 5888, 6912, 7680, 5888, 6144, 3584, -2048, -4096, -6144, -6144, -3072, -2560, -4864, -6912, -6656, -2304, -512, -1024, -1536, -4096, -3584, -512, 2048, 5888, 8704, 4352, -1536, -6656, -12032, -15616, -15872, -12800, -4608, 6656, 12800, 12288, 7936, 3072, 1536, 6144, 10240, 11264, 13056, 10240, 7424, 8704, 7168, 6912, 8192, 5120, 1792, -1280, -5888, -6656, -4864, -2304, -3072, -6400, -6400, -4352, -2048, 256, -1024, -3328, -3072, -4096, -2304, 3328, 6656, 5888, 2048, -3328, -9472, -14080, -18176, -19968, -15104, -4608, 4096, 8960, 8704, 2048, -768, 1024, 3328, 7936, 10240, 8704, 8704, 7424, 5888, 7680, 7936, 6912, 5376, 1792, -1536, -5376, -5376, -2560, -2560, -4864, -6144, -7168, -4352, -1536, -2048, -2304, -2304, -4864, -5376, -1280, 3072, 5888, 5632, 1280, -4096, -8704, -14080, -20480, -19968, -14336, -5632, 4608, 8448, 6144, 3584, 768, 1792, 6400, 7936, 9472, 10496, 8448, 7424, 7424, 8192, 8448, 7680, 6144, 1792, -4096, -5632, -4608, -3840, -3584, -6144, -7936, -5632, -3328, -3072, -2048, -1536, -4608, -6912, -5632, -1536, -1280, -256, -256, -256, 256, 512, 1792, 3328, 4864, 2560, -3072, -7936, -3328, 4352, 7424, -1024, -7424, 6144, 13568, 4608, 23552, 3840, -3840, 5888, 3328, -8960, -13312, 32512, 2304, 768, -2304, 7936, -16128, -16384, -1280, -12800, 3584, 8448, -7424, -10752, 0, 11008, 9984, -3840, -15104, -11520, 768, 8448, 3072, -8960, -2560, 13056, 4608, 12544, 14080, -7168, 4096, 1024, 768, -16384, 13824, 13568, -3072, 0, 1280, -1024, -18432, -1792, -7936, -3584, 6656, -512, -9472, -3584, 4352, 8960, 1024, -8448, -11520, -3072, 3840, 5376, -4096, -5888, 5632, 7168, 3072, 14080, -1792, -512, 1792, 1792, -8704, -2560, 16640, -1024, 256, -1280, 3584, -11776, -7168, -2304, -7424, 3328, 3328, -5888, -5888, 1024, 6912, 4608, -4352, -9984, -6400, 1280, 5120, 0, -6656, 256, 8704, 1792, 10496, 6144, -5120, 2816, 256, -1536, -11520, 13568, 5632, -1536, -1024, 2304, -4352, -13312, -1024, -7680, -1536, 5120, -2304, -7424, -2048, 4608, 6912, -512, -8448, -9216, -1536, 4096, 3328, -5120, -4096, 6912, 4864, 4608, 12544, -4352, 768, 512, 1536, -10752, 2304, 14080, -2304, 256, -768, 2304, -13824, -4864, -4096, -6144, 4096, 1792, -6912, -4864, 2048, 7168, 3072, -5632, -10240, -5120, 2048, 4864, -1792, -6400, 2304, 7936, 1792, 12288, 2304, -3584, 2304, 512, -4352, -8960, 15872, 2304, -512, -1536, 3328, -7680, -11264, -1024, -7936, 512, 4608, -3840, -6912, -768, 5632, 6144, -2048, -9216, -8192, -512, 4352, 2048, -5888, -2304, 7936, 3328, 7168, 10240, -5376, 2048, 256, 768, -12032, 7424, 11008, -2304, 0, 256, 256, -14592, -2816, -5632, -4352, 4864, 512, -7168, -3584, 3072, 7424, 1792, -6912, -9984, -3584, 2816, 4352, -3328, -5632, 4352, 6912, 2560, 13056, -1024, -1792, 1792, 1280, -6912, -4864, 16384, -256, 256, -1536, 3584, -10496, -8704, -2048, -7680, 2048, 3840, -5120, -6144, 512, 6400, 5120, -3584, -9728, -6912, 512, 4608, 512, -6400, -256, 8448, 2304, 9472, 7424, -5376, 2816, 0, -768, -11776, 11776, 7424, -1792, -512, 1792, -2304, -13824, -1536, -6912, -2560, 5120, -1024, -7168, -2304, 4096, 7168, 256, -7680, -9472, -2048, 3584, 3584, -4608, -4352, 6400, 5632, 4096, 12800, -3328, 256, 1024, 1280, -9472, 0, 15104, -1792, 512, -1024, 3072, -12544, -6144, -3328, -6656, 3328, 2816, -5888, -4864, 1536, 6912, 3840, -4864, -9984, -5376, 1536, 4608, -1024, -6144, 1792, 8192, 2048, 11520, 3840, -4096, 2560, 512, -3072, -9984, 14848, 4096, -768, -1280, 2816, -5632, -12288, -1024, -7680, -512, 4864, -2560, -6656, -1024, 5120, 6400, -1280, -8704, -8448, -1024, 4096, 2560, -5376, -2816, 7680, 4096, 6400, 11008, -4864, 1792, 256, 1024, -11264, 5120, 12544, -2048, 256, -256, 1536, -13824, -3840, -4864, -5120, 4352, 1536, -6656, -3840, 2560, 7424, 2304, -5888, -9984, -4096, 2304, 4352, -2560, -5632, 3840, 7424, 2560, 12800, 512, -2560, 2048, 768, -5632, -6656, 16128, 1280, 0, -1536, 3584, -8704, -9984, -1536, -7680, 1024, 4352, -3840, -6144, 0, 6144, 5632, -2816, -9216, -7168, 256, 4352, 1280, -5888, -768, 8192, 3072, 8704, 8448, -5376, 2560, 0, 0, -11776, 9984, 9216, -1792, -256, 1024, -768, -13824, -2304, -6144, -3584, 4864, 0, -6656, -2560, 3584, 7168, 1024, -6912, -9472, -2816, 3072, 3840, -3840, -4608, 5632, 6144, 3584, 12800, -2304, -512, 1280, 1280, -8192, -2048, 15616, -768, 512, -1280, 3584, -11264, -7424, -2560, -6912, 2560, 3328, -5120, -5120, 1024, 6656, 4352, -4096, -9472, -5888, 1024, 4608, -256, -5888, 1280, 8192, 2304, 10752, 5120, -4608, 2816, 256, -1792, -10496, 13568, 5632, -1024, -768, 2304, -3584, -12800, -1536, -6912, -1792, 4864, -1536, -6656, -1280, 4608, 6656, -512, -7936, -8704, -1536, 3584, 2816, -4864, -3072, 7168, 4864, 5632, 11520, -4352, 1024, 512, 1280, -10240, 2816, 13824, -1536, 512, -768, 2560, -13056, -5120, -4096, -5888, 3584, 2304, -5888, -3840, 2048, 7168, 3072, -5120, -9728, -4608, 1792, 4352, -1792, -5632, 3328, 7680, 2560, 12032, 1792, -3072, 2304, 512, -4352, -7936, 15616, 2560, 0, -1280, 3328, -6656, -11008, -1536, -7424, 0, 4608, -2816, -5888, -256, 5632, 5888, -2048, -8704, -7680, -256, 3840, 1792, -5632, -1280, 7936, 3584, 7680, 9472, -5120, 2304, 0, 512, -11264, 7680, 10752, -1792, 256, 512, 512, -13568, -3072, -5376, -4352, 4352, 1024, -6400, -2816, 3072, 7168, 1536, -6400, -9472, -3328, 2560, 3840, -3328, -4608, 5120, 6656, 3328, 12544, -1280, -1280, 1536, 1024, -6912, -4096, 15872, 256, 512, -1280, 3584, -9728, -8704, -2304, -7168, 1536, 3840, -4096, -5120, 768, 6400, 4864, -3328, -9216, -6400, 512, 4096, 256, -5888, 768, 8192, 2816, 9728, 6400, -4864, 2816, 0, -1024, -11008, 11776, 7424, -1024, -512, 1792, -2048, -13056, -2048, -6400, -2560, 4608, -512, -6400, -1792, 4096, 6912, 0, -7168, -8960, -2048, 3072, 3072, -4352, -3328, 6656, 5376, 4864, 11776, -3584, 512, 768, 1024, -9216, 512, 14592, -1024, 768, -1024, 3072, -11776, -6400, -3328, -6400, 2816, 3072, -5120, -4096, 1792, 6912, 3584, -4608, -9472, -5120, 1280, 4096, -1280, -5376, 2560, 7936, 2560, 11520, 3072, -3584, 2560, 256, -3072, -9216, 14592, 4096, -256, -1024, 2816, -5120, -11776, -1536, -7168, -1024, 4608, -2048, -5888, -768, 5120, 6144, -1280, -8192, -7936, -1024, 3328, 2048, -5120, -1536, 7424, 4352, 6912, 9984, -4864, 1792, 0, 768, -10752, 5376, 12032, -1536, 512, 0, 1792, -13056, -4352, -4608, -5120, 3840, 1792, -5888, -3072, 2560, 7168, 2048, -5632, -9472, -3840, 2048, 3840, -2560, -4864, 4608, 6912, 3328, 12032, 0, -2048, 2048, 768, -6144, -5120, 13312, -9216, -512, 0, -512, 768, 1280, -1024, -7168, 5632, -11008, 9216, -3328, -32512, -11008, 512, -4608, 32256, 19968, -32512, -12288, 17408, -18944, -17152, 8448, 15872, 21248, 10752, -8192, -11776, -17920, -6656, 29440, 5376, -16896, 18432, 13312, -6912, 11264, 12800, 12800, 15616, 7168, -3072, 768, -15104, 12544, 768, -4864, 9984, 24064, 4096, 7936, 1536, 7424, 768, -25600, -256, -1024, -15360, 4864, 1792, -7424, -7168, -9728, -768, -12032, -5120, -5376, -256, 1280, -14080, -3072, -14080, -9984, 6656, 12032, -5632, -2304, -10496, -5376, -4864, -9472, 0, 11520, -14336, 6144, 19200, -12800, -2304, 7936, 7168, 6656, 3328, -768, -3840, -6912, 256, 256, -7936, -2560, 9728, -256, 1792, 11008, 4864, 5376, 10496, 8448, 2304, -4352, -768, -10752, -19456, -7680, -2048, -2304, -256, 5376, 5632, 9728, 8192, 5632, 0, -4608, -8192, -14848, -3072, 1280, -12288, -3328, 16384, 7424, -512, 512, 4864, 11008, 6400, -4864, -9984, -17664, -23552, -3840, 5888, 7680, 7680, 13056, 9472, 8960, 9472, 7680, -6912, -16128, 1280, -7680, -14336, -4096, 6656, 13312, 5120, 3584, 15104, 6912, -2304, 5632, -1024, -5120, -9472, -4352, -8704, -8704, -256, 8960, 6656, 7936, 1280, -4096, 1024, 8448, 5632, 2048, 1280, -7168, -10496, -5120, -2560, -1536, -512, -4096, 3072, 7936, -5888, 1792, -512, -9984, -7168, -3328, 2048, 1280, 4096, -1024, -1536, -4608, -6144, -6912, -12800, -1536, 1280, 3072, 0, -512, -3584, -5888, 1280, -7168, -2560, 512, 7168, 3840, 512, 5632, 6912, 10496, 7936, 512, 3072, 7936, 1280, 3072, -1536, 3840, 10240, 8704, 4608, 6656, 6656, 3072, 8704, 5888, 8704, 7680, 5632, 2560, -6656, -5632, 256, 0, -256, 3072, -1024, -5376, -1280, -1280, -5120, -7936, -6400, -6144, -10752, -11264, -10496, -10496, -9472, -7424, -7168, -7424, -10240, -4352, -5376, -9728, -10752, -9728, -10240, -9216, -3328, -3584, -2048, -3840, -1792, -1536, 1280, 3072, -256, -4352, -256, 2304, 512, 4096, 7680, 6912, 9472, 9216, 9728, 9216, 9216, 4864, 11520, 11520, 8448, 6656, 8448, 7168, 9216, 7936, 4352, 3072, 5632, 2816, 2816, 4352, 1280, -3328, 1536, 2560, 512, -1536, 512, 2304, 3840, -1536, -2048, -5888, -11264, -768, -2816, -8960, -6400, -8960, -5888, -5376, 0, -2816, -5376, -4352, 2816, -1536, -2816, -4352, -8448, -4096, -4096, -1024, -1792, -1792, -2304, -1024, 256, 256, -768, 1536, 1792, 1024, -4352, -2816, -1536, -1024, 256, 768, 1536, 1024, 1280, -1024, 4352, 1792, 768, 2304, -5120, 0, -1792, -768, -1280, 1024, 2304, 4096, 512, 768, 2048, 3840, 3840, 256, -768, 2048, -256, 1280, 3584, 1792, 1024, 2048, -2048, 512, -768, 1280, 2816, 1280, 768, -1024, 2560, 4352, 3328, -2816, -1280, 256, -768, 0, -1536, -3072, 512, -768, 3328, -1280, -6400, -3840, -1792, 1024, 256, -2048, -1024, -3072, -4096, 768, 2304, -1536, 768, -5376, -1024, 1024, -3584, 256, -256, -512, 768, -2048, -1280, 0, 1792, -512, -768, -256, 768, -2304, 1280, -1024, -4352, -256, 2304, 768, 1792, 256, -1024, -768, 1280, 512, -1792, -2304, 3072, -1536, -3584, -4096, 512, -256, 4096, 512, 512, 1792, -1536, -6656, 768, -512, -1024, -512, 2560, 768, -1792, 768, 2048, 2304, 1280, 1024, 256, -1280, -1280, 2816, 2048, 1792, 2816, 3072, -256, -1280, -4096, 3328, 1792, 512, 2816, 1024, -1024, 2304, -2048, -2048, 3584, 2816, -2048, 0, -256, -1280, -512, -256, -2560, -1280, -2304, -2304, -4096, -3072, -2048, -4096, 1280, -2560, -1024, -2816, -768, 256, 0, -768, -1280, -3328, -2304, -512, -2048, 1280, -2304, -1792, -512, 512, -2816, -1792, 3328, 2048, -768, 512, 1792, -512, -256, 1280, 0, 2816, 1536, 3328, 3840, 256, -1024, 2304, 1280, 768, 2048, -768, -1024, 4096, 1024, 2816, 2304, 0, 2048, 256, -1536, -1280, -4608, 768, 1792, -4608, -1024, 0, -768, -768, -1536, -1024, -1280, -1280, -2560, -512, -2304, -1280, -512, -1024, -2816, -512, 256, -1280, -512, 2816, -1536, -2304, 256, 1024, -1536, -256, -1280, 256, 512, 2304, 1280, 0, 1024, 1024, -512, 1792, 0, -2560, 1280, 512, -768, 0, -1536, 1792, -1024, -768, 1536, -256, -1536, -256, -256, 512, -512, -1536, -768, 0, 2048, -1536, 1024, -256, -1280, -768, 768, 256, -1280, -1536, -512, -768, 1280, 1536, 0, 1792, -768, 768, -256, 0, -512, 2304, 256, 256, -768, 1024, 1280, -1280, 512, -512, 512, -2816, -512, -1024, 2816, 1024, 1280, 0, -1280, -3072, -1536, -1280, -1280, 768, -512, -512, 512, 512, 256, 0, -256, -2048, -1280, -1280, -768, 512, -256, 768, -256, 768, 0, -256, 0, -256, 256, 256, -1024, -1024, 512, -512, 256, -1536, 256, 512, 1024, 512, 512, -1280, -256, 1536, -768, -256, -1024, 2816, 768, -2304, -512, -1536, -768, 512, 1024, 512, 256, 512, 1024, 768, -1536, -1024, -768, -512, 0, 512, -512, 1280, 512, -256, 768, -2304, -768, -768, -1024, -1024, -256, 0, -512, 1792, 768, 256, 256, -512, -1024, -512, -768, -512, -1024, 512, 1024, -256, 512, 768, 0, 768, -256, 0, -512, -512, -768, 256, -256, -1024, 1280, -256, 1280, 0, -768, -512, -256, -1024, 768, -256, -768, -512, -512, -256, 0, 0, 256, -256, 0, -512, -512, 0, -768, -256, 0, 0, 256, 256, -512, -256, 256, -768, 256, 512, 0, -256, 0, -256, 256, 1280, -512, 256, -768, -768, -256, -768, 0, 256, 768, 512, -256, -256, -512, -512, -256, 256, 0, -256, -512, -512, -512, -768, -768, -768, -512, -512, -512, -512, -512, -512, -512, -256, 0, 256, 256, -512, -512, 0, 0, 512, -768, -4096, -5632, -5120, -7168, -8960, -7936, -4352, 4864, 8448, 9216, 8448, 8704, 10240, 9216, 6400, 4608, 5120, 4608, 3584, 4352, 3072, 3584, 2560, -6144, -9216, -6912, -9728, -14080, -17664, -16896, -12032, -8448, -3328, 768, 1280, 2560, 5632, 6400, 3840, 7168, 11008, 10496, 13056, 14336, 14848, 14848, 7936, -4608, -13312, -16384, -18176, -23552, -26880, -25088, -19712, -12800, -4352, 5888, 15104, 21760, 25344, 24064, 19456, 14080, 3584, -2304, -1280, -1792, -4608, -4352, -8960, -13568, -13568, -8448, -5888, -8448, -9216, -3840, 4352, 8192, 6144, 3072, 4864, 9472, 13824, 12544, 9728, 5376, -3584, -11264, -7680, -5632, -3840, 1280, 2048, -256, -6656, -10752, -11776, -12544, -13056, -9472, -4352, 256, -1024, -4864, -1024, 11520, 21504, 23296, 20224, 14592, 768, -7680, -7424, -8960, -6400, -2048, -1536, -6656, -15616, -19200, -18688, -19712, -18432, -13824, -4864, 2304, 1536, -2560, 768, 12032, 21760, 23552, 26368, 23552, 11520, 5376, 1536, 1024, 4096, 6912, 6912, -256, -12288, -17664, -19968, -20480, -21504, -18432, -8448, -2560, -6144, -10496, -5120, 10240, 20992, 25344, 31488, 26112, 17664, 12544, 7680, 6912, 8704, 10752, 10496, -512, -14848, -24576, -27648, -26368, -27136, -21248, -9472, -2560, -4608, -9728, -4608, 10240, 16640, 23552, 28160, 21504, 11264, 256, -6656, -5888, -1792, 5376, 8192, 1792, -9984, -19968, -21504, -20224, -20992, -15616, -4864, 1280, -3584, -13312, -6400, 6400, 15104, 26112, 32512, 29696, 22016, 10240, 3328, 1024, 2304, 6912, 7424, 1024, -12032, -22528, -24064, -22272, -21248, -14336, -4608, 3840, -3328, -12544, -7680, -512, 7424, 17664, 22272, 20480, 12800, 2304, -3840, -6912, -2560, 4608, 11264, 9216, -2304, -11520, -13568, -13568, -11776, -8448, 1536, 7936, -2048, -9216, -7168, -2816, 5376, 13824, 19456, 19456, 11264, 1024, -8448, -13568, -11520, -4608, 3328, 2560, -8960, -15872, -17920, -15616, -11264, -4864, 9728, 16128, 7680, 2304, 1024, 2304, 8960, 15360, 20736, 19200, 13056, 3584, -6400, -11264, -9472, -2304, 7424, 6144, -2816, -10496, -15104, -13056, -13824, -8448, 5888, 8960, 1536, -3328, -7168, -4608, 2048, 11008, 18688, 19456, 16128, 8448, -256, -5376, -5632, 2560, 11008, 8960, 1280, -8192, -12032, -13056, -17408, -11264, 1536, 3584, 0, -5376, -8704, -6400, 0, 9472, 16640, 18688, 16384, 8960, 1280, -5632, -6400, 2816, 10240, 9984, 3328, -5120, -7168, -10752, -16384, -8192, 1536, 3840, -256, -6400, -9984, -9984, -4096, 4864, 11264, 14848, 13568, 6912, -512, -9984, -9728, -512, 7680, 10240, 3328, -4096, -4864, -11520, -15360, -7424, 1536, 4352, 256, -5376, -10240, -11264, -6144, 2304, 9728, 14848, 13056, 9728, 2048, -7936, -7424, 0, 8704, 11264, 2304, -2816, -5888, -14848, -17664, -10752, -1536, 2304, 0, -4096, -8448, -9216, -3072, 4864, 14080, 18432, 17408, 14848, 4608, -5632, -6400, -1536, 7424, 7936, 512, -1280, -5888, -14592, -17664, -11520, -2048, 3072, 2560, 0, -5632, -6144, -1792, 5120, 13312, 15616, 16640, 15104, 5376, -3840, -7168, -2816, 6656, 5120, 512, -512, -5632, -14336, -18176, -12544, -3584, 768, 2048, -1280, -6656, -7168, -4864, 3584, 10752, 13824, 18176, 17152, 9728, 2048, -2816, 4096, 12032, 9472, 6656, 4608, -2560, -13056, -18944, -15104, -8960, -4864, -3072, -6144, -9472, -11264, -8704, 0, 6144, 11264, 17152, 16384, 11008, 768, -4608, 2816, 8960, 7168, 5632, 4608, -1024, -12032, -17408, -14080, -8704, -2816, -1792, -3840, -6912, -11008, -8192, -256, 4608, 10752, 14848, 15360, 11008, -2048, -7424, -1536, 2816, 1792, 1024, 1024, -4352, -15104, -19200, -16896, -10496, -3328, -768, 256, -2816, -7424, -4864, 256, 4864, 10752, 13568, 16384, 11520, -2048, -7168, -2304, 1792, 1024, 1024, 2304, -3328, -13056, -18176, -17664, -11008, -4864, -1792, 768, -2816, -6400, -4352, -512, 5888, 11008, 15360, 19968, 14080, 256, -4864, -1280, 2048, 768, 1792, 3328, -2048, -10496, -16896, -17152, -10240, -4864, 768, 4096, 256, -1792, -1280, 2560, 8704, 11776, 17152, 22272, 15872, 2816, -3328, -256, 2048, 1024, 3840, 5120, 256, -8448, -16384, -16640, -12288, -7680, -512, 1536, -1280, -3584, -4608, 256, 5376, 8192, 15872, 22016, 16896, 5120, -768, 1536, 1792, 1280, 4096, 5120, 1792, -7424, -15872, -16640, -15104, -9984, -3328, -1280, -2048, -5632, -6912, -1536, 1792, 4352, 12544, 18944, 14848, 3584, -1280, -512, -1024, -768, 1792, 3584, 1536, -8192, -15104, -16896, -16128, -10240, -4096, -512, -512, -4864, -5120, -256, 1536, 4608, 12544, 19712, 15872, 5376, 768, -256, -1280, -512, 1280, 4608, 2560, -6656, -12800, -16640, -16384, -11008, -6144, -1280, -1536, -6144, -5888, -2048, -512, 2560, 11520, 19200, 15360, 6400, 1536, -1024, -1024, -1280, 768, 5120, 2048, -5120, -11008, -15360, -14848, -11520, -6144, 256, -256, -3840, -3072, -256, 768, 4096, 13568, 21248, 17920, 10752, 4864, 2304, 1792, 768, 4096, 7424, 4352, -1792, -8960, -14080, -14336, -12544, -6144, 512, -256, -2816, -1792, 768, 1024, 4096, 14080, 21248, 19200, 12800, 6400, 3840, 1536, 0, 3328, 5376, 3328, -2304, -10240, -14848, -16896, -15872, -8960, -2816, -2816, -4608, -3328, -768, -1792, 2304, 12544, 19200, 18944, 13056, 7168, 4864, 1280, 256, 3328, 5120, 4096, -768, -7168, -12288, -15872, -15616, -9472, -4096, -3328, -5120, -3840, -3072, -4864, -1280, 5376, 12800, 15616, 12032, 7168, 3840, -256, -1536, 0, 2304, 3584, 256, -4864, -9472, -14080, -14336, -9728, -4096, -2816, -3328, -2304, -2304, -4096, -2048, 4608, 12288, 15104, 11264, 7168, 2304, 3840, -768, 512, -1280, 768, 768, 1024, 256, 1792, -512, 1792, -1024, 512, -31744, -9472, 8448, -12288, 1792, -6912, 2048, -3584, 19712, 6656, -2304, 6656, 1792, 5120, 2560, 3328, 2048, 2304, 1792, 1024, 1280, 512, 768, 512, 256, -256, 0, -768, -512, -1280, 256, -2560, 2816, 17920, -1536, 5376, 1280, 6912, -512, 10496, -3840, -15616, -16896, -32768, 0, -12288, -5376, -11776, -1536, -14080, 5888, 13568, -1536, 2816, 512, 3584, 2816, 2560, 2816, 2048, 2304, 2304, 2048, 1280, 2048, 1280, 1536, 1280, 1536, 512, 1792, -1024, 1536, 1280, -5888, 15872, 7424, 6144, 2048, 8448, 1024, 8192, 9216, -7680, -4096, -31744, -14848, -9984, -4608, -13056, -768, -11008, -10240, 13568, 4864, 3072, 1024, 2304, 3072, 3328, 2560, 2816, 2304, 2048, 2816, 1536, 1280, 2048, 1536, 768, 2304, 256, 1792, 512, -1280, 5632, -8448, 5120, 9472, 8960, 1792, 7424, 3584, 2048, 13312, -1280, 4352, -16384, -21504, -17920, -3840, -14080, -5888, -3072, -18432, 256, 7168, 4096, 2048, 1536, 1792, 3072, 2560, 2048, 2816, 1536, 2048, 2560, 1280, 1024, 2560, 256, 2048, 1024, 512, 2560, -3840, 6656, -4096, -2304, 3584, 10752, 4352, 4864, 7424, -768, 10752, 3584, 7168, -2048, -11520, -23552, -9472, -10496, -13824, 0, -13568, -12288, 512, 4608, 2560, 2048, 1024, 2048, 3072, 2048, 2560, 2560, 1536, 2304, 2560, 512, 2560, 1280, 768, 2304, -512, 4608, -4096, 4352, 768, -2304, -3072, 6656, 7168, 3328, 8960, 768, 6912, 4864, 7936, 4352, 1024, -15360, -17152, -8448, -16896, -5632, -5632, -14848, -9728, 512, 2816, 2304, 1792, 1024, 2304, 2560, 2048, 2560, 2304, 1280, 3072, 1280, 1280, 2304, 512, 2816, -1280, 5376, -2048, 1024, 2560, 1280, -4352, -256, 7168, 2816, 8704, 3328, 5120, 4352, 7168, 6144, 6912, -1536, -15616, -10496, -14592, -13056, -4352, -9216, -14336, -8192, -256, 1792, 2048, 1280, 1536, 2048, 2560, 2048, 3072, 1536, 2304, 2304, 1280, 2304, 256, 3840, -1792, 3840, 1280, -512, 1024, 3584, -768, -4608, 3840, 2048, 7168, 5376, 5120, 4096, 5888, 5888, 7424, 7680, -5120, -9728, -11520, -16128, -9728, -5888, -11008, -13568, -7424, -1280, 1280, 1280, 1280, 1280, 2304, 1792, 2816, 2048, 2048, 2560, 1280, 3072, -512, 4096, -256, 1024, 2816, 1024, -768, 2048, 3840, -4096, 0, 256, 4096, 5888, 5888, 4352, 5120, 5376, 5376, 9984, 4864, -3584, -7168, -13312, -14848, -8448, -7168, -12032, -12800, -7680, -1536, 512, 1280, 1024, 1536, 1536, 2304, 2560, 1792, 3072, 768, 3840, 0, 2560, 2048, 256, 1536, 2816, 512, -1024, 5120, -256, -1536, -1280, 1024, 3840, 6144, 5120, 4608, 5888, 3840, 7680, 9728, 3328, -1536, -6912, -14336, -13312, -7680, -8704, -12288, -12800, -7168, -2048, 512, 768, 1280, 1280, 1536, 2816, 1280, 3328, 768, 3072, 1536, 1280, 2560, 1280, 512, 1792, 3328, -2048, 2560, 2816, 0, -1536, -1024, 768, 4352, 5888, 4096, 6144, 4608, 4352, 9216, 8192, 3328, -256, -7680, -14592, -11520, -7936, -9216, -13056, -12544, -7168, -1792, -256, 768, 1536, 512, 2816, 1280, 3072, 1536, 2304, 2560, 1280, 2048, 2048, 1280, -256, 4096, 256, -256, 2816, 2304, -256, -1280, -1280, 1024, 5120, 4352, 5120, 6144, 3584, 5888, 9472, 7424, 4096, 512, -8448, -13568, -10752, -7680, -9984, -13312, -12544, -6912, -2304, -768, 1280, 0, 2048, 1280, 2560, 2048, 1536, 2560, 1536, 1792, 1536, 2816, -768, 2048, 2816, 0, 512, 2816, 2048, -256, -1280, -1792, 2304, 4608, 4096, 6144, 5120, 3584, 6912, 8960, 6912, 5376, 256, -8448, -12800, -9728, -8192, -10752, -13568, -12288, -6400, -3584, -256, -512, 1024, 768, 1536, 2304, 1280, 2304, 1792, 1792, 1024, 3072, 1024, 256, 2560, 1536, 512, 1536, 2560, 1024, 0, -1536, -512, 2816, 3584, 4608, 5632, 4352, 5120, 8192, 8704, 7168, 5120, 0, -6656, -9216, -8704, -9472, -11520, -13824, -11264, -7680, -3328, -2048, -768, 256, 512, 1536, 1024, 1792, 2048, 2048, 512, 2048, 2560, 256, 1024, 1536, 1280, 1280, 2304, 1536, 256, -768, -1280, 768, 2560, 3584, 4608, 4608, 4352, 6656, 8960, 8960, 7424, 4352, -256, -4352, -6144, -8192, -10496, -12800, -13056, -11264, -7168, -4608, -3072, -1280, -512, 512, 768, 768, 1536, 2304, 1024, 768, 2304, 1536, 512, 512, 1024, 1280, 2304, 2560, 1024, -512, -1280, -256, 1280, 2560, 3584, 4096, 3840, 4864, 7680, 9728, 9472, 7424, 3840, 256, -1280, -3584, -7936, -11008, -12800, -13312, -10752, -7424, -5632, -4096, -2304, -768, 0, 0, 512, 1536, 1536, 512, 1024, 1792, 1536, 512, 256, 512, 1536, 2816, 2560, 512, -1280, -1024, 0, 1280, 2560, 3584, 3840, 3584, 5376, 8192, 9984, 9728, 7424, 3584, 1024, 0, -768, -4864, -8192, -10240, -11008, -10496, -9216, -7936, -6400, -4864, -3072, -2304, -2048, -1536, -256, 512, 512, 0, -768, -1024, -256, 768, 1536, 1536, 512, -768, -1536, -512, 512, 512, 256, 512, 1792, 4096, 6400, 8192, 8960, 8960, 9216, 9216, 8448, 6144, 2816, -768, -4608, -8192, -10240, -10752, -10240, -9216, -7680, -6400, -4608, -3072, -2304, -2048, -1280, -256, 512, 512, 0, -768, -1024, -256, 768, 1792, 1536, 512, -1024, -1280, -512, 512, 512, 256, 512, 2048, 4352, 6400, 8192, 8960, 9216, 9216, 9216, 8192, 5888, 2560, -1024, -5120, -8448, -10496, -10752, -10240, -8960, -7680, -6144, -4608, -3072, -2304, -2048, -1280, -256, 768, 512, -256, -1024, -1024, -256, 1024, 1792, 1536, 256, -1024, -1280, -512, -256, 768, 256, 768, 1280, 768, -768, -256, -256, 256, -3840, 256, 256, -1280, -1792, 1792, -512, -1024, 768, -512, -1280, -256, -768, -768, -256, 1536, 768, 512, 768, -6656, -29952, 8960, -2048, -4864, 6144, 14848, -1792, -1536, 6400, -2304, 1792, 1024, 2560, 512, 1792, 1536, 1536, 0, 1536, -512, -256, -768, -768, 2048, 18176, 0, 4352, 6912, 5120, -26112, -29440, 9984, -8192, -4608, -1280, 14848, -3840, -3072, 3328, -2560, -1024, 256, 512, 256, 0, 1536, 512, 256, 512, 0, -1024, 0, -1280, 512, 17152, 2304, 3584, 7168, 7424, -18432, -32256, 6912, -6400, -4864, -3584, 14848, -1536, -2816, 3328, -1280, -768, 768, 768, 1024, 256, 2048, 768, 768, 768, 768, -512, 512, -768, -768, 15872, 4352, 3584, 6912, 8960, -11520, -32768, 2816, -4864, -5120, -5632, 13568, 256, -3072, 2816, -768, -1024, 512, 768, 1024, 256, 1792, 768, 768, 768, 768, -512, 512, -512, -2304, 14592, 5632, 3584, 6400, 9472, -5888, -32000, -2048, -3840, -5120, -7680, 11776, 2304, -3072, 2560, -512, -768, 0, 768, 768, 256, 1536, 1024, 512, 768, 512, -512, 256, 0, -4096, 12800, 6656, 3328, 5632, 9472, -512, -29952, -6912, -3328, -4608, -9216, 9216, 4096, -3328, 2304, -512, -512, -512, 768, 512, 512, 1024, 1280, 256, 1024, 512, -256, 0, 1024, -5120, 11008, 7424, 3840, 5120, 9216, 3584, -26112, -11008, -3840, -4096, -10240, 6656, 5632, -3072, 2048, -512, -512, -768, 768, 256, 768, 512, 1536, 256, 1280, 256, 0, -256, 1792, -5888, 8960, 7936, 4608, 4608, 8448, 6912, -21248, -14592, -5120, -3584, -10752, 3584, 6656, -2304, 1792, -512, 0, -1280, 768, 256, 1024, 256, 1792, 0, 1280, 256, 256, -512, 2560, -6144, 6656, 7936, 5120, 4352, 7680, 9216, -15872, -16640, -6912, -3072, -11008, 512, 7168, -1792, 1536, -512, 0, -1280, 768, 0, 1024, 0, 1792, 0, 1280, 256, 512, -1024, 2816, -5888, 4352, 8192, 5632, 4096, 6912, 10752, -11264, -17152, -9216, -2304, -10752, -2048, 7168, -768, 1280, -256, 256, -1280, 512, 0, 1024, 256, 1792, 256, 1280, 256, 768, -1280, 3328, -5632, 2560, 7936, 5888, 4352, 5632, 11520, -6400, -16896, -11520, -2048, -10240, -4608, 6912, 0, 1280, -256, 256, -1280, 256, 0, 1024, 0, 1536, 512, 1024, 512, 768, -1536, 3584, -4864, 512, 7424, 6400, 4864, 4864, 12032, -2560, -15360, -13824, -2560, -9472, -6912, 6144, 1024, 1024, 0, 256, -1280, 0, 0, 768, 256, 1280, 512, 1024, 512, 1024, -1792, 3840, -4096, -1024, 6912, 6400, 5376, 3840, 12288, 1024, -13056, -15616, -3072, -8448, -8704, 4864, 1792, 1024, 256, 0, -1024, -256, 0, 768, 512, 1280, 768, 768, 768, 1280, -2048, 3840, -2816, -2560, 6144, 6400, 5888, 3072, 11520, 3840, -9984, -16896, -4608, -7168, -10240, 3072, 2560, 1024, 512, 256, -768, -512, 0, 512, 512, 1024, 768, 768, 768, 1280, -2048, 3328, -1536, -3584, 4864, 6400, 6400, 2560, 11008, 6144, -6400, -17152, -6400, -6144, -11520, 1024, 2816, 1280, 768, 0, -512, -768, -256, 256, 512, 768, 768, 768, 512, 1536, -2304, 2816, -512, -4352, 3840, 6144, 6912, 2304, 9984, 7936, -3328, -16896, -8448, -4864, -12288, -768, 2816, 1280, 768, 256, -512, -768, -256, 256, 512, 1024, 768, 768, 512, 2048, -2304, 2304, 768, -4608, 2560, 5632, 7424, 2304, 8960, 8960, 0, -15616, -10496, -4352, -12544, -2816, 2560, 1536, 768, 512, -512, -768, -512, 256, 256, 1024, 768, 1280, 256, 2304, -2304, 1792, 1536, -4608, 1280, 5120, 7424, 2560, 8192, 9728, 2816, -12032, -11520, -4608, -12032, -5120, 1280, 1536, 1024, 512, -256, -768, -512, 0, 256, 1280, 256, 1536, 256, 1792, -1792, 1536, 1536, -4096, 256, 4096, 6912, 2816, 7424, 10240, 5120, -7680, -11008, -5888, -11776, -7168, -512, 1024, 1024, 512, -256, -768, -512, -256, 0, 1536, -256, 1792, 512, 1280, -1536, 1280, 1536, -3840, -768, 3328, 6400, 3072, 6656, 10496, 6656, -3584, -9216, -6656, -11264, -8960, -2816, 256, 1024, 512, 0, -1024, -768, -768, -256, 1792, -512, 1792, 1024, 1024, -1536, 1024, 1792, -3328, -1536, 2560, 5888, 3072, 6144, 10752, 7936, 0, -6144, -7168, -10752, -10240, -4864, -1024, 1024, 512, 256, -1024, -768, -1024, -768, 2048, -768, 1536, 1536, 768, -1536, 1024, 1792, -2816, -2048, 1792, 5120, 3072, 5376, 10496, 8704, -512, -7936, -8704, -7424, -5376, -3072, -768, -1024, -2560, -1792, -1280, -1536, -1024, 1280, 2048, -768, -256, 1792, -256, -2816, -1792, 0, 256, 1536, 4096, 7168, 8448, 8448, 7680, 3328, -256, -6656, -8960, -7680, -6144, -3584, -1280, -1024, -2816, -1792, -1280, -1536, -1536, 768, 2048, -512, -512, 1792, 256, -2816, -2304, -256, 0, 1024, 3584, 6656, 8192, 8448, 8192, 4352, 768, -5632, -8704, -7936, -6400, -4096, -1536, -768, -2560, -2048, -1280, -1536, -1792, 512, 2304, 0, -768, 1536, 768, -2304, -2560, -512, 0, 768, 3072, 6144, 8192, -256, 0, -768, -256, -2048, -1280, -4096, -1280, -3584, -1024, -3328, -1280, -256, -1792, 4096, -4352, 7168, -4096, 12032, 256, 17920, 8960, 24832, 18176, 25088, 16896, 8192, -1280, -18176, -17664, -31232, -17664, -26880, -8448, -17152, -1536, -8960, 512, -3072, -512, 1024, -3072, 4096, -4864, 7424, -4096, 11264, 512, 16896, 9472, 23552, 19456, 24320, 18944, 8448, 1280, -17664, -16128, -31232, -17664, -27136, -9216, -16896, -2816, -8448, -768, -2304, -1792, 1792, -4096, 4608, -5632, 7424, -4352, 10752, 768, 15616, 10240, 22016, 20736, 23296, 20992, 8704, 3840, -17152, -14592, -31232, -17664, -26880, -10240, -16384, -4352, -7424, -2304, -1536, -3072, 2560, -5120, 5120, -5888, 7168, -4352, 9984, 1024, 14336, 10752, 20480, 21760, 22528, 22784, 8960, 6144, -16128, -13568, -30464, -17920, -26624, -11520, -15872, -5632, -6656, -3584, -512, -4096, 3072, -5888, 5120, -6400, 6912, -4096, 8960, 1792, 13056, 11520, 18944, 22784, 21760, 24576, 9728, 8192, -14848, -12544, -29696, -18432, -26112, -12800, -15360, -6912, -6144, -4864, 0, -5120, 3584, -6144, 5120, -6144, 6144, -3584, 7936, 2560, 11520, 12288, 17664, 23552, 20992, 26112, 10240, 9984, -13568, -11520, -28672, -18944, -25600, -14080, -14592, -8448, -5376, -6144, 768, -6144, 3840, -6656, 4864, -6144, 5632, -3072, 6912, 3072, 10240, 12800, 16128, 24320, 20480, 27136, 11008, 11520, -12032, -10752, -27392, -19456, -24832, -15360, -14080, -9728, -4608, -7168, 1024, -6656, 3840, -6912, 4608, -5888, 4864, -2560, 5888, 3840, 8960, 13568, 15104, 24832, 19968, 28160, 12032, 12800, -9984, -9984, -26112, -20224, -24064, -16640, -13312, -11008, -4096, -8192, 1280, -7168, 3584, -6912, 4096, -5376, 3840, -1792, 4608, 4608, 7680, 14080, 13824, 25088, 19456, 28928, 13056, 14080, -8192, -9472, -24576, -20736, -23296, -17920, -12800, -12288, -3840, -8960, 1536, -7680, 3328, -6656, 3328, -4864, 2816, -1280, 3328, 5120, 6400, 14336, 12800, 25344, 19200, 29440, 14336, 15104, -6144, -8960, -23040, -21248, -22528, -19200, -12288, -13312, -3584, -9728, 1280, -7680, 2816, -6400, 2560, -4352, 1792, -512, 2304, 5632, 5376, 14592, 12032, 25344, 19200, 29696, 15616, 15872, -3840, -8448, -20992, -22016, -21504, -20480, -12032, -14336, -3584, -9984, 1024, -7680, 2304, -6144, 1536, -3840, 768, 256, 1280, 6144, 4352, 14592, 11264, 25088, 19200, 29696, 16896, 16640, -1536, -7936, -19200, -22528, -20736, -21248, -11776, -15104, -3584, -10496, 768, -7680, 1536, -5632, 768, -3072, -256, 768, 256, 6656, 3328, 14592, 10496, 24576, 19200, 29440, 18432, 17408, 512, -7424, -17664, -22784, -19968, -22272, -11520, -15872, -3840, -10752, 0, -7424, 768, -5120, -256, -2560, -1280, 1280, -512, 6656, 2816, 14336, 10240, 24064, 19456, 29184, 19712, 17664, 3072, -7168, -15616, -23296, -19200, -22784, -11520, -16384, -4096, -10752, -512, -7168, 0, -4608, -1280, -2048, -2304, 1792, -1536, 6912, 2048, 14080, 9728, 23296, 19712, 28672, 20992, 18176, 5120, -6400, -14080, -23296, -18688, -23296, -11776, -16640, -4608, -10752, -1280, -6656, -1024, -3840, -2560, -1280, -3328, 2304, -2304, 6912, 1792, 13568, 9472, 22528, 19968, 28160, 22272, 18432, 7424, -5888, -12288, -23040, -18176, -23808, -12032, -16896, -5376, -10496, -2304, -6144, -2048, -3328, -3328, -768, -4096, 2304, -2816, 6912, 1280, 13056, 9472, 21504, 20224, 27648, 23808, 18944, 9472, -5120, -10752, -23040, -17920, -24064, -12544, -16896, -6144, -10240, -3072, -5888, -3072, -3072, -4096, -512, -4608, 2560, -3072, 6400, 1280, 12288, 9472, 20480, 20736, 26880, 25088, 19200, 11520, -4096, -9216, -22528, -17408, -24064, -13056, -16896, -7168, -9984, -4096, -5376, -3840, -2560, -4864, -256, -5376, 2560, -3328, 6144, 1024, 11520, 9472, 19456, 20992, 26112, 26112, 19456, 13312, -3328, -7680, -21760, -17152, -24064, -13824, -16896, -7936, -9728, -5120, -4864, -4864, -2304, -5632, 0, -5632, 2304, -3584, 5632, 1024, 10496, 9472, 18176, 21248, 25344, 26880, 19712, 15104, -2048, -6400, -20992, -17152, -23808, -14336, -16640, -8960, -9472, -5888, -4608, -5632, -1792, -6400, 0, -6144, 2048, -3584, 5120, 1280, 9472, 9728, 17152, 21504, 24576, 27648, 20224, 16640, -768, -5120, -20224, -16896, -23552, -15104, -16640, -9984, -9216, -6912, -4352, -6400, -1792, -6912, -256, -6144, 1536, -3584, 4352, 1536, 8704, 9984, 16128, 21504, 23808, 28416, 20480, 18176, 256, -3840, -19200, -16896, -23040, -15872, -16384, -11008, -8960, -7936, -4096, -7168, -1536, -7168, -256, -6400, 1280, -3584, 3584, 1536, 7680, 9984, 14848, 21760, 23040, 28928, 20992, 19456, 1792, -2816, -17920, -16896, -22528, -16896, -15872, -11776, -8704, -8704, -3840, -7680, -1792, -7680, -512, -6400, 512, -3328, 2816, 1792, 6656, 10240, 13568, 21504, 22272, 29440, 21504, 20736, 3328, -1792, -16640, -16896, -21760, -17408, -15616, -12800, -8448, -9472, -3840, -8192, -1792, -7680, -1024, -6400, 0, -3072, 1792, 2304, 4864, 9472, 13312, 20480, 24832, 30208, 28928, 25088, 13824, 1792, -10496, -18432, -22272, -22272, -19200, -16640, -12032, -10752, -7424, -7680, -5632, -6144, -4864, -4864, -3584, -2304, -512, 2048, 4352, 9216, 12800, 19712, 24320, 29952, 29440, 25856, 15360, 3328, -8960, -17664, -21760, -22528, -19200, -16896, -12544, -11264, -7936, -7936, -5888, -6400, -5120, -5120, -3840, -2304, -512, -256, 0, 0, 0, 0, -256, -256, -256, 768, 2304, 3584, 3584, 2560, -768, -4352, -3328, 256, 256, 5888, 8448, -3584, -14080, -15104, -20480, -19200, -8960, -1792, 13056, 10240, -7424, -8960, -13568, -32768, -7936, 28416, 18432, 11776, 14080, -4864, -18688, -5888, 3584, 16384, 26624, 22272, 26880, 17408, -13824, -19456, -256, -4608, 3072, 23552, 5888, -20224, -23808, -26880, -30464, -16384, -5120, 9984, 17920, 512, -11520, -13312, -27392, -20992, 18688, 27136, 14336, 13568, 3072, -14592, -9472, 3584, 13312, 26880, 25856, 24064, 21760, -1280, -19200, -6400, -256, -2048, 15104, 13312, -11520, -22784, -24064, -29952, -23040, -10752, 256, 13568, 7424, -7424, -11520, -20224, -26624, 768, 25344, 19968, 16128, 10752, -6400, -12544, -1792, 7680, 21248, 28672, 26368, 25344, 10240, -13824, -14848, -2816, -1792, 9216, 17408, -1024, -20480, -25088, -29184, -27136, -14592, -3840, 8448, 10752, -2560, -11776, -16896, -24832, -11520, 17408, 23040, 17152, 13568, 1024, -10240, -5120, 4608, 15360, 26368, 27392, 25600, 17664, -3840, -15872, -7936, -2304, 3840, 15360, 7936, -12800, -23040, -27648, -29440, -20224, -8448, 2816, 10752, 3840, -8448, -14848, -22272, -19200, 5376, 22272, 20224, 16128, 6912, -6656, -8448, 256, 10240, 22528, 28416, 26880, 21760, 5120, -12800, -12544, -4352, 1280, 11776, 12544, -4352, -19712, -26112, -29440, -24320, -12544, -1792, 7936, 7168, -3840, -12800, -19456, -21504, -5376, 16384, 21504, 18176, 11520, -1024, -8192, -3328, 5632, 16896, 26368, 27648, 24320, 12800, -5888, -14336, -8192, -1280, 7680, 14080, 3584, -13568, -23552, -28416, -27392, -17408, -6144, 4096, 8704, 1024, -9472, -16896, -21760, -13568, 8192, 20736, 19712, 14848, 4352, -6400, -6144, 1536, 11776, 22784, 27648, 25856, 18176, 1536, -12544, -11520, -4096, 3840, 12544, 9216, -6656, -19712, -26368, -28160, -21760, -10496, 0, 7680, 5120, -5376, -14080, -20224, -18432, -1280, 16640, 20736, 17152, 9216, -2560, -7168, -2048, 6912, 18176, 26112, 26624, 21760, 8704, -7936, -13056, -7424, 256, 9472, 12288, 512, -14592, -23808, -27904, -24832, -14848, -4096, 5120, 7168, -1024, -10752, -17920, -20224, -9216, 9984, 19968, 18944, 13056, 2304, -6144, -4608, 2816, 13056, 23296, 26880, 24064, 14592, -1536, -12288, -10496, -3072, 5632, 12288, 6656, -8448, -20224, -26368, -26624, -18944, -8192, 1536, 7168, 3072, -6912, -15360, -19968, -15104, 2048, 16896, 19968, 15872, 6912, -3328, -6144, -768, 8448, 18944, 25600, 25344, 18944, 5120, -8960, -12288, -6400, 2048, 10240, 10240, -1792, -15616, -24064, -27136, -22528, -12544, -2304, 5376, 5376, -2816, -12032, -18432, -18176, -5632, 11520, 19456, 18176, 11008, 512, -5632, -3328, 4096, 14336, 23296, 25856, 21760, 11008, -3840, -12032, -9216, -1536, 7168, 11520, 4096, -9728, -20480, -26112, -24832, -16640, -6144, 2816, 6400, 1024, -8448, -16128, -19200, -11776, 4608, 16896, 19200, 14336, 4864, -3840, -5120, 512, 9728, 19712, 25088, 23808, 15872, 2048, -9728, -11264, -5120, 3584, 10496, 8192, -3840, -16384, -24064, -25856, -20224, -10240, -512, 5632, 3840, -4352, -13312, -18432, -15616, -2304, 12544, 18944, 16896, 9216, -512, -5376, -2304, 5632, 15616, 23296, 24576, 19456, 7936, -5632, -11520, -8192, 0, 8192, 10240, 1792, -11008, -20992, -25344, -22784, -14336, -4352, 3584, 5376, -512, -9728, -16640, -17664, -8448, 6656, 16896, 18176, 12800, 3328, -4096, -4096, 1792, 11008, 20224, 24320, 21760, 12800, -512, -10240, -10240, -3584, 5120, 10240, 6144, -5632, -16896, -23808, -24320, -17920, -8192, 768, 5376, 2304, -5888, -14080, -17920, -13056, 256, 13312, 18176, 15360, 7168, -1536, -4864, -1024, 6912, 16384, 23040, 23296, 16896, 4864, -6912, -11008, -6656, 1536, 8704, 8960, -256, -12288, -21248, -24576, -20736, -12032, -2560, 4096, 4352, -2304, -11008, -16896, -15872, -5632, 8448, 16896, 17152, 11008, 1792, -4096, -3328, 3072, 12288, 20480, 23296, 19712, 9984, -2560, -10240, -9216, -2048, 6144, 9728, 4352, -7168, -17664, -23552, -22784, -15872, -6400, 1792, 4864, 1024, -7424, -14848, -17152, -10752, 2560, 14080, 17920, 14080, 5632, -2304, -4352, 0, 8448, 17408, 23040, 22016, 14592, 2560, -7936, -10496, -5376, 3072, 9216, 7680, -2048, -13568, -21760, -24064, -19200, -10496, -1280, 4352, 3328, -3840, -12288, -17152, -14592, -3328, 9984, 17408, 16384, 9472, 768, -4096, -2304, 4608, 13824, 21504, 23296, 18432, 7680, -4352, -10496, -8448, -512, 7168, 9472, 2560, -8960, -18944, -24064, -22016, -14336, -4864, 2560, 4352, -512, -9216, -16128, -16896, -8704, 4864, 15360, 17920, 13056, 4352, -2816, -3840, 1280, 9984, 18944, 23552, 21248, 12544, 256, -9216, -10240, -4096, 4608, 9472, 6144, -4352, -15616, -23040, -23808, -17920, -8704, 256, 4608, 2048, -5632, -14080, -17664, -12800, -512, 12032, 17920, 15616, 7936, -768, -4352, -1280, 6656, 15872, 22528, 23040, 16640, 4864, -6400, -10752, -6912, 1280, 8448, 8448, 256, -11520, -20736, -24320, -20736, -12288, -2816, 3584, 3840, -2560, -11008, -16896, -15616, -5632, 7936, 16640, 17408, 11008, 2304, -3584, -2816, 3072, 12544, 20480, 23552, 19456, 9728, -2560, -9984, -9216, -2048, 6144, 9728, 4096, -6912, -17920, -23552, -22784, -15616, -6400, 1792, 4352, 768, -7936, -15104, -17408, -9984, 2048, 14080, 14080, 4864, 0, -2304, -2560, -3584, -3328, -5376, -7680, -8192, -11264, -12544, -14592, -16640, -18432, -21248, -25088, -26624, -29952, -31488, -32768, -32512, -32768, -32768, -32768, -32768, -32512, -32768, -30720, -29952, -27904, -25600, -23040, -21248, -18432, -16896, -14080, -12800, -8448, -10752, -4608, -7424, -4608, 3840, -1536, 2816, 1792, 4864, 768, 9728, 1280, 12288, 11264, 16384, 14592, 24832, 20992, 28416, 26624, 28160, 27392, 30720, 29696, 32000, 32256, 32256, 32256, 32256, 32512, 29952, 32000, 31488, 25600, 32512, 25856, 31744, 26112, 30976, 27904, 32256, 24576, 32000, 29696, 32512, 23040, 30464, 22272, 32512, 23040, 30208, 24320, 31488, 23808, 27136, 23040, 25600, 26624, 18944, 21504, 18688, 24832, 18432, 18176, 14592, 16896, 20480, 9216, 15104, 9728, 14080, 8960, 14592, -1536, 16384, 2560, 6400, 4864, 4864, -5632, 16640, -6656, 3584, 512, -4352, -3072, 5632, -10240, -768, -7936, -6144, -9728, -256, -14336, -1536, -12288, -9216, -13824, -4864, -14336, -8448, -12544, -17664, -12544, -13312, -13568, -15360, -15616, -21504, -19456, -21760, -24576, -24320, -24320, -29184, -23808, -29952, -26624, -23808, -25856, -25088, -25600, -25856, -24576, -19968, -24320, -18176, -17920, -18432, -13312, -16128, -17920, -11008, -19712, -10496, -12288, -16640, -13568, -13568, -15104, -10752, -14336, -9472, -16384, -13824, -13312, -12800, -13824, -14336, -13824, -14080, -15872, -13056, -12032, -11264, -17152, -15360, -16128, -14336, -16384, -13568, -12288, -15616, -13568, -14848, -9728, -12288, -8192, -9728, -8704, -7168, -6656, -5888, -6400, -5632, -1536, -1792, -3072, -256, 1280, 1536, 1536, -1792, 5632, -1024, 6912, 3840, 4608, 6144, 9472, 7680, 12032, 6144, 13568, 7424, 16128, 7424, 11776, 11776, 13056, 13312, 13568, 9216, 13824, 16640, 14080, 8448, 16384, 9216, 17664, 13824, 6656, 15872, 16896, 9216, 17408, 7680, 12032, 13824, 14848, 5120, 14080, 7936, 10240, 12800, 8960, 4864, 14336, 8448, 6400, 11776, 4608, 5632, 10752, 5376, 6400, 8192, 4864, 4864, 6656, 4608, 5888, 7424, 6144, 1792, 6912, 1536, 8448, 2048, 4352, -512, 3584, 768, 5888, 3584, 1792, 1280, -2304, -3328, -2560, -5888, -3072, -4096, -6912, -2048, -4608, -3840, -768, -4608, -6144, -1280, -5888, -2304, 0, -2816, 1024, -256, 1024, 512, 1280, -512, 768, -256, -1792, 1024, -2816, 256, -3072, -1024, -1792, -2560, -2816, -2816, -4096, -5888, -3840, -5120, -5632, -5888, -5120, -7680, -5888, -7936, -6400, -8192, -8960, -10496, -8704, -11264, -9984, -8704, -12544, -8448, -7680, -9216, -7424, -8448, -3584, -6144, -8192, -4608, -3840, -1792, -2304, -2816, 1280, -3584, 6912, -2816, 4096, -2560, 3328, -2304, 5888, -2560, 4864, 2560, 4608, 2816, 7424, 256, 12032, 6912, -1024, 11520, 768, 11008, 10240, 3584, 3328, 14592, 4096, 8704, 6912, 5632, 7680, 8192, 3584, 6144, 6912, 5120, 5120, 4352, 1024, 5120, 5120, 2048, 2048, 0, 2560, -768, 4352, -2048, -256, -1024, 256, 0, 1536, -1792, -768, -768, -3328, -1280, -1536, -4608, -1280, -7168, -3072, -3328, -1280, -2816, -1280, -7168, -1792, -3840, -2560, -1536, -7168, -4096, -3072, -4352, -2048, -2560, -4864, -2560, -6144, -7680, -8192, -6656, -7936, -9216, -8192, -8448, -6912, -6400, -6656, -6656, -6400, -6400, -5888, -4096, -5632, -2560, -2816, -1792, -1792, 1024, -2560, 2560, -2304, 2816, -2048, 1024, -1536, 1024, -2048, 768, -1024, 512, -768, -1280, -768, -2816, -2048, -1536, -3072, -2816, -1792, -6144, -1024, -4352, -2304, -4608, -7168, -4096, -7424, -5888, -9728, -6144, -8704, -5632, -9728, -4608, -6912, -2560, -5632, -4864, -5376, -512, -5888, 2560, -4864, 0, 1024, 4096, 1792, 0, 768, 4352, 3584, 6656, 2048, 6400, 6912, 7680, 6400, 9728, 7936, 12544, 9472, 10752, 11520, 12288, 14080, 16128, 11776, 13824, 13824, 14336, 15104, 14336, 12032, 12800, 13568, 12032, 12800, 11264, 10752, 8960, 10240, 7936, 9472, 8960, 6912, 5120, 5888, 4864, 6656, 6144, 4608, 2816, 3584, 4608, 6144, 4608, 3072, 2560, 768, 3072, 512, 2304, 1024, 0, 0, 768, -1024, 2816, 256, 256, -256, -1280, -1792, 256, -1536, -256, 512, -1024, 256, -256, -1792, -2304, -2816, -5376, -4864, -5120, -7168, -6912, -5632, -7424, -6144, -6656, -8192, -5632, -6400, -7936, -6144, -4864, -5632, -2816, -4864, -3840, -1024, -1280, -1024, 0, -1536, -1536, 512, -2304, -1280, -1280, -2304, -2560, -1792, -4608, -2048, -3584, -3584, -4864, -7424, -6400, -4096, -6400, -7680, -7680, -7680, -5376, -7424, -9728, -9472, -9216, -10496, -11264, -13568, -12288, -11008, -11264, -14080, -11776, -10240, -8448, -9216, -10240, -10240, -7168, -6400, -6144, -5888, -4352, -3840, 256, -768, -256, 1280, 512, 2304, 256, 1024, 3072, 3328, 3584, 3840, 2304, 5376, 6656, 8192, 7936, 7168, 7168, 10496, 9728, 12544, 11520, 11776, 13568, 14336, 14592, 14592, 14592, 14848, 14080, 12288, 14336, 14336, 14336, 11520, 9984, 10496, 10496, 11264, 10752, 6400, 7168, 6912, 6144, 7168, 5376, 3584, 4352, 2048, 3840, 5632, 3328, 3840, 4096, 768, 2816, 2560, 1024, 1536, 1024, -2048, 0, -512, -512, -768, -512, 256, 768, -768, -768, -1536, -2048, -1280, 1024, 768, 512, -1024, -512, -256, 1280, 768, -512, -512, -512, 768, 1792, -512, -6656, -9472, -8704, -7680, -3328, -3584, -5376, -6144, -6912, -6144, -3328, -1792, -3840, 1536, 768, -7680, -12800, -12288, -12032, -10496, -6656, -2048, 7168, 11008, 9728, 14592, 16128, 14336, 19200, 30208, 32512, 29952, 25344, 22016, 21760, 16896, 11776, 15104, 20480, 17664, 11008, 6912, -1536, -12032, -18944, -20480, -18176, -14592, -10240, -11264, -14336, -19968, -22528, -19968, -15104, -13312, -13056, -14336, -14592, -12032, -9216, -9216, -9984, -9984, -8192, -4352, 1536, 6144, 8448, 2560, -3584, -3584, -512, -2816, -5120, -3840, -6144, -7168, -7168, -6400, -7168, -13824, -18688, -16640, -11008, -4608, 1536, 6912, 5376, 5888, 4352, 5632, 4608, 4096, 7936, 12800, 11520, 6400, 5632, 2048, -5120, -4352, 2048, 7424, 2560, -5632, -10496, -11520, -13056, -13568, -7936, -4608, -5888, -1792, 9472, 13824, 9728, 9216, 15360, 25600, 30464, 30720, 31232, 32000, 28160, 22528, 24064, 25344, 23040, 21760, 20992, 13824, 6656, -1280, -12544, -21248, -21760, -17152, -9216, -3584, -7680, -14080, -19456, -22016, -16640, -10496, -11520, -15360, -13568, -11008, -8960, -8704, -10496, -11008, -11520, -8960, 2560, 10240, 8192, 768, -768, -3584, -7680, -9728, -8448, -5888, -7424, -6656, -4608, -2560, -4352, -9472, -11776, -14848, -15616, -11520, -4352, -1024, -512, 4864, 7936, 6912, 3328, 5632, 9728, 12544, 15104, 17664, 15360, 5888, -3328, -2816, 3328, 6144, 4864, 6144, 2048, -7680, -14848, -14848, -16896, -21760, -23040, -15616, -4864, -256, -2816, -1280, 6400, 10752, 15616, 23552, 27904, 27136, 28160, 26624, 23808, 23808, 22784, 20992, 22016, 20736, 18176, 13056, 3328, -10240, -18944, -22272, -18688, -8960, -6144, -12800, -18176, -18688, -13568, -12800, -14848, -17408, -15360, -15616, -13824, -7680, -6400, -10240, -13312, -6400, 3328, 8192, 11520, 12544, 11264, 7168, 5632, 7424, 8192, 5120, 768, 1792, 1536, 0, -256, -1024, -7680, -16128, -17664, -15872, -14592, -12544, -6400, 512, 4352, 6144, 6912, 7680, 2560, 1024, 9728, 19712, 16896, 8192, 3328, 1792, 0, 2304, 7936, 11008, 5888, -2816, -6400, -5888, -11776, -21248, -22272, -16128, -10752, -4864, -1536, -768, 1536, 6912, 12544, 20736, 27648, 30976, 31488, 31744, 29440, 28160, 25088, 20480, 19968, 19712, 19712, 17664, 13824, 2048, -14336, -25344, -23552, -13568, -11776, -16384, -19200, -18688, -17920, -19200, -15872, -17152, -22016, -22528, -13824, -7168, -8448, -11776, -12800, -10240, -6144, -768, 7424, 13056, 12288, 8704, 11264, 11264, 7680, 4608, 3328, -768, -3840, -1792, -256, -2560, -9216, -14336, -16640, -20224, -25600, -23296, -16384, -13312, -10240, -1280, 5120, 2304, -3584, -2304, 5376, 12544, 15104, 14848, 12544, 6400, -256, 2816, 9984, 9984, 5632, 4864, 5120, 2048, -4864, -12544, -18432, -17664, -14848, -11008, -6912, -6144, -3328, -1280, 3072, 9728, 18944, 24832, 28160, 31744, 32256, 32256, 29184, 26880, 25600, 22272, 23296, 27648, 29440, 18688, 1280, -10496, -12544, -12544, -13568, -11520, -12544, -17664, -19712, -15360, -13056, -18176, -24064, -24576, -17408, -12544, -11776, -11264, -11520, -15360, -15360, -6912, 0, 2816, 6656, 9472, 9472, 9472, 10240, 10752, 8704, 2048, -256, 3584, 3840, -1280, -3072, -4608, -11264, -19200, -21760, -22528, -25088, -25344, -19456, -9216, -3072, -4864, -6144, -2816, -2304, 256, 9216, 18176, 14848, 7424, 3328, 4352, 8448, 8448, 7680, 8960, 11264, 11264, 6912, -768, -9984, -13056, -15616, -14080, -10496, -7936, -6400, -7424, -5376, -256, 5888, 11776, 19456, 26112, 27904, 28160, 29696, 30208, 23552, 15616, 19456, 28672, 30720, 23808, 14592, 3584, -7168, -13824, -12800, -11776, -15360, -21248, -20992, -16384, -15872, -20992, -22784, -23808, -25856, -22528, -15104, -13312, -16384, -19200, -19456, -16128, -12800, -7680, -256, 2304, 2048, 2816, 8192, 11264, 9216, 7424, 8192, 6912, 5120, 5632, 7168, 6144, 0, -5376, -7680, -11520, -19968, -24832, -21248, -16896, -12800, -8192, -4352, -4096, -5888, -5120, 1024, 9728, 13056, 12032, 9472, 7168, 7424, 6912, 6912, 7936, 10752, 13824, 14080, 11008, 5120, -1280, -7424, -10240, -9472, -7680, -6912, -5888, -3840, -3072, -2816, 2048, 11008, 17152, 19968, 25600, 31232, 32256, 27392, 21504, 20736, 23552, 27136, 29440, 28160, 20224, 7936, -768, -3328, -6656, -12032, -14336, -14336, -14848, -14848, -14336, -15104, -18432, -22016, -21504, -16896, -14592, -14336, -14336, -15360, -18944, -18944, -13056, -8192, -6144, -3584, 768, 3584, 3840, 4864, 7168, 8448, 4864, 2816, 5632, 7424, 4608, 2048, 2304, 0, 0, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -256, -256, -256, -256, -256, -256, -256, -256, 0, -256, -768, -512, -256, 0, 512, -1024, -3328, -5376, -5888, -4864, -2048, 1792, 4352, 5888, 6656, 8448, 9728, 8192, 4352, -1280, -4352, -6144, -5120, -1536, -768, -4096, -7424, -6656, -4352, -1280, -256, 512, 1792, 2816, 4352, 3840, 2304, 2304, 768, 2560, 3840, 2304, -3584, -8448, -6912, -4608, -1536, -1792, -2560, -1536, 0, 3072, 3840, 7424, 9728, 9216, 8192, 2816, 0, -7680, -11520, -12800, -9984, -5888, -6912, -6144, -3840, 1536, 6400, 9472, 13056, 11776, 10240, 0, -4864, -5632, -8704, -7680, -10240, -11520, -13056, -8704, -256, 6400, 12288, 10240, 11008, 13056, 16384, 14848, 1280, -5632, -12544, -16128, -17664, -17408, -14848, -13824, -4096, 3328, 11264, 16896, 15616, 17408, 18432, 22016, 12032, -4352, -14336, -20992, -22528, -23808, -18432, -14848, -10240, 1024, 11520, 24064, 25088, 21504, 16640, 17408, 18176, 3840, -11776, -22528, -23040, -22528, -21760, -15872, -14336, -8704, -1024, 10496, 20480, 20992, 18944, 13824, 17920, 16896, 6400, -7424, -17920, -18944, -23040, -22272, -20224, -18688, -11776, -2560, 13824, 23040, 26368, 22528, 19456, 23040, 17664, 6400, -9728, -19456, -24576, -30464, -28416, -26368, -20736, -14592, -3072, 12800, 23040, 28928, 25088, 25600, 28672, 26368, 15360, -2816, -13824, -24320, -30976, -31744, -30464, -24320, -18176, -2560, 13568, 26368, 29696, 23808, 23296, 22784, 20480, 7936, -7168, -17152, -27648, -31232, -32768, -28160, -22272, -13568, 2048, 15360, 27392, 27392, 22784, 21248, 21248, 19456, 6912, -3584, -13312, -21504, -25344, -26368, -20992, -18432, -10240, 1024, 13568, 23552, 23552, 22528, 21760, 24832, 22272, 10752, 768, -11520, -18944, -27136, -28416, -26880, -25856, -17920, -7680, 6912, 16640, 19712, 21248, 22272, 27136, 23040, 14848, 4096, -7680, -17152, -25856, -25600, -25856, -23808, -17408, -6912, 7424, 15360, 19712, 20224, 23808, 28416, 24576, 18176, 6144, -5376, -18688, -27904, -30208, -32512, -30208, -25088, -12800, 1536, 11008, 16640, 17920, 25344, 29440, 27648, 20992, 10240, -256, -13568, -20480, -24064, -26880, -25856, -20992, -7936, 4608, 14336, 16896, 18432, 24320, 26368, 24832, 16384, 7424, -3840, -16128, -21760, -26112, -26880, -26624, -20736, -8960, 3328, 13568, 14848, 17664, 22016, 24832, 24064, 17152, 9984, -3072, -13824, -20480, -24832, -26112, -26368, -19712, -9728, 2304, 10240, 11520, 15360, 19712, 24320, 22528, 17920, 10496, -2048, -11776, -18944, -22272, -25344, -25600, -19968, -10752, 2560, 9472, 12800, 16896, 22784, 28160, 26368, 23296, 14592, 2304, -8448, -17408, -22016, -26880, -26880, -22784, -13056, -512, 5888, 10240, 13568, 20480, 25344, 25088, 22784, 13568, 2048, -9472, -17408, -23040, -27392, -27136, -24064, -13056, -1280, 6400, 11008, 14848, 22016, 24320, 25088, 22016, 13312, 2304, -9216, -16384, -23552, -26880, -27648, -24320, -13568, -2816, 5632, 9472, 14592, 20736, 23040, 24576, 20992, 13312, 1536, -8704, -16384, -23552, -26624, -28928, -24832, -15104, -4608, 3840, 7936, 14848, 20224, 23552, 25088, 22272, 14592, 2304, -7424, -16128, -22272, -25600, -27904, -23296, -14848, -3328, 4096, 9216, 15872, 19968, 23808, 24576, 22528, 14336, 3072, -6400, -15872, -21248, -25856, -27136, -22784, -14592, -3840, 1536, 7680, 13312, 18176, 22272, 24064, 22784, 14080, 4608, -5376, -14080, -19456, -24576, -25600, -22528, -13568, -4096, 1536, 7936, 13568, 19456, 23808, 26880, 25088, 16384, 6656, -4608, -13312, -19968, -25344, -26880, -24320, -15104, -6656, 0, 6144, 11520, 16896, 20736, 24832, 22528, 15872, 7168, -3072, -10240, -17152, -21504, -24320, -21248, -12800, -5376, 1024, 6144, 12032, 16384, 20736, 24576, 21760, 16128, 6656, -2816, -10496, -17664, -22528, -26112, -23296, -16384, -9216, -3072, 2560, 8704, 13056, 18944, 22272, 20736, 15872, 6656, -1792, -10240, -16128, -21248, -24320, -21248, -14848, -7936, -2560, 3584, 8704, 13056, 19200, 21760, 20992, 15616, 7680, -768, -8704, -14592, -20736, -23552, -21248, -15360, -9216, -3840, 2816, 6912, 12032, 17664, 20480, 20224, 15104, 7680, -1280, -8448, -14592, -20992, -23808, -21504, -15616, -9728, -3840, 2560, 6400, 12288, 17408, 20480, 19712, 14848, 7424, -1024, -7680, -14336, -20480, -22784, -19968, -13824, -8704, -2048, 2560, 0, 0, 256, 0, -512, -512, -1280, -2048, -768, 768, -1024, -2560, 512, 2048, 768, 1024, 1280, -768, -2304, 2560, 6656, 6656, 3072, -1024, -10240, -16384, -12800, 256, 14080, 17664, 7168, -5888, -16640, -21248, -13312, 3328, 17152, 17152, 9984, 4096, -3840, -12288, -9728, 2560, 13568, 11264, 1280, -1280, -3584, -11008, -8960, 4096, 13824, 9472, -256, -6656, -13568, -20992, -9472, 8960, 17152, 11264, 512, -2560, -5120, -9984, -4864, 6912, 14080, 10752, 768, -6656, -17152, -27392, -15872, 11008, 28160, 26112, 11008, -4608, -16128, -23296, -8960, 18688, 30720, 19712, -1536, -18432, -28928, -27904, -9216, 13568, 19968, 12800, 0, -11776, -18432, -18176, -5120, 17152, 28672, 25600, 11264, -6144, -22528, -31488, -21504, 1280, 18176, 24832, 16896, 1792, -13568, -25600, -20480, -256, 21248, 32512, 27648, 9728, -14592, -30976, -30464, -14592, 6144, 21504, 24832, 15872, -1024, -19712, -24832, -11776, 8192, 25856, 27648, 14336, -5120, -26368, -30464, -17664, 4608, 26880, 32256, 23040, 1536, -23552, -32256, -23040, -768, 21760, 27648, 19200, 0, -22016, -29952, -21760, -1536, 19456, 29440, 25856, 7680, -17408, -30208, -26880, -8448, 14592, 26880, 26112, 10496, -11776, -26624, -28672, -15104, 6400, 24320, 30976, 20736, -1280, -22528, -32256, -24064, -3072, 16128, 25856, 19456, 1792, -17152, -27392, -18688, 2816, 24064, 32512, 26112, 5376, -18944, -31744, -24320, -5376, 14592, 25856, 20992, 5376, -12288, -22784, -15104, 1536, 17152, 24320, 15360, -2816, -20992, -29440, -20736, -3328, 13312, 21504, 13312, -2304, -17408, -24576, -14336, 2304, 16896, 23808, 16128, 2560, -13312, -22016, -13824, 256, 15360, 24576, 17920, 4864, -11264, -20480, -13056, 0, 14080, 24064, 17664, 5120, -10752, -22528, -19456, -10240, 6144, 20224, 18432, 8704, -7168, -19200, -16128, -5888, 8960, 18176, 12288, 1024, -14592, -24320, -17152, -2560, 15872, 26368, 19200, 4608, -15616, -28160, -22016, -5632, 15616, 28160, 23040, 9472, -11520, -25600, -22272, -9984, 8704, 20736, 17920, 8448, -9984, -22528, -19456, -6144, 13824, 24064, 19456, 8192, -11776, -25600, -23552, -10752, 8960, 18688, 15872, 6656, -11776, -24832, -23808, -11264, 9216, 20736, 19200, 8960, -9728, -22272, -20736, -6656, 14848, 25344, 21760, 9472, -11264, -25856, -26368, -11776, 12032, 25088, 24832, 14336, -6912, -23040, -25344, -12544, 9472, 22528, 24320, 15872, -3072, -18944, -23808, -13056, 6912, 17664, 18176, 8960, -7680, -19968, -22272, -9728, 10496, 21504, 23040, 14592, -2816, -18176, -24576, -14336, 5376, 17664, 22016, 15360, -1024, -17152, -24832, -15616, 3072, 16640, 22528, 16640, 768, -15616, -24064, -15360, 3584, 18176, 24576, 17408, 768, -16896, -26624, -17920, 768, 15104, 21504, 15104, -256, -17152, -27392, -19456, -768, 15104, 22784, 16384, 768, -17152, -28416, -20992, -2304, 14592, 23552, 19456, 6656, -11008, -23808, -18176, -2304, 12800, 20480, 16384, 4096, -13056, -25600, -20224, -4352, 12544, 22528, 19712, 7680, -10496, -24320, -20224, -4352, 12544, 22272, 19712, 8704, -9216, -23552, -19968, -4864, 11264, 20992, 18688, 8448, -9472, -24320, -21504, -5888, 12032, 22784, 21248, 11008, -7680, -23552, -21248, -7168, 9984, 20224, 18944, 10240, -7168, -22272, -20992, -7936, 8704, 18176, 17152, 8960, -7936, -22528, -21760, -9216, 7168, 17408, 17664, 11264, -5120, -20224, -21248, -11008, 4864, 15104, 16384, 10496, -6400, -22784, -25600, -15616, 2304, 15360, 19456, 14592, -2560, -19200, -23040, -13056, 5632, 18944, 22528, 16896, 256, -15616, -19968, -10752, 6400, 18176, 21504, 16128, -256, -17152, -23040, -15104, 2048, 15104, 20736, 17408, 2048, -14336, -21760, -15872, 256, 12800, 18944, 16128, 1792, -13568, -21504, -15360, 1280, 14080, 20480, 17920, 4352, -11008, -19456, -14080, 1024, 12544, 18688, 16640, 4352, -10496, -19712, -15872, -2304, 9728, 17408, 16384, 4352, -11008, -21504, -18688, -5632, 5888, 14336, 14592, 4608, -9216, -19712, -17408, -5888, 5120, 13056, 13312, 4096, -9216, -19712, -17920, -6656, 4608, 13824, 15104, 7168, -5632, -16384, -15104, -5120, 5376, 14336, 16128, 9216, -3072, -14080, -13312, -4096, 6400, 14848, 16128, 8960, -3584, -15104, -14592, -5632, 4608, 13056, 14592, 7936, -4096, -14848, -14848, -6912, 2560, 11008, 13056, 7680, -4096, -15104, -15360, -7168, 3072, 12288, 14592, 8960, -3328, -15104, -16384, -8960, 1792, 12032, 16128, 12032, 256, -11776, -14080, -8192, 1792, 12032, 0, 0, -256, -256, -1024, 256, -256, -768, -3328, -2048, -3584, -768, -512, -512, 256, 2048, 1280, 1792, -5376, -3328, -512, -1536, -2048, -5632, -1536, 1280, 2816, 8704, 10496, 8448, 3328, 7168, 8448, 12288, 8960, 5376, -768, -6656, -4608, -2560, 768, 1792, 5632, 5376, 16128, 10240, 10496, 11008, 1024, -2048, -11008, -16128, -19712, -19712, -15104, -4608, 768, 512, -5376, -11776, -18944, -23040, -27648, -25856, -24064, -22784, -21504, -21760, -19712, -15104, -12800, -8448, -1792, 4608, 9472, 12032, 16384, 25856, 32512, 32000, 32512, 32256, 32256, 32256, 31232, 25600, 22272, 15872, 9472, 7168, 6912, 6400, 6912, 8704, 6400, -1024, -11520, -21760, -31488, -32768, -32256, -32768, -32512, -31488, -23552, -18688, -14080, -11520, -9472, -8448, -8192, -8448, -11008, -13568, -14080, -11008, -5120, 768, 5120, 8704, 10752, 12544, 14080, 16128, 18944, 21504, 23808, 25856, 27392, 28672, 29952, 27904, 23552, 16128, 8448, 2048, -3328, -6400, -7424, -7680, -6912, -6912, -8192, -11776, -16128, -20992, -25088, -27904, -29696, -30976, -30208, -26624, -20480, -12544, -3072, 5376, 11520, 14848, 16384, 16896, 16896, 15616, 13056, 11264, 9472, 8192, 8192, 8448, 8448, 7168, 5888, 3840, 2048, 768, 512, 2304, 4096, 5120, 6144, 5888, 3584, -256, -5120, -9472, -12288, -13568, -13312, -12032, -9728, -6656, -3328, -1280, -256, -1024, -2560, -5632, -8704, -11008, -12288, -11776, -8704, -4096, 1280, 6400, 11520, 16640, 19968, 21504, 21248, 18176, 14080, 9984, 6144, 2304, -768, -3072, -5888, -8704, -11520, -14592, -16640, -18176, -18176, -16128, -12544, -8704, -5376, -2816, -512, 512, 2048, 2816, 3072, 3584, 3584, 5120, 7168, 9728, 12800, 14848, 16128, 15616, 14336, 11776, 8448, 4352, -256, -4864, -8704, -11520, -12288, -11264, -8192, -4864, -1280, 1280, 1792, 1024, -512, -1792, -2816, -3840, -4608, -5376, -5888, -6656, -7168, -7680, -7936, -7424, -6656, -5120, -3072, -256, 2816, 5376, 8192, 10752, 13056, 14080, 14080, 13312, 11776, 10496, 9472, 8192, 7680, 7168, 6912, 6144, 4864, 3072, -256, -5376, -11520, -17152, -22784, -26368, -27392, -25856, -23040, -17920, -13056, -8448, -4608, -512, 2816, 5888, 8448, 9984, 11264, 12544, 13312, 14592, 15104, 15104, 14336, 13312, 12288, 10496, 8960, 7168, 5120, 3840, 2816, 1024, 0, -1280, -2816, -4608, -6400, -8704, -10752, -12032, -12288, -11776, -10240, -8448, -6912, -6144, -5376, -6144, -8192, -10752, -13056, -14336, -14848, -14336, -12032, -8960, -4608, 512, 6144, 12288, 17920, 22528, 25344, 26624, 26112, 24832, 22784, 20224, 17664, 15104, 12544, 9472, 6912, 3584, 0, -3584, -7424, -11264, -14848, -18176, -20736, -22272, -22528, -22528, -21760, -20736, -19712, -18432, -16128, -13056, -9472, -5376, -1280, 3072, 7424, 11008, 13568, 15104, 15616, 14592, 12288, 9216, 6144, 3328, 2048, 2048, 3840, 6400, 9728, 12288, 13824, 13824, 12800, 11008, 8448, 5632, 2816, 768, -1536, -3840, -6400, -8960, -11776, -13824, -15616, -16640, -17408, -17664, -17664, -17408, -16384, -15104, -13312, -11008, -8192, -5120, -1792, 1536, 4864, 7936, 10752, 13056, 14848, 15872, 16384, 15872, 14848, 13312, 11264, 8960, 6656, 4352, 2304, 256, -1280, -2560, -3840, -4608, -4864, -5120, -4864, -4608, -4096, -3840, -3584, -3584, -3840, -4096, -4352, -4608, -4864, -4864, -4864, -4864, -4608, -4096, -3584, -2816, -2304, -1536, -768, 0, 768, 1536, 2560, 3584, 4608, 5632, 6912, 8192, 8960, 9472, 9472, 8960, 7680, 5888, 3584, 1024, -1536, -3840, -6144, -7936, -9216, -9984, -10240, -9984, -9472, -8192, -6656, -4864, -2560, -256, 2048, 4352, 6144, 7424, 8192, 8448, 8192, 7424, 6400, 5120, 3840, 2816, 1792, 768, -256, -1280, -2304, -3584, -4864, -6144, -7168, -7936, -8192, -7936, -6912, -5888, -4096, -2560, -768, 512, 1792, 2560, 3072, 3328, 3328, 3328, 3072, 2560, 2048, 1792, 1280, 1280, 1280, 1280, 1536, 2048, 2560, 3328, 4352, 5120, 5888, 6400, 6656, 6400, 5376, 4096, 2304, 256, -1792, -4096, -6144, -7936, -9472, -10752, -12032, -12544, -13056, -13312, -13056, -12288, -11008, -9472, -7680, -5120, -1792, 1536, 4864, -256, -1024, -1024, 0, -256, -1024, -768, 1024, 1024, -512, -768, 512, 256, -1024, 0, 1280, 0, -1024, 512, -2560, -6656, -7424, -8704, -12544, -15616, -11264, -5376, -2048, -768, -768, 256, 5120, 8192, 9728, 8192, 3072, -1024, 256, 3584, 7168, 13056, 17408, 19968, 20480, 18432, 9728, 256, -1536, 4096, 5888, 512, -3584, -3840, -5120, -8448, -15872, -16640, -9472, -4608, -6912, -7424, -6656, -11520, -9728, 2048, 13312, 14080, 7936, 6656, 4096, 4352, 11520, 20480, 22272, 19712, 15872, 13824, 6144, -5888, -12800, -11008, -7168, -12032, -18432, -22016, -22016, -22272, -15616, -8960, -9728, -14592, -17664, -14080, -6912, 256, 1024, 5632, 11520, 13824, 7936, 0, -1792, -1280, -768, 0, -2304, -5376, -5120, -3840, -6912, -7936, -2560, 1280, 2304, 768, -5376, -17152, -21248, -11776, -768, 2048, 4608, 5632, 1024, -768, 1280, 8960, 13312, 17152, 18432, 21248, 22784, 18176, 9472, 4864, 6400, 2048, -2816, -9472, -14848, -20480, -21760, -17408, -8448, -6144, -14592, -15360, -8704, -4096, -3584, 4352, 18688, 24576, 19712, 12288, 4352, -1792, -2304, 1024, -256, -768, 1536, 768, -3072, -2560, 4864, 8448, 8448, 10496, 8960, -7424, -17920, -16384, -9728, -4608, 768, 4352, -1280, -6656, -8960, -1280, 7936, 16128, 18688, 22016, 24064, 20480, 16384, 12800, 11776, 9472, 7168, -512, -8192, -16640, -23296, -21504, -16128, -15104, -20992, -24832, -20480, -16896, -16640, -11008, 2048, 12544, 15360, 15616, 10752, 6912, 5888, 5888, 3584, 3840, 4608, 2560, -3072, -4352, -2304, -3328, 2048, 8960, 10752, 512, -10496, -19456, -22272, -17152, -11776, -7936, -8192, -11520, -18432, -13568, -1280, 8192, 11776, 18432, 23552, 24576, 23552, 19712, 19200, 18688, 15616, 11264, 3072, -8192, -17408, -18432, -13824, -14848, -19200, -21760, -17152, -14592, -15616, -15360, -11776, -2816, 6144, 8960, 5632, 3840, 1536, -256, -3328, 2048, 5888, 2048, -256, -256, -1536, -2048, 8960, 18176, 22016, 20224, 12800, -2816, -11776, -9728, -7936, -7424, -5376, -7680, -16384, -17408, -11008, -3072, 2560, 7168, 15872, 22784, 22528, 21504, 21760, 23040, 22784, 24320, 21248, 7168, -8192, -13568, -9216, -11264, -15872, -16384, -14080, -15104, -13824, -13312, -12288, -5888, 4864, 12288, 9472, 9984, 10752, 7936, 3072, 4864, 5120, 1280, 1024, 256, -5888, -10240, -3584, 3584, 10752, 17408, 16384, 3584, -8448, -13568, -13312, -8192, -4608, -6144, -11008, -17152, -15872, -9216, -4608, -256, 6400, 13824, 14592, 14848, 14336, 13824, 12800, 16896, 20480, 11264, -5376, -12800, -10240, -13312, -17664, -19712, -15360, -14336, -13824, -13568, -15872, -12544, -2304, 7168, 10496, 14848, 14848, 12032, 11008, 12544, 10496, 8704, 9472, 4608, -4864, -11264, -12032, -9216, 256, 8960, 9728, 4864, -5120, -15872, -18176, -15104, -9216, -8704, -12032, -16128, -16128, -12800, -9728, -4352, 1792, 9472, 14336, 18944, 20480, 18688, 15616, 22272, 29696, 25344, 12032, -1792, -6656, -5632, -5120, -8192, -14592, -18432, -19456, -19456, -18176, -12032, -2304, 3328, 6144, 7424, 7424, 6400, 6912, 13312, 17408, 15872, 2304, -9728, -17152, -16896, -9984, -2816, -1024, -6144, -9472, -12032, -13056, -12544, -11264, -14080, -9984, -1536, -4352, -13312, -13824, -4864, 256, 3840, 6144, 7936, 10496, 14080, 18176, 20224, 22784, 28416, 29440, 22528, 13824, 5632, -512, -2048, -1280, -1792, -6912, -12544, -14592, -17664, -18432, -16384, -7680, -768, 4352, 7936, 9472, 7424, 3584, 9984, 17152, 18688, 12032, 2560, -10240, -18432, -14848, -5888, -3072, -4864, -4864, -9984, -12544, -10752, -11776, -15872, -11264, -2048, -2816, -9216, -13056, -9984, -3840, 0, 3328, 5376, 6400, 10240, 14080, 16128, 18688, 24320, 29440, 29440, 21760, 13568, 5120, 512, -256, -512, -2560, -8192, -12288, -16384, -18688, -19712, -15872, -8448, -2304, 4096, 8448, 7936, 4608, 4352, 11264, 17152, 17920, 12544, 1536, -11520, -17664, -13568, -6144, -3328, -4864, -6144, -10240, -12032, -11520, -12800, -15872, -11008, -2560, -3328, -9472, -13056, -9984, -3840, 0, -768, -256, 256, -256, -1536, -1536, -1024, -256, -512, -1536, -2048, -1792, -1024, -1280, -2560, -3584, -4096, -4096, -4096, -4352, -4608, -4608, -4352, -3840, -3840, -4096, -3840, -3328, -2560, -2304, -2304, -2816, -3328, -3584, -2816, -2304, -2048, -2304, -1792, -768, -512, -1280, -2048, -1536, 256, 1280, 1024, 256, 0, 256, 1024, 1024, 1024, 1280, 1792, 2304, 2304, 2048, 2048, 2304, 2560, 2304, 1280, 512, 768, 1280, 1792, 1792, 2304, 2816, 2816, 3072, 3584, 3584, 3072, 2048, 1792, 2048, 1280, 256, 768, 2048, 2304, 2304, 2560, 3584, 4096, 3840, 3584, 3072, 2816, 2304, 1792, 768, -512, -768, 768, 1280, 0, -1280, -256, -256, -1536, -2560, -4096, -5888, -7168, -7424, -8192, -9984, -9216, -5888, -4096, -4864, -4864, -2560, -1792, -3072, -2816, -1280, -1536, -2816, -3328, -2816, -2304, -2048, -512, 1536, 2048, 2048, 2304, 1536, 512, 1024, 2048, 2304, 1024, 1024, 3072, 4608, 4352, 3584, 4352, 5120, 5120, 4096, 2304, 1792, 1792, 1280, 768, 1024, 256, -512, 0, 768, 512, -256, 256, 768, 768, 256, 512, 512, 0, 768, 1536, 2304, 2048, 0, -1280, -768, 1792, 3072, 2048, -512, -512, 2304, 2560, 512, -768, 512, 1280, 256, -768, -1280, -1536, -512, -768, -2816, -5120, -6656, -7168, -7680, -8192, -9472, -11008, -11520, -11008, -10240, -10752, -10496, -7936, -5632, -5120, -4608, -4096, -4096, -4864, -3840, -2048, -768, -768, 768, 4352, 6656, 5632, 4096, 4608, 5888, 6912, 6656, 5888, 4352, 3840, 5376, 6400, 6144, 6400, 7936, 9216, 8192, 7424, 5888, 4352, 3840, 2816, 1280, 256, 1024, 1536, 2048, 1536, 1792, 2048, 2560, 3584, 4608, 5632, 5120, 4352, 3584, 3840, 3328, 2560, 3840, 3840, 3072, 2304, 2560, 3840, 3584, 2304, 768, 1536, 2560, 1280, -768, -2304, -4096, -4096, -2560, -2816, -5120, -6144, -4608, -5120, -8192, -10752, -12288, -14080, -17920, -21504, -24320, -25600, -23552, -19200, -16640, -17408, -17152, -14336, -14080, -13056, -10496, -8448, -9472, -10752, -9728, -8448, -7936, -6656, -1536, 4864, 7680, 6400, 6400, 7168, 7680, 6912, 4864, 4096, 4608, 7936, 11264, 11776, 12288, 14336, 18176, 19712, 18944, 16896, 13824, 12032, 9472, 4864, 768, 512, 768, 768, 1024, 3328, 5120, 5376, 6400, 6144, 6400, 4864, 4608, 4864, 4864, 3584, 1536, 4352, 3584, 256, 768, 3072, 6912, 7424, 6400, 3328, 3584, 6144, 5632, 1536, -1792, -1792, 0, 2816, 3072, 256, 0, 2560, 2048, -3328, -8192, -11776, -13312, -14592, -17920, -22528, -27136, -25856, -20736, -18944, -20992, -19200, -12544, -9472, -10752, -11264, -10752, -11776, -13056, -12032, -10240, -8192, -6912, -1536, 768, 4096, 8192, 7424, 6400, 6144, 7680, 13824, 17664, 18944, 19968, 23040, 27648, 30208, 31744, 29952, 27392, 26112, 23808, 19456, 15616, 12800, 10496, 8960, 7936, 6656, 3328, 1024, 0, -256, 0, -1536, -3072, -2560, -2048, -1024, 0, -768, -5120, -7936, -6912, -4608, -4096, -5632, -7424, -7168, -2304, 0, -768, -256, 512, 2816, 5120, 6144, 4608, 5632, 8704, 8192, 4096, -256, -4608, -8704, -11776, -14080, -17152, -23296, -26112, -23296, -18432, -18688, -20736, -17408, -14080, -14080, -16640, -18944, -20224, -22272, -22272, -21248, -20736, -19712, -15360, -6400, 1024, 1024, -768, 0, 3328, 7424, 7424, 6144, 5888, 7424, 13056, 17152, 18432, 19712, 22528, 26880, 29184, 31232, 29696, 27136, 25600, 23808, 19712, 16128, 13056, 10752, 9216, 7936, 6912, 3840, 1280, 0, -256, 0, -1024, -2560, -2304, -1792, -768, 512, -256, -4096, -7168, -6656, -4096, -3328, -4608, -6400, -6400, -2048, 512, 256, 512, 1280, 3328, 5376, 6656, 5120, 5888, 8960, 8960, 5120, 768, -3584, -8192, -11520, -13824, -17152, -23296, -26112, -23040, -18432, -19200, -20992, -17408, -14336, -14336, -16896, -19200, -20736, -22528, -22528, -21248, -20992, -19712, -15104, -5632, 1024, 256, -256, -512, -768, -768, -256, -256, -1536, -2048, -2304, -3072, -1280, 1536, 3840, 5376, 5632, 5376, 2304, -2048, -4096, -5888, -8192, -5632, 1024, 6912, 8192, 4352, -512, -5376, -8704, -9472, -7680, -6144, -768, 6144, 12032, 14848, 12800, 5888, -3072, -10496, -13312, -12032, -8448, -512, 7168, 12288, 11520, 7168, 0, -9216, -14848, -13568, -8704, -1024, 6656, 13312, 19200, 18688, 11520, -1280, -16896, -25856, -23040, -15616, -3584, 5888, 15104, 22272, 22784, 16128, 2560, -11776, -20224, -20480, -14080, -5888, -768, 6912, 14848, 15872, 10496, -1536, -16896, -23552, -19712, -7424, 4864, 10496, 16640, 18944, 17664, 10752, -2304, -18688, -27904, -27392, -17152, -4352, 5888, 17920, 26624, 28416, 21248, 5376, -14336, -26624, -27904, -15872, -5376, 1024, 8704, 17408, 22784, 19200, 4864, -11776, -22784, -21760, -9728, -256, 5888, 11520, 16384, 18944, 15872, 2048, -13568, -25088, -23808, -12032, -2304, 4096, 9216, 15872, 22016, 19968, 3328, -17152, -30976, -27904, -14336, -2304, 6400, 14848, 22784, 27904, 20736, 2048, -17920, -30464, -27136, -14336, -1792, 8192, 16128, 23040, 27648, 18944, -768, -22784, -32768, -30208, -17920, -5632, 5888, 15872, 25856, 32256, 25088, 6656, -16384, -29952, -28160, -18432, -8192, 1536, 11264, 23808, 31744, 25600, 7168, -16128, -29696, -28160, -18176, -6656, 4096, 13824, 25856, 30976, 23552, 3328, -22016, -32768, -30720, -20224, -7168, 3840, 15360, 28416, 32512, 24320, 2816, -21248, -32512, -29696, -20480, -7424, 3840, 17152, 29952, 32512, 25600, 4352, -19200, -30208, -27648, -19200, -7936, 1792, 15360, 27904, 31488, 22272, 768, -21248, -30208, -27136, -17152, -5888, 3328, 15872, 27136, 30464, 21760, 768, -19712, -27136, -24320, -15616, -6912, 512, 13312, 26368, 31744, 24832, 4864, -15616, -24320, -23552, -16128, -8704, -1024, 11520, 24064, 29696, 22272, 2048, -16128, -23296, -21760, -14848, -9216, -2304, 9216, 20736, 26624, 19456, 512, -15360, -22272, -19712, -13312, -8192, -512, 12288, 24832, 30464, 22016, 1792, -15104, -23040, -21760, -16640, -12800, -5632, 6656, 19968, 27392, 20224, 2816, -12544, -19968, -18688, -14848, -11776, -4608, 7936, 21760, 28672, 19200, 256, -15104, -21504, -18688, -14080, -10240, -3072, 7680, 20480, 27136, 18944, 2560, -11776, -17920, -15872, -12544, -9984, -3328, 7936, 22016, 28160, 18944, 2048, -12544, -17920, -15104, -11776, -8448, -1536, 9728, 23552, 28416, 19456, 3328, -10752, -15872, -14336, -13056, -11264, -5888, 4864, 19200, 24832, 17152, 2048, -11264, -16128, -14848, -14336, -12288, -6656, 4864, 19200, 24064, 16384, 2048, -10240, -14080, -12800, -12544, -10752, -6400, 4608, 17664, 21760, 14592, 1024, -10496, -13824, -13056, -12800, -11520, -7168, 4608, 18176, 22528, 15360, 2048, -8960, -11776, -12032, -12288, -11776, -7680, 4096, 16896, 21504, 15104, 2304, -7680, -10496, -11008, -10752, -10240, -5632, 6400, 18688, 22528, 15360, 2048, -7680, -10752, -11776, -11520, -10752, -5376, 7168, 18944, 21248, 13312, -256, -9216, -11776, -11520, -10240, -9472, -4352, 6656, 16896, 18688, 10496, -2560, -10752, -13824, -13568, -12288, -11008, -4864, 6912, 17408, 19456, 11264, -1024, -8704, -11264, -10496, -9472, -8448, -2560, 8704, 18176, 19200, 10240, -1792, -9216, -12032, -11008, -9984, -8960, -2304, 8960, 18432, 19200, 9984, -1792, -9728, -12544, -11520, -11008, -9728, -2816, 8448, 17408, 17920, 9216, -1024, -7936, -9984, -9216, -8960, -7936, -1280, 9216, 17664, 17664, 8960, -1024, -7936, -9728, -8960, -9472, -8448, -2048, 7936, 16384, 16128, 7936, -1792, -8704, -10752, -10240, -11008, -9728, -3072, 7168, 15616, 15104, 6912, -2560, -8704, -10240, -9728, -10496, -8960, -2304, 7936, 16128, 15360, 7424, -1536, -7936, -9472, -9728, -10752, -8960, -2560, 7424, 15360, 14336, 6912, -2048, -7680, -8448, -8704, -9728, -8192, -2560, 7168, 14336, 13056, 5888, -2304, -7424, -8192, -8704, -9728, -8448, -2560, 7424, 14080, 12800, 5888, -2304, -7168, -7680, -8448, -9472, -8192, -2048, 8192, 14336, 13312, 5888, 5888, 0, -512, 0, -512, -1536, -1536, -1536, -1280, -512, -256, 1280, 3840, 5120, 2816, 3072, 3072, 1536, 0, -2048, -4864, -3072, -1024, -4864, -4864, -1024, 1024, -1792, -768, 1280, 2048, 2816, 3584, 2304, 2304, 2048, -1024, -2816, -1536, -2048, -4096, -3584, -1792, -256, -768, 256, 2560, 3328, 6144, 7168, 3072, 2560, 3584, 2816, -3584, -7424, -4864, -3072, -5376, -6400, -4096, 512, 0, -2816, -1792, 1792, 2560, 0, 0, 1280, 2816, 1536, 2560, 5376, 3328, 1792, 3584, 1024, -1024, -2304, -1280, -2816, -4096, -1792, -768, 768, 3840, -512, 512, 4352, 1536, -4864, -4096, 768, 768, -3584, -2560, 1792, 1792, 1024, 2048, 2816, 1024, -1280, -3072, -2304, -1536, -3584, -3328, -4352, -3328, -2048, 1280, 2304, 768, 2560, 3072, 6144, 7168, 6656, 8960, 5120, -768, 6144, 5888, -4864, -7936, -5888, -5888, -9728, -8704, -4608, -2560, -2048, -1536, -1024, -256, 1280, -1024, -2048, 512, 3840, 3072, 6656, 14336, 9472, 2560, 6400, 6400, -1024, -5376, -6144, -5888, -6656, -7680, -6912, -2048, 2560, -1280, 768, 7680, 1536, -6656, -1792, 3328, -512, -4864, -512, 2816, 768, 3584, 5376, 2048, 3072, 1280, -4864, -6656, -3072, 2304, 256, -2048, -2048, 5120, 6912, 4352, 4096, 3840, 0, 5888, 9984, 2816, -1024, -3328, -5376, -5376, -8192, -9216, -6912, -5120, -6144, -2560, -1024, 1280, 3584, 1024, -2816, -2560, 1792, -2048, -1792, 1792, 1792, 512, 3840, 7424, 14080, 6656, 1024, 5632, 9472, 8192, 3584, 2560, 4608, 1792, -256, -7168, -12544, -6144, -3584, -10496, -13568, -9472, -7168, -6912, -3840, 256, 512, 3584, 3584, 3328, 768, 0, 256, 4608, 2304, 1792, 2816, 5888, 5888, 6400, 4096, -1792, 256, 3328, 6656, 6656, 2304, 3328, 7168, 7168, 256, -7424, -7424, -6656, -6912, -11008, -11008, -7936, -3072, -6656, -3840, 1536, 4096, 1536, 5632, 2816, -1024, 0, 768, 0, -1024, -5120, -2304, 3840, 5888, 4864, 1792, 6400, 4864, 10752, 16128, 10240, 3328, 5632, 6144, 256, -10496, -15360, -14080, -16128, -17664, -15616, -7936, -1792, 2560, 2048, 0, 1792, 1024, 1024, 5120, 1280, -1024, 2304, 6912, 7936, 6912, 5888, 3328, 4864, 3072, 512, 1024, 3840, 5120, 8960, 4864, 4096, 6656, 768, -7680, -12288, -7936, -10240, -15360, -15104, -12032, -3328, -768, 3072, 5632, 2816, 1792, 2304, 2048, 768, -2560, -8704, -1280, 1536, 6144, 9728, 4864, 3328, 5376, 10240, 3840, 512, 6912, 6656, 4096, 11264, 12032, -1792, -11008, -10496, -7424, -11264, -20480, -20736, -14848, -6656, -4352, 768, 4096, 7680, 4864, 2560, 6400, 4096, 1536, -3072, -768, 3328, 7680, 9728, 5120, 4352, 5632, 6400, 4608, 3328, 4096, -768, 256, 8192, 11264, -2816, -12288, -13056, -8704, -9728, -12544, -16384, -17920, -5888, -2560, -3584, -256, 5120, 4608, 5120, 5376, 2816, 768, -2048, -768, 3328, 3584, 5632, 4608, 8192, 9472, 7680, 6400, 4096, 6912, 6912, 4608, 9472, 13312, 3072, -6656, -14336, -14592, -11776, -18176, -23552, -22016, -12800, -5376, -2560, 2048, 3840, 3840, 4608, 7168, 4352, 256, 256, 512, 3328, 3328, 5888, 5888, 5376, 7424, 7936, 7424, 3840, 5120, 8448, 8192, 7424, 11776, 5376, -7936, -12544, -13568, -13056, -16896, -20992, -19456, -13824, -8192, -2560, 3072, 4864, 7424, 4608, 768, 0, 4096, 5120, 7424, 7936, 5120, 6400, 7936, 11008, 10496, 8704, 11264, 6912, 7424, 16640, 13824, -3840, -17920, -20224, -16128, -22016, -29184, -29184, -20224, -6656, -512, 1536, 4608, 4864, 2560, 4864, 6656, 3840, 1280, 0, 4096, 5888, 7424, 7680, 5376, 6400, 7168, 9472, 9472, 9728, 11264, 8192, 7424, 16896, 16640, -1792, -17152, -18944, -15104, -20992, -29184, -29952, -21760, -7936, -512, 2816, 5120, 4608, 2304, 5120, 7680, 3840, 1280, 0, 0, 256, 256, 512, 768, 768, 768, 1024, 1024, 1280, 1536, 1536, 1792, 2048, 2048, 1792, 1792, 1792, 1792, 1792, 1536, 1024, 768, 512, 0, -256, -512, -768, -1280, -1536, -2048, -2304, -2304, -2816, -3072, -3584, -3840, -4352, -4352, -4352, -4608, -4864, -4864, -4864, -4608, -4352, -4096, -3840, -3328, -2816, -2048, -1792, -1536, -1280, -768, -256, 0, 0, 256, 768, 1280, 2048, 2560, 3072, 3584, 4352, 4864, 5376, 5888, 6656, 6912, 7168, 7168, 7168, 6656, 6400, 6144, 5888, 5888, 5376, 4864, 4608, 4096, 3840, 3584, 3328, 3072, 2816, 2816, 2816, 2560, 2048, 1536, 1280, 1280, 1024, 512, 0, -512, -1024, -1280, -1792, -2560, -2816, -3072, -3328, -3584, -3840, -3840, -3840, -3840, -3840, -4096, -4352, -4608, -4608, -4864, -5376, -5888, -6400, -6912, -7168, -7424, -7424, -7680, -7680, -7424, -6912, -6400, -5888, -5632, -5120, -4608, -4096, -3584, -3328, -3072, -2816, -2816, -2560, -2304, -2048, -1536, -1280, -1024, -768, -256, 256, 768, 1024, 1536, 1792, 2048, 2048, 2304, 2560, 2816, 3072, 3328, 3328, 3328, 3328, 3840, 4608, 5376, 5888, 6144, 6400, 6400, 7168, 7936, 8448, 8704, 8704, 8192, 7936, 7936, 7936, 7680, 6912, 5632, 4096, 3072, 2560, 2304, 1792, 768, -1280, -3328, -4864, -5632, -5632, -5888, -6400, -7168, -7936, -8448, -8448, -8192, -8192, -7936, -8192, -8448, -8192, -7424, -6400, -5376, -4864, -4864, -4864, -4864, -4608, -3840, -2304, -768, 512, 1536, 2304, 3072, 4096, 5376, 6912, 8192, 9472, 9984, 10240, 10240, 9984, 9984, 10240, 10496, 10240, 9728, 8960, 8704, 8704, 8448, 7424, 5632, 4096, 2816, 2560, 2816, 3072, 3072, 2560, 2048, 1792, 1280, 768, 512, 0, -1536, -3072, -4864, -5888, -5888, -5632, -5888, -6656, -7680, -8448, -8448, -8448, -8704, -8960, -9472, -10240, -11520, -12800, -13568, -13312, -12288, -10752, -9472, -8192, -6912, -5632, -5120, -4608, -4096, -4096, -4608, -5376, -6656, -7680, -8448, -8704, -8960, -9216, -9728, -10240, -10496, -10496, -9728, -9216, -9216, -9728, -10496, -10240, -9728, -8704, -7680, -6912, -6400, -5632, -5120, -4096, -3840, -4096, -4352, -4608, -4096, -3328, -2560, -1792, -1024, -512, 256, 1536, 2816, 4096, 5376, 6144, 6400, 6656, 6144, 5632, 4864, 4608, 4864, 5632, 6144, 6656, 7680, 8448, 9728, 11264, 12800, 14336, 15616, 16128, 17408, 18432, 18944, 18688, 17408, 16384, 14592, 12800, 12032, 11776, 11264, 9472, 5376, 768, -2816, -5120, -5888, -6400, -7680, -8448, -9216, -9216, -8704, -7936, -6912, -5632, -5376, -5632, -5376, -4608, -5376, -6144, -6912, -7936, -8448, -8192, -6912, -5376, -3584, -3328, -4352, -4352, -2560, 0, 2560, 3840, 4096, 3584, 2048, 1536, 2560, 4096, 6400, 8704, 9984, 11008, 12032, 13568, 15872, 18432, 20992, 22784, 23552, 23040, 21504, 20224, 19712, 19712, 19456, 17152, 13824, 10752, 8448, 6656, 4608, 1280, -2816, -6912, -10496, -13568, -16640, -18688, -19712, -20224, -20736, -22016, -23808, -26112, -28160, -29696, -30208, -30720, -31744, -32512, -32768, -32768, -32256, -31232, -29696, -27392, -24576, -21760, -19968, -18432, -16384, -13824, -11520, -9984, -10240, -11776, -12544, -12544, -12032, -11520, -11264, -11520, -11520, -11264, -10752, -9728, -8448, -7424, -6656, -5888, -5120, -4608, -3584, -2816, -2048, -1280, -512, 512, 1792, 2816, 2560, 2048, 1792, 2304, 4096, 5632, 6656, 7168, 7936, 8704, 9984, 11264, 12544, 13568, 14592, 15360, 15872, 16128, 16128, 16640, 16896, 16128, 14592, 13056, 11776, 11776, 12800, 13568, 13824, 14080, 13824, 14080, 14592, 16128, 17664, 18688, 19200, 18688, 17664, 16896, 16384, 16640, 16128, 14080, 11008, 7680, 4608, 2816, 768, -1536, -3840, -5888, -7424, -8192, -8192, -7168, -5632, -4096, -3328, -4096, -4096, -2816, -512, 2304, 3840, 256, 0, 0, 0, -256, 0, -768, 0, -256, 0, -4608, 5376, -5632, 5888, -10496, 5120, 21504, -9984, 12800, -15616, 6656, -32256, -4864, -9472, 3840, 512, 17920, -8448, 32512, -14080, 29952, -18688, 3840, -11520, -12800, 2048, -2816, 5888, 8448, 256, 6656, -17152, 6656, -6400, 3584, -11520, 14592, -31744, 3072, -1024, -5888, 27392, -13824, 32512, -12544, 11008, 6912, -15104, -7680, 3840, -32768, 1280, -32768, 22016, -9984, 20992, 3072, 15872, 2304, 13056, -15104, 13568, -24320, 17152, -23552, 17408, -7168, 24064, 5376, 12032, -2816, -256, -10496, 0, -6400, -2304, 4608, -17408, 3840, -6912, 12544, -6912, 26368, -1024, 768, -9216, 14848, -25088, 14336, -29696, -7936, -31488, 6400, -14848, 22784, -5376, 28160, -6400, 18688, -7168, 9984, -5376, 8960, -10240, 9472, -5120, 12800, 14080, 13056, 1536, 256, -12032, -2816, -8192, -5888, 9728, -17152, 768, -13824, 8704, -14080, 20224, 256, 8192, -15616, 22784, -22016, 13568, -17152, -2560, -32768, -1536, -17408, 13056, -1024, 20992, 3840, 21248, -4096, 16128, -6144, 14080, -7424, 2048, 0, 1536, 2816, 13824, 3584, 4096, -9984, -2304, -3072, -12032, 9472, -10240, -5632, -15360, 5376, -19456, 13056, -4352, 18944, -16128, 25088, -9216, 11264, -8448, 6144, -28928, -9472, -22784, 5120, -7680, 17152, 4608, 22272, 0, 17152, -1536, 9728, 256, -512, -4608, -1280, -5120, 8192, 4352, 5376, -2048, -7680, 3840, -12032, 2816, -4352, 2816, -24832, 11008, -22272, 6912, -9216, 23296, -10496, 16896, 768, 11264, -7168, 14080, -18944, -9472, -23552, -5376, -9472, 8448, -256, 19200, 5632, 9216, 3584, 6656, 2048, 2048, -3072, -1792, -5376, -256, 6912, 2816, 5376, -7680, 5376, -9472, -768, -3328, 5888, -6912, -8192, -2560, -5888, -11264, 14336, -256, 11008, -3072, 19456, -7424, 12288, -2304, -6400, -18176, -17920, -12288, -5120, 512, 2304, 14336, 2048, 14336, -2560, 13312, -3072, 7936, -7424, 6912, -15360, 15872, -10752, 21248, -11520, 7680, -6144, 1024, -6656, 8448, -5888, 1280, -4608, -6400, -13568, -1792, -1536, -1536, 4864, 4096, 7936, 768, 14848, -3584, 0, -16384, -8448, -14848, -2048, -11008, 10752, -4608, 14592, -2304, 13824, 256, 12032, -768, 9216, -4608, 768, 1024, 1536, 512, -4352, 2048, -3584, -6912, 8960, 512, -768, 256, -2048, -11008, -8704, -256, -5632, 3072, 512, 9472, -1536, 13568, 3584, 4096, -11008, -5632, -19200, -512, -17152, 5888, -6144, 9984, -768, 9984, 1536, 11264, 2304, 9472, 1280, 256, 768, 1280, 3072, -4608, 0, 0, -7936, 1280, 5888, 256, -768, 2560, -5120, -12288, -1536, -7680, 1792, -4608, 8960, -1024, 8192, 5376, 9984, -6656, -256, -19200, -2304, -16640, -768, -7168, 5120, -1280, 8192, 1280, 9216, 5120, 7680, 7680, 768, 2560, -256, 4096, -2560, -1792, -256, -4352, -5888, 4608, 3584, -768, 2048, 2304, -11520, -3584, -8960, -256, -6912, 4608, -512, 7424, 256, 15616, -3584, 5120, -14336, -4864, -13056, -5632, -9728, 2304, -3584, 5632, 1280, 6144, 6912, 5888, 10496, 3328, 5120, -1792, 5888, -512, -2048, -512, -2304, -6656, -1536, 3584, 2816, -2816, 9472, -8448, -3072, -9728, -1536, -8448, 1792, -3584, 7680, -3072, 14080, 1024, 8448, -8192, -3584, -11520, -5632, -11008, -1792, -3840, 4608, 4608, 8448, 4352, 10496, 5632, 3840, 3584, 2048, -6144, -4096, -4608, -4096, -1792, 1536, 4096, -512, 2048, -3584, -1536, -5888, 0, -5632, 256, -5888, 5376, 1024, 6144, -256, 2304, -2304, -2816, -3584, -3328, -4096, -3584, -3840, -3072, -4096, -1280, 2048, 7168, 6400, 7168, 8704, 6912, 3840, 4096, 512, -5120, -5632, -5120, -3840, -2048, 2560, 2816, 1792, -768, -1280, -4096, -2560, -3328, -1280, -4096, -1280, 1024, 4352, 3328, 1536, 256, -2304, -256, -512, -768, -1024, -1024, -1280, -1280, -1280, -1280, -1280, -1280, -1280, -1280, -1280, -1280, -1280, -1536, -1536, -1536, -1536, -1536, -1280, -768, -768, -1280, -1280, -1280, -1792, -2048, -1280, 1024, 1280, 3328, 3072, -3072, -1280, 2560, 1280, 1024, 0, 768, 6656, 8448, 2560, -3840, -17664, -22784, -6400, 6400, 14848, 17920, 5632, -10496, -15872, -7936, 4608, 4352, -4352, -3072, -2304, 5120, 25344, 24576, 0, -22528, -31488, -17664, 15616, 29696, 13824, -2816, -11520, -7168, 10240, 9728, -10752, -15104, -13568, -7936, 16128, 19968, -2304, -16640, -21248, -15104, 12288, 28160, 12800, -2816, -13056, -13824, 10496, 24576, 2304, -22272, -30464, -19712, 10752, 30208, 17152, -4608, -14592, -11776, 6144, 22784, 20736, 5632, -11008, -19712, -16640, -10496, -5888, -768, 1024, 2048, -3328, -13824, -13312, -5376, 7680, 22784, 22016, 2048, -12544, -19456, -14336, 7680, 14080, 13312, 12032, -1792, -11520, -12544, -12288, -2560, 17408, 18944, 11008, 5632, -6912, -6400, 3072, 5120, -1280, -11008, -17664, -11776, 5376, 13568, 13056, 9728, -2048, -8192, 1536, 5120, -256, -4864, -14336, -17152, -6656, 6912, 19456, 24320, 5888, -16384, -15360, -3840, 8448, 9984, -2048, -9472, -6144, -1792, 1792, 1024, -6400, -5888, -2560, -3584, -1792, -1280, -3072, 512, 7168, 7936, 9472, 5376, -4608, -4096, -1024, -5632, -9472, -11776, -14336, -2048, 14848, 16384, 13568, 7936, -2304, -2304, -512, -14592, -21760, -13312, -3328, 15104, 23552, 5376, -10752, -12032, -8448, 6912, 19200, 6912, -5632, -9728, -11264, 4608, 19712, 8192, -5376, -11776, -12800, 8704, 22784, 5632, -9472, -15360, -14336, 7936, 24320, 9216, -6912, -14592, -20992, -3840, 13568, 3840, -3328, -6400, -11264, 3584, 16896, 3584, -8192, -13568, -15872, 6400, 24576, 12800, 768, -8192, -14336, 6400, 25088, 13056, -2304, -14336, -19968, 1792, 23552, 18176, 7168, -7936, -23552, -10752, 7168, 5120, 6144, 2048, -8704, 5632, 17920, 4608, -4352, -13568, -22528, -5120, 9984, 1792, -512, -2048, -7168, 8960, 20480, 4864, -5888, -14080, -23808, -5632, 16128, 13824, 12032, 4864, -13312, -8960, 512, -9216, -8192, -4608, -12544, -2304, 10496, 3840, 6656, 8704, -5632, -1536, 7936, 256, 2048, 2304, -11008, -3840, 7680, -768, -256, -1792, -18688, -12288, 1536, -3584, 1280, 3328, -12032, -7680, 3072, -3328, 1536, 4608, -9472, -3328, 9984, 6912, 11520, 9728, -9472, -8192, 3072, 768, 8192, 11776, -2560, 1536, 12288, 4096, 3840, 3840, -8192, -512, 12032, 6144, 6656, 4608, -13056, -13056, -3840, -7424, -256, 4864, -7168, -3840, 5376, 512, 4608, 5632, -8704, -6144, 3328, -768, 3840, 3584, -11520, -8704, 1792, 2560, 9728, 7936, -8704, -7680, 1024, 1280, 11008, 15616, 3328, 1024, 1536, -5632, 1024, 6144, -3328, -3328, -2560, -8704, 0, 5888, -4096, -4096, -3328, -10752, -4608, -1024, -9216, -4352, 1280, -2560, 3584, 5632, -5376, -5632, -4096, -9472, -1536, 5120, -512, 4352, 9216, 4864, 11008, 11008, -2304, -3840, -3072, -7424, 1536, 7936, 1536, 2560, 1792, -5888, -512, 2304, -5888, -3840, -2560, -6656, 768, 5120, -1280, 256, 0, -5632, 1280, 5632, -1536, -2048, -4096, -9472, -1280, 5120, 512, 2816, 1536, -4864, 2816, 8448, 3072, 5120, 4096, -1792, 5120, 8960, 2816, 2816, -768, -7168, 512, 4864, -256, 768, -1536, -7424, -1280, 512, -6400, -4352, -3072, -4096, 5632, 8704, 768, -1024, -5376, -9216, 1024, 6656, 2048, -256, -7680, -13824, -5888, -768, -2816, 0, -3072, -6912, 1792, 6144, 3328, 4864, -256, -5376, 2560, 6912, 3584, 4352, 0, -3584, 4608, 8448, 4864, 3584, -4352, -10496, -2560, 2304, 512, 1792, -3584, -7680, 1024, 5120, 2304, 2304, -3840, -8960, -768, 4096, 2304, 0, -256, -512, -768, 1024, 1792, 1024, -512, -768, 0, 768, -256, -256, 1024, 1280, -512, -3328, -2304, 256, 1024, 512, 256, 512, 512, -512, -2048, -1024, 0, 1024, 1024, -768, -1024, -768, 256, 512, -256, 768, 3584, 256, -1792, -3072, -1024, -512, 256, 256, 2304, 1280, -1536, -1280, -512, -256, -256, 256, 3584, 1536, -1536, -1792, 768, 2048, -512, -1024, 3328, 3072, -2560, -4352, -2560, -1280, -1024, 512, 768, 1792, -1536, -1536, -256, -256, -1024, 256, 2816, 1536, -1536, -2304, 2560, 2816, 768, 256, 3584, 3840, -3072, -5120, -3072, -2304, -3840, -256, 1792, 512, -4096, -1792, 1536, 0, -512, 2560, 6656, 4352, -1536, -2816, 6144, 5376, 256, 0, 4608, 3840, -4352, -7936, -7168, -5888, -3584, 0, -1024, 0, -4096, -2048, 2048, -1024, -768, 1792, 3840, 1280, -768, -768, 6656, 6400, 3072, 2048, 7168, 4352, -3840, -7168, -4608, -4352, -4608, -1792, -768, -1792, -5120, 0, 1792, 256, -2304, 1536, 2304, -1024, -2304, 512, 3840, 6144, 8704, 7936, 2560, -1024, -3840, -7424, -4352, -5376, -10496, -10240, -1280, 4864, -5120, 768, 2816, 8448, 7168, 5376, 4608, 3840, 4096, 768, -256, 4608, 4352, 3840, 256, -3840, -2560, -1280, -3584, -10752, -12288, -11008, -6656, 1024, -7424, -3584, -2304, 8192, 5120, 3072, 3840, 5376, 9984, 6144, 2048, 6656, 8448, 1536, -768, 0, 256, -1792, -4096, -10496, -11264, -13056, -8704, -768, -1536, -1536, -4864, 6656, 2560, 3840, 8960, 11776, 8192, 5120, 4096, 5888, 9728, 3840, -1024, -2560, 4352, -1536, -10496, -12288, -13568, -17920, -13312, -2304, -2304, -5632, -3840, 4864, 6144, 5632, 7680, 12544, 8704, 2560, 256, 3840, 8448, 3840, 256, 4352, 11776, 3072, -9728, -15104, -12800, -14592, -11776, -3328, -4096, -7680, -6144, 6656, 9472, 8448, 7680, 11520, 10240, 512, -2816, 4352, 10496, 6144, -1024, 4096, 12288, 3840, -9728, -17152, -16384, -16640, -11776, -4608, -4608, -8960, -8192, 8960, 9984, 9472, 5376, 11520, 10752, -512, -4864, 3584, 9472, 5632, 1792, 6144, 10240, 3328, -10752, -17408, -16128, -16128, -9728, -1536, -3072, -8704, -6400, 9984, 11008, 9984, 4352, 12032, 11520, 768, -4864, 5376, 11520, 6400, 512, 5376, 7936, 0, -11520, -18176, -19968, -21248, -12288, 512, 1792, -6912, -8192, 8704, 11520, 12544, 5888, 11264, 9216, 1280, -1280, 9728, 15360, 6912, -3328, 5376, 10752, -3328, -17664, -20736, -22016, -20224, -9728, -2304, -2816, -10496, -9216, 9728, 14336, 11520, 2560, 11008, 11008, 2560, -1536, 9216, 14592, 10496, 2560, 9216, 11776, -4096, -17152, -16896, -18176, -20480, -11264, -2048, -1280, -7424, -6912, 7680, 11008, 11776, 5120, 13312, 9984, -2304, -5376, 10240, 17408, 10752, -256, 5120, 8192, -3584, -17920, -22016, -24064, -23040, -11520, -512, 0, -7936, -4352, 9216, 12032, 11776, 4608, 11264, 7424, -512, -2816, 11776, 18944, 13056, 3584, 9216, 11776, -3840, -19968, -22272, -23296, -22784, -11776, -3072, -2816, -7168, -1280, 10496, 11776, 10240, 4352, 13056, 8448, -1536, -3328, 12544, 19200, 13312, 3840, 7680, 8704, -5376, -20224, -22528, -23808, -22528, -10752, -2304, -1024, -6400, -768, 9216, 10240, 8704, 4096, 11264, 5888, -2048, -2560, 13312, 21248, 14080, 4352, 9728, 7936, -7936, -20992, -23296, -23808, -20992, -9984, -4096, -2560, -6400, 1280, 8448, 10752, 8192, 5120, 13824, 6400, -2304, -768, 15104, 21760, 16128, 6144, 9472, 6144, -9984, -22016, -23552, -24832, -20480, -8704, -4352, -3840, -6144, 2560, 8960, 11520, 8192, 4096, 11520, 3072, -5888, -512, 15872, 19968, 13568, 5376, 9472, 6656, -9984, -23296, -24320, -24576, -19712, -7424, -4096, -4096, -6400, 2560, -256, 0, 768, 5376, -6656, 4608, -7680, 8192, -4864, -3840, -6912, 512, 0, 26368, -21504, -13568, -13312, 20224, 13056, 9216, -17664, -7936, 12288, 18176, 8448, -18944, -16384, 2560, 13056, 12544, -17408, -23296, -4096, 7680, 8448, -7936, -14848, -10752, 3584, 6144, -6400, 5888, -18176, 20224, -5632, 31488, -18944, 7168, 7168, 29440, 25344, -1792, 2304, -3840, 18432, 256, 4096, -12032, -1280, -18176, -4608, -19200, -6656, -18176, -7168, -14336, -6144, -14592, -4864, -8448, -1280, 1792, -768, 3584, -2048, 20992, 25600, 5888, -8192, -3840, 20480, 25088, 17408, -7680, -5376, 6144, 18176, 7168, -10496, -24576, -5632, 8192, 9472, -14592, -28160, -17152, 7168, 8960, -5632, -28672, -20224, 3328, 17920, 6912, -14080, -16128, 7936, 24320, 22016, -1024, -10240, 7424, 28160, 28160, 7168, -12800, -3072, 16896, 20480, 3584, -22272, -20736, -1792, 9216, -1280, -24320, -30208, -10752, 6656, 2048, -17664, -30976, -12288, 9472, 15360, -1536, -17408, -7424, 17152, 26624, 15616, -6144, -4352, 17920, 31488, 23552, -1280, -11008, 5888, 20992, 17152, -7168, -24576, -13824, 4608, 7680, -9984, -29440, -24576, -1792, 6400, -3328, -25344, -25856, -3328, 13312, 10752, -8960, -15872, 2304, 22528, 23808, 7168, -8192, 3840, 24832, 30208, 14848, -7424, -6144, 13056, 20992, 9984, -15616, -22528, -6656, 7168, 2304, -17920, -29952, -16128, 1792, 3584, -11776, -27904, -18176, 3840, 14080, 4096, -13056, -10752, 11008, 24064, 19200, 512, -5376, 12288, 27392, 25856, 5888, -9216, 1024, 16640, 17920, 256, -20736, -17664, -768, 6656, -4864, -24064, -27136, -8192, 3584, -768, -18944, -26368, -9472, 8704, 11776, -2560, -14336, -3072, 16896, 23296, 12544, -3840, 256, 18944, 28416, 19456, -1024, -7168, 7936, 18432, 12800, -8448, -21760, -11008, 2816, 3840, -11776, -27136, -20480, -2816, 3328, -6656, -23552, -21504, -2048, 11264, 7424, -7680, -12288, 4864, 20480, 20736, 6656, -4608, 6912, 23296, 26368, 12544, -5632, -2560, 12288, 17408, 5632, -15360, -19200, -5632, 4352, -1280, -18176, -26880, -13824, 768, 768, -12544, -25088, -14848, 3584, 11264, 2816, -11264, -6912, 11520, 21760, 16640, 1280, -2048, 13568, 25600, 22272, 5376, -6656, 2816, 15360, 14336, -1536, -18944, -14848, -1024, 3328, -6400, -23040, -23296, -7424, 1792, -3072, -18432, -23040, -7424, 8192, 9472, -2560, -11776, -512, 16896, 21248, 12032, -2048, 2560, 18944, 25856, 17408, -768, -4864, 7936, 15872, 9728, -9216, -19712, -10240, 1536, 1024, -12544, -25600, -18432, -3072, 768, -7936, -22016, -18688, -1024, 9472, 6400, -7168, -9216, 6400, 19200, 18944, 6400, -2304, 8704, 22528, 24064, 11008, -4096, -1024, 12032, 14848, 3840, -14592, -17664, -5632, 1536, -3072, -18688, -24576, -12800, -1024, -1792, -13568, -22784, -12544, 3328, 9216, 1280, -9472, -4352, 12032, 19712, 15104, 2304, 512, 14848, 23552, 20224, 4864, -4352, 4096, 13824, 11520, -3328, -17664, -13312, -2048, 768, -8448, -21760, -20992, -7424, -512, -5120, -17408, -20224, -5888, 6144, 7424, -2816, -8704, 1792, 15616, 18688, 10496, 0, 5632, 18688, 23040, 14848, 256, -2304, 8192, 13312, 6656, -9216, -17664, -8960, -768, -1792, -13568, -23040, -16128, -4096, -1792, -9216, -19968, -15360, -1024, 7424, 4096, -5632, -5888, 7424, 17408, 16384, 6656, 512, 10752, 20480, 20736, 9728, -2048, 1280, 10752, 11264, 1024, -13568, -14592, -5376, -512, -5632, -17664, -21248, -11008, -2560, -3840, -13056, -19712, -9728, 2816, 6912, 768, -6912, -1280, 11776, 17408, 13312, 3328, 3840, 14848, 21248, 17408, 4864, -2048, 5376, 11776, 8192, -4096, -15360, -11264, -3072, -1536, -9216, -19456, -18944, -8704, -2560, -5120, -14592, -18688, -8448, 3072, 6912, 768, -256, -1536, -2816, -768, 1024, 0, -1792, -2048, 256, 5376, 3584, 7168, 8448, 6400, -256, 1792, 1024, -3328, -5376, -11264, -7424, -4352, -7936, -8192, 512, 0, -5120, 1024, 768, 1024, 0, -512, -1280, -1024, -3584, 768, 3584, 2304, 7168, 8704, 13824, 11008, 13824, 9984, 4864, 4352, -256, 1280, -5888, -7936, -6400, -8960, -11776, -15360, -7424, -7424, -3328, -9472, -5632, -4096, -5120, -6912, -5376, -1536, -4096, 2048, -1280, 3840, 6656, 17664, 16640, 18944, 21760, 20736, 19456, 13056, 5632, -2560, -2560, -4864, -768, -9984, -18688, -14080, -9216, -4608, -11520, -12544, -11520, -13312, -12032, -18944, -18688, -14336, -7936, -3840, -4096, -1280, 4608, 16640, 22016, 27648, 24064, 24832, 23040, 20224, 13824, 7680, 4864, 2560, 6400, -4096, -8704, -9472, -2304, -4096, -8960, -11264, -15360, -15360, -12800, -15872, -17920, -16896, -11264, -8704, -8704, -7424, -2560, 5888, 15616, 21760, 20224, 19200, 17920, 15616, 10496, 7936, 1792, 2048, 768, -5632, -10752, -7168, 0, -3328, -7424, -9984, -13312, -14336, -14080, -14848, -15360, -14592, -10496, -8960, -9472, -4864, 1280, 8960, 18176, 22272, 21760, 24832, 28672, 24832, 18176, 14336, 13312, 13568, 11008, 4608, -1792, -768, 2560, 0, -4352, -9984, -14080, -14848, -16384, -20480, -27136, -30976, -28672, -28160, -28928, -26880, -20992, -13056, -2048, 4096, 5120, 11520, 16896, 16896, 12544, 11776, 15104, 19200, 19968, 16128, 15872, 18944, 20480, 20480, 17664, 13056, 6912, 2816, 0, -3584, -10240, -13568, -12288, -14080, -17408, -18176, -14336, -8704, -256, 3584, 6144, 12544, 15872, 15104, 10752, 8704, 11008, 12032, 11008, 6656, 7680, 8448, 9728, 6656, 1024, -4352, -10496, -16896, -20736, -23552, -28672, -30720, -29440, -29696, -32768, -32000, -26368, -18176, -9216, -2816, 2304, 8448, 14336, 15104, 13824, 15616, 17152, 19712, 19712, 19712, 20224, 18944, 19200, 18688, 14080, 7680, 2560, -5376, -9728, -11776, -15616, -17920, -17152, -17920, -20736, -19712, -16384, -11520, -5888, -1024, 2560, 7680, 11264, 11264, 9984, 10752, 12288, 13056, 12800, 13056, 14848, 14848, 16640, 16640, 12032, 7424, 3072, -3584, -7936, -10496, -13568, -16128, -15360, -15872, -16384, -14848, -11264, -6656, -2816, 256, 2560, 5120, 5632, 4352, 2304, 1280, 1536, 1536, 512, 1024, 2560, 2560, 4352, 4864, 2304, 1792, -256, -3584, -4608, -3328, -3584, -2304, 256, 1792, 3072, 4352, 5888, 7936, 8960, 9216, 8960, 9728, 7936, 5376, 4096, 768, 0, -2048, -2816, -2816, -3328, -4864, -5120, -5888, -8704, -9984, -13056, -17664, -19968, -20736, -21248, -21248, -19968, -17920, -15360, -12032, -8704, -4864, 512, 5120, 9984, 14592, 15360, 16896, 17152, 16128, 15616, 13568, 12800, 13056, 12032, 9472, 8192, 5888, 3328, 1536, -768, -4352, -5888, -7168, -8704, -9472, -8960, -6912, -3840, -512, 1024, 3072, 5888, 7680, 11264, 12032, 11008, 10496, 8960, 7424, 5632, 3840, 3328, 3584, 1792, -256, -1280, -2816, -4864, -5120, -6400, -9472, -11008, -10496, -11008, -12032, -12032, -10240, -7424, -4352, -1792, 1280, 3328, 5888, 9728, 11264, 9472, 8704, 7936, 5888, 4352, 1536, 256, -512, -2560, -5120, -6400, -8960, -11520, -12800, -13824, -16384, -17408, -16640, -16896, -16640, -15104, -12032, -7680, -4864, -1792, 1280, 3584, 7168, 12288, 15872, 16896, 18432, 19200, 19968, 19456, 17152, 15360, 14336, 11776, 8192, 5120, 2304, -512, -2560, -5376, -8960, -11008, -11264, -12544, -14336, -14592, -13056, -9728, -6400, -3328, -512, 2304, 6400, 10752, 14336, 15104, 16384, 16640, 17152, 16640, 14592, 13312, 12544, 10496, 7168, 4608, 2048, -512, -2560, 0, 2048, 3328, 5376, 5120, 5120, 4352, 2560, 2048, -512, -1536, -4352, -5376, -7424, -5888, -6400, -3584, -1792, -512, 1792, 2560, 5120, 5376, 5632, 5888, 4864, 3584, 2304, -512, -1536, -4608, -5120, -7168, -6400, -5888, -4608, -2560, -768, 1280, 2304, 5632, 4352, 7168, 5632, 5376, 4352, 2816, 512, -2048, -4608, -5888, -6912, -6656, -6144, -4864, -3328, -1536, 768, 2304, 4352, 5120, 7168, 6144, 6400, 5376, 3328, 1536, -1280, -3584, -5376, -7424, -7424, -7680, -5888, -4864, -1792, -256, 2560, 4608, 6400, 7424, 6912, 7168, 5120, 4352, 1280, -1792, -3328, -6656, -7424, -7680, -7680, -6912, -5120, -3072, 0, 2816, 4864, 6400, 6912, 7680, 6656, 7168, 4864, 2816, -512, -3072, -6144, -7680, -8960, -8704, -7680, -6144, -3584, -512, 2304, 4608, 5888, 7168, 6656, 8448, 7936, 7424, 6144, 3072, 1280, -3072, -5888, -7680, -9472, -9216, -9216, -6656, -4864, -1280, 1280, 4864, 5632, 8192, 8192, 9216, 8960, 6656, 5376, 768, -1536, -5632, -8704, -10496, -11264, -9728, -7936, -4608, -1536, 1536, 3840, 5888, 8192, 8448, 9984, 8704, 7936, 5888, 2560, -512, -5376, -8192, -11264, -12032, -11520, -9472, -5888, -3072, 1536, 3328, 7168, 7680, 9728, 10240, 10240, 9728, 5888, 4352, -1536, -3840, -8960, -10752, -12800, -12544, -10496, -7936, -3584, 0, 3584, 6656, 8960, 10752, 11520, 11520, 10240, 6912, 4608, -1024, -3584, -8448, -10752, -13824, -13312, -12032, -9216, -5376, -1280, 3328, 6144, 9984, 11008, 13312, 12032, 10752, 9216, 5120, 1792, -3840, -8192, -11520, -14080, -14336, -13824, -11008, -6912, -2048, 3072, 6656, 9728, 11520, 12800, 13056, 12288, 10240, 6912, 2304, -2816, -7680, -11776, -14848, -15872, -14848, -12544, -7936, -2816, 2304, 6144, 10496, 11520, 13824, 13568, 13824, 11520, 7680, 3584, -2560, -6912, -12288, -14848, -17152, -16384, -14336, -8960, -3840, 1536, 6144, 9472, 11520, 13824, 14336, 14336, 12544, 9984, 4608, 0, -6656, -11520, -15360, -18944, -17920, -16128, -10496, -5888, 1024, 5376, 9984, 12288, 13568, 15616, 14848, 15104, 11008, 7424, 768, -5120, -11776, -16384, -19712, -19712, -17664, -12800, -6912, 0, 5120, 9216, 12544, 14336, 16384, 16384, 16128, 13056, 8704, 1536, -4352, -11776, -16640, -20224, -21248, -19456, -14848, -8448, -1536, 4352, 9728, 12544, 15360, 17152, 17408, 16896, 13568, 9472, 3328, -3328, -9728, -16640, -20224, -23040, -20992, -17408, -10496, -3840, 3584, 9216, 13312, 16128, 17920, 18688, 17664, 15872, 11264, 4864, -2048, -9728, -16128, -21248, -23808, -23040, -19712, -12544, -5120, 3072, 8704, 13824, 16640, 18432, 19200, 19456, 16640, 13056, 6656, -256, -8448, -15872, -22016, -25088, -24576, -22016, -14848, -7424, 1536, 8192, 13824, 16896, 18688, 20224, 19456, 18688, 14848, 9216, 1024, -6912, -15360, -21760, -25856, -26624, -23552, -17920, -9216, -256, 7936, 13568, 17920, 19200, 20736, 20480, 19968, 16640, 10496, 3840, -6144, -14336, -21504, -26880, -27904, -25856, -20224, -11776, -1792, 6400, 14336, 16640, 19712, 20992, 21760, 21248, 17664, 13056, 4864, -3584, -12800, -21248, -26368, -29440, -27392, -22528, -14080, -4352, 5376, 12800, 17152, 20736, 22016, 22784, 21760, 20224, 14080, 7168, -2048, -11776, -19712, -26368, -29696, -29952, -24832, -17152, -6400, 256, 9984, 16896, 20736, 23552, 24576, 24832, 23040, 18688, 11520, 2816, -6912, -16384, -24832, -30720, -32768, -29952, -22784, -12544, -1280, 8960, 16640, 20736, 23808, 25088, 25344, 23296, 19200, 11776, 3072, -6912, 7168, -2304, -10752, -14592, -12800, -4608, 8448, 19712, 19712, 4352, -16384, -24576, -14080, 5632, 18688, 17408, 4352, -11008, -19712, -17152, -3840, 15104, 26112, 20224, 3072, -12288, -18176, -14592, -7168, -768, 2816, 2560, -768, -4352, -1024, 11264, 22528, 20224, 2560, -17664, -26368, -18944, -1536, 13824, 19200, 13568, -1024, -16128, -20480, -9728, 8192, 18688, 15104, 1792, -11008, -17152, -14592, -4608, 8448, 18176, 18176, 6144, -7936, -12032, -4352, 5120, 5888, -3584, -14848, -18688, -12032, 2560, 18688, 28160, 23808, 5120, -15872, -24832, -17408, -1536, 11008, 13824, 7168, -3328, -13056, -16640, -8960, 6656, 18944, 17664, 3072, -12800, -17408, -9472, 2304, 9472, 9472, 4096, -3072, -6656, -1792, 9216, 16640, 11520, -4864, -22272, -28672, -19200, -1792, 14848, 24832, 23552, 10496, -7680, -19200, -15872, -768, 12544, 13312, 1792, -11264, -16128, -11520, -1536, 9472, 15360, 10752, -1280, -10752, -10496, -768, 9728, 10496, 2048, -8448, -13056, -9728, 768, 13824, 23040, 20224, 3072, -19456, -32512, -27136, -7424, 12032, 19968, 16128, 5888, -4864, -9216, -4096, 6144, 12800, 8960, -3840, -15104, -16384, -6912, 4352, 10240, 8960, 2816, -5120, -9984, -6656, 4864, 16128, 17152, 3584, -15616, -24832, -18432, -1280, 16384, 25856, 22272, 6656, -12544, -24576, -22016, -8192, 6144, 10240, 4352, -2816, -4352, -768, 6144, 13056, 14080, 7424, -5120, -16896, -17664, -5888, 8960, 14080, 6400, -6656, -15104, -14080, -3584, 11264, 22016, 20480, 5888, -14336, -26880, -22272, -4864, 12288, 20224, 17152, 6912, -4608, -11776, -11008, -3584, 4352, 4096, -5120, -13824, -12032, 768, 15104, 21248, 16896, 4608, -8960, -16384, -13824, -2048, 11264, 15104, 4608, -12288, -22272, -18432, -4096, 12544, 22528, 21504, 9472, -7936, -20736, -20224, -6656, 8448, 13312, 7424, -1280, -4864, -1536, 5120, 8704, 6912, -1280, -13056, -21504, -18176, -2304, 15872, 24320, 18176, 3072, -10240, -14848, -9472, 2048, 13312, 16128, 5632, -13568, -26368, -22528, -5888, 12032, 20480, 16384, 6144, -3584, -8448, -7168, -768, 5376, 4608, -3840, -11520, -9984, 1280, 14592, 19968, 13824, -256, -15360, -24832, -22784, -7424, 12800, 23552, 17152, 0, -13568, -14592, -3328, 9728, 16384, 13312, 2560, -11264, -20992, -19456, -6656, 7168, 12544, 8192, 256, -3584, -256, 6144, 10240, 9728, 2304, -11008, -22272, -20224, -3328, 17664, 28160, 20480, 1024, -16640, -23040, -17664, -5376, 8192, 14848, 9984, -2304, -12288, -11520, 0, 13312, 17664, 11776, 1280, -8704, -14592, -12800, -3584, 5888, 7168, -2048, -12288, -12288, 1024, 18176, 25344, 17664, 768, -16128, -25344, -22528, -7680, 11776, 23552, 19968, 4096, -11520, -16896, -11264, -1536, 6400, 8704, 4096, -6144, -14080, -11008, 2560, 17152, 20480, 9472, -5632, -12288, -7424, 1792, 7680, 6912, -1280, -13056, -21504, -18688, -2816, 18176, 29696, 24320, 6912, -11008, -21504, -21504, -11008, 4608, 16128, 15360, 2560, -11264, -13568, -2304, 10496, 12544, 3584, -7936, -14592, -12800, -3840, 7424, 15616, 14592, 3584, -9472, -13056, -3584, 9728, 16128, 12032, -256, -15616, -27136, -26880, -12032, 11264, 29440, 28928, 10752, -9216, -16384, -10752, -512, 5888, 5120, -768, -7168, -9984, -5376, 6144, 16384, 15104, 1792, -12288, -17152, -12032, -1792, 9216, 15104, 12032, 512, -14080, -19712, -7936, 14080, 28416, 22784, 1792, -19200, -28928, -24576, -10752, 5376, 15872, 16384, 7168, -3328, -4608, 4352, 11520, 7168, -512, -1792, -1536, -1792, -1792, -2048, -2048, -2048, -2048, -1792, -1536, -1280, -1024, -768, -768, -512, -512, -256, 0, 256, 512, 1024, 1280, 1536, 2048, 2304, 2560, 2816, 3072, 3328, 3328, 3584, 3840, 4096, 4352, 4352, 4352, 4352, 4352, 4096, 4096, 3840, 3840, 3584, 3584, 3328, 3072, 2560, 2560, 2304, 2048, 1792, 1536, 1280, 1280, 1024, 768, 512, 256, 0, -512, -768, -1024, -1280, -1536, -1792, -2048, -2304, -2560, -2816, -3072, -3328, -3328, -3584, -3584, -3584, -3584, -3584, -3840, -3840, -3840, -3840, -4096, -4096, -3584, -3584, -3072, -2560, -3328, -2560, -3328, -1792, -768, -1280, -256, -256, -1280, -1280, 2048, 3328, 2560, 2560, 3840, 4096, 4352, 7680, 8704, 4864, 4352, 5632, 7424, 6912, 5632, 4096, 256, -768, 2048, 4608, 2816, 1536, 2048, 2048, 256, 1536, 4608, 1280, -2048, -1024, 1024, 1280, 768, 1280, -768, -1536, 3072, 7680, 5888, 2304, 1280, 1536, 2304, 3840, 6912, 5120, 512, 0, 2560, 4352, 2048, -256, -1024, -2048, -2048, -768, -1792, -4864, -7168, -6144, -5632, -7936, -10752, -12032, -12800, -12800, -10752, -8960, -8960, -11008, -10496, -7936, -6912, -5888, -4352, -2304, -1792, 768, 6656, 9472, 9728, 9472, 10496, 9984, 9984, 12544, 14080, 12800, 11776, 13568, 14848, 13056, 11264, 9216, 6144, 2304, 1280, 512, -3072, -6400, -7168, -6656, -8448, -10752, -11264, -14080, -16896, -17664, -15872, -15360, -16640, -14592, -10752, -8448, -6656, -3840, -1280, -1536, 0, 3840, 7424, 8704, 10496, 14080, 15616, 15872, 17408, 18176, 15872, 12544, 12544, 12544, 9984, 7424, 6144, 3584, -512, -2560, -4096, -8704, -14336, -17152, -17920, -19712, -21248, -21760, -22528, -23808, -23552, -20224, -18944, -19968, -18944, -15616, -12544, -10496, -5888, -2304, -512, 2816, 8960, 13824, 14336, 14848, 16384, 17664, 18688, 20736, 23296, 22016, 19712, 19968, 19712, 17152, 12800, 9984, 6144, 1536, -1024, -2560, -5632, -10496, -12544, -13312, -15872, -18688, -20736, -22272, -25088, -24832, -21248, -18944, -17920, -16128, -11776, -8448, -5888, -1536, 2304, 4608, 6656, 12288, 17664, 19712, 21760, 24832, 27136, 27392, 28416, 29184, 26624, 22784, 21248, 21504, 19200, 15360, 12800, 8704, 3328, -1280, -4096, -8704, -15104, -18944, -20480, -22016, -24320, -24832, -24576, -26624, -26624, -24320, -22016, -22016, -20992, -16896, -12544, -8192, -2816, 3072, 6656, 9216, 14080, 18688, 20736, 21504, 24064, 26624, 27392, 29184, 30720, 29696, 26112, 23552, 22528, 18688, 13824, 9472, 5376, 0, -4096, -5888, -9472, -14848, -19456, -21760, -24064, -27648, -29184, -29696, -30720, -30464, -27136, -22784, -21504, -19968, -16384, -12544, -9472, -5376, 256, 3328, 6400, 11776, 18176, 22528, 24320, 26880, 28928, 28672, 28928, 29696, 28672, 24832, 23296, 23296, 21248, 17408, 13056, 8960, 2816, -2560, -5888, -9728, -15360, -20480, -22016, -23808, -26112, -27392, -28160, -29696, -30976, -29184, -26112, -25088, -23808, -19712, -14080, -9728, -4608, 256, 3328, 6400, 11776, 18176, 22528, 24320, 26880, 28928, 28672, 28928, 29696, 28672, 24832, 23296, 23296, 21248, 17408, 13056, 8960, 2816, -2560, -5888, -9728, -15360, -20480, -22016, -23808, -26112, -27392, -28160, -29696, -30976, -29184, -26112, -25088, -23808, -19712, -14080, -9728, -4608, 256, -768, -1792, -2048, -768, 256, 0, 768, -1280, -2304, -3584, -3840, -1024, 0, 1792, 3072, 3072, 2816, 4608, 4096, 3584, 3584, 2816, 5120, 3584, 4864, 1792, 3072, 2048, 3328, 2048, 1792, 2304, 0, 2304, -1792, -1024, -1280, -2048, -1792, -2304, -1792, -512, -1792, -1024, 256, 256, 0, -512, 768, 512, 256, 512, 256, -512, -768, -1792, -512, -512, -512, -1280, -1024, -1024, -1024, 768, 1536, 2048, 768, 0, -768, -512, 768, 1024, 768, 512, 512, -512, 256, 0, 512, 768, 2304, 2048, 512, -768, -1024, -512, 256, 1024, 0, -512, 768, 256, 1792, 256, -1024, 0, 512, 768, 256, 256, 512, -1280, 768, -768, -1024, -768, -2048, 512, -1792, 256, -768, -512, -1280, -2048, -1792, -2048, -1792, -1280, -1792, -1024, -2048, -2560, -1792, -2048, -1792, -1280, 0, -512, 0, -512, -768, -768, -512, 0, 256, 0, 256, 0, -768, -768, -1280, -1280, -2304, -2304, -3328, -4096, -5376, -6656, -6400, -6400, -4096, -4096, -3072, -3328, -3840, -2304, 768, 6400, 11264, 16896, 17408, 16896, 12544, 4352, 3328, 4608, 10496, 13056, 10240, 8960, 6400, 5888, -512, -4096, -7168, -2048, -1024, -3072, -4608, -8704, -7424, -7936, -7168, -4608, -1024, 512, 4096, 3328, 5120, 2304, 1024, 512, -768, -1024, -2304, -2304, -2304, -2048, -2304, -2560, -3328, -3584, -3840, -3328, -1024, 1792, 3328, 4864, 4608, 4096, 2304, 1792, 1024, 1536, 2048, 1792, 1792, 768, -768, -3840, -4864, -6144, -5376, -4096, -2304, 0, 768, 1792, 1024, 1024, -768, -512, 1536, 3328, 5120, 3584, 4096, 3584, 2816, 1792, 0, -1024, -768, -768, -1792, -3072, -3072, -2304, -1280, -1280, -1792, -2304, -1024, -512, -512, -512, -1024, -2304, -2560, -3328, -3328, -3584, -3840, -3328, -2304, -2048, -2304, -2304, -1792, -1024, 512, 512, 1536, 2304, 2048, 2816, 2304, 2816, 2304, 2048, 1536, 0, -1792, -3328, -5376, -7424, -9216, -11520, -13568, -16128, -18432, -18688, -15616, -10496, 0, 13312, 25088, 27904, 20736, 16384, 13824, 19968, 19712, 11520, 9984, 11264, 6400, 4864, 1536, -2048, 6400, 7680, 11264, 15872, 11776, -5120, -21760, -22784, -22528, -12032, -7424, -7680, 512, 2816, 2048, 3072, 6144, 8448, 7424, 6400, 5632, 256, -3840, -8704, -9472, -9216, -10496, -9216, -7168, -3840, 512, 2304, 2816, 3584, 3072, 2048, 3072, 4352, 4608, 4864, 5888, 5120, 5120, 5120, 2048, -1280, -3584, -3840, -3840, -3328, -3328, -4608, -4864, -6144, -7424, -8192, -7936, -5888, -3072, -512, 3072, 5120, 5888, 6144, 6400, 5120, 5632, 4608, 4096, 3584, 2304, 1792, 512, 256, -2304, -2560, -4864, -3840, -3072, -3328, -2048, -1280, -1024, -1024, -1792, -2560, -3072, -3072, -4096, -3584, -2048, -2304, -3328, -3584, -4608, -3840, -2560, -1280, -768, 768, 1024, 1536, 2816, 3328, 3328, 4096, 4096, 4096, 3072, 1536, -768, -2560, -4096, -5376, -7168, -9472, -12288, -15616, -19712, -22528, -22272, -17408, -8704, 7168, 23552, 32512, 25344, 16384, 12800, 18432, 23552, 14080, 11008, 13056, 10496, 8192, 1024, -2048, -1792, -4352, -5888, -7936, -8448, -8960, -8192, -7168, -5888, -4608, -3072, -2048, -1024, -512, 0, 256, 512, 512, 768, 512, 512, 512, 512, 512, 512, 512, 512, 512, 768, 1024, 1536, 1792, 1792, 1792, 2048, 2304, 2304, 2048, 2048, 2304, 2816, 3584, 4608, 5632, 6912, 8192, 8448, 7680, 5376, 1536, -3072, -7680, -11520, -13824, -14336, -13056, -10496, -7424, -4352, -2304, -768, 0, 256, 256, 256, 256, 256, 256, 256, 512, 512, 768, 768, 768, 768, 768, 512, 768, 1024, 1280, 2048, 2304, 2560, 2304, 2048, 1792, 1792, 2048, 2560, 3840, 5120, 6400, 7680, 8960, 9984, 9984, 8192, 4864, 0, -5632, -10752, -14336, -15872, -15616, -13568, -10240, -6912, -3840, -1792, -768, -256, 0, 0, 0, 0, 512, 768, 1024, 1280, 1280, 1280, 1024, 512, 0, -256, 0, 512, 1280, 2048, 2304, 2560, 2560, 2304, 2304, 2048, 2304, 2560, 3584, 4864, 6144, 7168, 8192, 8704, 9728, 9216, 7424, 4352, -1280, -7168, -12544, -15616, -16640, -15616, -13312, -9984, -6400, -3584, -1792, -768, -512, -256, -512, -256, 0, 512, 1024, 1536, 1792, 1792, 1280, 768, 0, -256, -256, 0, 768, 1792, 2816, 3328, 3584, 3328, 3072, 2560, 2048, 2048, 2304, 3072, 4352, 5632, 6656, 7424, 7936, 8448, 7936, 6656, 4608, 768, -4096, -8960, -12800, -15104, -15616, -14336, -11776, -8960, -5888, -3584, -1536, -512, 0, 256, 512, 768, 1024, 1024, 1280, 1280, 1280, 1024, 512, 256, -256, -256, 0, 512, 1280, 2304, 3072, 3328, 3328, 3072, 2816, 2304, 1792, 1792, 2048, 2816, 3840, 5120, 6144, 7424, 8448, 8960, 8704, 7680, 5376, 1024, -4096, -9472, -14080, -16896, -17408, -16128, -12800, -8960, -5376, -2304, -256, 1024, 1280, 1280, 1024, 1024, 768, 768, 768, 768, 512, 512, 256, 0, -256, -256, 256, 1536, 2560, 3328, 3840, 3840, 3328, 2816, 2048, 1280, 1024, 1024, 1792, 2816, 4352, 5632, 6912, 8192, 9216, 9984, 9984, 9216, 6144, 1536, -5120, -12288, -17920, -20736, -20224, -17152, -12288, -7424, -3072, -256, 1280, 1792, 1792, 1024, 512, 256, 256, 512, 512, 768, 512, 512, -256, -512, -768, -768, -256, 768, 2048, 3328, 4096, 4352, 4096, 3072, 2048, 768, -256, -768, -512, 512, 2816, 5376, 7424, 9216, 9728, 9984, 10752, 12288, 14592, 13312, 5888, -6912, -19456, -27392, -28928, -25088, -18176, -10752, -4608, -256, 2048, 3072, 3328, 2560, 1792, 768, 256, 256, 512, 768, 512, 256, 0, -512, -768, -768, -256, 512, 2048, 3328, 4352, 4608, 4352, 3072, 1792, 256, -768, -1024, -768, 5120, 7680, 9728, 10496, 9984, 9728, 11776, 16640, 19200, 11520, -5888, -22784, -32256, -32512, -25856, -16384, -7936, -1792, 1280, 2816, 3328, 3584, 3328, 2304, 1024, 256, 0, 256, 512, 256, -256, -768, -1024, -1024, -512, 512, 1536, 2560, 3584, 4608, 4608, 3840, 2304, 256, -1536, -2560, -3328, -2560, -1024, 1792, 5120, 0, 3584, 4864, 5888, 6656, 7168, 7168, 6656, 5888, 4608, 2816, 768, -1024, -2560, -4096, -5376, -5888, -6144, -5632, -5120, -4096, -3072, -2048, -768, 768, 2048, 3328, 4864, 5888, 6656, 6912, 6656, 5888, 4352, 2560, 1024, -768, -2304, -3840, -5120, -6144, -6400, -6400, -5632, -4352, -2816, -768, 768, 2304, 3584, 4608, 5120, 5632, 5888, 5888, 5376, 4352, 3328, 1536, 256, -1536, -2816, -3840, -4608, -5120, -4864, -4864, -4352, -4096, -3328, -2816, -2048, -1280, -256, 512, 1280, 1792, 2304, 2304, 2048, 1536, 768, 0, -768, -1792, -2560, -3584, -4352, -4864, -4864, -4608, -4096, -3072, -1792, -512, 768, 2048, 3328, 4096, 4608, 4864, 4352, 3584, 2048, -256, -2816, -5376, -7936, -9728, -10496, -10240, -8704, -6400, -3072, 512, 4352, 8192, 11520, 14336, 15872, 16640, 16128, 14848, 12544, 9728, 6400, 2560, -1536, -4608, -7168, -9472, -11264, -13056, -15104, -16384, -16384, -14336, -10240, -4352, 1792, 7424, 11776, 14336, 14848, 15104, 14336, 13056, 11520, 8448, 4864, 1024, -3328, -6656, -9984, -12544, -14336, -15104, -14080, -11776, -8704, -4864, -1024, 2560, 5376, 7680, 10240, 11776, 13056, 13312, 12544, 11008, 7936, 4608, 1280, -2048, -4096, -5376, -5888, -6656, -7424, -8960, -9984, -10752, -10240, -8704, -5632, -2816, 512, 2816, 4608, 5376, 6144, 5888, 5632, 4864, 3584, 1792, -768, -3328, -5376, -7680, -9984, -11776, -12800, -13312, -12544, -10752, -7936, -4352, -768, 3072, 6656, 9984, 12544, 14592, 15360, 14848, 13056, 9984, 5632, 256, -5888, -12032, -17408, -20992, -22784, -22528, -19712, -15360, -9472, -2816, 4096, 11008, 16640, 21248, 24064, 25600, 25856, 24576, 22272, 18176, 13056, 7424, 1024, -4608, -9728, -14848, -19200, -23296, -26624, -27904, -26880, -22272, -15616, -6912, 2048, 9984, 17152, 22272, 24832, 24832, 22528, 18176, 13824, 9216, 4096, -512, -5888, -10752, -14592, -17920, -19200, -19200, -18176, -15360, -11008, -5888, -256, 4608, 7936, 12032, 14592, 16896, 18176, 17408, 15616, 12544, 8192, 4352, 256, -2816, -5632, -8448, -10496, -12032, -13824, -15104, -16128, -15872, -14592, -11776, -7680, -3072, 256, 4352, 7680, 10496, 12544, 12800, 12032, 10240, 7424, 4352, 768, -3584, -7680, -11776, -15360, -17920, -19456, -19712, -18688, -16128, -12288, -7168, -1024, 5120, 11264, 16640, 20736, 23296, 23808, 22528, 19712, 15360, 9472, 2816, -4864, -12544, -19456, -24832, -27904, -28160, -25600, -20736, -14336, -6400, 1792, 9728, 17152, 23296, 27904, 30976, 32512, 32256, 29696, 24576, 17408, 9728, 2048, -4608, -11008, -17408, -23040, -28160, -31744, -32512, -29696, -23296, -15104, -5632, 3584, 12032, 19712, 25088, 27392, 26880, 23808, 18944, 13824, 8448, 3328, -1536, -6656, -11520, -15360, -18176, -19968, -20224, -18944, -15616, -10752, -5376, 256, 4608, 8448, 12544, 15360, 17408, 18688, 17920, 15872, 12288, 8192, 3840, 0, -3328, -6144, -8704, -10752, -12288, -14080, -15616, -16640, -16640, -15360, -12288, -8192, -3840, 512, 4864, 8192, 11008, 12800, 13056, 12032, 10240, 7168, 4096, 256, -3584, 512, -512, 512, -1280, -768, -256, 0, -1024, -1024, -1536, -1024, -1536, -1024, -1024, -1792, -1536, -1792, -1536, -256, 0, 768, 3328, 3584, 4096, 3072, 3328, 512, 256, 0, -256, -256, -256, -512, -512, -512, -768, -768, -1024, -2048, -1024, -1024, -1280, -1280, -1280, -1792, -2304, -3072, -2048, -3584, -2816, -3584, -4608, -2048, 256, 7936, 18176, 17408, 6144, -1280, -2816, -1792, -1280, -1280, -1280, -768, -512, -1280, -1280, -2304, -2048, -1792, -1792, -2304, -3072, -2816, -4352, -3584, -4096, -3840, -5120, -6656, -7680, -6912, -3840, 4096, 13056, 22272, 25856, 17920, 2048, -4608, -2816, -3584, -1792, -1792, -256, -512, -1280, -1792, -3072, -3584, -2560, -2560, -3328, -3584, -3328, -4096, -4096, -4352, -4608, -8960, -7936, -7680, -8704, -2304, 4096, 14336, 21504, 22784, 15360, 7680, 1280, -1792, -1280, -2048, -768, -1024, -1024, -1536, -3072, -3584, -3328, -2560, -3072, -3072, -2304, -2560, -2048, -3072, -3328, -3840, -4864, -5888, -6656, -8448, -7424, -7168, -2304, 3072, 11008, 18176, 22528, 18432, 12288, 7424, -512, -4096, -4864, -3072, -3072, -3072, -1792, -2816, -2560, -2560, -2560, -2816, -3328, -3840, -4608, -4864, -4352, -4096, -3840, -3328, -3072, -3328, -2304, -3328, -4352, -5376, -4608, 512, 8704, 15104, 22272, 23552, 25088, 9728, -7680, -6144, -6912, -4608, -4096, -2816, -2816, -3328, -3840, -3072, -3584, -3840, -4608, -4352, -5120, -4608, -3840, -2560, -1792, -768, -256, 512, -2048, -2816, -5632, -5632, -5120, 1792, 7936, 15616, 24832, 27136, 11008, -5888, -7168, -6400, -5120, -3072, -1792, -1280, -1792, -2560, -3328, -3328, -3328, -2816, -3584, -3840, -3840, -3072, -2048, -1792, -1024, -512, -1024, -2560, -3840, -4864, -6656, -2560, 3072, 10752, 18432, 25856, 23040, 5120, -6400, -6912, -5632, -4608, -2560, -1536, -2304, -2816, -4096, -4352, -4096, -3584, -2560, -2048, -2304, -2304, -2304, -2304, -2304, -2048, -1280, -768, -1536, -2560, -4352, -6144, -5376, 1024, 7680, 15616, 21504, 24576, 20224, -4096, -9728, -6912, -6656, -4352, -3072, -2048, -3072, -3328, -3584, -3584, -2816, -2048, -1024, -1024, -1792, -2304, -2048, -2560, -3072, -2048, -1280, -1024, -1792, -2560, -4608, -6144, -2816, 3584, 10752, 17920, 20224, 23808, 9216, -8192, -6656, -7168, -4864, -3840, -2304, -2304, -3328, -4096, -3584, -3072, -2048, -1280, -768, -1792, -2304, -2304, -2304, -2816, -2048, -1280, -256, -1536, -2304, -3840, -6144, -5888, 1536, 7168, 16128, 22016, 32512, 9472, -11520, -6912, -7168, -6656, -4864, -1024, -1280, -2048, -2816, -3072, -3584, -3072, -2048, -1024, -2048, -2048, -2560, -2048, -3328, -2048, -2048, -768, -2048, -2048, -4096, -5888, -4352, 1792, 8704, 17664, 21248, 28928, 9472, -12800, -7168, -6400, -5632, -4096, 0, -768, -2048, -3072, -3072, -3584, -3584, -2560, -1280, -1792, -1536, -2304, -2304, -3328, -2304, -2560, -1792, -2304, -2304, -3840, -5120, -3584, 2048, 8448, 16384, 20736, 23040, 14592, -7424, -7168, 0, -1024, 2560, 2560, 2816, -3840, 1024, -256, 768, -2816, 2816, 512, -3072, 768, 4608, -2560, -15872, 22784, -4096, -24320, 30208, -32768, 31232, -32768, 28672, -25600, 27904, -30976, 30720, -26624, 14848, 2560, -22528, 32512, -26112, 1536, 25088, -32256, 8960, 22784, -28416, -1792, 28672, -13568, -24064, 23552, 16384, -27136, -13568, 27904, 13312, -25600, -19200, 22016, 24320, -11520, -30464, -3072, 28416, 18944, -14848, -30208, -6912, 24832, 25600, -1024, -27392, -24320, 4352, 27904, 23552, -1024, -25344, -27904, -6656, 19968, 29440, 16896, -6912, -26624, -27904, -10496, 14080, 28672, 25088, 8192, -13568, -27904, -26880, -11264, 10496, 26112, 27904, 17152, -1024, -18944, -28672, -26112, -12032, 6912, 22528, 28672, 23808, 11520, -4864, -19968, -28160, -26880, -16640, -1024, 15104, 25856, 28160, 22272, 11008, -3328, -17152, -26368, -28416, -22784, -11264, 3328, 16640, 25600, 27904, 23808, 15104, 3584, -9216, -19968, -26624, -27648, -23040, -13568, -1536, 11008, 21248, 26624, 27136, 22528, 14592, 4352, -6912, -16896, -24320, -27648, -26112, -20480, -11264, -512, 10496, 19712, 25344, 27136, 25088, 19712, 11776, 2560, -7424, -16384, -23296, -26880, -26880, -23296, -16384, -7424, 2560, 12288, 19968, 25088, 26880, 25600, 21504, 15104, 7680, -768, -9216, -16640, -22528, -25856, -26880, -25344, -21248, -15360, -8192, -256, 7680, 14848, 20480, 24576, 26368, 26112, 24064, 20480, 15872, 10240, 4096, -2560, -8960, -14848, -19968, -23552, -25856, -26624, -25600, -23296, -19712, -14848, -9216, -3328, 3072, 9216, 14592, 19200, 22784, 25088, 26112, 26112, 24832, 22528, 19456, 15616, 11264, 6400, 1280, -3840, -8960, -13824, -17920, -21504, -24064, -25856, -26624, -26368, -25088, -22784, -19712, -16128, -11776, -6912, -2048, 3072, 7936, 12544, 16640, 20224, 23040, 24832, 26112, 26624, 26112, 24832, 23040, 20736, 17920, 14592, 10752, 6912, 2560, -1792, -6144, -10240, -14336, -17920, -20736, -23296, -25344, -26368, -26880, -26880, -25856, -24320, -22272, -19456, -16128, -12544, -8704, -4608, -256, 4096, 8192, 12288, 15872, 18944, 21760, 23808, 25600, 26624, 26880, 26880, 26112, 24832, 23040, 20992, 18432, 15616, 12288, 8960, 5376, 1536, -2304, -6144, -9728, -13312, -16640, -19456, -22016, -24064, -25856, -26880, -27648, -27648, -27136, -26112, -24576, -22272, -19968, -16896, -13824, -10240, -6656, -2816, 1024, 4864, 8704, 12288, 15616, 18688, 21248, 23552, 25344, 26624, 27392, 27648, 27648, 26880, 25856, 24576, 22784, 20480, 17920, 15360, 12288, 9216, 5632, 2304, -1280, -4864, -8448, -11776, -14848, -17664, -20480, -22784, -24576, -26112, -27392, -27904, -28160, -28160, -27392, -26112, -24832, -22784, -20480, -17920, -15104, -12032, -8448, -5120, -1536, 1792, 4864, 7680, 10496, 12800, 14848, 16640, 18176, 19200, 19968, 20224, 20480, 20224, 19712, 18944, 17920, 16640, 15360, 13824, 12288, 10752, 9216, 7424, 5632, 4096, 2560, 1024, -512, -1792, -3072, -4096, -4864, -5632, -6144, -6656, -6912, -6912, -6912, -6656, -6400, -5888, -5632, -4864, -4352, -3584, -3072, -2560, -256, -256, -1024, -2304, -2304, -1792, -1536, -1792, -768, 1024, 2048, 2560, 2816, 3328, 2560, 1024, -768, -2560, -3840, -3328, -2304, -2560, -2816, -1280, 1024, 3072, 3584, 3072, 3328, 3584, 2304, 256, -2048, -3840, -5376, -5888, -5632, -3328, -768, 1792, 4352, 6144, 6912, 4864, 2816, 4096, 3840, -1280, -6144, -7424, -5888, -6912, -8192, -5376, 1280, 4608, 5120, 5376, 6144, 6144, 3840, 2816, 2048, -1536, -7680, -7936, -4864, -4352, -6144, -3584, 512, 4352, 3840, 3072, 4352, 4096, 4864, 2048, -1280, -512, -256, -4352, -4352, -768, 1536, 1280, -1024, 0, 256, -3072, -2304, 2304, 2816, -1024, -3584, -2048, 2304, -512, -5376, -3584, 1024, 2304, 2304, 2816, 4608, 5376, 2560, 2048, 4096, 2560, 6656, 8960, 1536, -3584, -7168, -6400, -6144, -14080, -16640, -8448, -4352, 256, -1536, -1536, 2048, 5888, 8448, 12544, 9472, 4864, 4096, 2816, 6144, 10752, 4352, -9472, -9216, 768, 1792, -5888, -9216, -2304, 2304, -3072, -5120, -2048, -512, -1024, -5888, -4352, -1536, 0, 2560, 6144, 6144, 10240, 11776, 8448, 9984, 6656, 1280, 1536, 2304, -3072, -6656, -8448, -10752, -15616, -13312, -11008, -9472, -5376, -1024, 1792, 3328, 7168, 9216, 7936, 6144, 256, -256, 5120, 6144, 5888, 5376, 6656, 6912, 2048, -8192, -11264, -768, 7168, -256, -9216, -7680, -1536, 3328, -3072, -8704, -4608, -1536, 2304, 5376, 6400, 4096, 2560, 9728, 15872, 11776, 4352, -2816, -1792, 2560, -2048, -11264, -13568, -8448, -8960, -9728, -7424, -6912, -4096, 0, 256, 2304, 9472, 12800, 9216, 512, -5120, -3072, 3840, 5376, 6144, 8192, 7424, 5120, 5888, 3072, -2048, -768, 1024, -2560, -1280, 512, -4864, -16128, -17920, -5376, 5120, 10496, 5888, 8448, 14592, 15616, 10752, 5376, 3840, 2560, -11520, -20992, -15360, -7424, -11264, -19712, -12800, -1792, 1024, -1024, 2560, 8192, 14336, 10752, 256, -2560, -4608, 512, 5632, 7168, 8448, 10752, 12032, 11008, 12032, 2816, -5888, 0, 2560, -10240, -20736, -17920, -7168, -7424, -17408, -7424, 4864, 1536, 1792, 5376, 10240, 10496, 8192, 5632, 7168, 12032, 17664, 16896, 8960, 5376, 3840, -768, -5120, -8704, -6144, -1536, -4864, -15104, -12032, -10752, -8960, -7168, 3840, 11520, 13056, 16896, 19968, 21248, 9472, 256, 3328, 1792, -13056, -20736, -23552, -21248, -22272, -18944, -14848, -18688, -13056, 3072, 8960, 6656, 8960, 12032, 17664, 17920, 16128, 16640, 12544, 12032, 17408, 18688, 13312, 8448, 3840, -3072, -7680, -12800, -13056, -11776, -11520, -15360, -12800, -12800, -12800, -13824, -6144, 9728, 19968, 23040, 27136, 25344, 10240, -1536, -2816, -11776, -28160, -32512, -27392, -19456, -17152, -13568, -10496, -10496, -5888, 3584, 8448, 6912, 8704, 12544, 17920, 18176, 16896, 16640, 13056, 13056, 17664, 18432, 13312, 8192, 2560, -3072, 0, -1280, -512, -1280, 512, -7424, 5632, 0, -6912, 17152, -15104, 11520, -3328, -9472, 7168, 16640, -1024, 1536, 15360, 1280, 14848, 11264, 15360, 6912, 11008, 24576, 18176, 20736, 12288, 24576, 17920, 5888, 23040, 16896, 20480, 22528, 10240, 5120, 15616, 16384, 3072, 9216, 6144, 1024, 1792, 1280, -6912, -9728, -6656, -8448, -12544, -12800, -17920, -17664, -23808, -23552, -24064, -26624, -26624, -25856, -28160, -27392, -28416, -28416, -32256, -22272, -30464, -25600, -24064, -28672, -23808, -23808, -20480, -20736, -19456, -14848, -14336, -17920, -7680, -5376, -10752, -3328, -768, 512, 2048, 5120, 7168, 10496, 11520, 15104, 15872, 17664, 21504, 21760, 23040, 26368, 27904, 28416, 30208, 30976, 30976, 31488, 30976, 31232, 30976, 31232, 30976, 31232, 30976, 30976, 30720, 30976, 30720, 30976, 30720, 30976, 30720, 30720, 30464, 30720, 30464, 30720, 30208, 26880, 27136, 28160, 21248, 22784, 23552, 19200, 17152, 15616, 14592, 12032, 10240, 8448, 6144, 4352, 2560, 768, -512, -2560, -5120, -7936, -7936, -9472, -12544, -12800, -16128, -16896, -17664, -18944, -20224, -23296, -22784, -23552, -24320, -26112, -27136, -26624, -27392, -28928, -28928, -28160, -28928, -29696, -29184, -29440, -29184, -29440, -29184, -28928, -29184, -28928, -29184, -28928, -28672, -28928, -27904, -26880, -28416, -27136, -27392, -26368, -25600, -26368, -25344, -24832, -25088, -25344, -23552, -23552, -23808, -23552, -23552, -23040, -22528, -23040, -22528, -22016, -22784, -21760, -21760, -22272, -21760, -21760, -20992, -21248, -20992, -20480, -19968, -20224, -19456, -18944, -18688, -18688, -17664, -17408, -16896, -16384, -16640, -15872, -14848, -14336, -14336, -13312, -12800, -12032, -11008, -10752, -9984, -8960, -8448, -7936, -6912, -5888, -5376, -4096, -4096, -2048, -1792, -768, 256, 0, 2560, 3840, 3840, 4864, 6656, 7424, 7680, 9728, 10496, 10752, 12032, 13824, 13824, 14592, 16128, 17408, 17664, 18432, 19712, 19968, 20480, 21760, 21504, 22016, 22272, 22016, 22272, 22016, 21760, 22016, 21760, 21504, 21760, 21504, 21248, 21504, 21248, 20992, 20992, 21248, 20992, 20736, 20992, 20736, 20480, 20736, 20480, 20224, 20480, 20224, 20224, 19968, 20224, 19968, 19968, 19712, 18944, 17920, 16896, 16384, 15616, 14080, 13312, 12544, 11520, 10240, 8960, 8192, 7424, 6144, 4864, 3840, 3072, 2048, 1024, 0, -1024, -2048, -2816, -3840, -4352, -5120, -6400, -6656, -7424, -8192, -8704, -9472, -9984, -10496, -11008, -11520, -11776, -12288, -12544, -12800, -12800, -13312, -13312, -13568, -13312, -13568, -13824, -13568, -13568, -13312, -13312, -13056, -12800, -12800, -12544, -12288, -12288, -11776, -11520, -11264, -10752, -10496, -10240, -9984, -9472, -8960, -8704, -8192, -7680, -7168, -6912, -6144, -5888, -5632, -5120, -4864, -4352, -3840, -3584, -3328, -3072, -2560, -2304, -2048, -2048, -1536, -1536, -1280, -1024, -1024, -768, -768, -512, -512, -256, -512, -256, -512, -256, -256, 0, -256, -256, 256, 0, 0, -768, -256, 256, -1024, -1024, -768, -512, -1280, -768, 0, -256, -256, -768, -256, 0, 512, 0, -512, -1280, 1280, 1024, 256, 1792, 512, 512, 256, 2048, 256, 1536, 512, -1024, 512, 256, -1024, 1536, -2048, -768, -1792, -512, -1536, -256, -2304, 256, -512, -1024, 256, 512, 256, -512, 2048, 512, 0, 3584, 2304, 2560, 1280, 768, 1280, 1536, 1024, 768, -2048, -512, -1024, -2560, -256, -1280, -768, -1024, -1536, -3328, -1280, -1024, -1024, -768, 512, -3328, -1536, 768, 1536, 1536, 1792, 256, 256, 1536, 1536, 4096, 3328, 2304, 2560, 2304, 512, 1792, 2560, 1024, -1024, -768, -4352, -1792, -1536, -1536, -2560, -4352, -4352, -2560, -2816, -2304, -1280, -1536, -2048, 512, 256, 2048, 4864, 3840, 4608, 6144, 4864, 4096, 4352, 4864, 2816, 1792, 256, -1280, -2048, -2304, -3840, -2048, -2304, -3584, -5120, -4864, -2304, -4608, -2560, -3328, -5888, -3328, -3072, -1792, 0, -256, 1280, 4096, 3072, 7168, 7680, 8192, 8704, 8704, 4864, 6144, 5888, 4096, 2816, 1280, -1792, -4864, -4352, -4096, -5376, -6656, -5888, -8192, -7936, -7680, -6400, -6656, -6144, -4864, -3328, -2304, -256, 0, 1024, 1536, 3328, 3840, 4864, 4352, 3328, 2048, 2048, 2048, 1792, 0, -1024, -2048, -2560, -1792, -1280, -1536, -1536, -2304, -3072, -2048, -2560, -2304, -2304, -2816, -3328, -3072, -2304, -1024, -256, 1024, 2304, 4864, 6912, 7936, 6656, 4096, 3584, 4096, 4096, 3072, 256, -2048, -3584, -2816, -2304, -1536, -2816, -2816, -3072, -3584, -2560, -2816, -3328, -3840, -4864, -5888, -4864, -3584, -2048, -1280, -256, 2048, 8704, 15872, 15104, 3072, 3584, 8192, 5632, 1536, 5120, 1536, -2304, -13824, -4096, -256, -4864, 1792, -3840, -3328, -3072, -3584, -3840, -3584, -5632, -6144, -7680, -7680, -5120, -3072, -1536, 768, 6656, 16896, 22528, 9984, 0, 12032, 9216, -512, 6656, -5888, 5376, 3328, -1536, -15360, -10752, 1536, -5632, 1024, -4608, -4096, -1024, -4096, -4864, -6144, -9984, -7936, -6400, -8192, -6656, -2816, 3072, 14080, 26624, 19200, 2560, 8960, 15872, 2304, 6656, -4096, -2048, 4864, 768, -2304, -15616, -11776, 512, -6656, -1792, -4096, -2560, 512, -1792, -5632, -5888, -9728, -10240, -9472, -11264, -8448, -2048, 9472, 25856, 31744, 9216, -1280, 22784, 5120, 9728, 1280, -6656, 768, 256, 1280, -7168, -16640, -5376, 256, -5632, -3072, -6656, 256, -1792, -2560, -6144, -6656, -8448, -9472, -12288, -12800, -9216, 1280, 16128, 31232, 27904, 1792, 8960, 21504, 1280, 15104, -9216, -1024, -2816, -256, -1280, -10240, -14080, -1024, -3840, -5376, -4096, -5632, 1280, -2560, -4352, -5120, -6912, -5888, -11264, -13824, -15872, -5888, 7424, 29184, 32512, 13056, 1792, -512, -1024, -512, 1024, 2816, 3584, 2560, 512, -1792, -2304, -2304, -3840, -4096, -1792, 768, 512, -2560, -5376, -4352, 1536, 2560, -2048, -7168, -2816, 11520, 16896, 16384, 12032, 9216, 12544, 12544, 6912, 2304, -3072, -4608, -6400, -7680, -2816, 0, -1280, 0, -256, -4608, -9216, -8448, -4608, -2560, -3328, -7936, -6656, -6400, -4352, 1024, 7168, 17920, 22784, 12288, 2304, -8192, -14848, -14336, -17920, -14592, -4352, -9728, -12288, -8960, -8192, -1792, 8960, 9728, 13568, 15872, 11264, 8448, 6912, -1536, -8960, -13312, -16640, -13824, -10240, -11008, -7680, -6400, 512, 16128, 13824, 8704, 4352, 8704, 17920, 15360, 2048, -3840, -768, 0, 9984, 14080, 8960, 9984, 15360, 19200, 9216, 5120, -1792, -6400, -16896, -28160, -22784, -22784, -18176, -9216, -3072, 2304, 7936, 10496, 13824, 11776, 11520, 15104, 10496, 5632, 768, -17664, -28160, -32256, -29696, -16384, -3840, 2304, 7424, 8448, 7680, 14336, 10752, 3072, 5888, 1536, -6912, -9216, -5376, -5632, -8192, -5376, -7680, -7424, -1280, 2304, 4096, 5632, -2304, -3072, 7936, 6144, -4352, -10496, -5888, 8192, 8192, 6656, 8704, 16384, 16896, 27904, 26624, 13056, 1280, 3072, 4096, -9216, -14848, -15104, -16896, -16128, -20992, -16384, -5888, -2304, 2816, 4096, 5120, 4864, 3328, 3072, 8448, 9472, 10496, 11776, 7168, 1792, -14848, -23808, -20224, -16384, -8448, -256, 5632, -1024, 512, 4864, 1024, -1792, -768, -768, 1280, 256, -2560, -768, 3072, -1536, -9728, -7424, -4352, -1280, 2816, 512, -8448, -5120, 11264, 10752, 5120, -7680, -6144, 2304, 11264, 9728, 5120, 9216, 18176, 15616, 22016, 18432, 6400, -2048, 2560, 4352, -8960, -13824, -16128, -17152, -17920, -19968, -14848, -4096, -1792, 4864, 5632, 5120, 5376, 7424, 5376, 4096, 8960, 9216, 4096, -2048, -6912, -15616, -14848, -17152, -11008, 768, 8960, 9728, -512, -512, 2560, -2304, -7424, -3584, -1280, -256, -1280, 512, 3072, -1536, -8192, -5888, -5632, -4096, -1280, 768, -2304, -7424, 6912, 14336, 9984, 2816, -6912, -7168, 5888, 8704, 7168, 4608, 5120, 15872, 20992, 18176, 18944, 6144, -1024, 4096, 4608, -9984, -13824, -16640, -15616, -13312, -16384, -12544, -2816, -1024, 3072, 4352, 4096, 6400, 6144, 1536, 5888, 9216, 4608, 4608, -256, -10752, -12800, -23040, -11008, 768, 8960, 9728, -512, -512, 2560, -2304, -7424, -3584, -1280, -256, -1280, 512, 3072, -1536, -8192, -5888, -5632, -4096, -1280, 768, -2304, -7424, 6912, 14336, 9984, 2816, -6912, -7168, 5888, 8704, 7168, 4608, 5120, 15872, 20992, 18176, 18944, 6144, -1024, 4096, 4608, -9984, -13824, -16640, -15616, -13312, -16384, -12544, -2816, -1024, 3072, 4352, 4096, 6400, 6144, 1536, 5888, 9216, 4608, 4608, -256, -10752, -12800, -23040, -11008, 0, 256, 1536, -2816, 4864, -6400, 6144, -3840, 2816, -1536, 256, 2304, -1536, -768, 2816, -4608, 7168, -5888, 2048, 1536, -512, -256, 0, -1280, 4608, -5888, 6144, -7168, 6912, -3072, -256, -512, 1536, 1024, -3584, 4864, -7424, 10752, -10240, 5632, -1536, -768, 3584, -4096, 1024, 2048, -2304, 3328, -5632, 4352, 1280, -6144, 9472, -8704, 5120, -1024, -2816, 4864, -5120, 5376, -4096, 256, 4352, -4352, 1280, -2304, 6400, -7936, 7936, -10240, 8192, -2816, -1792, 1024, -1024, 3328, -5888, 7424, -10240, 13056, -12544, 5120, 768, -5120, 9728, -12032, 8704, -5376, 3584, -2304, 1024, -3328, 5120, -7424, 9472, -14592, 15104, -12288, 5888, -1280, -1792, 1280, -1536, -1280, 3328, -4352, 2304, -1024, -3072, 5632, -4864, -2048, 2560, -1280, -1792, 2048, -4608, 4864, -3328, 1280, -3072, 1536, -2560, 4608, -10240, 16896, -23296, 20992, -14336, 4352, 4864, -13056, 14336, -11520, 7680, -4864, 1280, -1536, 1792, -2304, -1024, -512, -1280, 3328, -4864, 256, 5120, -7168, 3328, -1536, 0, -4352, 8448, -12288, 9728, -4096, -5120, 13568, -19200, 19200, -15616, 7680, -3072, -2304, 512, 1280, -2304, -1792, 3840, -4352, 2304, 1024, -11776, 17920, -21760, 22016, -17152, 7424, 4608, -15360, 19456, -17920, 7424, -2048, -256, 256, 3584, -14848, 23808, -30208, 32512, -32000, 21760, -9216, -512, 4352, -9984, 11776, -15616, 17920, -25344, 31232, -30720, 14336, 3840, -21760, 29696, -25856, 7680, 11008, -27648, 32512, -31232, 18432, -9728, -768, 5120, -7936, 7424, -9472, 10752, -12800, 16128, -18432, 10240, -1792, -11776, 16896, -20992, 13568, -6400, 256, 256, -256, -768, 768, -6144, 6144, -8704, 6912, -6144, 9216, -12544, 9472, -9728, 8960, -10752, 3328, -1024, -3584, 3584, -7424, 10752, -14848, 14848, -15360, 10496, -9984, 6912, -8960, 6912, -8192, 6400, -9472, 11008, -12800, 8192, -5120, -1024, 1024, -3584, 4096, -11008, 16896, -23808, 20224, -14848, 6912, -2816, -5376, 8704, -10240, 6144, -1792, -6400, 7936, -7424, 4864, -4608, -512, 256, -1536, 1024, -7936, 12032, -16128, 15872, -16384, 8192, 512, -7424, 5888, -5376, 4864, -10496, 15104, -19456, 15872, -13312, 6656, -2816, -256, -2560, 1536, -2560, -1792, 4352, -10752, 8704, -3072, -8704, 18688, -27136, 23552, -15616, 6656, -6144, 2048, -1792, -512, 768, -6144, 7936, -11264, 6912, -2304, -5632, 9728, -11008, 3840, -1024, -768, -512, -3072, 1280, 256, -1792, 1792, -6400, 4352, -4352, 1024, -3840, 6912, -10240, 8704, -4608, 1536, -3328, 3072, -768, -2304, -1536, 2048, -4608, 4608, -9216, 13824, -14080, 7680, -6400, 6656, -10496, 9728, -12544, 12288, -9728, 2048, 4096, -10240, 12032, -13312, 8704, -3072, -1024, 512, -3328, 0, 256, 1536, -2816, 4864, -6400, 6144, -3840, 2816, -1536, 256, 2304, -1536, -768, 2816, -4608, 7168, -5888, 2048, 1536, -512, -256, 0, -1280, 4608, -5888, 6144, -7168, 6912, -3072, -256, -512, 1536, 1024, -3584, 4864, -7424, 10752, -10240, 5632, -1536, -768, 3584, -4096, 1024, 2048, -2304, 3328, -5632, 4352, 1280, -6144, 9472, -8704, 5120, -1024, -2816, 4864, -5120, 5376, -4096, 256, 4352, -4352, 1280, -2304, 6400, -7936, 7936, -10240, 8192, -2816, -1792, 1024, -1024, 3328, -5888, 7424, -10240, 13056, -12544, 5120, 768, -5120, 9728, -12032, 8704, -5376, 3584, -2304, 1024, -3328, 5120, -7424, 9472, -14592, 15104, -12288, 5888, -1280, -1792, 1280, -1536, -1280, 3328, -4352, 2304, -1024, -3072, 5632, -4864, -2048, 2560, -1280, -1792, 2048, -4608, 4864, -3328, 1280, -3072, 1536, -2560, 4608, -10240, 16896, -23296, 20992, -14336, 4352, 4864, -13056, 14336, -11520, 7680, -4864, 1280, -1536, 1792, -2304, -1024, -512, -1280, 3328, -4864, 256, 5120, -7168, 3328, -1536, 0, -4352, 8448, -12288, 9728, -4096, -5120, 13568, -19200, 19200, -15616, 7680, -3072, -2304, 512, 1280, -2304, -1792, 3840, -4352, 2304, 1024, -11776, 17920, -21760, 22016, -17152, 7424, 4608, -15360, 19456, -17920, 7424, -2048, -256, 256, 3584, -14848, 23808, -30208, 32512, -32000, 21760, -9216, -512, 4352, -9984, 11776, -15616, 17920, -25344, 31232, -30720, 14336, 3840, -21760, 29696, -25856, 7680, 11008, -27648, 32512, -31232, 18432, -9728, -768, 5120, -7936, 7424, -9472, 10752, -12800, 16128, -18432, 10240, -1792, -11776, 16896, -20992, 13568, -6400, 256, 256, -256, -768, 768, -6144, 6144, -8704, 6912, -6144, 9216, -12544, 9472, -9728, 8960, -10752, 3328, -1024, -3584, 3584, -7424, 10752, -14848, 14848, -15360, 10496, -9984, 6912, -8960, 6912, -8192, 6400, -9472, 11008, -12800, 8192, -5120, -1024, 1024, -3584, 4096, -11008, 16896, -23808, 20224, -14848, 6912, -2816, -5376, 8704, -10240, 6144, -1792, -6400, 7936, -7424, 4864, -4608, -512, 256, -1536, 1024, -7936, 12032, -16128, 15872, -16384, 8192, 512, -7424, 5888, -5376, 4864, -10496, 15104, -19456, 15872, -13312, 6656, -2816, -256, -2560, 1536, -2560, -1792, 4352, -10752, 8704, -3072, -8704, 18688, -27136, 23552, -15616, 6656, -6144, 2048, -1792, -512, 768, -6144, 7936, -11264, 6912, -2304, -5632, 9728, -11008, 3840, -1024, -768, -512, -3072, 1280, 256, -1792, 1792, -6400, 4352, -4352, 1024, -3840, 6912, -10240, 8704, -4608, 1536, -3328, 3072, -768, -2304, -1536, 2048, -4608, 4608, -9216, 13824, -14080, 7680, -6400, 6656, -10496, 9728, -12544, 12288, -9728, 2048, 4096, -10240, 12032, -13312, 8704, -3072, -1024, 512, -3328, -256, -512, -256, -1024, -768, -6400, -10496, 2048, 4096, 6912, 512, 4096, 256, 3328, 5376, -2048, -1536, -7424, 4352, 2048, 2048, 5120, -3328, 1280, 1024, 6400, 4352, 7680, 5632, 3584, 3840, 4864, 1792, 13056, -4096, -3840, -8192, -3328, 3072, -2048, -4352, -12544, -6912, -7424, -7424, -13312, -16896, -14080, -8192, -5120, -10496, -5376, -9216, -2816, -4096, 5632, 768, 4864, 0, -1536, -2560, 0, -9728, -4352, -8960, -4864, -6912, 0, -8960, -6912, -2304, -4352, -3584, -512, 5120, 12800, 16128, 14592, 12544, 17920, 17920, 24832, 20736, 17408, 13312, 19968, 23808, 25088, 26112, 14336, 8704, 5120, 13568, 15360, 11520, 6144, -4608, 5376, -2560, 0, -9728, -20224, -9728, -9472, -3328, -6912, -10496, -12800, -13056, 3584, 2560, 4096, -5376, -3328, -5632, -5120, -12288, -13568, -14080, -16896, -19456, -16640, -23296, -26880, -23552, -22272, -25856, -20224, -14336, -8704, -1792, -1024, 1792, 5120, 3840, 6656, 7424, 8192, -2048, 9216, 12032, 12800, 16896, 7424, 4608, -8448, -2816, -1024, -2560, -6144, -10752, -7936, -5632, 512, -5888, -19200, -8704, -9216, 1280, 256, 256, -4352, -12032, 5120, 11008, 17408, 7168, 7680, 2304, 7424, 1792, -2304, -1280, -8192, -11776, -9216, -3840, -10240, -8960, -3840, -6656, -5376, 512, 5376, 12544, 15872, 21248, 22272, 27136, 19712, 24832, 24064, 17152, 15360, 21760, 20224, 28160, 20480, 15616, 256, 2048, 4096, 12800, 9216, 512, -5632, 1024, -512, 5376, -8960, -8448, -4864, 1024, 6144, 4864, 2560, -14848, -5888, 4608, 11520, 8704, 2048, -3072, -1536, -1280, -12288, -13056, -19200, -18432, -19712, -9472, -16640, -20480, -14592, -16896, -17408, -9728, -9728, 512, 2560, 9728, 7936, 14848, 5632, 9984, 9472, 6912, -2304, 5888, 2304, 8960, 4608, 3840, -7936, -12800, -11264, -1280, 1536, -2560, -16128, -10496, -14336, -3840, -10496, -18176, -11520, -9472, 1792, -1536, 1280, -14336, -18176, -1536, 5376, 10496, 2048, -3328, -3584, -10240, -7680, -10496, -10240, -14336, -7936, -7936, -2304, -3840, -1280, 2560, 10752, 6912, 18688, 20992, 18688, 18688, 20224, 17920, 9728, 7168, 7936, 5888, 11520, 10752, 11264, 7680, -10240, 2048, 7168, 13312, 7680, -4608, -7424, -10240, -3584, -11520, -12800, -14080, -17408, -9984, -1536, -7424, -11520, -15104, -8192, 1024, 7936, 5888, 4096, 5120, 2816, -256, 256, -7168, -11520, -13568, -14336, -17152, -15360, -14080, -10240, -7936, -6400, -4096, 2816, 5120, 9216, 17152, 17920, 19200, 19712, 20736, 16640, 11776, 9728, 8704, 9984, 13056, 11264, 14592, 1792, -1024, 3328, 9472, 11776, 4864, -2048, -7424, -256, -2304, -5376, -8192, -11008, -14080, -14848, -10240, -2048, 3840, 7424, 9728, 11264, 15104, 16128, 13056, 5120, -5120, -12032, -15616, -14848, -12288, -10752, -11008, -8960, -3840, 3840, 10496, 14080, 15616, 15872, 17920, 17152, 11520, 2816, -7936, -15872, -20480, -19968, -18176, -15872, -13824, -9984, -3840, 4608, 12800, 17408, 20224, 21248, 23552, 22528, 14592, 4096, -7936, -18176, -24064, -24320, -23040, -21248, -18176, -14080, -7168, 1792, 12544, 19712, 23808, 25600, 27904, 27392, 19968, 9216, -5120, -18176, -25344, -26624, -25600, -23552, -21248, -17664, -11008, -1280, 10752, 20224, 25600, 27648, 29184, 28672, 23040, 13056, -2304, -16640, -25600, -28160, -26880, -24320, -22272, -19456, -13312, -2816, 8960, 19200, 25600, 27392, 28416, 27136, 23040, 13312, -1024, -15360, -24832, -27904, -25344, -22272, -20480, -16640, -8960, 1280, 11008, 19200, 23296, 24320, 23808, 22272, 18176, 7936, -4864, -16384, -23808, -25344, -22528, -19456, -16896, -11264, -2304, 7168, 15104, 20224, 21504, 20480, 18176, 15104, 8960, -1280, -11520, -19456, -24576, -24320, -19712, -15104, -9984, -2304, 7168, 15616, 22016, 25088, 23808, 18944, 13312, 7168, -1536, -11008, -18432, -24064, -27648, -25344, -19712, -13312, -5120, 4864, 14336, 21504, 27136, 29440, 27136, 20224, 11520, 768, -10240, -18944, -23808, -27648, -28672, -25600, -20224, -11776, -256, 11520, 19968, 25600, 28928, 30208, 27648, 20736, 9984, -4864, -17152, -23808, -26368, -27648, -26624, -24064, -18944, -8192, 4864, 15616, 22528, 26112, 27648, 27904, 25600, 18688, 5376, -11264, -22272, -26112, -26624, -24832, -23040, -19968, -12544, 0, 11776, 19968, 23040, 23552, 22784, 22272, 19712, 11008, -3840, -18432, -25856, -26624, -23808, -20224, -17664, -12032, -768, 12032, 21504, 24576, 22784, 18944, 16640, 14848, 9472, -1792, -15616, -25344, -28160, -25856, -20992, -15872, -9728, 512, 12544, 23552, 28672, 27136, 20992, 15104, 10496, 4608, -4864, -15616, -24320, -28416, -28160, -25088, -18944, -9984, 1536, 13824, 25344, 31232, 31488, 26624, 20224, 12800, 3072, -8192, -18432, -25600, -28416, -28160, -27136, -23040, -13824, -1024, 12544, 25344, 31488, 32256, 28928, 24320, 17664, 6144, -6912, -18432, -26112, -29184, -27904, -26624, -24064, -16384, -4096, 9216, 22272, 29696, 30976, 28416, 24832, 19456, 9216, -3840, -15616, -24064, -28160, -27648, -25088, -22016, -15360, -4864, 7424, 19712, 26624, 27904, 25344, 22016, 17152, 8960, -1792, -12032, -20992, -25088, -25856, -23552, -19712, -12288, -3584, 6400, 17152, 23552, 24320, 21248, 16896, 11520, 4608, -2304, -9472, -15872, -19712, -20736, -19968, -13824, -4096, 0, 0, 0, 3072, -2560, 4096, -3584, -4608, 4352, -7936, -512, 768, -4864, -2048, 4352, 7168, 9472, 7936, -256, -6400, -4096, -12032, -3328, -11008, -5632, 1536, 8704, 10496, 12544, 10496, 6912, 1536, -8448, -15872, -13824, -15104, -8192, -3328, 7424, 13568, 18688, 15360, 13824, 4096, -4864, -14848, -19712, -22784, -10752, -11776, 4352, 14080, 19968, 22016, 20736, 8448, -768, -8960, -21504, -28160, -19200, -17920, 0, 9984, 19968, 23552, 26880, 17920, 3328, -3840, -20992, -27392, -26368, -21504, -10496, 5120, 20736, 21760, 32512, 22016, 9984, -1024, -16128, -26368, -25344, -27392, -17664, 512, 17408, 20992, 32512, 21504, 14848, 7168, -11264, -22528, -26624, -27648, -21248, -3328, 7424, 17664, 29696, 22272, 19712, 10240, -4096, -16640, -22784, -26624, -22784, -10240, -256, 12032, 24576, 23040, 21760, 13312, 2304, -9728, -15872, -24576, -24320, -15872, -5632, 5376, 18688, 19968, 22016, 16640, 8960, -3840, -10496, -20480, -23552, -17664, -12288, 256, 11008, 16640, 20480, 18688, 12544, 2048, -5888, -15104, -19200, -18944, -15360, -5632, 4352, 12544, 17664, 16640, 15360, 6400, -256, -9216, -15104, -17920, -15616, -10240, -2304, 7680, 13312, 14592, 16128, 9472, 4352, -3072, -10496, -15616, -14592, -12800, -7680, 2304, 7680, 12544, 15360, 12032, 7168, 1536, -5120, -12544, -13056, -13568, -10752, -2816, 3328, 8704, 13568, 12800, 8704, 4608, -768, -8960, -9984, -13312, -12544, -5888, 0, 4608, 10496, 12032, 9216, 7936, 2560, -5376, -7168, -11008, -12544, -7936, -3328, 512, 7168, 9984, 8960, 9728, 4864, -1792, -4608, -8448, -10752, -9216, -6656, -3072, 4864, 7680, 8704, 9216, 5632, 1536, -1280, -6400, -9728, -9216, -7424, -4352, 2048, 4864, 6656, 8960, 7168, 3072, 768, -4352, -7680, -7424, -7424, -5632, -768, 2304, 4864, 8448, 6656, 3584, 2048, -2304, -4608, -5632, -7168, -6400, -2304, 768, 3840, 5632, 5120, 4608, 3072, 256, -2816, -5632, -6144, -5376, -3328, -768, 2048, 2816, 5120, 5376, 3072, 1280, -1536, -4864, -4096, -4352, -4352, -1792, 768, 2048, 5120, 4352, 1792, 1792, -512, -2816, -3328, -4096, -4352, -1280, 512, 1280, 3072, 3328, 2048, 1536, 768, -2304, -2816, -2304, -3584, -1280, 256, -768, 1536, 2816, 1536, 1792, 512, -1536, -1024, -1024, -2560, -1536, -768, -1024, 1280, 2048, 512, 1280, 1024, -512, 0, -768, -2304, -1024, -768, -768, 512, 768, 0, 1536, 1024, 0, -256, -512, -512, 0, 0, 0, 3072, -2560, 4096, -3584, -4608, 4352, -7936, -512, 768, -4864, -2048, 4352, 7168, 9472, 7936, -256, -6400, -4096, -12032, -3328, -11008, -5632, 1536, 8704, 10496, 12544, 10496, 6912, 1536, -8448, -15872, -13824, -15104, -8192, -3328, 7424, 13568, 18688, 15360, 13824, 4096, -4864, -14848, -19712, -22784, -10752, -11776, 4352, 14080, 19968, 22016, 20736, 8448, -768, -8960, -21504, -28160, -19200, -17920, 0, 9984, 19968, 23552, 26880, 17920, 3328, -3840, -20992, -27392, -26368, -21504, -10496, 5120, 20736, 21760, 32512, 22016, 9984, -1024, -16128, -26368, -25344, -27392, -17664, 512, 17408, 20992, 32512, 21504, 14848, 7168, -11264, -22528, -26624, -27648, -21248, -3328, 7424, 17664, 29696, 22272, 19712, 10240, -4096, -16640, -22784, -26624, -22784, -10240, -256, 12032, 24576, 23040, 21760, 13312, 2304, -9728, -15872, -24576, -24320, -15872, -5632, 5376, 18688, 19968, 22016, 16640, 8960, -3840, -10496, -20480, -23552, -17664, -12288, 256, 11008, 16640, 20480, 18688, 12544, 2048, -5888, -15104, -19200, -18944, -15360, -5632, 4352, 12544, 17664, 16640, 15360, 6400, -256, -9216, -15104, -17920, -15616, -10240, -2304, 7680, 13312, 14592, 16128, 9472, 4352, -3072, -10496, -15616, -14592, -12800, -7680, 2304, 7680, 12544, 15360, 12032, 7168, 1536, -5120, -12544, -13056, -13568, -10752, -2816, 3328, 8704, 13568, 12800, 8704, 4608, -768, -8960, -9984, -13312, -12544, -5888, 0, 4608, 10496, 12032, 9216, 7936, 2560, -5376, -7168, -11008, -12544, -7936, -3328, 512, 7168, 9984, 8960, 9728, 4864, -1792, -4608, -8448, -10752, -9216, -6656, -3072, 4864, 7680, 8704, 9216, 5632, 1536, -1280, -6400, -9728, -9216, -7424, -4352, 2048, 4864, 6656, 8960, 7168, 3072, 768, -4352, -7680, -7424, -7424, -5632, -768, 2304, 4864, 8448, 6656, 3584, 2048, -2304, -4608, -5632, -7168, -6400, -2304, 768, 3840, 5632, 5120, 4608, 3072, 256, -2816, -5632, -6144, -5376, -3328, -768, 2048, 2816, 5120, 5376, 3072, 1280, -1536, -4864, -4096, -4352, -4352, -1792, 768, 2048, 5120, 4352, 1792, 1792, -512, -2816, -3328, -4096, -4352, -1280, 512, 1280, 3072, 3328, 2048, 1536, 768, -2304, -2816, -2304, -3584, -1280, 256, -768, 1536, 2816, 1536, 1792, 512, -1536, -1024, -1024, -2560, -1536, -768, -1024, 1280, 2048, 512, 1280, 1024, -512, 0, -768, -2304, -1024, -768, -768, 512, 768, 0, 1536, 1024, 0, -256, -512, -512, 0, -256, -256, -768, -1792, -3584, -5888, -8192, -11520, -14080, -16896, -18944, -21248, -22528, -20480, -19712, -18176, -16384, -13824, -11776, -9472, -7936, -6400, -4864, -3072, -1536, -256, 1024, 2048, 3072, 4352, 5376, 5888, 6400, 6400, 6912, 7424, 8192, 8960, 9216, 8704, 8192, 7936, 8192, 8960, 9472, 9472, 8960, 7936, 7424, 7424, 7936, 8448, 8704, 8192, 7424, 6656, 6400, 6912, 7680, 8192, 7936, 7424, 6912, 6912, 7424, 7936, 8704, 8960, 8960, 8960, 9216, 9728, 10496, 11008, 11520, 12032, 12544, 13312, 14080, 14592, 15104, 15616, 16128, 16896, 17664, 17920, 17920, 17408, 16896, 16128, 15616, 14848, 13824, 12032, 9216, 6144, 2816, 256, -2304, -5120, -8448, -12288, -16384, -19968, -22784, -24832, -26368, -28160, -29696, -31488, -32768, -32768, -32256, -30976, -29696, -28672, -27392, -26112, -24320, -22528, -19968, -17664, -15616, -13824, -12032, -10496, -8704, -6912, -5376, -4096, -3072, -1792, -512, 512, 1280, 1536, 2048, 2560, 3328, 4096, 4864, 4864, 4864, 4352, 4608, 4864, 5632, 6144, 6144, 5632, 4864, 4608, 4864, 5376, 5888, 6144, 5632, 4864, 4352, 4608, 5120, 5632, 6144, 6144, 5632, 5376, 5632, 6144, 6912, 7424, 7680, 7680, 7936, 8192, 8960, 9472, 10240, 10752, 11520, 12032, 12800, 13568, 14336, 14848, 15360, 15872, 16896, 17408, 17920, 17664, 17408, 16640, 16128, 15616, 15104, 13824, 11776, 9216, 6144, 3328, -256, -3584, -7168, -11008, -14592, -17408, -19968, -22016, -24064, -26112, -27904, -29184, -29952, -29952, -29440, -28672, -27904, -27136, -25856, -24576, -22784, -20736, -18688, -17152, -15104, -13568, -11776, -10240, -8704, -7168, -5888, -4608, -3328, -2304, -1280, -512, 0, 512, 1280, 1792, 2560, 3072, 3584, 3840, 3840, 3840, 4096, 4608, 4864, 5120, 5120, 4864, 4608, 4608, 4864, 5376, 5632, 5632, 5376, 5120, 4864, 5376, 5888, 6144, 6400, 6400, 6400, 6400, 6656, 7424, 7936, 8448, 8704, 8960, 9216, 9728, 10240, 11008, 11776, 12288, 13056, 13568, 14336, 15104, 15872, 16640, 17408, 18176, 18944, 19712, 19968, 20224, 19968, 19712, 19456, 18944, 18176, 16896, 14848, 12544, 9984, 7168, 4352, 1536, -1536, -5120, -8960, -12800, -16384, -19200, -21760, -24064, -26112, -28160, -29952, -31232, -31744, -31488, -30976, -30208, -29184, -28160, -27136, -25344, -23552, -21504, -19456, -17664, -15616, -14080, -12288, -10496, -8704, -7424, -5888, -4608, -3328, -2304, -1280, -512, 0, -256, -256, 0, 512, 0, 768, 512, 512, 1024, 1280, 1024, 1024, 1024, 1024, 1280, 768, 1024, 768, 256, 512, 0, 0, -256, -768, -1024, -512, -768, -1280, -768, -1024, -1280, -1280, -1024, -768, -768, -1536, -1280, -1024, -512, -1280, -1280, -512, -768, -768, -768, 256, 1024, 1024, 2048, 2048, 2048, 3328, 3072, 3328, 3584, 3072, 2304, 2048, 1536, 1536, 768, -512, -512, -1280, -1280, -1024, -1280, -2816, -4096, -3072, -1792, -768, -1280, -2560, -2816, -1536, -512, -512, -256, -1024, -1536, -1536, -1792, -2048, -1280, -512, 512, 1280, 1536, 2048, 2048, 2304, 3328, 4096, 4096, 3584, 2816, 1792, 1280, 1024, 512, 0, -512, -768, -768, 0, -768, -3328, -7168, -2816, 1792, -256, -3840, -256, -1280, -4608, -2560, 1536, 2816, -2816, -256, -2560, -3584, -3328, -3328, -1024, 1024, 1536, 3584, 3328, 2560, 2560, 3840, 4352, 6144, 6144, 3328, 3072, 2560, 256, 0, 512, -1024, 0, -1536, 512, 1792, -5632, -17408, 512, 8960, -10240, 3584, -6144, -768, -2560, -2304, -5120, -768, 7168, 512, -2304, -3072, -7168, -4864, -1024, -256, 3840, 4352, 4352, 4096, 3072, 4096, 5632, 6400, 7168, 1536, 4352, 2304, -256, -512, -768, 512, 3072, -1536, 1536, -1280, -8960, -22784, 8192, 7168, -9984, 5120, -9216, 2304, -5120, -2304, -8704, 768, 8704, 2048, -4096, -2816, -9472, -3840, -768, 0, 6656, 4608, 3328, 3840, 3328, 6400, 6912, 7424, 5120, 768, 5376, 512, -512, 0, -2048, 2816, 4096, -256, 2048, -5376, -19456, -20736, 22272, -6400, 1024, -1024, -5888, 1536, -6656, -5120, -8960, 5888, 7168, 0, -4608, -4096, -11008, 512, -2304, 4352, 6400, 3840, 2304, 4608, 4352, 9472, 7168, 8960, 768, 3584, 3072, -1280, -256, -256, -1280, 6912, 0, 4096, -2816, -12544, -32768, 9216, 10240, -9216, 8960, -10496, 5376, -6912, -3584, -11520, 1024, 6144, 5120, -5888, -1536, -10496, -2304, -256, 1536, 5888, 4864, 1280, 3840, 3584, 8448, 8960, 10240, 4096, 1280, 4096, -768, -1280, 1024, -3072, 6144, 2560, 4608, 256, -9728, -32768, -5376, 18432, -12800, 10752, -9728, 4864, -4096, -4096, -11008, -2560, 5376, 6144, -5632, -2816, -7680, -3840, 1536, 1024, 5632, 4608, 1536, 2816, 3328, 6912, 9984, 10752, 5632, 1024, -768, -512, -512, -1280, -768, -1280, -768, -512, -1536, -1280, -1280, -1536, -1280, -768, -1280, -768, -1280, -1024, -1536, -768, -256, -512, -256, 0, -512, 256, 512, 256, 1024, 1024, 1280, 1280, 1280, 2048, 2560, 2816, 2304, 2560, 2816, 2048, 1280, 2560, 1792, 1280, 1280, 0, -768, 256, 0, -1280, -512, -2048, -2304, -1792, -1792, -1280, -2304, -2816, -2304, -2048, -2048, -1792, -2304, -1792, -1536, -1792, -1280, -1536, -1280, -768, -768, -768, -1024, -1024, -512, 0, 256, 512, 1280, 2304, 3072, 4096, 4864, 5632, 5632, 6144, 5632, 5632, 4864, 3328, 2816, 1792, 1792, 1024, -512, -1792, -2304, -2304, -2048, -2560, -3584, -3584, -3840, -3840, -3328, -3584, -4352, -4608, -3584, -3072, -3072, -2048, -2304, -1792, -1536, -1536, -1536, -2048, -2304, -2304, -2816, -3328, -2816, -1536, -256, 768, 2304, 5120, 6912, 8448, 9472, 11776, 11776, 10752, 9472, 7168, 5376, 3584, 2816, 2560, 3584, 5120, -512, -10240, -12032, -5632, -1280, -1024, -256, 1024, -3840, -13568, -14336, -1792, -8448, -3584, -512, -4864, -1792, -2048, -3840, -1536, -2304, -2048, -768, -2304, -3840, -4608, -6656, -4864, -1536, -1280, -1536, 0, 3072, 5632, 7424, 7680, 7168, 8192, 7424, 5376, 3840, 3328, 1280, 1280, 768, 4864, 7680, 768, -17408, -6656, 512, -4352, 4352, -3072, 3840, -256, -3072, -12288, -11008, -4864, -256, 768, 1536, -2048, -1024, -2560, -2560, -1024, 0, -1536, -256, -1792, -2304, -4352, -3072, -1536, -2304, -3584, -1280, 3584, 8448, 8448, 10496, 8192, 10496, 8960, 5120, 2560, 2048, 1024, 2560, -512, 9216, 10240, 768, -28160, -2048, -1792, -1536, 4096, -4608, 6912, -512, -1024, -14336, -14592, -8448, 4096, -512, 3072, -2816, -1280, -4352, -2304, -1280, 2560, -1536, 0, -3072, -2816, -5120, -2560, -2048, -3072, -4352, -768, 4352, 9728, 8704, 11520, 9216, 13056, 9472, 4608, 1024, -768, 768, 2048, 2048, 13824, 12288, -8704, -32768, 7168, -8448, 7168, -3328, 256, 5376, 768, -5120, -15104, -16640, -2560, 4352, -256, 1792, -4352, -2560, -4864, -2048, 1280, 2816, -1024, -512, -4096, -4352, -5120, -2304, -2816, -4608, -2816, 768, 7936, 9216, 10496, 10496, 11264, 13568, 7680, 2560, 256, -3328, 3072, -1280, 10752, 16128, 11008, -32512, -14080, 4864, -6912, 7168, -256, 0, 768, 1280, 2048, 3072, 3584, 3840, 3840, 3584, 3072, 2048, 1280, 256, -768, -2304, -3584, -4352, -4864, -4608, -4096, -3072, -2048, -1280, -1024, -512, -256, -256, -512, -768, -1024, -768, -512, -256, -256, 0, 0, 0, 512, 2048, 3072, 4096, 4864, 5888, 6656, 8704, 10240, 9984, 7168, 2816, -2048, -6656, -9216, -10240, -9984, -8960, -6912, -4864, -2560, -1280, -1536, -2560, -3072, -3840, -3584, -3072, -2304, -1280, -768, -256, 256, 1536, 2048, 1792, 1792, 1792, 2048, 3328, 5120, 7168, 8960, 11008, 12288, 14080, 14592, 13056, 8192, 768, -7424, -14336, -17408, -17152, -15360, -11776, -7936, -4352, -1792, -1024, -1792, -2816, -3840, -4096, -3840, -2560, -1280, -256, 256, 768, 1280, 1792, 2304, 2816, 3072, 3072, 2560, 3328, 4864, 6656, 9216, 11008, 13056, 14848, 16640, 15616, 10240, 1536, -7680, -15360, -19200, -18688, -16384, -12544, -8192, -4096, -1280, -256, -1024, -2816, -4608, -5888, -5888, -4864, -3072, -1280, 512, 2048, 3072, 3328, 2816, 2304, 2048, 2048, 2560, 3840, 5376, 6912, 8192, 9472, 10752, 12544, 14080, 16128, 14080, 8192, -768, -9984, -16896, -20224, -18688, -14336, -9984, -6144, -3072, -1792, -1792, -3072, -4864, -6144, -6144, -5376, -3584, -1536, 768, 2048, 2816, 3072, 2816, 2560, 2560, 2560, 2816, 3584, 4352, 5376, 6912, 8448, 10496, 12544, 14336, 16128, 16896, 12544, 3840, -6912, -15616, -20992, -21760, -18688, -13312, -8448, -4608, -2304, -1280, -1792, -3072, -4608, -5376, -5120, -3840, -2304, -256, 1024, 2048, 3072, 3840, 3840, 3584, 2816, 2048, 1792, 2560, 3840, 5632, 8192, 11520, 15104, 18432, 22016, 24320, 19200, 5632, -10240, -23808, -30464, -30720, -24832, -16384, -8192, -2304, 1280, 2304, 1280, -768, -3584, -5376, -5888, -5120, -3328, -1280, 1024, 3072, 4352, 4608, 3840, 2560, 1792, 1024, 768, 1536, 2304, 3840, 5376, 7680, 10240, 14336, 19712, 25344, 25344, 13824, -4864, -22016, -31488, -32512, -26368, -16896, -6912, 256, 4096, 4608, 2816, -256, -3072, -5376, -5888, -5376, -4096, -2048, 256, 2304, 4096, 4864, 4096, 2816, 2048, 1280, 1280, 1792, 2304, 3584, 4864, 6912, 8960, 12544, 17408, 23040, 25856, 18688, 1536, -16896, -29184, -32768, -28928, -19968, -9984, -1536, 3328, 4864, 2816, -256, 0, 2560, 7680, 8960, 10240, 9984, 9472, 7168, 4608, 1536, -2304, -5120, -7680, -8960, -8448, -7680, -7168, -5888, -6144, -5888, -4864, -5120, -3840, -2816, -2048, -768, 0, 256, 0, -512, -1024, -256, 0, 2560, 3840, 5376, 6912, 6400, 6400, 5632, 3328, 2560, -1280, -2304, -3840, -4864, -4352, -4352, -3072, -1792, 0, 1024, 2560, 2048, 1280, -1280, -3328, -5888, -7936, -7680, -6144, -3328, 2816, 9216, 15872, 20736, 21248, 19968, 13824, 8960, 4864, -2816, -7424, -12544, -14592, -12032, -8960, -5120, -4864, -6656, -6912, -8448, -7680, -6656, -5632, -2816, -2048, 768, 2816, 1536, 0, -4096, -5888, -5888, -2816, 2304, 5888, 8960, 11520, 13056, 11776, 12544, 6656, 3072, -3328, -6656, -9472, -11520, -7936, -8960, -4352, -1024, 2048, 5888, 6144, 5888, 2304, -2560, -5632, -9472, -10240, -9728, -8448, -3072, 5632, 17152, 25600, 30464, 28416, 20224, 12800, 2560, -3072, -8192, -13312, -17664, -15872, -9728, -3584, -2304, -5376, -10752, -15360, -12800, -9984, -4864, -1024, -256, 768, 3840, 4864, 512, -4096, -11008, -14592, -12288, -5376, 4864, 9728, 16128, 16896, 17664, 18944, 15104, 9984, 1024, -8448, -13312, -17152, -14848, -9984, -6400, 512, 2560, 8192, 8960, 9216, 4608, -1792, -6400, -9472, -7936, -7168, -5888, -2560, 2816, 13568, 25856, 30976, 31488, 23552, 12288, 2816, -6144, -10752, -15360, -16896, -17152, -12288, -5120, 512, -4096, -10496, -17152, -22272, -15872, -11264, -2560, 2048, 4864, 7680, 8704, 8960, 1024, -9216, -16896, -19968, -19200, -6912, 5632, 12544, 21248, 23296, 24832, 23040, 17664, 9984, -4608, -15616, -26624, -25088, -19200, -8192, 4864, 12032, 17408, 17920, 14336, 4096, -8448, -19712, -22784, -19456, -12032, 1792, 8960, 16384, 25600, 31488, 32000, 27392, 15360, 1280, -9984, -19456, -24064, -25856, -23808, -17664, -9216, -768, 4352, 2560, -3840, -14336, -20480, -22016, -17664, -10240, -1792, 6400, 12544, 16896, 18432, 13824, 4864, -4864, -14080, -19712, -17152, -10240, 1024, 11520, 19456, 24576, 25600, 23552, 17152, 8192, -2816, -14336, -22528, -23296, -18688, -8448, 2304, 10496, 15616, 16640, 13312, 4352, -7168, -17152, -20480, -17408, -9216, 1536, 12032, 20992, 29184, 32256, 29184, 18944, 4608, -8192, -18688, -23808, -25856, -23808, -17920, -9216, -768, 4352, 2560, -3840, 0, -256, -512, -512, 0, 512, 768, 1536, 1792, 1536, 1536, 768, 512, -256, -1024, -2048, -3072, -3584, -3328, -3328, -2816, -1280, -256, 1280, 2560, 3584, 4352, 4864, 4608, 3840, 3072, 1792, 768, 256, -512, -1024, -1024, -1792, -2816, -3328, -4096, -4096, -3072, -2304, -1536, -768, -256, -256, -256, -1024, -2048, -2816, -3840, -4096, -3840, -2560, -512, 1792, 4608, 6400, 7168, 7168, 6144, 4096, 2560, 1024, -512, -1280, -1280, -1024, -1024, -256, 0, 0, 256, 256, 0, -256, -768, -1536, -2816, -2816, -3584, -4096, -4352, -4864, -4864, -4096, -2560, -512, 2048, 4864, 6912, 8448, 8960, 8192, 6656, 5376, 3584, 1792, 0, -1536, -2816, -4608, -6400, -7936, -8192, -6912, -4864, -2304, 256, 2560, 3840, 3584, 2560, 0, -3328, -7168, -9728, -10752, -10240, -6656, -1024, 4352, 10240, 14848, 16896, 15872, 13056, 8960, 4352, 768, -2048, -4096, -4608, -4608, -3840, -3328, -3840, -4352, -4352, -3840, -3328, -2816, -3072, -768, -512, 256, -768, -3840, -7168, -9216, -10752, -10240, -7168, -2816, 3584, 11520, 16128, 17920, 17664, 14336, 11264, 9216, 5376, 768, -3072, -4608, -6656, -9472, -12032, -14848, -14080, -10496, -5120, 1024, 5632, 8704, 11008, 9472, 5632, -1792, -11008, -18176, -22528, -22016, -16384, -7936, 1792, 14336, 25344, 29440, 27136, 21760, 12288, 4352, 256, -3584, -7168, -8448, -5120, -2816, -3072, -4608, -9472, -11264, -10496, -7424, -5888, -1792, 3840, 7936, 10240, 8448, 2048, -6912, -14336, -18688, -18944, -16128, -8448, 1024, 12800, 23808, 25856, 23296, 20224, 14336, 11008, 6144, 1280, -4352, -8192, -7936, -11008, -14336, -16128, -18432, -14592, -8192, 768, 6656, 11776, 15872, 16128, 11520, 2304, -9984, -21760, -28672, -27136, -21504, -12544, 1536, 15360, 26624, 32512, 29440, 21248, 11776, 4096, -256, -4096, -5376, -6656, -4096, -512, -2048, -6400, -12032, -17152, -15872, -12544, -6656, 512, 8704, 15360, 18944, 16640, 8448, -5376, -18176, -25088, -23552, -19712, -9216, 5376, 17664, 27136, 28672, 22528, 14848, 7424, 2304, -2048, -4608, -6144, -4352, -1024, -2560, -6656, -12032, -17152, -15872, -12544, -6656, 512, 8704, 15360, 18944, 16640, 8448, 4352, 4096, -9728, 2304, 10240, -14848, 6912, 11008, -20480, 13312, -512, -13824, 16384, -6912, -4352, 8192, 1024, -12544, 13568, -5632, -12032, 23040, -18688, 4352, 10752, -11520, 2048, 5888, -10496, -256, 14848, -18944, 10240, 6400, -16896, 14336, -4864, -11520, 14848, -2304, -9984, 11520, 768, -12288, 14080, -10496, -6912, 19968, -16896, 3328, 10240, -9728, 0, 7424, -13056, 3072, 14592, -20224, 9728, 7936, -16384, 10240, -1024, -12032, 16128, -4096, -10240, 14080, -4096, -8192, 11520, -7936, -7424, 19456, -16384, 0, 14848, -12544, 1024, 7936, -13312, 7936, 1280, -8960, 11520, -5376, 1024, -1280, 768, -4352, -1792, 14080, -18432, 11008, 8960, -22528, 20480, -14592, 768, 11520, -15872, 13568, -3584, -512, -4352, 11776, -19712, 10752, 5888, -15616, 19200, -13824, 9984, -10240, 7936, -10752, 6400, 2816, -12288, 23808, -24832, 15872, -6912, -3328, 1792, 0, 7680, -15104, 20992, -18944, 7168, 2560, -13568, 16640, -12032, 11776, -10496, 10240, -12288, 1792, 11520, -24320, 32512, -25344, 11008, -2304, -6400, 10240, -14848, 21504, -21504, 19968, -16896, 2816, 12800, -24576, 28416, -21760, 13056, -6656, -3584, 9216, -15360, 23296, -21504, 14848, -6656, -5632, 14336, -22272, 25088, -18176, 12032, -6400, -2816, 11264, -21504, 26368, -23552, 17664, -8192, -768, 6400, -15104, 22272, -23040, 17920, -11520, 4352, 4096, -14592, 20736, -18688, 12800, -8448, 3584, 0, -8960, 19200, -21504, 17664, -10752, 2048, 2816, -11776, 18944, -17664, 14592, -12032, 9216, -6656, -5120, 17664, -22784, 21248, -14848, 9472, -6144, -1792, 10496, -14848, 13824, -13568, 13568, -10752, 3584, 7168, -13824, 13312, -14080, 11776, -10496, 5632, 7680, -14592, 14848, -16384, 14336, -13824, 6656, 7936, -14080, 16128, -18688, 16896, -17408, 12544, -768, -9728, 15616, -18176, 19200, -22272, 17664, -3840, -6912, 9472, -14080, 18944, -21504, 18688, -8704, -1280, 6656, -15104, 18944, -21760, 21504, -8448, -3072, 7680, -14592, 16640, -21760, 22016, -10240, 2304, 3840, -12800, 17664, -24064, 23808, -13568, 3840, 2816, -9728, 14848, -22016, 24576, -16384, 2816, 5376, -7680, 4352, -768, -768, 0, 0, -768, -1024, -1024, -768, -1024, -1024, -1280, -1536, -1536, -2048, -1280, -1536, -768, 0, 512, 1024, 1792, 2048, 3072, 3072, 3584, 3328, 3328, 3072, 2048, 1792, 512, 512, -1024, -1536, -2560, -2816, -3072, -3072, -3584, -2560, -2304, -768, -768, 512, 768, 768, 512, 256, 256, -768, -768, -1024, -768, -768, -768, -1024, 0, -768, -768, -768, 0, -768, 0, -768, 0, 256, 0, 0, 0, 0, 0, -768, 256, -768, 256, -768, 512, 256, 0, 0, -768, -1024, -1280, -2304, -2560, -3840, -4096, -4352, -4352, -3584, -2560, -768, 1024, 2304, 3584, 4864, 6144, 6400, 6656, 7168, 7680, 8704, 10752, 7936, 2304, -7936, -9984, -5888, -3840, -4352, -5888, -7680, -5888, -3072, -2560, 1024, 2304, 4864, 3328, 3584, 1536, 0, -2304, -2816, -3072, -2304, -2048, 0, 0, 512, 256, 256, -768, -768, -1280, -768, -1280, -768, -1024, 0, -768, -1024, -1024, -768, -1280, -768, -1280, -768, 0, 768, 512, 1792, 1792, 1792, 768, 0, -3584, -4352, -6656, -6656, -7168, -5376, -4352, -2816, -2560, 512, 1536, 4864, 4608, 8192, 8192, 15360, 17664, 25088, 15360, 1792, -14848, -2048, -2048, -3584, -9984, -7680, -3584, -12032, -5376, -11520, -768, 1792, 5120, 3584, 7936, 3072, 2560, -3840, -1280, -5888, -3584, -3840, -1024, -2048, 512, 256, 1792, -768, 512, -2048, -1024, -1536, -1536, -768, 0, -1536, -1536, -2048, -2560, -2816, -3072, -2304, -2304, -1024, -768, 0, 2048, 2560, 3072, 3840, 3328, 1024, -2560, -3840, -7680, -8192, -7680, -5888, -5632, -4864, -3584, -1024, 768, 2560, 3584, 6656, 10240, 17920, 26112, 32512, 15872, -4352, -9984, 2304, -6400, -2304, -22272, -3072, -4096, 0, -7680, -6912, -4864, -2304, 1536, 4608, 5376, 4864, 1536, 0, -2304, -4352, -3584, -4096, -2048, -1536, 0, 1024, 1024, -1280, -1024, -2816, -768, -1536, 512, 512, 0, -1536, 0, -512, -1024, -2048, -3584, -5376, -6400, -7168, -8192, -9216, -10240, -11264, -12288, -13056, -14080, -15104, -16128, -17152, -18176, -18944, -19968, -20992, -22016, -23040, -24064, -25088, -25856, -21504, -15360, -9728, -3840, 2048, 7168, 6912, 5888, 4864, 4096, 2816, 5376, 11776, 17408, 23808, 27904, 27136, 26112, 25088, 24320, 23296, 22272, 21248, 20224, 19200, 18176, 17152, 16384, 15360, 14336, 13312, 12544, 11520, 10496, 9472, 8448, 7680, 6656, 5632, 4608, 3840, 2816, 1792, 768, -256, -1280, -2304, -3328, -4352, -5120, -6144, -7168, -8192, -8960, -9984, -11008, -12032, -13056, -13824, -14848, -15872, -16896, -17664, -18688, -19712, -20736, -21760, -22784, -23808, -24832, -25600, -26880, -24320, -17920, -12288, -5888, -1792, -2560, -3584, -4352, -5632, -4608, 1024, 6656, 12800, 18432, 24576, 27392, 26368, 25600, 24576, 23552, 22528, 21504, 20480, 19456, 18432, 17408, 16384, 15616, 14592, 13568, 12544, 11776, 10752, 9728, 8704, 7680, 6656, 5888, 4864, 3840, 2816, 2048, 1024, 0, -1024, -2048, -2816, -3840, -4864, -5888, -6912, -7680, -8960, -9728, -11008, -11776, -13056, -13824, -14848, -15616, -16896, -14336, -7936, -2304, 4096, 8448, 7680, 6656, 5632, 4608, 3840, 2816, 1792, 768, -256, -1280, -2304, -3328, -4096, -5120, -6144, -7168, -8192, -9216, -10240, -11008, -12288, -13056, -14080, -15104, -16128, -12800, -6656, -1024, 5120, 10752, 16384, 17152, 15872, 15104, 14080, 13056, 12032, 11008, 9984, 8960, 7936, 6912, 5888, 5120, 4096, 3072, 2048, 1024, 0, -1024, -1792, -2816, -3840, -4864, -5632, -6912, -4352, 2048, 7680, 14080, 18432, 17664, 16640, 15616, 14592, 13824, 12800, 11776, 10752, 9728, 8704, 7680, 6656, 5632, 4608, 3840, 2816, 1792, 768, 0, -1024, -2048, -3072, -3840, -4864, -5888, -6912, -7936, -8960, -9728, -10752, -11776, -12800, -13824, -14592, -15616, -16640, -17664, -18688, -19712, -20736, -21760, -22784, -23552, -24576, -25600, -25600, -20224, -16384, -12032, -7936, -3840, 0, 0, -1024, -768, -1536, -2048, 1536, 2560, -2048, -3328, 5632, 14080, 3840, -14848, -26112, -22528, -6400, 13056, 19712, 20224, 20992, 4864, -11520, -27392, -32768, -22528, 4864, 20736, 22016, 18176, 8960, -4096, -12800, -18688, -14080, -6912, -3584, 1792, 19712, 22784, 7936, -5632, -6912, -15616, -22016, -8704, 10240, 14080, 17152, 20480, 14592, -256, -12288, -15360, -10496, -11776, -7936, 7168, 15872, 12032, 11008, 8448, -1280, -8704, -11520, -13312, -8448, 6656, 16896, 17920, 10496, 4352, -8704, -20224, -23808, -10496, -1536, 5632, 13568, 23808, 15872, 4352, -5120, -16896, -30208, -22528, -1024, 11520, 15360, 17664, 17152, 512, -18432, -27904, -24320, -19968, -1792, 17152, 25856, 19968, 17664, 4864, -14336, -28160, -22784, -16384, -4864, 11520, 25600, 22016, 9216, -2816, -16640, -27392, -27648, -10496, 6144, 17664, 23808, 28416, 14336, -3840, -17920, -20736, -22528, -9728, 7680, 22528, 23040, 21248, 11008, -6144, -20736, -20992, -14592, -6144, 9728, 25600, 29440, 17920, 6656, -6400, -19200, -27648, -16896, -5120, 7424, 18176, 26880, 17152, 1792, -11776, -17152, -21248, -15360, 0, 14848, 20992, 20736, 14592, -2304, -18432, -25344, -19968, -15360, -2048, 13824, 24320, 17664, 11264, 0, -13056, -23552, -17664, -6656, 4608, 13568, 20736, 16128, 1536, -11264, -18944, -22528, -20224, -4864, 10240, 19200, 19200, 18432, 4608, -10752, -20480, -18944, -17664, -6400, 8192, 19456, 16896, 9984, 1280, -10496, -20992, -19456, -8704, 768, 10752, 20224, 22528, 9728, -3072, -12544, -18944, -23552, -12288, 2048, 13056, 17920, 21248, 12800, -1792, -14848, -17408, -16640, -11008, 3328, 17920, 20992, 15872, 8704, -4352, -18432, -24064, -16640, -7168, 4352, 17664, 25856, 18176, 6400, -5376, -15360, -22528, -16896, -3328, 9472, 15872, 20992, 17408, 2816, -12032, -18688, -20224, -16896, -3840, 12544, 20992, 19456, 14592, 2816, -13056, -22528, -19968, -12288, -2304, 12544, 0, 0, 0, 0, 0, 0, -768, -1280, -1280, -1792, -1536, -512, 1280, 4096, 6144, 5376, 4352, 3072, 768, -2560, -7936, -11264, -12032, -10752, -7168, -512, 6656, 7424, 9216, 8960, 256, -6656, -9984, -13312, -13568, -9728, -2560, -8192, -10496, -1792, 512, 5632, 16640, 22784, 18944, 3840, -4096, -6144, 3072, 15872, 9984, 1536, -3072, -768, 12032, 12288, 5376, 27904, 32512, 30464, 13568, -2304, 4864, 2304, -12800, -14080, -11008, -18176, -11776, -1280, -512, -5120, -3072, -2304, 3072, -6912, -16896, -12800, -2048, -4864, -14848, -5632, -2048, -4864, -8704, -10752, 2560, 8192, -1024, 1024, 11776, 24576, 8704, -13056, -2560, -2048, -23808, -17920, -14848, -11776, -4096, -8192, -7680, 1536, 1792, -10496, -7424, 768, 6400, 18688, 17152, 11520, 9472, 7680, 21248, 0, -7936, -1024, -12800, -7168, -10496, -19200, -28160, -13568, -3328, -768, 5632, 3584, 3584, 3328, 1792, 2304, 9728, 12032, 9984, 4352, -2048, 23040, 19200, -1280, -7424, -11776, -13824, -26112, -16896, -8960, -6912, -7424, -5376, 8192, 1280, 256, 256, -512, 4096, 4096, 4864, 7680, 12800, 22784, 10496, 1536, 10240, -2560, -3840, -10496, -11776, -11008, -19712, -25600, -25600, -12288, -9472, -6656, -1024, -2304, 0, 3328, 9216, 17920, 19200, 15104, 8704, 3072, -3328, -6912, 9472, 18176, 12288, 13568, 9472, 1792, 2048, 8704, 12288, 10240, 7936, 6400, 512, -5120, -3840, -1280, 3072, -2816, -12544, -5120, 3840, -3328, -10752, -7424, 4096, -1536, -14848, -7168, 4352, 3072, -5120, -2816, 4096, -768, -9472, -3584, 768, -8192, -2560, 10240, 13824, 13568, 6912, -768, -1280, -8704, -12032, -12544, -23040, -17408, -9216, -8192, -7936, -4096, 6656, 768, 0, -512, -512, 3840, 4096, 4864, 7680, 13056, 22528, 10240, 1536, 9984, -2560, 768, -512, 2816, -1792, 5888, 4864, 18944, 9984, 8192, -3328, -5376, -1792, -9984, -11264, -32768, -14848, -5376, 13312, -22016, -18944, -24064, 19200, 15616, 18432, -9728, 3328, 15104, 29696, 18176, -2304, -8448, -3072, 17408, -512, -8960, -32768, -10752, -11008, 9984, -19968, -14592, -20736, 14336, 15104, 16128, -3328, 1792, 17664, 25088, 22272, -3328, -2304, -6144, 17920, -2816, -5888, -32768, -10752, -12288, 7168, -17408, -15616, -17664, 8704, 16384, 11776, 2048, -1280, 20224, 20992, 25600, -4352, 1280, -7424, 17664, -3328, -5376, -31232, -12544, -11008, 2816, -14080, -18432, -13824, 3328, 18688, 7680, 5888, -4096, 22272, 18432, 27392, -4352, 2560, -6656, 16384, -1536, -6656, -27904, -15616, -7936, -1536, -10240, -22016, -10496, -1024, 20480, 4352, 7936, -5632, 22528, 17920, 27136, -2560, 1536, -4096, 13568, 1792, -9472, -23808, -19456, -4352, -5376, -7168, -25344, -8448, -3840, 21248, 3072, 7936, -5376, 21248, 19456, 25088, 512, -1024, -256, 10496, 6144, -12544, -19712, -22784, -1536, -7936, -5120, -27136, -8192, -4864, 20224, 3584, 5888, -3840, 18176, 22272, 22272, 4352, -4096, 3328, 7680, 9984, -14592, -17152, -24832, -256, -8704, -4864, -27136, -9728, -4096, 17664, 5888, 2816, -1280, 14336, 25600, 19200, 8192, -7168, 6400, 5632, 12800, -15104, -15872, -25088, -512, -7680, -6144, -25600, -13312, -2304, 14080, 9216, -1024, 1280, 10496, 28672, 17152, 11008, -8704, 7680, 5376, 14080, -13568, -16640, -23808, -2816, -4608, -8704, -22528, -17664, 0, 10496, 12288, -4352, 3072, 7424, 30208, 16640, 12544, -8704, 7168, 6912, 13568, -10752, -18432, -21248, -5888, -1536, -11264, -19712, -21760, 1280, -17664, 256, -3072, -7424, -7168, -3328, 256, 2304, -1024, -6912, -4608, -1280, 2816, 16640, 22272, 13824, 15104, 16896, 7680, 3072, 2048, -1536, -1792, 1024, -1792, -9984, -15104, -16128, -12288, -5888, -3328, -1536, 5632, 15616, 17408, 3840, -15104, -22272, -10496, 768, 1280, -2560, -4352, -4352, -5120, -5888, -5120, -7168, -4352, -768, -2560, -7424, 5888, 2816, 6400, 13312, 14336, 15872, 20480, 13824, 5632, -3840, -7936, -9728, -1280, 2816, -2304, -1792, -9216, -11264, -1536, 13312, 32512, 6656, -17408, -32000, -26880, 5632, 3840, -6912, -6912, 3328, 6400, 17664, 7168, -10752, -19712, -14592, -17920, 3840, 11264, 3584, 6656, 14592, 17664, 11008, 8448, 10496, 8448, 8192, 6400, -12800, -25088, -25600, -9728, 6144, 1792, -8960, -9728, -512, 19456, 16384, 3840, -20224, -23808, -12800, -3072, 6912, 11520, 8192, -1024, 5888, 1536, -9216, -12032, -8448, -13312, -3840, 9472, 19968, 12544, 10240, 4352, 3584, 3584, 17920, 20736, 15360, -768, -1024, -3072, -10752, -12800, -7168, -5120, 1280, 2304, 6912, 11776, -3328, -17664, -25344, -22528, -12032, 1280, -1024, -2560, 4352, 9984, -3072, -2048, -5376, -4096, 5632, 2304, -2304, 256, 3840, 3840, 8448, 7424, 4352, 2816, 9728, 18432, 7424, -2048, -9216, -6912, -10752, 4352, -10240, 6400, 6400, 2048, -768, 3584, 3840, 512, 11008, 8448, -512, -4864, -6144, -2048, 512, -17664, -29184, -24064, -19712, -22272, 5632, 6912, 4864, 6144, 14592, 30976, 24064, 10240, -6912, -7424, 1024, 7168, -3072, 1280, -5376, -7168, -4608, 0, -2304, 256, 9216, 5632, 1792, 1536, 3072, 1792, 2048, 14080, 1536, -512, -1792, -3328, -3072, -3072, -2048, -1280, -1280, -256, -1024, -1024, -768, -256, 1280, 2816, 3840, 4608, 4096, 2816, 1280, -1280, -3072, -4096, -4352, -3584, -2560, -1792, -768, -512, -768, -768, -1280, -768, 512, 2304, 4608, 5632, 5888, 4608, 2816, -512, -3584, -5120, -5632, -4608, -3072, -2048, -1280, -768, -1280, -1536, -1536, -1280, 256, 2816, 5632, 7680, 7936, 6144, 3840, -256, -3072, -5120, -5888, -4864, -3328, -2048, -768, -768, -512, -1536, -2048, -2304, -1280, 1536, 5376, 8192, 8960, 7424, 4864, 256, -3840, -6912, -7424, -6400, -3840, -2304, -1024, -256, -512, -1792, -3584, -3840, -2560, 1024, 6144, 10752, 12288, 11008, 6656, 1024, -5120, -9216, -9728, -7680, -4352, -1792, -768, 0, -256, -1024, -4096, -6144, -4864, -768, 6656, 12544, 15616, 15360, 10240, 2304, -5888, -11520, -13312, -9984, -5632, -1280, -512, 256, 768, -512, -4608, -8192, -7680, -2560, 5632, 14080, 19712, 19968, 13312, 3840, -5632, -13056, -16896, -13312, -7424, -1280, 0, 512, 2304, 1536, -3840, -9472, -10752, -5632, 2560, 14080, 22784, 25344, 18176, 5632, -5120, -14848, -20224, -17408, -8960, -2048, 1536, 256, 3072, 3328, -2304, -9472, -12800, -8960, 0, 11776, 23808, 29696, 23040, 8448, -3840, -15360, -22784, -21504, -11264, -2304, 2560, 768, 3328, 4864, -768, -8960, -13568, -11008, -3072, 8704, 23296, 32512, 27904, 11776, -2304, -14592, -24320, -24576, -14592, -3328, 2816, 1792, 2560, 6400, 512, -512, -8960, 0, 512, 1792, 3072, -1792, -20224, -17408, 512, -1536, -1280, 4864, 10240, 8448, 14080, 14336, 4352, 8192, 8192, 512, -5120, 1280, 13056, 6912, -5376, -3328, -2816, -4352, -5120, -1536, -16128, -32000, -29696, -22016, -15104, -8704, 2816, 5888, 5120, 9984, 16896, 12800, 12032, 13824, 11776, 2816, -1024, 11264, 17152, 7680, 2816, 4096, 1536, -512, 1792, -1024, -19712, -29184, -27392, -17920, -12800, -5120, 7424, 6656, 3072, 12288, 17664, 11264, 12032, 12544, 7168, -2048, 2304, 13568, 12544, 3840, 2304, 2048, -768, -2816, 1792, -8448, -27392, -31488, -25856, -15872, -12544, -1280, 6400, 1536, 3328, 14080, 12544, 8192, 10240, 9984, 1792, -4352, 4608, 12544, 8192, 1792, 2048, 256, -3072, -768, 1792, -15872, -28928, -27904, -18944, -12800, -7936, 5888, 8192, 3328, 10240, 17664, 12288, 11776, 13824, 10752, 512, 256, 10752, 13312, 6400, 2560, 2816, 0, -2816, 2560, -2560, -23040, -29440, -25856, -16384, -13312, -3840, 7424, 4096, 2560, 13056, 15104, 10496, 11776, 12544, 6400, -2304, 3840, 12288, 10752, 3840, 2560, 1792, -2304, -1792, 4096, -11008, -27392, -28928, -22784, -15360, -12032, 1024, 6912, 1024, 4864, 14848, 12032, 9728, 11776, 11008, 1536, -2304, 7168, 12032, 7424, 2560, 2816, 512, -3584, 1280, 1280, -18688, -28416, -27136, -18688, -14336, -7424, 6144, 5632, 1536, 10240, 15616, 11008, 11008, 13312, 9472, -768, 1536, 10496, 12032, 5888, 3072, 2816, 0, -3584, 256, 768, 1280, 1280, 1536, 2048, 1536, 1024, 0, -1024, -1280, -1536, -2304, -2304, -2816, -2816, -3072, -3328, -3328, -3328, -3072, -2816, -2304, -1280, -512, -256, 256, 1024, 1536, 2304, 2816, 3072, 3072, 2816, 2048, 1280, 512, -512, -512, -512, -512, 0, -256, -256, -512, -1280, -1280, -1280, -256, 1024, 2560, 4352, 5120, 5632, 4864, 3840, 1792, -256, -2304, -3840, -4864, -5376, -5376, -4608, -4096, -3328, -2816, -3072, -3840, -4864, -5888, -6144, -5120, -3328, -768, 2304, 5120, 8704, 11264, 12800, 11776, 8960, 5376, 1792, -1024, -3584, -5120, -4864, -3328, -2048, 512, 0, -1280, -3840, -7168, -8192, -7424, -3584, 0, 2816, 6912, 10752, 14848, 15104, 11520, 5632, 1024, -3840, -6656, -9472, -11008, -10752, -9472, -4352, 256, 4608, 5888, 2048, -1280, -7424, -12032, -12032, -11008, -6400, -1280, 5120, 13312, 20480, 23552, 19456, 11008, 2304, -5120, -8960, -9728, -11776, -10496, -7424, -3072, 4864, 8960, 5632, 1024, -8704, -13568, -14848, -10240, -6656, -4096, 3584, 12032, 22528, 27648, 23040, 12800, 4096, -2304, -9216, -13056, -16384, -16384, -13312, -8448, -256, 8192, 10240, 6144, 768, -7424, -15872, -14848, -16640, -13312, -4608, 5888, 17408, 29184, 32512, 24320, 10496, 256, -9216, -13824, -14336, -17408, -14080, -8960, -4352, 4864, 10752, 7424, 3328, -4096, -11776, -15360, -13824, -14336, -12032, -2816, 7424, 18432, 29696, 32512, 24064, 10496, -768, 0, 4096, 9984, 13824, 11776, 4608, 1792, -3840, -9216, -2304, -1536, -4096, -1280, -3840, -7680, -5888, -8960, -5120, 5632, 768, -4864, -5120, -3328, -2304, 4864, 5888, 2560, 3072, 8960, 16896, 13824, 1024, -11008, -14848, -3840, -2560, 4096, 14080, 4608, -9984, -9728, -7680, 512, 2304, 6912, 13056, -8192, -15360, -18432, -1024, 8192, 18176, 4864, -2048, 14336, -512, -10752, 2560, 5376, -1536, 7936, -2304, -17920, 2048, -1536, -4864, -23808, -5120, -1280, -7936, 2560, 1280, 14336, 6144, -11520, 2816, 16896, 12288, 15616, 22784, 12544, -14592, -1536, -5120, -17664, -26624, -21248, -12800, 8192, 2560, -4096, -22272, -19968, 7680, 32512, 16128, -4352, -23296, -512, -3072, 11520, 21248, 7680, 14336, 13824, 10752, 1792, 20224, -6656, -13312, -16384, -24832, 3072, -768, -27392, -25344, -9984, 8704, 22016, 4864, -6400, 6400, 23040, -2048, -9728, 16640, 9216, 2560, 7680, 9216, 4864, -1536, 9728, -12032, -25856, -13312, -11520, 7680, -2304, -27136, 4608, -2560, -9472, 4096, 25600, -24064, -28416, -6400, -8960, -3072, -2048, -2304, 13056, 6144, -1280, -17920, -13312, -13312, -4864, -2816, 12288, 23808, 15616, 4352, 28928, 32000, 18688, -4096, -7680, -14592, -19968, -29696, -14080, -9728, -2560, -1280, -1024, 9728, 7936, -768, -11776, -11776, -12800, -5120, -2560, 13312, 21504, 12288, 3584, 29440, 30464, 16384, -4096, -256, 1024, 0, -2304, -2816, -256, 1536, 512, -512, 1024, -1536, -2560, -512, 2816, 3584, 768, -2560, -3840, -256, 4352, 1024, 1536, 1024, -3072, -4608, 1536, 2560, 1024, 1536, -2048, -9216, 512, 768, 768, 1280, 3840, -5120, -4352, 2304, 2048, 2816, 4352, -2048, -6656, 4608, 512, 1280, 1280, 3328, -6144, -2048, -512, 512, 1280, 1792, -5376, -4608, 3328, 1280, -1280, 4352, 1792, -3584, -3328, -3072, 0, 3584, 768, -3072, -6656, 3328, 768, 2560, 4608, 3072, -3840, -3584, -256, 768, 4864, 0, -2560, -7424, 2816, 1024, 4352, 3840, 3072, -6144, -5120, 1536, 2304, 5632, -768, -3328, -3840, 2304, 256, 1792, 1536, 4608, -4864, -6656, -4608, 512, 5632, 0, -6400, -5120, 3840, 2048, -1024, 2048, 7936, -3072, -5120, -3840, 2304, 8448, 2304, -7424, -512, 6912, 1792, -2816, 2048, 5120, -5120, -10496, -2560, 3840, 8960, 3840, -5376, 2816, 12544, 1536, -1536, 1024, 768, -12288, -19456, -8960, 3584, 9472, 5632, -6144, 7424, 17408, 5120, 768, 1792, -1280, -17408, -23040, -15104, 4864, 9216, 7168, -3328, 15104, 23808, 7680, 512, 4608, -6400, -22528, -26880, -20736, 3328, 6656, 7680, -1024, 22528, 27904, 8448, 0, 5632, -7680, -22528, -28672, -19456, 4352, 7936, 4608, 1280, 24064, 29184, 7680, -1024, 0, 1024, -7680, -256, 0, -512, -512, -512, -256, 1024, 2816, 4608, 7680, 1792, -16384, -15360, -7680, -1792, 0, 512, 5632, 17152, 29952, 5888, -32768, -18944, -7680, -1280, -512, 256, 4864, 15872, 29696, 9728, -31488, -20992, -7936, -2048, -256, -256, 4096, 14592, 29184, 13312, -29952, -22528, -8448, -2560, -512, -768, 3584, 13312, 28672, 16384, -27648, -24576, -8960, -3328, -512, -1024, 3072, 12544, 27648, 19712, -25344, -26112, -9472, -3840, -512, -1280, 2560, 11008, 26624, 22016, -22272, -27904, -10240, -4608, -512, -1536, 2048, 10240, 25600, 24320, -18688, -29440, -10752, -5376, -512, -2048, 1792, 8960, 24320, 26112, -15104, -30720, -11520, -6144, -512, -2048, 1280, 8192, 23040, 27904, -11264, -31744, -12544, -6656, -768, -2304, 768, 7168, 21760, 29184, -7424, -32256, -13568, -7168, -1024, -2304, 512, 6400, 20736, 29696, -3328, -32512, -14848, -7424, -1536, -2304, 0, 5632, 19200, 30464, 768, -32256, -16128, -7936, -1792, -2304, -512, 4864, 17920, 30720, 4608, -31744, -17664, -8192, -2304, -2304, -768, 4096, 16640, 30464, 8704, -16128, -27392, -14848, -5888, -2816, -1792, 1792, 11776, 27392, 22784, -13312, -27904, -15872, -6400, -3072, -2048, 1280, 10752, 26624, 24832, -10496, -22272, -17920, -9216, -4608, -2816, 0, 7680, 21760, 25600, -512, -22272, -1280, 2816, -5888, -2560, -768, -5120, -768, -4352, -6144, -8448, -6656, -256, -3328, -3072, -1536, -2304, 1536, 6400, 4864, -1792, -256, 5632, -1536, -5120, 3328, 1536, -3072, 6656, 12288, 0, -1792, 8704, 5888, 1024, 8192, 5888, -10496, -2816, 12544, -768, -7680, 8960, 11520, -3584, -512, 15872, 4608, -11264, -512, 6656, -1024, -7168, -1536, 4096, 512, -2304, -2304, 512, 4608, 6144, 2304, -6400, -14592, -9216, 7680, 9728, -5376, -16128, -9472, 2304, 9472, 10240, 0, -14336, -14336, 768, 9984, 5120, -5888, -13312, -14848, -11776, 2048, 17152, 14336, -4608, -15616, -4608, 9216, 17920, 24320, 18688, -8960, -32768, -32512, -18688, -4352, 8192, 12288, 7424, 7168, 15360, 27136, 28928, 23296, 9216, -6656, -17152, -23040, -23296, -18176, -11264, -6400, -3328, 2304, 9216, 13056, 17664, 17920, 8192, -10240, -23552, -25344, -17920, -6400, 3072, 7424, 5376, 768, -2304, 2560, 5376, 3072, -2816, -5632, -6912, -11264, -5888, 2560, 7680, 6400, 6144, 9984, 4608, 768, 2048, 4864, -256, -4864, -2048, 1536, 1280, 3328, 12800, 11008, 9472, 9216, 10240, 9472, 1024, 3072, -2560, -8448, -7936, -6400, -256, 256, 1792, 3584, 2560, -1024, -2816, -2560, -1536, -4864, -10752, -7168, -13824, -13056, -4608, -1280, 768, 512, -2560, -2560, 2560, 7168, 6912, 4096, 1280, -1280, -6144, -6656, -1792, -3584, -6400, -4096, 13568, 8448, -12544, -7680, 13568, 12800, -6144, -8704, 10240, 20992, -30208, -5888, 30720, -14336, -17920, -18432, 27136, -2560, -12288, 768, 22272, 7168, -32256, -4096, 20736, 1024, -21504, -13056, 9728, 15872, -8192, 9216, 21504, -3072, -10496, 18432, -10752, -15360, -16384, 1024, 19712, -6144, -20224, -2304, 31232, 1536, -24064, 13312, 11008, 8960, 3328, -15872, -1792, -22784, 6144, -7680, 4096, 7424, 14336, -15104, 21248, 10752, 7936, 9216, -19456, -512, -32768, -512, 11520, 6912, -26624, -7936, 16896, 5376, 4864, 9216, 30976, 2816, -19456, -6656, -23808, 8704, 6144, -8704, -16640, -13568, 13568, 4352, 18688, 11776, 19200, -2304, -16384, -5376, -26368, 10496, 13056, -10496, -21248, -11008, 27648, 1536, -2816, 7168, 32512, 512, -21504, -9728, -18432, 9984, 4352, -5888, -3840, -17152, 9472, 1536, 7424, 16384, 20224, 4352, -9984, -9984, -30720, 14080, 5888, -4352, -15872, -13056, 20736, 5888, 5120, 6144, 25344, -9728, -25344, 1024, 4352, -16896, -10496, -8448, 16128, 15872, 4096, 13568, 23296, 14336, -16640, -9216, -25344, -9728, 3584, -12032, -7424, -9728, 8960, 21248, 2304, 12288, 21248, 15872, -11520, -7936, -26368, -12544, 3584, 512, 1536, -8448, 8448, -1024, -256, 8704, -23808, 15360, -12544, 17408, -5376, 10496, -9728, -9728, 6912, -22272, 32512, -8704, 9728, -768, -8704, -512, -21760, 20224, -6144, 1024, 19200, -5888, 2816, -17920, 256, -1536, -1536, 16128, -12288, 19456, -18176, 512, -1792, -3840, 11776, -8192, 12288, -6400, -1280, 2560, -7936, 4608, -5888, 1280, 1536, 4352, 2816, 768, 6144, -11776, -5376, -256, -1280, 7936, 256, 9216, -5888, -2816, -1024, -7424, 3584, -1280, 7424, 2304, -512, -512, -5120, -512, -3840, 3328, 1792, 1024, 3840, -2816, 1024, -3328, -256, 256, -3328, 3840, -1536, 2304, 2304, -512, -1024, -2816, -512, -2816, 1792, 3072, 2304, 1280, -1536, -1536, -4096, -512, 768, 1536, 3328, 256, 1792, -3584, -768, -2816, -256, 2048, 0, 4608, -768, -768, -1536, -3328, 0, 1024, 512, 2304, 512, 512, -1536, -1024, -256, -2048, 512, 1024, 512, 1792, -1024, 512, 256, -1792, -768, -512, 0, 512, 2048, -512, 512, -256, -1792, -768, -256, 768, 1024, 768, 768, -768, -1024, -1024, 0, 512, 256, 1280, -256, -512, 256, -1024, -256, 256, 0, 512, -1280, -2048, -768, -768, -2304, -512, -512, 1280, 2560, 4096, 2816, 1280, -768, -1280, -256, -1024, -1536, -1792, -3840, -4608, -6912, -7936, -5376, -2816, 5632, 14336, 23040, 16896, -4352, -6400, -6400, 0, -3072, -3840, -6400, -8192, -9984, -9472, -6656, 1536, 8448, 16640, 17664, 11264, -256, -3328, -3072, 256, 0, -2304, -3584, -5632, -10240, -11264, -10752, -5888, 2048, 9984, 15360, 21504, 14592, -4096, -6400, -4864, 512, -2048, -2816, -4608, -8192, -13056, -11520, -8192, -1536, 7168, 13824, 21760, 24576, -1280, -7424, -5888, -1792, -2560, -4352, -4096, -7168, -13568, -11264, -10240, -1792, 5632, 13312, 20992, 28672, 4352, -9472, -6400, -5120, -2816, -4608, -2560, -5888, -8448, -13056, -10240, -5888, 2560, 11520, 16640, 24576, 16384, -5376, -8960, -8704, -4864, -5120, -3328, -1280, -3584, -8960, -10496, -9984, -4352, 2304, 11520, 14848, 20992, 25088, -512, -14592, -12032, -5888, -3072, -2816, -512, -4608, -7168, -9984, -9216, -6144, -256, 6656, 14592, 21504, 30976, 5888, -16640, -12800, -10240, -3072, -2816, -1024, -3584, -5120, -8704, -8192, -6912, -1280, 4864, 14336, 20480, 32512, 3840, -16896, -12800, -512, -1280, -1280, 512, 2560, 2048, -1792, -4096, -2304, 1536, 4352, 2048, -4864, -5120, 3584, 9728, 8704, 5120, -1280, 256, 12800, 9472, -12800, -13824, -16896, -8192, 8192, -768, -3328, -4608, -4352, 11776, 22784, -4352, -15872, 11520, 32512, 14592, -14592, -17152, -27904, -2816, 22528, -7936, -23040, -22528, -6912, 16128, 24832, -6912, -26880, -11264, 16640, 28160, 15360, -3072, -7680, -6912, 4352, 12544, -512, -9984, -1536, 7680, -4096, -9216, -11008, 8192, 17152, -13824, -14848, -9728, -5376, 12032, 24320, 19456, -8448, -19968, -15872, 2560, 27392, 6144, -27136, -27392, 3072, 13312, 6912, 19968, 2048, -19200, 6400, 1536, -6656, 15104, 8192, -4352, -1792, -4864, 2816, 8192, -13056, -13312, 10496, -2304, -3328, 24064, 512, -16640, 1280, -11776, -22016, 8704, 15872, 21760, 7424, -23808, -22784, -7424, 11264, 8960, -7936, -8448, -4864, 14336, 32512, 1792, -2304, -15872, -13312, 5888, 11776, 11264, -14336, -4096, -14080, -11776, 5632, 21248, -3328, -10752, -1792, 3328, 20736, 12544, 768, -2304, -7680, -12032, -7680, 768, 5888, 1536, -1792, -5120, -11264, 2560, 24576, -3328, 0, 4096, 7936, 12032, 15616, 19200, 22272, 25088, 27392, 29440, 30976, 32000, 32512, 32512, 32000, 30976, 29696, 27648, 25344, 22528, 19200, 15872, 12032, 8192, 4096, 0, -4096, -7936, -12032, -15616, -19200, -22272, -25088, -27648, -29696, -31232, -32256, -32768, -32768, -32256, -31488, -29952, -27904, -25600, -22784, -19712, -16384, -12544, -8704, -4608, -512, 3584, 7424, 11520, 15104, 18688, 22016, 24832, 27136, 29184, 30976, 32000, 32512, 32512, 32256, 31232, 29696, 27904, 25600, 22784, 19712, 16128, 12544, 8704, 4608, 512, -3584, -7680, -11520, -15360, -18688, -22016, -24832, -27392, -29440, -30976, -32256, -32768, -32768, -32512, -31488, -30208, -28160, -25856, -23296, -20224, -16640, -13056, -9216, -5120, -1024, 3072, 7168, 11008, 14848, 18432, 21504, 24576, 27136, 29184, 30720, 31744, 32512, 32512, 32256, 31232, 29952, 27904, 25600, 23040, 19968, 16384, 12800, 8960, 4864, 768, -3328, -7424, -11264, -15104, -18688, -21760, -24832, -27392, -29440, -30976, -32000, -32768, -32768, -32512, -31488, -30208, -28160, -25856, -23296, -20224, -16640, -13056, -9216, -5120, -1024, 3072, 512, 1280, 1280, 0, -4096, -2304, -512, -4864, 1024, 4608, 1536, 2560, -4096, -5376, 5632, -512, 768, -1792, 5376, 11008, -14592, -9472, 11776, -9984, -7936, 19968, 5888, -5888, -2560, -2560, -1792, -13312, 11264, 12800, -11264, 2304, -2304, -11776, 12032, 3072, -19200, 10240, 11520, 8192, -2560, -6400, -3840, -11520, 6144, 11264, -10240, -2560, 4608, -12288, -7424, 16128, 11264, -7680, -256, 21248, -11520, -24064, 24576, 0, -26368, 5376, 7424, -10752, 5376, 20480, -6400, -3840, 6656, 9984, -20224, -4608, 18688, -28416, -11520, 15616, 7424, 14080, -5632, -19712, 10240, 2304, -18432, 19968, 8960, -256, -256, -17664, 3072, -12800, -10752, 31488, 11520, -1792, -9984, -22016, 768, 13056, 7680, 7168, -1024, -8448, -10496, -16896, 13824, -2048, -7680, 32512, -1792, -7680, -8192, -9984, 12288, -16640, 5120, 30976, -8448, -3584, -13568, -8192, 11776, -6144, 9216, 25088, -12544, -9984, -15616, 256, 12544, -13824, 16640, 15104, -21248, -2816, -12544, 8192, 9984, -18432, 28928, 15104, -21248, -2816, -12544, 8192, 9984, -18432, 28928, 15104, -512, -1024, -1024, -1792, -2048, -2048, -1792, -1024, -768, -512, 256, 1024, 1536, 1536, 1536, 1024, 512, 0, -512, -768, -1024, -1792, -1792, -1280, -768, 0, 1024, 2304, 2816, 2816, 2304, 1792, 1024, 256, -768, -1792, -2304, -3072, -3328, -4096, -4864, -4864, -3328, -512, 2304, 4352, 4864, 5120, 4608, 3328, 2048, 768, 0, -512, -768, -2048, -3584, -5376, -6400, -5376, -2304, 1024, 3840, 5888, 7168, 6400, 5120, 2304, -1792, -5376, -3584, 768, 768, -4608, -9728, -12544, -8192, -1792, 2048, 3584, 6656, 9472, 10752, 9472, 6656, 1792, -4608, -6912, -1280, 2048, -1792, -6144, -8704, -10240, -8192, -4864, 256, 4352, 10752, 14336, 14848, 10240, -4864, -20736, 256, 17152, 0, -15360, -12544, -6912, -6144, 0, -4608, -6144, -2048, 9472, 17152, 17920, 15104, 8704, -10752, -20736, 1792, 13056, -3072, -13824, -9472, -3584, -6400, -3584, -4096, -6144, 1024, 14080, 19200, 26112, 13312, -26112, -26624, 23040, 7680, -12288, -19456, 256, -3584, 0, -512, -512, -768, -1280, -1792, -2048, -2048, -1792, -1536, -1024, -512, 0, 256, 768, 1024, 1536, 1536, 1536, 1536, 1280, 1024, 768, 256, 0, 0, -768, -1024, -1792, -2560, -2816, -2816, -2048, -1536, 256, 1280, 1536, 2048, 2816, 2816, 2048, 1280, 1280, 512, 256, 0, 0, -512, 256, -1024, -4096, -9216, -6912, -1280, 1536, -768, -1536, 0, -1536, 512, 6912, 6144, 4864, 4096, 2304, 768, 0, -1024, 512, 256, 2304, 4864, -3584, -20224, -8192, 5632, -1024, -5632, -3584, 6400, 2048, -2816, 3328, 7168, 4096, 4864, 4096, 256, -512, -1024, -768, -1536, 7168, 9728, -15104, -28416, 6400, 4096, -4096, -10240, 4096, 6144, -5120, 1024, 6144, 7424, 4352, 6912, 3328, 256, -2560, -1536, -2560, -2048, 11008, 15616, -17408, -32768, 7168, 3072, -3840, -9984, 3072, 5376, -7168, 3072, 9472, 6400, 3072, 6912, 2816, 0, -4096, -512, -3072, -2816, 13312, 17152, -17408, 8960, 13824, 12032, 1024, -15360, -23552, -17408, -6912, 0, -512, -4608, -5120, -1536, 512, -2048, -3840, -2816, -768, 768, -1792, -2816, -1536, -512, 1792, 3840, 4608, 4864, 5632, 6912, 10240, 10240, 7424, 5120, 6144, 7168, 8704, 7680, 6400, 8192, 5120, 3584, 2304, 4096, 4864, 4352, 1536, -256, 768, -1536, -3584, -5888, -4608, -1792, 256, -4608, -4608, -6144, -6400, -6144, -8960, -8960, -8960, -5376, -3072, -3584, -5376, -4352, -7424, -6144, -7936, -8704, -2304, -2816, -2304, -768, -1792, -1792, 1536, -4352, -5632, 1792, 4096, 3584, -1024, -2816, 2560, 8448, 6144, 5376, 6912, 768, -4864, -6400, -4608, 4352, 12800, 12288, 12544, 15616, 7936, -12288, -26368, -18688, 2304, 14336, 17920, 20992, 27904, 32512, 18176, -11776, -32512, -24576, -7680, -1024, 2304, 12032, 26368, 29952, 15360, -9984, -28160, -30464, -24064, -16384, -10240, -1024, 8960, -2048, -3584, -2304, -1280, -1024, -768, 1536, 4608, 4864, 1536, -3584, -5120, -3072, -768, -768, -1536, 512, 5376, 7168, 3328, -4096, -6656, -3584, -1536, -1536, -1792, 256, 6912, 9216, 4608, -3840, -6912, -3840, -768, -512, -2560, -1536, 6400, 10496, 5632, -4352, -8704, -4608, -1024, -768, -4096, -3072, 7424, 14336, 7936, -6144, -11264, -5120, -1024, -256, -4864, -5632, 7936, 18688, 12032, -6912, -15872, -6400, -512, 1024, -5376, -9216, 6656, 23296, 15616, -6912, -20224, -8448, 0, 2560, -4608, -12544, 3584, 27136, 20992, -6144, -24064, -10240, 2048, 3584, -3072, -15104, 256, 28672, 26880, -4864, -27136, -13056, 3072, 4096, -1024, -16128, -3328, 28160, 32512, -3072, -29184, -13056, 0, -256, -1024, -2048, -2816, -2048, -512, 0, 1792, 3584, 5376, 11776, 23552, 30720, 19456, -9216, -30976, -30464, -18688, -7936, -1792, 768, 512, -1024, -1536, 512, 5632, 15360, 27136, 29696, 11008, -18432, -32768, -26880, -14592, -5376, -768, 768, -256, -1536, -1280, 1792, 8448, 19456, 29952, 26112, 1280, -25600, -32512, -22784, -11008, -3328, 0, 512, -768, -1792, -512, 3584, 11776, 23552, 31232, 20224, -8704, -30208, -30208, -18432, -7936, -2048, 256, 0, -1280, -1792, 512, 5888, 15616, 27392, 30208, 11776, -17664, -32256, -26624, -14336, -5376, -1024, 256, 0, -1024, -1280, 0, 4096, 12288, 22272, 26368, 15360, -6400, -22272, -24064, -14848, -5120, -1024, -2816, 3072, 6144, 7936, -9216, 7424, -2304, 512, -9728, -1280, -1280, -2560, -8448, -2560, -6144, -5120, -9984, -9216, -4608, -9728, -14848, -1280, -5632, -3840, -3840, 23040, -10752, -768, -2048, 6400, 1536, 7168, 6400, 4352, 6400, -4096, 7168, 20480, 5632, 3072, -1536, 8960, 5632, 2048, -1792, 7168, 7424, -4864, 1792, 2048, -256, -7424, -5888, 2560, -5888, -3328, -6656, -4352, -5120, -8448, -10496, -4864, -7168, -16384, -3328, -5376, -3328, -7424, 13824, 6400, -5120, -9216, 10752, -1024, 3328, 13312, -2048, 12032, -3584, 2304, 10752, 22528, -3072, 5120, -1280, 11008, 5632, -2816, 32512, 32512, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, -32768, 256, 1024, 1792, 2560, 3072, 4096, 4864, 5632, 6400, 7168, 7936, 8960, 9728, 10752, 11520, 12544, 13056, 14336, 14848, 16128, 16640, 17920, 18688, 19968, 20480, 21760, 22272, 23808, 24320, 25600, 26112, 27648, 27904, 29952, 29184, 32512, 21760, -16128, -15360, -16384, -15360, -15872, -15104, -15616, -15104, -15616, -14848, -15360, -14848, -15104, -14848, -14848, -14592, -14592, -14080, -14080, -13824, -13824, -13312, -13056, -12800, -12544, -12032, -11776, -11264, -11008, -10496, -10240, -9472, -9216, -8704, -8192, -7680, -7168, -6400, -6144, -5376, -4864, -4096, -3584, -2816, -2304, -1536, 256, 256, 1024, 1792, 2560, 3072, 4096, 4864, 5632, 6400, 7168, 7936, 8960, 9728, 10752, 11520, 12544, 13056, 14336, 14848, 16128, 16640, 17920, 18688, 19968, 20480, 21760, 22272, 23808, 24320, 25600, 26112, 27648, 27904, 29952, 29184, 32512, 21760, -16128, -15360, -16384, -15360, -15872, -15104, -15616, -15104, -15616, -14848, -15360, -14848, -15104, -14848, -14848, -14592, -14592, -14080, -14080, -13824, -13824, -13312, -13056, -12800, -12544, -12032, -11776, -11264, -11008, -10496, -10240, -9472, -9216, -8704, -8192, -7680, -7168, -6400, -6144, -5376, -4864, -4096, -3584, -2816, -2304, -1536, 256, -768, -4864, -6144, -3584, -2048, -4864, -3072, -2560, -1280, -3072, -12800, -4864, 5888, 8960, 1024, -5120, -1792, -6656, 2304, 10240, 17664, 4096, -22528, -17664, -9728, -8192, -6912, 10496, 16640, 14080, 4608, -10240, -9728, -5120, 16896, 32512, 30976, 14592, -5888, -14080, -12288, 3328, 13568, 7936, -5120, -9728, -3328, 2560, 2048, 0, 3072, 4352, 3328, 512, -256, -768, -768, 1536, 3328, 1792, -4352, -6144, -3072, 1024, 768, -2560, -5120, -8192, -5632, -4608, -3072, -768, 1536, 4096, 5632, 7424, 7680, 6912, 5120, 2816, 0, -1792, -3072, -2816, -1280, 0, -768, -3584, -5120, -4096, -2304, -2304, -4352, -6400, -7424, -7936, -8448, -8960, -8448, -7424, -6400, -5632, -5120, -4352, -3584, -3328, -3072, -2816, -2304, -2560, -3328, -3840, -2816, -1280, 768, 2304, 2560, 2304, 2304, 3072, 4608, 7680, 12800, 20480, 30464, 32512, 26112, 20992, 19712, 15360, 9472, 1280, -8704, -17920, -21504, -21248, -18944, -15360, -11776, -7424, -3072, -512, 1536, -5888, 7168, -5120, 12800, 12800, -3584, 3584, -7168, -512, 7168, 13312, -6400, -3328, -13312, 11008, -10496, -2304, -6656, 9216, -6400, -5120, -4352, 768, -2816, 9728, 7680, -15616, 3072, -1536, 1280, 11520, 10496, -1024, 1024, -5120, -3072, 11520, 8448, -2816, -7424, -11264, 6912, -4352, -9216, -256, 4352, -2816, -7936, -3072, 1024, -2560, 9472, 5120, -9984, -5888, 0, -26624, -14080, -2816, 6144, 8448, 7680, 1792, -3840, -7936, -7680, -6400, -5888, -5120, -2304, 2560, 7936, 15104, 23296, 28416, 29440, 23552, 13056, 1792, -8448, -16384, -20736, -20736, -18176, -13056, -5632, 4096, 13312, 18944, 20992, 20736, 17408, 9728, 0, -10240, -20736, -28672, -31744, -26112, -14592, -2816, 0, 1792, -5888, -14848, -21760, -25600, -26624, -25600, -23552, -20736, -17664, -14592, -11520, -8448, -5632, -2816, -256, 2048, 4608, 6912, 9472, 12544, 15872, 20224, 25344, 30208, 31744, 28416, 21504, 13568, 6656, 1280, -2048, -3584, -3840, -3072, -1536, 512, 3072, 5376, 7168, 6656, 2304, -5632, -14848, -5120, 1792, 2560, 5376, -3584, 2304, 5632, 14592, 15872, 32512, 14336, 7168, 6656, -7168, 2560, -20736, -7936, -20736, -8960, -4864, -14080, -6912, -1024, -1024, 5888, 12544, 22528, 21760, 5632, 256, 0, -768, 4608, -5632, -3072, -9984, -3584, -12032, -17152, -13568, -13568, -8448, -5120, 2048, -5632, 6400, 7680, 1536, -4864, -15872, -4864, 2560, 21248, 14592, -17152, -22528, -13312, 16128, 32512, 10752, -16128, -30976, -17920, 20992, 28416, 11776, -11008, -29184, -8960, 11520, 18688, 9984, -4864, -13824, -10496, 2304, 12544, 6144, -4096, -3584, -2304, -1536, 2560, 2048, -5632, 6400, 7680, 1536, -4864, -15872, -4864, 2560, 21248, 14592, -17152, -22528, -13312, 16128, 32512, 10752, -16128, -30976, -17920, 20992, 28416, 11776, -11008, -29184, -8960, 11520, 18688, 9984, -4864, -13824, -10496, 2304, 12544, 6144, -4096, -3584, -2304, -1536, 2560, 2048, -5632, 6400, 7680, 1536, -4864, -15872, -4864, 2560, 21248, 14592, -17152, -22528, -13312, 16128, 32512, 10752, -16128, -30976, -17920, 20992, 28416, 11776, -11008, -29184, -8960, 11520, 18688, 9984, -4864, -13824, -10496, 2304, 12544, 6144, -4096, -3584, -2304, -1536, 2560, -4608, -3840, 20480, 32512, 5120, 4608, 18432, 15360, -9216, 5632, 8448, -18688, -26880, -6912, 7424, 6400, 2048, 11008, 5888, -5632, -8960, -3584, -2048, -8704, -6400, -1280, -4608, -11776, -3328, -7168, -768, -4864, -2560, -7168, -2560, 4352, -4608, 24576, 32512, 31488, 32512, 32256, 32256, 24320, 15616, 5632, -4352, -14336, -24320, -30208, -31488, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -31744, -23808, -14080, -4352, 6400, 15872, 25600, 27392, 30464, 30464, 32512, 10496, -1024, -1024, -2560, -6912, -15872, -26112, -32768, -29952, -21760, -19456, -12544, -6400, -1792, 3840, 6144, 3584, 0, -2304, -3072, -768, 8448, 20736, 26880, 28416, 25856, 20480, 15872, 11520, 7680, 4096, 2048, 256, -1024, 32256, 22016, -11264, -17408, -22528, -16128, 1024, 21504, 32512, 3584, -7424, -13056, -32512, -12032, 14848, 22272, 20992, 6144, -4352, -28672, -28928, 4608, 11776, 18432, 26112, 4864, -18432, -30208, -13056, 2304, 6912, 32256, 4864, -13568, -29184, -27648, 3840, 31232, 28416, 5376, -18176, -17920, 1280, 15104, 21248, 5888, -18432, -21504, -12544, 3072, 9472, 9728, -7168, -16640, -6656, 1792, -512, 2816, 1280, 5888, 17408, 4864, 6912, -13824, 3840, -6144, -7936, 11776, 18176, 20736, -6144, -8448, -22272, -10496, -18176, -15616, -17920, -9216, -11264, -768, 3072, -6400, -5120, 5120, 17408, 21760, 32512, 3840, 12800, -1280, 6912, 13056, 20992, 27136, 32512, 30208, 25856, 23552, 18944, 13312, 9984, 9472, 3584, -10496, -26880, -27648, -24064, -30464, -31744, -23808, -14592, -10240, -9472, -11520, -13056, -10496, -1280, 13056, 32512, 32512, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512, 32512 }; const EAS_U32 eas_sampleLengths[] = { 33640, 33416, 33184, 23508, 21908, 20590, 19844, 14978, 11558, 10924, 8904, 7558, 6230, 6186, 6114, 6048, 5636, 5552, 4342, 4336, 4104, 3804, 3670, 3228, 3206, 3056, 3034, 2960, 2910, 2848, 2774, 2604, 2524, 2508, 2460, 2454, 2370, 2362, 2356, 2336, 2264, 2240, 2068, 2066, 2036, 1988, 1928, 1852, 1814, 1772, 1762, 1732, 1660, 1634, 1632, 1626, 1498, 1496, 1478, 1440, 1304, 1220, 1220, 1166, 1128, 1122, 1112, 1098, 1084, 1070, 1060, 1060, 1032, 1016, 984, 956, 922, 896, 874, 862, 846, 836, 806, 804, 800, 788, 774, 774, 734, 714, 694, 694, 682, 672, 668, 658, 650, 624, 588, 568, 554, 530, 510, 466, 460, 426, 414, 410, 388, 386, 368, 362, 362, 334, 328, 316, 304, 304, 290, 278, 256, 206, 200, 176, 174, 168, 168, 144, 142, 110, 92, 90, 86, 80, 80, 80, 74, 70, 64, 64, 60, 58, 54, 46, 44, 42, 42, 42, 42, 40, }; const EAS_U32 eas_sampleOffsets[] = { 0x00000000, 0x00008368, 0x000105f0, 0x00018790, 0x0001e364, 0x000238f8, 0x00028966, 0x0002d6ea, 0x0003116c, 0x00033e92, 0x0003693e, 0x00038c06, 0x0003a98c, 0x0003c1e2, 0x0003da0c, 0x0003f1ee, 0x0004098e, 0x00041f92, 0x00043542, 0x00044638, 0x00045728, 0x00046730, 0x0004760c, 0x00048462, 0x000490fe, 0x00049d84, 0x0004a974, 0x0004b54e, 0x0004c0de, 0x0004cc3c, 0x0004d75c, 0x0004e232, 0x0004ec5e, 0x0004f63a, 0x00050006, 0x000509a2, 0x00051338, 0x00051c7a, 0x000525b4, 0x00052ee8, 0x00053808, 0x000540e0, 0x000549a0, 0x000551b4, 0x000559c6, 0x000561ba, 0x0005697e, 0x00057106, 0x00057842, 0x00057f58, 0x00058644, 0x00058d26, 0x000593ea, 0x00059a66, 0x0005a0c8, 0x0005a728, 0x0005ad82, 0x0005b35c, 0x0005b934, 0x0005befa, 0x0005c49a, 0x0005c9b2, 0x0005ce76, 0x0005d33a, 0x0005d7c8, 0x0005dc30, 0x0005e092, 0x0005e4ea, 0x0005e934, 0x0005ed70, 0x0005f19e, 0x0005f5c2, 0x0005f9e6, 0x0005fdee, 0x000601e6, 0x000605be, 0x0006097a, 0x00060d14, 0x00061094, 0x000613fe, 0x0006175c, 0x00061aaa, 0x00061dee, 0x00062114, 0x00062438, 0x00062758, 0x00062a6c, 0x00062d72, 0x00063078, 0x00063356, 0x00063620, 0x000638d6, 0x00063b8c, 0x00063e36, 0x000640d6, 0x00064372, 0x00064604, 0x0006488e, 0x00064afe, 0x00064d4a, 0x00064f82, 0x000651ac, 0x000653be, 0x000655bc, 0x0006578e, 0x0006595a, 0x00065b04, 0x00065ca2, 0x00065e3c, 0x00065fc0, 0x00066142, 0x000662b2, 0x0006641c, 0x00066586, 0x000666d4, 0x0006681c, 0x00066958, 0x00066a88, 0x00066bb8, 0x00066cda, 0x00066df0, 0x00066ef0, 0x00066fbe, 0x00067086, 0x00067136, 0x000671e4, 0x0006728c, 0x00067334, 0x000673c4, 0x00067452, 0x000674c0, 0x0006751c, 0x00067576, 0x000675cc, 0x0006761c, 0x0006766c, 0x000676bc, 0x00067706, 0x0006774c, 0x0006778c, 0x000677cc, 0x00067808, 0x00067842, 0x00067878, 0x000678a6, 0x000678d2, 0x000678fc, 0x00067926, 0x00067950, 0x0006797a, }; #endif /*---------------------------------------------------------------------------- * S_EAS *---------------------------------------------------------------------------- */ const S_EAS easSoundLib = { 0x01534145, #if defined (_8_BIT_SAMPLES) 0x00105622, #else //_16_BIT_SAMPLES 0x00205622, #endif eas_banks, eas_programs, eas_regions, eas_articulations, eas_sampleLengths, eas_sampleOffsets, eas_samples, 0, 1, 1, 377, 185, 150, 0 }; /* end S_EAS */ /*---------------------------------------------------------------------------- * Statistics * * Number of banks: 1 * Number of programs: 1 * Number of regions: 377 * Number of articulations: 185 * Number of samples: 150 * Size of sample pool: 212050 *---------------------------------------------------------------------------- */ /* end wt_200k_G.c */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_vm_protos.h0000644000000000000000000000013214200302440027132 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.189324413 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_vm_protos.h0000644000175000001440000011265014200302440027720 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_vm_protos.h * * Contents and purpose: * Declarations, interfaces, and prototypes for voice manager. * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 736 $ * $Date: 2007-06-22 13:51:24 -0700 (Fri, 22 Jun 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_VM_PROTOS_H #define _EAS_VM_PROTOS_H // includes #include "eas_data.h" #include "eas_sndlib.h" /*---------------------------------------------------------------------------- * VMInitialize() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ EAS_RESULT VMInitialize (S_EAS_DATA *pEASData); /*---------------------------------------------------------------------------- * VMInitMIDI() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth); /*---------------------------------------------------------------------------- * VMInitializeAllChannels() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMResetControllers() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ void VMResetControllers (S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMInitMIPTable() *---------------------------------------------------------------------------- * Purpose: * Initialize the SP-MIDI MIP table * * Inputs: * pEASData - pointer to synthesizer instance data * mute - EAS_FALSE to unmute channels, EAS_TRUE to mute * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ void VMInitMIPTable (S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMSetMIPEntry() *---------------------------------------------------------------------------- * Purpose: * Sets the priority and MIP level for a MIDI channel * * Inputs: * pEASData - pointer to synthesizer instance data * channel - MIDI channel number * priority - priority (0-15 with 0 = highest priority) * mip - maximum instantaneous polyphony * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip); /*---------------------------------------------------------------------------- * VMUpdateMIPTable() *---------------------------------------------------------------------------- * Purpose: * This routine is called when the polyphony count in the synthesizer changes * * Inputs: * pEASData - pointer to synthesizer instance data * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMInitializeAllVoices() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum); /*---------------------------------------------------------------------------- * VMStartNote() *---------------------------------------------------------------------------- * Purpose: * Update the synth's state to play the requested note on the requested * channel if possible. * * Inputs: * nChannel - the MIDI channel * nKeyNumber - the MIDI key number for this note * nNoteVelocity - the key velocity for this note * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity); /*---------------------------------------------------------------------------- * VMCheckKeyGroup() *---------------------------------------------------------------------------- * Purpose: * If the note that we've been asked to start is in the same key group as * any currently playing notes, then we must shut down the currently playing * note in the same key group and then start the newly requested note. * * Inputs: * nChannel - synth channel that wants to start a new note * nKeyNumber - new note's midi note number * nRegionIndex - calling routine finds this index and gives to us * nNoteVelocity - new note's velocity * psEASData - pointer to overall EAS data structure * * Outputs: * pbVoiceStealingRequired - flag: this routine sets true if we needed to * steal a voice * * Side Effects: * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber may be assigned * gsSynthObject.m_sVoice[free voice num].m_nVelocity may be assigned *---------------------------------------------------------------------------- */ void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel); /*---------------------------------------------------------------------------- * VMCheckPolyphonyLimiting() *---------------------------------------------------------------------------- * Purpose: * We only play at most 2 of the same note on a MIDI channel. * E.g., if we are asked to start note 36, and there are already two voices * that are playing note 36, then we must steal the voice playing * the oldest note 36 and use that stolen voice to play the new note 36. * * Inputs: * nChannel - synth channel that wants to start a new note * nKeyNumber - new note's midi note number * nNoteVelocity - new note's velocity * psEASData - pointer to overall EAS data structure * * Outputs: * pbVoiceStealingRequired - flag: this routine sets true if we needed to * steal a voice * * * Side Effects: * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned *---------------------------------------------------------------------------- */ EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice); /*---------------------------------------------------------------------------- * VMStopNote() *---------------------------------------------------------------------------- * Purpose: * Update the synth's state to end the requested note on the requested * channel. * * Inputs: * nChannel - the MIDI channel * nKeyNumber - the key number of the note to stop * nNoteVelocity - the note-off velocity * psEASData - pointer to overall EAS data structure * * Outputs: * Side Effects: * gsSynthObject.m_sVoice[free voice num].m_nSynthChannel may be assigned * gsSynthObject.m_sVoice[free voice num].m_nKeyNumber is assigned * gsSynthObject.m_sVoice[free voice num].m_nVelocity is assigned *---------------------------------------------------------------------------- */ void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 key, EAS_U8 velocity); /*---------------------------------------------------------------------------- * VMFindAvailableVoice() *---------------------------------------------------------------------------- * Purpose: * Find an available voice and return the voice number if available. * * Inputs: * pnVoiceNumber - really an output, see below * psEASData - pointer to overall EAS data structure * * Outputs: * pnVoiceNumber - returns the voice number of available voice if found * success - if there is an available voice * failure - otherwise *---------------------------------------------------------------------------- */ EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice); /*---------------------------------------------------------------------------- * VMStealVoice() *---------------------------------------------------------------------------- * Purpose: * Steal a voice and return the voice number * * Stealing algorithm: steal the best choice with minimal work, taking into * account SP-Midi channel priorities and polyphony allocation. * * In one pass through all the voices, figure out which voice to steal * taking into account a number of different factors: * Priority of the voice's MIDI channel * Number of voices over the polyphony allocation for voice's MIDI channel * Amplitude of the voice * Note age * Key velocity (for voices that haven't been started yet) * If any matching notes are found * * Inputs: * nChannel - the channel that this voice wants to be started on * nKeyNumber - the key number for this new voice * psEASData - pointer to overall EAS data structure * * Outputs: * pnVoiceNumber - voice stolen * EAS_RESULT EAS_SUCCESS - always successful *---------------------------------------------------------------------------- */ EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice); /*---------------------------------------------------------------------------- * VMAddSamples() *---------------------------------------------------------------------------- * Purpose: * Synthesize the requested number of samples. * * Inputs: * nNumSamplesToAdd - number of samples to write to buffer * psEASData - pointer to overall EAS data structure * * Outputs: * number of samples actually written to buffer * * Side Effects: * - samples are added to the presently free buffer * *---------------------------------------------------------------------------- */ EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamplesToAdd); /*---------------------------------------------------------------------------- * VMProgramChange() *---------------------------------------------------------------------------- * Purpose: * Change the instrument (program) for the given channel. * * Depending on the program number, and the bank selected for this channel, the * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or * Alternate wavetable (from mobile DLS or other DLS file) * * This function figures out what wavetable should be used, and sets it up as the * wavetable to use for this channel. Also the channel may switch from a melodic * channel to a rhythm channel, or vice versa. * * Inputs: * * Outputs: * Side Effects: * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed * *---------------------------------------------------------------------------- */ void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program); /*---------------------------------------------------------------------------- * VMChannelPressure() *---------------------------------------------------------------------------- * Purpose: * Change the channel pressure for the given channel * * Inputs: * nChannel - the MIDI channel * nVelocity - the channel pressure value * psEASData - pointer to overall EAS data structure * * Outputs: * Side Effects: * gsSynthObject.m_sChannel[nChannel].m_nChannelPressure is updated *---------------------------------------------------------------------------- */ void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value); /*---------------------------------------------------------------------------- * VMPitchBend() *---------------------------------------------------------------------------- * Purpose: * Change the pitch wheel value for the given channel. * This routine constructs the proper 14-bit argument when the calling routine * passes the pitch LSB and MSB. * * Note: some midi disassemblers display a bipolar pitch bend value. * We can display the bipolar value using * if m_nPitchBend >= 0x2000 * bipolar pitch bend = postive (m_nPitchBend - 0x2000) * else * bipolar pitch bend = negative (0x2000 - m_nPitchBend) * * Inputs: * nChannel - the MIDI channel * nPitchLSB - the LSB byte from the pitch bend message * nPitchMSB - the MSB byte from the message * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * gsSynthObject.m_sChannel[nChannel].m_nPitchBend is changed * *---------------------------------------------------------------------------- */ void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 pitchLSB, EAS_U8 pitchMSB); /*---------------------------------------------------------------------------- * VMControlChange() *---------------------------------------------------------------------------- * Purpose: * Change the controller (or mode) for the given channel. * * Inputs: * nChannel - the MIDI channel * nControllerNumber - the controller number * nControlValue - the controller number for this control change * nControlValue - the value for this control change * psEASData - pointer to overall EAS data structure * * Outputs: * Side Effects: * gsSynthObject.m_sChannel[nChannel] controller is changed * *---------------------------------------------------------------------------- */ void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value); /*---------------------------------------------------------------------------- * VMUpdateRPNStateMachine() *---------------------------------------------------------------------------- * Purpose: * Call this function when we want to parse a stream of RPN messages. * NOTE: The synth has only one set of global RPN data instead of RPN data * per channel. * So actually, we don't really need to look at the nChannel parameter, * but we pass it to facilitate future upgrades. Furthermore, we only * support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and * RPN2 (coarse tuning). Any other RPNs are rejected. * * Inputs: * nChannel - the MIDI channel * nControllerNumber - the RPN controller number * nControlValue - the value for this control change * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * gsSynthObject.m_RPN0 (or m_RPN1 or m_RPN2) may be updated if the * proper RPN message sequence is parsed. *---------------------------------------------------------------------------- */ EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value); /*---------------------------------------------------------------------------- * VMUpdateStaticChannelParameters() *---------------------------------------------------------------------------- * Purpose: * Update all of the static channel parameters for channels that have had * a controller change values * Or if the synth has signalled that all channels must forcibly * be updated * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * none * * Side Effects: * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch * are updated for channels whose controller values have changed * or if the synth has signalled that all channels must forcibly * be updated *---------------------------------------------------------------------------- */ void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMReleaseAllDeferredNoteOffs() *---------------------------------------------------------------------------- * Purpose: * Call this functin when the sustain flag is presently set but * we are now transitioning from damper pedal on to * damper pedal off. This means all notes in this channel * that received a note off while the damper pedal was on, and * had their note-off requests deferred, should now proceed to * the release state. * * Inputs: * nChannel - this channel has its sustain pedal transitioning from on to off * psEASData - pointer to overall EAS data structure * * Outputs: * Side Effects: * any voice with deferred note offs on this channel are updated such that * * *---------------------------------------------------------------------------- */ void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel); /*---------------------------------------------------------------------------- * VMCatchNotesForSustainPedal() *---------------------------------------------------------------------------- * Purpose: * Call this function when the sustain flag is presently clear and * the damper pedal is off and we are transitioning from damper pedal OFF to * damper pedal ON. Currently sounding notes should be left * unchanged. However, we should try to "catch" notes if possible. * If any notes have levels >= sustain level, catch them, * otherwise, let them continue to release. * * Inputs: * nChannel - this channel has its sustain pedal transitioning from on to off * psEASData - pointer to overall EAS data structure * * Outputs: * Side Effects: * any voice with deferred note offs on this channel are updated such that * psVoice->m_sEG1.m_eState = eEnvelopeStateSustainPedal *---------------------------------------------------------------------------- */ void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel); /*---------------------------------------------------------------------------- * VMUpdateAllNotesAge() *---------------------------------------------------------------------------- * Purpose: * Increment the note age for all voices older than the age of the voice * that is stopping, effectively making the voices "younger". * * Inputs: * nAge - age of voice that is going away * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * m_nAge for some voices is incremented *---------------------------------------------------------------------------- */ void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 nAge); /*---------------------------------------------------------------------------- * VMFindRegionIndex() *---------------------------------------------------------------------------- * Purpose: * Find the region index for the given instrument using the midi key number * and the RPN2 (coarse tuning) value. By using RPN2 as part of the * region selection process, we reduce the amount a given sample has * to be transposed by selecting the closest recorded root instead. * * Inputs: * nChannel - current channel for this note * nKeyNumber - current midi note number * psEASData - pointer to overall EAS data structure * * Outputs: * pnRegionIndex - valid only if we returned success * success if we found the region index number, otherwise * failure * * Side Effects: *---------------------------------------------------------------------------- */ EAS_RESULT VMFindRegionIndex (S_VOICE_MGR *pVoiceMgr, EAS_U8 channel, EAS_U8 note, EAS_U16 *pRegionIndex); /*---------------------------------------------------------------------------- * VMIncRefCount() *---------------------------------------------------------------------------- * Increment reference count for virtual synth *---------------------------------------------------------------------------- */ void VMIncRefCount (S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMReset() *---------------------------------------------------------------------------- * Purpose: * We call this routine to start the process of reseting the synth. * This routine sets a flag for the entire synth indicating that we want * to reset. * We also force all voices to mute quickly. * However, we do not actually perform any synthesis in this routine. That * is, we do not ramp the voices down from this routine, but instead, we * let the "regular" synth processing steps take care of adding the ramp * down samples to the output buffer. After we are sure that all voices * have completed ramping down, we continue the process of resetting the * synth (from another routine). * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - set a flag (in gsSynthObject.m_nFlags) indicating synth reset requested. * - force all voices to update their envelope states to mute * *---------------------------------------------------------------------------- */ void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force); /*---------------------------------------------------------------------------- * VMMuteAllVoices() *---------------------------------------------------------------------------- * Purpose: * We call this in an emergency reset situation. * This forces all voices to mute quickly. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - forces all voices to update their envelope states to mute * *---------------------------------------------------------------------------- */ void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum); void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMReleaseAllVoices() *---------------------------------------------------------------------------- * Purpose: * We call this after we've encountered the end of the Midi file. * This ensures all voice are either in release (because we received their * note off already) or forces them to mute quickly. * We use this as a safety to prevent bad midi files from playing forever. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - forces all voices to update their envelope states to release or mute * *---------------------------------------------------------------------------- */ void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMAllNotesOff() *---------------------------------------------------------------------------- * Purpose: * Quickly mute all notes on the given channel. * * Inputs: * nChannel - quickly turn off all notes on this channel * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - forces all voices on this channel to update their envelope states to mute * *---------------------------------------------------------------------------- */ void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel); /*---------------------------------------------------------------------------- * VMDeferredStopNote() *---------------------------------------------------------------------------- * Purpose: * Stop the notes that had deferred note-off requests. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * None. * * Side Effects: * voices that have had deferred note-off requests are now put into release * gsSynthObject.m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF * cleared *---------------------------------------------------------------------------- */ void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMSetSynthPolyphony() *---------------------------------------------------------------------------- * Purpose: * Set the synth to a new polyphony value. Value must be >= 1 and * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits * * Inputs: * pVoiceMgr pointer to synthesizer data * synth synthesizer number (0 = onboard, 1 = DSP) * polyphonyCount desired polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount); /*---------------------------------------------------------------------------- * VMGetSynthPolyphony() *---------------------------------------------------------------------------- * Purpose: * Set the synth to a new polyphony value. Value must be >= 1 and * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits * * Inputs: * pVoiceMgr pointer to synthesizer data * synth synthesizer number (0 = onboard, 1 = DSP) * polyphonyCount desired polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount); /*---------------------------------------------------------------------------- * VMSetPolyphony() *---------------------------------------------------------------------------- * Purpose: * Set the virtual synth polyphony. 0 = no limit (i.e. can use * all available voices). * * Inputs: * pVoiceMgr pointer to synthesizer data * polyphonyCount desired polyphony count * pSynth pointer to virtual synth * * Outputs: * Returns error code * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount); /*---------------------------------------------------------------------------- * VMGetPolyphony() *---------------------------------------------------------------------------- * Purpose: * Returns the current polyphony setting * * Inputs: * pVoiceMgr pointer to synthesizer data * pSynth pointer to virtual synth * pPolyphonyCount pointer to variable to receive data * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount); /*---------------------------------------------------------------------------- * VMSetPriority() *---------------------------------------------------------------------------- * Purpose: * Set the virtual synth priority * * Inputs: * pVoiceMgr pointer to synthesizer data * priority new priority * pSynth pointer to virtual synth * * Outputs: * Returns error code * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority); /*---------------------------------------------------------------------------- * VMGetPriority() *---------------------------------------------------------------------------- * Purpose: * Get the virtual synth priority * * Inputs: * pVoiceMgr pointer to synthesizer data * pPriority pointer to variable to hold priority * pSynth pointer to virtual synth * * Outputs: * Returns error code * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority); /*---------------------------------------------------------------------------- * VMSetVolume() *---------------------------------------------------------------------------- * Purpose: * Set the master volume for this sequence * * Inputs: * nSynthVolume - the desired master volume * psEASData - pointer to overall EAS data structure * * Outputs: * * * Side Effects: * overrides any previously set master volume from sysex * *---------------------------------------------------------------------------- */ void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume); /*---------------------------------------------------------------------------- * VMSetPitchBendRange() *---------------------------------------------------------------------------- * Set the pitch bend range for the given channel. *---------------------------------------------------------------------------- */ void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange); /*---------------------------------------------------------------------------- * VMSetEASLib() *---------------------------------------------------------------------------- * Purpose: * Sets the pointer to the sound library * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS); EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS); #ifdef DLS_SYNTHESIZER /*---------------------------------------------------------------------------- * VMSetDLSLib() *---------------------------------------------------------------------------- * Purpose: * Sets the pointer to the sound library * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS); EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS); #endif /*---------------------------------------------------------------------------- * VMSetTranposition() *---------------------------------------------------------------------------- * Purpose: * Sets the global key transposition used by the synthesizer. * Transposes all melodic instruments up or down by the specified * amount. Range is limited to +/-12 semitones. * * Inputs: * psEASData - pointer to overall EAS data structure * transposition - transpose amount (+/-12) * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition); /*---------------------------------------------------------------------------- * VMGetTranposition() *---------------------------------------------------------------------------- * Purpose: * Gets the global key transposition used by the synthesizer. * Transposes all melodic instruments up or down by the specified * amount. Range is limited to +/-12 semitones. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition); /*---------------------------------------------------------------------------- * VMGetNoteCount() *---------------------------------------------------------------------------- * Returns the total note count *---------------------------------------------------------------------------- */ EAS_I32 VMGetNoteCount (S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMRender() *---------------------------------------------------------------------------- * Purpose: * This routine renders a frame of audio * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * pVoicesRendered - number of voices rendered this frame * * Side Effects: * sets psMidiObject->m_nMaxWorkloadPerFrame * *---------------------------------------------------------------------------- */ EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered); /*---------------------------------------------------------------------------- * VMInitWorkload() *---------------------------------------------------------------------------- * Purpose: * Clears the workload counter * * Inputs: * pVoiceMgr - pointer to instance data * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ void VMInitWorkload (S_VOICE_MGR *pVoiceMgr); /*---------------------------------------------------------------------------- * VMSetWorkload() *---------------------------------------------------------------------------- * Purpose: * Sets the max workload for a single frame. * * Inputs: * pVoiceMgr - pointer to instance data * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad); /*---------------------------------------------------------------------------- * VMCheckWorkload() *---------------------------------------------------------------------------- * Purpose: * Checks to see if work load has been exceeded on this frame. * * Inputs: * pVoiceMgr - pointer to instance data * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr); /*---------------------------------------------------------------------------- * VMActiveVoices() *---------------------------------------------------------------------------- * Purpose: * Returns the number of active voices in the synthesizer. * * Inputs: * pEASData - pointer to instance data * * Outputs: * Returns the number of active voices * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_I32 VMActiveVoices (S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMMIDIShutdown() *---------------------------------------------------------------------------- * Purpose: * Clean up any Synth related system issues. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * None * * Side Effects: * *---------------------------------------------------------------------------- */ void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth); /*---------------------------------------------------------------------------- * VMShutdown() *---------------------------------------------------------------------------- * Purpose: * Clean up any Synth related system issues. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * None * * Side Effects: * *---------------------------------------------------------------------------- */ void VMShutdown (S_EAS_DATA *pEASData); #ifdef EXTERNAL_AUDIO /*---------------------------------------------------------------------------- * EAS_RegExtAudioCallback() *---------------------------------------------------------------------------- * Register a callback for external audio processing *---------------------------------------------------------------------------- */ void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc); /*---------------------------------------------------------------------------- * VMGetMIDIControllers() *---------------------------------------------------------------------------- * Returns the MIDI controller values on the specified channel *---------------------------------------------------------------------------- */ void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl); #endif #ifdef _SPLIT_ARCHITECTURE /*---------------------------------------------------------------------------- * VMStartFrame() *---------------------------------------------------------------------------- * Purpose: * Starts an audio frame * * Inputs: * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData); /*---------------------------------------------------------------------------- * VMEndFrame() *---------------------------------------------------------------------------- * Purpose: * Stops an audio frame * * Inputs: * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData); #endif #endif /* #ifdef _EAS_VM_PROTOS_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_rtttldata.c0000644000000000000000000000013214200302440027100 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.189324413 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_rtttldata.c0000644000175000001440000000253114200302440027662 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_rtttldata.c * * Contents and purpose: * RTTTL File Parser data module for static memory models * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 547 $ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $ *---------------------------------------------------------------------------- */ #include "eas_types.h" #include "eas_rtttldata.h" /*---------------------------------------------------------------------------- * * eas_RTTTLData * * Static memory allocation for RTTTL parser *---------------------------------------------------------------------------- */ S_RTTTL_DATA eas_RTTTLData; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_wavefile.h0000644000000000000000000000013214200302440026704 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.189324413 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_wavefile.h0000644000175000001440000000353014200302440027466 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_wavefile.h * * Contents and purpose: * Static data block for wave file parser. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 439 $ * $Date: 2006-10-26 11:53:18 -0700 (Thu, 26 Oct 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_WAVEFILE_H #define _EAS_WAVEFILE_H #include "eas_data.h" #include "eas_pcm.h" /*---------------------------------------------------------------------------- * * S_WAVE_STATE * * This structure contains the WAVE file parser state information *---------------------------------------------------------------------------- */ typedef struct s_wave_state_tag { EAS_FILE_HANDLE fileHandle; EAS_PCM_HANDLE streamHandle; S_METADATA_CB metadata; EAS_U32 time; EAS_I32 fileOffset; EAS_I32 audioOffset; EAS_I32 mediaLength; EAS_U32 audioSize; EAS_U32 flags; EAS_I16 fileType; #ifdef MMAPI_SUPPORT EAS_VOID_PTR fmtChunk; #endif EAS_I32 infoChunkPos; EAS_I32 infoChunkSize; } S_WAVE_STATE; #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_xmf.h0000644000000000000000000000013214200302440025674 xustar0030 mtime=1644266784.809324171 30 atime=1644266785.189324413 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_xmf.h0000644000175000001440000000336114200302440026460 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_xmf.h * * Contents and purpose: * XMF Type 0 and 1 File Parser * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_XMF_H #define _EAS_XMF_H #ifndef MAX_XMF_STREAMS #define MAX_XMF_STREAMS 16 #endif /* offsets in to the XMF file */ #define XMF_OFS_HEADER_SIZE 4 #define XMF_OFS_FILE_TYPE 8 #define XMF_OFS_NUM_TRACKS 10 /* size of chunk info (chunk ID + chunk size) */ #define XMF_CHUNK_INFO_SIZE 8 /* 'MTrk' track chunk ID */ #define XMF_CHUNK_TYPE_TRACK 0x4d54726bL /* some useful meta-events */ #define XMF_META_END_OF_TRACK 0x2f #define XMF_META_TEMPO 0x51 /* default timebase (120BPM) */ #define XMF_DEFAULT_TIMEBASE 500000L /* value for pXMFStream->ticks to signify end of track */ #define XMF_END_OF_TRACK 0xffffffff #endif /* end _EAS_XMF_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_synthcfg.h0000644000000000000000000000013214200302440026727 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.189324413 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_synthcfg.h0000644000175000001440000000351514200302440027514 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_synthcfg.h * * Contents and purpose: * Defines for various synth configurations * * Copyright Sonic Network Inc. 2004, 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 664 $ * $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_SYNTHCFG_H #define _EAS_SYNTHCFG_H #if defined(EAS_WT_SYNTH) #define _WT_SYNTH /* FM on MCU */ #elif defined(EAS_FM_SYNTH) #define _FM_SYNTH /* wavetable drums and FM melodic on MCU */ #elif defined(EAS_HYBRID_SYNTH) #define _WT_SYNTH #define _FM_SYNTH #define _SECONDARY_SYNTH #define _HYBRID_SYNTH /* wavetable drums on MCU, wavetable melodic on DSP */ #elif defined(EAS_SPLIT_WT_SYNTH) #define _WT_SYNTH #define _SPLIT_ARCHITECTURE /* wavetable drums on MCU, FM melodic on DSP */ #elif defined(EAS_SPLIT_HYBRID_SYNTH) #define _WT_SYNTH #define _FM_SYNTH #define _SECONDARY_SYNTH #define _SPLIT_ARCHITECTURE #define _HYBRID_SYNTH /* FM synth on DSP */ #elif defined(EAS_SPLIT_FM_SYNTH) #define _FM_SYNTH #define _SPLIT_ARCHITECTURE #else #error "Unrecognized architecture option" #endif #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_mixbuf.c0000644000000000000000000000013214200302440026367 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.189324413 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_mixbuf.c0000644000175000001440000000224414200302440027152 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_mixbuf.c * * Contents and purpose: * Contains a data allocation for synthesizer * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ // includes #include "eas_data.h" #include "eas_mixer.h" // globals EAS_I32 eas_MixBuffer[BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS]; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_wtsynth.h0000644000000000000000000000013214200302440026622 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.189324413 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_wtsynth.h0000644000175000001440000000417114200302440027406 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_wtsynth.h * * Contents and purpose: * This file defines the interface for synthesizer engine * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_WTSYNTH_H #define _EAS_WTSYNTH_H #include "eas_sndlib.h" #include "eas_wtengine.h" /* adjust the filter cutoff frequency to the sample rate */ #if defined (_SAMPLE_RATE_8000) #define FILTER_CUTOFF_FREQ_ADJUST 0 #elif defined (_SAMPLE_RATE_16000) #define FILTER_CUTOFF_FREQ_ADJUST 1200 #elif defined (_SAMPLE_RATE_20000) #define FILTER_CUTOFF_FREQ_ADJUST 1586 #elif defined (_SAMPLE_RATE_22050) #define FILTER_CUTOFF_FREQ_ADJUST 1756 #elif defined (_SAMPLE_RATE_24000) #define FILTER_CUTOFF_FREQ_ADJUST 1902 #elif defined (_SAMPLE_RATE_32000) #define FILTER_CUTOFF_FREQ_ADJUST 2400 #elif defined (_SAMPLE_RATE_44100) #define FILTER_CUTOFF_FREQ_ADJUST 2956 #elif defined (_SAMPLE_RATE_48000) #define FILTER_CUTOFF_FREQ_ADJUST 3102 #else #error "_SAMPLE_RATE_XXXXX must be defined to valid rate" #endif /* function prototypes */ void WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc); #if defined(_FILTER_ENABLED) || defined(DLS_SYNTHESIZER) void WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance); #endif #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_data.c0000644000000000000000000000013214200302440026006 xustar0030 mtime=1644266784.809324171 30 atime=1644266785.189324413 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_data.c0000644000175000001440000000220014200302440026561 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_data.c * * Contents and purpose: * Contains a data allocation for synthesizer * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 547 $ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $ *---------------------------------------------------------------------------- */ // includes #include "eas_data.h" // globals S_EAS_DATA eas_Data; S_VOICE_MGR eas_Synth; S_SYNTH eas_MIDI; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_rtttl.c0000644000000000000000000000013214200302440026246 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.189324413 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_rtttl.c0000644000175000001440000010262514200302440027035 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_rtttl.c * * Contents and purpose: * RTTTL parser * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 795 $ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $ *---------------------------------------------------------------------------- */ #include "eas_data.h" #include "eas_miditypes.h" #include "eas_parser.h" #include "eas_report.h" #include "eas_host.h" #include "eas_midi.h" #include "eas_config.h" #include "eas_vm_protos.h" #include "eas_rtttldata.h" #include "eas_ctype.h" /* increase gain for mono ringtones */ #define RTTTL_GAIN_OFFSET 8 /* maximum title length including colon separator */ #define RTTTL_MAX_TITLE_LEN 32 #define RTTTL_INFINITE_LOOP 15 /* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */ #define DEFAULT_TICK_CONV 30476 #define TICK_CONVERT 1920000 /* default channel and program for RTTTL playback */ #define RTTTL_CHANNEL 0 #define RTTTL_PROGRAM 80 #define RTTTL_VELOCITY 127 /* note used for rest */ #define RTTTL_REST 1 /* multiplier for fixed point triplet conversion */ #define TRIPLET_MULTIPLIER 683 #define TRIPLET_SHIFT 10 /* local prototypes */ static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset); static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime); static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode); static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState); static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData); static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration); static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave); static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData); static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue); static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData); static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue); static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue); /* inline functions */ EAS_INLINE void RTTTL_PutBackChar (S_RTTTL_DATA *pData, EAS_I8 value) { pData->dataByte = value; } /* lookup table for note values */ static const EAS_U8 noteTable[] = { 21, 23, 12, 14, 16, 17, 19, 23 }; /*---------------------------------------------------------------------------- * * EAS_RTTTL_Parser * * This structure contains the functional interface for the iMelody parser *---------------------------------------------------------------------------- */ const S_FILE_PARSER_INTERFACE EAS_RTTTL_Parser = { RTTTL_CheckFileType, RTTTL_Prepare, RTTTL_Time, RTTTL_Event, RTTTL_State, RTTTL_Close, RTTTL_Reset, RTTTL_Pause, RTTTL_Resume, NULL, RTTTL_SetData, RTTTL_GetData, NULL }; /*---------------------------------------------------------------------------- * RTTTL_CheckFileType() *---------------------------------------------------------------------------- * Purpose: * Check the file type to see if we can parse it * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset) { S_RTTTL_DATA data; S_RTTTL_DATA *pData; /* see if we can parse the header */ data.fileHandle = fileHandle; data.fileOffset = offset; *ppHandle= NULL; if (RTTTL_ParseHeader (pEASData, &data, EAS_FALSE) == EAS_SUCCESS) { /* check for static memory allocation */ if (pEASData->staticMemoryModel) pData = EAS_CMEnumData(EAS_CM_RTTTL_DATA); else pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_RTTTL_DATA)); if (!pData) return EAS_ERROR_MALLOC_FAILED; EAS_HWMemSet(pData, 0, sizeof(S_RTTTL_DATA)); /* return a pointer to the instance data */ pData->fileHandle = fileHandle; pData->fileOffset = offset; pData->state = EAS_STATE_OPEN; *ppHandle = pData; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_Prepare() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. Allocates instance data (or uses static allocation for * static memory model). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_RTTTL_DATA* pData; EAS_RESULT result; /* check for valid state */ pData = (S_RTTTL_DATA*) pInstData; if (pData->state != EAS_STATE_OPEN) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* instantiate a synthesizer */ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ } return result; } pData->state = EAS_STATE_ERROR; if ((result = RTTTL_ParseHeader (pEASData, pData, (EAS_BOOL) (pData->metadata.callback != NULL))) != EAS_SUCCESS) { /* if using dynamic memory, free it */ if (!pEASData->staticMemoryModel) EAS_HWFree(pEASData->hwInstData, pData); return result; } pData->state = EAS_STATE_READY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_Time() *---------------------------------------------------------------------------- * Purpose: * Returns the time of the next event in msecs * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pTime - pointer to variable to hold time of next event (in msecs) * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ static EAS_RESULT RTTTL_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime) { S_RTTTL_DATA *pData; pData = (S_RTTTL_DATA*) pInstData; /* return time in milliseconds */ /*lint -e{704} use shift instead of division */ *pTime = pData->time >> 8; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_Event() *---------------------------------------------------------------------------- * Purpose: * Parse the next event in the file * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode) { S_RTTTL_DATA* pData; EAS_RESULT result; EAS_I32 ticks; EAS_I32 temp; EAS_I8 c; EAS_U8 note; EAS_U8 octave; pData = (S_RTTTL_DATA*) pInstData; if (pData->state >= EAS_STATE_OPEN) return EAS_SUCCESS; /* initialize MIDI channel when the track starts playing */ if (pData->time == 0) { /* set program to square lead */ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, RTTTL_PROGRAM); /* set channel volume to max */ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, 7, 127); } /* check for end of note */ if (pData->note) { /* stop the note */ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, 0); pData->note = 0; /* check for rest between notes */ if (pData->restTicks) { pData->time += pData->restTicks; pData->restTicks = 0; return EAS_SUCCESS; } } /* parse the next event */ octave = pData->octave; note = 0; ticks = pData->duration * pData->tick; for (;;) { /* get next character */ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS) { if (result != EAS_EOF) return result; /* end of file, if no notes to process, check for looping */ if (!note) { /* if no loop set state to stopping */ if (pData->repeatCount == 0) { pData->state = EAS_STATE_STOPPING; VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth); return EAS_SUCCESS; } /* decrement loop count */ if (pData->repeatCount != RTTTL_INFINITE_LOOP) pData->repeatCount--; /* if locating, ignore infinite loops */ else if (parserMode != eParserModePlay) { pData->state = EAS_STATE_STOPPING; VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth); return EAS_SUCCESS; } /* loop back to start of notes */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS) return result; continue; } /* still have a note to process */ else c = ','; } /* bpm */ if (c == 'b') { /* peek at next character */ if ((result = RTTTL_PeekNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS) return result; /* if a number, must be octave or tempo */ if (IsDigit(c)) { if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS) return result; /* check for octave first */ if ((temp >= 4) && (temp <= 7)) { octave = (EAS_U8) temp; } /* check for tempo */ else if ((temp >= 25) && (temp <= 900)) { pData->tick = TICK_CONVERT / (EAS_U32) temp; } /* don't know what it was */ else return EAS_ERROR_FILE_FORMAT; } /* must be a note */ else { note = noteTable[1]; } } /* octave */ else if (c == 'o') { if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS) return result; } /* style */ else if (c == 's') { if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS) return result; } /* duration or octave */ else if (IsDigit(c)) { RTTTL_PutBackChar(pData, c); /* duration comes before note */ if (!note) { if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS) return result; ticks = c * pData->tick; } /* octave comes after note */ else { if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &octave)) != EAS_SUCCESS) return result; } } /* note or rest */ else if ((c >= 'a') && (c <= 'h')) { note = noteTable[c - 'a']; } else if (c == 'p') { note = RTTTL_REST; } /* dotted note */ else if (c == '.') { /*lint -e{704} shift for performance */ ticks += ticks >> 1; } /* accidental */ else if (c == '#') { if (note) note++; } /* end of event */ else if ((c == ',') && note) { /* handle note events */ if (note != RTTTL_REST) { /* save note and start it */ pData->note = note + octave; if (parserMode == eParserModePlay) VMStartNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, RTTTL_VELOCITY); /* determine note length */ switch (pData->style) { /* natural */ case 'n': /*lint -e{704} shift for performance */ pData->restTicks = ticks >> 4; break; /* continuous */ case 'c': pData->restTicks = 0; break; /* staccato */ case 's': /*lint -e{704} shift for performance */ pData->restTicks = ticks >> 1; break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "RTTTL_Event: Unexpected style type %c\n", pData->style); */ } break; } /* next event is at end of this note */ pData->time += ticks - pData->restTicks; } /* rest */ else pData->time += ticks; /* event found, return to caller */ break; } } pData->state = EAS_STATE_PLAY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_State() *---------------------------------------------------------------------------- * Purpose: * Returns the current state of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pState - pointer to variable to store state * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ static EAS_RESULT RTTTL_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState) { S_RTTTL_DATA* pData; /* establish pointer to instance data */ pData = (S_RTTTL_DATA*) pInstData; /* if stopping, check to see if synth voices are active */ if (pData->state == EAS_STATE_STOPPING) { if (VMActiveVoices(pData->pSynth) == 0) pData->state = EAS_STATE_STOPPED; } if (pData->state == EAS_STATE_PAUSING) { if (VMActiveVoices(pData->pSynth) == 0) pData->state = EAS_STATE_PAUSED; } /* return current state */ *pState = pData->state; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_Close() *---------------------------------------------------------------------------- * Purpose: * Close the file and clean up * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_RTTTL_DATA* pData; EAS_RESULT result; pData = (S_RTTTL_DATA*) pInstData; /* close the file */ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS) return result; /* free the synth */ if (pData->pSynth != NULL) VMMIDIShutdown(pEASData, pData->pSynth); /* if using dynamic memory, free it */ if (!pEASData->staticMemoryModel) EAS_HWFree(pEASData->hwInstData, pData); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_Reset() *---------------------------------------------------------------------------- * Purpose: * Reset the sequencer. Used for locating backwards in the file. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_RTTTL_DATA* pData; EAS_RESULT result; pData = (S_RTTTL_DATA*) pInstData; /* reset the synth */ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE); /* reset time to zero */ pData->time = 0; pData->note = 0; /* reset file position and re-parse header */ pData->state = EAS_STATE_ERROR; if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS) return result; if ((result = RTTTL_ParseHeader (pEASData, pData, EAS_TRUE)) != EAS_SUCCESS) return result; pData->state = EAS_STATE_READY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_Pause() *---------------------------------------------------------------------------- * Purpose: * Pauses the sequencer. Mutes all voices and sets state to pause. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_RTTTL_DATA *pData; /* can't pause a stopped stream */ pData = (S_RTTTL_DATA*) pInstData; if (pData->state == EAS_STATE_STOPPED) return EAS_ERROR_ALREADY_STOPPED; /* mute the synthesizer */ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth); pData->state = EAS_STATE_PAUSING; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_Resume() *---------------------------------------------------------------------------- * Purpose: * Resume playing after a pause, sets state back to playing. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ static EAS_RESULT RTTTL_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_RTTTL_DATA *pData; /* can't resume a stopped stream */ pData = (S_RTTTL_DATA*) pInstData; if (pData->state == EAS_STATE_STOPPED) return EAS_ERROR_ALREADY_STOPPED; /* nothing to do but resume playback */ pData->state = EAS_STATE_PLAY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_SetData() *---------------------------------------------------------------------------- * Purpose: * Return file type * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ static EAS_RESULT RTTTL_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value) { S_RTTTL_DATA *pData; pData = (S_RTTTL_DATA *) pInstData; switch (param) { /* set metadata callback */ case PARSER_DATA_METADATA_CB: EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB)); break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_GetData() *---------------------------------------------------------------------------- * Purpose: * Return file type * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ static EAS_RESULT RTTTL_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue) { S_RTTTL_DATA *pData; pData = (S_RTTTL_DATA *) pInstData; switch (param) { /* return file type as RTTTL */ case PARSER_DATA_FILE_TYPE: *pValue = EAS_FILE_RTTTL; break; #if 0 /* set transposition */ case PARSER_DATA_TRANSPOSITION: *pValue = pData->transposition; break; #endif case PARSER_DATA_SYNTH_HANDLE: *pValue = (EAS_I32) pData->pSynth; break; case PARSER_DATA_GAIN_OFFSET: *pValue = RTTTL_GAIN_OFFSET; break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_GetStyle() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_GetStyle (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData) { EAS_RESULT result; EAS_I8 style; /* get style */ if ((result = RTTTL_GetNextChar(hwInstData, pData, &style)) != EAS_SUCCESS) return result; if ((style != 's') && (style != 'n') && (style != 'c')) return EAS_ERROR_FILE_FORMAT; pData->style = style; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_GetDuration() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pDuration) { EAS_RESULT result; EAS_I32 duration; EAS_I8 temp; /* get the duration */ if ((result = RTTTL_GetNumber(hwInstData, pData, &duration)) != EAS_SUCCESS) return result; if ((duration != 1) && (duration != 2) && (duration != 4) && (duration != 8) && (duration != 16) && (duration != 32)) return EAS_ERROR_FILE_FORMAT; temp = 64; while (duration) { /*lint -e{704} shift for performance */ duration = duration >> 1; /*lint -e{702} use shift for performance */ temp = temp >> 1; } *pDuration = temp; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_GetOctave() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_GetOctave (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_U8 *pOctave) { EAS_RESULT result; EAS_I32 octave; /* get the tempo */ if ((result = RTTTL_GetNumber(hwInstData, pData, &octave)) != EAS_SUCCESS) return result; if ((octave < 4) || (octave > 7)) return EAS_ERROR_FILE_FORMAT; *pOctave = (EAS_U8) (octave * 12); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_GetTempo() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_GetTempo (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData) { EAS_RESULT result; EAS_I32 tempo; /* get the tempo */ if ((result = RTTTL_GetNumber(hwInstData, pData, &tempo)) != EAS_SUCCESS) return result; if ((tempo < 25) || (tempo > 900)) return EAS_ERROR_FILE_FORMAT; pData->tick = TICK_CONVERT / (EAS_U32) tempo; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_GetNumber() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I32 *pValue) { EAS_RESULT result; EAS_INT temp; EAS_I8 c; *pValue = -1; temp = 0; for (;;) { if ((result = RTTTL_PeekNextChar(hwInstData, pData, &c)) != EAS_SUCCESS) { if ((result == EAS_EOF) && (*pValue != -1)) return EAS_SUCCESS; return result; } if (IsDigit(c)) { pData->dataByte = 0; temp = temp * 10 + c - '0'; *pValue = temp; } else return EAS_SUCCESS; } } /*---------------------------------------------------------------------------- * RTTTL_ParseHeader() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. Allocates instance data (or uses static allocation for * static memory model). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_ParseHeader (S_EAS_DATA *pEASData, S_RTTTL_DATA* pData, EAS_BOOL metaData) { EAS_RESULT result; EAS_I32 i; EAS_I8 temp; EAS_I8 control; /* initialize some defaults */ pData->time = 0; pData->tick = DEFAULT_TICK_CONV; pData->note = 0; pData->duration = 4; pData ->restTicks = 0; pData->octave = 60; pData->repeatOffset = -1; pData->repeatCount = 0; pData->style = 'n'; pData->dataByte = 0; metaData = metaData && (pData->metadata.buffer != NULL) && (pData->metadata.callback != NULL); /* seek to start of data */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS) return result; /* zero the metadata buffer */ if (metaData) EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize); /* read the title */ for (i = 0; i < RTTTL_MAX_TITLE_LEN; i++) { if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS) return result; if (temp == ':') break; /* pass along metadata */ if (metaData) { if (i < (pData->metadata.bufferSize- 1)) pData->metadata.buffer[i] = (char) temp; } } /* check for error in title */ if (i == RTTTL_MAX_TITLE_LEN) return EAS_ERROR_FILE_FORMAT; /* pass along metadata */ if (metaData) (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData); /* control fields */ for (;;) { /* get control type */ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &control)) != EAS_SUCCESS) return result; /* next char should be equal sign */ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS) return result; if (temp != '=') return EAS_ERROR_FILE_FORMAT; /* get the control value */ switch (control) { /* bpm */ case 'b': if ((result = RTTTL_GetTempo(pEASData->hwInstData, pData)) != EAS_SUCCESS) return result; break; /* duration */ case 'd': if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS) return result; pData->duration = temp; break; /* loop */ case 'l': if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &i)) != EAS_SUCCESS) return result; if ((i < 0) || (i > 15)) return EAS_ERROR_FILE_FORMAT; pData->repeatCount = (EAS_U8) i; break; /* octave */ case 'o': if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS) return result; break; /* get style */ case 's': if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS) return result; break; /* unrecognized control */ default: return EAS_ERROR_FILE_FORMAT; } /* next character should be comma or colon */ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS) return result; /* check for end of control field */ if (temp == ':') break; /* must be a comma */ if (temp != ',') return EAS_ERROR_FILE_FORMAT; } /* should be at the start of the music block */ if ((result = EAS_HWFilePos(pEASData->hwInstData, pData->fileHandle, &pData->repeatOffset)) != EAS_SUCCESS) return result; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * RTTTL_GetNextChar() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue) { EAS_RESULT result; EAS_I8 temp; *pValue = 0; for(;;) { /* check for character that has been put back */ if (pData->dataByte) { temp = pData->dataByte; pData->dataByte = 0; } else { if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS) return result; } /* ignore white space */ if (!IsSpace(temp)) { *pValue = ToLower(temp); return EAS_SUCCESS; } } } /*---------------------------------------------------------------------------- * RTTTL_PeekNextChar() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_PeekNextChar (EAS_HW_DATA_HANDLE hwInstData, S_RTTTL_DATA *pData, EAS_I8 *pValue) { EAS_RESULT result; EAS_I8 temp; *pValue = 0; for(;;) { /* read a character from the file, if necessary */ if (!pData->dataByte) { if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->dataByte)) != EAS_SUCCESS) return result; } temp = pData->dataByte; /* ignore white space */ if (!IsSpace(temp)) { *pValue = ToLower(temp); return EAS_SUCCESS; } pData->dataByte = 0; } } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_rtttldata.h0000644000000000000000000000013214200302440027105 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.189324413 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_rtttldata.h0000644000175000001440000000515214200302440027671 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_rtttldata.h * * Contents and purpose: * SMF File Parser * * This file contains data declarations for the RTTTL parser. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef EAS_RTTTLDATA_H #define EAS_RTTTLDATA_H #include "eas_data.h" /* maximum line size as specified in iMelody V1.2 spec */ #define MAX_LINE_SIZE 75 /*---------------------------------------------------------------------------- * * S_RTTTL_DATA * * This structure contains the state data for the iMelody parser *---------------------------------------------------------------------------- */ typedef struct { EAS_FILE_HANDLE fileHandle; /* file handle */ S_SYNTH *pSynth; /* synthesizer handle */ S_METADATA_CB metadata; /* metadata callback */ EAS_I32 fileOffset; /* offset to start of data */ EAS_I32 time; /* current time in 256ths of a msec */ EAS_I32 tick; /* length of 32nd note in 256th of a msec */ EAS_I32 restTicks; /* ticks to rest after current note */ EAS_I32 repeatOffset; /* file offset to start of repeat section */ EAS_U8 repeatCount; /* repeat counter */ EAS_I8 dataByte; /* storage for characters that are "put back" */ EAS_U8 state; /* current state EAS_STATE_XXXX */ EAS_I8 style; /* from STYLE */ EAS_U8 note; /* MIDI note number */ EAS_U8 octave; /* decault octave prefix */ EAS_I8 duration; /* default note duration */ } S_RTTTL_DATA; #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_midictrl.h0000644000000000000000000000013214200302440026711 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.189324413 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_midictrl.h0000644000175000001440000000460714200302440027501 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_midictrl.h * * Contents and purpose: * MIDI controller definitions * * This header only contains declarations that are specific * to this implementation. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_MIDICTRL_H #define _EAS_MIDICTRL_H /* define controller types */ /* Note that these controller types are specified in base 10 (decimal) and not in hexadecimal. The above midi messages are specified in hexadecimal. */ #define MIDI_CONTROLLER_BANK_SELECT 0 #define MIDI_CONTROLLER_BANK_SELECT_MSB 0 #define MIDI_CONTROLLER_MOD_WHEEL 1 #define MIDI_CONTROLLER_ENTER_DATA_MSB 6 #define MIDI_CONTROLLER_VOLUME 7 #define MIDI_CONTROLLER_PAN 10 #define MIDI_CONTROLLER_EXPRESSION 11 #define MIDI_CONTROLLER_BANK_SELECT_LSB 32 #define MIDI_CONTROLLER_ENTER_DATA_LSB 38 /* 0x26 */ #define MIDI_CONTROLLER_SUSTAIN_PEDAL 64 #define MIDI_CONTROLLER_SELECT_NRPN_LSB 98 #define MIDI_CONTROLLER_SELECT_NRPN_MSB 99 #define MIDI_CONTROLLER_SELECT_RPN_LSB 100 /* 0x64 */ #define MIDI_CONTROLLER_SELECT_RPN_MSB 101 /* 0x65 */ #define MIDI_CONTROLLER_ALL_SOUND_OFF 120 #define MIDI_CONTROLLER_RESET_CONTROLLERS 121 #define MIDI_CONTROLLER_ALL_NOTES_OFF 123 #define MIDI_CONTROLLER_OMNI_OFF 124 #define MIDI_CONTROLLER_OMNI_ON 125 #define MIDI_CONTROLLER_MONO_ON_POLY_OFF 126 #define MIDI_CONTROLLER_POLY_ON_MONO_OFF 127 #endif /* #ifndef _EAS_MIDICTRL_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_pcm.h0000644000000000000000000000013214200302440025661 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.189324413 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_pcm.h0000644000175000001440000002544714200302440026456 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_pcm.h * * Contents and purpose: * External function prototypes for eas_pcm.c module * * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 847 $ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_PCM_H #define _EAS_PCM_H /* default gain setting - roughly unity gain */ #define PCM_DEFAULT_GAIN_SETTING 0x6000 typedef struct s_pcm_state_tag *EAS_PCM_HANDLE; typedef void (*EAS_PCM_CALLBACK) (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR cbInstData, EAS_PCM_HANDLE pcmHandle, EAS_STATE state); /* parameters for EAS_PEOpenStream */ typedef struct s_pcm_open_params_tag { EAS_FILE_HANDLE fileHandle; EAS_I32 decoder; EAS_U32 sampleRate; EAS_I32 size; EAS_U32 loopStart; EAS_U32 loopSamples; EAS_I32 blockSize; EAS_U32 flags; EAS_U32 envData; EAS_I16 volume; EAS_PCM_CALLBACK pCallbackFunc; EAS_VOID_PTR cbInstData; } S_PCM_OPEN_PARAMS; /*---------------------------------------------------------------------------- * EAS_PEInit() *---------------------------------------------------------------------------- * Purpose: * Initializes the PCM engine * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEInit (EAS_DATA_HANDLE pEASData); /*---------------------------------------------------------------------------- * EAS_PEShutdown() *---------------------------------------------------------------------------- * Purpose: * Shuts down the PCM engine * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEShutdown (EAS_DATA_HANDLE pEASData); /*---------------------------------------------------------------------------- * EAS_PEOpenStream() *---------------------------------------------------------------------------- * Purpose: * Starts up a PCM playback * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEOpenStream (EAS_DATA_HANDLE pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle); /*---------------------------------------------------------------------------- * EAS_PEContinueStream() *---------------------------------------------------------------------------- * Purpose: * Continues a PCM stream * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEContinueStream (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_I32 size); /*---------------------------------------------------------------------------- * EAS_PEGetFileHandle() *---------------------------------------------------------------------------- * Purpose: * Returns the file handle of a stream * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEGetFileHandle (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_FILE_HANDLE *pFileHandle); /*---------------------------------------------------------------------------- * EAS_PERender() *---------------------------------------------------------------------------- * Purpose: * Render a buffer of PCM audio * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PERender (EAS_DATA_HANDLE pEASData, EAS_I32 numSamples); /*---------------------------------------------------------------------------- * EAS_PEUpdateParams() *---------------------------------------------------------------------------- * Purpose: * Update the pitch and volume parameters using MIDI controls * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEUpdateParams (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight); /*---------------------------------------------------------------------------- * EAS_PELocate() *---------------------------------------------------------------------------- * Purpose: * This function seeks to the requested place in the file. Accuracy * is dependent on the sample rate and block size. * * Inputs: * pEASData - pointer to overall EAS data structure * pState - stream handle * time - media time in milliseconds *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PELocate (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I32 time); /*---------------------------------------------------------------------------- * EAS_PEUpdateVolume() *---------------------------------------------------------------------------- * Purpose: * Update the volume parameters for a PCM stream * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_PCM_STATE for this stream * gainLeft - linear gain multipler in 1.15 fraction format * gainRight - linear gain multipler in 1.15 fraction format * initial - initial settings, set current gain * * Outputs: * * * Side Effects: * * Notes * In mono mode, leftGain controls the output gain and rightGain is ignored *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT EAS_PEUpdateVolume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume); /*---------------------------------------------------------------------------- * EAS_PEUpdatePitch() *---------------------------------------------------------------------------- * Purpose: * Update the pitch parameter for a PCM stream * * Inputs: * pEASData - pointer to EAS library instance data * pState - pointer to S_PCM_STATE for this stream * pitch - new pitch value in pitch cents *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT EAS_PEUpdatePitch (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch); /*---------------------------------------------------------------------------- * EAS_PEState() *---------------------------------------------------------------------------- * Purpose: * Returns the current state of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pState - pointer to variable to store state * * Outputs: * * * Side Effects: * * Notes: * This interface is also exposed in the internal library for use by the other modules. *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEState (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_STATE *pState); /*---------------------------------------------------------------------------- * EAS_PEClose() *---------------------------------------------------------------------------- * Purpose: * Close the file and clean up * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEClose (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle); /*---------------------------------------------------------------------------- * EAS_PEReset() *---------------------------------------------------------------------------- * Purpose: * Reset the sequencer. Used for locating backwards in the file. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEReset (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle); /*---------------------------------------------------------------------------- * EAS_PEPause() *---------------------------------------------------------------------------- * Purpose: * Mute and pause rendering a PCM stream. Sets the gain target to zero and stops the playback * at the end of the next audio frame. * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_PCM_STATE for this stream * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEPause (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle); /*---------------------------------------------------------------------------- * EAS_PEResume() *---------------------------------------------------------------------------- * Purpose: * Resume rendering a PCM stream. Sets the gain target back to its * previous setting and restarts playback at the end of the next audio * frame. * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_PCM_STATE for this stream * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PEResume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle); /*---------------------------------------------------------------------------- * EAS_PERelease() *---------------------------------------------------------------------------- * Purpose: * Put the PCM stream envelope into release. * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_PCM_STATE for this stream * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PERelease (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle); #endif /* end _EAS_PCM_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_imelody.c0000644000000000000000000000013214200302440026537 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.189324413 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_imelody.c0000644000175000001440000014272214200302440027330 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_imelody.c * * Contents and purpose: * iMelody parser * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 797 $ * $Date: 2007-08-01 00:15:56 -0700 (Wed, 01 Aug 2007) $ *---------------------------------------------------------------------------- */ /* lint doesn't like the way some string.h files look */ #ifdef _lint #include "lint_stdlib.h" #else #include #endif #include "eas_data.h" #include "eas_miditypes.h" #include "eas_parser.h" #include "eas_report.h" #include "eas_host.h" #include "eas_midi.h" #include "eas_config.h" #include "eas_vm_protos.h" #include "eas_imelodydata.h" #include "eas_ctype.h" // #define _DEBUG_IMELODY /* increase gain for mono ringtones */ #define IMELODY_GAIN_OFFSET 8 /* length of 32nd note in 1/256ths of a msec for 120 BPM tempo */ #define DEFAULT_TICK_CONV 16000 #define TICK_CONVERT 1920000 /* default channel and program for iMelody playback */ #define IMELODY_CHANNEL 0 #define IMELODY_PROGRAM 80 #define IMELODY_VEL_MUL 4 #define IMELODY_VEL_OFS 67 /* multiplier for fixed point triplet conversion */ #define TRIPLET_MULTIPLIER 683 #define TRIPLET_SHIFT 10 static const char* const tokens[] = { "BEGIN:IMELODY", "VERSION:", "FORMAT:CLASS", "NAME:", "COMPOSER:", "BEAT:", "STYLE:", "VOLUME:", "MELODY:", "END:IMELODY" }; /* ledon or ledoff */ static const char ledStr[] = "edo"; /* vibeon or vibeoff */ static const char vibeStr[] = "ibeo"; /* backon or backoff */ static const char backStr[] = "cko"; typedef enum { TOKEN_BEGIN, TOKEN_VERSION, TOKEN_FORMAT, TOKEN_NAME, TOKEN_COMPOSER, TOKEN_BEAT, TOKEN_STYLE, TOKEN_VOLUME, TOKEN_MELODY, TOKEN_END, TOKEN_INVALID } ENUM_IMELODY_TOKENS; /* lookup table for note values */ static const EAS_I8 noteTable[] = { 9, 11, 0, 2, 4, 5, 7 }; /* inline functions */ #ifdef _DEBUG_IMELODY static void PutBackChar (S_IMELODY_DATA *pData) { if (pData->index) pData->index--; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "PutBackChar '%c'\n", pData->buffer[pData->index]); */ } } #else EAS_INLINE void PutBackChar (S_IMELODY_DATA *pData) { if (pData->index) pData->index--; } #endif /* local prototypes */ static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset); static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime); static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode); static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState); static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode); static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData); static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration); static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData); static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData); static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData); static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader); static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader); static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData); static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader); static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine); static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex); /*---------------------------------------------------------------------------- * * EAS_iMelody_Parser * * This structure contains the functional interface for the iMelody parser *---------------------------------------------------------------------------- */ const S_FILE_PARSER_INTERFACE EAS_iMelody_Parser = { IMY_CheckFileType, IMY_Prepare, IMY_Time, IMY_Event, IMY_State, IMY_Close, IMY_Reset, IMY_Pause, IMY_Resume, NULL, IMY_SetData, IMY_GetData, NULL }; /*---------------------------------------------------------------------------- * IMY_CheckFileType() *---------------------------------------------------------------------------- * Purpose: * Check the file type to see if we can parse it * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset) { S_IMELODY_DATA* pData; EAS_I8 buffer[MAX_LINE_SIZE+1]; EAS_U8 index; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_CheckFileType\n"); */ } #endif /* read the first line of the file */ *ppHandle = NULL; if (IMY_ReadLine(pEASData->hwInstData, fileHandle, buffer, NULL) != EAS_SUCCESS) return EAS_SUCCESS; /* check for header string */ if (IMY_ParseLine(buffer, &index) == TOKEN_BEGIN) { /* check for static memory allocation */ if (pEASData->staticMemoryModel) pData = EAS_CMEnumData(EAS_CM_IMELODY_DATA); else pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_IMELODY_DATA)); if (!pData) return EAS_ERROR_MALLOC_FAILED; EAS_HWMemSet(pData, 0, sizeof(S_IMELODY_DATA)); /* initialize */ pData->fileHandle = fileHandle; pData->fileOffset = offset; pData->state = EAS_STATE_ERROR; pData->state = EAS_STATE_OPEN; /* return a pointer to the instance data */ *ppHandle = pData; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_Prepare() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. Allocates instance data (or uses static allocation for * static memory model). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_IMELODY_DATA* pData; EAS_RESULT result; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_Prepare\n"); */ } #endif /* check for valid state */ pData = (S_IMELODY_DATA*) pInstData; if (pData->state != EAS_STATE_OPEN) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* instantiate a synthesizer */ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ } return result; } /* parse the header */ if ((result = IMY_ParseHeader(pEASData, pData)) != EAS_SUCCESS) return result; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Prepare: state set to EAS_STATE_READY\n"); */ } #endif pData ->state = EAS_STATE_READY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_Time() *---------------------------------------------------------------------------- * Purpose: * Returns the time of the next event in msecs * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pTime - pointer to variable to hold time of next event (in msecs) * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) common decoder interface - pEASData not used */ static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime) { S_IMELODY_DATA *pData; pData = (S_IMELODY_DATA*) pInstData; /* return time in milliseconds */ /*lint -e{704} use shift instead of division */ *pTime = pData->time >> 8; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_Event() *---------------------------------------------------------------------------- * Purpose: * Parse the next event in the file * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode) { S_IMELODY_DATA* pData; EAS_RESULT result; EAS_I8 c; EAS_BOOL eof; EAS_INT temp; pData = (S_IMELODY_DATA*) pInstData; if (pData->state >= EAS_STATE_OPEN) return EAS_SUCCESS; if (pData->state == EAS_STATE_READY) { pData->state = EAS_STATE_PLAY; } /* initialize MIDI channel when the track starts playing */ if (pData->time == 0) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: Reset\n"); */ } #endif /* set program to square lead */ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, IMELODY_PROGRAM); /* set channel volume to max */ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, 7, 127); } /* check for end of note */ if (pData->note) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Stopping note %d\n", pData->note); */ } #endif /* stop the note */ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, 0); pData->note = 0; /* check for rest between notes */ if (pData->restTicks) { pData->time += pData->restTicks; pData->restTicks = 0; return EAS_SUCCESS; } } /* parse the next event */ eof = EAS_FALSE; while (!eof) { /* get next character */ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE); switch (c) { /* start repeat */ case '(': #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter repeat section\n", c); */ } #endif if (pData->repeatOffset < 0) { pData->repeatOffset = pData->startLine + (EAS_I32) pData->index; /* save current time and check it later to make sure the loop isn't zero length */ pData->repeatTime = pData->time; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat offset = %d\n", pData->repeatOffset); */ } #endif } else { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring nested repeat section\n"); */ } break; /* end repeat */ case ')': #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "End repeat section, repeat offset = %d\n", pData->repeatOffset); */ } #endif /* ignore zero-length loops */ if (pData->repeatTime == pData->time) { pData->repeatCount = -1; pData->repeatOffset = -1; } else if (pData->repeatCount >= 0) { /* decrement repeat count (repeatCount == 0 means infinite loop) */ if (pData->repeatCount > 0) { if (--pData->repeatCount == 0) { pData->repeatCount = -1; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat loop complete\n"); */ } #endif } } //2 TEMPORARY FIX: If locating, don't do infinite loops. //3 We need a different mode for metadata parsing where we don't loop at all if ((parserMode == eParserModePlay) || (pData->repeatCount != 0)) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Rewinding file for repeat\n"); */ } #endif /* rewind to start of loop */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS) return result; IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine); pData->index = 0; /* if last loop, prevent future loops */ if (pData->repeatCount == -1) pData->repeatOffset = -1; } } break; /* repeat count */ case '@': if (!IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_FALSE)) eof = EAS_TRUE; else if (pData->repeatOffset > 0) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat count = %dt", pData->repeatCount); */ } #endif if (pData->repeatCount < 0) pData->repeatCount = (EAS_I16) temp; } break; /* volume */ case 'V': if (!IMY_GetVolume(pEASData->hwInstData, pData, EAS_FALSE)) eof = EAS_TRUE; break; /* flat */ case '&': pData->noteModifier = -1; break; /* sharp */ case '#': pData->noteModifier = +1; break; /* octave */ case '*': c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE); if (IsDigit(c)) pData->octave = (EAS_U8) ((c - '0' + 1) * 12); else if (!c) eof = EAS_TRUE; break; /* ledon or ledoff */ case 'l': if (!IMY_GetLEDState(pEASData, pData)) eof = EAS_TRUE; break; /* vibeon or vibeoff */ case 'v': if (!IMY_GetVibeState(pEASData, pData)) eof = EAS_TRUE; break; /* either a B note or backon or backoff */ case 'b': if (IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE) == 'a') { if (!IMY_GetBackState(pEASData, pData)) eof = EAS_TRUE; } else { PutBackChar(pData); if (IMY_PlayNote(pEASData, pData, c, parserMode)) return EAS_SUCCESS; eof = EAS_TRUE; } break; /* rest */ case 'r': case 'R': if (IMY_PlayRest(pEASData, pData)) return EAS_SUCCESS; eof = EAS_TRUE; break; /* EOF */ case 0: #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: end of iMelody file detected\n"); */ } #endif eof = EAS_TRUE; break; /* must be a note */ default: c = ToLower(c); if ((c >= 'a') && (c <= 'g')) { if (IMY_PlayNote(pEASData, pData, c, parserMode)) return EAS_SUCCESS; eof = EAS_TRUE; } else { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unexpected character '%c' [0x%02x]\n", c, c); */ } break; } } /* handle EOF */ #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: state set to EAS_STATE_STOPPING\n"); */ } #endif pData->state = EAS_STATE_STOPPING; VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_State() *---------------------------------------------------------------------------- * Purpose: * Returns the current state of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pState - pointer to variable to store state * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) common decoder interface - pEASData not used */ static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState) { S_IMELODY_DATA* pData; /* establish pointer to instance data */ pData = (S_IMELODY_DATA*) pInstData; /* if stopping, check to see if synth voices are active */ if (pData->state == EAS_STATE_STOPPING) { if (VMActiveVoices(pData->pSynth) == 0) { pData->state = EAS_STATE_STOPPED; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_STOPPED\n"); */ } #endif } } if (pData->state == EAS_STATE_PAUSING) { if (VMActiveVoices(pData->pSynth) == 0) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_PAUSED\n"); */ } #endif pData->state = EAS_STATE_PAUSED; } } /* return current state */ *pState = pData->state; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_Close() *---------------------------------------------------------------------------- * Purpose: * Close the file and clean up * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_IMELODY_DATA* pData; EAS_RESULT result; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Close: close file\n"); */ } #endif pData = (S_IMELODY_DATA*) pInstData; /* close the file */ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS) return result; /* free the synth */ if (pData->pSynth != NULL) VMMIDIShutdown(pEASData, pData->pSynth); /* if using dynamic memory, free it */ if (!pEASData->staticMemoryModel) EAS_HWFree(pEASData->hwInstData, pData); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_Reset() *---------------------------------------------------------------------------- * Purpose: * Reset the sequencer. Used for locating backwards in the file. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_IMELODY_DATA* pData; EAS_RESULT result; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: reset file\n"); */ } #endif pData = (S_IMELODY_DATA*) pInstData; /* reset the synth */ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE); /* reset time to zero */ pData->time = 0; pData->note = 0; /* reset file position and re-parse header */ pData->state = EAS_STATE_ERROR; if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS) return result; if ((result = IMY_ParseHeader (pEASData, pData)) != EAS_SUCCESS) return result; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: state set to EAS_STATE_ERROR\n"); */ } #endif pData->state = EAS_STATE_READY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_Pause() *---------------------------------------------------------------------------- * Purpose: * Pauses the sequencer. Mutes all voices and sets state to pause. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_IMELODY_DATA *pData; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Pause: pause file\n"); */ } #endif /* can't pause a stopped stream */ pData = (S_IMELODY_DATA*) pInstData; if (pData->state == EAS_STATE_STOPPED) return EAS_ERROR_ALREADY_STOPPED; /* mute the synthesizer */ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth); pData->state = EAS_STATE_PAUSING; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_Resume() *---------------------------------------------------------------------------- * Purpose: * Resume playing after a pause, sets state back to playing. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) common decoder interface - pEASData not used */ static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_IMELODY_DATA *pData; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Resume: resume file\n"); */ } #endif /* can't resume a stopped stream */ pData = (S_IMELODY_DATA*) pInstData; if (pData->state == EAS_STATE_STOPPED) return EAS_ERROR_ALREADY_STOPPED; /* nothing to do but resume playback */ pData->state = EAS_STATE_PLAY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_SetData() *---------------------------------------------------------------------------- * Purpose: * Adjust tempo relative to song tempo * * Inputs: * pEASData - pointer to overall EAS data structure * pInstData - pointer to iMelody instance data * rate - rate (28-bit fractional amount) * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) common decoder interface - pEASData not used */ static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value) { S_IMELODY_DATA *pData; pData = (S_IMELODY_DATA*) pInstData; switch (param) { /* set metadata callback */ case PARSER_DATA_METADATA_CB: EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB)); break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_GetData() *---------------------------------------------------------------------------- * Purpose: * Return the file type * * Inputs: * pEASData - pointer to overall EAS data structure * pInstData - pointer to iMelody instance data * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) common decoder interface - pEASData not used */ static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue) { S_IMELODY_DATA *pData; pData = (S_IMELODY_DATA*) pInstData; switch (param) { /* return file type as iMelody */ case PARSER_DATA_FILE_TYPE: *pValue = EAS_FILE_IMELODY; break; case PARSER_DATA_SYNTH_HANDLE: *pValue = (EAS_I32) pData->pSynth; break; case PARSER_DATA_GAIN_OFFSET: *pValue = IMELODY_GAIN_OFFSET; break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_PlayNote() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode) { EAS_I32 duration; EAS_U8 velocity; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: start note %d\n", note); */ } #endif /* get the duration */ if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration)) return EAS_FALSE; /* save note value */ pData->note = (EAS_U8) (pData->octave + noteTable[note - 'a'] + pData->noteModifier); velocity = (EAS_U8) (pData->volume ? pData->volume * IMELODY_VEL_MUL + IMELODY_VEL_OFS : 0); /* start note only if in play mode */ if (parserMode == eParserModePlay) VMStartNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, velocity); #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: Start note %d, duration %d\n", pData->note, duration); */ } #endif /* determine note length */ switch (pData->style) { case 0: /*lint -e{704} shift for performance */ pData->restTicks = duration >> 4; break; case 1: pData->restTicks = 0; break; case 2: /*lint -e{704} shift for performance */ pData->restTicks = duration >> 1; break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "IMY_PlayNote: Note style out of range: %d\n", pData->style); */ } /*lint -e{704} shift for performance */ pData->restTicks = duration >> 4; break; } /* next event is at end of this note */ pData->time += duration - pData->restTicks; /* reset the flat/sharp modifier */ pData->noteModifier = 0; return EAS_TRUE; } /*---------------------------------------------------------------------------- * IMY_PlayRest() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData) { EAS_I32 duration; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_PlayRest]n"); */ } #endif /* get the duration */ if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration)) return EAS_FALSE; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayRest: note duration %d\n", duration); */ } #endif /* next event is at end of this note */ pData->time += duration; return EAS_TRUE; } /*---------------------------------------------------------------------------- * IMY_GetDuration() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration) { EAS_I32 duration; EAS_I8 c; /* get the duration */ *pDuration = 0; c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE); if (!c) return EAS_FALSE; if ((c < '0') || (c > '5')) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetDuration: error in duration '%c'\n", c); */ } #endif return EAS_FALSE; } /* calculate total length of note */ duration = pData->tick * (1 << ('5' - c)); /* check for duration modifier */ c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE); if (c) { if (c == '.') /*lint -e{704} shift for performance */ duration += duration >> 1; else if (c == ':') /*lint -e{704} shift for performance */ duration += (duration >> 1) + (duration >> 2); else if (c == ';') /*lint -e{704} shift for performance */ duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT; else PutBackChar(pData); } *pDuration = duration; return EAS_TRUE; } /*---------------------------------------------------------------------------- * IMY_GetLEDState() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData) { EAS_I8 c; EAS_INT i; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetLEDState\n"); */ } #endif for (i = 0; i < 5; i++) { c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE); if (!c) return EAS_FALSE; switch (i) { case 3: if (c == 'n') { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED on\n"); */ } #endif EAS_HWLED(pEASData->hwInstData, EAS_TRUE); return EAS_TRUE; } else if (c != 'f') return EAS_FALSE; break; case 4: if (c == 'f') { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED off\n"); */ } #endif EAS_HWLED(pEASData->hwInstData, EAS_FALSE); return EAS_TRUE; } return EAS_FALSE; default: if (c != ledStr[i]) return EAS_FALSE; break; } } return EAS_FALSE; } /*---------------------------------------------------------------------------- * IMY_GetVibeState() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData) { EAS_I8 c; EAS_INT i; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVibeState\n"); */ } #endif for (i = 0; i < 6; i++) { c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE); if (!c) return EAS_FALSE; switch (i) { case 4: if (c == 'n') { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate on\n"); */ } #endif EAS_HWVibrate(pEASData->hwInstData, EAS_TRUE); return EAS_TRUE; } else if (c != 'f') return EAS_FALSE; break; case 5: if (c == 'f') { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate off\n"); */ } #endif EAS_HWVibrate(pEASData->hwInstData, EAS_FALSE); return EAS_TRUE; } return EAS_FALSE; default: if (c != vibeStr[i]) return EAS_FALSE; break; } } return EAS_FALSE; } /*---------------------------------------------------------------------------- * IMY_GetBackState() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData) { EAS_I8 c; EAS_INT i; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetBackState\n"); */ } #endif for (i = 0; i < 5; i++) { c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE); if (!c) return EAS_FALSE; switch (i) { case 3: if (c == 'n') { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight on\n"); */ } #endif EAS_HWBackLight(pEASData->hwInstData, EAS_TRUE); return EAS_TRUE; } else if (c != 'f') return EAS_FALSE; break; case 4: if (c == 'f') { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight off\n"); */ } #endif EAS_HWBackLight(pEASData->hwInstData, EAS_FALSE); return EAS_TRUE; } return EAS_FALSE; default: if (c != backStr[i]) return EAS_FALSE; break; } } return EAS_FALSE; } /*---------------------------------------------------------------------------- * IMY_GetVolume() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader) { EAS_INT temp; EAS_I8 c; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVolume\n"); */ } #endif c = IMY_GetNextChar(hwInstData, pData, inHeader); if (c == '+') { if (pData->volume < 15) pData->volume++; return EAS_TRUE; } else if (c == '-') { if (pData->volume > 0) pData->volume--; return EAS_TRUE; } else if (IsDigit(c)) temp = c - '0'; else return EAS_FALSE; c = IMY_GetNextChar(hwInstData, pData, inHeader); if (IsDigit(c)) temp = temp * 10 + c - '0'; else if (c) PutBackChar(pData); if ((temp >= 0) && (temp <= 15)) { if (inHeader && (temp == 0)) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring V0 encountered in header\n"); */ } else pData->volume = (EAS_U8) temp; } return EAS_TRUE; } /*---------------------------------------------------------------------------- * IMY_GetNumber() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader) { EAS_BOOL ok; EAS_I8 c; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetNumber\n"); */ } #endif *temp = 0; ok = EAS_FALSE; for (;;) { c = IMY_GetNextChar(hwInstData, pData, inHeader); if (IsDigit(c)) { *temp = *temp * 10 + c - '0'; ok = EAS_TRUE; } else { if (c) PutBackChar(pData); #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNumber: value %d\n", *temp); */ } #endif return ok; } } } /*---------------------------------------------------------------------------- * IMY_GetVersion() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_BOOL IMY_GetVersion (S_IMELODY_DATA *pData, EAS_INT *pVersion) { EAS_I8 c; EAS_INT temp; EAS_INT version; version = temp = 0; for (;;) { c = pData->buffer[pData->index++]; if ((c == 0) || (c == '.')) { /*lint -e{701} use shift for performance */ version = (version << 8) + temp; if (c == 0) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVersion: version 0x%04x\n", version); */ } #endif *pVersion = version; return EAS_TRUE; } temp = 0; } else if (IsDigit(c)) temp = (temp * 10) + c - '0'; } } /*---------------------------------------------------------------------------- * IMY_MetaData() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. Allocates instance data (or uses static allocation for * static memory model). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static void IMY_MetaData (S_IMELODY_DATA *pData, E_EAS_METADATA_TYPE metaType, EAS_I8 *buffer) { EAS_I32 len; /* check for callback */ if (!pData->metadata.callback) return; /* copy data to host buffer */ len = (EAS_I32) strlen((char*) buffer); if (len >pData->metadata.bufferSize) len = pData->metadata.bufferSize; strncpy((char*) pData->metadata.buffer, (char*) buffer, (size_t) len); pData->metadata.buffer[len] = 0; /* callback to host */ pData->metadata.callback(metaType, pData->metadata.buffer, pData->metadata.pUserData); } /*---------------------------------------------------------------------------- * IMY_ParseHeader() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. Allocates instance data (or uses static allocation for * static memory model). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData) { EAS_RESULT result; EAS_INT token; EAS_INT temp; EAS_I8 c; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_ParseHeader\n"); */ } #endif /* initialize some defaults */ pData->time = 0; pData->tick = DEFAULT_TICK_CONV; pData->note = 0; pData->noteModifier = 0; pData ->restTicks = 0; pData->volume = 7; pData->octave = 60; pData->repeatOffset = -1; pData->repeatCount = -1; pData->style = 0; /* force the read of the first line */ pData->index = 1; /* read data until we get to melody */ for (;;) { /* read a line from the file and parse the token */ if (pData->index != 0) { if ((result = IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine)) != EAS_SUCCESS) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: IMY_ReadLine returned %d\n", result); */ } #endif return result; } } token = IMY_ParseLine(pData->buffer, &pData->index); switch (token) { /* ignore these valid tokens */ case TOKEN_BEGIN: break; case TOKEN_FORMAT: if (!IMY_GetVersion(pData, &temp)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid FORMAT field '%s'\n", pData->buffer); */ } return EAS_ERROR_FILE_FORMAT; } if ((temp != 0x0100) && (temp != 0x0200)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported FORMAT %02x\n", temp); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } break; case TOKEN_VERSION: if (!IMY_GetVersion(pData, &temp)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid VERSION field '%s'\n", pData->buffer); */ } return EAS_ERROR_FILE_FORMAT; } if ((temp != 0x0100) && (temp != 0x0102)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported VERSION %02x\n", temp); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } break; case TOKEN_NAME: IMY_MetaData(pData, EAS_METADATA_TITLE, pData->buffer + pData->index); break; case TOKEN_COMPOSER: IMY_MetaData(pData, EAS_METADATA_AUTHOR, pData->buffer + pData->index); break; /* handle beat */ case TOKEN_BEAT: IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_TRUE); if ((temp >= 25) && (temp <= 900)) pData->tick = TICK_CONVERT / temp; break; /* handle style */ case TOKEN_STYLE: c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE); if (c == 'S') c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE); if ((c >= '0') && (c <= '2')) pData->style = (EAS_U8) (c - '0'); else { PutBackChar(pData); { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in style command: %s\n", pData->buffer); */ } } break; /* handle volume */ case TOKEN_VOLUME: c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE); if (c != 'V') { PutBackChar(pData); if (!IsDigit(c)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in volume command: %s\n", pData->buffer); */ } break; } } IMY_GetVolume(pEASData->hwInstData, pData, EAS_TRUE); break; case TOKEN_MELODY: #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Header successfully parsed\n"); */ } #endif return EAS_SUCCESS; case TOKEN_END: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unexpected END:IMELODY encountered\n"); */ } return EAS_ERROR_FILE_FORMAT; default: /* force a read of the next line */ pData->index = 1; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized token in iMelody file: %s\n", pData->buffer); */ } break; } } } /*---------------------------------------------------------------------------- * IMY_GetNextChar() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader) { EAS_I8 c; EAS_U8 index; for (;;) { /* get next character */ c = pData->buffer[pData->index++]; /* buffer empty, read more */ if (!c) { /* don't read the next line in the header */ if (inHeader) return 0; pData->index = 0; pData->buffer[0] = 0; if (IMY_ReadLine(hwInstData, pData->fileHandle, pData->buffer, &pData->startLine) != EAS_SUCCESS) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: EOF\n"); */ } #endif return 0; } /* check for END:IMELODY token */ if (IMY_ParseLine(pData->buffer, &index) == TOKEN_END) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: found END:IMELODY\n"); */ } #endif pData->buffer[0] = 0; return 0; } continue; } /* ignore white space */ if (!IsSpace(c)) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar returned '%c'\n", c); */ } #endif return c; } } } /*---------------------------------------------------------------------------- * IMY_ReadLine() *---------------------------------------------------------------------------- * Purpose: * Reads a line of input from the file, discarding the CR/LF * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine) { EAS_RESULT result; EAS_INT i; EAS_I8 c; /* fetch current file position and save it */ if (pStartLine != NULL) { if ((result = EAS_HWFilePos(hwInstData, fileHandle, pStartLine)) != EAS_SUCCESS) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: EAS_HWFilePos returned %d\n", result); */ } #endif return result; } } buffer[0] = 0; for (i = 0; i < MAX_LINE_SIZE; ) { if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS) { if ((result == EAS_EOF) && (i > 0)) break; return result; } /* return on LF or end of data */ if (c == '\n') break; /* store characters in buffer */ if (c != '\r') buffer[i++] = c; } buffer[i] = 0; #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ReadLine read %s\n", buffer); */ } #endif return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMY_ParseLine() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex) { EAS_INT i; EAS_INT j; /* there's no strnicmp() in stdlib, so we have to roll our own */ for (i = 0; i < TOKEN_INVALID; i++) { for (j = 0; ; j++) { /* end of token, must be a match */ if (tokens[i][j] == 0) { #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine found token %d\n", i); */ } #endif *pIndex = (EAS_U8) j; return i; } if (tokens[i][j] != ToUpper(buffer[j])) break; } } #ifdef _DEBUG_IMELODY { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine: no token found\n"); */ } #endif return TOKEN_INVALID; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_miditypes.h0000644000000000000000000000013214200302440027111 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.189324413 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_miditypes.h0000644000175000001440000001306714200302440027701 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_miditypes.h * * Contents and purpose: * Contains declarations for the MIDI stream parser. * * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 778 $ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_MIDITYPES_H #define _EAS_MIDITYPES_H #include "eas_data.h" #include "eas_parser.h" /*---------------------------------------------------------------------------- * S_MIDI_STREAM * * Maintains parser state for the MIDI stream parser * *---------------------------------------------------------------------------- */ typedef struct s_midi_stream_tag { EAS_BOOL8 byte3; /* flag indicates 3rd byte expected */ EAS_BOOL8 pending; /* flag indicates more data expected */ EAS_U8 sysExState; /* maintains the SysEx state */ EAS_U8 runningStatus; /* last running status received */ EAS_U8 status; /* status byte */ EAS_U8 d1; /* first data byte */ EAS_U8 d2; /* second data byte */ EAS_U8 flags; /* flags - see below for definition */ #ifdef JET_INTERFACE EAS_U32 jetData; /* JET data */ #endif } S_MIDI_STREAM; /* flags for S_MIDI_STREAM.flags */ #define MIDI_FLAG_GM_ON 0x01 /* GM System On message received */ #define MIDI_FLAG_FIRST_NOTE 0x02 /* first note received */ /* flags for S_MIDI_STREAM.jetFlags */ #define MIDI_FLAGS_JET_MUTE 0x00000001 /* track is muted */ #define MIDI_FLAGS_JET_CB 0x00000002 /* JET callback enabled */ /*---------------------------------------------------------------------------- * * S_SMF_STREAM * * This structure contains data required to parse an SMF stream. For SMF0 files, there * will be a single instance of this per file. For SMF1 files, there will be multiple instance, * one for each separate stream in the file. * *---------------------------------------------------------------------------- */ typedef struct s_smf_stream_tag { EAS_FILE_HANDLE fileHandle; /* host wrapper file handle */ EAS_U32 ticks; /* time of next event in stream */ EAS_I32 startFilePos; /* start location of track within file */ S_MIDI_STREAM midiStream; /* MIDI stream state */ } S_SMF_STREAM; /*---------------------------------------------------------------------------- * * S_SMF_DATA * * This structure contains the instance data required to parse an SMF stream. * *---------------------------------------------------------------------------- */ typedef struct s_smf_data_tag { #ifdef _CHECKED_BUILD EAS_U32 handleCheck; /* signature check for checked build */ #endif S_SMF_STREAM *streams; /* pointer to individual streams in file */ S_SMF_STREAM *nextStream; /* pointer to next stream with event */ S_SYNTH *pSynth; /* pointer to synth */ EAS_FILE_HANDLE fileHandle; /* file handle */ S_METADATA_CB metadata; /* metadata callback */ EAS_I32 fileOffset; /* for embedded files */ EAS_I32 time; /* current time in milliseconds/256 */ EAS_U16 numStreams; /* actual number of streams */ EAS_U16 tickConv; /* current MIDI tick to msec conversion */ EAS_U16 ppqn; /* ticks per quarter note */ EAS_U8 state; /* current state EAS_STATE_XXXX */ EAS_U8 flags; /* flags - see definitions below */ } S_SMF_DATA; #define SMF_FLAGS_CHASE_MODE 0x01 /* chase mode - skip to first note */ #define SMF_FLAGS_HAS_TIME_SIG 0x02 /* time signature encountered at time 0 */ #define SMF_FLAGS_HAS_TEMPO 0x04 /* tempo encountered at time 0 */ #define SMF_FLAGS_HAS_GM_ON 0x08 /* GM System On encountered at time 0 */ #define SMF_FLAGS_JET_STREAM 0x80 /* JET in use - keep strict timing */ /* combo flags indicate setup bar */ #define SMF_FLAGS_SETUP_BAR (SMF_FLAGS_HAS_TIME_SIG | SMF_FLAGS_HAS_TEMPO | SMF_FLAGS_HAS_GM_ON) /*---------------------------------------------------------------------------- * Interactive MIDI structure *---------------------------------------------------------------------------- */ typedef struct s_interactive_midi_tag { #ifdef _CHECKED_BUILD EAS_U32 handleCheck; /* signature check for checked build */ #endif S_SYNTH *pSynth; /* pointer to synth */ S_MIDI_STREAM stream; /* stream data */ } S_INTERACTIVE_MIDI; #endif /* #ifndef _EAS_MIDITYPES_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_pcmdata.c0000644000000000000000000000013214200302440026506 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.189324413 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_pcmdata.c0000644000175000001440000000217014200302440027267 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_pcmdata.c * * Contents and purpose: * Contains the static data for the PCM engine. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 547 $ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $ *---------------------------------------------------------------------------- */ #include "eas_data.h" /* static data allocation */ S_PCM_STATE eas_PCMData[MAX_PCM_STREAMS]; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_audioconst.h0000644000000000000000000000013214200302440027252 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.189324413 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_audioconst.h0000644000175000001440000000671314200302440030042 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_audioconst.h * * Contents and purpose: * Defines audio constants related to the sample rate, bit size, etc. * * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_AUDIOCONST_H #define _EAS_AUDIOCONST_H /*---------------------------------------------------------------------------- * These macros define the various characteristics of the defined sample rates *---------------------------------------------------------------------------- * BUFFER_SIZE_IN_MONO_SAMPLES size of buffer in samples * _OUTPUT_SAMPLE_RATE compiled output sample rate * AUDIO_FRAME_LENGTH length of an audio frame in 256ths of a millisecond * SYNTH_UPDATE_PERIOD_IN_BITS length of an audio frame (2^x samples) *---------------------------------------------------------------------------- */ #if defined (_SAMPLE_RATE_8000) #define BUFFER_SIZE_IN_MONO_SAMPLES 32 #define _OUTPUT_SAMPLE_RATE 8000 #define AUDIO_FRAME_LENGTH 1024 #define SYNTH_UPDATE_PERIOD_IN_BITS 5 #elif defined (_SAMPLE_RATE_16000) #define BUFFER_SIZE_IN_MONO_SAMPLES 64 #define _OUTPUT_SAMPLE_RATE 16000 #define AUDIO_FRAME_LENGTH 1024 #define SYNTH_UPDATE_PERIOD_IN_BITS 6 #elif defined (_SAMPLE_RATE_20000) #define BUFFER_SIZE_IN_MONO_SAMPLES 128 #define _OUTPUT_SAMPLE_RATE 20000 #define AUDIO_FRAME_LENGTH 1638 #define SYNTH_UPDATE_PERIOD_IN_BITS 7 #elif defined (_SAMPLE_RATE_22050) #define BUFFER_SIZE_IN_MONO_SAMPLES 128 #define _OUTPUT_SAMPLE_RATE 22050 #define AUDIO_FRAME_LENGTH 1486 #define SYNTH_UPDATE_PERIOD_IN_BITS 7 #elif defined (_SAMPLE_RATE_24000) #define BUFFER_SIZE_IN_MONO_SAMPLES 128 #define _OUTPUT_SAMPLE_RATE 24000 #define AUDIO_FRAME_LENGTH 1365 #define SYNTH_UPDATE_PERIOD_IN_BITS 7 #elif defined (_SAMPLE_RATE_32000) #define BUFFER_SIZE_IN_MONO_SAMPLES 128 #define _OUTPUT_SAMPLE_RATE 32000 #define AUDIO_FRAME_LENGTH 1024 #define SYNTH_UPDATE_PERIOD_IN_BITS 7 #elif defined (_SAMPLE_RATE_44100) #define BUFFER_SIZE_IN_MONO_SAMPLES 256 #define _OUTPUT_SAMPLE_RATE 44100 #define AUDIO_FRAME_LENGTH 1486 #define SYNTH_UPDATE_PERIOD_IN_BITS 8 #elif defined (_SAMPLE_RATE_48000) #define BUFFER_SIZE_IN_MONO_SAMPLES 256 #define _OUTPUT_SAMPLE_RATE 48000 #define AUDIO_FRAME_LENGTH 1365 #define SYNTH_UPDATE_PERIOD_IN_BITS 8 #else #error "_SAMPLE_RATE_XXXXX must be defined to valid rate" #endif #endif /* #ifndef _EAS_AUDIOCONST_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_mixer.c0000644000000000000000000000013214200302440026221 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.189324413 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_mixer.c0000644000175000001440000003734314200302440027014 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_mixer.c * * Contents and purpose: * This file contains the critical components of the mix engine that * must be optimized for best performance. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 706 $ * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $ *---------------------------------------------------------------------------- */ //3 dls: This module is in the midst of being converted from a synth //3 specific module to a general purpose mix engine /*------------------------------------ * includes *------------------------------------ */ #include "eas_data.h" #include "eas_host.h" #include "eas_math.h" #include "eas_mixer.h" #include "eas_config.h" #include "eas_report.h" #ifdef _MAXIMIZER_ENABLED EAS_I32 MaximizerProcess (EAS_VOID_PTR pInstData, EAS_I32 *pSrc, EAS_I32 *pDst, EAS_I32 numSamples); #endif /*------------------------------------ * defines *------------------------------------ */ /* need to boost stereo by ~3dB to compensate for the panner */ #define STEREO_3DB_GAIN_BOOST 512 /*---------------------------------------------------------------------------- * EAS_MixEngineInit() *---------------------------------------------------------------------------- * Purpose: * Prepares the mix engine for work, allocates buffers, locates effects modules, etc. * * Inputs: * pEASData - instance data * pInstData - pointer to variable to receive instance data handle * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_MixEngineInit (S_EAS_DATA *pEASData) { /* check Configuration Module for mix buffer allocation */ if (pEASData->staticMemoryModel) pEASData->pMixBuffer = EAS_CMEnumData(EAS_CM_MIX_BUFFER); else pEASData->pMixBuffer = EAS_HWMalloc(pEASData->hwInstData, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32)); if (pEASData->pMixBuffer == NULL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate mix buffer memory\n"); */ } return EAS_ERROR_MALLOC_FAILED; } EAS_HWMemSet((void *)(pEASData->pMixBuffer), 0, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32)); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_MixEnginePrep() *---------------------------------------------------------------------------- * Purpose: * Performs prep before synthesize a buffer of audio, such as clearing * audio buffers, etc. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ void EAS_MixEnginePrep (S_EAS_DATA *pEASData, EAS_I32 numSamples) { /* clear the mix buffer */ #if (NUM_OUTPUT_CHANNELS == 2) EAS_HWMemSet(pEASData->pMixBuffer, 0, numSamples * (EAS_I32) sizeof(long) * 2); #else EAS_HWMemSet(pEASData->pMixBuffer, 0, (EAS_I32) numSamples * (EAS_I32) sizeof(long)); #endif /* need to clear other side-chain effect buffers (chorus & reverb) */ } /*---------------------------------------------------------------------------- * EAS_MixEnginePost *---------------------------------------------------------------------------- * Purpose: * This routine does the post-processing after all voices have been * synthesized. It calls any sweeteners and does the final mixdown to * the output buffer. * * Inputs: * * Outputs: * * Notes: *---------------------------------------------------------------------------- */ void EAS_MixEnginePost (S_EAS_DATA *pEASData, EAS_I32 numSamples) { EAS_U16 gain; //3 dls: Need to restore the mix engine metrics /* calculate the gain multiplier */ #ifdef _MAXIMIZER_ENABLED if (pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effect) { EAS_I32 temp; temp = MaximizerProcess(pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effectData, pEASData->pMixBuffer, pEASData->pMixBuffer, numSamples); temp = (temp * pEASData->masterGain) >> 15; if (temp > 32767) gain = 32767; else gain = (EAS_U16) temp; } else gain = (EAS_U16) pEASData->masterGain; #else gain = (EAS_U16) pEASData->masterGain; #endif /* Not using all the gain bits for now * Reduce the input to the compressor by 6dB to prevent saturation */ #ifdef _COMPRESSOR_ENABLED if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData) gain = gain >> 5; else gain = gain >> 4; #else gain = gain >> 4; #endif /* convert 32-bit mix buffer to 16-bit output format */ #if (NUM_OUTPUT_CHANNELS == 2) SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) ((EAS_U16) numSamples * 2)); #else SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) numSamples); #endif #ifdef _ENHANCER_ENABLED /* enhancer effect */ if (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData) (*pEASData->effectsModules[EAS_MODULE_ENHANCER].effect->pfProcess) (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData, pEASData->pOutputAudioBuffer, pEASData->pOutputAudioBuffer, numSamples); #endif #ifdef _GRAPHIC_EQ_ENABLED /* graphic EQ effect */ if (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData) (*pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effect->pfProcess) (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData, pEASData->pOutputAudioBuffer, pEASData->pOutputAudioBuffer, numSamples); #endif #ifdef _COMPRESSOR_ENABLED /* compressor effect */ if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData) (*pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effect->pfProcess) (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData, pEASData->pOutputAudioBuffer, pEASData->pOutputAudioBuffer, numSamples); #endif #ifdef _WOW_ENABLED /* WOW requires a 32-bit buffer, borrow the mix buffer and * pass it as the destination buffer */ /*lint -e{740} temporarily passing a parameter through an existing I/F */ if (pEASData->effectsModules[EAS_MODULE_WOW].effectData) (*pEASData->effectsModules[EAS_MODULE_WOW].effect->pfProcess) (pEASData->effectsModules[EAS_MODULE_WOW].effectData, pEASData->pOutputAudioBuffer, (EAS_PCM*) pEASData->pMixBuffer, numSamples); #endif #ifdef _TONECONTROLEQ_ENABLED /* ToneControlEQ effect */ if (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData) (*pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effect->pfProcess) (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData, pEASData->pOutputAudioBuffer, pEASData->pOutputAudioBuffer, numSamples); #endif #ifdef _REVERB_ENABLED /* Reverb effect */ if (pEASData->effectsModules[EAS_MODULE_REVERB].effectData) (*pEASData->effectsModules[EAS_MODULE_REVERB].effect->pfProcess) (pEASData->effectsModules[EAS_MODULE_REVERB].effectData, pEASData->pOutputAudioBuffer, pEASData->pOutputAudioBuffer, numSamples); #endif #ifdef _CHORUS_ENABLED /* Chorus effect */ if (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData) (*pEASData->effectsModules[EAS_MODULE_CHORUS].effect->pfProcess) (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData, pEASData->pOutputAudioBuffer, pEASData->pOutputAudioBuffer, numSamples); #endif } #ifndef NATIVE_EAS_KERNEL /*---------------------------------------------------------------------------- * SynthMasterGain *---------------------------------------------------------------------------- * Purpose: * Mixes down audio from 32-bit to 16-bit target buffer * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ void SynthMasterGain (long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 numSamples) { /* loop through the buffer */ while (numSamples--) { long s; /* read a sample from the input buffer and add some guard bits */ s = *pInputBuffer++; /* add some guard bits */ /*lint -e{704} */ s = s >> 7; /* apply master gain */ s *= (long) nGain; /* shift to lower 16-bits */ /*lint -e{704} */ s = s >> 9; /* saturate */ s = SATURATE(s); *pOutputBuffer++ = (EAS_PCM)s; } } #endif /*---------------------------------------------------------------------------- * EAS_MixEngineShutdown() *---------------------------------------------------------------------------- * Purpose: * Shuts down effects modules and deallocates memory * * Inputs: * pEASData - instance data * pInstData - instance data handle * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_MixEngineShutdown (S_EAS_DATA *pEASData) { /* check Configuration Module for static memory allocation */ if (!pEASData->staticMemoryModel && (pEASData->pMixBuffer != NULL)) EAS_HWFree(pEASData->hwInstData, pEASData->pMixBuffer); return EAS_SUCCESS; } #ifdef UNIFIED_MIXER #ifndef NATIVE_MIX_STREAM /*---------------------------------------------------------------------------- * EAS_MixStream *---------------------------------------------------------------------------- * Mix a 16-bit stream into a 32-bit buffer * * pInputBuffer 16-bit input buffer * pMixBuffer 32-bit mix buffer * numSamples number of samples to mix * gainLeft initial gain left or mono * gainRight initial gain right * gainLeft left gain increment per sample * gainRight right gain increment per sample * flags bit 0 = stereo source * bit 1 = stereo output *---------------------------------------------------------------------------- */ void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags) { EAS_I32 temp; EAS_INT src, dest; /* NOTE: There are a lot of optimizations that can be done * in the native implementations based on register * availability, etc. For example, it may make sense to * break this down into 8 separate routines: * * 1. Mono source to mono output * 2. Mono source to stereo output * 3. Stereo source to mono output * 4. Stereo source to stereo output * 5. Mono source to mono output - no gain change * 6. Mono source to stereo output - no gain change * 7. Stereo source to mono output - no gain change * 8. Stereo source to stereo output - no gain change * * Other possibilities include loop unrolling, skipping * a gain calculation every 2 or 4 samples, etc. */ /* no gain change, use fast loops */ if ((gainIncLeft == 0) && (gainIncRight == 0)) { switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT)) { /* mono to mono */ case 0: gainLeft >>= 15; for (src = dest = 0; src < numSamples; src++, dest++) { pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS; } break; /* mono to stereo */ case MIX_FLAGS_STEREO_OUTPUT: gainLeft >>= 15; gainRight >>= 15; for (src = dest = 0; src < numSamples; src++, dest+=2) { pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS; pMixBuffer[dest+1] += (pInputBuffer[src] * gainRight) >> NUM_MIXER_GUARD_BITS; } break; /* stereo to mono */ case MIX_FLAGS_STEREO_SOURCE: gainLeft >>= 15; gainRight >>= 15; for (src = dest = 0; src < numSamples; src+=2, dest++) { temp = (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS; temp += ((pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS); pMixBuffer[dest] += temp; } break; /* stereo to stereo */ case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT: gainLeft >>= 15; gainRight >>= 15; for (src = dest = 0; src < numSamples; src+=2, dest+=2) { pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS; pMixBuffer[dest+1] += (pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS; } break; } } /* gain change - do gain increment */ else { switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT)) { /* mono to mono */ case 0: for (src = dest = 0; src < numSamples; src++, dest++) { gainLeft += gainIncLeft; pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS; } break; /* mono to stereo */ case MIX_FLAGS_STEREO_OUTPUT: for (src = dest = 0; src < numSamples; src++, dest+=2) { gainLeft += gainIncLeft; gainRight += gainIncRight; pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS; pMixBuffer[dest+1] += (pInputBuffer[src] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS; } break; /* stereo to mono */ case MIX_FLAGS_STEREO_SOURCE: for (src = dest = 0; src < numSamples; src+=2, dest++) { gainLeft += gainIncLeft; gainRight += gainIncRight; temp = (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS; temp += ((pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS); pMixBuffer[dest] += temp; } break; /* stereo to stereo */ case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT: for (src = dest = 0; src < numSamples; src+=2, dest+=2) { gainLeft += gainIncLeft; gainRight += gainIncRight; pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS; pMixBuffer[dest+1] += (pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS; } break; } } } #endif #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_synth.h0000644000000000000000000000013214200302440026247 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.189324413 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_synth.h0000644000175000001440000003114714200302440027036 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_synth.h * * Contents and purpose: * Declarations, interfaces, and prototypes for synth. * * Copyright Sonic Network Inc. 2004, 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 718 $ * $Date: 2007-06-08 16:43:16 -0700 (Fri, 08 Jun 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_SYNTH_H #define _EAS_SYNTH_H #include "eas_types.h" #include "eas_sndlib.h" #ifdef _WT_SYNTH #include "eas_wtsynth.h" #endif #ifdef _FM_SYNTH #include "eas_fmsynth.h" #endif #ifndef NUM_OUTPUT_CHANNELS #define NUM_OUTPUT_CHANNELS 2 #endif #ifndef MAX_SYNTH_VOICES #define MAX_SYNTH_VOICES 64 #endif #ifndef MAX_VIRTUAL_SYNTHESIZERS #define MAX_VIRTUAL_SYNTHESIZERS 4 #endif /* defines */ #ifndef NUM_PRIMARY_VOICES #define NUM_PRIMARY_VOICES MAX_SYNTH_VOICES #elif !defined(NUM_SECONDARY_VOICES) #define NUM_SECONDARY_VOICES (MAX_SYNTH_VOICES - NUM_PRIMARY_VOICES) #endif #if defined(EAS_WT_SYNTH) #define NUM_WT_VOICES MAX_SYNTH_VOICES /* FM on MCU */ #elif defined(EAS_FM_SYNTH) #define NUM_FM_VOICES MAX_SYNTH_VOICES /* wavetable drums on MCU, wavetable melodic on DSP */ #elif defined(EAS_SPLIT_WT_SYNTH) #define NUM_WT_VOICES MAX_SYNTH_VOICES /* wavetable drums and FM melodic on MCU */ #elif defined(EAS_HYBRID_SYNTH) #define NUM_WT_VOICES NUM_PRIMARY_VOICES #define NUM_FM_VOICES NUM_SECONDARY_VOICES /* wavetable drums on MCU, FM melodic on DSP */ #elif defined(EAS_SPLIT_HYBRID_SYNTH) #define NUM_WT_VOICES NUM_PRIMARY_VOICES #define NUM_FM_VOICES NUM_SECONDARY_VOICES /* FM synth on DSP */ #elif defined(EAS_SPLIT_FM_SYNTH) #define NUM_FM_VOICES MAX_SYNTH_VOICES #else #error "Unrecognized architecture option" #endif #define NUM_SYNTH_CHANNELS 16 #define DEFAULT_SYNTH_VOICES MAX_SYNTH_VOICES /* use the following values to specify unassigned channels or voices */ #define UNASSIGNED_SYNTH_CHANNEL NUM_SYNTH_CHANNELS #define UNASSIGNED_SYNTH_VOICE MAX_SYNTH_VOICES /* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */ #define SYNTH_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << SYNTH_UPDATE_PERIOD_IN_BITS) /* stealing weighting factors */ #define NOTE_AGE_STEAL_WEIGHT 1 #define NOTE_GAIN_STEAL_WEIGHT 4 #define CHANNEL_POLY_STEAL_WEIGHT 12 #define CHANNEL_PRIORITY_STEAL_WEIGHT 2 #define NOTE_MATCH_PENALTY 128 #define SYNTH_PRIORITY_WEIGHT 8 /* default synth master volume */ #define DEFAULT_SYNTH_MASTER_VOLUME 0x7fff #define DEFAULT_SYNTH_PRIORITY 5 /* default tuning values */ #define DEFAULT_PITCH_BEND_SENSITIVITY 200 /* 2 semitones */ #define DEFAULT_FINE_PITCH 0 /* 0 cents */ #define DEFAULT_COARSE_PITCH 0 /* 0 semitones */ /* default drum channel is 10, but is internally 9 due to unit offset */ #define DEFAULT_DRUM_CHANNEL 9 /* drum channel can simultaneously play this many voices at most */ #define DEFAULT_CHANNEL_POLYPHONY_LIMIT 2 /* default instrument is acoustic piano */ #define DEFAULT_MELODY_BANK_MSB 0x79 #define DEFAULT_RHYTHM_BANK_MSB 0x78 #define DEFAULT_MELODY_BANK_NUMBER (DEFAULT_MELODY_BANK_MSB << 8) #define DEFAULT_RHYTHM_BANK_NUMBER (DEFAULT_RHYTHM_BANK_MSB << 8) #define DEFAULT_SYNTH_PROGRAM_NUMBER 0 #define DEFAULT_PITCH_BEND 0x2000 /* 0x2000 == (0x40 << 7) | 0x00 */ #define DEFAULT_MOD_WHEEL 0 #define DEFAULT_CHANNEL_VOLUME 0x64 #define DEFAULT_PAN 0x40 /* decimal 64, center */ #ifdef _REVERB #define DEFAULT_REVERB_SEND 40 /* some reverb */ #endif #ifdef _CHORUS #define DEFAULT_CHORUS_SEND 0 /* no chorus */ #endif #define DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY 0 /* EAS synth uses a different default */ #define DEFAULT_FILTER_RESONANCE 0 #define DEFAULT_EXPRESSION 0x7F #define DEFAULT_CHANNEL_PRESSURE 0 #define DEFAULT_REGISTERED_PARAM 0x3FFF #define DEFAULT_CHANNEL_STATIC_GAIN 0 #define DEFAULT_CHANNEL_STATIC_PITCH 0 #define DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS 50 #define DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS 50 #define DEFAULT_KEY_NUMBER 0x69 #define DEFAULT_VELOCITY 0x64 #define DEFAULT_REGION_INDEX 0 #define DEFAULT_ARTICULATION_INDEX 0 #define DEFAULT_VOICE_GAIN 0 #define DEFAULT_AGE 0 #define DEFAULT_SP_MIDI_PRIORITY 16 /* filter defines */ #define DEFAULT_FILTER_ZERO 0 #define FILTER_CUTOFF_MAX_PITCH_CENTS 1919 #define FILTER_CUTOFF_MIN_PITCH_CENTS -4467 #define A5_PITCH_OFFSET_IN_CENTS 6900 /*------------------------------------ * S_SYNTH_CHANNEL data structure *------------------------------------ */ /* S_SYNTH_CHANNEL.m_nFlags */ #define CHANNEL_FLAG_SUSTAIN_PEDAL 0x01 #define CHANNEL_FLAG_MUTE 0x02 #define CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS 0x04 #define CHANNEL_FLAG_RHYTHM_CHANNEL 0x08 #define CHANNEL_FLAG_EXTERNAL_AUDIO 0x10 #define DEFAULT_CHANNEL_FLAGS 0 /* macros for extracting virtual synth and channel numbers */ #define GET_VSYNTH(a) ((a) >> 4) #define GET_CHANNEL(a) ((a) & 15) typedef struct s_synth_channel_tag { /* use static channel parameters to reduce MIPs */ /* parameters shared by multiple voices assigned to same channel */ EAS_I32 staticPitch; /* (pitch bend * pitch sens) + fine pitch */ EAS_I16 staticGain; /* (CC7 * CC11 * master vol)^2 */ EAS_U16 regionIndex; /* index of first region in program */ EAS_U16 bankNum; /* play programs from this bank */ EAS_I16 pitchBend; /* pitch wheel value */ EAS_I16 pitchBendSensitivity; EAS_I16 registeredParam; /* currently selected registered param */ #if defined(_FM_SYNTH) EAS_I16 lfoAmt; /* amount of LFO to apply to voice */ #endif EAS_U8 programNum; /* play this instrument number */ EAS_U8 modWheel; /* CC1 */ EAS_U8 volume; /* CC7 */ EAS_U8 pan; /* CC10 */ EAS_U8 expression; /* CC11 */ /* the following parameters are controlled by RPNs */ EAS_I8 finePitch; EAS_I8 coarsePitch; EAS_U8 channelPressure; /* applied to all voices on a given channel */ EAS_U8 channelFlags; /* bit field channelFlags for */ /* CC64, SP-MIDI channel masking */ EAS_U8 pool; /* SPMIDI channel voice pool */ EAS_U8 mip; /* SPMIDI MIP setting */ #ifdef _REVERB EAS_U8 reverbSend; /* CC91 */ #endif #ifdef _CHORUS EAS_U8 chorusSend; /* CC93 */ #endif } S_SYNTH_CHANNEL; /*------------------------------------ * S_SYNTH_VOICE data structure *------------------------------------ */ /* S_SYNTH_VOICE.m_nFlags */ #define VOICE_FLAG_UPDATE_VOICE_PARAMETERS 0x01 #define VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF 0x02 #define VOICE_FLAG_DEFER_MIDI_NOTE_OFF 0x04 #define VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET 0x08 #define VOICE_FLAG_DEFER_MUTE 0x40 #define DEFAULT_VOICE_FLAGS 0 /* S_SYNTH_VOICE.m_eState */ typedef enum { eVoiceStateFree = 0, eVoiceStateStart, eVoiceStatePlay, eVoiceStateRelease, eVoiceStateMuting, eVoiceStateStolen, eVoiceStateInvalid /* should never be in this state! */ } E_VOICE_STATE; #define DEFAULT_VOICE_STATE eVoiceStateFree typedef struct s_synth_voice_tag { /* These parameters are common to both wavetable and FM * synthesizers. The voice manager should only access this data. * Any other data should be manipulated by the code that is * specific to that synthesizer and reflected back through the * common state data available here. */ EAS_U16 regionIndex; /* index to wave and playback params */ EAS_I16 gain; /* current gain */ EAS_U16 age; /* large value means old note */ EAS_U16 nextRegionIndex; /* index to wave and playback params */ EAS_U8 voiceState; /* current voice state */ EAS_U8 voiceFlags; /* misc flags/bit fields */ EAS_U8 channel; /* this voice plays on this synth channel */ EAS_U8 note; /* 12 <= key number <= 108 */ EAS_U8 velocity; /* 0 <= velocity <= 127 */ EAS_U8 nextChannel; /* play stolen voice on this channel */ EAS_U8 nextNote; /* 12 <= key number <= 108 */ EAS_U8 nextVelocity; /* 0 <= velocity <= 127 */ } S_SYNTH_VOICE; /*------------------------------------ * S_SYNTH data structure * * One instance for each MIDI stream *------------------------------------ */ /* S_SYNTH.m_nFlags */ #define SYNTH_FLAG_RESET_IS_REQUESTED 0x01 #define SYNTH_FLAG_SP_MIDI_ON 0x02 #define SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS 0x04 #define SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING 0x08 #define DEFAULT_SYNTH_FLAGS SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS typedef struct s_synth_tag { struct s_eas_data_tag *pEASData; const S_EAS *pEAS; #ifdef DLS_SYNTHESIZER S_DLS *pDLS; #endif #ifdef EXTERNAL_AUDIO EAS_EXT_PRG_CHG_FUNC cbProgChgFunc; EAS_EXT_EVENT_FUNC cbEventFunc; EAS_VOID_PTR *pExtAudioInstData; #endif S_SYNTH_CHANNEL channels[NUM_SYNTH_CHANNELS]; EAS_I32 totalNoteCount; EAS_U16 maxPolyphony; EAS_U16 numActiveVoices; EAS_U16 masterVolume; EAS_U8 channelsByPriority[NUM_SYNTH_CHANNELS]; EAS_U8 poolCount[NUM_SYNTH_CHANNELS]; EAS_U8 poolAlloc[NUM_SYNTH_CHANNELS]; EAS_U8 synthFlags; EAS_I8 globalTranspose; EAS_U8 vSynthNum; EAS_U8 refCount; EAS_U8 priority; } S_SYNTH; /*------------------------------------ * S_VOICE_MGR data structure * * One instance for each EAS library instance *------------------------------------ */ typedef struct s_voice_mgr_tag { S_SYNTH *pSynth[MAX_VIRTUAL_SYNTHESIZERS]; EAS_PCM voiceBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES]; #ifdef _FM_SYNTH EAS_PCM operMixBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES]; S_FM_VOICE fmVoices[NUM_FM_VOICES]; #endif #ifdef _WT_SYNTH S_WT_VOICE wtVoices[NUM_WT_VOICES]; #endif #ifdef _REVERB EAS_PCM reverbSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES]; #endif #ifdef _CHORUS EAS_PCM chorusSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES]; #endif S_SYNTH_VOICE voices[MAX_SYNTH_VOICES]; EAS_SNDLIB_HANDLE pGlobalEAS; #ifdef DLS_SYNTHESIZER S_DLS *pGlobalDLS; #endif #ifdef _SPLIT_ARCHITECTURE EAS_FRAME_BUFFER_HANDLE pFrameBuffer; #endif #if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH) EAS_U16 maxPolyphonyPrimary; EAS_U16 maxPolyphonySecondary; #endif EAS_I32 workload; EAS_I32 maxWorkLoad; EAS_U16 activeVoices; EAS_U16 maxPolyphony; EAS_U16 age; /* limits the number of voice starts in a frame for split architecture */ #ifdef MAX_VOICE_STARTS EAS_U16 numVoiceStarts; #endif } S_VOICE_MGR; #endif /* #ifdef _EAS_SYNTH_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_data.h0000644000000000000000000000013214200302440026013 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.189324413 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_data.h0000644000175000001440000000715514200302440026604 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_data.h * * Contents and purpose: * This header defines all types, to support dynamic allocation of the * memory resources needed for persistent EAS data. * * Copyright 2004 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 842 $ * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_DATA_H #define _EAS_DATA_H #define JET_INTERFACE #include "eas_types.h" #include "eas_synthcfg.h" #include "eas.h" #include "eas_audioconst.h" #include "eas_sndlib.h" #include "eas_pcm.h" #include "eas_pcmdata.h" #include "eas_synth.h" #include "eas_miditypes.h" #include "eas_effects.h" #ifdef AUX_MIXER #include "eas_auxmixdata.h" #endif #ifdef JET_INTERFACE #include "jet.h" #endif #ifdef _METRICS_ENABLED #include "eas_perf.h" #endif #ifndef MAX_NUMBER_STREAMS #define MAX_NUMBER_STREAMS 4 #endif /* flags for S_EAS_STREAM */ #define STREAM_FLAGS_PARSED 1 #define STREAM_FLAGS_PAUSE 2 #define STREAM_FLAGS_LOCATE 4 #define STREAM_FLAGS_RESUME 8 /* structure for parsing a stream */ typedef struct s_eas_stream_tag { void *pParserModule; EAS_U32 time; EAS_U32 frameLength; EAS_I32 repeatCount; EAS_VOID_PTR handle; EAS_U8 volume; EAS_BOOL8 streamFlags; } S_EAS_STREAM; /* default master volume is -10dB */ #define DEFAULT_VOLUME 90 #define DEFAULT_STREAM_VOLUME 100 #define DEFAULT_STREAM_GAIN 14622 /* 10 dB of boost available for individual parsers */ #define STREAM_VOLUME_HEADROOM 10 /* amalgamated persistent data type */ typedef struct s_eas_data_tag { #ifdef _CHECKED_BUILD EAS_U32 handleCheck; #endif EAS_HW_DATA_HANDLE hwInstData; S_EFFECTS_MODULE effectsModules[NUM_EFFECTS_MODULES]; #ifdef _METRICS_ENABLED S_METRICS_INTERFACE *pMetricsModule; EAS_VOID_PTR pMetricsData; #endif EAS_I32 *pMixBuffer; EAS_PCM *pOutputAudioBuffer; #ifdef AUX_MIXER S_EAS_AUX_MIXER auxMixer; #endif #ifdef _MAXIMIZER_ENABLED EAS_VOID_PTR pMaximizerData; #endif S_EAS_STREAM streams[MAX_NUMBER_STREAMS]; S_PCM_STATE *pPCMStreams; S_VOICE_MGR *pVoiceMgr; #ifdef JET_INTERFACE JET_DATA_HANDLE jetHandle; #endif EAS_U32 renderTime; EAS_I16 masterGain; EAS_U8 masterVolume; EAS_BOOL8 staticMemoryModel; EAS_BOOL8 searchHeaderFlag; } S_EAS_DATA; #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_mdls.h0000644000000000000000000000013214200302440026041 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.189324413 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_mdls.h0000644000175000001440000002310314200302440026621 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_mdls.h * * Contents and purpose: * Declarations, interfaces, and prototypes for eas_mdls.c * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- */ #ifndef _EAS_MDLS_H #define _EAS_MDLS_H /*------------------------------------ * includes *------------------------------------ */ #include "eas_data.h" /*------------------------------------ * Some defines for dls.h *------------------------------------ */ #ifndef DWORD #define DWORD EAS_I32 #define FAR #define SHORT EAS_I16 #define USHORT EAS_U16 #define LONG EAS_I32 #define ULONG EAS_U32 #endif /* GUID struct (call it DLSID in case GUID is defined elsewhere) */ typedef struct { EAS_U32 Data1; EAS_U16 Data2; EAS_U16 Data3; EAS_U8 Data4[8]; } DLSID; #define DEFINE_DLSID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const DLSID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } /*------------------------------------ * defines *------------------------------------ */ /* maximum sample memory for DLS query support */ #ifndef MAX_DLS_MEMORY #define MAX_DLS_MEMORY 65536 #endif /* size of conditional chunk stack */ #ifndef CDL_STACK_SIZE #define CDL_STACK_SIZE 8 #endif /* size of read buffer for sample conversion */ #ifndef SAMPLE_CONVERT_CHUNK_SIZE #define SAMPLE_CONVERT_CHUNK_SIZE 32 #endif #define ZERO_TIME_IN_CENTS -32768 /* Pan calculation macros */ #define PAN_CONVERSION_FACTOR 4129 #define MAX_PAN_VALUE 63 #define MIN_PAN_VALUE -63 /* multiplier to convert time cents to 10-bit fraction log for EAS_LogToLinear16 */ #define TIME_CENTS_TO_LOG2 27962 /* conversion factor sustain level from percent to exponent for LogToLinear16 */ #define SUSTAIN_LOG_CONVERSION_FACTOR 536871 #define SUSTAIN_LOG_CONVERSION_SHIFT 15 /* conversion factor sustain level from percent to EG full scale */ #define SUSTAIN_LINEAR_CONVERSION_FACTOR 1073709 /* conversion factor to convert frame period to decay rate */ #define DECAY_CONVERSION_FACTOR -16 /*---------------------------------------------------------------------------- * These macros define the various characteristics of the defined sample rates *---------------------------------------------------------------------------- * DLS_ATTACK_TIME_CONVERT log offset for conversion from time cents to attack rate * DLS_LFO_FREQUENCY_CONVERT pitch-cents offset for LFO frequency conversion *---------------------------------------------------------------------------- */ #if defined (_SAMPLE_RATE_8000) #define DLS_RATE_CONVERT -9559 #define DLS_LFO_FREQUENCY_CONVERT 5921 #elif defined (_SAMPLE_RATE_16000) #define DLS_RATE_CONVERT -9559 #define DLS_LFO_FREQUENCY_CONVERT 5921 #elif defined (_SAMPLE_RATE_20000) #define DLS_RATE_CONVERT -8745 #define DLS_LFO_FREQUENCY_CONVERT 5108 #elif defined (_SAMPLE_RATE_22050) #define DLS_RATE_CONVERT -8914 #define DLS_LFO_FREQUENCY_CONVERT 5277 #elif defined (_SAMPLE_RATE_24000) #define DLS_RATE_CONVERT -9061 #define DLS_LFO_FREQUENCY_CONVERT 5423 #elif defined (_SAMPLE_RATE_32000) #define DLS_RATE_CONVERT -9559 #define DLS_LFO_FREQUENCY_CONVERT 5921 #elif defined (_SAMPLE_RATE_44100) #define DLS_RATE_CONVERT -8914 #define DLS_LFO_FREQUENCY_CONVERT 5277 #elif defined (_SAMPLE_RATE_48000) #define DLS_RATE_CONVERT -9061 #define DLS_LFO_FREQUENCY_CONVERT 5423 #else #error "_SAMPLE_RATE_XXXXX must be defined to valid rate" #endif /* * FILTER_Q_CONVERSION_FACTOR convers the 0.1dB steps in the DLS * file to our internal 0.75 dB steps. The value is calculated * as follows: * * 32768 / (10 * ) * * FILTER_RESONANCE_NUM_ENTRIES is the number of entries in the table */ #define FILTER_Q_CONVERSION_FACTOR 4369 #define FILTER_RESONANCE_NUM_ENTRIES 31 /* * Multiplier to convert DLS gain units (10ths of a dB) to a * power-of-two exponent for conversion to linear gain using our * piece-wise linear approximator. Note that we ignore the lower * 16-bits of the DLS gain value. The result is a 10-bit fraction * that works with the EAS_LogToLinear16 function. * * DLS_GAIN_FACTOR = (2^18) / (200 * log10(2)) */ #define DLS_GAIN_FACTOR 4354 #define DLS_GAIN_SHIFT 8 /* * Reciprocal of 10 for quick divide by 10's * * DLS_GAIN_FACTOR = (2^18) / (200 * log10(2)) */ #define DLS_DIV_10_FACTOR 3277 #define DLS_DIV_10_SHIFT 16 /* * Multiplier to convert DLS time cents units to a power-of-two * exponent for conversion to absolute time units using our * piece-wise linear approximator. * * DLS_TIME_FACTOR = (2^22) / 1200 */ #define DLS_TIME_FACTOR 3495 #define DLS_TIME_SHIFT 22 /* LFO limits */ #define MAX_LFO_FREQUENCY_IN_HERTZ 20 #define MIN_LFO_FREQUENCY_IN_HERTZ 0.1 #define MAX_LFO_FREQUENCY_IN_PITCHCENTS 1549 #define MIN_LFO_FREQUENCY_IN_PITCHCENTS -7624 #define MAX_LFO_AMPLITUDE_DEPTH 12 /* in dB, DLS2.1 p 31*/ #define MIN_LFO_AMPLITUDE_DEPTH -12 /* in dB, DLS2.1 p 31*/ /* add to pitch cents before pow(2.0, n) to convert to frequency */ #define ABSOLUTE_PITCH_BIAS 238395828 #define A5_PITCH_OFFSET 6900 /* CHUNK_TYPE is a macro that converts the 4 input args into a 32-bit int where argument a is placed at the MSB location and argument d is placed at the LSB location. This is useful for determining the DLS chunk types */ #define CHUNK_TYPE(a,b,c,d) ( \ ( ((EAS_U32)(a) & 0xFF) << 24 ) \ + ( ((EAS_U32)(b) & 0xFF) << 16 ) \ + ( ((EAS_U32)(c) & 0xFF) << 8 ) \ + ( ((EAS_U32)(d) & 0xFF) ) ) #define CHUNK_RIFF CHUNK_TYPE('R','I','F','F') #define CHUNK_DLS CHUNK_TYPE('D','L','S',' ') #define CHUNK_CDL CHUNK_TYPE('c','d','l',' ') #define CHUNK_VERS CHUNK_TYPE('v','e','r','s') #define CHUNK_DLID CHUNK_TYPE('d','l','i','d') #define CHUNK_LIST CHUNK_TYPE('L','I','S','T') #define CHUNK_COLH CHUNK_TYPE('c','o','l','h') #define CHUNK_LINS CHUNK_TYPE('l','i','n','s') #define CHUNK_PTBL CHUNK_TYPE('p','t','b','l') #define CHUNK_WVPL CHUNK_TYPE('w','v','p','l') #define CHUNK_INFO CHUNK_TYPE('I','N','F','O') #define CHUNK_INAM CHUNK_TYPE('I','N','A','M') #define CHUNK_INS CHUNK_TYPE('i','n','s',' ') #define CHUNK_INSH CHUNK_TYPE('i','n','s','h') #define CHUNK_LRGN CHUNK_TYPE('l','r','g','n') #define CHUNK_RGN CHUNK_TYPE('r','g','n',' ') #define CHUNK_RGN2 CHUNK_TYPE('r','g','n','2') #define CHUNK_RGNH CHUNK_TYPE('r','g','n','h') #define CHUNK_WSMP CHUNK_TYPE('w','s','m','p') #define CHUNK_WLNK CHUNK_TYPE('w','l','n','k') #define CHUNK_LART CHUNK_TYPE('l','a','r','t') #define CHUNK_LAR2 CHUNK_TYPE('l','a','r','2') #define CHUNK_ART1 CHUNK_TYPE('a','r','t','1') #define CHUNK_ART2 CHUNK_TYPE('a','r','t','2') #define CHUNK_WAVE CHUNK_TYPE('w','a','v','e') #define CHUNK_FMT CHUNK_TYPE('f','m','t',' ') #define CHUNK_DATA CHUNK_TYPE('d','a','t','a') #define CHUNK_DMPR CHUNK_TYPE('d','m','p','r') #define WAVE_FORMAT_PCM 0x0001 /* Microsoft PCM format, see DLS2.1 p60 */ #define WAVE_FORMAT_EXTENSIBLE 0xffff /* defines for wave table structures */ /* initialize each articulation structure to a harmless state */ /* change art values after we've determined EAS internals */ #define DEFAULT_DLS_FILTER_CUTOFF_FREQUENCY 0x7FFF /* DLS2.1, p 31 means leave filter off */ /**********/ /* define the waves that we expect to generate instead of store */ /* NOTE: our comparison routine converts the input string to lowercase, so the following comparison values should all be in lowercase. */ #define STRING_NOISE "noise" /*------------------------------------ * type definitions *------------------------------------ */ #ifdef _STANDALONE_CONVERTER typedef struct s_dls_params { EAS_INT sampleRate; EAS_INT samplesPerFrame; EAS_INT bitDepth; double ditherLevel; double ditherFilterCoeff; EAS_BOOL compatibility; EAS_BOOL encodeADPCM; } S_DLS_PARAMS; #endif /* function prototypes */ EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, S_DLS **pDLS); EAS_RESULT DLSCleanup (EAS_HW_DATA_HANDLE hwInstData, S_DLS *pDLS); void DLSAddRef (S_DLS *pDLS); EAS_I16 ConvertDelay (EAS_I32 timeCents); EAS_I16 ConvertRate (EAS_I32 timeCents); #ifdef _STANDALONE_CONVERTER void DLSConvParams (S_DLS_PARAMS *pParams, EAS_BOOL set); #endif #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/jet.c0000644000000000000000000000013214200302440025027 xustar0030 mtime=1644266784.809324171 30 atime=1644266785.189324413 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/jet.c0000644000175000001440000011733214200302440025617 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * jet.c * * Contents and purpose: * Implementation for JET sound engine * * Copyright (c) 2006 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *---------------------------------------------------------------------------- * Revision Control: * $Revision: 563 $ * $Date: 2007-02-13 20:26:23 -0800 (Tue, 13 Feb 2007) $ *---------------------------------------------------------------------------- */ //#define LOG_NDEBUG 0 #define LOG_TAG "JET_C" //#define DEBUG_JET #include "eas_data.h" #include "eas_smf.h" #include "jet_data.h" #include "eas_host.h" #include "eas_report.h" /* default configuration */ static const S_JET_CONFIG jetDefaultConfig = { JET_EVENT_APP_LOW, JET_EVENT_APP_HIGH }; /* function prototypes */ extern EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value); extern EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream); extern EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_DLSLIB_HANDLE *ppDLS); /*---------------------------------------------------------------------------- * JET_ParseEvent() *---------------------------------------------------------------------------- * Returns current status *---------------------------------------------------------------------------- */ EAS_PUBLIC void JET_ParseEvent (EAS_U32 event, S_JET_EVENT *pEvent) { pEvent->segment = (EAS_U8) ((event & JET_EVENT_SEG_MASK) >> JET_EVENT_SEG_SHIFT); pEvent->track = (EAS_U8) ((event & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT); pEvent->channel = (EAS_U8) ((event & JET_EVENT_CHAN_MASK) >> JET_EVENT_CHAN_SHIFT); pEvent->controller = (EAS_U8) ((event & JET_EVENT_CTRL_MASK) >> JET_EVENT_CTRL_SHIFT); pEvent->value = (EAS_U8) (event & JET_EVENT_VAL_MASK); } #ifdef DEBUG_JET /*---------------------------------------------------------------------------- * JET_DumpEvent *---------------------------------------------------------------------------- * Advances queue read/write index *---------------------------------------------------------------------------- */ static void JET_DumpEvent (const char *procName, EAS_U32 event) { S_JET_EVENT sEvent; JET_ParseEvent(event, &sEvent); { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "%s: SegID=%d, TrkID=%d, channel=%d, ctrl=%d, val=%d\n", procName, sEvent.segment, sEvent.track, sEvent.channel, sEvent.controller, sEvent.value); */ } } #endif /*---------------------------------------------------------------------------- * JET_IncQueueIndex *---------------------------------------------------------------------------- * Advances queue read/write index *---------------------------------------------------------------------------- */ EAS_INLINE EAS_U8 JET_IncQueueIndex (EAS_U8 index, EAS_U8 queueSize) { if (++index == queueSize) index = 0; return index; } /*---------------------------------------------------------------------------- * JET_WriteQueue *---------------------------------------------------------------------------- * Save event to queue *---------------------------------------------------------------------------- */ EAS_INLINE void JET_WriteQueue (EAS_U32 *pEventQueue, EAS_U8 *pWriteIndex, EAS_U8 readIndex, EAS_U8 queueSize, EAS_U32 event) { EAS_U8 temp; /* check for queue overflow */ temp = JET_IncQueueIndex(*pWriteIndex, queueSize); if (temp == readIndex) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "JET_Event: Event queue overflow --- event ignored!\n"); */ } return; } /* save in queue and advance write index */ pEventQueue[*pWriteIndex] = event; *pWriteIndex = temp; } /*---------------------------------------------------------------------------- * JET_ReadQueue *---------------------------------------------------------------------------- * Read event to queue *---------------------------------------------------------------------------- */ EAS_INLINE EAS_BOOL JET_ReadQueue (EAS_U32 *pEventQueue, EAS_U8 *pReadIndex, EAS_U8 writeIndex, EAS_U8 queueSize, EAS_U32 *pEvent) { /* check for empty queue */ if (*pReadIndex == writeIndex) return EAS_FALSE; /* save in queue and advance write index */ *pEvent = pEventQueue[*pReadIndex]; *pReadIndex = JET_IncQueueIndex(*pReadIndex, queueSize); return EAS_TRUE; } /*---------------------------------------------------------------------------- * JET_NextSegment *---------------------------------------------------------------------------- * Advances segment number *---------------------------------------------------------------------------- */ EAS_INLINE EAS_INT JET_NextSegment (EAS_INT seg_num) { if (++seg_num == SEG_QUEUE_DEPTH) seg_num = 0; return seg_num; } /*---------------------------------------------------------------------------- * JET_PrepareSegment() *---------------------------------------------------------------------------- * Prepare a segment for playback *---------------------------------------------------------------------------- */ static EAS_RESULT JET_PrepareSegment (EAS_DATA_HANDLE easHandle, EAS_I32 queueNum) { EAS_RESULT result; S_JET_SEGMENT *p; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_PrepareSegment: %d\n", queueNum); */ } p = &easHandle->jetHandle->segQueue[queueNum]; result = EAS_Prepare(easHandle, p->streamHandle); if (result != EAS_SUCCESS) return result; /* pause segment - must be triggered by play or end of previous segment */ result = EAS_Pause(easHandle, p->streamHandle); if (result != EAS_SUCCESS) return result; p->state = JET_STATE_READY; /* set calback data */ result = EAS_IntSetStrmParam(easHandle, p->streamHandle, PARSER_DATA_JET_CB, queueNum); if (result != EAS_SUCCESS) return result; /* set DLS collection */ if (p->libNum >= 0) { result = EAS_IntSetStrmParam(easHandle, p->streamHandle, PARSER_DATA_DLS_COLLECTION, (EAS_I32) easHandle->jetHandle->libHandles[p->libNum]); if (result != EAS_SUCCESS) return result; } /* set transposition */ if (p->transpose) { result = EAS_SetTransposition(easHandle, p->streamHandle, p->transpose); if (result != EAS_SUCCESS) return result; } return result; } /*---------------------------------------------------------------------------- * JET_StartPlayback() *---------------------------------------------------------------------------- * Start segment playback *---------------------------------------------------------------------------- */ static EAS_RESULT JET_StartPlayback (EAS_DATA_HANDLE easHandle, EAS_I32 queueNum) { EAS_RESULT result = EAS_SUCCESS; S_JET_SEGMENT *pSeg; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_StartPlayback %d\n", queueNum); */ } /* if next segment is queued, start playback */ pSeg = &easHandle->jetHandle->segQueue[queueNum]; if (pSeg->streamHandle != NULL) { result = EAS_Resume(easHandle, pSeg->streamHandle); easHandle->jetHandle->segQueue[queueNum].state = JET_STATE_PLAYING; /* set mute flags */ if ((result == EAS_SUCCESS) && (pSeg->muteFlags != 0)) result = EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags); } return result; } /*---------------------------------------------------------------------------- * JET_CloseSegment *---------------------------------------------------------------------------- * Closes stream associated with a segment *---------------------------------------------------------------------------- */ EAS_INLINE EAS_INT JET_CloseSegment (EAS_DATA_HANDLE easHandle, EAS_INT queueNum) { EAS_RESULT result; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_CloseSegment %d\n", queueNum); */ } /* close the segment */ result = EAS_CloseFile(easHandle, easHandle->jetHandle->segQueue[queueNum].streamHandle); if (result != EAS_SUCCESS) return result; easHandle->jetHandle->segQueue[queueNum].streamHandle = NULL; easHandle->jetHandle->segQueue[queueNum].state = JET_STATE_CLOSED; easHandle->jetHandle->numQueuedSegments--; return result; } /*---------------------------------------------------------------------------- * JetParseInfoChunk() *---------------------------------------------------------------------------- * Parses the JET info chunk *---------------------------------------------------------------------------- */ static EAS_RESULT JetParseInfoChunk (EAS_DATA_HANDLE easHandle, EAS_I32 pos, EAS_I32 chunkSize) { EAS_RESULT result; EAS_U32 infoType; EAS_U32 temp; /* offset to data */ result = EAS_HWFileSeek(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos); if (result != EAS_SUCCESS) return result; /* read the entire chunk */ result = EAS_SUCCESS; while ((result == EAS_SUCCESS) && (chunkSize > 0)) { /* get info infoType */ result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &infoType, EAS_TRUE); if (result != EAS_SUCCESS) break; /* get info field */ result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &temp, EAS_FALSE); if (result == EAS_SUCCESS) switch (infoType) { case INFO_NUM_SMF_CHUNKS: if (temp >= JET_MAX_SEGMENTS) { return EAS_ERROR_INCOMPATIBLE_VERSION; } easHandle->jetHandle->numSegments = (EAS_U8) temp; break; case INFO_NUM_DLS_CHUNKS: if (temp >= JET_MAX_DLS_COLLECTIONS) { return EAS_ERROR_INCOMPATIBLE_VERSION; } easHandle->jetHandle->numLibraries = (EAS_U8) temp; break; case INFO_JET_VERSION: /* check major version number */ if ((temp & 0xff000000) != (JET_VERSION & 0xff000000)) return EAS_ERROR_INCOMPATIBLE_VERSION; break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized JET info type 0x%08x", infoType); */ } break; } chunkSize -= 8; } /* allocate pointers for chunks to follow */ return result; } /*---------------------------------------------------------------------------- * JET_OpenFile() *---------------------------------------------------------------------------- * Opens a JET content file for playback *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_OpenFile (EAS_DATA_HANDLE easHandle, EAS_FILE_LOCATOR locator) { EAS_RESULT result; EAS_U32 chunkType; EAS_I32 pos; EAS_I32 chunkSize; EAS_INT smfChunkNum; EAS_INT dlsChunkNum; EAS_I32 dataSize = 0; /* make lint happy */ /* make sure that we don't have an open file */ if (easHandle->jetHandle->jetFileHandle != NULL) return EAS_ERROR_FILE_ALREADY_OPEN; /* open the media file */ result = EAS_HWOpenFile(easHandle->hwInstData, locator, &easHandle->jetHandle->jetFileHandle, EAS_FILE_READ); if (result != EAS_SUCCESS) return result; /* check header */ result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkType, EAS_TRUE); if (result == EAS_SUCCESS) { if (chunkType != JET_HEADER_TAG) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "File is not JET format\n"); */ } result = EAS_ERROR_UNRECOGNIZED_FORMAT; } } /* get the file data size */ if (result == EAS_SUCCESS) result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &dataSize, EAS_FALSE); /* parse through the file to find contents */ smfChunkNum = dlsChunkNum = 0; pos = chunkSize = 8; while ((result == EAS_SUCCESS) && (pos < dataSize)) { /* offset to chunk data */ result = EAS_HWFileSeek(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos); if (result != EAS_SUCCESS) break; /* get chunk size and type */ result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkType, EAS_TRUE); if (result != EAS_SUCCESS) break; result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkSize, EAS_FALSE); if (result != EAS_SUCCESS) break; pos += 8; switch (chunkType) { case JET_INFO_CHUNK: result = JetParseInfoChunk(easHandle, pos, chunkSize); break; case JET_SMF_CHUNK: if (smfChunkNum < easHandle->jetHandle->numSegments) easHandle->jetHandle->segmentOffsets[smfChunkNum++] = pos; else { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring extraneous SMF chunk"); */ } break; case JET_DLS_CHUNK: if (dlsChunkNum < easHandle->jetHandle->numLibraries) result = DLSParser(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos, &easHandle->jetHandle->libHandles[dlsChunkNum++]); else { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring extraneous DLS chunk"); */ } break; case JET_APP_DATA_CHUNK: easHandle->jetHandle->appDataOffset = pos; easHandle->jetHandle->appDataSize = chunkSize; break; case INFO_JET_COPYRIGHT: break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized JET chunk type 0x%08x", chunkType); */ } break; } /* offset to next chunk */ pos += chunkSize; } /* close file if something went wrong */ if (result != EAS_SUCCESS) EAS_HWCloseFile(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle); return result; } /*---------------------------------------------------------------------------- * JET_GetAppData() *---------------------------------------------------------------------------- * Returns location and size of application data in the JET file *---------------------------------------------------------------------------- */ EAS_RESULT JET_GetAppData (EAS_DATA_HANDLE easHandle, EAS_I32 *pAppDataOffset, EAS_I32 *pAppDataSize) { /* check for app chunk */ if (easHandle->jetHandle->appDataSize == 0) { *pAppDataOffset = *pAppDataSize = 0; return EAS_FAILURE; } /* return app data */ *pAppDataOffset = easHandle->jetHandle->appDataOffset; *pAppDataSize = easHandle->jetHandle->appDataSize; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * JET_CloseFile() *---------------------------------------------------------------------------- * Closes a JET content file and releases associated resources *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_CloseFile (EAS_DATA_HANDLE easHandle) { EAS_INT index; EAS_RESULT result = EAS_SUCCESS; /* close open streams */ for (index = 0; index < SEG_QUEUE_DEPTH; index++) { if (easHandle->jetHandle->segQueue[index].streamHandle != NULL) { result = JET_CloseSegment(easHandle, index); if (result != EAS_SUCCESS) break; } } /* close the main file handle */ if ((result == EAS_SUCCESS) && (easHandle->jetHandle->jetFileHandle != NULL)) { result = EAS_HWCloseFile(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle); if (result == EAS_SUCCESS) easHandle->jetHandle->jetFileHandle = NULL; } return result; } /*---------------------------------------------------------------------------- * JET_Init() *---------------------------------------------------------------------------- * Initializes the JET library, allocates memory, etc. Call * JET_Shutdown to de-allocate memory. *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Init (EAS_DATA_HANDLE easHandle, const S_JET_CONFIG *pConfig, EAS_INT configSize) { S_JET_DATA *pJet; EAS_U8 flags = 0; /* sanity check */ if (easHandle == NULL) return EAS_ERROR_HANDLE_INTEGRITY; if (easHandle->jetHandle != NULL) return EAS_ERROR_FEATURE_ALREADY_ACTIVE; if (pConfig == NULL) pConfig = &jetDefaultConfig; /* allocate the JET data object */ pJet = EAS_HWMalloc(easHandle->hwInstData, sizeof(S_JET_DATA)); if (pJet == NULL) return EAS_ERROR_MALLOC_FAILED; /* initialize JET data structure */ EAS_HWMemSet(pJet, 0, sizeof(S_JET_DATA)); easHandle->jetHandle = pJet; pJet->flags = flags; /* copy config data */ if (configSize > (EAS_INT) sizeof(S_JET_CONFIG)) configSize = sizeof(S_JET_CONFIG); EAS_HWMemCpy(&pJet->config, pConfig, configSize); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * JET_Shutdown() *---------------------------------------------------------------------------- * Frees any memory used by the JET library *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Shutdown (EAS_DATA_HANDLE easHandle) { EAS_RESULT result; int i; /* close any open files */ result = JET_CloseFile(easHandle); /* free allocated data */ for(i = 0 ; i < easHandle->jetHandle->numLibraries ; i++) { if(easHandle->jetHandle->libHandles[i] != NULL) { EAS_HWFree(easHandle->hwInstData, easHandle->jetHandle->libHandles[i]); easHandle->jetHandle->libHandles[i] = NULL; } } EAS_HWFree(easHandle->hwInstData, easHandle->jetHandle); easHandle->jetHandle = NULL; return result; } /*---------------------------------------------------------------------------- * JET_Status() *---------------------------------------------------------------------------- * Returns current status *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Status (EAS_DATA_HANDLE easHandle, S_JET_STATUS *pStatus) { S_JET_SEGMENT *pSeg; pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment]; if (pSeg->streamHandle != NULL) { pStatus->currentUserID = pSeg->userID; pStatus->segmentRepeatCount = pSeg->repeatCount; } else { pStatus->currentUserID = -1; pStatus->segmentRepeatCount = 0; } pStatus->paused = !(easHandle->jetHandle->flags & JET_FLAGS_PLAYING); pStatus->numQueuedSegments = easHandle->jetHandle->numQueuedSegments; pStatus->currentPlayingSegment = easHandle->jetHandle->playSegment; pStatus->currentQueuedSegment = easHandle->jetHandle->queueSegment; if (pSeg->streamHandle != NULL) { EAS_RESULT result; EAS_I32 location ; if ((result = EAS_GetLocation(easHandle, pSeg->streamHandle, &location)) == EAS_SUCCESS) if(location != 0) { pStatus->location = location; } } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * JET_GetEvent() *---------------------------------------------------------------------------- * Checks for application events *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_BOOL JET_GetEvent (EAS_DATA_HANDLE easHandle, EAS_U32 *pEventRaw, S_JET_EVENT *pEvent) { EAS_U32 jetEvent; EAS_BOOL gotEvent; /* process event queue */ gotEvent = JET_ReadQueue(easHandle->jetHandle->appEventQueue, &easHandle->jetHandle->appEventQueueRead, easHandle->jetHandle->appEventQueueWrite, APP_EVENT_QUEUE_SIZE, &jetEvent); if (gotEvent) { if (pEventRaw != NULL) *pEventRaw = jetEvent; if (pEvent != NULL) JET_ParseEvent(jetEvent, pEvent); } return gotEvent; } /*---------------------------------------------------------------------------- * JET_QueueSegment() *---------------------------------------------------------------------------- * Queue a segment for playback *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_QueueSegment (EAS_DATA_HANDLE easHandle, EAS_INT segmentNum, EAS_INT libNum, EAS_INT repeatCount, EAS_INT transpose, EAS_U32 muteFlags, EAS_U8 userID) { EAS_FILE_HANDLE fileHandle; EAS_RESULT result; S_JET_SEGMENT *p; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_QueueSegment segNum=%d, queue=%d\n", segmentNum, easHandle->jetHandle->queueSegment); */ } /* make sure it's a valid segment */ if (segmentNum >= easHandle->jetHandle->numSegments) return EAS_ERROR_PARAMETER_RANGE; /* make sure it's a valid DLS */ if (libNum >= easHandle->jetHandle->numLibraries) return EAS_ERROR_PARAMETER_RANGE; /* check to see if queue is full */ p = &easHandle->jetHandle->segQueue[easHandle->jetHandle->queueSegment]; if (p->streamHandle != NULL) return EAS_ERROR_QUEUE_IS_FULL; /* initialize data */ p->userID = userID; p->repeatCount = (EAS_I16) repeatCount; p->transpose = (EAS_I8) transpose; p->libNum = (EAS_I8) libNum; p->muteFlags = muteFlags; p->state = JET_STATE_CLOSED; /* open the file */ result = EAS_OpenJETStream(easHandle, easHandle->jetHandle->jetFileHandle, easHandle->jetHandle->segmentOffsets[segmentNum], &p->streamHandle); if (result != EAS_SUCCESS) return result; p->state = JET_STATE_OPEN; /* if less than SEG_QUEUE_DEPTH segments queued up, prepare file for playback */ if (++easHandle->jetHandle->numQueuedSegments < SEG_QUEUE_DEPTH) { result = JET_PrepareSegment(easHandle, easHandle->jetHandle->queueSegment); if (result != EAS_SUCCESS) return result; } /* create duplicate file handle */ result = EAS_HWDupHandle(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &fileHandle); if (result != EAS_SUCCESS) return result; easHandle->jetHandle->jetFileHandle = fileHandle; easHandle->jetHandle->queueSegment = (EAS_U8) JET_NextSegment(easHandle->jetHandle->queueSegment); return result; } /*---------------------------------------------------------------------------- * JET_Play() *---------------------------------------------------------------------------- * Starts playback of the file *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Play (EAS_DATA_HANDLE easHandle) { EAS_RESULT result; EAS_INT index; EAS_INT count = 0; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Play\n"); */ } /* sanity check */ if (easHandle->jetHandle->flags & JET_FLAGS_PLAYING) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* resume all paused streams */ for (index = 0; index < SEG_QUEUE_DEPTH; index++) { if (((index == easHandle->jetHandle->playSegment) && (easHandle->jetHandle->segQueue[index].state == JET_STATE_READY)) || (easHandle->jetHandle->segQueue[index].state == JET_STATE_PAUSED)) { result = JET_StartPlayback(easHandle, index); if (result != EAS_SUCCESS) return result; count++; } } /* if no streams are playing, return error */ if (!count) return EAS_ERROR_QUEUE_IS_EMPTY; easHandle->jetHandle->flags |= JET_FLAGS_PLAYING; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * JET_Pause() *---------------------------------------------------------------------------- * Pauses playback of the file *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Pause (EAS_DATA_HANDLE easHandle) { EAS_RESULT result; EAS_INT index; EAS_INT count = 0; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Pause\n"); */ } /* sanity check */ if ((easHandle->jetHandle->flags & JET_FLAGS_PLAYING) == 0) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* pause all playing streams */ for (index = 0; index < SEG_QUEUE_DEPTH; index++) { if (easHandle->jetHandle->segQueue[index].state == JET_STATE_PLAYING) { result = EAS_Pause(easHandle, easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].streamHandle); if (result != EAS_SUCCESS) return result; easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].state = JET_STATE_PAUSED; count++; } } /* if no streams are paused, return error */ if (!count) return EAS_ERROR_QUEUE_IS_EMPTY; easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * JET_SetMuteFlags() *---------------------------------------------------------------------------- * Change the state of the mute flags *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_SetMuteFlags (EAS_DATA_HANDLE easHandle, EAS_U32 muteFlags, EAS_BOOL sync) { S_JET_SEGMENT *pSeg; /* get pointer to current segment */ pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment]; /* unsynchronized mute, set flags and return */ if (!sync) { if (pSeg->streamHandle == NULL) return EAS_ERROR_QUEUE_IS_EMPTY; pSeg->muteFlags = muteFlags; return EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) muteFlags); } /* check for valid stream state */ if (pSeg->state == JET_STATE_CLOSED) return EAS_ERROR_QUEUE_IS_EMPTY; /* save mute flags */ pSeg->muteFlags = muteFlags; /* if repeating segment, set mute update flag */ if (sync) pSeg->flags |= JET_SEG_FLAG_MUTE_UPDATE; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * JET_SetMuteFlag() *---------------------------------------------------------------------------- * Change the state of a single mute flag *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_SetMuteFlag (EAS_DATA_HANDLE easHandle, EAS_INT trackNum, EAS_BOOL muteFlag, EAS_BOOL sync) { S_JET_SEGMENT *pSeg; EAS_U32 trackMuteFlag; /* setup flag */ if ((trackNum < 0) || (trackNum > 31)) return EAS_ERROR_PARAMETER_RANGE; trackMuteFlag = (1 << trackNum); /* get pointer to current segment */ pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment]; /* unsynchronized mute, set flags and return */ if (!sync) { if (pSeg->streamHandle == NULL) return EAS_ERROR_QUEUE_IS_EMPTY; if (muteFlag) pSeg->muteFlags |= trackMuteFlag; else pSeg->muteFlags &= ~trackMuteFlag; return EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags); } /* check for valid stream state */ if (pSeg->state == JET_STATE_CLOSED) return EAS_ERROR_QUEUE_IS_EMPTY; /* save mute flags and set mute update flag */ if (muteFlag) pSeg->muteFlags |= trackMuteFlag; else pSeg->muteFlags &= ~trackMuteFlag; pSeg->flags |= JET_SEG_FLAG_MUTE_UPDATE; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * JET_TriggerClip() *---------------------------------------------------------------------------- * Unmute a track and then mute it when it is complete. If a clip * is already playing, change mute event to a trigger event. The * JET_Event function will not mute the clip, but will allow it * to continue playing through the next clip. * * NOTE: We use bit 7 to indicate an entry in the queue. For a * small queue, it is cheaper in both memory and CPU cycles to * scan the entire queue for non-zero events than keep enqueue * and dequeue indices. *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_TriggerClip (EAS_DATA_HANDLE easHandle, EAS_INT clipID) { EAS_INT i; EAS_INT index = -1; /* check for valid clipID */ if ((clipID < 0) || (clipID > 63)) return EAS_ERROR_PARAMETER_RANGE; /* set active flag */ clipID |= JET_CLIP_ACTIVE_FLAG; /* Reverse the search so that we get the first empty element */ for (i = JET_MUTE_QUEUE_SIZE-1; i >= 0 ; i--) { if (easHandle->jetHandle->muteQueue[i] == clipID) { index = i; break; } if (easHandle->jetHandle->muteQueue[i] == 0) index = i; } if (index < 0) return EAS_ERROR_QUEUE_IS_FULL; easHandle->jetHandle->muteQueue[index] = (EAS_U8) clipID | JET_CLIP_TRIGGER_FLAG; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * JET_Process() *---------------------------------------------------------------------------- * Called during EAS_Render to process stream states *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Process (EAS_DATA_HANDLE easHandle) { S_JET_SEGMENT *pSeg; EAS_STATE state; EAS_INT index; EAS_INT playIndex; EAS_RESULT result = EAS_SUCCESS; EAS_BOOL endOfLoop = EAS_FALSE; EAS_BOOL startNextSegment = EAS_FALSE; EAS_BOOL prepareNextSegment = EAS_FALSE; EAS_U32 jetEvent; /* process event queue */ while (JET_ReadQueue(easHandle->jetHandle->jetEventQueue, &easHandle->jetHandle->jetEventQueueRead, easHandle->jetHandle->jetEventQueueWrite, JET_EVENT_QUEUE_SIZE, &jetEvent)) { S_JET_EVENT event; #ifdef DEBUG_JET JET_DumpEvent("JET_Process", jetEvent); #endif JET_ParseEvent(jetEvent, &event); /* check for end of loop */ if ((event.controller == JET_EVENT_MARKER) && (event.value == JET_MARKER_LOOP_END) && (easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].streamHandle != NULL)) endOfLoop = EAS_TRUE; } /* check state of all streams */ index = playIndex = easHandle->jetHandle->playSegment; for (;;) { pSeg = &easHandle->jetHandle->segQueue[index]; if (pSeg->state != JET_STATE_CLOSED) { /* get playback state */ result = EAS_State(easHandle, pSeg->streamHandle, &state); if (result != EAS_SUCCESS) return result; /* process state */ switch (pSeg->state) { /* take action if this segment is stopping */ case JET_STATE_PLAYING: if (endOfLoop || (state == EAS_STATE_STOPPING) || (state == EAS_STATE_STOPPED)) { /* handle repeats */ if (pSeg->repeatCount != 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Render repeating segment %d\n", index); */ } result = EAS_Locate(easHandle, pSeg->streamHandle, 0, EAS_FALSE); if (result != EAS_SUCCESS) return result; if (pSeg->repeatCount > 0) pSeg->repeatCount--; /* update mute flags if necessary */ if (pSeg->flags & JET_SEG_FLAG_MUTE_UPDATE) { result = EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags); if (result != EAS_SUCCESS) return result; pSeg->flags &= ~JET_SEG_FLAG_MUTE_UPDATE; } } /* no repeat, start next segment */ else { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Render stopping queue %d\n", index); */ } startNextSegment = EAS_TRUE; pSeg->state = JET_STATE_STOPPING; easHandle->jetHandle->playSegment = (EAS_U8) JET_NextSegment(index); } } break; /* if playback has stopped, close the segment */ case JET_STATE_STOPPING: if (state == EAS_STATE_STOPPED) { result = JET_CloseSegment(easHandle, index); if (result != EAS_SUCCESS) return result; } break; case JET_STATE_READY: if (startNextSegment) { result = JET_StartPlayback(easHandle, index); if (result != EAS_SUCCESS) return result; startNextSegment = EAS_FALSE; prepareNextSegment = EAS_TRUE; } break; case JET_STATE_OPEN: if (prepareNextSegment) { result = JET_PrepareSegment(easHandle, index); if (result != EAS_SUCCESS) return result; prepareNextSegment = EAS_FALSE; } break; case JET_STATE_PAUSED: break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "JET_Render: Unexpected segment state %d\n", pSeg->state); */ } break; } } /* increment index */ index = JET_NextSegment(index); if (index == playIndex) break; } /* if out of segments, clear playing flag */ if (easHandle->jetHandle->numQueuedSegments == 0) easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING; return result; } /*---------------------------------------------------------------------------- * JET_Event() *---------------------------------------------------------------------------- * Called from MIDI parser when data of interest is received *---------------------------------------------------------------------------- */ void JET_Event (EAS_DATA_HANDLE easHandle, EAS_U32 segTrack, EAS_U8 channel, EAS_U8 controller, EAS_U8 value) { EAS_U32 event; if (easHandle->jetHandle == NULL) return; /* handle triggers */ if (controller == JET_EVENT_TRIGGER_CLIP) { S_JET_SEGMENT *pSeg; EAS_INT i; EAS_U32 muteFlag; for (i = 0; i < JET_MUTE_QUEUE_SIZE; i++) { /* search for event in queue */ if ((easHandle->jetHandle->muteQueue[i] & JET_CLIP_ID_MASK) == (value & JET_CLIP_ID_MASK)) { /* get segment pointer and mute flag */ pSeg = &easHandle->jetHandle->segQueue[segTrack >> JET_EVENT_SEG_SHIFT]; muteFlag = 1 << ((segTrack & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT); /* un-mute the track */ if ((easHandle->jetHandle->muteQueue[i] & JET_CLIP_TRIGGER_FLAG) && ((value & 0x40) > 0)) { pSeg->muteFlags &= ~muteFlag; easHandle->jetHandle->muteQueue[i] &= ~JET_CLIP_TRIGGER_FLAG; } /* mute the track */ else { EAS_U32 beforeMute ; beforeMute = pSeg->muteFlags ; pSeg->muteFlags |= muteFlag; if (beforeMute != pSeg->muteFlags) easHandle->jetHandle->muteQueue[i] = 0; } EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags); return; } } return; } /* generic event stuff */ event = (channel << JET_EVENT_CHAN_SHIFT) | (controller << JET_EVENT_CTRL_SHIFT) | value; /* write to app queue, translate queue index to segment number */ if ((controller >= easHandle->jetHandle->config.appEventRangeLow) && (controller <= easHandle->jetHandle->config.appEventRangeHigh)) { event |= easHandle->jetHandle->segQueue[(segTrack & JET_EVENT_SEG_MASK) >> JET_EVENT_SEG_SHIFT].userID << JET_EVENT_SEG_SHIFT; #ifdef DEBUG_JET JET_DumpEvent("JET_Event[app]", event); #endif JET_WriteQueue(easHandle->jetHandle->appEventQueue, &easHandle->jetHandle->appEventQueueWrite, easHandle->jetHandle->appEventQueueRead, APP_EVENT_QUEUE_SIZE, event); } /* write to JET queue */ else if ((controller >= JET_EVENT_LOW) && (controller <= JET_EVENT_HIGH)) { event |= segTrack; #ifdef DEBUG_JET JET_DumpEvent("JET_Event[jet]", event); #endif JET_WriteQueue(easHandle->jetHandle->jetEventQueue, &easHandle->jetHandle->jetEventQueueWrite, easHandle->jetHandle->jetEventQueueRead, JET_EVENT_QUEUE_SIZE, event); } } /*---------------------------------------------------------------------------- * JET_Clear_Queue() *---------------------------------------------------------------------------- * Clears the queue and stops play without a complete shutdown *---------------------------------------------------------------------------- */ EAS_RESULT JET_Clear_Queue(EAS_DATA_HANDLE easHandle) { EAS_INT index; EAS_RESULT result = EAS_SUCCESS; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Clear_Queue\n"); */ } /* pause all playing streams */ for (index = 0; index < SEG_QUEUE_DEPTH; index++) { if (easHandle->jetHandle->segQueue[index].state == JET_STATE_PLAYING) { result = EAS_Pause(easHandle, easHandle->jetHandle->segQueue[index].streamHandle); if (result != EAS_SUCCESS) return result; easHandle->jetHandle->segQueue[index].state = JET_STATE_PAUSED; } } /* close all streams */ for (index = 0; index < SEG_QUEUE_DEPTH; index++) { if (easHandle->jetHandle->segQueue[index].streamHandle != NULL) { result = JET_CloseSegment(easHandle, index); if (result != EAS_SUCCESS) return result; } } /* clear all clips */ for (index = 0; index < JET_MUTE_QUEUE_SIZE ; index++) { easHandle->jetHandle->muteQueue[index] = 0; } easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING; easHandle->jetHandle->playSegment = easHandle->jetHandle->queueSegment = 0; return result; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/jet_data.h0000644000000000000000000000013214200302440026025 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.189324413 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/jet_data.h0000644000175000001440000001410514200302440026607 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * jet_data.h * * Contents and purpose: * Internal data structures and interfaces for JET * * Copyright (c) 2006 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *---------------------------------------------------------------------------- * Revision Control: * $Revision: 554 $ * $Date: 2007-02-02 11:06:10 -0800 (Fri, 02 Feb 2007) $ *---------------------------------------------------------------------------- */ #ifndef _JET_DATA_H #define _JET_DATA_H #include "eas.h" #include "jet.h" /* maximum number of segments allowed in a JET file */ #ifndef JET_MAX_SEGMENTS #define JET_MAX_SEGMENTS 32 #endif /* maximum number of DLS collections allowed in a JET file */ #ifndef JET_MAX_DLS_COLLECTIONS #define JET_MAX_DLS_COLLECTIONS 4 #endif /* maximum number of JET events in internal queue */ #ifndef JET_EVENT_QUEUE_SIZE #define JET_EVENT_QUEUE_SIZE 32 #endif /* maximum number of JET events in application queue */ #ifndef APP_EVENT_QUEUE_SIZE #define APP_EVENT_QUEUE_SIZE 32 #endif /* maximum number of active mute events */ #ifndef JET_MUTE_QUEUE_SIZE #define JET_MUTE_QUEUE_SIZE 8 #endif /*---------------------------------------------------------------------------- * JET event definitions *---------------------------------------------------------------------------- */ #define JET_EVENT_APP_LOW 80 #define JET_EVENT_APP_HIGH 83 #define JET_EVENT_LOW 102 #define JET_EVENT_HIGH 119 #define JET_EVENT_MARKER 102 #define JET_EVENT_TRIGGER_CLIP 103 #define JET_MARKER_LOOP_END 0 #define JET_CLIP_ACTIVE_FLAG 0x80 #define JET_CLIP_TRIGGER_FLAG 0x40 #define JET_CLIP_ID_MASK 0x3f /*---------------------------------------------------------------------------- * JET file definitions *---------------------------------------------------------------------------- */ #define JET_TAG(a,b,c,d) (\ ( ((EAS_U32)(a) & 0xFF) << 24 ) \ + ( ((EAS_U32)(b) & 0xFF) << 16 ) \ + ( ((EAS_U32)(c) & 0xFF) << 8 ) \ + ( ((EAS_U32)(d) & 0xFF))) #define JET_VERSION 0x01000000 #define JET_HEADER_TAG JET_TAG('J','E','T',' ') #define JET_INFO_CHUNK JET_TAG('J','I','N','F') #define JET_SMF_CHUNK JET_TAG('J','S','M','F') #define JET_DLS_CHUNK JET_TAG('J','D','L','S') #define INFO_JET_COPYRIGHT JET_TAG('J','C','O','P') #define JET_APP_DATA_CHUNK JET_TAG('J','A','P','P') #define INFO_NUM_SMF_CHUNKS JET_TAG('S','M','F','#') #define INFO_NUM_DLS_CHUNKS JET_TAG('D','L','S','#') #define INFO_JET_VERSION JET_TAG('J','V','E','R') /*---------------------------------------------------------------------------- * S_JET_SEGMENT * * JET segment data *---------------------------------------------------------------------------- */ typedef struct s_jet_segment_tag { EAS_HANDLE streamHandle; EAS_U32 muteFlags; EAS_I16 repeatCount; EAS_U8 userID; EAS_I8 transpose; EAS_I8 libNum; EAS_U8 state; EAS_U8 flags; } S_JET_SEGMENT; /* S_JET_SEGMENT.state */ typedef enum { JET_STATE_CLOSED, JET_STATE_OPEN, JET_STATE_READY, JET_STATE_PLAYING, JET_STATE_PAUSED, JET_STATE_STOPPING } E_JET_SEGMENT_STATE; /* S_JEG_SEGMENT.flags */ #define JET_SEG_FLAG_MUTE_UPDATE 0x01 /*---------------------------------------------------------------------------- * S_JET_DATA * * Main JET data structure *---------------------------------------------------------------------------- */ #define SEG_QUEUE_DEPTH 3 typedef struct s_jet_data_tag { EAS_FILE_HANDLE jetFileHandle; S_JET_SEGMENT segQueue[SEG_QUEUE_DEPTH]; EAS_I32 segmentOffsets[JET_MAX_SEGMENTS]; EAS_I32 appDataOffset; EAS_I32 appDataSize; EAS_DLSLIB_HANDLE libHandles[JET_MAX_DLS_COLLECTIONS]; EAS_U32 jetEventQueue[JET_EVENT_QUEUE_SIZE]; EAS_U32 appEventQueue[APP_EVENT_QUEUE_SIZE]; S_JET_CONFIG config; EAS_U32 segmentTime; EAS_U8 muteQueue[JET_MUTE_QUEUE_SIZE]; EAS_U8 numSegments; EAS_U8 numLibraries; EAS_U8 flags; EAS_U8 playSegment; EAS_U8 queueSegment; EAS_U8 numQueuedSegments; EAS_U8 jetEventQueueRead; EAS_U8 jetEventQueueWrite; EAS_U8 appEventQueueRead; EAS_U8 appEventQueueWrite; } S_JET_DATA; /* flags for S_JET_DATA.flags */ #define JET_FLAGS_PLAYING 1 #define JET_EVENT_VAL_MASK 0x0000007f /* mask for value */ #define JET_EVENT_CTRL_MASK 0x00003f80 /* mask for controller */ #define JET_EVENT_CHAN_MASK 0x0003c000 /* mask for channel */ #define JET_EVENT_TRACK_MASK 0x00fc0000 /* mask for track number */ #define JET_EVENT_SEG_MASK 0xff000000 /* mask for segment ID */ #define JET_EVENT_CTRL_SHIFT 7 /* shift for controller number */ #define JET_EVENT_CHAN_SHIFT 14 /* shift to for MIDI channel */ #define JET_EVENT_TRACK_SHIFT 18 /* shift to get track ID to bit 0 */ #define JET_EVENT_SEG_SHIFT 24 /* shift to get segment ID to bit 0 */ /* prototype for callback function */ extern void JET_Event (EAS_DATA_HANDLE easHandle, EAS_U32 segTrack, EAS_U8 channel, EAS_U8 controller, EAS_U8 value); /* prototype for JET render function */ extern EAS_PUBLIC EAS_RESULT JET_Process (EAS_DATA_HANDLE easHandle); #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_ctype.h0000644000000000000000000000013214200302440026226 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.189324413 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_ctype.h0000644000175000001440000000310514200302440027006 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_ctype.h * * Contents and purpose: * This is a replacement for the CRT ctype.h functions. These * functions are currently ASCII only, but eventually, we will want * to support wide-characters for localization. * * Copyright (c) 2005 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 429 $ * $Date: 2006-10-19 23:50:15 -0700 (Thu, 19 Oct 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_CTYPE_H #define _EAS_CTYPE_H EAS_INLINE EAS_I8 IsDigit (EAS_I8 c) { return ((c >= '0') && (c <= '9')); } EAS_INLINE EAS_I8 IsSpace (EAS_I8 c) { return (((c >= 9) && (c <= 13)) || (c == ' ')); } EAS_INLINE EAS_I8 ToUpper (EAS_I8 c) { if ((c >= 'a') && (c <= 'z')) return c & ~0x20; else return c; } EAS_INLINE EAS_I8 ToLower (EAS_I8 c) { if ((c >= 'A') && (c <= 'Z')) return c |= 0x20; else return c; } #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_smfdata.h0000644000000000000000000000013214200302440026521 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.189324413 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_smfdata.h0000644000175000001440000000375114200302440027310 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_smfdata.h * * Contents and purpose: * SMF File Parser * * This file contains data definitions for the SMF parser. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 686 $ * $Date: 2007-05-03 14:10:54 -0700 (Thu, 03 May 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_SMF_DATA_H #define _EAS_SMF_DATA_H #ifndef MAX_SMF_STREAMS #define MAX_SMF_STREAMS 128 #endif /* offsets in to the SMF file */ #define SMF_OFS_HEADER_SIZE 4 #define SMF_OFS_FILE_TYPE 8 #define SMF_OFS_NUM_TRACKS 10 /* size of chunk info (chunk ID + chunk size) */ #define SMF_CHUNK_INFO_SIZE 8 /* 'MTrk' track chunk ID */ #define SMF_CHUNK_TYPE_TRACK 0x4d54726bL /* some useful meta-events */ #define SMF_META_TEXT 0x01 #define SMF_META_COPYRIGHT 0x02 #define SMF_META_SEQTRK_NAME 0x03 #define SMF_META_LYRIC 0x05 #define SMF_META_END_OF_TRACK 0x2f #define SMF_META_TEMPO 0x51 #define SMF_META_TIME_SIGNATURE 0x58 /* default timebase (120BPM) */ #define SMF_DEFAULT_TIMEBASE 500000L /* value for pSMFStream->ticks to signify end of track */ #define SMF_END_OF_TRACK 0xffffffff #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_wavefile.c0000644000000000000000000000013214200302440026677 xustar0030 mtime=1644266784.809324171 30 atime=1644266785.189324413 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_wavefile.c0000644000175000001440000007023514200302440027467 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_wavefile.c * * Contents and purpose: * This file implements the wave file parser. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 852 $ * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $ *---------------------------------------------------------------------------- */ #include "eas_data.h" #include "eas_report.h" #include "eas_host.h" #include "eas_config.h" #include "eas_parser.h" #include "eas_pcm.h" #include "eas_wavefile.h" /* lint is choking on the ARM math.h file, so we declare the log10 function here */ extern double log10(double x); /* increase gain to compensate for loss in mixer */ #define WAVE_GAIN_OFFSET 6 /* constant for 1200 / log10(2.0) */ #define PITCH_CENTS_CONVERSION 3986.313714 /*---------------------------------------------------------------------------- * WAVE file defines *---------------------------------------------------------------------------- */ /* RIFF chunks */ #define CHUNK_TYPE(a,b,c,d) ( \ ( ((EAS_U32)(a) & 0xFF) << 24 ) \ + ( ((EAS_U32)(b) & 0xFF) << 16 ) \ + ( ((EAS_U32)(c) & 0xFF) << 8 ) \ + ( ((EAS_U32)(d) & 0xFF) ) ) #define CHUNK_RIFF CHUNK_TYPE('R','I','F','F') #define CHUNK_WAVE CHUNK_TYPE('W','A','V','E') #define CHUNK_FMT CHUNK_TYPE('f','m','t',' ') #define CHUNK_DATA CHUNK_TYPE('d','a','t','a') #define CHUNK_LIST CHUNK_TYPE('L','I','S','T') #define CHUNK_INFO CHUNK_TYPE('I','N','F','O') #define CHUNK_INAM CHUNK_TYPE('I','N','A','M') #define CHUNK_ICOP CHUNK_TYPE('I','C','O','P') #define CHUNK_IART CHUNK_TYPE('I','A','R','T') /* wave file format identifiers */ #define WAVE_FORMAT_PCM 0x0001 #define WAVE_FORMAT_IMA_ADPCM 0x0011 /* file size for streamed file */ #define FILE_SIZE_STREAMING 0x80000000 /*---------------------------------------------------------------------------- * prototypes *---------------------------------------------------------------------------- */ static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset); static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState); static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate); static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData); static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength); #ifdef MMAPI_SUPPORT static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 size); #endif /*---------------------------------------------------------------------------- * * EAS_Wave_Parser * * This structure contains the functional interface for the Wave file parser *---------------------------------------------------------------------------- */ const S_FILE_PARSER_INTERFACE EAS_Wave_Parser = { WaveCheckFileType, WavePrepare, NULL, NULL, WaveState, WaveClose, WaveReset, WavePause, WaveResume, WaveLocate, WaveSetData, WaveGetData, WaveGetMetaData }; /*---------------------------------------------------------------------------- * WaveCheckFileType() *---------------------------------------------------------------------------- * Purpose: * Check the file type to see if we can parse it * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset) { S_WAVE_STATE *pWaveData; /* zero the memory to insure complete initialization */ *pHandle = NULL; /* read the file header */ if (WaveParseHeader(pEASData, fileHandle, NULL) == EAS_SUCCESS) { /* check for static memory allocation */ if (pEASData->staticMemoryModel) pWaveData = EAS_CMEnumData(EAS_CM_WAVE_DATA); else pWaveData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_WAVE_STATE)); if (!pWaveData) return EAS_ERROR_MALLOC_FAILED; EAS_HWMemSet(pWaveData, 0, sizeof(S_WAVE_STATE)); /* return a pointer to the instance data */ pWaveData->fileHandle = fileHandle; pWaveData->fileOffset = offset; *pHandle = pWaveData; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * WavePrepare() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_WAVE_STATE *pWaveData; EAS_RESULT result; /* validate parser state */ pWaveData = (S_WAVE_STATE*) pInstData; if (pWaveData->streamHandle != NULL) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* back to start of file */ pWaveData->time = 0; if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->fileOffset)) != EAS_SUCCESS) return result; /* parse the file header */ if ((result = WaveParseHeader(pEASData, pWaveData->fileHandle, pWaveData)) != EAS_SUCCESS) return result; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * WaveState() *---------------------------------------------------------------------------- * Purpose: * Returns the current state of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pState - pointer to variable to store state * * Outputs: * * * Side Effects: * * Notes: * This interface is also exposed in the internal library for use by the other modules. *---------------------------------------------------------------------------- */ static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState) { S_WAVE_STATE *pWaveData; /* return current state */ pWaveData = (S_WAVE_STATE*) pInstData; if (pWaveData->streamHandle) return EAS_PEState(pEASData, pWaveData->streamHandle, pState); /* if no stream handle, and time is not zero, we are done */ if (pWaveData->time > 0) *pState = EAS_STATE_STOPPED; else *pState = EAS_STATE_OPEN; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * WaveClose() *---------------------------------------------------------------------------- * Purpose: * Close the file and clean up * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_WAVE_STATE *pWaveData; EAS_RESULT result; pWaveData = (S_WAVE_STATE*) pInstData; /* close the stream */ if (pWaveData->streamHandle) { if ((result = EAS_PEClose(pEASData, pWaveData->streamHandle)) != EAS_SUCCESS) return result; pWaveData->streamHandle = NULL; } /* if using dynamic memory, free it */ if (!pEASData->staticMemoryModel) { #ifdef MMAPI_SUPPORT /* need to free the fmt chunk */ if (pWaveData->fmtChunk != NULL) EAS_HWFree(pEASData->hwInstData, pWaveData->fmtChunk); #endif /* free the instance data */ EAS_HWFree(pEASData->hwInstData, pWaveData); } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * WaveReset() *---------------------------------------------------------------------------- * Purpose: * Reset the sequencer. Used for locating backwards in the file. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { EAS_PCM_HANDLE streamHandle; /* reset to first byte of data in the stream */ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle; if (streamHandle) return EAS_PEReset(pEASData, streamHandle); return EAS_ERROR_NOT_VALID_IN_THIS_STATE; } /*---------------------------------------------------------------------------- * WaveLocate() *---------------------------------------------------------------------------- * Purpose: * Rewind/fast-forward in file. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * time - time (in msecs) * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pParserLocate) reserved for future use */ static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate) { EAS_PCM_HANDLE streamHandle; /* reset to first byte of data in the stream */ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle; if (streamHandle) return EAS_PELocate(pEASData, streamHandle, time); return EAS_ERROR_NOT_VALID_IN_THIS_STATE; } /*---------------------------------------------------------------------------- * WavePause() *---------------------------------------------------------------------------- * Purpose: * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback * at the end of the next audio frame. * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_WAVE_STATE for this stream * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { EAS_PCM_HANDLE streamHandle; /* pause the stream */ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle; if (streamHandle) return EAS_PEPause(pEASData, streamHandle); return EAS_ERROR_NOT_VALID_IN_THIS_STATE; } /*---------------------------------------------------------------------------- * WaveResume() *---------------------------------------------------------------------------- * Purpose: * Resume rendering a PCM stream. Sets the gain target back to its * previous setting and restarts playback at the end of the next audio * frame. * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_WAVE_STATE for this stream * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { EAS_PCM_HANDLE streamHandle; /* resume the stream */ streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle; if (streamHandle) return EAS_PEResume(pEASData, streamHandle); return EAS_ERROR_NOT_VALID_IN_THIS_STATE; } /*---------------------------------------------------------------------------- * WaveSetData() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_WAVE_STATE for this stream * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value) { S_WAVE_STATE *pWaveData = (S_WAVE_STATE*) pInstData; switch (param) { /* set metadata callback */ case PARSER_DATA_METADATA_CB: EAS_HWMemCpy(&pWaveData->metadata, (void*) value, sizeof(S_METADATA_CB)); return EAS_SUCCESS; case PARSER_DATA_PLAYBACK_RATE: value = (EAS_I32) (PITCH_CENTS_CONVERSION * log10((double) value / (double) (1 << 28))); return EAS_PEUpdatePitch(pEASData, pWaveData->streamHandle, (EAS_I16) value); case PARSER_DATA_VOLUME: return EAS_PEUpdateVolume(pEASData, pWaveData->streamHandle, (EAS_I16) value); default: return EAS_ERROR_INVALID_PARAMETER; } } /*---------------------------------------------------------------------------- * WaveGetData() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_WAVE_STATE for this stream * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue) { S_WAVE_STATE *pWaveData; pWaveData = (S_WAVE_STATE*) pInstData; switch (param) { /* return file type as WAVE */ case PARSER_DATA_FILE_TYPE: *pValue = pWaveData->fileType; break; #ifdef MMAPI_SUPPORT /* return pointer to 'fmt' chunk */ case PARSER_DATA_FORMAT: *pValue = (EAS_I32) pWaveData->fmtChunk; break; #endif case PARSER_DATA_GAIN_OFFSET: *pValue = WAVE_GAIN_OFFSET; break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * WaveParseHeader() *---------------------------------------------------------------------------- * Purpose: * Parse the WAVE file header. * * Inputs: * pEASData - pointer to EAS library instance data * handle - pointer to S_WAVE_STATE for this stream * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData) { S_PCM_OPEN_PARAMS params; EAS_RESULT result; EAS_U32 tag; EAS_U32 fileSize; EAS_U32 size; EAS_I32 pos; EAS_I32 audioOffset; EAS_U16 usTemp; EAS_BOOL parseDone; EAS_U32 avgBytesPerSec; /* init some data (and keep lint happy) */ params.sampleRate = 0; params.size = 0; audioOffset = 0; params.decoder = 0; params.blockSize = 0; params.pCallbackFunc = NULL; params.cbInstData = NULL; params.loopSamples = 0; params.fileHandle = fileHandle; params.volume = 0x7fff; params.envData = 0; avgBytesPerSec = 8000; /* check for 'RIFF' tag */ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE) return result; if (tag != CHUNK_RIFF) return EAS_ERROR_UNRECOGNIZED_FORMAT; /* get size */ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &fileSize, EAS_FALSE)) != EAS_FALSE) return result; /* check for 'WAVE' tag */ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE) return result; if (tag != CHUNK_WAVE) return EAS_ERROR_UNRECOGNIZED_FORMAT; /* this is enough to say we recognize the file */ if (pWaveData == NULL) return EAS_SUCCESS; /* check for streaming mode */ pWaveData->flags = 0; pWaveData->mediaLength = -1; pWaveData->infoChunkPos = -1; pWaveData->infoChunkSize = -1; if (fileSize== FILE_SIZE_STREAMING) { pWaveData->flags |= PCM_FLAGS_STREAMING; fileSize = 0x7fffffff; } /* find out where we're at */ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS) return result; fileSize -= 4; parseDone = EAS_FALSE; for (;;) { /* get tag and size for next chunk */ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE) return result; if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &size, EAS_FALSE)) != EAS_FALSE) return result; /* process chunk */ pos += 8; switch (tag) { case CHUNK_FMT: #ifdef MMAPI_SUPPORT if ((result = SaveFmtChunk(pEASData, fileHandle, pWaveData, (EAS_I32) size)) != EAS_SUCCESS) return result; #endif /* get audio format */ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE) return result; if (usTemp == WAVE_FORMAT_PCM) { params.decoder = EAS_DECODER_PCM; pWaveData->fileType = EAS_FILE_WAVE_PCM; } else if (usTemp == WAVE_FORMAT_IMA_ADPCM) { params.decoder = EAS_DECODER_IMA_ADPCM; pWaveData->fileType = EAS_FILE_WAVE_IMA_ADPCM; } else return EAS_ERROR_UNRECOGNIZED_FORMAT; /* get number of channels */ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE) return result; if (usTemp == 2) pWaveData->flags |= PCM_FLAGS_STEREO; else if (usTemp != 1) return EAS_ERROR_UNRECOGNIZED_FORMAT; /* get sample rate */ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, ¶ms.sampleRate, EAS_FALSE)) != EAS_FALSE) return result; /* get stream rate */ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &avgBytesPerSec, EAS_FALSE)) != EAS_FALSE) return result; /* get block alignment */ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE) return result; params.blockSize = usTemp; /* get bits per sample */ if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE) return result; /* PCM, must be 8 or 16 bit samples */ if (params.decoder == EAS_DECODER_PCM) { if (usTemp == 8) pWaveData->flags |= PCM_FLAGS_8_BIT | PCM_FLAGS_UNSIGNED; else if (usTemp != 16) return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* for IMA ADPCM, we only support mono 4-bit ADPCM */ else { if ((usTemp != 4) || (pWaveData->flags & PCM_FLAGS_STEREO)) return EAS_ERROR_UNRECOGNIZED_FORMAT; } break; case CHUNK_DATA: audioOffset = pos; if (pWaveData->flags & PCM_FLAGS_STREAMING) { params.size = 0x7fffffff; parseDone = EAS_TRUE; } else { params.size = (EAS_I32) size; params.loopStart = size; /* use more accurate method if possible */ if (size <= (0x7fffffff / 1000)) pWaveData->mediaLength = (EAS_I32) ((size * 1000) / avgBytesPerSec); else pWaveData->mediaLength = (EAS_I32) (size / (avgBytesPerSec / 1000)); } break; case CHUNK_LIST: /* get the list type */ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE) return result; if (tag == CHUNK_INFO) { pWaveData->infoChunkPos = pos + 4; pWaveData->infoChunkSize = (EAS_I32) size - 4; } break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n", (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ } break; } if (parseDone) break; /* subtract header size */ fileSize -= 8; /* account for zero-padding on odd length chunks */ if (size & 1) size++; /* this check works for files with odd length last chunk and no zero-pad */ if (size >= fileSize) { if (size > fileSize) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: '%c%c%c%c' chunk size exceeds length of file or is not zero-padded\n", (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ } break; } /* subtract size of data chunk (including any zero-pad) */ fileSize -= size; /* seek to next chunk */ pos += (EAS_I32) size; if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos)) != EAS_SUCCESS) return result; } /* check for valid header */ if ((params.sampleRate == 0) || (params.size == 0)) return EAS_ERROR_UNRECOGNIZED_FORMAT; /* save the pertinent information */ pWaveData->audioOffset = audioOffset; params.flags = pWaveData->flags; /* seek to data */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, audioOffset)) != EAS_SUCCESS) return result; /* open a stream in the PCM engine */ return EAS_PEOpenStream(pEASData, ¶ms, &pWaveData->streamHandle); } /*---------------------------------------------------------------------------- * WaveGetMetaData() *---------------------------------------------------------------------------- * Purpose: * Process the INFO chunk and return metadata to host *---------------------------------------------------------------------------- */ static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength) { S_WAVE_STATE *pWaveData; EAS_RESULT result; EAS_I32 pos; EAS_U32 size; EAS_I32 infoSize; EAS_U32 tag; EAS_I32 restorePos; E_EAS_METADATA_TYPE metaType; EAS_I32 metaLen; /* get current position so we can restore it */ pWaveData = (S_WAVE_STATE*) pInstData; /* return media length */ *pMediaLength = pWaveData->mediaLength; /* did we encounter an INFO chunk? */ if (pWaveData->infoChunkPos < 0) return EAS_SUCCESS; if ((result = EAS_HWFilePos(pEASData->hwInstData, pWaveData->fileHandle, &restorePos)) != EAS_SUCCESS) return result; /* offset to start of first chunk in INFO chunk */ pos = pWaveData->infoChunkPos; infoSize = pWaveData->infoChunkSize; /* read all the chunks in the INFO chunk */ for (;;) { /* seek to next chunk */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pos)) != EAS_SUCCESS) return result; /* get tag and size for next chunk */ if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &tag, EAS_TRUE)) != EAS_FALSE) return result; if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &size, EAS_FALSE)) != EAS_FALSE) return result; /* process chunk */ pos += 8; metaType = EAS_METADATA_UNKNOWN; switch (tag) { case CHUNK_INAM: metaType = EAS_METADATA_TITLE; break; case CHUNK_IART: metaType = EAS_METADATA_AUTHOR; break; case CHUNK_ICOP: metaType = EAS_METADATA_COPYRIGHT; break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n", (char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ } break; } /* process known metadata */ if (metaType != EAS_METADATA_UNKNOWN) { metaLen = pWaveData->metadata.bufferSize - 1; if (metaLen > (EAS_I32) size) metaLen = (EAS_I32) size; if ((result = EAS_HWReadFile(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->metadata.buffer, metaLen, &metaLen)) != EAS_SUCCESS) return result; pWaveData->metadata.buffer[metaLen] = 0; pWaveData->metadata.callback(metaType, pWaveData->metadata.buffer, pWaveData->metadata.pUserData); } /* subtract this block */ if (size & 1) size++; infoSize -= (EAS_I32) size + 8; if (infoSize == 0) break; pos += (EAS_I32) size; } /* restore original position */ return EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, restorePos); } #ifdef MMAPI_SUPPORT /*---------------------------------------------------------------------------- * SaveFmtChunk() *---------------------------------------------------------------------------- * Purpose: * Save the fmt chunk for the MMAPI library *---------------------------------------------------------------------------- */ static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 fmtSize) { EAS_RESULT result; EAS_I32 pos; EAS_I32 count; /* save current file position */ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS) return result; /* allocate a chunk of memory */ pWaveData->fmtChunk = EAS_HWMalloc(pEASData->hwInstData, fmtSize); if (!pWaveData->fmtChunk) return EAS_ERROR_MALLOC_FAILED; /* read the fmt chunk into memory */ if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, pWaveData->fmtChunk, fmtSize, &count)) != EAS_SUCCESS) return result; if (count != fmtSize) return EAS_ERROR_FILE_READ_FAILED; /* restore file position */ return EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos); } #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_flog.c0000644000000000000000000000013214200302440026024 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.189324413 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_flog.c0000644000175000001440000000524014200302440026606 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_flog2.c * * Contents and purpose: * Fixed point square root * * * Copyright (c) 2006 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision$ * $Date$ *---------------------------------------------------------------------------- */ #include "eas_types.h" #include "eas_math.h" #define MANTISSA_SHIFT 27 #define MANTISSA_MASK 0x0000000f #define MANTISSA_LSB_SHIFT 7 #define MANTISSA_LSB_MASK 0x000fffff #define LOG_EXPONENT_SHIFT 10 #define INTERPOLATION_SHIFT 20 #define MAX_NEGATIVE (-2147483647-1) /* log lookup table */ static const EAS_U16 eas_log2_table[] = { 0, 90, 174, 254, 330, 402, 470, 536, 599, 659, 717, 773, 827, 879, 929, 977, 1024 }; /*---------------------------------------------------------------------------- * EAS_flog2() *---------------------------------------------------------------------------- * Purpose: * Calculates the log2 of a 32-bit fixed point value * * Inputs: * n = value of interest * * Outputs: * returns the log2 of n * *---------------------------------------------------------------------------- */ EAS_I32 EAS_flog2 (EAS_U32 n) { EAS_U32 exp; EAS_U32 interp; /* check for error condition */ if (n == 0) return MAX_NEGATIVE; /* find exponent */ for (exp = 31; exp > 0; exp--) { /* shift until we get a 1 bit in bit 31 */ if ((n & (EAS_U32) MAX_NEGATIVE) != 0) break; n <<= 1; } /*lint -e{701} use shift for performance */ exp <<= LOG_EXPONENT_SHIFT; /* get the least significant bits for interpolation */ interp = (n >> MANTISSA_LSB_SHIFT) & MANTISSA_LSB_MASK; /* get the most significant bits for mantissa lookup */ n = (n >> MANTISSA_SHIFT) & MANTISSA_MASK; /* interpolate mantissa */ interp = ((eas_log2_table[n+1] - eas_log2_table[n]) * interp) >> INTERPOLATION_SHIFT; exp += eas_log2_table[n] + interp; return (EAS_I32) exp; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_math.c0000644000000000000000000000013214200302440026026 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.189324413 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_math.c0000644000175000001440000001141514200302440026611 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_math.c * * Contents and purpose: * Contains common math routines for the various audio engines. * * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 586 $ * $Date: 2007-03-08 20:33:04 -0800 (Thu, 08 Mar 2007) $ *---------------------------------------------------------------------------- */ #include "eas.h" #include "eas_math.h" /* anything less than this converts to a fraction too small to represent in 32-bits */ #define MIN_CENTS -18000 /*---------------------------------------------------------------------------- * EAS_Calculate2toX() *---------------------------------------------------------------------------- * Purpose: * Calculate 2^x * * Inputs: * nCents - measured in cents * psEASData - pointer to overall EAS data structure * * Outputs: * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS) * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_I32 EAS_Calculate2toX (EAS_I32 nCents) { EAS_I32 nDents; EAS_I32 nExponentInt, nExponentFrac; EAS_I32 nTemp1, nTemp2; EAS_I32 nResult; /* check for minimum value */ if (nCents < MIN_CENTS) return 0; /* for the time being, convert cents to dents */ nDents = FMUL_15x15(nCents, CENTS_TO_DENTS); nExponentInt = GET_DENTS_INT_PART(nDents); nExponentFrac = GET_DENTS_FRAC_PART(nDents); /* implement 2^(fracPart) as a power series */ nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3); nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1); nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2); /* implement 2^(intPart) as a left shift for intPart >= 0 or a left shift for intPart < 0 */ if (nExponentInt >= 0) { /* left shift for positive exponents */ /*lint -e{703} */ nResult = nTemp1 << nExponentInt; } else { /* right shift for negative exponents */ nExponentInt = -nExponentInt; nResult = nTemp1 >> nExponentInt; } return nResult; } /*---------------------------------------------------------------------------- * EAS_LogToLinear16() *---------------------------------------------------------------------------- * Purpose: * Transform log value to linear gain multiplier using piece-wise linear * approximation * * Inputs: * nGain - log scale value in 20.10 format. Even though gain is normally * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate * the need for saturation checking when combining gain values. * * Outputs: * Returns a 16-bit linear value approximately equal to 2^(nGain/1024) * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain) { EAS_INT nExp; EAS_U16 nTemp; /* bias to positive */ nGain += 32767; /* check for infinite attenuation */ if (nGain < 0) return 0; /* extract the exponent */ nExp = 31 - (nGain >> 10); /* check for maximum output */ if (nExp < 0) return 0x7fff; /* extract mantissa and restore implied 1 bit */ nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp); /* use shift to approximate power-of-2 operation */ return nTemp; } /*---------------------------------------------------------------------------- * EAS_VolumeToGain() *---------------------------------------------------------------------------- * Purpose: * Transform volume control in 1dB increments to gain multiplier * * Inputs: * volume - 100 = 0dB, 99 = -1dB, 0 = -inf * * Outputs: * Returns a 16-bit linear value *---------------------------------------------------------------------------- */ EAS_I16 EAS_VolumeToGain (EAS_INT volume) { /* check for limits */ if (volume <= 0) return 0; if (volume >= 100) return 0x7fff; /*lint -e{702} use shift instead of division */ return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1); } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/dls.h0000644000000000000000000000013214200302440025034 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.189324413 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/dls.h0000644000175000001440000001765114200302440025627 0ustar00pedrousers00000000000000 /* dls.h Description: Interface defines and structures for the Instrument Collection Form RIFF DLS. Written by Sonic Foundry 1996. Released for public use. */ #ifndef _INC_DLS #define _INC_DLS /* Layout of an instrument collection: RIFF [] 'DLS ' [colh,INSTLIST,WAVEPOOL,INFOLIST] INSTLIST LIST [] 'lins' LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST] LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST] LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST] RGNLIST LIST [] 'lrgn' LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST] LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST] LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST] ARTLIST LIST [] 'lart' 'art1' level 1 Articulation connection graph 'art2' level 2 Articulation connection graph '3rd1' Possible 3rd party articulation structure 1 '3rd2' Possible 3rd party articulation structure 2 .... and so on WAVEPOOL ptbl [] [pool table] LIST [] 'wvpl' [path], [path], LIST [] 'wave',RIFFWAVE LIST [] 'wave',RIFFWAVE LIST [] 'wave',RIFFWAVE LIST [] 'wave',RIFFWAVE LIST [] 'wave',RIFFWAVE INFOLIST LIST [] 'INFO' 'icmt' 'One of those crazy comments.' 'icop' 'Copyright (C) 1996 Sonic Foundry' */ /* FOURCC's used in the DLS file */ /* shree */ //#define FAR /* shree #define FOURCC_DLS mmioFOURCC('D','L','S',' ') #define FOURCC_COLH mmioFOURCC('c','o','l','h') #define FOURCC_WVPL mmioFOURCC('w','v','p','l') #define FOURCC_PTBL mmioFOURCC('p','t','b','l') #define FOURCC_PATH mmioFOURCC('p','a','t','h') #define FOURCC_wave mmioFOURCC('w','a','v','e') #define FOURCC_LINS mmioFOURCC('l','i','n','s') #define FOURCC_INS mmioFOURCC('i','n','s',' ') #define FOURCC_INSH mmioFOURCC('i','n','s','h') #define FOURCC_LRGN mmioFOURCC('l','r','g','n') #define FOURCC_RGN mmioFOURCC('r','g','n',' ') #define FOURCC_RGNH mmioFOURCC('r','g','n','h') #define FOURCC_LART mmioFOURCC('l','a','r','t') #define FOURCC_ART1 mmioFOURCC('a','r','t','1') #define FOURCC_WLNK mmioFOURCC('w','l','n','k') #define FOURCC_WSMP mmioFOURCC('w','s','m','p') #define FOURCC_VERS mmioFOURCC('v','e','r','s') */ /* Articulation connection graph definitions */ /* Generic Sources */ #define CONN_SRC_NONE 0x0000 #define CONN_SRC_LFO 0x0001 #define CONN_SRC_KEYONVELOCITY 0x0002 #define CONN_SRC_KEYNUMBER 0x0003 #define CONN_SRC_EG1 0x0004 #define CONN_SRC_EG2 0x0005 #define CONN_SRC_PITCHWHEEL 0x0006 /* Midi Controllers 0-127 */ #define CONN_SRC_CC1 0x0081 #define CONN_SRC_CC7 0x0087 #define CONN_SRC_CC10 0x008a #define CONN_SRC_CC11 0x008b /* Registered Parameter Numbers */ #define CONN_SRC_RPN0 0x0100 #define CONN_SRC_RPN1 0x0101 #define CONN_SRC_RPN2 0x0102 /* Generic Destinations */ #define CONN_DST_NONE 0x0000 #define CONN_DST_ATTENUATION 0x0001 #define CONN_DST_RESERVED 0x0002 #define CONN_DST_PITCH 0x0003 #define CONN_DST_PAN 0x0004 /* LFO Destinations */ #define CONN_DST_LFO_FREQUENCY 0x0104 #define CONN_DST_LFO_STARTDELAY 0x0105 /* EG1 Destinations */ #define CONN_DST_EG1_ATTACKTIME 0x0206 #define CONN_DST_EG1_DECAYTIME 0x0207 #define CONN_DST_EG1_RESERVED 0x0208 #define CONN_DST_EG1_RELEASETIME 0x0209 #define CONN_DST_EG1_SUSTAINLEVEL 0x020a /* EG2 Destinations */ #define CONN_DST_EG2_ATTACKTIME 0x030a #define CONN_DST_EG2_DECAYTIME 0x030b #define CONN_DST_EG2_RESERVED 0x030c #define CONN_DST_EG2_RELEASETIME 0x030d #define CONN_DST_EG2_SUSTAINLEVEL 0x030e #define CONN_TRN_NONE 0x0000 #define CONN_TRN_CONCAVE 0x0001 typedef struct _DLSVERSION { DWORD dwVersionMS; DWORD dwVersionLS; }DLSVERSION, FAR *LPDLSVERSION; typedef struct _CONNECTION { USHORT usSource; USHORT usControl; USHORT usDestination; USHORT usTransform; LONG lScale; }CONNECTION, FAR *LPCONNECTION; /* Level 1 Articulation Data */ typedef struct _CONNECTIONLIST { ULONG cbSize; /* size of the connection list structure */ ULONG cConnections; /* count of connections in the list */ } CONNECTIONLIST, FAR *LPCONNECTIONLIST; /* Generic type defines for regions and instruments */ typedef struct _RGNRANGE { USHORT usLow; USHORT usHigh; }RGNRANGE, FAR * LPRGNRANGE; #define F_INSTRUMENT_DRUMS 0x80000000 typedef struct _MIDILOCALE { ULONG ulBank; ULONG ulInstrument; }MIDILOCALE, FAR *LPMIDILOCALE; /* Header structures found in an DLS file for collection, instruments, and regions. */ #define F_RGN_OPTION_SELFNONEXCLUSIVE 0x0001 typedef struct _RGNHEADER { RGNRANGE RangeKey; /* Key range */ RGNRANGE RangeVelocity; /* Velocity Range */ USHORT fusOptions; /* Synthesis options for this range */ USHORT usKeyGroup; /* Key grouping for non simultaneous play 0 = no group, 1 up is group for Level 1 only groups 1-15 are allowed */ }RGNHEADER, FAR *LPRGNHEADER; typedef struct _INSTHEADER { ULONG cRegions; /* Count of regions in this instrument */ MIDILOCALE Locale; /* Intended MIDI locale of this instrument */ }INSTHEADER, FAR *LPINSTHEADER; typedef struct _DLSHEADER { ULONG cInstruments; /* Count of instruments in the collection */ }DLSHEADER, FAR *LPDLSHEADER; /* definitions for the Wave link structure */ /***** For level 1 only WAVELINK_CHANNEL_MONO is valid **** ulChannel allows for up to 32 channels of audio with each bit position specifiying a channel of playback */ #define WAVELINK_CHANNEL_LEFT 0x0001 #define WAVELINK_CHANNEL_RIGHT 0x0002 #define F_WAVELINK_PHASE_MASTER 0x0001 typedef struct _WAVELINK { /* any paths or links are stored right after struct */ USHORT fusOptions; /* options flags for this wave */ USHORT usPhaseGroup; /* Phase grouping for locking channels */ ULONG ulChannel; /* channel placement */ ULONG ulTableIndex; /* index into the wave pool table, 0 based */ }WAVELINK, FAR *LPWAVELINK; #define POOL_CUE_NULL 0xffffffff typedef struct _POOLCUE { // ULONG ulEntryIndex; /* Index entry in the list */ ULONG ulOffset; /* Offset to the entry in the list */ }POOLCUE, FAR *LPPOOLCUE; typedef struct _POOLTABLE { ULONG cbSize; /* size of the pool table structure */ ULONG cCues; /* count of cues in the list */ } POOLTABLE, FAR *LPPOOLTABLE; /* Structures for the "wsmp" chunk */ #define F_WSMP_NO_TRUNCATION 0x0001 #define F_WSMP_NO_COMPRESSION 0x0002 typedef struct _rwsmp { ULONG cbSize; USHORT usUnityNote; /* MIDI Unity Playback Note */ SHORT sFineTune; /* Fine Tune in log tuning */ LONG lAttenuation; /* Overall Attenuation to be applied to data */ ULONG fulOptions; /* Flag options */ ULONG cSampleLoops; /* Count of Sample loops, 0 loops is one shot */ } WSMPL, FAR *LPWSMPL; /* This loop type is a normal forward playing loop which is continually played until the envelope reaches an off threshold in the release portion of the volume envelope */ #define WLOOP_TYPE_FORWARD 0 typedef struct _rloop { ULONG cbSize; ULONG ulType; /* Loop Type */ ULONG ulStart; /* Start of loop in samples */ ULONG ulLength; /* Length of loop in samples */ } WLOOP, FAR *LPWLOOP; #endif /* _INC_DLS */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_reverbdata.h0000644000000000000000000000013214200302440027221 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.189324413 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_reverbdata.h0000644000175000001440000004151414200302440030007 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_reverbdata.h * * Contents and purpose: * Contains the prototypes for the Reverb effect. * * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 499 $ * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_REVERBDATA_H #define _EAS_REVERBDATA_H #include "eas_types.h" #include "eas_audioconst.h" /*------------------------------------ * defines *------------------------------------ */ /* CIRCULAR() calculates the array index using modulo arithmetic. The "trick" is that modulo arithmetic is simplified by masking the effective address where the mask is (2^n)-1. This only works if the buffer size is a power of two. */ #define CIRCULAR(base,offset,size) (EAS_U32)( \ ( \ ((EAS_I32)(base)) + ((EAS_I32)(offset)) \ ) \ & size \ ) /* reverb parameters are updated every 2^(REVERB_UPDATE_PERIOD_IN_BITS) samples */ #if defined (_SAMPLE_RATE_8000) #define REVERB_UPDATE_PERIOD_IN_BITS 5 #define REVERB_BUFFER_SIZE_IN_SAMPLES 2048 #elif defined (_SAMPLE_RATE_16000) #define REVERB_UPDATE_PERIOD_IN_BITS 6 #define REVERB_BUFFER_SIZE_IN_SAMPLES 4096 #elif defined (_SAMPLE_RATE_22050) #define REVERB_UPDATE_PERIOD_IN_BITS 7 #define REVERB_BUFFER_SIZE_IN_SAMPLES 4096 #elif defined (_SAMPLE_RATE_32000) #define REVERB_UPDATE_PERIOD_IN_BITS 7 #define REVERB_BUFFER_SIZE_IN_SAMPLES 8192 #elif defined (_SAMPLE_RATE_44100) #define REVERB_UPDATE_PERIOD_IN_BITS 8 #define REVERB_BUFFER_SIZE_IN_SAMPLES 8192 #elif defined (_SAMPLE_RATE_48000) #define REVERB_UPDATE_PERIOD_IN_BITS 8 #define REVERB_BUFFER_SIZE_IN_SAMPLES 8192 #endif // Define a mask for circular addressing, so that array index // can wraparound and stay in array boundary of 0, 1, ..., (buffer size -1) // The buffer size MUST be a power of two #define REVERB_BUFFER_MASK (REVERB_BUFFER_SIZE_IN_SAMPLES -1) #define REVERB_MAX_ROOM_TYPE 4 // any room numbers larger than this are invalid #define REVERB_MAX_NUM_REFLECTIONS 5 // max num reflections per channel /* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */ #define REVERB_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << REVERB_UPDATE_PERIOD_IN_BITS) /* calculate the update counter by bitwise ANDING with this value to generate a 2^n modulo value */ #define REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(REVERB_UPDATE_PERIOD_IN_SAMPLES -1) /* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SECONDS seconds */ #define REVERB_UPDATE_PERIOD_IN_SECONDS (REVERB_UPDATE_PERIOD_IN_SAMPLES / _OUTPUT_SAMPLE_RATE) // xfade parameters #define REVERB_XFADE_PERIOD_IN_SECONDS (100.0 / 1000.0) // xfade once every this many seconds #define REVERB_XFADE_PERIOD_IN_SAMPLES (REVERB_XFADE_PERIOD_IN_SECONDS * _OUTPUT_SAMPLE_RATE) #define REVERB_XFADE_PHASE_INCREMENT (EAS_I16)(65536 / ((EAS_I16)REVERB_XFADE_PERIOD_IN_SAMPLES/(EAS_I16)REVERB_UPDATE_PERIOD_IN_SAMPLES)) /**********/ /* the entire synth uses various flags in a bit field */ /* if flag is set, synth reset has been requested */ #define REVERB_FLAG_RESET_IS_REQUESTED 0x01 /* bit 0 */ #define MASK_REVERB_RESET_IS_REQUESTED 0x01 #define MASK_REVERB_RESET_IS_NOT_REQUESTED (EAS_U32)(~MASK_REVERB_RESET_IS_REQUESTED) /* by default, we always want to update ALL channel parameters when we reset the synth (e.g., during GM ON) */ #define DEFAULT_REVERB_FLAGS 0x0 /* coefficients for generating sin, cos */ #define REVERB_PAN_G2 4294940151 /* -0.82842712474619 = 2 - 4/sqrt(2) */ /* EAS_I32 nPanG1 = +1.0 for sin EAS_I32 nPanG1 = -1.0 for cos */ #define REVERB_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */ /*************************************************************/ // define the input injection points #define GUARD 5 // safety guard of this many samples #define MAX_AP_TIME (double) (20.0/1000.0) // delay time in milliseconds #define MAX_DELAY_TIME (double) (65.0/1000.0) // delay time in milliseconds #define MAX_AP_SAMPLES (int)(((double) MAX_AP_TIME) * ((double) _OUTPUT_SAMPLE_RATE)) #define MAX_DELAY_SAMPLES (int)(((double) MAX_DELAY_TIME) * ((double) _OUTPUT_SAMPLE_RATE)) #define AP0_IN 0 #define AP1_IN (AP0_IN + MAX_AP_SAMPLES + GUARD) #define DELAY0_IN (AP1_IN + MAX_AP_SAMPLES + GUARD) #define DELAY1_IN (DELAY0_IN + MAX_DELAY_SAMPLES + GUARD) // Define the max offsets for the end points of each section // i.e., we don't expect a given section's taps to go beyond // the following limits #define AP0_OUT (AP0_IN + MAX_AP_SAMPLES -1) #define AP1_OUT (AP1_IN + MAX_AP_SAMPLES -1) #define DELAY0_OUT (DELAY0_IN + MAX_DELAY_SAMPLES -1) #define DELAY1_OUT (DELAY1_IN + MAX_DELAY_SAMPLES -1) #define REVERB_DEFAULT_ROOM_NUMBER 1 // default preset number #define DEFAULT_AP0_LENGTH (int)(((double) (17.0/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE)) #define DEFAULT_AP0_GAIN 19400 #define DEFAULT_AP1_LENGTH (int)(((double) (16.5/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE)) #define DEFAULT_AP1_GAIN -19400 #define REVERB_DEFAULT_WET 32767 #define REVERB_DEFAULT_DRY 0 #define EAS_REVERB_WET_MAX 32767 #define EAS_REVERB_WET_MIN 0 #define EAS_REVERB_DRY_MAX 32767 #define EAS_REVERB_DRY_MIN 0 /* parameters for each allpass */ typedef struct { EAS_U16 m_zApOut; // delay offset for ap out EAS_I16 m_nApGain; // gain for ap EAS_U16 m_zApIn; // delay offset for ap in } S_ALLPASS_OBJECT; /* parameters for each allpass */ typedef struct { EAS_PCM m_zLpf; // actual state variable, not a length EAS_I16 m_nLpfFwd; // lpf forward gain EAS_I16 m_nLpfFbk; // lpf feedback gain EAS_U16 m_zDelay[REVERB_MAX_NUM_REFLECTIONS]; // delay offset for ap out EAS_I16 m_nGain[REVERB_MAX_NUM_REFLECTIONS]; // gain for ap } S_EARLY_REFLECTION_OBJECT; //demo typedef struct { EAS_I16 m_nLpfFbk; EAS_I16 m_nLpfFwd; EAS_I16 m_nEarly; EAS_I16 m_nWet; EAS_I16 m_nDry; EAS_I16 m_nEarlyL_LpfFbk; EAS_I16 m_nEarlyL_LpfFwd; EAS_I16 m_nEarlyL_Delay0; //8 EAS_I16 m_nEarlyL_Gain0; EAS_I16 m_nEarlyL_Delay1; EAS_I16 m_nEarlyL_Gain1; EAS_I16 m_nEarlyL_Delay2; EAS_I16 m_nEarlyL_Gain2; EAS_I16 m_nEarlyL_Delay3; EAS_I16 m_nEarlyL_Gain3; EAS_I16 m_nEarlyL_Delay4; EAS_I16 m_nEarlyL_Gain4; EAS_I16 m_nEarlyR_Delay0; //18 EAS_I16 m_nEarlyR_Gain0; EAS_I16 m_nEarlyR_Delay1; EAS_I16 m_nEarlyR_Gain1; EAS_I16 m_nEarlyR_Delay2; EAS_I16 m_nEarlyR_Gain2; EAS_I16 m_nEarlyR_Delay3; EAS_I16 m_nEarlyR_Gain3; EAS_I16 m_nEarlyR_Delay4; EAS_I16 m_nEarlyR_Gain4; EAS_U16 m_nMaxExcursion; //28 EAS_I16 m_nXfadeInterval; EAS_I16 m_nAp0_ApGain; //30 EAS_I16 m_nAp0_ApOut; EAS_I16 m_nAp1_ApGain; EAS_I16 m_nAp1_ApOut; EAS_I16 m_rfu4; EAS_I16 m_rfu5; EAS_I16 m_rfu6; EAS_I16 m_rfu7; EAS_I16 m_rfu8; EAS_I16 m_rfu9; EAS_I16 m_rfu10; //43 } S_REVERB_PRESET; typedef struct { S_REVERB_PRESET m_sPreset[REVERB_MAX_ROOM_TYPE]; //array of presets } S_REVERB_PRESET_BANK; /* parameters for each reverb */ typedef struct { /* controls entire reverb playback volume */ /* to conserve memory, use the MSB and ignore the LSB */ EAS_U8 m_nMasterVolume; /* update counter keeps track of when synth params need updating */ /* only needs to be as large as REVERB_UPDATE_PERIOD_IN_SAMPLES */ EAS_I16 m_nUpdateCounter; EAS_U16 m_nMinSamplesToAdd; /* ComputeReverb() generates this many samples */ EAS_U8 m_nFlags; /* misc flags/bit fields */ EAS_PCM *m_pOutputBuffer; EAS_PCM *m_pInputBuffer; EAS_U16 m_nNumSamplesInOutputBuffer; EAS_U16 m_nNumSamplesInInputBuffer; EAS_U16 m_nNumInputSamplesRead; // if m_nNumInputSamplesRead >= NumSamplesInInputBuffer // then get a new input buffer EAS_PCM *m_pNextInputSample; EAS_U16 m_nBaseIndex; // base index for circular buffer // reverb delay line offsets, allpass parameters, etc: EAS_PCM m_nRevOutFbkR; // combine feedback reverb right out with dry left in S_ALLPASS_OBJECT m_sAp0; // allpass 0 (left channel) EAS_U16 m_zD0In; // delay offset for delay line D0 in EAS_PCM m_nRevOutFbkL; // combine feedback reverb left out with dry right in S_ALLPASS_OBJECT m_sAp1; // allpass 1 (right channel) EAS_U16 m_zD1In; // delay offset for delay line D1 in // delay output taps, notice criss cross order EAS_U16 m_zD0Self; // self feeds forward d0 --> d0 EAS_U16 m_zD1Cross; // cross feeds across d1 --> d0 EAS_PCM m_zLpf0; // actual state variable, not a length EAS_U16 m_zD1Self; // self feeds forward d1 --> d1 EAS_U16 m_zD0Cross; // cross feeds across d0 --> d1 EAS_PCM m_zLpf1; // actual state variable, not a length EAS_I16 m_nSin; // gain for self taps EAS_I16 m_nCos; // gain for cross taps EAS_I16 m_nSinIncrement; // increment for gain EAS_I16 m_nCosIncrement; // increment for gain EAS_I16 m_nLpfFwd; // lpf forward gain (includes scaling for mixer) EAS_I16 m_nLpfFbk; // lpf feedback gain EAS_U16 m_nXfadeInterval; // update/xfade after this many samples EAS_U16 m_nXfadeCounter; // keep track of when to xfade EAS_I16 m_nPhase; // -1 <= m_nPhase < 1 // but during sin,cos calculations // use m_nPhase/2 EAS_I16 m_nPhaseIncrement; // add this to m_nPhase each frame EAS_I16 m_nNoise; // random noise sample EAS_U16 m_nMaxExcursion; // the taps can excurse +/- this amount EAS_BOOL m_bUseNoise; // if EAS_TRUE, use noise as input signal EAS_BOOL m_bBypass; // if EAS_TRUE, then bypass reverb and copy input to output EAS_I16 m_nCurrentRoom; // preset number for current room EAS_I16 m_nNextRoom; // preset number for next room EAS_I16 m_nWet; // gain for wet (processed) signal EAS_I16 m_nDry; // gain for dry (unprocessed) signal EAS_I16 m_nEarly; // gain for early (widen) signal S_EARLY_REFLECTION_OBJECT m_sEarlyL; // left channel early reflections S_EARLY_REFLECTION_OBJECT m_sEarlyR; // right channel early reflections EAS_PCM m_nDelayLine[REVERB_BUFFER_SIZE_IN_SAMPLES]; // one large delay line for all reverb elements S_REVERB_PRESET pPreset; S_REVERB_PRESET_BANK m_sPreset; //EAS_I8 preset; } S_REVERB_OBJECT; /*------------------------------------ * prototypes *------------------------------------ */ /*---------------------------------------------------------------------------- * ReverbUpdateXfade *---------------------------------------------------------------------------- * Purpose: * Update the xfade parameters as required * * Inputs: * nNumSamplesToAdd - number of samples to write to buffer * * Outputs: * * * Side Effects: * - xfade parameters will be changed * *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd); /*---------------------------------------------------------------------------- * ReverbCalculateNoise *---------------------------------------------------------------------------- * Purpose: * Calculate a noise sample and limit its value * * Inputs: * nMaxExcursion - noise value is limited to this value * pnNoise - return new noise sample in this (not limited) * * Outputs: * new limited noise value * * Side Effects: * - *pnNoise noise value is updated * *---------------------------------------------------------------------------- */ static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise); /*---------------------------------------------------------------------------- * ReverbCalculateSinCos *---------------------------------------------------------------------------- * Purpose: * Calculate a new sin and cosine value based on the given phase * * Inputs: * nPhase - phase angle * pnSin - input old value, output new value * pnCos - input old value, output new value * * Outputs: * * Side Effects: * - *pnSin, *pnCos are updated * *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos); /*---------------------------------------------------------------------------- * Reverb *---------------------------------------------------------------------------- * Purpose: * apply reverb to the given signal * * Inputs: * nNu * pnSin - input old value, output new value * pnCos - input old value, output new value * * Outputs: * number of samples actually reverberated * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT Reverb(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer); /*---------------------------------------------------------------------------- * ReverbReadInPresets() *---------------------------------------------------------------------------- * Purpose: sets global reverb preset bank to defaults * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT* pReverbData); /*---------------------------------------------------------------------------- * ReverbUpdateRoom *---------------------------------------------------------------------------- * Purpose: * Update the room's preset parameters as required * * Inputs: * * Outputs: * * * Side Effects: * - reverb paramters (fbk, fwd, etc) will be changed * - m_nCurrentRoom := m_nNextRoom *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT* pReverbData); #endif /* #ifndef _EAS_REVERBDATA_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_chorus.c0000644000000000000000000000013214200302440026400 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.189324413 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_chorus.c0000644000175000001440000005246314200302440027173 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_chorus.c * * Contents and purpose: * Contains the implementation of the Chorus effect. * * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 499 $ * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $ *---------------------------------------------------------------------------- */ #include "eas_data.h" #include "eas_effects.h" #include "eas_math.h" #include "eas_chorusdata.h" #include "eas_chorus.h" #include "eas_config.h" #include "eas_host.h" #include "eas_report.h" /* prototypes for effects interface */ static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData); static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples); static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); /* common effects interface for configuration module */ const S_EFFECTS_INTERFACE EAS_Chorus = { ChorusInit, ChorusProcess, ChorusShutdown, ChorusGetParam, ChorusSetParam }; //LFO shape table used by the chorus, larger table would sound better //this is a sine wave, where 32767 = 1.0 static const EAS_I16 EAS_chorusShape[CHORUS_SHAPE_SIZE] = { 0, 1608, 3212, 4808, 6393, 7962, 9512, 11309, 12539, 14010, 15446, 16846, 18204, 19519, 20787, 22005, 23170, 24279, 25329, 26319, 27245, 28105, 28898, 29621, 30273, 30852, 31356, 31785, 32137, 32412, 32609, 32728, 32767, 32728, 32609, 32412, 32137, 31785, 31356, 30852, 30273, 29621, 28898, 28105, 27245, 26319, 25329, 24279, 23170, 22005, 20787, 19519, 18204, 16846, 15446, 14010, 12539, 11039, 9512, 7962, 6393, 4808, 3212, 1608, 0, -1608, -3212, -4808, -6393, -7962, -9512, -11309, -12539, -14010, -15446, -16846, -18204, -19519, -20787, -22005, -23170, -24279, -25329, -26319, -27245, -28105, -28898, -29621, -30273, -30852, -31356, -31785, -32137, -32412, -32609, -32728, -32767, -32728, -32609, -32412, -32137, -31785, -31356, -30852, -30273, -29621, -28898, -28105, -27245, -26319, -25329, -24279, -23170, -22005, -20787, -19519, -18204, -16846, -15446, -14010, -12539, -11039, -9512, -7962, -6393, -4808, -3212, -1608 }; /*---------------------------------------------------------------------------- * InitializeChorus() *---------------------------------------------------------------------------- * Purpose: Initializes chorus parameters * * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData) { S_CHORUS_OBJECT *pChorusData; S_CHORUS_PRESET *pPreset; EAS_I32 index; /* check Configuration Module for data allocation */ if (pEASData->staticMemoryModel) pChorusData = EAS_CMEnumFXData(EAS_MODULE_CHORUS); /* allocate dynamic memory */ else pChorusData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_CHORUS_OBJECT)); if (pChorusData == NULL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Chorus memory\n"); */ } return EAS_ERROR_MALLOC_FAILED; } /* clear the structure */ EAS_HWMemSet(pChorusData, 0, sizeof(S_CHORUS_OBJECT)); ChorusReadInPresets(pChorusData); /* set some default values */ pChorusData->bypass = EAS_CHORUS_BYPASS_DEFAULT; pChorusData->preset = EAS_CHORUS_PRESET_DEFAULT; pChorusData->m_nLevel = EAS_CHORUS_LEVEL_DEFAULT; pChorusData->m_nRate = EAS_CHORUS_RATE_DEFAULT; pChorusData->m_nDepth = EAS_CHORUS_DEPTH_DEFAULT; //chorus rate and depth need some massaging from preset value (which is sample rate independent) //convert rate from steps of .05 Hz to value which can be used as phase increment, //with current CHORUS_SHAPE_SIZE and rate limits, this fits into 16 bits //want to compute ((shapeSize * 65536) * (storedRate/20))/sampleRate; //computing it as below allows rate steps to be evenly spaced //uses 32 bit divide, but only once when new value is selected pChorusData->m_nRate = (EAS_I16) ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate); //convert depth from steps of .05 ms, to samples, with 16 bit whole part, discard fraction //want to compute ((depth * sampleRate)/20000) //use the following approximation since 105/32 is roughly 65536/20000 /*lint -e{704} use shift for performance */ pChorusData->m_nDepth = (EAS_I16) (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16); pChorusData->m_nLevel = pChorusData->m_nLevel; //zero delay memory for chorus for (index = CHORUS_L_SIZE - 1; index >= 0; index--) { pChorusData->chorusDelayL[index] = 0; } for (index = CHORUS_R_SIZE - 1; index >= 0; index--) { pChorusData->chorusDelayR[index] = 0; } //init delay line index, these are used to implement circular delay buffer pChorusData->chorusIndexL = 0; pChorusData->chorusIndexR = 0; //init LFO phase //16 bit whole part, 16 bit fraction pChorusData->lfoLPhase = 0; pChorusData->lfoRPhase = (CHORUS_SHAPE_SIZE << 16) >> 2; // 1/4 of total, i.e. 90 degrees out of phase; //init chorus delay position //right now chorus delay is a compile-time value, as is sample rate pChorusData->chorusTapPosition = (EAS_I16)((CHORUS_DELAY_MS * _OUTPUT_SAMPLE_RATE)/1000); //now copy from the new preset into Chorus pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus]; pChorusData->m_nLevel = pPreset->m_nLevel; pChorusData->m_nRate = pPreset->m_nRate; pChorusData->m_nDepth = pPreset->m_nDepth; pChorusData->m_nRate = (EAS_I16) ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate); /*lint -e{704} use shift for performance */ pChorusData->m_nDepth = (EAS_I16) (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16); *pInstData = pChorusData; return EAS_SUCCESS; } /* end ChorusInit */ /*---------------------------------------------------------------------------- * WeightedTap() *---------------------------------------------------------------------------- * Purpose: Does fractional array look-up using linear interpolation * * first convert indexDesired to actual desired index by taking into account indexReference * then do linear interpolation between two actual samples using fractional part * * Inputs: * array: pointer to array of signed 16 bit values, typically either PCM data or control data * indexReference: the circular buffer relative offset * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction) * indexLimit: the total size of the array, used to compute buffer wrap * * Outputs: * Value from the input array, linearly interpolated between two actual data values * *---------------------------------------------------------------------------- */ static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit) { EAS_I16 index; EAS_I16 fraction; EAS_I16 val1; EAS_I16 val2; //separate indexDesired into whole and fractional parts /*lint -e{704} use shift for performance */ index = (EAS_I16)(indexDesired >> 16); /*lint -e{704} use shift for performance */ fraction = (EAS_I16)((indexDesired>>1) & 0x07FFF); //just use 15 bits of fractional part //adjust whole part by indexReference index = indexReference - index; //make sure we stay within array bounds, this implements circular buffer while (index < 0) { index += indexLimit; } //get two adjacent values from the array val1 = array[index]; //handle special case when index == 0, else typical case if (index == 0) { val2 = array[indexLimit-1]; //get last value from array } else { val2 = array[index-1]; //get previous value from array } //compute linear interpolation as (val1 + ((val2-val1)*fraction)) return(val1 + (EAS_I16)MULT_EG1_EG1(val2-val1,fraction)); } /*---------------------------------------------------------------------------- * ChorusProcess() *---------------------------------------------------------------------------- * Purpose: compute the chorus on the input buffer, and mix into output buffer * * * Inputs: * src: pointer to input buffer of PCM values to be processed * dst: pointer to output buffer of PCM values we are to sume the result with * bufSize: the number of sample frames (i.e. stereo samples) in the buffer * * Outputs: * None * *---------------------------------------------------------------------------- */ //compute the chorus, and mix into output buffer static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples) { EAS_I32 ix; EAS_I32 nChannelNumber; EAS_I16 lfoValueLeft; EAS_I16 lfoValueRight; EAS_I32 positionOffsetL; EAS_I32 positionOffsetR; EAS_PCM tapL; EAS_PCM tapR; EAS_I32 tempValue; EAS_PCM nInputSample; EAS_I32 nOutputSample; EAS_PCM *pIn; EAS_PCM *pOut; S_CHORUS_OBJECT *pChorusData; pChorusData = (S_CHORUS_OBJECT*) pInstData; //if the chorus is disabled or turned all the way down if (pChorusData->bypass == EAS_TRUE || pChorusData->m_nLevel == 0) { if (pSrc != pDst) EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM)); return; } if (pChorusData->m_nNextChorus != pChorusData->m_nCurrentChorus) { ChorusUpdate(pChorusData); } for (nChannelNumber = 0; nChannelNumber < NUM_OUTPUT_CHANNELS; nChannelNumber++) { pIn = pSrc + nChannelNumber; pOut = pDst + nChannelNumber; if(nChannelNumber==0) { for (ix = 0; ix < numSamples; ix++) { nInputSample = *pIn; pIn += NUM_OUTPUT_CHANNELS; //feed input into chorus delay line pChorusData->chorusDelayL[pChorusData->chorusIndexL] = nInputSample; //compute chorus lfo value using phase as fractional index into chorus shape table //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number lfoValueLeft = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoLPhase, CHORUS_SHAPE_SIZE); //scale chorus depth by lfo value to get relative fractional sample index //index is expressed as 32 bit number with 16 bit fractional part /*lint -e{703} use shift for performance */ positionOffsetL = pChorusData->m_nDepth * (((EAS_I32)lfoValueLeft) << 1); //add fixed chorus delay to get actual fractional sample index positionOffsetL += ((EAS_I32)pChorusData->chorusTapPosition) << 16; //get tap value from chorus delay using fractional sample index tapL = WeightedTap(pChorusData->chorusDelayL, pChorusData->chorusIndexL, positionOffsetL, CHORUS_L_SIZE); //scale by chorus level, then sum with input buffer contents and saturate tempValue = MULT_EG1_EG1(tapL, pChorusData->m_nLevel); nOutputSample = SATURATE(tempValue + nInputSample); *pOut = (EAS_I16)SATURATE(nOutputSample); pOut += NUM_OUTPUT_CHANNELS; //increment chorus delay index and make it wrap as needed //this implements circular buffer if ((pChorusData->chorusIndexL+=1) >= CHORUS_L_SIZE) pChorusData->chorusIndexL = 0; //increment fractional lfo phase, and make it wrap as needed pChorusData->lfoLPhase += pChorusData->m_nRate; while (pChorusData->lfoLPhase >= (CHORUS_SHAPE_SIZE<<16)) { pChorusData->lfoLPhase -= (CHORUS_SHAPE_SIZE<<16); } } } else { for (ix = 0; ix < numSamples; ix++) { nInputSample = *pIn; pIn += NUM_OUTPUT_CHANNELS; //feed input into chorus delay line pChorusData->chorusDelayR[pChorusData->chorusIndexR] = nInputSample; //compute chorus lfo value using phase as fractional index into chorus shape table //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number lfoValueRight = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoRPhase, CHORUS_SHAPE_SIZE); //scale chorus depth by lfo value to get relative fractional sample index //index is expressed as 32 bit number with 16 bit fractional part /*lint -e{703} use shift for performance */ positionOffsetR = pChorusData->m_nDepth * (((EAS_I32)lfoValueRight) << 1); //add fixed chorus delay to get actual fractional sample index positionOffsetR += ((EAS_I32)pChorusData->chorusTapPosition) << 16; //get tap value from chorus delay using fractional sample index tapR = WeightedTap(pChorusData->chorusDelayR, pChorusData->chorusIndexR, positionOffsetR, CHORUS_R_SIZE); //scale by chorus level, then sum with output buffer contents and saturate tempValue = MULT_EG1_EG1(tapR, pChorusData->m_nLevel); nOutputSample = SATURATE(tempValue + nInputSample); *pOut = (EAS_I16)SATURATE(nOutputSample); pOut += NUM_OUTPUT_CHANNELS; //increment chorus delay index and make it wrap as needed //this implements circular buffer if ((pChorusData->chorusIndexR+=1) >= CHORUS_R_SIZE) pChorusData->chorusIndexR = 0; //increment fractional lfo phase, and make it wrap as needed pChorusData->lfoRPhase += pChorusData->m_nRate; while (pChorusData->lfoRPhase >= (CHORUS_SHAPE_SIZE<<16)) { pChorusData->lfoRPhase -= (CHORUS_SHAPE_SIZE<<16); } } } } } /* end ChorusProcess */ /*---------------------------------------------------------------------------- * ChorusShutdown() *---------------------------------------------------------------------------- * Purpose: * Initializes the Chorus effect. * * Inputs: * pInstData - handle to instance data * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData) { /* check Configuration Module for static memory allocation */ if (!pEASData->staticMemoryModel) EAS_HWFree(pEASData->hwInstData, pInstData); return EAS_SUCCESS; } /* end ChorusShutdown */ /*---------------------------------------------------------------------------- * ChorusGetParam() *---------------------------------------------------------------------------- * Purpose: * Get a Chorus parameter * * Inputs: * pInstData - handle to instance data * param - parameter index * *pValue - pointer to variable to hold retrieved value * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue) { S_CHORUS_OBJECT *p; p = (S_CHORUS_OBJECT*) pInstData; switch (param) { case EAS_PARAM_CHORUS_BYPASS: *pValue = (EAS_I32) p->bypass; break; case EAS_PARAM_CHORUS_PRESET: *pValue = (EAS_I8) p->m_nCurrentChorus; break; case EAS_PARAM_CHORUS_RATE: *pValue = (EAS_I32) p->m_nRate; break; case EAS_PARAM_CHORUS_DEPTH: *pValue = (EAS_I32) p->m_nDepth; break; case EAS_PARAM_CHORUS_LEVEL: *pValue = (EAS_I32) p->m_nLevel; break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /* end ChorusGetParam */ /*---------------------------------------------------------------------------- * ChorusSetParam() *---------------------------------------------------------------------------- * Purpose: * Set a Chorus parameter * * Inputs: * pInstData - handle to instance data * param - parameter index * *pValue - new paramter value * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value) { S_CHORUS_OBJECT *p; p = (S_CHORUS_OBJECT*) pInstData; switch (param) { case EAS_PARAM_CHORUS_BYPASS: p->bypass = (EAS_BOOL) value; break; case EAS_PARAM_CHORUS_PRESET: if(value!=EAS_PARAM_CHORUS_PRESET1 && value!=EAS_PARAM_CHORUS_PRESET2 && value!=EAS_PARAM_CHORUS_PRESET3 && value!=EAS_PARAM_CHORUS_PRESET4) return EAS_ERROR_INVALID_PARAMETER; p->m_nNextChorus = (EAS_I8)value; break; case EAS_PARAM_CHORUS_RATE: if(valueEAS_CHORUS_RATE_MAX) return EAS_ERROR_INVALID_PARAMETER; p->m_nRate = (EAS_I16) value; break; case EAS_PARAM_CHORUS_DEPTH: if(valueEAS_CHORUS_DEPTH_MAX) return EAS_ERROR_INVALID_PARAMETER; p->m_nDepth = (EAS_I16) value; break; case EAS_PARAM_CHORUS_LEVEL: if(valueEAS_CHORUS_LEVEL_MAX) return EAS_ERROR_INVALID_PARAMETER; p->m_nLevel = (EAS_I16) value; break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /* end ChorusSetParam */ /*---------------------------------------------------------------------------- * ChorusReadInPresets() *---------------------------------------------------------------------------- * Purpose: sets global Chorus preset bank to defaults * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData) { int preset = 0; int defaultPreset = 0; //now init any remaining presets to defaults for (defaultPreset = preset; defaultPreset < CHORUS_MAX_TYPE; defaultPreset++) { S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[defaultPreset]; if (defaultPreset == 0 || defaultPreset > CHORUS_MAX_TYPE-1) { pPreset->m_nDepth = 39; pPreset->m_nRate = 30; pPreset->m_nLevel = 32767; } else if (defaultPreset == 1) { pPreset->m_nDepth = 21; pPreset->m_nRate = 45; pPreset->m_nLevel = 25000; } else if (defaultPreset == 2) { pPreset->m_nDepth = 53; pPreset->m_nRate = 25; pPreset->m_nLevel = 32000; } else if (defaultPreset == 3) { pPreset->m_nDepth = 32; pPreset->m_nRate = 37; pPreset->m_nLevel = 29000; } } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * ChorusUpdate *---------------------------------------------------------------------------- * Purpose: * Update the Chorus preset parameters as required * * Inputs: * * Outputs: * * * Side Effects: * - chorus paramters will be changed * - m_nCurrentRoom := m_nNextRoom *---------------------------------------------------------------------------- */ static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT *pChorusData) { S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus]; pChorusData->m_nLevel = pPreset->m_nLevel; pChorusData->m_nRate = pPreset->m_nRate; pChorusData->m_nDepth = pPreset->m_nDepth; pChorusData->m_nRate = (EAS_I16) ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate); /*lint -e{704} use shift for performance */ pChorusData->m_nDepth = (EAS_I16) (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16); pChorusData->m_nCurrentChorus = pChorusData->m_nNextChorus; return EAS_SUCCESS; } /* end ChorusUpdate */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_smf.c0000644000000000000000000000013214200302440025662 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_smf.c0000644000175000001440000011275314200302440026454 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_smf.c * * Contents and purpose: * SMF Type 0 and 1 File Parser * * For SMF timebase analysis, see "MIDI Sequencer Analysis.xls". * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 803 $ * $Date: 2007-08-01 09:57:00 -0700 (Wed, 01 Aug 2007) $ *---------------------------------------------------------------------------- */ #define LOG_TAG "Sonivox" //#include "log/log.h" #include "eas_data.h" #include "eas_miditypes.h" #include "eas_parser.h" #include "eas_report.h" #include "eas_host.h" #include "eas_midi.h" #include "eas_config.h" #include "eas_vm_protos.h" #include "eas_smfdata.h" #include "eas_smf.h" #ifdef JET_INTERFACE #include "jet_data.h" #endif //3 dls: The timebase for this module is adequate to keep MIDI and //3 digital audio synchronized for only a few minutes. It should be //3 sufficient for most mobile applications. If better accuracy is //3 required, more fractional bits should be added to the timebase. static const EAS_U8 smfHeader[] = { 'M', 'T', 'h', 'd' }; /* local prototypes */ static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData); static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream); static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode); static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode); static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream); static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks); /*---------------------------------------------------------------------------- * * SMF_Parser * * This structure contains the functional interface for the SMF parser *---------------------------------------------------------------------------- */ const S_FILE_PARSER_INTERFACE EAS_SMF_Parser = { SMF_CheckFileType, SMF_Prepare, SMF_Time, SMF_Event, SMF_State, SMF_Close, SMF_Reset, SMF_Pause, SMF_Resume, NULL, SMF_SetData, SMF_GetData, NULL }; /*---------------------------------------------------------------------------- * SMF_CheckFileType() *---------------------------------------------------------------------------- * Purpose: * Check the file type to see if we can parse it * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset) { S_SMF_DATA* pSMFData; EAS_RESULT result; /* seek to starting offset - usually 0 */ *ppHandle = NULL; if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS) return result; /* search through file for header - slow method */ if (pEASData->searchHeaderFlag) { result = EAS_SearchFile(pEASData, fileHandle, smfHeader, sizeof(smfHeader), &offset); if (result != EAS_SUCCESS) return (result == EAS_EOF) ? EAS_SUCCESS : result; } /* read the first 4 bytes of the file - quick method */ else { EAS_U8 header[4]; EAS_I32 count; if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, header, sizeof(header), &count)) != EAS_SUCCESS) return result; /* check for 'MThd' - If no match then return SUCCESS with NULL handle * to indicate not an SMF file. */ if ((header[0] != 'M') || (header[1] != 'T') || (header[2] != 'h') || (header[3] != 'd')) return EAS_SUCCESS; } /* check for static memory allocation */ if (pEASData->staticMemoryModel) pSMFData = EAS_CMEnumData(EAS_CM_SMF_DATA); else { pSMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SMF_DATA)); EAS_HWMemSet((void *)pSMFData,0, sizeof(S_SMF_DATA)); } if (!pSMFData) return EAS_ERROR_MALLOC_FAILED; /* initialize some critical data */ pSMFData->fileHandle = fileHandle; pSMFData->fileOffset = offset; pSMFData->pSynth = NULL; pSMFData->time = 0; pSMFData->state = EAS_STATE_OPEN; *ppHandle = pSMFData; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_Prepare() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. Allocates instance data (or uses static allocation for * static memory model). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_SMF_DATA* pSMFData; EAS_RESULT result; /* check for valid state */ pSMFData = (S_SMF_DATA *) pInstData; if (pSMFData->state != EAS_STATE_OPEN) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* instantiate a synthesizer */ if ((result = VMInitMIDI(pEASData, &pSMFData->pSynth)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ } return result; } /* parse the file header and setup the individual stream parsers */ if ((result = SMF_ParseHeader(pEASData->hwInstData, pSMFData)) != EAS_SUCCESS) return result; /* ready to play */ pSMFData->state = EAS_STATE_READY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_Time() *---------------------------------------------------------------------------- * Purpose: * Returns the time of the next event in msecs * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pTime - pointer to variable to hold time of next event (in msecs) * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime) { S_SMF_DATA *pSMFData; pSMFData = (S_SMF_DATA*) pInstData; /* sanity check */ #ifdef _CHECKED_BUILD if (pSMFData->state == EAS_STATE_STOPPED) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Can't ask for time on a stopped stream\n"); */ } } if (pSMFData->nextStream == NULL) { { /* dpp: EAS_ReportEx( _EAS_SEVERITY_ERROR, "no is NULL\n"); */ } } #endif #if 0 /* return time in milliseconds */ /* if chase mode, lie about time */ if (pSMFData->flags & SMF_FLAGS_CHASE_MODE) *pTime = 0; else #endif /*lint -e{704} use shift instead of division */ *pTime = pSMFData->time >> 8; *pTime = pSMFData->time >> 8; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_Event() *---------------------------------------------------------------------------- * Purpose: * Parse the next event in the file * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode) { S_SMF_DATA* pSMFData; EAS_RESULT result; EAS_I32 i; EAS_U32 ticks; EAS_U32 temp; /* establish pointer to instance data */ pSMFData = (S_SMF_DATA*) pInstData; if (pSMFData->state >= EAS_STATE_OPEN) return EAS_SUCCESS; if (!pSMFData->nextStream) { return EAS_ERROR_FILE_FORMAT; } /* get current ticks */ ticks = pSMFData->nextStream->ticks; /* assume that an error occurred */ pSMFData->state = EAS_STATE_ERROR; #ifdef JET_INTERFACE /* if JET has track muted, set parser mode to mute */ if (pSMFData->nextStream->midiStream.jetData & MIDI_FLAGS_JET_MUTE) parserMode = eParserModeMute; #endif /* parse the next event from all the streams */ if ((result = SMF_ParseEvent(pEASData, pSMFData, pSMFData->nextStream, parserMode)) != EAS_SUCCESS) { /* check for unexpected end-of-file */ if (result != EAS_EOF) return result; /* indicate end of track for this stream */ pSMFData->nextStream->ticks = SMF_END_OF_TRACK; } /* get next delta time, unless already at end of track */ else if (pSMFData->nextStream->ticks != SMF_END_OF_TRACK) { if ((result = SMF_GetDeltaTime(pEASData->hwInstData, pSMFData->nextStream)) != EAS_SUCCESS) { /* check for unexpected end-of-file */ if (result != EAS_EOF) return result; /* indicate end of track for this stream */ pSMFData->nextStream->ticks = SMF_END_OF_TRACK; } /* if zero delta to next event, stay with this stream */ else if (pSMFData->nextStream->ticks == ticks) { pSMFData->state = EAS_STATE_PLAY; return EAS_SUCCESS; } } /* find next event in all streams */ temp = 0x7ffffff; pSMFData->nextStream = NULL; for (i = 0; i < pSMFData->numStreams; i++) { if (pSMFData->streams[i].ticks < temp) { temp = pSMFData->streams[i].ticks; pSMFData->nextStream = &pSMFData->streams[i]; } } /* are there any more events to parse? */ if (pSMFData->nextStream) { pSMFData->state = EAS_STATE_PLAY; /* update the time of the next event */ SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks - ticks); } else { pSMFData->state = EAS_STATE_STOPPING; VMReleaseAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth); } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_State() *---------------------------------------------------------------------------- * Purpose: * Returns the current state of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pState - pointer to variable to store state * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState) { S_SMF_DATA* pSMFData; /* establish pointer to instance data */ pSMFData = (S_SMF_DATA*) pInstData; /* if stopping, check to see if synth voices are active */ if (pSMFData->state == EAS_STATE_STOPPING) { if (VMActiveVoices(pSMFData->pSynth) == 0) pSMFData->state = EAS_STATE_STOPPED; } if (pSMFData->state == EAS_STATE_PAUSING) { if (VMActiveVoices(pSMFData->pSynth) == 0) pSMFData->state = EAS_STATE_PAUSED; } /* return current state */ *pState = pSMFData->state; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_Close() *---------------------------------------------------------------------------- * Purpose: * Close the file and clean up * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_SMF_DATA* pSMFData; EAS_I32 i; EAS_RESULT result; pSMFData = (S_SMF_DATA*) pInstData; /* close all the streams */ for (i = 0; i < pSMFData->numStreams; i++) { if (pSMFData->streams[i].fileHandle != NULL) { if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->streams[i].fileHandle)) != EAS_SUCCESS) return result; } } if (pSMFData->fileHandle != NULL) if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->fileHandle)) != EAS_SUCCESS) return result; /* free the synth */ if (pSMFData->pSynth != NULL) VMMIDIShutdown(pEASData, pSMFData->pSynth); /* if using dynamic memory, free it */ if (!pEASData->staticMemoryModel) { if (pSMFData->streams) EAS_HWFree(pEASData->hwInstData, pSMFData->streams); /* free the instance data */ EAS_HWFree(pEASData->hwInstData, pSMFData); } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_Reset() *---------------------------------------------------------------------------- * Purpose: * Reset the sequencer. Used for locating backwards in the file. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_SMF_DATA* pSMFData; EAS_I32 i; EAS_RESULT result; EAS_U32 ticks; pSMFData = (S_SMF_DATA*) pInstData; /* reset time to zero */ pSMFData->time = 0; /* reset the synth */ VMReset(pEASData->pVoiceMgr, pSMFData->pSynth, EAS_TRUE); /* find the start of each track */ ticks = 0x7fffffffL; pSMFData->nextStream = NULL; for (i = 0; i < pSMFData->numStreams; i++) { /* reset file position to first byte of data in track */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFData->streams[i].fileHandle, pSMFData->streams[i].startFilePos)) != EAS_SUCCESS) return result; /* initalize some data */ pSMFData->streams[i].ticks = 0; /* initalize the MIDI parser data */ EAS_InitMIDIStream(&pSMFData->streams[i].midiStream); /* parse the first delta time in each stream */ if ((result = SMF_GetDeltaTime(pEASData->hwInstData,&pSMFData->streams[i])) != EAS_SUCCESS) return result; if (pSMFData->streams[i].ticks < ticks) { ticks = pSMFData->streams[i].ticks; pSMFData->nextStream = &pSMFData->streams[i]; } } pSMFData->state = EAS_STATE_READY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_Pause() *---------------------------------------------------------------------------- * Purpose: * Pauses the sequencer. Mutes all voices and sets state to pause. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_SMF_DATA *pSMFData; /* can't pause a stopped stream */ pSMFData = (S_SMF_DATA*) pInstData; if (pSMFData->state == EAS_STATE_STOPPED) return EAS_ERROR_ALREADY_STOPPED; /* mute the synthesizer */ VMMuteAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth); pSMFData->state = EAS_STATE_PAUSING; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_Resume() *---------------------------------------------------------------------------- * Purpose: * Resume playing after a pause, sets state back to playing. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_SMF_DATA *pSMFData; /* can't resume a stopped stream */ pSMFData = (S_SMF_DATA*) pInstData; if (pSMFData->state == EAS_STATE_STOPPED) return EAS_ERROR_ALREADY_STOPPED; /* nothing to do but resume playback */ pSMFData->state = EAS_STATE_PLAY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_SetData() *---------------------------------------------------------------------------- * Purpose: * Sets parser parameters * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value) { S_SMF_DATA *pSMFData; pSMFData = (S_SMF_DATA*) pInstData; switch (param) { /* set metadata callback */ case PARSER_DATA_METADATA_CB: EAS_HWMemCpy(&pSMFData->metadata, (void*) value, sizeof(S_METADATA_CB)); break; #ifdef JET_INTERFACE /* set jet segment and track ID of all tracks for callback function */ case PARSER_DATA_JET_CB: { EAS_U32 i; EAS_U32 bit = (EAS_U32) value; bit = (bit << JET_EVENT_SEG_SHIFT) & JET_EVENT_SEG_MASK; for (i = 0; i < pSMFData->numStreams; i++) pSMFData->streams[i].midiStream.jetData = (pSMFData->streams[i].midiStream.jetData & ~(JET_EVENT_TRACK_MASK | JET_EVENT_SEG_MASK)) | i << JET_EVENT_TRACK_SHIFT | bit | MIDI_FLAGS_JET_CB; pSMFData->flags |= SMF_FLAGS_JET_STREAM; } break; /* set state of all mute flags at once */ case PARSER_DATA_MUTE_FLAGS: { EAS_INT i; EAS_U32 bit = (EAS_U32) value; for (i = 0; i < pSMFData->numStreams; i++) { if (bit & 1) pSMFData->streams[i].midiStream.jetData |= MIDI_FLAGS_JET_MUTE; else pSMFData->streams[i].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE; bit >>= 1; } } break; /* set track mute */ case PARSER_DATA_SET_MUTE: if (value < pSMFData->numStreams) pSMFData->streams[value].midiStream.jetData |= MIDI_FLAGS_JET_MUTE; else return EAS_ERROR_PARAMETER_RANGE; break; /* clear track mute */ case PARSER_DATA_CLEAR_MUTE: if (value < pSMFData->numStreams) pSMFData->streams[value].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE; else return EAS_ERROR_PARAMETER_RANGE; break; #endif default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_GetData() *---------------------------------------------------------------------------- * Purpose: * Retrieves parser parameters * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) reserved for future use */ EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue) { S_SMF_DATA *pSMFData; pSMFData = (S_SMF_DATA*) pInstData; switch (param) { /* return file type */ case PARSER_DATA_FILE_TYPE: if (pSMFData->numStreams == 1) *pValue = EAS_FILE_SMF0; else *pValue = EAS_FILE_SMF1; break; /* now handled in eas_public.c */ #if 0 case PARSER_DATA_POLYPHONY: if (pSMFData->pSynth) VMGetPolyphony(pEASData->pVoiceMgr, pSMFData->pSynth, pValue); else return EAS_ERROR_NOT_VALID_IN_THIS_STATE; break; case PARSER_DATA_PRIORITY: if (pSMFData->pSynth) VMGetPriority(pEASData->pVoiceMgr, pSMFData->pSynth, pValue); break; /* set transposition */ case PARSER_DATA_TRANSPOSITION: *pValue = pSMFData->transposition; break; #endif case PARSER_DATA_SYNTH_HANDLE: *pValue = (EAS_I32) pSMFData->pSynth; break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_GetVarLenData() *---------------------------------------------------------------------------- * Purpose: * Reads a varible length quantity from an SMF file * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData) { EAS_RESULT result; EAS_U32 data; EAS_U8 c; /* read until bit 7 is zero */ data = 0; do { if ((result = EAS_HWGetByte(hwInstData, fileHandle,&c)) != EAS_SUCCESS) return result; data = (data << 7) | (c & 0x7f); } while (c & 0x80); *pData = data; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_GetDeltaTime() *---------------------------------------------------------------------------- * Purpose: * Reads a varible length quantity from an SMF file * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream) { EAS_RESULT result; EAS_U32 ticks; if ((result = SMF_GetVarLenData(hwInstData, pSMFStream->fileHandle, &ticks)) != EAS_SUCCESS) return result; pSMFStream->ticks += ticks; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_ParseMetaEvent() *---------------------------------------------------------------------------- * Purpose: * Reads a varible length quantity from an SMF file * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream) { EAS_RESULT result; EAS_U32 len; EAS_I32 pos; EAS_U32 temp; EAS_U8 c; /* get the meta-event type */ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS) return result; /* get the length */ if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS) return result; /* get the current file position so we can skip the event */ if ((result = EAS_HWFilePos(pEASData->hwInstData, pSMFStream->fileHandle, &pos)) != EAS_SUCCESS) return result; /* prevent a large unsigned length from being treated as a negative length */ if ((EAS_I32) len < 0) { /* note that EAS_I32 is a long, which can be 64-bits on some computers */ //ALOGE("%s() negative len = %ld", __func__, (long) len); //android_errorWriteLog(0x534e4554, "68953854"); return EAS_ERROR_FILE_FORMAT; } /* prevent numeric overflow caused by a very large len, assume pos > 0 */ const EAS_I32 EAS_I32_MAX = 0x7FFFFFFF; if ((EAS_I32) len > (EAS_I32_MAX - pos)) { //ALOGE("%s() too large len = %ld", __func__, (long) len); //android_errorWriteLog(0x534e4554, "68953854"); return EAS_ERROR_FILE_FORMAT; } pos += (EAS_I32) len; /* end of track? */ if (c == SMF_META_END_OF_TRACK) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: end of track\n", c, len); */ } pSMFStream->ticks = SMF_END_OF_TRACK; } /* tempo event? */ else if (c == SMF_META_TEMPO) { /* read the 3-byte timebase value */ temp = 0; while (len--) { if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS) return result; temp = (temp << 8) | c; } pSMFData->tickConv = (EAS_U16) (((temp * 1024) / pSMFData->ppqn + 500) / 1000); pSMFData->flags |= SMF_FLAGS_HAS_TEMPO; } /* check for time signature - see iMelody spec V1.4 section 4.1.2.2.3.6 */ else if (c == SMF_META_TIME_SIGNATURE) { pSMFData->flags |= SMF_FLAGS_HAS_TIME_SIG; } /* if the host has registered a metadata callback return the metadata */ else if (pSMFData->metadata.callback) { EAS_I32 readLen; E_EAS_METADATA_TYPE metaType; metaType = EAS_METADATA_UNKNOWN; /* only process title on the first track */ if (c == SMF_META_SEQTRK_NAME) metaType = EAS_METADATA_TITLE; else if (c == SMF_META_TEXT) metaType = EAS_METADATA_TEXT; else if (c == SMF_META_COPYRIGHT) metaType = EAS_METADATA_COPYRIGHT; else if (c == SMF_META_LYRIC) metaType = EAS_METADATA_LYRIC; if (metaType != EAS_METADATA_UNKNOWN) { readLen = pSMFData->metadata.bufferSize - 1; if ((EAS_I32) len < readLen) readLen = (EAS_I32) len; if ((result = EAS_HWReadFile(pEASData->hwInstData, pSMFStream->fileHandle, pSMFData->metadata.buffer, readLen, &readLen)) != EAS_SUCCESS) return result; pSMFData->metadata.buffer[readLen] = 0; pSMFData->metadata.callback(metaType, pSMFData->metadata.buffer, pSMFData->metadata.pUserData); } } /* position file to next event - in case we ignored all or part of the meta-event */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFStream->fileHandle, pos)) != EAS_SUCCESS) return result; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: type=%02x, len=%d\n", c, len); */ } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_ParseSysEx() *---------------------------------------------------------------------------- * Purpose: * Reads a varible length quantity from an SMF file * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode) { EAS_RESULT result; EAS_U32 len; EAS_U8 c; /* get the length */ if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS) return result; /* start of SysEx message? */ if (f0 == 0xf0) { if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, f0, parserMode)) != EAS_SUCCESS) return result; } /* feed the SysEx to the stream parser */ while (len--) { if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS) return result; if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS) return result; /* check for GM system ON */ if (pSMFStream->midiStream.flags & MIDI_FLAG_GM_ON) pSMFData->flags |= SMF_FLAGS_HAS_GM_ON; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_ParseEvent() *---------------------------------------------------------------------------- * Purpose: * Reads a varible length quantity from an SMF file * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode) { EAS_RESULT result; EAS_U8 c; /* get the event type */ if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS) return result; /* parse meta-event */ if (c == 0xff) { if ((result = SMF_ParseMetaEvent(pEASData, pSMFData, pSMFStream)) != EAS_SUCCESS) return result; } /* parse SysEx */ else if ((c == 0xf0) || (c == 0xf7)) { if ((result = SMF_ParseSysEx(pEASData, pSMFData, pSMFStream, c, parserMode)) != EAS_SUCCESS) return result; } /* parse MIDI message */ else { if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS) return result; /* keep streaming data to the MIDI parser until the message is complete */ while (pSMFStream->midiStream.pending) { if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS) return result; if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS) return result; } } /* chase mode logic */ if (pSMFData->time == 0) { if (pSMFData->flags & SMF_FLAGS_CHASE_MODE) { if (pSMFStream->midiStream.flags & MIDI_FLAG_FIRST_NOTE) pSMFData->flags &= ~SMF_FLAGS_CHASE_MODE; } else if ((pSMFData->flags & SMF_FLAGS_SETUP_BAR) == SMF_FLAGS_SETUP_BAR) pSMFData->flags = (pSMFData->flags & ~SMF_FLAGS_SETUP_BAR) | SMF_FLAGS_CHASE_MODE; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * SMF_ParseHeader() *---------------------------------------------------------------------------- * Purpose: * Parses the header of an SMF file, allocates memory the stream parsers and initializes the * stream parsers. * * Inputs: * pEASData - pointer to overall EAS data structure * pSMFData - pointer to parser instance data * fileHandle - file handle * fileOffset - offset in the file where the header data starts, usually 0 * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -e{801} we know that 'goto' is deprecated - but it's cleaner in this case */ EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData) { EAS_RESULT result; EAS_I32 i; EAS_U16 division; EAS_U16 numStreams; EAS_U32 chunkSize; EAS_U32 chunkStart; EAS_U32 temp; EAS_U32 ticks; /* explicitly set numStreams to 0. It will later be used by SMF_Close to * determine whether we have valid streams or not. */ pSMFData->numStreams = 0; /* rewind the file and find the end of the header chunk */ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_HEADER_SIZE)) != EAS_SUCCESS) goto ReadError; if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS) goto ReadError; /* determine the number of tracks */ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_NUM_TRACKS)) != EAS_SUCCESS) goto ReadError; if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &numStreams, EAS_TRUE)) != EAS_SUCCESS) goto ReadError; /* limit the number of tracks */ if (numStreams > MAX_SMF_STREAMS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "SMF file contains %u tracks, playing %d tracks\n", numStreams, MAX_SMF_STREAMS); */ } numStreams = MAX_SMF_STREAMS; } else if (numStreams == 0) { /* avoid 0 sized allocation */ return EAS_ERROR_PARAMETER_RANGE; } /* get the time division */ if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &division, EAS_TRUE)) != EAS_SUCCESS) goto ReadError; /* setup default timebase for 120 bpm */ pSMFData->ppqn = 192; if (!division || division & 0x8000) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"No support for SMPTE code timebase\n"); */ } else pSMFData->ppqn = (division & 0x7fff); pSMFData->tickConv = (EAS_U16) (((SMF_DEFAULT_TIMEBASE * 1024) / pSMFData->ppqn + 500) / 1000); /* dynamic memory allocation, allocate memory for streams */ if (pSMFData->streams == NULL) { pSMFData->streams = EAS_HWMalloc(hwInstData,sizeof(S_SMF_STREAM) * numStreams); if (pSMFData->streams == NULL) return EAS_ERROR_MALLOC_FAILED; /* zero the memory to insure complete initialization */ EAS_HWMemSet((void *)(pSMFData->streams), 0, sizeof(S_SMF_STREAM) * numStreams); } pSMFData->numStreams = numStreams; /* find the start of each track */ chunkStart = (EAS_U32) pSMFData->fileOffset; ticks = 0x7fffffffL; pSMFData->nextStream = NULL; for (i = 0; i < pSMFData->numStreams; i++) { for (;;) { /* calculate start of next chunk - checking for errors */ temp = chunkStart + SMF_CHUNK_INFO_SIZE + chunkSize; if (temp <= chunkStart) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Error in chunk size at offset %d\n", chunkStart); */ } return EAS_ERROR_FILE_FORMAT; } chunkStart = temp; /* seek to the start of the next chunk */ if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, (EAS_I32) chunkStart)) != EAS_SUCCESS) goto ReadError; /* read the chunk identifier */ if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS) goto ReadError; /* read the chunk size */ if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS) goto ReadError; /* make sure this is an 'MTrk' chunk */ if (temp == SMF_CHUNK_TYPE_TRACK) break; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Unexpected chunk type: 0x%08x\n", temp); */ } } /* initalize some data */ pSMFData->streams[i].ticks = 0; pSMFData->streams[i].fileHandle = pSMFData->fileHandle; /* NULL the file handle so we don't try to close it twice */ pSMFData->fileHandle = NULL; /* save this file position as the start of the track */ pSMFData->streams[i].startFilePos = (EAS_I32) chunkStart + SMF_CHUNK_INFO_SIZE; /* initalize the MIDI parser data */ EAS_InitMIDIStream(&pSMFData->streams[i].midiStream); /* parse the first delta time in each stream */ if ((result = SMF_GetDeltaTime(hwInstData, &pSMFData->streams[i])) != EAS_SUCCESS) goto ReadError; if (pSMFData->streams[i].ticks < ticks) { ticks = pSMFData->streams[i].ticks; pSMFData->nextStream = &pSMFData->streams[i]; } /* more tracks to do, create a duplicate file handle */ if (i < (pSMFData->numStreams - 1)) { if ((result = EAS_HWDupHandle(hwInstData, pSMFData->streams[i].fileHandle, &pSMFData->fileHandle)) != EAS_SUCCESS) goto ReadError; } } /* update the time of the next event */ if (pSMFData->nextStream) SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks); return EAS_SUCCESS; /* ugly goto: but simpler than structured */ ReadError: if (result == EAS_EOF) return EAS_ERROR_FILE_FORMAT; return result; } /*---------------------------------------------------------------------------- * SMF_UpdateTime() *---------------------------------------------------------------------------- * Purpose: * Update the millisecond time base by converting the ticks into millieconds * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks) { EAS_U32 temp1, temp2; if (pSMFData->flags & SMF_FLAGS_CHASE_MODE) return; temp1 = (ticks >> 10) * pSMFData->tickConv; temp2 = (ticks & 0x3ff) * pSMFData->tickConv; pSMFData->time += (EAS_I32)((temp1 << 8) + (temp2 >> 2)); } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_imelodydata.h0000644000000000000000000000013214200302440027376 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.269324464 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_imelodydata.h0000644000175000001440000000607714200302440030171 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_imelodydata.h * * Contents and purpose: * SMF File Parser * * This file contains data declarations for the iMelody parser. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 778 $ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $ *---------------------------------------------------------------------------- */ #ifndef EAS_IMELODYDATA_H #define EAS_IMELODYDATA_H #include "eas_data.h" /* maximum line size as specified in iMelody V1.2 spec */ #define MAX_LINE_SIZE 75 /*---------------------------------------------------------------------------- * * S_IMELODY_DATA * * This structure contains the state data for the iMelody parser *---------------------------------------------------------------------------- */ typedef struct { EAS_FILE_HANDLE fileHandle; /* file handle */ S_SYNTH *pSynth; /* pointer to synth */ EAS_I32 fileOffset; /* offset to start of data */ EAS_I32 time; /* current time in 256ths of a msec */ EAS_I32 tickBase; /* basline length of 32nd note in 256th of a msec */ EAS_I32 tick; /* actual length of 32nd note in 256th of a msec */ EAS_I32 restTicks; /* ticks to rest after current note */ EAS_I32 startLine; /* file offset at start of line (for repeats) */ EAS_I32 repeatOffset; /* file offset to start of repeat section */ EAS_I32 repeatTime; /* time at start of repeat section */ S_METADATA_CB metadata; /* metadata callback */ EAS_I16 repeatCount; /* repeat counter */ EAS_U8 state; /* current state EAS_STATE_XXXX */ EAS_U8 style; /* from STYLE */ EAS_U8 index; /* index into buffer */ EAS_U8 octave; /* octave prefix */ EAS_U8 volume; /* current volume */ EAS_U8 note; /* MIDI note number */ EAS_I8 noteModifier; /* sharp or flat */ EAS_I8 buffer[MAX_LINE_SIZE+1]; /* buffer for ASCII data */ } S_IMELODY_DATA; #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_ota.c0000644000000000000000000000013214200302440025660 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_ota.c0000644000175000001440000010176014200302440026446 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_ota.c * * Contents and purpose: * OTA parser * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 795 $ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $ *---------------------------------------------------------------------------- */ #define LOG_TAG "Sonivox" #include #include "eas_data.h" #include "eas_miditypes.h" #include "eas_parser.h" #include "eas_report.h" #include "eas_host.h" #include "eas_midi.h" #include "eas_config.h" #include "eas_vm_protos.h" #include "eas_otadata.h" /* increase gain for mono ringtones */ #define OTA_GAIN_OFFSET 8 /* file definitions */ #define OTA_RINGTONE 0x25 #define OTA_SOUND 0x1d #define OTA_UNICODE 0x22 /* song type definitions */ #define OTA_BASIC_SONG_TYPE 0x01 #define OTA_TEMPORARY_SONG_TYPE 0x02 /* instruction ID coding */ #define OTA_PATTERN_HEADER_ID 0x00 #define OTA_NOTE_INST_ID 0x01 #define OTA_SCALE_INST_ID 0x02 #define OTA_STYLE_INST_ID 0x03 #define OTA_TEMPO_INST_ID 0x04 #define OTA_VOLUME_INST_ID 0x05 /* note durations */ #define OTA_NORMAL_DURATION 0x00 #define OTA_DOTTED_NOTE 0x01 #define OTA_DOUBLE_DOTTED_NOTE 0x02 #define OTA_TRIPLET_NOTE 0x03 /* loop count value for infinite loop */ #define OTA_INFINITE_LOOP 0x0f /* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */ #define DEFAULT_TICK_CONV 30476 /* default channel and program for OTA playback */ #define OTA_CHANNEL 0 #define OTA_PROGRAM 80 #define OTA_VEL_MUL 4 #define OTA_VEL_OFS 67 #define OTA_VEL_DEFAULT 95 /* multiplier for fixed point triplet conversion */ #define TRIPLET_MULTIPLIER 683 #define TRIPLET_SHIFT 10 /* local prototypes */ static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset); static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime); static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode); static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState); static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData); static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue); static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc); static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc); /*---------------------------------------------------------------------------- * * EAS_OTA_Parser * * This structure contains the functional interface for the OTA parser *---------------------------------------------------------------------------- */ const S_FILE_PARSER_INTERFACE EAS_OTA_Parser = { OTA_CheckFileType, OTA_Prepare, OTA_Time, OTA_Event, OTA_State, OTA_Close, OTA_Reset, OTA_Pause, OTA_Resume, NULL, OTA_SetData, OTA_GetData, NULL }; /*---------------------------------------------------------------------------- * * bpmTable * * BPM conversion table. Converts bpm values to 256ths of a millisecond for a 32nd note *---------------------------------------------------------------------------- */ static const EAS_U32 bpmTable[32] = { 76800, 68571, 61935, 54857, 48000, 42667, 38400, 34286, 30476, 27429, 24000, 21333, 19200, 17143, 15360, 13714, 12000, 10667, 9600, 8533, 7680, 6737, 6000, 5408, 4800, 4267, 3840, 3398, 3024, 2685, 2400, 2133 }; /*---------------------------------------------------------------------------- * OTA_CheckFileType() *---------------------------------------------------------------------------- * Purpose: * Check the file type to see if we can parse it * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset) { S_OTA_DATA* pData; EAS_RESULT result; EAS_INT cmdLen; EAS_INT state; EAS_U8 temp; /* read the first byte, should be command length */ *ppHandle = NULL; if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS) return result; /* read all the commands */ cmdLen = temp; state = 0; while (cmdLen--) { /* read the command, upper 7 bits */ if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS) return result; temp = temp >> 1; if (state == 0) { if (temp != OTA_RINGTONE) break; state++; } else { if (temp == OTA_SOUND) { /* check for static memory allocation */ if (pEASData->staticMemoryModel) pData = EAS_CMEnumData(EAS_CM_OTA_DATA); else pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_OTA_DATA)); if (!pData) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Malloc failed in OTA_Prepare\n"); */ } return EAS_ERROR_MALLOC_FAILED; } EAS_HWMemSet(pData, 0, sizeof(S_OTA_DATA)); /* return a pointer to the instance data */ pData->fileHandle = fileHandle; pData->fileOffset = offset; pData->state = EAS_STATE_OPEN; *ppHandle = pData; ALOGD("%s() OTA file recognized", __func__); break; } if (temp != OTA_UNICODE) break; } } /* not recognized */ return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_Prepare() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. Allocates instance data (or uses static allocation for * static memory model). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_OTA_DATA* pData; EAS_RESULT result; /* check for valid state */ pData = (S_OTA_DATA*) pInstData; if (pData->state != EAS_STATE_OPEN) return EAS_ERROR_NOT_VALID_IN_THIS_STATE; /* instantiate a synthesizer */ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ } return result; } pData->state = EAS_STATE_ERROR; if ((result = OTA_ParseHeader(pEASData, pData)) != EAS_SUCCESS) return result; pData->state = EAS_STATE_READY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_Time() *---------------------------------------------------------------------------- * Purpose: * Returns the time of the next event in msecs * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pTime - pointer to variable to hold time of next event (in msecs) * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) common decoder interface - pEASData not used */ static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime) { S_OTA_DATA *pData; pData = (S_OTA_DATA*) pInstData; /* return time in milliseconds */ /*lint -e{704} use shift instead of division */ *pTime = pData->time >> 8; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_Event() *---------------------------------------------------------------------------- * Purpose: * Parse the next event in the file * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode) { S_OTA_DATA* pData; EAS_RESULT result; EAS_U32 duration; EAS_U8 temp; pData = (S_OTA_DATA*) pInstData; if (pData->state >= EAS_STATE_OPEN) return EAS_SUCCESS; /* initialize MIDI channel when the track starts playing */ if (pData->time == 0) { /* set program to square lead */ if (parserMode != eParserModeMetaData) VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, OTA_PROGRAM); /* set channel volume to max */ if (parserMode != eParserModeMetaData) VMControlChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, 7, 127); } /* check for end of note */ if (pData->note) { /* stop the note */ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, 0); pData->note = 0; /* check for rest between notes */ if (pData->restTicks) { pData->time += (EAS_I32) pData->restTicks; pData->restTicks = 0; return EAS_SUCCESS; } } /* if not in a pattern, read the pattern header */ while (pData->current.patternLen == 0) { /* check for loop - don't do infinite loops when locating */ if (pData->loopCount && ((parserMode == eParserModePlay) || (pData->loopCount != OTA_INFINITE_LOOP))) { ALOGV("%s() loop backwards, loopCount = %d", __func__, pData->loopCount); /* if not infinite loop, decrement loop count */ if (pData->loopCount != OTA_INFINITE_LOOP) pData->loopCount--; /* back to start of pattern*/ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS) return result; } /* if no previous position to restore, continue forward */ else if (pData->restore.fileOffset < 0) { /* check for end of song */ if (pData->numPatterns == 0) { pData->state = EAS_STATE_STOPPING; VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth); return EAS_SUCCESS; } /* read the next pattern header */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS) return result; if (temp != OTA_PATTERN_HEADER_ID) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA pattern header\n"); */ } return EAS_ERROR_FILE_FORMAT; } /* get the pattern ID */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->currentPattern)) != EAS_SUCCESS) return result; /* get the loop count */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->loopCount)) != EAS_SUCCESS) return result; /* get the pattern length */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->current.patternLen)) != EAS_SUCCESS) return result; /* if pattern definition, save the current position */ if (pData->current.patternLen) { if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS) return result; } /* if pattern length is zero, repeat a previous pattern */ else { /* make sure it's a valid pattern */ if (pData->patterns[pData->currentPattern].fileOffset < 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA pattern error, invalid pattern specified\n"); */ } return EAS_ERROR_FILE_FORMAT; } /* save current position and data */ if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS) return result; /* seek to the pattern in the file */ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS) return result; } /* decrement pattern count */ pData->numPatterns--; } /* restore previous position */ else { if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS) return result; } } /* get the next event */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS) return result; switch (temp) { case OTA_NOTE_INST_ID: /* fetch note value */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->note)) != EAS_SUCCESS) return result; /* fetch note duration */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS) return result; duration = pData->tick * (0x20 >> temp); /* fetch note duration modifier */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS) return result; switch (temp) { case OTA_NORMAL_DURATION: break; case OTA_DOTTED_NOTE: duration += duration >> 1; break; case OTA_DOUBLE_DOTTED_NOTE: duration += (duration >> 1) + (duration >> 2); break; case OTA_TRIPLET_NOTE: duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT; break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note duration ignored\n"); */ } break; } /* check for note */ if (pData->note) { /* determine note length based on style */ switch (pData->style) { case 0: pData->restTicks = duration >> 4; break; case 1: pData->restTicks = 0; break; case 2: pData->restTicks = duration >> 1; break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note style ignored\n"); */ } } /* add octave */ pData->note += pData->octave; if (parserMode == eParserModePlay) VMStartNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, pData->velocity); pData->time += (EAS_I32) duration - (EAS_I32) pData->restTicks; } /* this is a rest */ else pData->time += (EAS_I32) duration; break; case OTA_SCALE_INST_ID: /* fetch octave */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS) return result; pData->octave = (EAS_U8) (temp * 12 + 59); break; case OTA_STYLE_INST_ID: /* fetch note style */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->style)) != EAS_SUCCESS) return result; break; case OTA_TEMPO_INST_ID: /* fetch tempo */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 5, &temp)) != EAS_SUCCESS) return result; pData->tick = bpmTable[temp]; break; case OTA_VOLUME_INST_ID: /* fetch volume */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &temp)) != EAS_SUCCESS) return result; pData->velocity = temp ? (EAS_U8) (temp * OTA_VEL_MUL + OTA_VEL_OFS) : 0; break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected instruction ID in OTA stream\n"); */ } return EAS_ERROR_FILE_FORMAT; } /* decrement pattern length */ pData->current.patternLen--; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_State() *---------------------------------------------------------------------------- * Purpose: * Returns the current state of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * pState - pointer to variable to store state * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) common decoder interface - pEASData not used */ static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState) { S_OTA_DATA* pData; /* establish pointer to instance data */ pData = (S_OTA_DATA*) pInstData; /* if stopping, check to see if synth voices are active */ if (pData->state == EAS_STATE_STOPPING) { if (VMActiveVoices(pData->pSynth) == 0) pData->state = EAS_STATE_STOPPED; } if (pData->state == EAS_STATE_PAUSING) { if (VMActiveVoices(pData->pSynth) == 0) pData->state = EAS_STATE_PAUSED; } /* return current state */ *pState = pData->state; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_Close() *---------------------------------------------------------------------------- * Purpose: * Close the file and clean up * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_OTA_DATA* pData; EAS_RESULT result; pData = (S_OTA_DATA*) pInstData; /* close the file */ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS) return result; /* free the synth */ if (pData->pSynth != NULL) VMMIDIShutdown(pEASData, pData->pSynth); /* if using dynamic memory, free it */ if (!pEASData->staticMemoryModel) EAS_HWFree(pEASData->hwInstData, pData); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_Reset() *---------------------------------------------------------------------------- * Purpose: * Reset the sequencer. Used for locating backwards in the file. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_OTA_DATA* pData; EAS_RESULT result; pData = (S_OTA_DATA*) pInstData; /* reset the synth */ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE); pData->note = 0; /* reset file position and re-parse header */ pData->state = EAS_STATE_ERROR; if ((result = OTA_ParseHeader (pEASData, pData)) != EAS_SUCCESS) return result; pData->state = EAS_STATE_READY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_Pause() *---------------------------------------------------------------------------- * Purpose: * Pauses the sequencer. Mutes all voices and sets state to pause. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_OTA_DATA *pData; /* can't pause a stopped stream */ pData = (S_OTA_DATA*) pInstData; if (pData->state == EAS_STATE_STOPPED) return EAS_ERROR_ALREADY_STOPPED; /* mute the synthesizer */ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth); pData->state = EAS_STATE_PAUSING; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_Resume() *---------------------------------------------------------------------------- * Purpose: * Resume playing after a pause, sets state back to playing. * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) common decoder interface - pEASData not used */ static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData) { S_OTA_DATA *pData; /* can't resume a stopped stream */ pData = (S_OTA_DATA*) pInstData; if (pData->state == EAS_STATE_STOPPED) return EAS_ERROR_ALREADY_STOPPED; /* nothing to do but resume playback */ pData->state = EAS_STATE_PLAY; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_SetData() *---------------------------------------------------------------------------- * Purpose: * Return file type * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) common decoder interface - pEASData not used */ static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value) { S_OTA_DATA *pData; pData = (S_OTA_DATA *) pInstData; switch (param) { /* set metadata callback */ case PARSER_DATA_METADATA_CB: EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB)); break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_GetData() *---------------------------------------------------------------------------- * Purpose: * Return file type * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) common decoder interface - pEASData not used */ static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue) { S_OTA_DATA *pData; pData = (S_OTA_DATA*) pInstData; switch (param) { /* return file type as OTA */ case PARSER_DATA_FILE_TYPE: *pValue = EAS_FILE_OTA; break; #if 0 /* set transposition */ case PARSER_DATA_TRANSPOSITION: *pValue = pData->transposition; break; #endif case PARSER_DATA_SYNTH_HANDLE: *pValue = (EAS_I32) pData->pSynth; break; case PARSER_DATA_GAIN_OFFSET: *pValue = OTA_GAIN_OFFSET; break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_ParseHeader() *---------------------------------------------------------------------------- * Purpose: * Prepare to parse the file. Allocates instance data (or uses static allocation for * static memory model). * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData) { EAS_RESULT result; EAS_INT i; EAS_INT state; EAS_U8 temp; EAS_U8 titleLen; /* initialize some data */ pData->flags = 0; pData->time = 0; pData->tick = DEFAULT_TICK_CONV; pData->patterns[0].fileOffset = pData->patterns[1].fileOffset = pData->patterns[2].fileOffset = pData->patterns[3].fileOffset = -1; pData->current.bitCount = 0; pData->current.patternLen = 0; pData->loopCount = 0; pData->restore.fileOffset = -1; pData->note = 0; pData->restTicks = 0; pData->velocity = OTA_VEL_DEFAULT; pData->style = 0; pData->octave = 59; /* seek to start of data */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS) return result; /* read the first byte, should be command length */ if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS) return result; /* read all the commands */ i = temp; state = 0; while (i--) { /* fetch command, always starts on byte boundary */ pData->current.bitCount = 0; if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 7, &temp)) != EAS_SUCCESS) return result; if (state == 0) { if (temp != OTA_RINGTONE) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Ring Tone Programming type\n"); */ } return EAS_ERROR_FILE_FORMAT; } state++; } else { if (temp == OTA_SOUND) break; if (temp == OTA_UNICODE) pData->flags |= OTA_FLAGS_UNICODE; else { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Sound or Unicode type\n"); */ } return EAS_ERROR_FILE_FORMAT; } } } /* get song type */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS) return result; /* check for basic song type */ if (temp == OTA_BASIC_SONG_TYPE) { /* fetch title length */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &titleLen)) != EAS_SUCCESS) return result; /* if unicode, double the length */ if (pData->flags & OTA_FLAGS_UNICODE) titleLen = (EAS_U8) (titleLen << 1); /* zero the metadata buffer */ if (pData->metadata.buffer) EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize); /* read the song title */ for (i = 0; i < titleLen; i++) { /* fetch character */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &temp)) != EAS_SUCCESS) return result; /* check for metadata callback */ if (pData->metadata.callback) { if (i < (pData->metadata.bufferSize - 1)) pData->metadata.buffer[i] = (char) temp; } } /* if host has registered callback, call it now */ if (pData->metadata.callback) (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData); } /* must be temporary song */ else if (temp != OTA_TEMPORARY_SONG_TYPE) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA basic or temporary song type\n"); */ } return EAS_ERROR_FILE_FORMAT; } /* get the song length */ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->numPatterns)) != EAS_SUCCESS) return result; /* sanity check */ if (pData->numPatterns == 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA number of patterns is zero\n"); */ } return EAS_ERROR_FILE_FORMAT; } /* at start of first pattern */ return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_FetchBitField() *---------------------------------------------------------------------------- * Purpose: * Fetch a specified number of bits from the input stream * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue) { EAS_RESULT result; EAS_I32 bitsLeft; EAS_U8 value; value = 0; /* do we have enough bits? */ bitsLeft = pData->current.bitCount - numBits; /* not enough bits, assemble them from 2 characters */ if (bitsLeft < 0) { /* grab the remaining bits from the previous byte */ if (pData->current.bitCount) /*lint -e{504,734} this is a legitimate shift operation */ value = pData->current.dataByte << -bitsLeft; /* read the next byte */ if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->current.dataByte)) != EAS_SUCCESS) return result; bitsLeft += 8; } /* more bits than needed? */ if (bitsLeft > 0) { value |= pData->current.dataByte >> bitsLeft; pData->current.bitCount = (EAS_U8) bitsLeft; pData->current.dataByte = pData->current.dataByte & (0xff >> (8 - bitsLeft)); } /* exactly the right number of bits */ else { value |= pData->current.dataByte; pData->current.bitCount = 0; } *pValue = value; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * OTA_SavePosition() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc) { EAS_HWMemCpy(pLoc, &pData->current, sizeof(S_OTA_LOC)); return EAS_HWFilePos(hwInstData, pData->fileHandle, &pLoc->fileOffset); } /*---------------------------------------------------------------------------- * OTA_RestorePosition() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc) { EAS_HWMemCpy(&pData->current, pLoc, sizeof(S_OTA_LOC)); pData->restore.fileOffset = -1; return EAS_HWFileSeek(hwInstData, pData->fileHandle, pLoc->fileOffset); } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_imaadpcm.c0000644000000000000000000000013214200302440026650 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.269324464 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_imaadpcm.c0000644000175000001440000002764214200302440027444 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_imaadpcm.c * * Contents and purpose: * Implements the IMA ADPCM decoder * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 847 $ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $ *---------------------------------------------------------------------------- */ #include "eas_data.h" #include "eas_host.h" #include "eas_pcm.h" #include "eas_math.h" #include "eas_report.h" // #define _DEBUG_IMA_ADPCM_LOCATE /*---------------------------------------------------------------------------- * externs *---------------------------------------------------------------------------- */ extern const EAS_I16 imaIndexTable[]; extern const EAS_I16 imaStepSizeTable[]; /*---------------------------------------------------------------------------- * prototypes *---------------------------------------------------------------------------- */ static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState); static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState); static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble); static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time); /*---------------------------------------------------------------------------- * IMA ADPCM Decoder interface *---------------------------------------------------------------------------- */ const S_DECODER_INTERFACE IMADecoder = { IMADecoderInit, IMADecoderSample, IMADecoderLocate }; /*---------------------------------------------------------------------------- * IMADecoderInit() *---------------------------------------------------------------------------- * Purpose: * Initializes the IMA ADPCM decoder * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pEASData) common decoder interface - pEASData not used */ static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState) { pState->decoderL.step = 0; pState->decoderR.step = 0; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMADecoderSample() *---------------------------------------------------------------------------- * Purpose: * Decodes an IMA ADPCM sample * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState) { EAS_RESULT result; EAS_I16 sTemp; /* if high nibble, decode */ if (pState->hiNibble) { IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte >> 4)); pState->hiNibble = EAS_FALSE; } /* low nibble, need to fetch another byte */ else { /* check for loop */ if ((pState->bytesLeft == 0) && (pState->loopSamples != 0)) { /* seek to start of loop */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS) return result; pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop; pState->blockCount = 0; pState->flags &= ~PCM_FLAGS_EMPTY; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMADecoderSample: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ } } /* if start of block, fetch new predictor and step index */ if ((pState->blockSize != 0) && (pState->blockCount == 0) && (pState->bytesLeft != 0)) { /* get predicted sample for left channel */ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS) return result; #ifdef _DEBUG_IMA_ADPCM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Predictor: Was %d, now %d\n", pState->decoderL.acc, sTemp); */ } #endif pState->decoderL.acc = pState->decoderL.x1 = sTemp; /* get step index for left channel - upper 8 bits are reserved */ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS) return result; #ifdef _DEBUG_IMA_ADPCM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderL.step, sTemp); */ } #endif pState->decoderL.step = sTemp & 0xff; if (pState->flags & PCM_FLAGS_STEREO) { /* get predicted sample for right channel */ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS) return result; pState->decoderR.acc = pState->decoderR.x1 = sTemp; /* get step index for right channel - upper 8 bits are reserved */ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS) return result; #ifdef _DEBUG_IMA_ADPCM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderR.step, sTemp); */ } #endif pState->decoderR.step = sTemp & 0xff; pState->blockCount = pState->blockSize - 8; pState->bytesLeft -= 8; } else { pState->blockCount = pState->blockSize - 4; pState->bytesLeft -= 4; } } else { /* get another ADPCM data pair */ if (pState->bytesLeft) { if ((result = EAS_HWGetByte(pEASData->hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS) return result; /* decode the low nibble */ pState->bytesLeft--; pState->blockCount--; IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte & 0x0f)); if (pState->flags & PCM_FLAGS_STEREO) IMADecoderADPCM(&pState->decoderR, (EAS_U8)(pState->srcByte >> 4)); else pState->hiNibble = EAS_TRUE; } /* out of ADPCM data, generate enough samples to fill buffer */ else { pState->decoderL.x1 = pState->decoderL.x0; pState->decoderR.x1 = pState->decoderR.x0; } } } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * IMADecoderADPCM() *---------------------------------------------------------------------------- * Purpose: * Decodes an IMA ADPCM sample * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble) { EAS_INT delta; EAS_INT stepSize; /* get stepsize from table */ stepSize = imaStepSizeTable[pState->step]; /* delta = (abs(delta) + 0.5) * step / 4 */ delta = 0; if (nibble & 4) delta += stepSize; if (nibble & 2) /*lint -e{702} use shift for performance */ delta += stepSize >> 1; if (nibble & 1) /*lint -e{702} use shift for performance */ delta += stepSize >> 2; /*lint -e{702} use shift for performance */ delta += stepSize >> 3; /* integrate the delta */ if (nibble & 8) pState->acc -= delta; else pState->acc += delta; /* saturate */ if (pState->acc > 32767) pState->acc = 32767; if (pState->acc < -32768) pState->acc = -32768; pState->x1 = (EAS_PCM) pState->acc; /* compute new step size */ pState->step += imaIndexTable[nibble]; if (pState->step < 0) pState->step = 0; if (pState->step > 88) pState->step = 88; #ifdef _DEBUG_IMA_ADPCM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "In=%u, Pred=%d, Step=%d\n", nibble, pState->acc, imaStepSizeTable[pState->step]); */ } #endif } /*---------------------------------------------------------------------------- * IMADecoderLocate() *---------------------------------------------------------------------------- * Locate in an IMA ADPCM stream *---------------------------------------------------------------------------- */ static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time) { EAS_RESULT result; EAS_I32 temp; EAS_I32 samplesPerBlock; EAS_I32 secs, msecs; /* no need to calculate if time is zero */ if (time == 0) temp = 0; /* not zero */ else { /* can't seek if not a blocked file */ if (pState->blockSize == 0) return EAS_ERROR_FEATURE_NOT_AVAILABLE; /* calculate number of samples per block */ if (pState->flags & PCM_FLAGS_STEREO) samplesPerBlock = pState->blockSize - 7; else samplesPerBlock = (pState->blockSize << 1) - 7; /* break down into secs and msecs */ secs = time / 1000; msecs = time - (secs * 1000); /* calculate sample number fraction from msecs */ temp = (msecs * pState->sampleRate); temp = (temp >> 10) + ((temp * 49) >> 21); /* add integer sample count */ temp += secs * pState->sampleRate; #ifdef _DEBUG_IMA_ADPCM_LOCATE EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000006 , time, temp); #endif /* for looped samples, calculate position in the loop */ if ((temp > pState->byteCount) && (pState->loopSamples != 0)) { EAS_I32 numBlocks; EAS_I32 samplesPerLoop; EAS_I32 samplesInLastBlock; numBlocks = (EAS_I32) (pState->loopStart / pState->blockSize); samplesInLastBlock = (EAS_I32) pState->loopStart - (numBlocks * pState->blockSize); if (samplesInLastBlock) { if (pState->flags & PCM_FLAGS_STEREO) samplesInLastBlock = samplesInLastBlock - 7; else /*lint -e{703} use shift for performance */ samplesInLastBlock = (samplesInLastBlock << 1) - 7; } samplesPerLoop = numBlocks * samplesPerBlock + samplesInLastBlock; temp = temp % samplesPerLoop; #ifdef _DEBUG_IMA_ADPCM_LOCATE EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000007 , numBlocks, samplesPerLoop, samplesInLastBlock, temp); #endif } /* find start of block for requested sample */ temp = (temp / samplesPerBlock) * pState->blockSize; #ifdef _DEBUG_IMA_ADPCM_LOCATE EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000008 , temp); #endif } /* seek to new location */ if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS) return result; #ifdef _DEBUG_IMA_ADPCM_LOCATE EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000009 , pState->bytesLeft); #endif /* reset state */ pState->blockCount = 0; pState->hiNibble = EAS_FALSE; if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED)) pState->state = EAS_STATE_READY; return EAS_SUCCESS; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_tcdata.c0000644000000000000000000000013214200302440026335 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.269324464 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_tcdata.c0000644000175000001440000000256314200302440027124 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_tcdata.c * * Contents and purpose: * ToneControl Parser data * * This file contains static data for the ToneControl parser. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 547 $ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $ *---------------------------------------------------------------------------- */ #include "eas_types.h" #include "eas_tcdata.h" /*---------------------------------------------------------------------------- * * eas_iMelodyData * * Static memory allocation for iMelody parser *---------------------------------------------------------------------------- */ S_TC_DATA eas_TCData; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_otadata.c0000644000000000000000000000013214200302440026512 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.269324464 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_otadata.c0000644000175000001440000000251514200302440027276 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_otadata..c * * Contents and purpose: * OTA Stream Parser data module for static memory model * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 547 $ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $ *---------------------------------------------------------------------------- */ #include "eas_types.h" #include "eas_otadata.h" /*---------------------------------------------------------------------------- * * eas_OTAData * * Static memory allocation for OTA parser *---------------------------------------------------------------------------- */ S_OTA_DATA eas_OTAData; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_reverb.c0000644000000000000000000000013214200302440026362 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_reverb.c0000644000175000001440000011646714200302440027162 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_reverb.c * * Contents and purpose: * Contains the implementation of the Reverb effect. * * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 510 $ * $Date: 2006-12-19 01:47:33 -0800 (Tue, 19 Dec 2006) $ *---------------------------------------------------------------------------- */ /*------------------------------------ * includes *------------------------------------ */ #include "eas_data.h" #include "eas_effects.h" #include "eas_math.h" #include "eas_reverbdata.h" #include "eas_reverb.h" #include "eas_config.h" #include "eas_host.h" #include "eas_report.h" /* prototypes for effects interface */ static EAS_RESULT ReverbInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData); static void ReverbProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples); static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData); static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); /* common effects interface for configuration module */ const S_EFFECTS_INTERFACE EAS_Reverb = { ReverbInit, ReverbProcess, ReverbShutdown, ReverbGetParam, ReverbSetParam }; /*---------------------------------------------------------------------------- * InitializeReverb() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbInit(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData) { EAS_I32 i; EAS_U16 nOffset; EAS_INT temp; S_REVERB_OBJECT *pReverbData; S_REVERB_PRESET *pPreset; /* check Configuration Module for data allocation */ if (pEASData->staticMemoryModel) pReverbData = EAS_CMEnumFXData(EAS_MODULE_REVERB); /* allocate dynamic memory */ else pReverbData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_REVERB_OBJECT)); if (pReverbData == NULL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Reverb memory\n"); */ } return EAS_ERROR_MALLOC_FAILED; } /* clear the structure */ EAS_HWMemSet(pReverbData, 0, sizeof(S_REVERB_OBJECT)); ReverbReadInPresets(pReverbData); pReverbData->m_nMinSamplesToAdd = REVERB_UPDATE_PERIOD_IN_SAMPLES; pReverbData->m_nRevOutFbkR = 0; pReverbData->m_nRevOutFbkL = 0; pReverbData->m_sAp0.m_zApIn = AP0_IN; pReverbData->m_sAp0.m_zApOut = AP0_IN + DEFAULT_AP0_LENGTH; pReverbData->m_sAp0.m_nApGain = DEFAULT_AP0_GAIN; pReverbData->m_zD0In = DELAY0_IN; pReverbData->m_sAp1.m_zApIn = AP1_IN; pReverbData->m_sAp1.m_zApOut = AP1_IN + DEFAULT_AP1_LENGTH; pReverbData->m_sAp1.m_nApGain = DEFAULT_AP1_GAIN; pReverbData->m_zD1In = DELAY1_IN; pReverbData->m_zLpf0 = 0; pReverbData->m_zLpf1 = 0; pReverbData->m_nLpfFwd = 8837; pReverbData->m_nLpfFbk = 6494; pReverbData->m_nSin = 0; pReverbData->m_nCos = 0; pReverbData->m_nSinIncrement = 0; pReverbData->m_nCosIncrement = 0; // set xfade parameters pReverbData->m_nXfadeInterval = (EAS_U16)REVERB_XFADE_PERIOD_IN_SAMPLES; pReverbData->m_nXfadeCounter = pReverbData->m_nXfadeInterval + 1; // force update on first iteration pReverbData->m_nPhase = -32768; pReverbData->m_nPhaseIncrement = REVERB_XFADE_PHASE_INCREMENT; pReverbData->m_nNoise = (EAS_I16)0xABCD; pReverbData->m_nMaxExcursion = 0x007F; // set delay tap lengths nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); pReverbData->m_zD1Cross = DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); pReverbData->m_zD0Cross = DELAY1_OUT - pReverbData->m_nMaxExcursion - nOffset; nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); pReverbData->m_zD0Self = DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset; nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); pReverbData->m_zD1Self = DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; // for debugging purposes, allow noise generator pReverbData->m_bUseNoise = EAS_FALSE; // for debugging purposes, allow bypass pReverbData->m_bBypass = EAS_TRUE; //EAS_FALSE; pReverbData->m_nNextRoom = 1; pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom + 1; // force update on first iteration pReverbData->m_nWet = REVERB_DEFAULT_WET; pReverbData->m_nDry = REVERB_DEFAULT_DRY; // set base index into circular buffer pReverbData->m_nBaseIndex = 0; // set the early reflections, L pReverbData->m_sEarlyL.m_nLpfFbk = 4915; pReverbData->m_sEarlyL.m_nLpfFwd = 27852; pReverbData->m_sEarlyL.m_zLpf = 0; for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++) { pReverbData->m_sEarlyL.m_nGain[i] = 0; pReverbData->m_sEarlyL.m_zDelay[i] = 0; } // set the early reflections, R pReverbData->m_sEarlyR.m_nLpfFbk = 4915; pReverbData->m_sEarlyR.m_nLpfFwd = 27852; pReverbData->m_sEarlyR.m_zLpf = 0; for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++) { pReverbData->m_sEarlyR.m_nGain[i] = 0; pReverbData->m_sEarlyR.m_zDelay[i] = 0; } // clear the reverb delay line for (i=0; i < REVERB_BUFFER_SIZE_IN_SAMPLES; i++) { pReverbData->m_nDelayLine[i] = 0; } //////////////////////////////// ///code from the EAS DEMO Reverb //now copy from the new preset into the reverb pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom]; pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk; pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd; pReverbData->m_nEarly = pPreset->m_nEarly; pReverbData->m_nWet = pPreset->m_nWet; pReverbData->m_nDry = pPreset->m_nDry; pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion; //stored as time based, convert to sample based temp = pPreset->m_nXfadeInterval; /*lint -e{702} shift for performance */ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; pReverbData->m_nXfadeInterval = (EAS_U16) temp; //gsReverbObject.m_nXfadeInterval = pPreset->m_nXfadeInterval; pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain; //stored as time based, convert to absolute sample value temp = pPreset->m_nAp0_ApOut; /*lint -e{702} shift for performance */ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp); //gsReverbObject.m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut; pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain; //stored as time based, convert to absolute sample value temp = pPreset->m_nAp1_ApOut; /*lint -e{702} shift for performance */ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp); //gsReverbObject.m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut; ///code from the EAS DEMO Reverb //////////////////////////////// *pInstData = pReverbData; return EAS_SUCCESS; } /* end InitializeReverb */ /*---------------------------------------------------------------------------- * ReverbProcess() *---------------------------------------------------------------------------- * Purpose: * Reverberate the requested number of samples (block based processing) * * Inputs: * pInputBuffer - src buffer * pOutputBuffer - dst buffer * nNumSamplesToAdd - number of samples to write to buffer * * Outputs: * number of samples actually written to buffer * * Side Effects: * - samples are added to the presently free buffer * *---------------------------------------------------------------------------- */ static void ReverbProcess(EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples) { S_REVERB_OBJECT *pReverbData; pReverbData = (S_REVERB_OBJECT*) pInstData; //if bypassed or the preset forces the signal to be completely dry if (pReverbData->m_bBypass || (pReverbData->m_nWet == 0 && pReverbData->m_nDry == 32767)) { if (pSrc != pDst) EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM)); return; } if (pReverbData->m_nNextRoom != pReverbData->m_nCurrentRoom) { ReverbUpdateRoom(pReverbData); } ReverbUpdateXfade(pReverbData, numSamples); Reverb(pReverbData, numSamples, pDst, pSrc); /* check if update counter needs to be reset */ if (pReverbData->m_nUpdateCounter >= REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES) { /* update interval has elapsed, so reset counter */ pReverbData->m_nUpdateCounter = 0; } /* end if m_nUpdateCounter >= update interval */ /* increment update counter */ pReverbData->m_nUpdateCounter += (EAS_I16)numSamples; } /* end ComputeReverb */ /*---------------------------------------------------------------------------- * ReverbUpdateXfade *---------------------------------------------------------------------------- * Purpose: * Update the xfade parameters as required * * Inputs: * nNumSamplesToAdd - number of samples to write to buffer * * Outputs: * * * Side Effects: * - xfade parameters will be changed * *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd) { EAS_U16 nOffset; EAS_I16 tempCos; EAS_I16 tempSin; if (pReverbData->m_nXfadeCounter >= pReverbData->m_nXfadeInterval) { /* update interval has elapsed, so reset counter */ pReverbData->m_nXfadeCounter = 0; // Pin the sin,cos values to min / max values to ensure that the // modulated taps' coefs are zero (thus no clicks) if (pReverbData->m_nPhaseIncrement > 0) { // if phase increment > 0, then sin -> 1, cos -> 0 pReverbData->m_nSin = 32767; pReverbData->m_nCos = 0; // reset the phase to match the sin, cos values pReverbData->m_nPhase = 32767; // modulate the cross taps because their tap coefs are zero nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); pReverbData->m_zD1Cross = DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); pReverbData->m_zD0Cross = DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset; } else { // if phase increment < 0, then sin -> 0, cos -> 1 pReverbData->m_nSin = 0; pReverbData->m_nCos = 32767; // reset the phase to match the sin, cos values pReverbData->m_nPhase = -32768; // modulate the self taps because their tap coefs are zero nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); pReverbData->m_zD0Self = DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset; nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); pReverbData->m_zD1Self = DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; } // end if-else (pReverbData->m_nPhaseIncrement > 0) // Reverse the direction of the sin,cos so that the // tap whose coef was previously increasing now decreases // and vice versa pReverbData->m_nPhaseIncrement = -pReverbData->m_nPhaseIncrement; } // end if counter >= update interval //compute what phase will be next time pReverbData->m_nPhase += pReverbData->m_nPhaseIncrement; //calculate what the new sin and cos need to reach by the next update ReverbCalculateSinCos(pReverbData->m_nPhase, &tempSin, &tempCos); //calculate the per-sample increment required to get there by the next update /*lint -e{702} shift for performance */ pReverbData->m_nSinIncrement = (tempSin - pReverbData->m_nSin) >> REVERB_UPDATE_PERIOD_IN_BITS; /*lint -e{702} shift for performance */ pReverbData->m_nCosIncrement = (tempCos - pReverbData->m_nCos) >> REVERB_UPDATE_PERIOD_IN_BITS; /* increment update counter */ pReverbData->m_nXfadeCounter += (EAS_U16) nNumSamplesToAdd; return EAS_SUCCESS; } /* end ReverbUpdateXfade */ /*---------------------------------------------------------------------------- * ReverbCalculateNoise *---------------------------------------------------------------------------- * Purpose: * Calculate a noise sample and limit its value * * Inputs: * nMaxExcursion - noise value is limited to this value * pnNoise - return new noise sample in this (not limited) * * Outputs: * new limited noise value * * Side Effects: * - *pnNoise noise value is updated * *---------------------------------------------------------------------------- */ static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise) { // calculate new noise value *pnNoise = (EAS_I16) (*pnNoise * 5 + 1); #if 0 // 1xxx, test *pnNoise = 0; #endif // 1xxx, test // return the limited noise value return (nMaxExcursion & (*pnNoise)); } /* end ReverbCalculateNoise */ /*---------------------------------------------------------------------------- * ReverbCalculateSinCos *---------------------------------------------------------------------------- * Purpose: * Calculate a new sin and cosine value based on the given phase * * Inputs: * nPhase - phase angle * pnSin - input old value, output new value * pnCos - input old value, output new value * * Outputs: * * Side Effects: * - *pnSin, *pnCos are updated * *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos) { EAS_I32 nTemp; EAS_I32 nNetAngle; // -1 <= nPhase < 1 // However, for the calculation, we need a value // that ranges from -1/2 to +1/2, so divide the phase by 2 /*lint -e{702} shift for performance */ nNetAngle = nPhase >> 1; /* Implement the following sin(x) = (2-4*c)*x^2 + c + x cos(x) = (2-4*c)*x^2 + c - x where c = 1/sqrt(2) using the a0 + x*(a1 + x*a2) approach */ /* limit the input "angle" to be between -0.5 and +0.5 */ if (nNetAngle > EG1_HALF) { nNetAngle = EG1_HALF; } else if (nNetAngle < EG1_MINUS_HALF) { nNetAngle = EG1_MINUS_HALF; } /* calculate sin */ nTemp = EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle); nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle); *pnSin = (EAS_I16) SATURATE_EG1(nTemp); /* calculate cos */ nTemp = -EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle); nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle); *pnCos = (EAS_I16) SATURATE_EG1(nTemp); return EAS_SUCCESS; } /* end ReverbCalculateSinCos */ /*---------------------------------------------------------------------------- * Reverb *---------------------------------------------------------------------------- * Purpose: * apply reverb to the given signal * * Inputs: * nNu * pnSin - input old value, output new value * pnCos - input old value, output new value * * Outputs: * number of samples actually reverberated * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT Reverb(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer) { EAS_I32 i; EAS_I32 nDelayOut; EAS_U16 nBase; EAS_U32 nAddr; EAS_I32 nTemp1; EAS_I32 nTemp2; EAS_I32 nApIn; EAS_I32 nApOut; EAS_I32 j; EAS_I32 nEarlyOut; EAS_I32 tempValue; // get the base address nBase = pReverbData->m_nBaseIndex; for (i=0; i < nNumSamplesToAdd; i++) { // ********** Left Allpass - start // left input = (left dry/4) + right feedback from previous period /*lint -e{702} use shift for performance */ nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkR; // nApIn = *pInputBuffer++; // 1xxx test and debug ap // fetch allpass delay line out //nAddr = CIRCULAR(nBase, psAp0->m_zApOut, REVERB_BUFFER_MASK); nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApOut, REVERB_BUFFER_MASK); nDelayOut = pReverbData->m_nDelayLine[nAddr]; // calculate allpass feedforward; subtract the feedforward result nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp0.m_nApGain); nApOut = SATURATE(nDelayOut - nTemp1); // allpass output // calculate allpass feedback; add the feedback result nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp0.m_nApGain); nTemp1 = SATURATE(nApIn + nTemp1); // inject into allpass delay nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApIn, REVERB_BUFFER_MASK); pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1; // inject allpass output into delay line nAddr = CIRCULAR(nBase, pReverbData->m_zD0In, REVERB_BUFFER_MASK); pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut; // ********** Left Allpass - end // ********** Right Allpass - start // right input = (right dry/4) + left feedback from previous period /*lint -e{702} use shift for performance */ nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkL; // nApIn = *pInputBuffer++; // 1xxx test and debug ap // fetch allpass delay line out nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApOut, REVERB_BUFFER_MASK); nDelayOut = pReverbData->m_nDelayLine[nAddr]; // calculate allpass feedforward; subtract the feedforward result nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp1.m_nApGain); nApOut = SATURATE(nDelayOut - nTemp1); // allpass output // calculate allpass feedback; add the feedback result nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp1.m_nApGain); nTemp1 = SATURATE(nApIn + nTemp1); // inject into allpass delay nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApIn, REVERB_BUFFER_MASK); pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1; // inject allpass output into delay line nAddr = CIRCULAR(nBase, pReverbData->m_zD1In, REVERB_BUFFER_MASK); pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut; // ********** Right Allpass - end // ********** D0 output - start // fetch delay line self out nAddr = CIRCULAR(nBase, pReverbData->m_zD0Self, REVERB_BUFFER_MASK); nDelayOut = pReverbData->m_nDelayLine[nAddr]; // calculate delay line self out nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin); // fetch delay line cross out nAddr = CIRCULAR(nBase, pReverbData->m_zD1Cross, REVERB_BUFFER_MASK); nDelayOut = pReverbData->m_nDelayLine[nAddr]; // calculate delay line self out nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos); // calculate unfiltered delay out nDelayOut = SATURATE(nTemp1 + nTemp2); // calculate lowpass filter (mixer scale factor included in LPF feedforward) nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd); nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf0, pReverbData->m_nLpfFbk); // calculate filtered delay out and simultaneously update LPF state variable // filtered delay output is stored in m_zLpf0 pReverbData->m_zLpf0 = (EAS_PCM) SATURATE(nTemp1 + nTemp2); // ********** D0 output - end // ********** D1 output - start // fetch delay line self out nAddr = CIRCULAR(nBase, pReverbData->m_zD1Self, REVERB_BUFFER_MASK); nDelayOut = pReverbData->m_nDelayLine[nAddr]; // calculate delay line self out nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin); // fetch delay line cross out nAddr = CIRCULAR(nBase, pReverbData->m_zD0Cross, REVERB_BUFFER_MASK); nDelayOut = pReverbData->m_nDelayLine[nAddr]; // calculate delay line self out nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos); // calculate unfiltered delay out nDelayOut = SATURATE(nTemp1 + nTemp2); // calculate lowpass filter (mixer scale factor included in LPF feedforward) nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd); nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf1, pReverbData->m_nLpfFbk); // calculate filtered delay out and simultaneously update LPF state variable // filtered delay output is stored in m_zLpf1 pReverbData->m_zLpf1 = (EAS_PCM)SATURATE(nTemp1 + nTemp2); // ********** D1 output - end // ********** mixer and feedback - start // sum is fedback to right input (R + L) pReverbData->m_nRevOutFbkL = (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 + (EAS_I32)pReverbData->m_zLpf0); // difference is feedback to left input (R - L) /*lint -e{685} lint complains that it can't saturate negative */ pReverbData->m_nRevOutFbkR = (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 - (EAS_I32)pReverbData->m_zLpf0); // ********** mixer and feedback - end // ********** start early reflection generator, left //psEarly = &(pReverbData->m_sEarlyL); nEarlyOut = 0; for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) { // fetch delay line out //nAddr = CIRCULAR(nBase, psEarly->m_zDelay[j], REVERB_BUFFER_MASK); nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyL.m_zDelay[j], REVERB_BUFFER_MASK); nDelayOut = pReverbData->m_nDelayLine[nAddr]; // calculate reflection //nTemp1 = MULT_EG1_EG1(nDelayOut, psEarly->m_nGain[j]); nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyL.m_nGain[j]); nEarlyOut = SATURATE(nEarlyOut + nTemp1); } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) // apply lowpass to early reflections //nTemp1 = MULT_EG1_EG1(nEarlyOut, psEarly->m_nLpfFwd); nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyL.m_nLpfFwd); //nTemp2 = MULT_EG1_EG1(psEarly->m_zLpf, psEarly->m_nLpfFbk); nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyL.m_zLpf, pReverbData->m_sEarlyL.m_nLpfFbk); // calculate filtered out and simultaneously update LPF state variable // filtered output is stored in m_zLpf1 //psEarly->m_zLpf = SATURATE(nTemp1 + nTemp2); pReverbData->m_sEarlyL.m_zLpf = (EAS_PCM) SATURATE(nTemp1 + nTemp2); // combine filtered early and late reflections for output //*pOutputBuffer++ = inL; //tempValue = SATURATE(psEarly->m_zLpf + pReverbData->m_nRevOutFbkL); tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyL.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkL); //scale reverb output by wet level /*lint -e{701} use shift for performance */ tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet<<1)); //sum with output buffer tempValue += *pOutputBuffer; *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue); // ********** end early reflection generator, left // ********** start early reflection generator, right //psEarly = &(pReverbData->m_sEarlyR); nEarlyOut = 0; for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) { // fetch delay line out nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyR.m_zDelay[j], REVERB_BUFFER_MASK); nDelayOut = pReverbData->m_nDelayLine[nAddr]; // calculate reflection nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyR.m_nGain[j]); nEarlyOut = SATURATE(nEarlyOut + nTemp1); } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) // apply lowpass to early reflections nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyR.m_nLpfFwd); nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyR.m_zLpf, pReverbData->m_sEarlyR.m_nLpfFbk); // calculate filtered out and simultaneously update LPF state variable // filtered output is stored in m_zLpf1 pReverbData->m_sEarlyR.m_zLpf = (EAS_PCM)SATURATE(nTemp1 + nTemp2); // combine filtered early and late reflections for output //*pOutputBuffer++ = inR; tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyR.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkR); //scale reverb output by wet level /*lint -e{701} use shift for performance */ tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet << 1)); //sum with output buffer tempValue = tempValue + *pOutputBuffer; *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue); // ********** end early reflection generator, right // decrement base addr for next sample period nBase--; pReverbData->m_nSin += pReverbData->m_nSinIncrement; pReverbData->m_nCos += pReverbData->m_nCosIncrement; } // end for (i=0; i < nNumSamplesToAdd; i++) // store the most up to date version pReverbData->m_nBaseIndex = nBase; return EAS_SUCCESS; } /* end Reverb */ /*---------------------------------------------------------------------------- * ReverbShutdown() *---------------------------------------------------------------------------- * Purpose: * Initializes the Reverb effect. * * Inputs: * pInstData - handle to instance data * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData) { /* check Configuration Module for static memory allocation */ if (!pEASData->staticMemoryModel) EAS_HWFree(pEASData->hwInstData, pInstData); return EAS_SUCCESS; } /* end ReverbShutdown */ /*---------------------------------------------------------------------------- * ReverbGetParam() *---------------------------------------------------------------------------- * Purpose: * Get a Reverb parameter * * Inputs: * pInstData - handle to instance data * param - parameter index * *pValue - pointer to variable to hold retrieved value * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue) { S_REVERB_OBJECT *p; p = (S_REVERB_OBJECT*) pInstData; switch (param) { case EAS_PARAM_REVERB_BYPASS: *pValue = (EAS_I32) p->m_bBypass; break; case EAS_PARAM_REVERB_PRESET: *pValue = (EAS_I8) p->m_nCurrentRoom; break; case EAS_PARAM_REVERB_WET: *pValue = p->m_nWet; break; case EAS_PARAM_REVERB_DRY: *pValue = p->m_nDry; break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /* end ReverbGetParam */ /*---------------------------------------------------------------------------- * ReverbSetParam() *---------------------------------------------------------------------------- * Purpose: * Set a Reverb parameter * * Inputs: * pInstData - handle to instance data * param - parameter index * *pValue - new paramter value * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value) { S_REVERB_OBJECT *p; p = (S_REVERB_OBJECT*) pInstData; switch (param) { case EAS_PARAM_REVERB_BYPASS: p->m_bBypass = (EAS_BOOL) value; break; case EAS_PARAM_REVERB_PRESET: if(value!=EAS_PARAM_REVERB_LARGE_HALL && value!=EAS_PARAM_REVERB_HALL && value!=EAS_PARAM_REVERB_CHAMBER && value!=EAS_PARAM_REVERB_ROOM) return EAS_ERROR_INVALID_PARAMETER; p->m_nNextRoom = (EAS_I16)value; break; case EAS_PARAM_REVERB_WET: if(value>EAS_REVERB_WET_MAX || valuem_nWet = (EAS_I16)value; break; case EAS_PARAM_REVERB_DRY: if(value>EAS_REVERB_DRY_MAX || valuem_nDry = (EAS_I16)value; break; default: return EAS_ERROR_INVALID_PARAMETER; } return EAS_SUCCESS; } /* end ReverbSetParam */ /*---------------------------------------------------------------------------- * ReverbUpdateRoom *---------------------------------------------------------------------------- * Purpose: * Update the room's preset parameters as required * * Inputs: * * Outputs: * * * Side Effects: * - reverb paramters (fbk, fwd, etc) will be changed * - m_nCurrentRoom := m_nNextRoom *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT *pReverbData) { EAS_INT temp; S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom]; pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd; pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk; pReverbData->m_nEarly = pPreset->m_nEarly; pReverbData->m_nWet = pPreset->m_nWet; pReverbData->m_nDry = pPreset->m_nDry; pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion; //stored as time based, convert to sample based temp = pPreset->m_nXfadeInterval; /*lint -e{702} shift for performance */ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; pReverbData->m_nXfadeInterval = (EAS_U16) temp; //gpsReverbObject->m_nXfadeInterval = pPreset->m_nXfadeInterval; pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain; //stored as time based, convert to absolute sample value temp = pPreset->m_nAp0_ApOut; /*lint -e{702} shift for performance */ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp); //gpsReverbObject->m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut; pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain; //stored as time based, convert to absolute sample value temp = pPreset->m_nAp1_ApOut; /*lint -e{702} shift for performance */ temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp); //gpsReverbObject->m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut; pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom; return EAS_SUCCESS; } /* end ReverbUpdateRoom */ /*---------------------------------------------------------------------------- * ReverbReadInPresets() *---------------------------------------------------------------------------- * Purpose: sets global reverb preset bank to defaults * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT *pReverbData) { int preset = 0; int defaultPreset = 0; //now init any remaining presets to defaults for (defaultPreset = preset; defaultPreset < REVERB_MAX_ROOM_TYPE; defaultPreset++) { S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[defaultPreset]; if (defaultPreset == 0 || defaultPreset > REVERB_MAX_ROOM_TYPE-1) { pPreset->m_nLpfFbk = 8307; pPreset->m_nLpfFwd = 14768; pPreset->m_nEarly = 0; pPreset->m_nWet = 27690; pPreset->m_nDry = 32767; pPreset->m_nEarlyL_LpfFbk = 3692; pPreset->m_nEarlyL_LpfFwd = 29075; pPreset->m_nEarlyL_Delay0 = 922; pPreset->m_nEarlyL_Gain0 = 22152; pPreset->m_nEarlyL_Delay1 = 1462; pPreset->m_nEarlyL_Gain1 = 17537; pPreset->m_nEarlyL_Delay2 = 0; pPreset->m_nEarlyL_Gain2 = 14768; pPreset->m_nEarlyL_Delay3 = 1221; pPreset->m_nEarlyL_Gain3 = 14307; pPreset->m_nEarlyL_Delay4 = 0; pPreset->m_nEarlyL_Gain4 = 13384; pPreset->m_nEarlyR_Delay0 = 502; pPreset->m_nEarlyR_Gain0 = 20306; pPreset->m_nEarlyR_Delay1 = 1762; pPreset->m_nEarlyR_Gain1 = 17537; pPreset->m_nEarlyR_Delay2 = 0; pPreset->m_nEarlyR_Gain2 = 14768; pPreset->m_nEarlyR_Delay3 = 0; pPreset->m_nEarlyR_Gain3 = 16153; pPreset->m_nEarlyR_Delay4 = 0; pPreset->m_nEarlyR_Gain4 = 13384; pPreset->m_nMaxExcursion = 127; pPreset->m_nXfadeInterval = 6388; pPreset->m_nAp0_ApGain = 15691; pPreset->m_nAp0_ApOut = 711; pPreset->m_nAp1_ApGain = 17999; pPreset->m_nAp1_ApOut = 1113; pPreset->m_rfu4 = 0; pPreset->m_rfu5 = 0; pPreset->m_rfu6 = 0; pPreset->m_rfu7 = 0; pPreset->m_rfu8 = 0; pPreset->m_rfu9 = 0; pPreset->m_rfu10 = 0; } else if (defaultPreset == 1) { pPreset->m_nLpfFbk = 6461; pPreset->m_nLpfFwd = 14307; pPreset->m_nEarly = 0; pPreset->m_nWet = 27690; pPreset->m_nDry = 32767; pPreset->m_nEarlyL_LpfFbk = 3692; pPreset->m_nEarlyL_LpfFwd = 29075; pPreset->m_nEarlyL_Delay0 = 922; pPreset->m_nEarlyL_Gain0 = 22152; pPreset->m_nEarlyL_Delay1 = 1462; pPreset->m_nEarlyL_Gain1 = 17537; pPreset->m_nEarlyL_Delay2 = 0; pPreset->m_nEarlyL_Gain2 = 14768; pPreset->m_nEarlyL_Delay3 = 1221; pPreset->m_nEarlyL_Gain3 = 14307; pPreset->m_nEarlyL_Delay4 = 0; pPreset->m_nEarlyL_Gain4 = 13384; pPreset->m_nEarlyR_Delay0 = 502; pPreset->m_nEarlyR_Gain0 = 20306; pPreset->m_nEarlyR_Delay1 = 1762; pPreset->m_nEarlyR_Gain1 = 17537; pPreset->m_nEarlyR_Delay2 = 0; pPreset->m_nEarlyR_Gain2 = 14768; pPreset->m_nEarlyR_Delay3 = 0; pPreset->m_nEarlyR_Gain3 = 16153; pPreset->m_nEarlyR_Delay4 = 0; pPreset->m_nEarlyR_Gain4 = 13384; pPreset->m_nMaxExcursion = 127; pPreset->m_nXfadeInterval = 6391; pPreset->m_nAp0_ApGain = 15230; pPreset->m_nAp0_ApOut = 708; pPreset->m_nAp1_ApGain = 9692; pPreset->m_nAp1_ApOut = 1113; pPreset->m_rfu4 = 0; pPreset->m_rfu5 = 0; pPreset->m_rfu6 = 0; pPreset->m_rfu7 = 0; pPreset->m_rfu8 = 0; pPreset->m_rfu9 = 0; pPreset->m_rfu10 = 0; } else if (defaultPreset == 2) { pPreset->m_nLpfFbk = 5077; pPreset->m_nLpfFwd = 12922; pPreset->m_nEarly = 0; pPreset->m_nWet = 24460; pPreset->m_nDry = 32767; pPreset->m_nEarlyL_LpfFbk = 3692; pPreset->m_nEarlyL_LpfFwd = 29075; pPreset->m_nEarlyL_Delay0 = 922; pPreset->m_nEarlyL_Gain0 = 22152; pPreset->m_nEarlyL_Delay1 = 1462; pPreset->m_nEarlyL_Gain1 = 17537; pPreset->m_nEarlyL_Delay2 = 0; pPreset->m_nEarlyL_Gain2 = 14768; pPreset->m_nEarlyL_Delay3 = 1221; pPreset->m_nEarlyL_Gain3 = 14307; pPreset->m_nEarlyL_Delay4 = 0; pPreset->m_nEarlyL_Gain4 = 13384; pPreset->m_nEarlyR_Delay0 = 502; pPreset->m_nEarlyR_Gain0 = 20306; pPreset->m_nEarlyR_Delay1 = 1762; pPreset->m_nEarlyR_Gain1 = 17537; pPreset->m_nEarlyR_Delay2 = 0; pPreset->m_nEarlyR_Gain2 = 14768; pPreset->m_nEarlyR_Delay3 = 0; pPreset->m_nEarlyR_Gain3 = 16153; pPreset->m_nEarlyR_Delay4 = 0; pPreset->m_nEarlyR_Gain4 = 13384; pPreset->m_nMaxExcursion = 127; pPreset->m_nXfadeInterval = 6449; pPreset->m_nAp0_ApGain = 15691; pPreset->m_nAp0_ApOut = 774; pPreset->m_nAp1_ApGain = 15691; pPreset->m_nAp1_ApOut = 1113; pPreset->m_rfu4 = 0; pPreset->m_rfu5 = 0; pPreset->m_rfu6 = 0; pPreset->m_rfu7 = 0; pPreset->m_rfu8 = 0; pPreset->m_rfu9 = 0; pPreset->m_rfu10 = 0; } else if (defaultPreset == 3) { pPreset->m_nLpfFbk = 5077; pPreset->m_nLpfFwd = 11076; pPreset->m_nEarly = 0; pPreset->m_nWet = 23075; pPreset->m_nDry = 32767; pPreset->m_nEarlyL_LpfFbk = 3692; pPreset->m_nEarlyL_LpfFwd = 29075; pPreset->m_nEarlyL_Delay0 = 922; pPreset->m_nEarlyL_Gain0 = 22152; pPreset->m_nEarlyL_Delay1 = 1462; pPreset->m_nEarlyL_Gain1 = 17537; pPreset->m_nEarlyL_Delay2 = 0; pPreset->m_nEarlyL_Gain2 = 14768; pPreset->m_nEarlyL_Delay3 = 1221; pPreset->m_nEarlyL_Gain3 = 14307; pPreset->m_nEarlyL_Delay4 = 0; pPreset->m_nEarlyL_Gain4 = 13384; pPreset->m_nEarlyR_Delay0 = 502; pPreset->m_nEarlyR_Gain0 = 20306; pPreset->m_nEarlyR_Delay1 = 1762; pPreset->m_nEarlyR_Gain1 = 17537; pPreset->m_nEarlyR_Delay2 = 0; pPreset->m_nEarlyR_Gain2 = 14768; pPreset->m_nEarlyR_Delay3 = 0; pPreset->m_nEarlyR_Gain3 = 16153; pPreset->m_nEarlyR_Delay4 = 0; pPreset->m_nEarlyR_Gain4 = 13384; pPreset->m_nMaxExcursion = 127; pPreset->m_nXfadeInterval = 6470; //6483; pPreset->m_nAp0_ApGain = 14768; pPreset->m_nAp0_ApOut = 792; pPreset->m_nAp1_ApGain = 15783; pPreset->m_nAp1_ApOut = 1113; pPreset->m_rfu4 = 0; pPreset->m_rfu5 = 0; pPreset->m_rfu6 = 0; pPreset->m_rfu7 = 0; pPreset->m_rfu8 = 0; pPreset->m_rfu9 = 0; pPreset->m_rfu10 = 0; } } return EAS_SUCCESS; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_wtsynth.c0000644000000000000000000000013214200302440026615 xustar0030 mtime=1644266784.809324171 30 atime=1644266785.269324464 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_wtsynth.c0000644000175000001440000013115514200302440027404 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_wtsynth.c * * Contents and purpose: * Implements the synthesizer functions. * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 795 $ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $ *---------------------------------------------------------------------------- */ // includes #define LOG_TAG "SYNTH" //#include "log/log.h" //#include #include "eas_data.h" #include "eas_report.h" #include "eas_host.h" #include "eas_math.h" #include "eas_synth_protos.h" #include "eas_wtsynth.h" #include "eas_pan.h" #ifdef DLS_SYNTHESIZER #include "eas_dlssynth.h" #endif #ifdef _METRICS_ENABLED #include "eas_perf.h" #endif /* local prototypes */ static EAS_RESULT WT_Initialize(S_VOICE_MGR *pVoiceMgr); static void WT_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum); static void WT_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum); static void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum); static EAS_RESULT WT_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex); static EAS_BOOL WT_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples); static void WT_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel); static EAS_I32 WT_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents); static EAS_I32 WT_UpdateGain (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain); static void WT_UpdateEG1 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv); static void WT_UpdateEG2 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv); #ifdef EAS_SPLIT_WT_SYNTH extern EAS_BOOL WTE_StartFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer); extern EAS_BOOL WTE_EndFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain); #endif #ifdef _FILTER_ENABLED static void WT_UpdateFilter (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, const S_ARTICULATION *pArt); #endif #ifdef _STATS extern double statsPhaseIncrement; extern double statsMaxPhaseIncrement; extern long statsPhaseSampleCount; extern double statsSampleSize; extern long statsSampleCount; #endif /*---------------------------------------------------------------------------- * Synthesizer interface *---------------------------------------------------------------------------- */ const S_SYNTH_INTERFACE wtSynth = { WT_Initialize, WT_StartVoice, WT_UpdateVoice, WT_ReleaseVoice, WT_MuteVoice, WT_SustainPedal, WT_UpdateChannel }; #ifdef EAS_SPLIT_WT_SYNTH const S_FRAME_INTERFACE wtFrameInterface = { WTE_StartFrame, WTE_EndFrame }; #endif /*---------------------------------------------------------------------------- * WT_Initialize() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * pVoice - pointer to voice to initialize * * Outputs: * *---------------------------------------------------------------------------- */ static EAS_RESULT WT_Initialize (S_VOICE_MGR *pVoiceMgr) { EAS_INT i; for (i = 0; i < NUM_WT_VOICES; i++) { pVoiceMgr->wtVoices[i].artIndex = DEFAULT_ARTICULATION_INDEX; pVoiceMgr->wtVoices[i].eg1State = DEFAULT_EG1_STATE; pVoiceMgr->wtVoices[i].eg1Value = DEFAULT_EG1_VALUE; pVoiceMgr->wtVoices[i].eg1Increment = DEFAULT_EG1_INCREMENT; pVoiceMgr->wtVoices[i].eg2State = DEFAULT_EG2_STATE; pVoiceMgr->wtVoices[i].eg2Value = DEFAULT_EG2_VALUE; pVoiceMgr->wtVoices[i].eg2Increment = DEFAULT_EG2_INCREMENT; /* left and right gain values are needed only if stereo output */ #if (NUM_OUTPUT_CHANNELS == 2) pVoiceMgr->wtVoices[i].gainLeft = DEFAULT_VOICE_GAIN; pVoiceMgr->wtVoices[i].gainRight = DEFAULT_VOICE_GAIN; #endif pVoiceMgr->wtVoices[i].phaseFrac = DEFAULT_PHASE_FRAC; pVoiceMgr->wtVoices[i].phaseAccum = DEFAULT_PHASE_INT; #ifdef _FILTER_ENABLED pVoiceMgr->wtVoices[i].filter.z1 = DEFAULT_FILTER_ZERO; pVoiceMgr->wtVoices[i].filter.z2 = DEFAULT_FILTER_ZERO; #endif } return EAS_TRUE; } /*---------------------------------------------------------------------------- * WT_ReleaseVoice() *---------------------------------------------------------------------------- * Purpose: * The selected voice is being released. * * Inputs: * pEASData - pointer to S_EAS_DATA * pVoice - pointer to voice to release * * Outputs: * None *---------------------------------------------------------------------------- */ /*lint -esym(715, pVoice) used in some implementations */ static void WT_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum) { S_WT_VOICE *pWTVoice; const S_ARTICULATION *pArticulation; #ifdef DLS_SYNTHESIZER if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH) { DLS_ReleaseVoice(pVoiceMgr, pSynth, pVoice, voiceNum); return; } #endif pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; pArticulation = &pSynth->pEAS->pArticulations[pWTVoice->artIndex]; /* release EG1 */ pWTVoice->eg1State = eEnvelopeStateRelease; pWTVoice->eg1Increment = pArticulation->eg1.releaseTime; /* The spec says we should release EG2, but doing so with the current voicing is causing clicks. This fix will need to be coordinated with a new sound library release */ /* release EG2 */ pWTVoice->eg2State = eEnvelopeStateRelease; pWTVoice->eg2Increment = pArticulation->eg2.releaseTime; } /*---------------------------------------------------------------------------- * WT_MuteVoice() *---------------------------------------------------------------------------- * Purpose: * The selected voice is being muted. * * Inputs: * pVoice - pointer to voice to release * * Outputs: * None *---------------------------------------------------------------------------- */ /*lint -esym(715, pSynth) used in some implementations */ static void WT_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum) { #ifdef DLS_SYNTHESIZER if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH) { DLS_MuteVoice(pVoiceMgr, pSynth, pVoice, voiceNum); return; } #endif /* clear deferred action flags */ pVoice->voiceFlags &= ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF | VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF | VOICE_FLAG_DEFER_MUTE); /* set the envelope state */ pVoiceMgr->wtVoices[voiceNum].eg1State = eEnvelopeStateMuted; pVoiceMgr->wtVoices[voiceNum].eg2State = eEnvelopeStateMuted; } /*---------------------------------------------------------------------------- * WT_SustainPedal() *---------------------------------------------------------------------------- * Purpose: * The selected voice is held due to sustain pedal * * Inputs: * pVoice - pointer to voice to sustain * * Outputs: * None *---------------------------------------------------------------------------- */ /*lint -esym(715, pChannel) used in some implementations */ static void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum) { S_WT_VOICE *pWTVoice; #ifdef DLS_SYNTHESIZER if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH) { DLS_SustainPedal(pVoiceMgr, pSynth, pVoice, pChannel, voiceNum); return; } #endif /* don't catch the voice if below the sustain level */ pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; if (pWTVoice->eg1Value < pSynth->pEAS->pArticulations[pWTVoice->artIndex].eg1.sustainLevel) return; /* sustain flag is set, damper pedal is on */ /* defer releasing this note until the damper pedal is off */ pWTVoice->eg1State = eEnvelopeStateDecay; pVoice->voiceState = eVoiceStatePlay; /* because sustain pedal is on, this voice should defer releasing its note */ pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF; #ifdef _DEBUG_SYNTH { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_SustainPedal: defer note off because sustain pedal is on\n"); */ } #endif } /*---------------------------------------------------------------------------- * WT_StartVoice() *---------------------------------------------------------------------------- * Purpose: * Assign the region for the given instrument using the midi key number * and the RPN2 (coarse tuning) value. By using RPN2 as part of the * region selection process, we reduce the amount a given sample has * to be transposed by selecting the closest recorded root instead. * * This routine is the second half of SynthAssignRegion(). * If the region was successfully found by SynthFindRegionIndex(), * then assign the region's parameters to the voice. * * Setup and initialize the following voice parameters: * m_nRegionIndex * * Inputs: * pVoice - ptr to the voice we have assigned for this channel * nRegionIndex - index of the region * pEASData - pointer to overall EAS data structure * * Outputs: * success - could find and assign the region for this voice's note otherwise * failure - could not find nor assign the region for this voice's note * * Side Effects: * psSynthObject->m_sVoice[].m_nRegionIndex is assigned * psSynthObject->m_sVoice[] parameters are assigned *---------------------------------------------------------------------------- */ static EAS_RESULT WT_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex) { S_WT_VOICE *pWTVoice; const S_WT_REGION *pRegion; const S_ARTICULATION *pArt; S_SYNTH_CHANNEL *pChannel; #if (NUM_OUTPUT_CHANNELS == 2) EAS_INT pan; #endif #ifdef EAS_SPLIT_WT_SYNTH S_WT_CONFIG wtConfig; #endif /* no samples have been synthesized for this note yet */ pVoice->regionIndex = regionIndex; pVoice->voiceFlags = VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET; /* get the articulation index for this region */ pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; pChannel = &pSynth->channels[pVoice->channel & 15]; /* update static channel parameters */ if (pChannel->channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS) WT_UpdateChannel(pVoiceMgr, pSynth, pVoice->channel & 15); #ifdef DLS_SYNTHESIZER if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH) return DLS_StartVoice(pVoiceMgr, pSynth, pVoice, voiceNum, regionIndex); #endif pRegion = &(pSynth->pEAS->pWTRegions[regionIndex]); pWTVoice->artIndex = pRegion->artIndex; #ifdef _DEBUG_SYNTH { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ } #endif pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex]; /* MIDI note on puts this voice into attack state */ pWTVoice->eg1State = eEnvelopeStateAttack; pWTVoice->eg1Value = 0; pWTVoice->eg1Increment = pArt->eg1.attackTime; pWTVoice->eg2State = eEnvelopeStateAttack; pWTVoice->eg2Value = 0; pWTVoice->eg2Increment = pArt->eg2.attackTime; /* init the LFO */ pWTVoice->modLFO.lfoValue = 0; pWTVoice->modLFO.lfoPhase = -pArt->lfoDelay; pVoice->gain = 0; #if (NUM_OUTPUT_CHANNELS == 2) /* Get the Midi CC10 pan value for this voice's channel convert the pan value to an "angle" representation suitable for our sin, cos calculator. This representation is NOT necessarily the same as the transform in the GM manuals because of our sin, cos calculator. "angle" = (CC10 - 64)/128 */ pan = (EAS_INT) pSynth->channels[pVoice->channel & 15].pan - 64; pan += pArt->pan; EAS_CalcPanControl(pan, &pWTVoice->gainLeft, &pWTVoice->gainRight); #endif #ifdef _FILTER_ENABLED /* clear out the filter states */ pWTVoice->filter.z1 = 0; pWTVoice->filter.z2 = 0; #endif /* if this wave is to be generated using noise generator */ if (pRegion->region.keyGroupAndFlags & REGION_FLAG_USE_WAVE_GENERATOR) { pWTVoice->phaseAccum = 4574296; pWTVoice->loopStart = WT_NOISE_GENERATOR; pWTVoice->loopEnd = 4574295; } /* normal sample */ else { #ifdef EAS_SPLIT_WT_SYNTH if (voiceNum < NUM_PRIMARY_VOICES) pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex]; else pWTVoice->phaseAccum = pSynth->pEAS->pSampleOffsets[pRegion->waveIndex]; #else pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex]; #endif if (pRegion->region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED) { #if defined (_8_BIT_SAMPLES) pWTVoice->loopStart = pWTVoice->phaseAccum + pRegion->loopStart; pWTVoice->loopEnd = pWTVoice->phaseAccum + pRegion->loopEnd - 1; #else //_16_BIT_SAMPLES pWTVoice->loopStart = pWTVoice->phaseAccum + (pRegion->loopStart<<1); pWTVoice->loopEnd = pWTVoice->phaseAccum + (pRegion->loopEnd<<1) - 2; #endif } else { #if defined (_8_BIT_SAMPLES) pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pEAS->pSampleLen[pRegion->waveIndex] - 1; #else //_16_BIT_SAMPLES pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pEAS->pSampleLen[pRegion->waveIndex] - 2; #endif } } #ifdef EAS_SPLIT_WT_SYNTH /* configure off-chip voices */ if (voiceNum >= NUM_PRIMARY_VOICES) { wtConfig.phaseAccum = pWTVoice->phaseAccum; wtConfig.loopStart = pWTVoice->loopStart; wtConfig.loopEnd = pWTVoice->loopEnd; wtConfig.gain = pVoice->gain; #if (NUM_OUTPUT_CHANNELS == 2) wtConfig.gainLeft = pWTVoice->gainLeft; wtConfig.gainRight = pWTVoice->gainRight; #endif WTE_ConfigVoice(voiceNum - NUM_PRIMARY_VOICES, &wtConfig, pVoiceMgr->pFrameBuffer); } #endif return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * WT_CheckSampleEnd *---------------------------------------------------------------------------- * Purpose: * Check for end of sample and calculate number of samples to synthesize * * Inputs: * * Outputs: * * Notes: * *---------------------------------------------------------------------------- */ EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, EAS_BOOL update) { EAS_U32 endPhaseAccum; EAS_U32 endPhaseFrac; EAS_I32 numSamples; EAS_BOOL done = EAS_FALSE; /* check to see if we hit the end of the waveform this time */ /*lint -e{703} use shift for performance */ endPhaseFrac = pWTVoice->phaseFrac + (pWTIntFrame->frame.phaseIncrement << SYNTH_UPDATE_PERIOD_IN_BITS); #if defined (_8_BIT_SAMPLES) endPhaseAccum = pWTVoice->phaseAccum + GET_PHASE_INT_PART(endPhaseFrac); #else //_16_BIT_SAMPLES // Multiply by 2 for 16 bit processing module implementation endPhaseAccum = pWTVoice->phaseAccum + (EAS_U32)(endPhaseFrac >> 14); #endif if (endPhaseAccum >= pWTVoice->loopEnd) { /* calculate how far current ptr is from end */ numSamples = (EAS_I32) (pWTVoice->loopEnd - pWTVoice->phaseAccum); #if defined (_16_BIT_SAMPLES) numSamples >>= 1; // Divide by 2 for 16 bit processing module implementation #endif /* now account for the fractional portion */ /*lint -e{703} use shift for performance */ numSamples = (EAS_I32) ((numSamples << NUM_PHASE_FRAC_BITS) - pWTVoice->phaseFrac); if (pWTIntFrame->frame.phaseIncrement) { pWTIntFrame->numSamples = 1 + (numSamples / pWTIntFrame->frame.phaseIncrement); } else { pWTIntFrame->numSamples = numSamples; } if (pWTIntFrame->numSamples < 0) { //ALOGE("b/26366256"); //android_errorWriteLog(0x534e4554, "26366256"); pWTIntFrame->numSamples = 0; } /* sound will be done this frame */ done = EAS_TRUE; } /* update data for off-chip synth */ if (update) { pWTVoice->phaseFrac = endPhaseFrac; pWTVoice->phaseAccum = endPhaseAccum; } return done; } /*---------------------------------------------------------------------------- * WT_UpdateVoice() *---------------------------------------------------------------------------- * Purpose: * Synthesize a block of samples for the given voice. * Use linear interpolation. * * Inputs: * pEASData - pointer to overall EAS data structure * * Outputs: * number of samples actually written to buffer * * Side Effects: * - samples are added to the presently free buffer * *---------------------------------------------------------------------------- */ static EAS_BOOL WT_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples) { S_WT_VOICE *pWTVoice; S_WT_INT_FRAME intFrame; S_SYNTH_CHANNEL *pChannel; const S_WT_REGION *pWTRegion; const S_ARTICULATION *pArt; EAS_I32 temp; EAS_BOOL done; #ifdef DLS_SYNTHESIZER if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH) return DLS_UpdateVoice(pVoiceMgr, pSynth, pVoice, voiceNum, pMixBuffer, numSamples); #endif /* establish pointers to critical data */ pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; pWTRegion = &pSynth->pEAS->pWTRegions[pVoice->regionIndex & REGION_INDEX_MASK]; pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex]; pChannel = &pSynth->channels[pVoice->channel & 15]; intFrame.prevGain = pVoice->gain; /* update the envelopes */ WT_UpdateEG1(pWTVoice, &pArt->eg1); WT_UpdateEG2(pWTVoice, &pArt->eg2); /* update the LFO */ WT_UpdateLFO(&pWTVoice->modLFO, pArt->lfoFreq); #ifdef _FILTER_ENABLED /* calculate filter if library uses filter */ if (pSynth->pEAS->libAttr & LIB_FORMAT_FILTER_ENABLED) WT_UpdateFilter(pWTVoice, &intFrame, pArt); else intFrame.frame.k = 0; #endif /* update the gain */ intFrame.frame.gainTarget = WT_UpdateGain(pVoice, pWTVoice, pArt, pChannel, pWTRegion->gain); /* calculate base pitch*/ temp = pChannel->staticPitch + pWTRegion->tuning; /* include global transpose */ if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL) temp += pVoice->note * 100; else temp += (pVoice->note + pSynth->globalTranspose) * 100; intFrame.frame.phaseIncrement = WT_UpdatePhaseInc(pWTVoice, pArt, pChannel, temp); temp = pWTVoice->loopEnd - pWTVoice->loopStart; #ifdef _16_BIT_SAMPLES temp >>= 1; #endif if (temp != 0) { temp = temp << NUM_PHASE_FRAC_BITS; if (intFrame.frame.phaseIncrement > temp) { //ALOGW("%p phaseIncrement=%d", pWTVoice, (int)intFrame.frame.phaseIncrement); intFrame.frame.phaseIncrement %= temp; } } /* call into engine to generate samples */ intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer; intFrame.pMixBuffer = pMixBuffer; intFrame.numSamples = numSamples; /* check for end of sample */ if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd)) done = WT_CheckSampleEnd(pWTVoice, &intFrame, (EAS_BOOL) (voiceNum >= NUM_PRIMARY_VOICES)); else done = EAS_FALSE; if (intFrame.numSamples < 0) intFrame.numSamples = 0; if (intFrame.numSamples > BUFFER_SIZE_IN_MONO_SAMPLES) intFrame.numSamples = BUFFER_SIZE_IN_MONO_SAMPLES; #ifdef EAS_SPLIT_WT_SYNTH if (voiceNum < NUM_PRIMARY_VOICES) { #ifndef _SPLIT_WT_TEST_HARNESS WT_ProcessVoice(pWTVoice, &intFrame); #endif } else WTE_ProcessVoice(voiceNum - NUM_PRIMARY_VOICES, &intFrame.frame, pVoiceMgr->pFrameBuffer); #else WT_ProcessVoice(pWTVoice, &intFrame); #endif /* clear flag */ pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET; /* if voice has finished, set flag for voice manager */ if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted)) done = EAS_TRUE; /* if the update interval has elapsed, then force the current gain to the next * gain since we never actually reach the next gain when ramping -- we just get * very close to the target gain. */ pVoice->gain = (EAS_I16) intFrame.frame.gainTarget; return done; } /*---------------------------------------------------------------------------- * WT_UpdatePhaseInc() *---------------------------------------------------------------------------- * Purpose: * Calculate the phase increment * * Inputs: * pVoice - pointer to the voice being updated * psRegion - pointer to the region * psArticulation - pointer to the articulation * nChannelPitchForThisVoice - the portion of the pitch that is fixed for this * voice during the duration of this synthesis * pEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * set the phase increment for this voice *---------------------------------------------------------------------------- */ static EAS_I32 WT_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents) { EAS_I32 temp; /*pitchCents due to CC1 = LFO * (CC1 / 128) * DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS */ temp = MULT_EG1_EG1(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS, ((pChannel->modWheel) << (NUM_EG1_FRAC_BITS -7))); /* pitchCents due to channel pressure = LFO * (channel pressure / 128) * DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS */ temp += MULT_EG1_EG1(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS, ((pChannel->channelPressure) << (NUM_EG1_FRAC_BITS -7))); /* now multiply the (channel pressure + CC1) pitch values by the LFO value */ temp = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, temp); /* add in the LFO pitch due to channel pressure and CC1 along with the LFO pitch, the EG2 pitch, and the "static" pitch for this voice on this channel */ temp += pitchCents + (MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToPitch)) + (MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToPitch)); /* convert from cents to linear phase increment */ return EAS_Calculate2toX(temp); } /*---------------------------------------------------------------------------- * WT_UpdateChannel() *---------------------------------------------------------------------------- * Purpose: * Calculate and assign static channel parameters * These values only need to be updated if one of the controller values * for this channel changes * * Inputs: * nChannel - channel to update * pEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - the given channel's static gain and static pitch are updated *---------------------------------------------------------------------------- */ /*lint -esym(715, pVoiceMgr) reserved for future use */ static void WT_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel) { EAS_I32 staticGain; EAS_I32 pitchBend; S_SYNTH_CHANNEL *pChannel; pChannel = &pSynth->channels[channel]; /* nChannelGain = (CC7 * CC11)^2 * master volume where CC7 == 100 by default, CC11 == 127, master volume == 32767 */ staticGain = MULT_EG1_EG1((pChannel->volume) << (NUM_EG1_FRAC_BITS - 7), (pChannel->expression) << (NUM_EG1_FRAC_BITS - 7)); /* staticGain has to be squared */ staticGain = MULT_EG1_EG1(staticGain, staticGain); pChannel->staticGain = (EAS_I16) MULT_EG1_EG1(staticGain, pSynth->masterVolume); /* calculate pitch bend: RPN0 * ((2*pitch wheel)/16384 -1) However, if we use the EG1 macros, remember that EG1 has a full scale value of 32768 (instead of 16384). So instead of multiplying by 2, multiply by 4 (left shift by 2), and subtract by 32768 instead of 16384. This utilizes the fact that the EG1 macro places a binary point 15 places to the left instead of 14 places. */ /*lint -e{703} */ pitchBend = (((EAS_I32)(pChannel->pitchBend) << 2) - 32768); pChannel->staticPitch = MULT_EG1_EG1(pitchBend, pChannel->pitchBendSensitivity); /* if this is not a drum channel, then add in the per-channel tuning */ if (!(pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)) pChannel->staticPitch += pChannel->finePitch + (pChannel->coarsePitch * 100); /* clear update flag */ pChannel->channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS; return; } /*---------------------------------------------------------------------------- * WT_UpdateGain() *---------------------------------------------------------------------------- * Purpose: * Calculate and assign static voice parameters as part of WT_UpdateVoice() * * Inputs: * pVoice - ptr to the synth voice that we want to synthesize * pEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - various voice parameters are calculated and assigned * *---------------------------------------------------------------------------- */ static EAS_I32 WT_UpdateGain (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain) { EAS_I32 lfoGain; EAS_I32 temp; /* If this voice was stolen, then the velocity is actually for the new note, not the note that we are currently ramping down. So we really shouldn't use this velocity. However, that would require more memory to store the velocity value, and the improvement may not be sufficient to warrant the added memory. */ /* velocity is fixed at note start for a given voice and must be squared */ temp = (pVoice->velocity) << (NUM_EG1_FRAC_BITS - 7); temp = MULT_EG1_EG1(temp, temp); /* region gain is fixed as part of the articulation */ temp = MULT_EG1_EG1(temp, gain); /* include the channel gain */ temp = MULT_EG1_EG1(temp, pChannel->staticGain); /* calculate LFO gain using an approximation for 10^x */ lfoGain = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToGain); lfoGain = MULT_EG1_EG1(lfoGain, LFO_GAIN_TO_CENTS); /* convert from a dB-like value to linear gain */ lfoGain = EAS_Calculate2toX(lfoGain); temp = MULT_EG1_EG1(temp, lfoGain); /* calculate the voice's gain */ temp = (EAS_I16)MULT_EG1_EG1(temp, pWTVoice->eg1Value); return temp; } /*---------------------------------------------------------------------------- * WT_UpdateEG1() *---------------------------------------------------------------------------- * Purpose: * Calculate the EG1 envelope for the given voice (but do not update any * state) * * Inputs: * pVoice - ptr to the voice whose envelope we want to update * nVoice - this voice's number - used only for debug * pEASData - pointer to overall EAS data structure * * Outputs: * nValue - the envelope value * * Side Effects: * - updates EG1 state value for the given voice *---------------------------------------------------------------------------- */ static void WT_UpdateEG1 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv) { EAS_I32 temp; switch (pWTVoice->eg1State) { case eEnvelopeStateAttack: temp = pWTVoice->eg1Value + pWTVoice->eg1Increment; /* check if we have reached peak amplitude */ if (temp >= SYNTH_FULL_SCALE_EG1_GAIN) { /* limit the volume */ temp = SYNTH_FULL_SCALE_EG1_GAIN; /* prepare to move to decay state */ pWTVoice->eg1State = eEnvelopeStateDecay; pWTVoice->eg1Increment = pEnv->decayTime; } break; /* exponential decay */ case eEnvelopeStateDecay: temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment); /* check if we have reached sustain level */ if (temp <= pEnv->sustainLevel) { /* enforce the sustain level */ temp = pEnv->sustainLevel; /* if sustain level is zero, skip sustain & release the voice */ if (temp > 0) pWTVoice->eg1State = eEnvelopeStateSustain; /* move to sustain state */ else pWTVoice->eg1State = eEnvelopeStateMuted; } break; case eEnvelopeStateSustain: return; case eEnvelopeStateRelease: temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment); /* if we hit zero, this voice isn't contributing any audio */ if (temp <= 0) { temp = 0; pWTVoice->eg1State = eEnvelopeStateMuted; } break; /* voice is muted, set target to zero */ case eEnvelopeStateMuted: temp = 0; break; case eEnvelopeStateInvalid: default: temp = 0; #ifdef _DEBUG_SYNTH { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG1: error, %d is an unrecognized state\n", pWTVoice->eg1State); */ } #endif break; } pWTVoice->eg1Value = (EAS_I16) temp; } /*---------------------------------------------------------------------------- * WT_UpdateEG2() *---------------------------------------------------------------------------- * Purpose: * Update the EG2 envelope for the given voice * * Inputs: * pVoice - ptr to the voice whose envelope we want to update * pEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - updates EG2 values for the given voice *---------------------------------------------------------------------------- */ static void WT_UpdateEG2 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv) { EAS_I32 temp; switch (pWTVoice->eg2State) { case eEnvelopeStateAttack: temp = pWTVoice->eg2Value + pWTVoice->eg2Increment; /* check if we have reached peak amplitude */ if (temp >= SYNTH_FULL_SCALE_EG1_GAIN) { /* limit the volume */ temp = SYNTH_FULL_SCALE_EG1_GAIN; /* prepare to move to decay state */ pWTVoice->eg2State = eEnvelopeStateDecay; pWTVoice->eg2Increment = pEnv->decayTime; } break; /* implement linear pitch decay in cents */ case eEnvelopeStateDecay: temp = pWTVoice->eg2Value -pWTVoice->eg2Increment; /* check if we have reached sustain level */ if (temp <= pEnv->sustainLevel) { /* enforce the sustain level */ temp = pEnv->sustainLevel; /* prepare to move to sustain state */ pWTVoice->eg2State = eEnvelopeStateSustain; } break; case eEnvelopeStateSustain: return; case eEnvelopeStateRelease: temp = pWTVoice->eg2Value - pWTVoice->eg2Increment; if (temp <= 0) { temp = 0; pWTVoice->eg2State = eEnvelopeStateMuted; } break; /* voice is muted, set target to zero */ case eEnvelopeStateMuted: temp = 0; break; case eEnvelopeStateInvalid: default: temp = 0; #ifdef _DEBUG_SYNTH { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG2: error, %d is an unrecognized state\n", pWTVoice->eg2State); */ } #endif break; } pWTVoice->eg2Value = (EAS_I16) temp; } /*---------------------------------------------------------------------------- * WT_UpdateLFO () *---------------------------------------------------------------------------- * Purpose: * Calculate the LFO for the given voice * * Inputs: * pLFO - ptr to the LFO data * phaseInc - phase increment * * Outputs: * * Side Effects: * - updates LFO values for the given voice *---------------------------------------------------------------------------- */ void WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc) { /* To save memory, if m_nPhaseValue is negative, we are in the * delay phase, and m_nPhaseValue represents the time left * in the delay. */ if (pLFO->lfoPhase < 0) { pLFO->lfoPhase++; return; } /* calculate LFO output from phase value */ /*lint -e{701} Use shift for performance */ pLFO->lfoValue = (EAS_I16) (pLFO->lfoPhase << 2); /*lint -e{502} */ if ((pLFO->lfoPhase > 0x1fff) && (pLFO->lfoPhase < 0x6000)) pLFO->lfoValue = ~pLFO->lfoValue; /* update LFO phase */ pLFO->lfoPhase = (pLFO->lfoPhase + phaseInc) & 0x7fff; } #ifdef _FILTER_ENABLED /*---------------------------------------------------------------------------- * WT_UpdateFilter() *---------------------------------------------------------------------------- * Purpose: * Update the Filter parameters * * Inputs: * pVoice - ptr to the voice whose filter we want to update * pEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - updates Filter values for the given voice *---------------------------------------------------------------------------- */ static void WT_UpdateFilter (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, const S_ARTICULATION *pArt) { EAS_I32 cutoff; /* no need to calculate filter coefficients if it is bypassed */ if (pArt->filterCutoff == DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY) { pIntFrame->frame.k = 0; return; } /* determine the dynamic cutoff frequency */ cutoff = MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToFc); cutoff += pArt->filterCutoff; /* subtract the A5 offset and the sampling frequency */ cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS; /* limit the cutoff frequency */ if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS) cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS; else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS) cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS; WT_SetFilterCoeffs(pIntFrame, cutoff, pArt->filterQ); } #endif #if defined(_FILTER_ENABLED) || defined(DLS_SYNTHESIZER) /*---------------------------------------------------------------------------- * coef *---------------------------------------------------------------------------- * Table of filter coefficients for low-pass filter *---------------------------------------------------------------------------- * * polynomial coefficients are based on 8kHz sampling frequency * filter coef b2 = k2 = k2g0*k^0 + k2g1*k^1*(2^x) + k2g2*k^2*(2^x) * *where k2g0, k2g1, k2g2 are from the truncated power series expansion on theta *(k*2^x = theta, but we incorporate the k along with the k2g0, k2g1, k2g2) *note: this is a power series in 2^x, not k*2^x *where k = (2*pi*440)/8kHz == convert octaves to radians * * so actually, the following coefs listed as k2g0, k2g1, k2g2 are really * k2g0*k^0 = k2g0 * k2g1*k^1 * k2g2*k^2 * * * filter coef n1 = numerator = n1g0*k^0 + n1g1*k^1*(2^x) + n1g2*k^2*(2^x) + n1g3*k^3*(2^x) * *where n1g0, n1g1, n1g2, n1g3 are from the truncated power series expansion on theta *(k*2^x = theta, but we incorporate the k along with the n1g0, n1g1, n1g2, n2g3) *note: this is a power series in 2^x, not k*2^x *where k = (2*pi*440)/8kHz == convert octaves to radians *we also include the optimization factor of 0.81 * * so actually, the following coefs listed as n1g0, n1g1, n1g2, n2g3 are really * n1g0*k^0 = n1g0 * n1g1*k^1 * n1g2*k^2 * n1g3*k^3 * * NOTE that n1g0 == n1g1 == 0, always, so we only need to store n1g2 and n1g3 *---------------------------------------------------------------------------- */ static const EAS_I16 nk1g0 = -32768; static const EAS_I16 nk1g2 = 1580; static const EAS_I16 k2g0 = 32767; static const EAS_I16 k2g1[] = { -11324, /* k2g1[0] = -0.3455751918948761 */ -10387, /* k2g1[1] = -0.3169878073928751 */ -9528, /* k2g1[2] = -0.29076528753345476 */ -8740, /* k2g1[3] = -0.2667120011011279 */ -8017, /* k2g1[4] = -0.24464850028971705 */ -7353, /* k2g1[5] = -0.22441018194495696 */ -6745, /* k2g1[6] = -0.20584605955455101 */ -6187, /* k2g1[7] = -0.18881763682420102 */ -5675, /* k2g1[8] = -0.1731978744360067 */ -5206, /* k2g1[9] = -0.15887024228080968 */ -4775, /* k2g1[10] = -0.14572785009373057 */ -4380, /* k2g1[11] = -0.13367265000706827 */ -4018, /* k2g1[12] = -0.1226147050712642 */ -3685, /* k2g1[13] = -0.11247151828678581 */ -3381, /* k2g1[14] = -0.10316741714122014 */ -3101, /* k2g1[15] = -0.0946329890599603 */ -2844, /* k2g1[16] = -0.08680456355870586 */ -2609, /* k2g1[17] = -0.07962373723441349 */ -2393, /* k2g1[18] = -0.07303693805092666 */ -2195, /* k2g1[19] = -0.06699502566866912 */ -2014, /* k2g1[20] = -0.06145292483669077 */ -1847, /* k2g1[21] = -0.056369289112013346 */ -1694, /* k2g1[22] = -0.05170619239747895 */ -1554, /* k2g1[23] = -0.04742884599684141 */ -1426, /* k2g1[24] = -0.043505339076210514 */ -1308, /* k2g1[25] = -0.03990640059558053 */ -1199, /* k2g1[26] = -0.03660518093435039 */ -1100, /* k2g1[27] = -0.03357705158166837 */ -1009, /* k2g1[28] = -0.030799421397205727 */ -926, /* k2g1[29] = -0.028251568071585884 */ -849 /* k2g1[30] = -0.025914483529091967 */ }; static const EAS_I16 k2g2[] = { 1957, /* k2g2[0] = 0.059711106626580836 */ 1646, /* k2g2[1] = 0.05024063501786333 */ 1385, /* k2g2[2] = 0.042272226217199664 */ 1165, /* k2g2[3] = 0.03556764576567844 */ 981, /* k2g2[4] = 0.029926444346999134 */ 825, /* k2g2[5] = 0.025179964880280382 */ 694, /* k2g2[6] = 0.02118630011706455 */ 584, /* k2g2[7] = 0.01782604998793514 */ 491, /* k2g2[8] = 0.014998751854573014 */ 414, /* k2g2[9] = 0.012619876941179595 */ 348, /* k2g2[10] = 0.010618303146468736 */ 293, /* k2g2[11] = 0.008934188679954682 */ 246, /* k2g2[12] = 0.007517182949855368 */ 207, /* k2g2[13] = 0.006324921212866403 */ 174, /* k2g2[14] = 0.005321757979794424 */ 147, /* k2g2[15] = 0.004477701309210577 */ 123, /* k2g2[16] = 0.00376751612730811 */ 104, /* k2g2[17] = 0.0031699697655869644 */ 87, /* k2g2[18] = 0.00266719715992703 */ 74, /* k2g2[19] = 0.0022441667321724647 */ 62, /* k2g2[20] = 0.0018882309854916855 */ 52, /* k2g2[21] = 0.0015887483774966232 */ 44, /* k2g2[22] = 0.0013367651661223448 */ 37, /* k2g2[23] = 0.0011247477162958733 */ 31, /* k2g2[24] = 0.0009463572640678758 */ 26, /* k2g2[25] = 0.0007962604042473498 */ 22, /* k2g2[26] = 0.0006699696356181593 */ 18, /* k2g2[27] = 0.0005637091964589207 */ 16, /* k2g2[28] = 0.00047430217920125243 */ 13, /* k2g2[29] = 0.00039907554925166274 */ 11 /* k2g2[30] = 0.00033578022828973666 */ }; static const EAS_I16 n1g2[] = { 3170, /* n1g2[0] = 0.0967319927350769 */ 3036, /* n1g2[1] = 0.0926446051254155 */ 2908, /* n1g2[2] = 0.08872992911818503 */ 2785, /* n1g2[3] = 0.08498066682523227 */ 2667, /* n1g2[4] = 0.08138982872895201 */ 2554, /* n1g2[5] = 0.07795072065216213 */ 2446, /* n1g2[6] = 0.0746569312785634 */ 2343, /* n1g2[7] = 0.07150232020051943 */ 2244, /* n1g2[8] = 0.06848100647187474 */ 2149, /* n1g2[9] = 0.06558735764447099 */ 2058, /* n1g2[10] = 0.06281597926792246 */ 1971, /* n1g2[11] = 0.06016170483307614 */ 1888, /* n1g2[12] = 0.05761958614040857 */ 1808, /* n1g2[13] = 0.05518488407540374 */ 1732, /* n1g2[14] = 0.052853059773715245 */ 1659, /* n1g2[15] = 0.05061976615964251 */ 1589, /* n1g2[16] = 0.04848083984214659 */ 1521, /* n1g2[17] = 0.046432293353298 */ 1457, /* n1g2[18] = 0.04447030771468711 */ 1396, /* n1g2[19] = 0.04259122531793907 */ 1337, /* n1g2[20] = 0.040791543106060944 */ 1280, /* n1g2[21] = 0.03906790604290942 */ 1226, /* n1g2[22] = 0.037417100858604564 */ 1174, /* n1g2[23] = 0.035836050059229754 */ 1125, /* n1g2[24] = 0.03432180618965023 */ 1077, /* n1g2[25] = 0.03287154633875494 */ 1032, /* n1g2[26] = 0.03148256687687814 */ 988, /* n1g2[27] = 0.030152278415589925 */ 946, /* n1g2[28] = 0.028878200980459685 */ 906, /* n1g2[29] = 0.02765795938779331 */ 868 /* n1g2[30] = 0.02648927881672521 */ }; static const EAS_I16 n1g3[] = { -548, /* n1g3[0] = -0.016714088475899017 */ -481, /* n1g3[1] = -0.014683605122742116 */ -423, /* n1g3[2] = -0.012899791676436092 */ -371, /* n1g3[3] = -0.01133268185193299 */ -326, /* n1g3[4] = -0.00995594976868754 */ -287, /* n1g3[5] = -0.008746467702146129 */ -252, /* n1g3[6] = -0.00768391756106361 */ -221, /* n1g3[7] = -0.006750449563854721 */ -194, /* n1g3[8] = -0.005930382380083576 */ -171, /* n1g3[9] = -0.005209939699767622 */ -150, /* n1g3[10] = -0.004577018805123356 */ -132, /* n1g3[11] = -0.004020987256990177 */ -116, /* n1g3[12] = -0.003532504280467257 */ -102, /* n1g3[13] = -0.00310336384922047 */ -89, /* n1g3[14] = -0.002726356832432369 */ -78, /* n1g3[15] = -0.002395149888601605 */ -69, /* n1g3[16] = -0.0021041790717285314 */ -61, /* n1g3[17] = -0.0018485563625771063 */ -53, /* n1g3[18] = -0.001623987554831628 */ -47, /* n1g3[19] = -0.0014267001167177025 */ -41, /* n1g3[20] = -0.0012533798162347005 */ -36, /* n1g3[21] = -0.0011011150453668693 */ -32, /* n1g3[22] = -0.0009673479079754438 */ -28, /* n1g3[23] = -0.0008498312496971563 */ -24, /* n1g3[24] = -0.0007465909079943587 */ -21, /* n1g3[25] = -0.0006558925481952733 */ -19, /* n1g3[26] = -0.0005762125284029567 */ -17, /* n1g3[27] = -0.0005062123038325457 */ -15, /* n1g3[28] = -0.0004447159405951901 */ -13, /* n1g3[29] = -0.00039069036118270117 */ -11 /* n1g3[30] = -0.00034322798979677605 */ }; /*---------------------------------------------------------------------------- * WT_SetFilterCoeffs() *---------------------------------------------------------------------------- * Purpose: * Update the Filter parameters * * Inputs: * pVoice - ptr to the voice whose filter we want to update * pEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - updates Filter values for the given voice *---------------------------------------------------------------------------- */ void WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance) { EAS_I32 temp; /* Convert the cutoff, which has had A5 subtracted, using the 2^x approx Note, this cutoff is related to theta cutoff by theta = k * 2^x We use 2^x and incorporate k in the power series coefs instead */ cutoff = EAS_Calculate2toX(cutoff); /* calculate b2 coef */ temp = k2g1[resonance] + MULT_AUDIO_COEF(cutoff, k2g2[resonance]); temp = k2g0 + MULT_AUDIO_COEF(cutoff, temp); pIntFrame->frame.b2 = temp; /* calculate b1 coef */ temp = MULT_AUDIO_COEF(cutoff, nk1g2); temp = nk1g0 + MULT_AUDIO_COEF(cutoff, temp); temp += MULT_AUDIO_COEF(temp, pIntFrame->frame.b2); pIntFrame->frame.b1 = temp >> 1; /* calculate K coef */ temp = n1g2[resonance] + MULT_AUDIO_COEF(cutoff, n1g3[resonance]); temp = MULT_AUDIO_COEF(cutoff, temp); temp = MULT_AUDIO_COEF(cutoff, temp); pIntFrame->frame.k = temp; } #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_voicemgt.c0000644000000000000000000000013214200302440026712 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_voicemgt.c0000644000175000001440000040465214200302440027506 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_voicemgt.c * * Contents and purpose: * Implements the synthesizer functions. * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 794 $ * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $ *---------------------------------------------------------------------------- */ /* includes */ #include "eas.h" #include "eas_data.h" #include "eas_config.h" #include "eas_report.h" #include "eas_midictrl.h" #include "eas_host.h" #include "eas_synth_protos.h" #include "eas_vm_protos.h" #ifdef DLS_SYNTHESIZER #include "eas_mdls.h" #endif // #define _DEBUG_VM /* some defines for workload */ #define WORKLOAD_AMOUNT_SMALL_INCREMENT 5 #define WORKLOAD_AMOUNT_START_NOTE 10 #define WORKLOAD_AMOUNT_STOP_NOTE 10 #define WORKLOAD_AMOUNT_KEY_GROUP 10 #define WORKLOAD_AMOUNT_POLY_LIMIT 10 /* pointer to base sound library */ extern S_EAS easSoundLib; #ifdef TEST_HARNESS extern S_EAS easTestLib; EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum) { switch (libNum) { case 0: return &easSoundLib; #ifdef _WT_SYNTH case 1: return &easTestLib; #endif default: return NULL; } } #endif /* pointer to synthesizer interface(s) */ #ifdef _WT_SYNTH extern const S_SYNTH_INTERFACE wtSynth; #endif #ifdef _FM_SYNTH extern const S_SYNTH_INTERFACE fmSynth; #endif typedef S_SYNTH_INTERFACE *S_SYNTH_INTERFACE_HANDLE; /* wavetable on MCU */ #if defined(EAS_WT_SYNTH) const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth; /* FM on MCU */ #elif defined(EAS_FM_SYNTH) const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth; /* wavetable drums on MCU, FM melodic on DSP */ #elif defined(EAS_HYBRID_SYNTH) const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth; const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth; /* wavetable drums on MCU, wavetable melodic on DSP */ #elif defined(EAS_SPLIT_WT_SYNTH) const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth; extern const S_FRAME_INTERFACE wtFrameInterface; const S_FRAME_INTERFACE *const pFrameInterface = &wtFrameInterface; /* wavetable drums on MCU, FM melodic on DSP */ #elif defined(EAS_SPLIT_HYBRID_SYNTH) const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth; const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth; extern const S_FRAME_INTERFACE fmFrameInterface; const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface; /* FM on DSP */ #elif defined(EAS_SPLIT_FM_SYNTH) const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth; extern const S_FRAME_INTERFACE fmFrameInterface; const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface; #else #error "Undefined architecture option" #endif /*---------------------------------------------------------------------------- * inline functions *---------------------------------------------------------------------------- */ EAS_INLINE const S_REGION* GetRegionPtr (S_SYNTH *pSynth, EAS_U16 regionIndex) { #if defined(DLS_SYNTHESIZER) if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH) return &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK].wtRegion.region; #endif #if defined(_HYBRID_SYNTH) if (regionIndex & FLAG_RGN_IDX_FM_SYNTH) return &pSynth->pEAS->pFMRegions[regionIndex & REGION_INDEX_MASK].region; else return &pSynth->pEAS->pWTRegions[regionIndex].region; #elif defined(_WT_SYNTH) return &pSynth->pEAS->pWTRegions[regionIndex].region; #elif defined(_FM_SYNTH) return &pSynth->pEAS->pFMRegions[regionIndex].region; #endif } /*lint -esym(715, voiceNum) used in some implementation */ EAS_INLINE const S_SYNTH_INTERFACE* GetSynthPtr (EAS_INT voiceNum) { #if defined(_HYBRID_SYNTH) if (voiceNum < NUM_PRIMARY_VOICES) return pPrimarySynth; else return pSecondarySynth; #else return pPrimarySynth; #endif } EAS_INLINE EAS_INT GetAdjustedVoiceNum (EAS_INT voiceNum) { #if defined(_HYBRID_SYNTH) if (voiceNum >= NUM_PRIMARY_VOICES) return voiceNum - NUM_PRIMARY_VOICES; #endif return voiceNum; } EAS_INLINE EAS_U8 VSynthToChannel (S_SYNTH *pSynth, EAS_U8 channel) { /*lint -e{734} synthNum is always 0-15 */ return channel | (pSynth->vSynthNum << 4); } /*---------------------------------------------------------------------------- * InitVoice() *---------------------------------------------------------------------------- * Initialize a synthesizer voice *---------------------------------------------------------------------------- */ void InitVoice (S_SYNTH_VOICE *pVoice) { pVoice->channel = UNASSIGNED_SYNTH_CHANNEL; pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL; pVoice->note = pVoice->nextNote = DEFAULT_KEY_NUMBER; pVoice->velocity = pVoice->nextVelocity = DEFAULT_VELOCITY; pVoice->regionIndex = DEFAULT_REGION_INDEX; pVoice->age = DEFAULT_AGE; pVoice->voiceFlags = DEFAULT_VOICE_FLAGS; pVoice->voiceState = DEFAULT_VOICE_STATE; } /*---------------------------------------------------------------------------- * IncVoicePoolCount() *---------------------------------------------------------------------------- * Updates the voice pool count when a voice changes state *---------------------------------------------------------------------------- */ static void IncVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice) { S_SYNTH *pSynth; EAS_INT pool; /* ignore muting voices */ if (pVoice->voiceState == eVoiceStateMuting) return; if (pVoice->voiceState == eVoiceStateStolen) { pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)]; pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool; } else { pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)]; pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool; } pSynth->poolCount[pool]++; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IncVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ } #endif } /*---------------------------------------------------------------------------- * DecVoicePoolCount() *---------------------------------------------------------------------------- * Updates the voice pool count when a voice changes state *---------------------------------------------------------------------------- */ static void DecVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice) { S_SYNTH *pSynth; EAS_INT pool; /* ignore muting voices */ if (pVoice->voiceState == eVoiceStateMuting) return; if (pVoice->voiceState == eVoiceStateStolen) { pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)]; pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool; } else { pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)]; pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool; } pSynth->poolCount[pool]--; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "DecVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ } #endif } /*---------------------------------------------------------------------------- * VMInitialize() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ EAS_RESULT VMInitialize (S_EAS_DATA *pEASData) { S_VOICE_MGR *pVoiceMgr; EAS_INT i; /* check Configuration Module for data allocation */ if (pEASData->staticMemoryModel) pVoiceMgr = EAS_CMEnumData(EAS_CM_SYNTH_DATA); else pVoiceMgr = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_VOICE_MGR)); if (!pVoiceMgr) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitialize: Failed to allocate synthesizer memory\n"); */ } return EAS_ERROR_MALLOC_FAILED; } EAS_HWMemSet(pVoiceMgr, 0, sizeof(S_VOICE_MGR)); /* initialize non-zero variables */ pVoiceMgr->pGlobalEAS = (S_EAS*) &easSoundLib; pVoiceMgr->maxPolyphony = (EAS_U16) MAX_SYNTH_VOICES; #if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH) pVoiceMgr->maxPolyphonyPrimary = NUM_PRIMARY_VOICES; pVoiceMgr->maxPolyphonySecondary = NUM_SECONDARY_VOICES; #endif /* set max workload to zero */ pVoiceMgr->maxWorkLoad = 0; /* initialize the voice manager parameters */ for (i = 0; i < MAX_SYNTH_VOICES; i++) InitVoice(&pVoiceMgr->voices[i]); /* initialize the synth */ /*lint -e{522} return unused at this time */ pPrimarySynth->pfInitialize(pVoiceMgr); /* initialize the off-chip synth */ #ifdef _HYBRID_SYNTH /*lint -e{522} return unused at this time */ pSecondarySynth->pfInitialize(pVoiceMgr); #endif pEASData->pVoiceMgr = pVoiceMgr; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMInitMIDI() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth) { EAS_RESULT result; S_SYNTH *pSynth; EAS_INT virtualSynthNum; *ppSynth = NULL; /* static memory model only allows one synth */ if (pEASData->staticMemoryModel) { if (pEASData->pVoiceMgr->pSynth[0] != NULL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: No virtual synthesizer support for static memory model\n"); */ } return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER; } /* check Configuration Module for data allocation */ pSynth = EAS_CMEnumData(EAS_CM_MIDI_DATA); virtualSynthNum = 0; } /* dynamic memory model */ else { for (virtualSynthNum = 0; virtualSynthNum < MAX_VIRTUAL_SYNTHESIZERS; virtualSynthNum++) if (pEASData->pVoiceMgr->pSynth[virtualSynthNum] == NULL) break; if (virtualSynthNum == MAX_VIRTUAL_SYNTHESIZERS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Exceeded number of active virtual synthesizers"); */ } return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER; } pSynth = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SYNTH)); } /* make sure we have a valid memory pointer */ if (pSynth == NULL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Failed to allocate synthesizer memory\n"); */ } return EAS_ERROR_MALLOC_FAILED; } EAS_HWMemSet(pSynth, 0, sizeof(S_SYNTH)); /* set the sound library pointer */ if ((result = VMSetEASLib(pSynth, pEASData->pVoiceMgr->pGlobalEAS)) != EAS_SUCCESS) { VMMIDIShutdown(pEASData, pSynth); return result; } /* link in DLS bank if downloaded */ #ifdef DLS_SYNTHESIZER if (pEASData->pVoiceMgr->pGlobalDLS) { pSynth->pDLS = pEASData->pVoiceMgr->pGlobalDLS; DLSAddRef(pSynth->pDLS); } #endif /* initialize MIDI state variables */ pSynth->synthFlags = DEFAULT_SYNTH_FLAGS; pSynth->masterVolume = DEFAULT_SYNTH_MASTER_VOLUME; pSynth->refCount = 1; pSynth->priority = DEFAULT_SYNTH_PRIORITY; pSynth->poolAlloc[0] = (EAS_U8) pEASData->pVoiceMgr->maxPolyphony; VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth); pSynth->vSynthNum = (EAS_U8) virtualSynthNum; pEASData->pVoiceMgr->pSynth[virtualSynthNum] = pSynth; *ppSynth = pSynth; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMIncRefCount() *---------------------------------------------------------------------------- * Increment reference count for virtual synth *---------------------------------------------------------------------------- */ void VMIncRefCount (S_SYNTH *pSynth) { pSynth->refCount++; } /*---------------------------------------------------------------------------- * VMReset() *---------------------------------------------------------------------------- * Purpose: * We call this routine to start the process of reseting the synth. * This routine sets a flag for the entire synth indicating that we want * to reset. * We also force all voices to mute quickly. * However, we do not actually perform any synthesis in this routine. That * is, we do not ramp the voices down from this routine, but instead, we * let the "regular" synth processing steps take care of adding the ramp * down samples to the output buffer. After we are sure that all voices * have completed ramping down, we continue the process of resetting the * synth (from another routine). * * Inputs: * psEASData - pointer to overall EAS data structure * force - force reset even if voices are active * * Outputs: * * Side Effects: * - set a flag (in psSynthObject->m_nFlags) indicating synth reset requested. * - force all voices to update their envelope states to mute * *---------------------------------------------------------------------------- */ void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force) { #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: request to reset synth. Force = %d\n", force); */ } #endif /* force voices to off state - may cause audio artifacts */ if (force) { pVoiceMgr->activeVoices -= pSynth->numActiveVoices; pSynth->numActiveVoices = 0; VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum); } else VMMuteAllVoices(pVoiceMgr, pSynth); /* don't reset if voices are still playing */ if (pSynth->numActiveVoices == 0) { EAS_INT i; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: complete the reset process\n"); */ } #endif VMInitializeAllChannels(pVoiceMgr, pSynth); for (i = 0; i < NUM_SYNTH_CHANNELS; i++) pSynth->poolCount[i] = 0; /* set polyphony */ if (pSynth->maxPolyphony < pVoiceMgr->maxPolyphony) pSynth->poolAlloc[0] = (EAS_U8) pVoiceMgr->maxPolyphony; else pSynth->poolAlloc[0] = (EAS_U8) pSynth->maxPolyphony; /* clear reset flag */ pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED; } /* handle reset after voices are muted */ else pSynth->synthFlags |= SYNTH_FLAG_RESET_IS_REQUESTED; } /*---------------------------------------------------------------------------- * VMInitializeAllChannels() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth) { S_SYNTH_CHANNEL *pChannel; EAS_INT i; VMResetControllers(pSynth); /* init each channel */ pChannel = pSynth->channels; for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++) { pChannel->channelFlags = DEFAULT_CHANNEL_FLAGS; pChannel->staticGain = DEFAULT_CHANNEL_STATIC_GAIN; pChannel->staticPitch = DEFAULT_CHANNEL_STATIC_PITCH; pChannel->pool = 0; /* the drum channel needs a different init */ if (i == DEFAULT_DRUM_CHANNEL) { pChannel->bankNum = DEFAULT_RHYTHM_BANK_NUMBER; pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL; } else pChannel->bankNum = DEFAULT_MELODY_BANK_NUMBER; VMProgramChange(pVoiceMgr, pSynth, (EAS_U8) i, DEFAULT_SYNTH_PROGRAM_NUMBER); } } /*---------------------------------------------------------------------------- * VMResetControllers() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ void VMResetControllers (S_SYNTH *pSynth) { S_SYNTH_CHANNEL *pChannel; EAS_INT i; pChannel = pSynth->channels; for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++) { pChannel->pitchBend = DEFAULT_PITCH_BEND; pChannel->modWheel = DEFAULT_MOD_WHEEL; pChannel->volume = DEFAULT_CHANNEL_VOLUME; pChannel->pan = DEFAULT_PAN; pChannel->expression = DEFAULT_EXPRESSION; #ifdef _REVERB pSynth->channels[i].reverbSend = DEFAULT_REVERB_SEND; #endif #ifdef _CHORUS pSynth->channels[i].chorusSend = DEFAULT_CHORUS_SEND; #endif pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE; pChannel->registeredParam = DEFAULT_REGISTERED_PARAM; pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY; pChannel->finePitch = DEFAULT_FINE_PITCH; pChannel->coarsePitch = DEFAULT_COARSE_PITCH; /* update all voices on this channel */ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS; } } /*---------------------------------------------------------------------------- * VMInitializeAllVoices() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * *---------------------------------------------------------------------------- */ void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum) { EAS_INT i; /* initialize the voice manager parameters */ for (i = 0; i < MAX_SYNTH_VOICES; i++) { if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen) { if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == vSynthNum) InitVoice(&pVoiceMgr->voices[i]); } else { if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == vSynthNum) InitVoice(&pVoiceMgr->voices[i]); } } } /*---------------------------------------------------------------------------- * VMMuteVoice() *---------------------------------------------------------------------------- * Mute the selected voice *---------------------------------------------------------------------------- */ void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum) { S_SYNTH *pSynth; S_SYNTH_VOICE *pVoice; /* take no action if voice is already muted */ pVoice = &pVoiceMgr->voices[voiceNum]; if ((pVoice->voiceState == eVoiceStateMuting) || (pVoice->voiceState == eVoiceStateFree)) return; /* one less voice in pool */ DecVoicePoolCount(pVoiceMgr, pVoice); pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)]; GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum)); pVoice->voiceState = eVoiceStateMuting; } /*---------------------------------------------------------------------------- * VMReleaseVoice() *---------------------------------------------------------------------------- * Release the selected voice *---------------------------------------------------------------------------- */ void VMReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum) { S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum]; /* take no action if voice is already free, muting, or releasing */ if (( pVoice->voiceState == eVoiceStateMuting) || (pVoice->voiceState == eVoiceStateFree) || (pVoice->voiceState == eVoiceStateRelease)) return; /* stolen voices should just be muted */ if (pVoice->voiceState == eVoiceStateStolen) VMMuteVoice(pVoiceMgr, voiceNum); /* release this voice */ GetSynthPtr(voiceNum)->pfReleaseVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum)); pVoice->voiceState = eVoiceStateRelease; } /*---------------------------------------------------------------------------- * VMInitMIPTable() *---------------------------------------------------------------------------- * Initialize the SP-MIDI MIP table in preparation for receiving MIP message *---------------------------------------------------------------------------- */ void VMInitMIPTable (S_SYNTH *pSynth) { EAS_INT i; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMInitMIPTable\n"); */ } #endif /* clear SP-MIDI flag */ pSynth->synthFlags &= ~SYNTH_FLAG_SP_MIDI_ON; for (i = 0; i < NUM_SYNTH_CHANNELS; i++) { pSynth->channels[i].pool = 0; pSynth->channels[i].mip = 0; } } /*---------------------------------------------------------------------------- * VMSetMIPEntry() *---------------------------------------------------------------------------- * Sets the priority and MIP level for a MIDI channel *---------------------------------------------------------------------------- */ /*lint -esym(715, pVoiceMgr) reserved for future use */ void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip) { #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMSetMIPEntry: channel=%d, priority=%d, MIP=%d\n", channel, priority, mip); */ } #endif /* save data for use by MIP message processing */ if (priority < NUM_SYNTH_CHANNELS) { pSynth->channels[channel].pool = priority; pSynth->channels[channel].mip = mip; } } /*---------------------------------------------------------------------------- * VMMIPUpdateChannelMuting() *---------------------------------------------------------------------------- * This routine is called after an SP-MIDI message is received and * any time the allocated polyphony changes. It mutes or unmutes * channels based on polyphony. *---------------------------------------------------------------------------- */ void VMMIPUpdateChannelMuting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth) { EAS_INT i; EAS_INT maxPolyphony; EAS_INT channel; EAS_INT vSynthNum; EAS_INT pool; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ } #endif /* determine max polyphony */ if (pSynth->maxPolyphony) maxPolyphony = pSynth->maxPolyphony; else maxPolyphony = pVoiceMgr->maxPolyphony; /* process channels */ for (i = 0; i < NUM_SYNTH_CHANNELS; i++) { /* channel must be in MIP message and must meet allocation target */ if ((pSynth->channels[i].mip != 0) && (pSynth->channels[i].mip <= maxPolyphony)) pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_MUTE; else pSynth->channels[i].channelFlags |= CHANNEL_FLAG_MUTE; /* reset voice pool count */ pSynth->poolCount[i] = 0; } /* mute any voices on muted channels, and count unmuted voices */ for (i = 0; i < MAX_SYNTH_VOICES; i++) { /* ignore free voices */ if (pVoiceMgr->voices[i].voiceState == eVoiceStateFree) continue; /* get channel and virtual synth */ if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen) { vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].channel); channel = GET_CHANNEL(pVoiceMgr->voices[i].channel); } else { vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].nextChannel); channel = GET_CHANNEL(pVoiceMgr->voices[i].nextChannel); } /* ignore voices on other synths */ if (vSynthNum != pSynth->vSynthNum) continue; /* count voices */ pool = pSynth->channels[channel].pool; /* deal with muted channels */ if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_MUTE) { /* mute stolen voices scheduled to play on this channel */ if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen) pVoiceMgr->voices[i].voiceState = eVoiceStateMuting; /* release voices that aren't already muting */ else if (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting) { VMReleaseVoice(pVoiceMgr, pSynth, i); pSynth->poolCount[pool]++; } } /* not muted, count this voice */ else pSynth->poolCount[pool]++; } } /*---------------------------------------------------------------------------- * VMUpdateMIPTable() *---------------------------------------------------------------------------- * This routine is called at the end of the SysEx message to allow * the Voice Manager to complete the initialization of the MIP * table. It assigns channels to the appropriate voice pool based * on the MIP setting and calculates the voices allocated for each * pool. *---------------------------------------------------------------------------- */ /*lint -esym(715, pVoiceMgr) reserved for future use */ void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth) { S_SYNTH_CHANNEL *pChannel; EAS_INT i; EAS_INT currentMIP; EAS_INT currentPool; EAS_INT priority[NUM_SYNTH_CHANNELS]; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ } #endif /* set SP-MIDI flag */ pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON; /* sort channels into priority order */ for (i = 0; i < NUM_SYNTH_CHANNELS; i++) priority[i] = -1; for (i = 0; i < NUM_SYNTH_CHANNELS; i++) { if (pSynth->channels[i].pool != DEFAULT_SP_MIDI_PRIORITY) priority[pSynth->channels[i].pool] = i; } /* process channels in priority order */ currentMIP = 0; currentPool = -1; for (i = 0; i < NUM_SYNTH_CHANNELS; i++) { /* stop when we run out of channels */ if (priority[i] == -1) break; pChannel = &pSynth->channels[priority[i]]; /* when 2 or more channels have the same MIP setting, they * share a common voice pool */ if (pChannel->mip == currentMIP && currentPool != -1) pChannel->pool = (EAS_U8) currentPool; /* new voice pool */ else { currentPool++; pSynth->poolAlloc[currentPool] = (EAS_U8) (pChannel->mip - currentMIP); currentMIP = pChannel->mip; } } /* set SP-MIDI flag */ pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON; /* update channel muting */ VMMIPUpdateChannelMuting (pVoiceMgr, pSynth); } /*---------------------------------------------------------------------------- * VMMuteAllVoices() *---------------------------------------------------------------------------- * Purpose: * We call this in an emergency reset situation. * This forces all voices to mute quickly. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - forces all voices to update their envelope states to mute * *---------------------------------------------------------------------------- */ void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth) { EAS_INT i; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMMuteAllVoices: about to mute all voices!!\n"); */ } #endif for (i = 0; i < MAX_SYNTH_VOICES; i++) { /* for stolen voices, check new channel */ if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen) { if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum) VMMuteVoice(pVoiceMgr, i); } else if (pSynth->vSynthNum == GET_VSYNTH(pVoiceMgr->voices[i].channel)) VMMuteVoice(pVoiceMgr, i); } } /*---------------------------------------------------------------------------- * VMReleaseAllVoices() *---------------------------------------------------------------------------- * Purpose: * We call this after we've encountered the end of the Midi file. * This ensures all voices are either in release (because we received their * note off already) or forces them to mute quickly. * We use this as a safety to prevent bad midi files from playing forever. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - forces all voices to update their envelope states to release or mute * *---------------------------------------------------------------------------- */ void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth) { EAS_INT i; /* release sustain pedal on all channels */ for (i = 0; i < NUM_SYNTH_CHANNELS; i++) { if (pSynth->channels[ i ].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL) { VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, (EAS_U8) i); pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL; } } /* release all voices */ for (i = 0; i < MAX_SYNTH_VOICES; i++) { switch (pVoiceMgr->voices[i].voiceState) { case eVoiceStateStart: case eVoiceStatePlay: /* only release voices on this synth */ if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == pSynth->vSynthNum) VMReleaseVoice(pVoiceMgr, pSynth, i); break; case eVoiceStateStolen: if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum) VMMuteVoice(pVoiceMgr, i); break; case eVoiceStateFree: case eVoiceStateRelease: case eVoiceStateMuting: break; case eVoiceStateInvalid: default: #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllVoices: error, %d is an unrecognized state\n", pVoiceMgr->voices[i].voiceState); */ } #endif break; } } } /*---------------------------------------------------------------------------- * VMAllNotesOff() *---------------------------------------------------------------------------- * Purpose: * Quickly mute all notes on the given channel. * * Inputs: * nChannel - quickly turn off all notes on this channel * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * - forces all voices on this channel to update their envelope states to mute * *---------------------------------------------------------------------------- */ void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel) { EAS_INT voiceNum; S_SYNTH_VOICE *pVoice; #ifdef _DEBUG_VM if (channel >= NUM_SYNTH_CHANNELS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAllNotesOff: error, %d invalid channel number\n", channel); */ } return; } #endif /* increment workload */ pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT; /* check each voice */ channel = VSynthToChannel(pSynth, channel); for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++) { pVoice = &pVoiceMgr->voices[voiceNum]; if (pVoice->voiceState != eVoiceStateFree) { if (((pVoice->voiceState != eVoiceStateStolen) && (channel == pVoice->channel)) || ((pVoice->voiceState == eVoiceStateStolen) && (channel == pVoice->nextChannel))) { /* this voice is assigned to the requested channel */ GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum)); pVoice->voiceState = eVoiceStateMuting; } } } } /*---------------------------------------------------------------------------- * VMDeferredStopNote() *---------------------------------------------------------------------------- * Purpose: * Stop the notes that had deferred note-off requests. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * None. * * Side Effects: * voices that have had deferred note-off requests are now put into release * psSynthObject->m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF * cleared *---------------------------------------------------------------------------- */ void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth) { EAS_INT voiceNum; EAS_INT channel; EAS_BOOL deferredNoteOff; deferredNoteOff = EAS_FALSE; /* check each voice to see if it requires a deferred note off */ for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++) { if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF) { /* check if this voice was stolen */ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen) { /* This voice was stolen, AND it also has a deferred note-off. The stolen note must be completely ramped down at this point. The note that caused the stealing to occur, however, must have received a note-off request before the note that caused stealing ever had a chance to even start. We want to give the note that caused the stealing a chance to play, so we start it on the next update interval, and we defer sending the note-off request until the subsequent update interval. So do not send the note-off request for this voice because this voice was stolen and should have completed ramping down, Also, do not clear the global flag nor this voice's flag because we must indicate that the subsequent update interval, after the note that caused stealing has started, should then send the deferred note-off request. */ deferredNoteOff = EAS_TRUE; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: defer request to stop voice %d (channel=%d note=%d) - voice not started\n", voiceNum, pVoiceMgr->voices[voiceNum].nextChannel, pVoiceMgr->voices[voiceNum].note); */ } /* sanity check: this stolen voice better be ramped to zero */ if (0 != pVoiceMgr->voices[voiceNum].gain) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: warning, this voice did not complete its ramp to zero\n"); */ } } #endif // #ifdef _DEBUG_VM } else { /* clear the flag using exor */ pVoiceMgr->voices[voiceNum].voiceFlags ^= VOICE_FLAG_DEFER_MIDI_NOTE_OFF; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: Stop voice %d (channel=%d note=%d)\n", voiceNum, pVoiceMgr->voices[voiceNum].nextChannel, pVoiceMgr->voices[voiceNum].note); */ } #endif channel = pVoiceMgr->voices[voiceNum].channel & 15; /* check if sustain pedal is on */ if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL) { GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum)); } /* release this voice */ else VMReleaseVoice(pVoiceMgr, pSynth, voiceNum); } } } /* clear the deferred note-off flag, unless there's another one pending */ if (deferredNoteOff == EAS_FALSE) pSynth->synthFlags ^= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING; } /*---------------------------------------------------------------------------- * VMReleaseAllDeferredNoteOffs() *---------------------------------------------------------------------------- * Purpose: * Call this functin when the sustain flag is presently set but * we are now transitioning from damper pedal on to * damper pedal off. This means all notes in this channel * that received a note off while the damper pedal was on, and * had their note-off requests deferred, should now proceed to * the release state. * * Inputs: * nChannel - this channel has its sustain pedal transitioning from on to off * psEASData - pointer to overall EAS data structure * * Outputs: * Side Effects: * any voice with deferred note offs on this channel are updated such that * pVoice->m_sEG1.m_eState = eEnvelopeStateRelease * pVoice->m_sEG1.m_nIncrement = release increment * pVoice->m_nFlags = clear the deferred note off flag *---------------------------------------------------------------------------- */ void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel) { S_SYNTH_VOICE *pVoice; EAS_INT voiceNum; #ifdef _DEBUG_VM if (channel >= NUM_SYNTH_CHANNELS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllDeferredNoteOffs: error, %d invalid channel number\n", channel); */ } return; } #endif /* #ifdef _DEBUG_VM */ /* increment workload */ pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT; /* find all the voices assigned to this channel */ channel = VSynthToChannel(pSynth, channel); for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++) { pVoice = &pVoiceMgr->voices[voiceNum]; if (channel == pVoice->channel) { /* does this voice have a deferred note off? */ if (pVoice->voiceFlags & VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF) { /* release voice */ VMReleaseVoice(pVoiceMgr, pSynth, voiceNum); /* use exor to flip bit, clear the flag */ pVoice->voiceFlags &= ~VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF; } } } return; } /*---------------------------------------------------------------------------- * VMCatchNotesForSustainPedal() *---------------------------------------------------------------------------- * Purpose: * Call this function when the sustain flag is presently clear and * the damper pedal is off and we are transitioning from damper pedal OFF to * damper pedal ON. Currently sounding notes should be left * unchanged. However, we should try to "catch" notes if possible. * If any notes are in release and have levels >= sustain level, catch them, * otherwise, let them continue to release. * * Inputs: * nChannel - this channel has its sustain pedal transitioning from on to off * psEASData - pointer to overall EAS data structure * * Outputs: *---------------------------------------------------------------------------- */ void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel) { EAS_INT voiceNum; #ifdef _DEBUG_VM if (channel >= NUM_SYNTH_CHANNELS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCatchNotesForSustainPedal: error, %d invalid channel number\n", channel); */ } return; } #endif pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT; channel = VSynthToChannel(pSynth, channel); /* find all the voices assigned to this channel */ for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++) { if (channel == pVoiceMgr->voices[voiceNum].channel) { if (eVoiceStateRelease == pVoiceMgr->voices[voiceNum].voiceState) GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum)); } } } /*---------------------------------------------------------------------------- * VMUpdateAllNotesAge() *---------------------------------------------------------------------------- * Purpose: * Increment the note age for all of the active voices. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * m_nAge for all voices is incremented *---------------------------------------------------------------------------- */ void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 age) { EAS_INT i; for (i = 0; i < MAX_SYNTH_VOICES; i++) { if (age - pVoiceMgr->voices[i].age > 0) pVoiceMgr->voices[i].age++; } } /*---------------------------------------------------------------------------- * VMStolenVoice() *---------------------------------------------------------------------------- * Purpose: * The selected voice is being stolen. Sets the parameters so that the * voice will begin playing the new sound on the next buffer. * * Inputs: * pVoice - pointer to voice to steal * nChannel - the channel to start a note on * nKeyNumber - the key number to start a note for * nNoteVelocity - the key velocity from this note * * Outputs: * None *---------------------------------------------------------------------------- */ static void VMStolenVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex) { S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum]; /* one less voice in old pool */ DecVoicePoolCount(pVoiceMgr, pVoice); /* mute the sound that is currently playing */ GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)], &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum)); pVoice->voiceState = eVoiceStateStolen; /* set new note data */ pVoice->nextChannel = VSynthToChannel(pSynth, channel); pVoice->nextNote = note; pVoice->nextVelocity = velocity; pVoice->nextRegionIndex = regionIndex; /* one more voice in new pool */ IncVoicePoolCount(pVoiceMgr, pVoice); /* clear the deferred flags */ pVoice->voiceFlags &= ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF | VOICE_FLAG_DEFER_MUTE | VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF); /* all notes older than this one get "younger" */ VMUpdateAllNotesAge(pVoiceMgr, pVoice->age); /* assign current age to this note and increment for the next note */ pVoice->age = pVoiceMgr->age++; } /*---------------------------------------------------------------------------- * VMFreeVoice() *---------------------------------------------------------------------------- * Purpose: * The selected voice is done playing and being returned to the * pool of free voices * * Inputs: * pVoice - pointer to voice to free * * Outputs: * None *---------------------------------------------------------------------------- */ static void VMFreeVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice) { /* do nothing if voice is already free */ if (pVoice->voiceState == eVoiceStateFree) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMFreeVoice: Attempt to free voice that is already free\n"); */ } return; } /* if we jump directly to free without passing muting stage, * we need to adjust the voice count */ DecVoicePoolCount(pVoiceMgr, pVoice); #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMFreeVoice: Synth=%d\n", pSynth->vSynthNum); */ } #endif /* return to free voice pool */ pVoiceMgr->activeVoices--; pSynth->numActiveVoices--; InitVoice(pVoice); #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFreeVoice: free voice %d\n", pVoice - pVoiceMgr->voices); */ } #endif /* all notes older than this one get "younger" */ VMUpdateAllNotesAge(pVoiceMgr, pVoice->age); } /*---------------------------------------------------------------------------- * VMRetargetStolenVoice() *---------------------------------------------------------------------------- * Purpose: * The selected voice has been stolen and needs to be initalized with * the paramters of its new note. * * Inputs: * pVoice - pointer to voice to retarget * * Outputs: * None *---------------------------------------------------------------------------- */ static EAS_BOOL VMRetargetStolenVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum) { EAS_U8 flags; S_SYNTH_CHANNEL *pMIDIChannel; S_SYNTH_VOICE *pVoice; S_SYNTH *pSynth; S_SYNTH *pNextSynth; /* establish some pointers */ pVoice = &pVoiceMgr->voices[voiceNum]; pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)]; pMIDIChannel = &pSynth->channels[pVoice->channel & 15]; pNextSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)]; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: retargeting stolen voice %d on channel %d\n", voiceNum, pVoice->channel); */ } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\to channel %d note: %d velocity: %d\n", pVoice->nextChannel, pVoice->nextNote, pVoice->nextVelocity); */ } #endif /* make sure new channel hasn't been muted by SP-MIDI since the voice was stolen */ if ((pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON) && (pMIDIChannel->channelFlags & CHANNEL_FLAG_MUTE)) { VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]); return EAS_FALSE; } /* if assigned to a new synth, correct the active voice count */ if (pVoice->channel != pVoice->nextChannel) { #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: Note assigned to different virtual synth, adjusting numActiveVoices\n"); */ } #endif pSynth->numActiveVoices--; pNextSynth->numActiveVoices++; } /* assign new channel number, and increase channel voice count */ pVoice->channel = pVoice->nextChannel; pMIDIChannel = &pNextSynth->channels[pVoice->channel & 15]; /* assign other data */ pVoice->note = pVoice->nextNote; pVoice->velocity = pVoice->nextVelocity; pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL; pVoice->regionIndex = pVoice->nextRegionIndex; /* save the flags, pfStartVoice() will clear them */ flags = pVoice->voiceFlags; /* keep track of the note-start related workload */ pVoiceMgr->workload += WORKLOAD_AMOUNT_START_NOTE; /* setup the voice parameters */ pVoice->voiceState = eVoiceStateStart; /*lint -e{522} return not used at this time */ GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pNextSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pVoice->regionIndex); /* did the new note already receive a MIDI note-off request? */ if (flags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF) { #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetVoice: stolen note note-off request deferred\n"); */ } #endif pVoice->voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF; pNextSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING; } return EAS_TRUE; } /*---------------------------------------------------------------------------- * VMCheckKeyGroup() *---------------------------------------------------------------------------- * If the note that we've been asked to start is in the same key group as * any currently playing notes, then we must shut down the currently playing * note in the same key group *---------------------------------------------------------------------------- */ void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel) { const S_REGION *pRegion; EAS_INT voiceNum; /* increment frame workload */ pVoiceMgr->workload += WORKLOAD_AMOUNT_KEY_GROUP; /* need to check all voices in case this is a layered sound */ channel = VSynthToChannel(pSynth, channel); for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++) { if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen) { /* voice must be on the same channel */ if (channel == pVoiceMgr->voices[voiceNum].channel) { /* check key group */ pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].regionIndex); if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00)) { #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ } #endif /* if this voice was just started, set it to mute on the next buffer */ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET) pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE; /* mute immediately */ else VMMuteVoice(pVoiceMgr, voiceNum); } } } /* for stolen voice, check new values */ else { /* voice must be on the same channel */ if (channel == pVoiceMgr->voices[voiceNum].nextChannel) { /* check key group */ pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].nextRegionIndex); if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00)) { #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ } #endif /* if this voice was just started, set it to mute on the next buffer */ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET) pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE; /* mute immediately */ else VMMuteVoice(pVoiceMgr, voiceNum); } } } } } /*---------------------------------------------------------------------------- * VMCheckPolyphonyLimiting() *---------------------------------------------------------------------------- * Purpose: * We only play at most 2 of the same note on a MIDI channel. * E.g., if we are asked to start note 36, and there are already two voices * that are playing note 36, then we must steal the voice playing * the oldest note 36 and use that stolen voice to play the new note 36. * * Inputs: * nChannel - synth channel that wants to start a new note * nKeyNumber - new note's midi note number * nNoteVelocity - new note's velocity * psEASData - pointer to overall EAS data structure * * Outputs: * pbVoiceStealingRequired - flag: this routine sets true if we needed to * steal a voice * * * Side Effects: * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned *---------------------------------------------------------------------------- */ EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice) { EAS_INT voiceNum; EAS_INT oldestVoiceNum; EAS_INT numVoicesPlayingNote; EAS_U16 age; EAS_U16 oldestNoteAge; pVoiceMgr->workload += WORKLOAD_AMOUNT_POLY_LIMIT; numVoicesPlayingNote = 0; oldestVoiceNum = MAX_SYNTH_VOICES; oldestNoteAge = 0; channel = VSynthToChannel(pSynth, channel); /* examine each voice on this channel playing this note */ for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++) { /* check stolen notes separately */ if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen) { /* same channel and note ? */ if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note)) { numVoicesPlayingNote++; age = pVoiceMgr->age - pVoiceMgr->voices[voiceNum].age; /* is this the oldest voice for this note? */ if (age >= oldestNoteAge) { oldestNoteAge = age; oldestVoiceNum = voiceNum; } } } /* handle stolen voices */ else { /* same channel and note ? */ if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote)) { numVoicesPlayingNote++; } } } /* check to see if we exceeded poly limit */ if (numVoicesPlayingNote < DEFAULT_CHANNEL_POLYPHONY_LIMIT) return EAS_FALSE; /* make sure we have a voice to steal */ if (oldestVoiceNum != MAX_SYNTH_VOICES) { #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckPolyphonyLimiting: voice %d has the oldest note\n", oldestVoiceNum); */ } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMCheckPolyphonyLimiting: polyphony limiting requires shutting down note %d \n", pVoiceMgr->voices[oldestVoiceNum].note); */ } #endif VMStolenVoice(pVoiceMgr, pSynth, oldestVoiceNum, channel, note, velocity, regionIndex); return EAS_TRUE; } #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMCheckPolyphonyLimiting: No oldest voice to steal\n"); */ } #endif return EAS_FALSE; } /*---------------------------------------------------------------------------- * VMStartVoice() *---------------------------------------------------------------------------- * Starts a voice given a region index *---------------------------------------------------------------------------- */ void VMStartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex) { const S_REGION *pRegion; S_SYNTH_CHANNEL *pChannel; EAS_INT voiceNum; EAS_INT maxSynthPoly; EAS_I32 lowVoice, highVoice; EAS_U16 keyGroup; pChannel = &pSynth->channels[channel]; pRegion = GetRegionPtr(pSynth, regionIndex); /* select correct synth */ #if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH) { #ifdef EAS_SPLIT_WT_SYNTH if ((pRegion->keyGroupAndFlags & REGION_FLAG_OFF_CHIP) == 0) #else if ((regionIndex & FLAG_RGN_IDX_FM_SYNTH) == 0) #endif { lowVoice = 0; highVoice = NUM_PRIMARY_VOICES - 1; } else { lowVoice = NUM_PRIMARY_VOICES; highVoice = MAX_SYNTH_VOICES - 1; } } #else lowVoice = 0; highVoice = MAX_SYNTH_VOICES - 1; #endif /* keep track of the note-start related workload */ pVoiceMgr->workload+= WORKLOAD_AMOUNT_START_NOTE; /* other voices in pool, check for key group and poly limiting */ if (pSynth->poolCount[pChannel->pool] != 0) { /* check for key group exclusivity */ keyGroup = pRegion->keyGroupAndFlags & 0x0f00; if (keyGroup!= 0) VMCheckKeyGroup(pVoiceMgr, pSynth, keyGroup, channel); /* check polyphony limit and steal a voice if necessary */ if ((pRegion->keyGroupAndFlags & REGION_FLAG_NON_SELF_EXCLUSIVE) == 0) { if (VMCheckPolyphonyLimiting(pVoiceMgr, pSynth, channel, note, velocity, regionIndex, lowVoice, highVoice) == EAS_TRUE) return; } } /* check max poly allocation */ if ((pSynth->maxPolyphony == 0) || (pVoiceMgr->maxPolyphony < pSynth->maxPolyphony)) maxSynthPoly = pVoiceMgr->maxPolyphony; else maxSynthPoly = pSynth->maxPolyphony; /* any free voices? */ if ((pVoiceMgr->activeVoices < pVoiceMgr->maxPolyphony) && (pSynth->numActiveVoices < maxSynthPoly) && (EAS_SUCCESS == VMFindAvailableVoice(pVoiceMgr, &voiceNum, lowVoice, highVoice))) { S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum]; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMStartVoice: Synth=%d\n", pSynth->vSynthNum); */ } #endif /* bump voice counts */ pVoiceMgr->activeVoices++; pSynth->numActiveVoices++; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: voice %d assigned to channel %d note %d velocity %d\n", voiceNum, channel, note, velocity); */ } #endif /* save parameters */ pVoiceMgr->voices[voiceNum].channel = VSynthToChannel(pSynth, channel); pVoiceMgr->voices[voiceNum].note = note; pVoiceMgr->voices[voiceNum].velocity = velocity; /* establish note age for voice stealing */ pVoiceMgr->voices[voiceNum].age = pVoiceMgr->age++; /* setup the synthesis parameters */ pVoiceMgr->voices[voiceNum].voiceState = eVoiceStateStart; /* increment voice pool count */ IncVoicePoolCount(pVoiceMgr, pVoice); /* start voice on correct synth */ /*lint -e{522} return not used at this time */ GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), regionIndex); return; } /* no free voices, we have to steal one using appropriate algorithm */ if (VMStealVoice(pVoiceMgr, pSynth, &voiceNum, channel, note, lowVoice, highVoice) == EAS_SUCCESS) VMStolenVoice(pVoiceMgr, pSynth, voiceNum, channel, note, velocity, regionIndex); #ifdef _DEBUG_VM else { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: Could not steal a voice for channel %d note %d velocity %d\n", channel, note, velocity); */ } } #endif return; } /*---------------------------------------------------------------------------- * VMStartNote() *---------------------------------------------------------------------------- * Purpose: * Update the synth's state to play the requested note on the requested * channel if possible. * * Inputs: * nChannel - the channel to start a note on * nKeyNumber - the key number to start a note for * nNoteVelocity - the key velocity from this note * psEASData - pointer to overall EAS data structure * * Outputs: * Side Effects: * psSynthObject->m_nNumActiveVoices may be incremented * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned *---------------------------------------------------------------------------- */ void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity) { S_SYNTH_CHANNEL *pChannel; EAS_U16 regionIndex; EAS_I16 adjustedNote; /* bump note count */ pSynth->totalNoteCount++; pChannel = &pSynth->channels[channel]; /* check channel mute */ if (pChannel->channelFlags & CHANNEL_FLAG_MUTE) return; #ifdef EXTERNAL_AUDIO /* pass event to external audio when requested */ if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL)) { S_EXT_AUDIO_EVENT event; event.channel = channel; event.note = note; event.velocity = velocity; event.noteOn = EAS_TRUE; if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event)) return; } #endif /* start search at first region */ regionIndex = pChannel->regionIndex; /* handle transposition */ adjustedNote = note; if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL) adjustedNote += pChannel->coarsePitch; else adjustedNote += pChannel->coarsePitch + pSynth->globalTranspose; /* limit adjusted key number so it does not wraparound, over/underflow */ if (adjustedNote < 0) { adjustedNote = 0; } else if (adjustedNote > 127) { adjustedNote = 127; } #if defined(DLS_SYNTHESIZER) if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH) { /* DLS voice */ for (;;) { /*lint -e{740,826} cast OK, we know this is actually a DLS region */ const S_DLS_REGION *pDLSRegion = (S_DLS_REGION*) GetRegionPtr(pSynth, regionIndex); /* check key against this region's key and velocity range */ if (((adjustedNote >= pDLSRegion->wtRegion.region.rangeLow) && (adjustedNote <= pDLSRegion->wtRegion.region.rangeHigh)) && ((velocity >= pDLSRegion->velLow) && (velocity <= pDLSRegion->velHigh))) { VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex); } /* last region in program? */ if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_LAST_REGION) break; /* advance to next region */ regionIndex++; } } else #endif /* braces here for #if clause */ { /* EAS voice */ for (;;) { const S_REGION *pRegion = GetRegionPtr(pSynth, regionIndex); /* check key against this region's keyrange */ if ((adjustedNote >= pRegion->rangeLow) && (adjustedNote <= pRegion->rangeHigh)) { VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex); break; } /* last region in program? */ if (pRegion->keyGroupAndFlags & REGION_FLAG_LAST_REGION) break; /* advance to next region */ regionIndex++; } } } /*---------------------------------------------------------------------------- * VMStopNote() *---------------------------------------------------------------------------- * Purpose: * Update the synth's state to end the requested note on the requested * channel. * * Inputs: * nChannel - the channel to stop a note on * nKeyNumber - the key number for this note off * nNoteVelocity - the note-off velocity * psEASData - pointer to overall EAS data structure * * Outputs: * Side Effects: * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned *---------------------------------------------------------------------------- */ /*lint -esym(715, velocity) reserved for future use */ void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity) { S_SYNTH_CHANNEL *pChannel; EAS_INT voiceNum; pChannel = &(pSynth->channels[channel]); #ifdef EXTERNAL_AUDIO if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL)) { S_EXT_AUDIO_EVENT event; event.channel = channel; event.note = note; event.velocity = velocity; event.noteOn = EAS_FALSE; if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event)) return; } #endif /* keep track of the note-start workload */ pVoiceMgr->workload += WORKLOAD_AMOUNT_STOP_NOTE; channel = VSynthToChannel(pSynth, channel); for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++) { /* stolen notes are handled separately */ if (eVoiceStateStolen != pVoiceMgr->voices[voiceNum].voiceState) { /* channel and key number must match */ if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note)) { #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n", voiceNum, channel, note); */ } #endif /* if sustain pedal is down, set deferred note-off flag */ if (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL) { pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF; continue; } /* if this note just started, wait before we stop it */ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET) { #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tDeferred: Not started yet\n"); */ } #endif pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF; pSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING; } /* release voice */ else VMReleaseVoice(pVoiceMgr, pSynth, voiceNum); } } /* process stolen notes, new channel and key number must match */ else if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote)) { #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n\tDeferred: Stolen voice\n", voiceNum, channel, note); */ } #endif pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF; } } } /*---------------------------------------------------------------------------- * VMFindAvailableVoice() *---------------------------------------------------------------------------- * Purpose: * Find an available voice and return the voice number if available. * * Inputs: * pnVoiceNumber - really an output, returns the voice number found * psEASData - pointer to overall EAS data structure * * Outputs: * success - if there is an available voice * failure - otherwise *---------------------------------------------------------------------------- */ EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice) { EAS_INT voiceNum; /* Check each voice to see if it has been assigned to a synth channel */ for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++) { /* check if this voice has been assigned to a synth channel */ if ( pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateFree) { *pVoiceNumber = voiceNum; /* this voice is available */ return EAS_SUCCESS; } } /* if we reach here, we have not found a free voice */ *pVoiceNumber = UNASSIGNED_SYNTH_VOICE; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFindAvailableVoice: error, could not find an available voice\n"); */ } #endif return EAS_FAILURE; } /*---------------------------------------------------------------------------- * VMStealVoice() *---------------------------------------------------------------------------- * Purpose: * Steal a voice and return the voice number * * Stealing algorithm: steal the best choice with minimal work, taking into * account SP-Midi channel priorities and polyphony allocation. * * In one pass through all the voices, figure out which voice to steal * taking into account a number of different factors: * Priority of the voice's MIDI channel * Number of voices over the polyphony allocation for voice's MIDI channel * Amplitude of the voice * Note age * Key velocity (for voices that haven't been started yet) * If any matching notes are found * * Inputs: * pnVoiceNumber - really an output, see below * nChannel - the channel that this voice wants to be started on * nKeyNumber - the key number for this new voice * psEASData - pointer to overall EAS data structure * * Outputs: * pnVoiceNumber - voice number of the voice that was stolen * EAS_RESULT EAS_SUCCESS - always successful *---------------------------------------------------------------------------- */ EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice) { S_SYNTH_VOICE *pCurrVoice; S_SYNTH *pCurrSynth; EAS_INT voiceNum; EAS_INT bestCandidate; EAS_U8 currChannel; EAS_U8 currNote; EAS_I32 bestPriority; EAS_I32 currentPriority; /* determine which voice to steal */ bestPriority = 0; bestCandidate = MAX_SYNTH_VOICES; for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++) { pCurrVoice = &pVoiceMgr->voices[voiceNum]; /* ignore free voices */ if (pCurrVoice->voiceState == eVoiceStateFree) continue; /* for stolen voices, use the new parameters, not the old */ if (pCurrVoice->voiceState == eVoiceStateStolen) { pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->nextChannel)]; currChannel = pCurrVoice->nextChannel; currNote = pCurrVoice->nextNote; } else { pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->channel)]; currChannel = pCurrVoice->channel; currNote = pCurrVoice->note; } /* ignore voices that are higher priority */ if (pSynth->priority > pCurrSynth->priority) continue; #ifdef _DEBUG_VM // { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: New priority = %d exceeds old priority = %d\n", pSynth->priority, pCurrSynth->priority); */ } #endif /* if voice is stolen or just started, reduce the likelihood it will be stolen */ if (( pCurrVoice->voiceState == eVoiceStateStolen) || (pCurrVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)) { currentPriority = 128 - pCurrVoice->nextVelocity; } else { /* compute the priority of this voice, higher means better for stealing */ /* use not age */ currentPriority = (EAS_I32) pCurrVoice->age << NOTE_AGE_STEAL_WEIGHT; /* include note gain -higher gain is lower steal value */ /*lint -e{704} use shift for performance */ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) - ((EAS_I32) pCurrVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT)); } /* in SP-MIDI mode, include over poly allocation and channel priority */ if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON) { S_SYNTH_CHANNEL *pChannel = &pCurrSynth->channels[GET_CHANNEL(currChannel)]; /*lint -e{701} use shift for performance */ if (pSynth->poolCount[pChannel->pool] >= pSynth->poolAlloc[pChannel->pool]) currentPriority += (pSynth->poolCount[pChannel->pool] -pSynth->poolAlloc[pChannel->pool] + 1) << CHANNEL_POLY_STEAL_WEIGHT; /* include channel priority */ currentPriority += (EAS_I32)(pChannel->pool << CHANNEL_PRIORITY_STEAL_WEIGHT); } /* if a note is already playing that matches this note, consider stealing it more readily */ if ((note == currNote) && (channel == currChannel)) currentPriority += NOTE_MATCH_PENALTY; /* is this the best choice so far? */ if (currentPriority >= bestPriority) { bestPriority = currentPriority; bestCandidate = voiceNum; } } /* may happen if all voices are allocated to a higher priority virtual synth */ if (bestCandidate == MAX_SYNTH_VOICES) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Unable to allocate a voice\n"); */ } return EAS_ERROR_NO_VOICE_ALLOCATED; } #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Voice %d stolen\n", bestCandidate); */ } /* are we stealing a stolen voice? */ if (pVoiceMgr->voices[bestCandidate].voiceState == eVoiceStateStolen) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMStealVoice: Voice %d is already marked as stolen and was scheduled to play ch: %d note: %d vel: %d\n", bestCandidate, pVoiceMgr->voices[bestCandidate].nextChannel, pVoiceMgr->voices[bestCandidate].nextNote, pVoiceMgr->voices[bestCandidate].nextVelocity); */ } } #endif *pVoiceNumber = (EAS_U16) bestCandidate; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMChannelPressure() *---------------------------------------------------------------------------- * Purpose: * Change the channel pressure for the given channel * * Inputs: * nChannel - the MIDI channel * nVelocity - the channel pressure value * psEASData - pointer to overall EAS data structure * * Outputs: * Side Effects: * psSynthObject->m_sChannel[nChannel].m_nChannelPressure is updated *---------------------------------------------------------------------------- */ void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value) { S_SYNTH_CHANNEL *pChannel; pChannel = &(pSynth->channels[channel]); pChannel->channelPressure = value; /* set a channel flag to request parameter updates for all the voices associated with this channel */ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS; } /*---------------------------------------------------------------------------- * VMPitchBend() *---------------------------------------------------------------------------- * Purpose: * Change the pitch wheel value for the given channel. * This routine constructs the proper 14-bit argument when the calling routine * passes the pitch LSB and MSB. * * Note: some midi disassemblers display a bipolar pitch bend value. * We can display the bipolar value using * if m_nPitchBend >= 0x2000 * bipolar pitch bend = postive (m_nPitchBend - 0x2000) * else * bipolar pitch bend = negative (0x2000 - m_nPitchBend) * * Inputs: * nChannel - the MIDI channel * nPitchLSB - the LSB byte of the pitch bend message * nPitchMSB - the MSB byte of the pitch bend message * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * psSynthObject->m_sChannel[nChannel].m_nPitchBend is changed * *---------------------------------------------------------------------------- */ void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 nPitchLSB, EAS_U8 nPitchMSB) { S_SYNTH_CHANNEL *pChannel; pChannel = &(pSynth->channels[channel]); pChannel->pitchBend = (EAS_I16) ((nPitchMSB << 7) | nPitchLSB); /* set a channel flag to request parameter updates for all the voices associated with this channel */ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS; } /*---------------------------------------------------------------------------- * VMControlChange() *---------------------------------------------------------------------------- * Purpose: * Change the controller (or mode) for the given channel. * * Inputs: * nChannel - the MIDI channel * nControllerNumber - the MIDI controller number * nControlValue - the value for this controller message * psEASData - pointer to overall EAS data structure * * Outputs: * Side Effects: * psSynthObject->m_sChannel[nChannel] controller is changed * *---------------------------------------------------------------------------- */ void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value) { S_SYNTH_CHANNEL *pChannel; pChannel = &(pSynth->channels[channel]); /* set a channel flag to request parameter updates for all the voices associated with this channel */ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS; switch ( controller ) { case MIDI_CONTROLLER_BANK_SELECT_MSB: #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select MSB: msb 0x%X\n", value); */ } #endif /* use this MSB with a zero LSB, until we get an LSB message */ pChannel->bankNum = value << 8; break; case MIDI_CONTROLLER_MOD_WHEEL: /* we treat mod wheel as a 7-bit controller and only use the MSB */ pChannel->modWheel = value; break; case MIDI_CONTROLLER_VOLUME: /* we treat volume as a 7-bit controller and only use the MSB */ pChannel->volume = value; break; case MIDI_CONTROLLER_PAN: /* we treat pan as a 7-bit controller and only use the MSB */ pChannel->pan = value; break; case MIDI_CONTROLLER_EXPRESSION: /* we treat expression as a 7-bit controller and only use the MSB */ pChannel->expression = value; break; case MIDI_CONTROLLER_BANK_SELECT_LSB: #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select LSB: lsb 0x%X\n", value); */ } #endif /* construct bank number as 7-bits (stored as 8) of existing MSB and 7-bits of new LSB (also stored as 8( */ pChannel->bankNum = (pChannel->bankNum & 0xFF00) | value; break; case MIDI_CONTROLLER_SUSTAIN_PEDAL: /* we treat sustain pedal as a boolean on/off bit flag */ if (value < 64) { /* we are requested to turn the pedal off, but first check if the pedal is already on */ if (0 != (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL) ) { /* The sustain flag is presently set and the damper pedal is on. We are therefore transitioning from damper pedal ON to damper pedal OFF. This means all notes in this channel that received a note off while the damper pedal was on, and had their note-off requests deferred, should now proceed to the release state. */ VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, channel); } /* end if sustain pedal is already on */ /* turn the sustain pedal off */ pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL; } else { /* we are requested to turn the pedal on, but first check if the pedal is already off */ if (0 == (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL) ) { /* The sustain flag is presently clear and the damper pedal is off. We are therefore transitioning from damper pedal OFF to damper pedal ON. Currently sounding notes should be left unchanged. However, we should try to "catch" notes if possible. If any notes have levels >= sustain level, catch them, otherwise, let them continue to release. */ VMCatchNotesForSustainPedal(pVoiceMgr, pSynth, channel); } /* turn the sustain pedal on */ pChannel->channelFlags |= CHANNEL_FLAG_SUSTAIN_PEDAL; } break; #ifdef _REVERB case MIDI_CONTROLLER_REVERB_SEND: /* we treat send as a 7-bit controller and only use the MSB */ pSynth->channels[channel].reverbSend = value; break; #endif #ifdef _CHORUS case MIDI_CONTROLLER_CHORUS_SEND: /* we treat send as a 7-bit controller and only use the MSB */ pSynth->channels[channel].chorusSend = value; break; #endif case MIDI_CONTROLLER_RESET_CONTROLLERS: /* despite the Midi message name, not ALL controllers are reset */ pChannel->modWheel = DEFAULT_MOD_WHEEL; pChannel->expression = DEFAULT_EXPRESSION; /* turn the sustain pedal off as default/reset */ pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL; pChannel->pitchBend = DEFAULT_PITCH_BEND; /* reset channel pressure */ pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE; /* reset RPN values */ pChannel->registeredParam = DEFAULT_REGISTERED_PARAM; pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY; pChannel->finePitch = DEFAULT_FINE_PITCH; pChannel->coarsePitch = DEFAULT_COARSE_PITCH; /* program change, bank select, channel volume CC7, pan CC10 are NOT reset */ break; /* For logical reasons, the RPN data entry are grouped together. However, keep in mind that these cases are not necessarily in ascending order. e.g., MIDI_CONTROLLER_DATA_ENTRY_MSB == 6, whereas MIDI_CONTROLLER_SUSTAIN_PEDAL == 64. So arrange these case statements in whatever manner is more efficient for the processor / compiler. */ case MIDI_CONTROLLER_ENTER_DATA_MSB: case MIDI_CONTROLLER_ENTER_DATA_LSB: case MIDI_CONTROLLER_SELECT_RPN_LSB: case MIDI_CONTROLLER_SELECT_RPN_MSB: case MIDI_CONTROLLER_SELECT_NRPN_MSB: case MIDI_CONTROLLER_SELECT_NRPN_LSB: VMUpdateRPNStateMachine(pSynth, channel, controller, value); break; case MIDI_CONTROLLER_ALL_SOUND_OFF: case MIDI_CONTROLLER_ALL_NOTES_OFF: case MIDI_CONTROLLER_OMNI_OFF: case MIDI_CONTROLLER_OMNI_ON: case MIDI_CONTROLLER_MONO_ON_POLY_OFF: case MIDI_CONTROLLER_POLY_ON_MONO_OFF: /* NOTE: we treat all sounds off the same as all notes off */ VMAllNotesOff(pVoiceMgr, pSynth, channel); break; default: #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: controller %d not yet implemented\n", controller); */ } #endif break; } return; } /*---------------------------------------------------------------------------- * VMUpdateRPNStateMachine() *---------------------------------------------------------------------------- * Purpose: * Call this function when we want to parse RPN related controller messages. * We only support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and * RPN2 (coarse tuning). Any other RPNs or NRPNs are ignored for now. *. * Supports any order, so not a state machine anymore. This function was * rewritten to work correctly regardless of order. * * Inputs: * nChannel - the channel this controller message is coming from * nControllerNumber - which RPN related controller * nControlValue - the value of the RPN related controller * psEASData - pointer to overall EAS data structure * * Outputs: * returns EAS_RESULT, which is typically EAS_SUCCESS, since there are * few possible errors * * Side Effects: * gsSynthObject.m_sChannel[nChannel].m_nPitchBendSensitivity * (or m_nFinePitch or m_nCoarsePitch) * will be updated if the proper RPN message is received. *---------------------------------------------------------------------------- */ EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value) { S_SYNTH_CHANNEL *pChannel; #ifdef _DEBUG_VM if (channel >= NUM_SYNTH_CHANNELS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateRPNStateMachines: error, %d invalid channel number\n", channel); */ } return EAS_FAILURE; } #endif pChannel = &(pSynth->channels[channel]); switch (controller) { case MIDI_CONTROLLER_SELECT_NRPN_MSB: case MIDI_CONTROLLER_SELECT_NRPN_LSB: pChannel->registeredParam = DEFAULT_REGISTERED_PARAM; break; case MIDI_CONTROLLER_SELECT_RPN_MSB: pChannel->registeredParam = (pChannel->registeredParam & 0x7F) | (value<<7); break; case MIDI_CONTROLLER_SELECT_RPN_LSB: pChannel->registeredParam = (pChannel->registeredParam & 0x7F00) | value; break; case MIDI_CONTROLLER_ENTER_DATA_MSB: switch (pChannel->registeredParam) { case 0: pChannel->pitchBendSensitivity = value * 100; break; case 1: /*lint -e{702} */ pChannel->finePitch = (EAS_I8)((((value << 7) - 8192) * 100) >> 13); break; case 2: pChannel->coarsePitch = (EAS_I8)(value - 64); break; default: break; } break; case MIDI_CONTROLLER_ENTER_DATA_LSB: switch (pChannel->registeredParam) { case 0: //ignore lsb break; case 1: //ignore lsb break; case 2: //ignore lsb break; default: break; } break; default: return EAS_FAILURE; //not a RPN related controller } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMUpdateStaticChannelParameters() *---------------------------------------------------------------------------- * Purpose: * Update all of the static channel parameters for channels that have had * a controller change values * Or if the synth has signalled that all channels must forcibly * be updated * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * none * * Side Effects: * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch * are updated for channels whose controller values have changed * or if the synth has signalled that all channels must forcibly * be updated *---------------------------------------------------------------------------- */ void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth) { EAS_INT channel; if (pSynth->synthFlags & SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS) { /* the synth wants us to forcibly update all channel parameters. This event occurs when we are about to finish resetting the synth */ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++) { #ifdef _HYBRID_SYNTH if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH) pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel); else pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel); #else pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel); #endif } /* clear the flag to indicates we have now forcibly updated all channel parameters */ pSynth->synthFlags &= ~SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS; } else { /* only update channel params if signalled by a channel flag */ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++) { if ( 0 != (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS)) { #ifdef _HYBRID_SYNTH if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH) pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel); else pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel); #else pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel); #endif } } } return; } /*---------------------------------------------------------------------------- * VMFindProgram() *---------------------------------------------------------------------------- * Purpose: * Look up an individual program in sound library. This function * searches the bank list for a program, then the individual program * list. * * Inputs: * * Outputs: *---------------------------------------------------------------------------- */ static EAS_RESULT VMFindProgram (const S_EAS *pEAS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex) { EAS_U32 locale; const S_PROGRAM *p; EAS_U16 i; EAS_U16 regionIndex; /* make sure we have a valid sound library */ if (pEAS == NULL) return EAS_FAILURE; /* search the banks */ for (i = 0; i < pEAS->numBanks; i++) { if (bank == (EAS_U32) pEAS->pBanks[i].locale) { regionIndex = pEAS->pBanks[i].regionIndex[programNum]; if (regionIndex != INVALID_REGION_INDEX) { *pRegionIndex = regionIndex; return EAS_SUCCESS; } break; } } /* establish locale */ locale = ( bank << 8) | programNum; /* search for program */ for (i = 0, p = pEAS->pPrograms; i < pEAS->numPrograms; i++, p++) { if (p->locale == locale) { *pRegionIndex = p->regionIndex; return EAS_SUCCESS; } } return EAS_FAILURE; } #ifdef DLS_SYNTHESIZER /*---------------------------------------------------------------------------- * VMFindDLSProgram() *---------------------------------------------------------------------------- * Purpose: * Look up an individual program in sound library. This function * searches the bank list for a program, then the individual program * list. * * Inputs: * * Outputs: *---------------------------------------------------------------------------- */ static EAS_RESULT VMFindDLSProgram (const S_DLS *pDLS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex) { EAS_U32 locale; const S_PROGRAM *p; EAS_U16 i; /* make sure we have a valid sound library */ if (pDLS == NULL) return EAS_FAILURE; /* establish locale */ locale = (bank << 8) | programNum; /* search for program */ for (i = 0, p = pDLS->pDLSPrograms; i < pDLS->numDLSPrograms; i++, p++) { if (p->locale == locale) { *pRegionIndex = p->regionIndex; return EAS_SUCCESS; } } return EAS_FAILURE; } #endif /*---------------------------------------------------------------------------- * VMProgramChange() *---------------------------------------------------------------------------- * Purpose: * Change the instrument (program) for the given channel. * * Depending on the program number, and the bank selected for this channel, the * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or * Alternate wavetable (from mobile DLS or other DLS file) * * This function figures out what wavetable should be used, and sets it up as the * wavetable to use for this channel. Also the channel may switch from a melodic * channel to a rhythm channel, or vice versa. * * Inputs: * * Outputs: * Side Effects: * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed * *---------------------------------------------------------------------------- */ /*lint -esym(715, pVoiceMgr) reserved for future use */ void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program) { S_SYNTH_CHANNEL *pChannel; EAS_U32 bank; EAS_U16 regionIndex; #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMProgramChange: vSynthNum=%d, channel=%d, program=%d\n", pSynth->vSynthNum, channel, program); */ } #endif /* setup pointer to MIDI channel data */ pChannel = &pSynth->channels[channel]; bank = pChannel->bankNum; /* allow channels to switch between being melodic or rhythm channels, using GM2 CC values */ if ((bank & 0xFF00) == DEFAULT_RHYTHM_BANK_NUMBER) { /* make it a rhythm channel */ pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL; } else if ((bank & 0xFF00) == DEFAULT_MELODY_BANK_NUMBER) { /* make it a melody channel */ pChannel->channelFlags &= ~CHANNEL_FLAG_RHYTHM_CHANNEL; } regionIndex = DEFAULT_REGION_INDEX; #ifdef EXTERNAL_AUDIO /* give the external audio interface a chance to handle it */ if (pSynth->cbProgChgFunc != NULL) { S_EXT_AUDIO_PRG_CHG prgChg; prgChg.channel = channel; prgChg.bank = (EAS_U16) bank; prgChg.program = program; if (pSynth->cbProgChgFunc(pSynth->pExtAudioInstData, &prgChg)) pChannel->channelFlags |= CHANNEL_FLAG_EXTERNAL_AUDIO; } #endif #ifdef DLS_SYNTHESIZER /* first check for DLS program that may overlay the internal instrument */ if (VMFindDLSProgram(pSynth->pDLS, bank, program, ®ionIndex) != EAS_SUCCESS) #endif /* braces to support 'if' clause above */ { /* look in the internal banks */ if (VMFindProgram(pSynth->pEAS, bank, program, ®ionIndex) != EAS_SUCCESS) /* fall back to default bank */ { if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL) bank = DEFAULT_RHYTHM_BANK_NUMBER; else bank = DEFAULT_MELODY_BANK_NUMBER; if (VMFindProgram(pSynth->pEAS, bank, program, ®ionIndex) != EAS_SUCCESS) /* switch to program 0 in the default bank */ { if (VMFindProgram(pSynth->pEAS, bank, 0, ®ionIndex) != EAS_SUCCESS) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMProgramChange: No program @ %03d:%03d:%03d\n", (bank >> 8) & 0x7f, bank & 0x7f, program); */ } } } } /* we have our new program change for this channel */ pChannel->programNum = program; pChannel->regionIndex = regionIndex; /* set a channel flag to request parameter updates for all the voices associated with this channel */ pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS; return; } /*---------------------------------------------------------------------------- * VMAddSamples() *---------------------------------------------------------------------------- * Purpose: * Synthesize the requested number of samples (block based processing) * * Inputs: * nNumSamplesToAdd - number of samples to write to buffer * psEASData - pointer to overall EAS data structure * * Outputs: * number of voices rendered * * Side Effects: * - samples are added to the presently free buffer * *---------------------------------------------------------------------------- */ EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamples) { S_SYNTH *pSynth; EAS_INT voicesRendered; EAS_INT voiceNum; EAS_BOOL done; #ifdef _REVERB EAS_PCM *pReverbSendBuffer; #endif // ifdef _REVERB #ifdef _CHORUS EAS_PCM *pChorusSendBuffer; #endif // ifdef _CHORUS voicesRendered = 0; for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++) { /* retarget stolen voices */ if ((pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen) && (pVoiceMgr->voices[voiceNum].gain <= 0)) VMRetargetStolenVoice(pVoiceMgr, voiceNum); /* get pointer to virtual synth */ pSynth = pVoiceMgr->pSynth[pVoiceMgr->voices[voiceNum].channel >> 4]; /* synthesize active voices */ if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateFree) { done = GetSynthPtr(voiceNum)->pfUpdateVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pMixBuffer, numSamples); voicesRendered++; /* voice is finished */ if (done == EAS_TRUE) { /* set gain of stolen voice to zero so it will be restarted */ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen) pVoiceMgr->voices[voiceNum].gain = 0; /* or return it to the free voice pool */ else VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]); } /* if this voice is scheduled to be muted, set the mute flag */ if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MUTE) { pVoiceMgr->voices[voiceNum].voiceFlags &= ~(VOICE_FLAG_DEFER_MUTE | VOICE_FLAG_DEFER_MIDI_NOTE_OFF); VMMuteVoice(pVoiceMgr, voiceNum); } /* if voice just started, advance state to play */ if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStart) pVoiceMgr->voices[voiceNum].voiceState = eVoiceStatePlay; } } return voicesRendered; } /*---------------------------------------------------------------------------- * VMRender() *---------------------------------------------------------------------------- * Purpose: * This routine renders a frame of audio * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * pVoicesRendered - number of voices rendered this frame * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered) { S_SYNTH *pSynth; EAS_INT i; EAS_INT channel; #ifdef _CHECKED_BUILD SanityCheck(pVoiceMgr); #endif /* update MIDI channel parameters */ *pVoicesRendered = 0; for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++) { if (pVoiceMgr->pSynth[i] != NULL) VMUpdateStaticChannelParameters(pVoiceMgr, pVoiceMgr->pSynth[i]); } /* synthesize a buffer of audio */ *pVoicesRendered = VMAddSamples(pVoiceMgr, pMixBuffer, numSamples); /* * check for deferred note-off messages * If flag is set, that means one or more voices are expecting deferred * midi note-off messages because the midi note-on and corresponding midi * note-off requests occurred during the same update interval. The goal * is the defer the note-off request so that the note can at least start. */ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++) { pSynth = pVoiceMgr->pSynth[i]; if (pSynth== NULL) continue; if (pSynth->synthFlags & SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING) VMDeferredStopNote(pVoiceMgr, pSynth); /* check if we need to reset the synth */ if ((pSynth->synthFlags & SYNTH_FLAG_RESET_IS_REQUESTED) && (pSynth->numActiveVoices == 0)) { /* complete the process of resetting the synth now that all voices have muted */ #ifdef _DEBUG_VM { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAddSamples: complete the reset process\n"); */ } #endif VMInitializeAllChannels(pVoiceMgr, pSynth); VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum); /* clear the reset flag */ pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED; } /* clear channel update flags */ for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++) pSynth->channels[channel].channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS; } #ifdef _CHECKED_BUILD SanityCheck(pVoiceMgr); #endif return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMInitWorkload() *---------------------------------------------------------------------------- * Purpose: * Clears the workload counter * * Inputs: * pVoiceMgr - pointer to instance data * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ void VMInitWorkload (S_VOICE_MGR *pVoiceMgr) { pVoiceMgr->workload = 0; } /*---------------------------------------------------------------------------- * VMSetWorkload() *---------------------------------------------------------------------------- * Purpose: * Sets the max workload for a single frame. * * Inputs: * pVoiceMgr - pointer to instance data * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad) { pVoiceMgr->maxWorkLoad = maxWorkLoad; } /*---------------------------------------------------------------------------- * VMCheckWorkload() *---------------------------------------------------------------------------- * Purpose: * Checks to see if work load has been exceeded on this frame. * * Inputs: * pVoiceMgr - pointer to instance data * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr) { if (pVoiceMgr->maxWorkLoad > 0) return (EAS_BOOL) (pVoiceMgr->workload >= pVoiceMgr->maxWorkLoad); return EAS_FALSE; } /*---------------------------------------------------------------------------- * VMActiveVoices() *---------------------------------------------------------------------------- * Purpose: * Returns the number of active voices in the synthesizer. * * Inputs: * pEASData - pointer to instance data * * Outputs: * Returns the number of active voices * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_I32 VMActiveVoices (S_SYNTH *pSynth) { return pSynth->numActiveVoices; } /*---------------------------------------------------------------------------- * VMSetSynthPolyphony() *---------------------------------------------------------------------------- * Purpose: * Set the synth to a new polyphony value. Value must be >= 1 and * <= MAX_SYNTH_VOICES. This function will pin the polyphony at those limits * * Inputs: * pVoiceMgr pointer to synthesizer data * polyphonyCount desired polyphony count * synth synthesizer number (0 = onboard, 1 = DSP) * * Outputs: * Returns error code * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMSetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 polyphonyCount) { EAS_INT i; EAS_INT activeVoices; /* lower limit */ if (polyphonyCount < 1) polyphonyCount = 1; /* split architecture */ #if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH) if (synth == EAS_MCU_SYNTH) { if (polyphonyCount > NUM_PRIMARY_VOICES) polyphonyCount = NUM_PRIMARY_VOICES; if (pVoiceMgr->maxPolyphonyPrimary == polyphonyCount) return EAS_SUCCESS; pVoiceMgr->maxPolyphonyPrimary = (EAS_U16) polyphonyCount; } else if (synth == EAS_DSP_SYNTH) { if (polyphonyCount > NUM_SECONDARY_VOICES) polyphonyCount = NUM_SECONDARY_VOICES; if (pVoiceMgr->maxPolyphonySecondary == polyphonyCount) return EAS_SUCCESS; pVoiceMgr->maxPolyphonySecondary = (EAS_U16) polyphonyCount; } else return EAS_ERROR_PARAMETER_RANGE; /* setting for SP-MIDI */ pVoiceMgr->maxPolyphony = pVoiceMgr->maxPolyphonyPrimary + pVoiceMgr->maxPolyphonySecondary; /* standard architecture */ #else if (synth != EAS_MCU_SYNTH) return EAS_ERROR_PARAMETER_RANGE; /* pin desired value to possible limits */ if (polyphonyCount > MAX_SYNTH_VOICES) polyphonyCount = MAX_SYNTH_VOICES; /* set polyphony, if value is different than current value */ if (pVoiceMgr->maxPolyphony == polyphonyCount) return EAS_SUCCESS; pVoiceMgr->maxPolyphony = (EAS_U16) polyphonyCount; #endif /* if SPMIDI enabled, update channel masking based on new polyphony */ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++) { if (pVoiceMgr->pSynth[i]) { if (pVoiceMgr->pSynth[i]->synthFlags & SYNTH_FLAG_SP_MIDI_ON) VMMIPUpdateChannelMuting(pVoiceMgr, pVoiceMgr->pSynth[i]); else pVoiceMgr->pSynth[i]->poolAlloc[0] = (EAS_U8) polyphonyCount; } } /* are we under polyphony limit? */ if (pVoiceMgr->activeVoices <= polyphonyCount) return EAS_SUCCESS; /* count the number of active voices */ activeVoices = 0; for (i = 0; i < MAX_SYNTH_VOICES; i++) { /* is voice active? */ if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting)) activeVoices++; } /* we may have to mute voices to reach new target */ while (activeVoices > polyphonyCount) { S_SYNTH *pSynth; S_SYNTH_VOICE *pVoice; EAS_I32 currentPriority, bestPriority; EAS_INT bestCandidate; /* find the lowest priority voice */ bestPriority = bestCandidate = -1; for (i = 0; i < MAX_SYNTH_VOICES; i++) { pVoice = &pVoiceMgr->voices[i]; /* ignore free and muting voices */ if ((pVoice->voiceState == eVoiceStateFree) || (pVoice->voiceState == eVoiceStateMuting)) continue; pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)]; /* if voice is stolen or just started, reduce the likelihood it will be stolen */ if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)) { /* include velocity */ currentPriority = 128 - pVoice->nextVelocity; /* include channel priority */ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT; } else { /* include age */ currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT; /* include note gain -higher gain is lower steal value */ /*lint -e{704} use shift for performance */ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) - ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT)); /* include channel priority */ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->channel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT; } /* include synth priority */ currentPriority += pSynth->priority << SYNTH_PRIORITY_WEIGHT; /* is this the best choice so far? */ if (currentPriority > bestPriority) { bestPriority = currentPriority; bestCandidate = i; } } /* shutdown best candidate */ if (bestCandidate < 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ } break; } /* shut down this voice */ /*lint -e{771} pSynth is initialized if bestCandidate >= 0 */ VMMuteVoice(pVoiceMgr, bestCandidate); activeVoices--; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMGetSynthPolyphony() *---------------------------------------------------------------------------- * Purpose: * Returns the current polyphony setting * * Inputs: * pVoiceMgr pointer to synthesizer data * synth synthesizer number (0 = onboard, 1 = DSP) * * Outputs: * Returns actual polyphony value set, as pinned by limits * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMGetSynthPolyphony (S_VOICE_MGR *pVoiceMgr, EAS_I32 synth, EAS_I32 *pPolyphonyCount) { #if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH) if (synth == EAS_MCU_SYNTH) *pPolyphonyCount = pVoiceMgr->maxPolyphonyPrimary; else if (synth == EAS_DSP_SYNTH) *pPolyphonyCount = pVoiceMgr->maxPolyphonySecondary; else return EAS_ERROR_PARAMETER_RANGE; #else if (synth != EAS_MCU_SYNTH) return EAS_ERROR_PARAMETER_RANGE; *pPolyphonyCount = pVoiceMgr->maxPolyphony; #endif return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMSetPolyphony() *---------------------------------------------------------------------------- * Purpose: * Set the virtual synth polyphony. 0 = no limit (i.e. can use * all available voices). * * Inputs: * pVoiceMgr pointer to synthesizer data * polyphonyCount desired polyphony count * pSynth pointer to virtual synth * * Outputs: * Returns error code * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount) { EAS_INT i; EAS_INT activeVoices; /* check limits */ if (polyphonyCount < 0) return EAS_ERROR_PARAMETER_RANGE; /* zero is max polyphony */ if ((polyphonyCount == 0) || (polyphonyCount > MAX_SYNTH_VOICES)) { pSynth->maxPolyphony = 0; return EAS_SUCCESS; } /* set new polyphony */ pSynth->maxPolyphony = (EAS_U16) polyphonyCount; /* max polyphony is minimum of virtual synth and actual synth */ if (polyphonyCount > pVoiceMgr->maxPolyphony) polyphonyCount = pVoiceMgr->maxPolyphony; /* if SP-MIDI mode, update the channel muting */ if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON) VMMIPUpdateChannelMuting(pVoiceMgr, pSynth); else pSynth->poolAlloc[0] = (EAS_U8) polyphonyCount; /* are we under polyphony limit? */ if (pSynth->numActiveVoices <= polyphonyCount) return EAS_SUCCESS; /* count the number of active voices */ activeVoices = 0; for (i = 0; i < MAX_SYNTH_VOICES; i++) { /* this synth? */ if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) != pSynth->vSynthNum) continue; /* is voice active? */ if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting)) activeVoices++; } /* we may have to mute voices to reach new target */ while (activeVoices > polyphonyCount) { S_SYNTH_VOICE *pVoice; EAS_I32 currentPriority, bestPriority; EAS_INT bestCandidate; /* find the lowest priority voice */ bestPriority = bestCandidate = -1; for (i = 0; i < MAX_SYNTH_VOICES; i++) { pVoice = &pVoiceMgr->voices[i]; /* this synth? */ if (GET_VSYNTH(pVoice->nextChannel) != pSynth->vSynthNum) continue; /* if voice is stolen or just started, reduce the likelihood it will be stolen */ if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)) { /* include velocity */ currentPriority = 128 - pVoice->nextVelocity; /* include channel priority */ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT; } else { /* include age */ currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT; /* include note gain -higher gain is lower steal value */ /*lint -e{704} use shift for performance */ currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) - ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT)); /* include channel priority */ currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT; } /* is this the best choice so far? */ if (currentPriority > bestPriority) { bestPriority = currentPriority; bestCandidate = i; } } /* shutdown best candidate */ if (bestCandidate < 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ } break; } /* shut down this voice */ VMMuteVoice(pVoiceMgr, bestCandidate); activeVoices--; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMGetPolyphony() *---------------------------------------------------------------------------- * Purpose: * Get the virtual synth polyphony * * Inputs: * pVoiceMgr pointer to synthesizer data * pPolyphonyCount pointer to variable to hold polyphony count * pSynth pointer to virtual synth * * Outputs: * Returns error code * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pVoiceMgr) reserved for future use */ EAS_RESULT VMGetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPolyphonyCount) { *pPolyphonyCount = (EAS_U16) pSynth->maxPolyphony; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMSetPriority() *---------------------------------------------------------------------------- * Purpose: * Set the virtual synth priority * * Inputs: * pVoiceMgr pointer to synthesizer data * priority new priority * pSynth pointer to virtual synth * * Outputs: * Returns error code * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pVoiceMgr) reserved for future use */ EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority) { pSynth->priority = (EAS_U8) priority ; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMGetPriority() *---------------------------------------------------------------------------- * Purpose: * Get the virtual synth priority * * Inputs: * pVoiceMgr pointer to synthesizer data * pPriority pointer to variable to hold priority * pSynth pointer to virtual synth * * Outputs: * Returns error code * * Side Effects: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pVoiceMgr) reserved for future use */ EAS_RESULT VMGetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 *pPriority) { *pPriority = pSynth->priority; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMSetVolume() *---------------------------------------------------------------------------- * Purpose: * Set the master volume for this synthesizer for this sequence. * * Inputs: * nSynthVolume - the desired master volume * psEASData - pointer to overall EAS data structure * * Outputs: * * * Side Effects: * overrides any previously set master volume from sysex * *---------------------------------------------------------------------------- */ void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume) { pSynth->masterVolume = masterVolume; pSynth->synthFlags |= SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS; } /*---------------------------------------------------------------------------- * VMSetPitchBendRange() *---------------------------------------------------------------------------- * Set the pitch bend range for the given channel. *---------------------------------------------------------------------------- */ void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange) { pSynth->channels[channel].pitchBendSensitivity = pitchBendRange; } /*---------------------------------------------------------------------------- * VMValidateEASLib() *---------------------------------------------------------------------------- * Validates an EAS library *---------------------------------------------------------------------------- */ EAS_RESULT VMValidateEASLib (EAS_SNDLIB_HANDLE pEAS) { /* validate the sound library */ if (pEAS) { if (pEAS->identifier != _EAS_LIBRARY_VERSION) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sound library mismatch in sound library: Read 0x%08x, expected 0x%08x\n", pEAS->identifier, _EAS_LIBRARY_VERSION); */ } return EAS_ERROR_SOUND_LIBRARY; } /* check sample rate */ if ((pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK) != _OUTPUT_SAMPLE_RATE) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sample rate mismatch in sound library: Read %lu, expected %lu\n", pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ } return EAS_ERROR_SOUND_LIBRARY; } #ifdef _WT_SYNTH /* check sample bit depth */ #ifdef _8_BIT_SAMPLES if (pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 8-bit samples and found 16-bit\n", pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ } return EAS_ERROR_SOUND_LIBRARY; } #endif #ifdef _16_BIT_SAMPLES if ((pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES) == 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 16-bit samples and found 8-bit\n", pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ } return EAS_ERROR_SOUND_LIBRARY; } #endif #endif } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMSetGlobalEASLib() *---------------------------------------------------------------------------- * Purpose: * Sets the EAS library to be used by the synthesizer * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMSetGlobalEASLib (S_VOICE_MGR *pVoiceMgr, EAS_SNDLIB_HANDLE pEAS) { EAS_RESULT result; result = VMValidateEASLib(pEAS); if (result != EAS_SUCCESS) return result; pVoiceMgr->pGlobalEAS = pEAS; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMSetEASLib() *---------------------------------------------------------------------------- * Purpose: * Sets the EAS library to be used by the synthesizer * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS) { EAS_RESULT result; result = VMValidateEASLib(pEAS); if (result != EAS_SUCCESS) return result; pSynth->pEAS = pEAS; return EAS_SUCCESS; } #ifdef DLS_SYNTHESIZER /*---------------------------------------------------------------------------- * VMSetGlobalDLSLib() *---------------------------------------------------------------------------- * Purpose: * Sets the DLS library to be used by the synthesizer * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMSetGlobalDLSLib (EAS_DATA_HANDLE pEASData, EAS_DLSLIB_HANDLE pDLS) { if (pEASData->pVoiceMgr->pGlobalDLS) DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS); pEASData->pVoiceMgr->pGlobalDLS = pDLS; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * VMSetDLSLib() *---------------------------------------------------------------------------- * Purpose: * Sets the DLS library to be used by the synthesizer * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS) { pSynth->pDLS = pDLS; return EAS_SUCCESS; } #endif /*---------------------------------------------------------------------------- * VMSetTranposition() *---------------------------------------------------------------------------- * Purpose: * Sets the global key transposition used by the synthesizer. * Transposes all melodic instruments up or down by the specified * amount. Range is limited to +/-12 semitones. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition) { pSynth->globalTranspose = (EAS_I8) transposition; } /*---------------------------------------------------------------------------- * VMGetTranposition() *---------------------------------------------------------------------------- * Purpose: * Gets the global key transposition used by the synthesizer. * Transposes all melodic instruments up or down by the specified * amount. Range is limited to +/-12 semitones. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ void VMGetTranposition (S_SYNTH *pSynth, EAS_I32 *pTransposition) { *pTransposition = pSynth->globalTranspose; } /*---------------------------------------------------------------------------- * VMGetNoteCount() *---------------------------------------------------------------------------- * Returns the total note count *---------------------------------------------------------------------------- */ EAS_I32 VMGetNoteCount (S_SYNTH *pSynth) { return pSynth->totalNoteCount; } /*---------------------------------------------------------------------------- * VMMIDIShutdown() *---------------------------------------------------------------------------- * Purpose: * Clean up any Synth related system issues. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * None * * Side Effects: * *---------------------------------------------------------------------------- */ void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth) { EAS_INT vSynthNum; /* decrement reference count, free if all references are gone */ if (--pSynth->refCount > 0) return; vSynthNum = pSynth->vSynthNum; /* cleanup DLS load */ #ifdef DLS_SYNTHESIZER /*lint -e{550} result used only in debugging code */ if (pSynth->pDLS != NULL) { EAS_RESULT result; if ((result = DLSCleanup(pEASData->hwInstData, pSynth->pDLS)) != EAS_SUCCESS) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMMIDIShutdown: Error %ld cleaning up DLS collection\n", result); */ } pSynth->pDLS = NULL; } #endif VMReset(pEASData->pVoiceMgr, pSynth, EAS_TRUE); /* check Configuration Module for static memory allocation */ if (!pEASData->staticMemoryModel) EAS_HWFree(pEASData->hwInstData, pSynth); /* clear pointer to MIDI state */ pEASData->pVoiceMgr->pSynth[vSynthNum] = NULL; } /*---------------------------------------------------------------------------- * VMShutdown() *---------------------------------------------------------------------------- * Purpose: * Clean up any Synth related system issues. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * None * * Side Effects: * *---------------------------------------------------------------------------- */ void VMShutdown (S_EAS_DATA *pEASData) { /* don't free a NULL pointer */ if (pEASData->pVoiceMgr == NULL) return; #ifdef DLS_SYNTHESIZER /* if we have a global DLS collection, clean it up */ if (pEASData->pVoiceMgr->pGlobalDLS) { DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS); pEASData->pVoiceMgr->pGlobalDLS = NULL; } #endif /* check Configuration Module for static memory allocation */ if (!pEASData->staticMemoryModel) EAS_HWFree(pEASData->hwInstData, pEASData->pVoiceMgr); pEASData->pVoiceMgr = NULL; } #ifdef EXTERNAL_AUDIO /*---------------------------------------------------------------------------- * EAS_RegExtAudioCallback() *---------------------------------------------------------------------------- * Register a callback for external audio processing *---------------------------------------------------------------------------- */ void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc) { pSynth->pExtAudioInstData = pInstData; pSynth->cbProgChgFunc = cbProgChgFunc; pSynth->cbEventFunc = cbEventFunc; } /*---------------------------------------------------------------------------- * VMGetMIDIControllers() *---------------------------------------------------------------------------- * Returns the MIDI controller values on the specified channel *---------------------------------------------------------------------------- */ void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl) { pControl->modWheel = pSynth->channels[channel].modWheel; pControl->volume = pSynth->channels[channel].volume; pControl->pan = pSynth->channels[channel].pan; pControl->expression = pSynth->channels[channel].expression; pControl->channelPressure = pSynth->channels[channel].channelPressure; #ifdef _REVERB pControl->reverbSend = pSynth->channels[channel].reverbSend; #endif #ifdef _CHORUSE pControl->chorusSend = pSynth->channels[channel].chorusSend; #endif } #endif #ifdef _SPLIT_ARCHITECTURE /*---------------------------------------------------------------------------- * VMStartFrame() *---------------------------------------------------------------------------- * Purpose: * Starts an audio frame * * Inputs: * * Outputs: * Returns true if EAS_MixEnginePrep should be called (onboard mixing) * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData) { /* init counter for voices starts in split architecture */ #ifdef MAX_VOICE_STARTS pVoiceMgr->numVoiceStarts = 0; #endif return pFrameInterface->pfStartFrame(pEASData->pVoiceMgr->pFrameBuffer); } /*---------------------------------------------------------------------------- * VMEndFrame() *---------------------------------------------------------------------------- * Purpose: * Stops an audio frame * * Inputs: * * Outputs: * Returns true if EAS_MixEnginePost should be called (onboard mixing) * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData) { return pFrameInterface->pfEndFrame(pEASData->pVoiceMgr->pFrameBuffer, pEASData->pMixBuffer, pEASData->masterGain); } #endif #ifdef TEST_HARNESS /*---------------------------------------------------------------------------- * SanityCheck() *---------------------------------------------------------------------------- */ EAS_RESULT VMSanityCheck (EAS_DATA_HANDLE pEASData) { S_SYNTH_VOICE *pVoice; S_SYNTH *pSynth; EAS_INT i; EAS_INT j; EAS_INT freeVoices; EAS_INT activeVoices; EAS_INT playingVoices; EAS_INT stolenVoices; EAS_INT releasingVoices; EAS_INT mutingVoices; EAS_INT poolCount[MAX_VIRTUAL_SYNTHESIZERS][NUM_SYNTH_CHANNELS]; EAS_INT vSynthNum; EAS_RESULT result = EAS_SUCCESS; /* initialize counts */ EAS_HWMemSet(poolCount, 0, sizeof(poolCount)); freeVoices = activeVoices = playingVoices = stolenVoices = releasingVoices = mutingVoices = 0; /* iterate through all voices */ for (i = 0; i < MAX_SYNTH_VOICES; i++) { pVoice = &pEASData->pVoiceMgr->voices[i]; if (pVoice->voiceState != eVoiceStateFree) { vSynthNum = GET_VSYNTH(pVoice->channel); if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ } result = EAS_FAILURE; continue; } pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum]; switch (pVoice->voiceState) { case eVoiceStateMuting: activeVoices++; mutingVoices++; break; case eVoiceStateStolen: vSynthNum = GET_VSYNTH(pVoice->nextChannel); if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ } result = EAS_FAILURE; continue; } pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum]; activeVoices++; stolenVoices++; poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool]++; break; case eVoiceStateStart: case eVoiceStatePlay: activeVoices++; playingVoices++; poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++; break; case eVoiceStateRelease: activeVoices++; releasingVoices++; poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++; break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck : voice %d in invalid state\n", i); */ } result = EAS_FAILURE; break; } } /* count free voices */ else freeVoices++; } /* dump state info */ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d free\n", freeVoices); */ } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d active\n", activeVoices); */ } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d playing\n", playingVoices); */ } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d releasing\n", releasingVoices); */ } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d muting\n", mutingVoices); */ } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d stolen\n", stolenVoices); */ } if (pEASData->pVoiceMgr->activeVoices != activeVoices) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Active voice mismatch was %d should be %d\n", pEASData->pVoiceMgr->activeVoices, activeVoices); */ } result = EAS_FAILURE; } /* check virtual synth status */ for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++) { if (pEASData->pVoiceMgr->pSynth[i] == NULL) continue; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Synth %d numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ } if (pEASData->pVoiceMgr->pSynth[i]->numActiveVoices > MAX_SYNTH_VOICES) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Synth %d illegal count for numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ } result = EAS_FAILURE; } for (j = 0; j < NUM_SYNTH_CHANNELS; j++) { if (poolCount[i][j] != pEASData->pVoiceMgr->pSynth[i]->poolCount[j]) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Pool count mismatch synth %d pool %d, was %d, should be %d\n", i, j, pEASData->pVoiceMgr->pSynth[i]->poolCount[j], poolCount[i][j]); */ } result = EAS_FAILURE; } } } return result; } #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_midi.c0000644000000000000000000000013214200302440026017 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.269324464 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_midi.c0000644000175000001440000004413714200302440026611 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_midi.c * * Contents and purpose: * This file implements the MIDI stream parser. It is called by eas_smf.c to parse MIDI messages * that are streamed out of the file. It can also parse live MIDI streams. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 794 $ * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $ *---------------------------------------------------------------------------- */ #include "eas_data.h" #include "eas_report.h" #include "eas_miditypes.h" #include "eas_midi.h" #include "eas_vm_protos.h" #include "eas_parser.h" #ifdef JET_INTERFACE #include "jet_data.h" #endif /* state enumerations for ProcessSysExMessage */ typedef enum { eSysEx, eSysExUnivNonRealTime, eSysExUnivNrtTargetID, eSysExGMControl, eSysExUnivRealTime, eSysExUnivRtTargetID, eSysExDeviceControl, eSysExMasterVolume, eSysExMasterVolLSB, eSysExSPMIDI, eSysExSPMIDIchan, eSysExSPMIDIMIP, eSysExMfgID1, eSysExMfgID2, eSysExMfgID3, eSysExEnhancer, eSysExEnhancerSubID, eSysExEnhancerFeedback1, eSysExEnhancerFeedback2, eSysExEnhancerDrive, eSysExEnhancerWet, eSysExEOX, eSysExIgnore } E_SYSEX_STATES; /* local prototypes */ static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode); static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode); /*---------------------------------------------------------------------------- * EAS_InitMIDIStream() *---------------------------------------------------------------------------- * Purpose: * Initializes the MIDI stream state for parsing. * * Inputs: * * Outputs: * returns EAS_RESULT (EAS_SUCCESS is OK) * * Side Effects: * *---------------------------------------------------------------------------- */ void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream) { pMIDIStream->byte3 = EAS_FALSE; pMIDIStream->pending = EAS_FALSE; pMIDIStream->runningStatus = 0; pMIDIStream->status = 0; } /*---------------------------------------------------------------------------- * EAS_ParseMIDIStream() *---------------------------------------------------------------------------- * Purpose: * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled) * so the interface works equally well for both file and stream I/O. * * Inputs: * c - character from MIDI stream * * Outputs: * returns EAS_RESULT (EAS_SUCCESS is OK) * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode) { /* check for new status byte */ if (c & 0x80) { /* save new running status */ if (c < 0xf8) { pMIDIStream->runningStatus = c; pMIDIStream->byte3 = EAS_FALSE; /* deal with SysEx */ if ((c == 0xf7) || (c == 0xf0)) { if (parserMode == eParserModeMetaData) return EAS_SUCCESS; return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode); } /* inform the file parser that we're in the middle of a message */ if ((c < 0xf4) || (c > 0xf6)) pMIDIStream->pending = EAS_TRUE; } /* real-time message - ignore it */ return EAS_SUCCESS; } /* 3rd byte of a 3-byte message? */ if (pMIDIStream->byte3) { pMIDIStream->d2 = c; pMIDIStream->byte3 = EAS_FALSE; pMIDIStream->pending = EAS_FALSE; if (parserMode == eParserModeMetaData) return EAS_SUCCESS; return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode); } /* check for status received */ if (pMIDIStream->runningStatus) { /* save new status and data byte */ pMIDIStream->status = pMIDIStream->runningStatus; /* check for 3-byte messages */ if (pMIDIStream->status < 0xc0) { pMIDIStream->d1 = c; pMIDIStream->pending = EAS_TRUE; pMIDIStream->byte3 = EAS_TRUE; return EAS_SUCCESS; } /* check for 2-byte messages */ if (pMIDIStream->status < 0xe0) { pMIDIStream->d1 = c; pMIDIStream->pending = EAS_FALSE; if (parserMode == eParserModeMetaData) return EAS_SUCCESS; return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode); } /* check for more 3-bytes message */ if (pMIDIStream->status < 0xf0) { pMIDIStream->d1 = c; pMIDIStream->pending = EAS_TRUE; pMIDIStream->byte3 = EAS_TRUE; return EAS_SUCCESS; } /* SysEx message? */ if (pMIDIStream->status == 0xF0) { if (parserMode == eParserModeMetaData) return EAS_SUCCESS; return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode); } /* remaining messages all clear running status */ pMIDIStream->runningStatus = 0; /* F2 is 3-byte message */ if (pMIDIStream->status == 0xf2) { pMIDIStream->byte3 = EAS_TRUE; return EAS_SUCCESS; } } /* no status byte received, provide a warning, but we should be able to recover */ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Received MIDI data without a valid status byte: %d\n",c); */ } pMIDIStream->pending = EAS_FALSE; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * ProcessMIDIMessage() *---------------------------------------------------------------------------- * Purpose: * This function processes a typical MIDI message. All of the data has been received, just need * to take appropriate action. * * Inputs: * * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode) { EAS_U8 channel; channel = pMIDIStream->status & 0x0f; switch (pMIDIStream->status & 0xf0) { case 0x80: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n", pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ } if (parserMode <= eParserModeMute) VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2); break; case 0x90: if (pMIDIStream->d2) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOn: %02x %02x %02x\n", pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ } pMIDIStream->flags |= MIDI_FLAG_FIRST_NOTE; if (parserMode == eParserModePlay) VMStartNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2); } else { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n", pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ } if (parserMode <= eParserModeMute) VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2); } break; case 0xa0: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PolyPres: %02x %02x %02x\n", pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ } break; case 0xb0: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Control: %02x %02x %02x\n", pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ } if (parserMode <= eParserModeMute) VMControlChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2); #ifdef JET_INTERFACE if (pMIDIStream->jetData & MIDI_FLAGS_JET_CB) { JET_Event(pEASData, pMIDIStream->jetData & (JET_EVENT_SEG_MASK | JET_EVENT_TRACK_MASK), channel, pMIDIStream->d1, pMIDIStream->d2); } #endif break; case 0xc0: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Program: %02x %02x\n", pMIDIStream->status, pMIDIStream->d1); */ } if (parserMode <= eParserModeMute) VMProgramChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1); break; case 0xd0: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"ChanPres: %02x %02x\n", pMIDIStream->status, pMIDIStream->d1); */ } if (parserMode <= eParserModeMute) VMChannelPressure(pSynth, channel, pMIDIStream->d1); break; case 0xe0: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PBend: %02x %02x %02x\n", pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ } if (parserMode <= eParserModeMute) VMPitchBend(pSynth, channel, pMIDIStream->d1, pMIDIStream->d2); break; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Unknown: %02x %02x %02x\n", pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ } } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * ProcessSysExMessage() *---------------------------------------------------------------------------- * Purpose: * Process a SysEx character byte from the MIDI stream. Since we cannot * simply wait for the next character to arrive, we are forced to save * state after each character. It would be easier to parse at the file * level, but then we lose the nice feature of being able to support * these messages in a real-time MIDI stream. * * Inputs: * pEASData - pointer to synthesizer instance data * c - character to be processed * locating - if true, the sequencer is relocating to a new position * * Outputs: * * * Side Effects: * * Notes: * These are the SysEx messages we can receive: * * SysEx messages * { f0 7e 7f 09 01 f7 } GM 1 On * { f0 7e 7f 09 02 f7 } GM 1/2 Off * { f0 7e 7f 09 03 f7 } GM 2 On * { f0 7f 7f 04 01 lsb msb } Master Volume * { f0 7f 7f 0b 01 ch mip [ch mip ...] f7 } SP-MIDI * { f0 00 01 3a 04 01 fdbk1 fdbk2 drive wet dry f7 } Enhancer * *---------------------------------------------------------------------------- */ static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode) { /* check for start byte */ if (c == 0xf0) { pMIDIStream->sysExState = eSysEx; } /* check for end byte */ else if (c == 0xf7) { /* if this was a MIP message, update the MIP table */ if ((pMIDIStream->sysExState == eSysExSPMIDIchan) && (parserMode != eParserModeMetaData)) VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth); pMIDIStream->sysExState = eSysExIgnore; } /* process SysEx message */ else { switch (pMIDIStream->sysExState) { case eSysEx: /* first byte, determine message class */ switch (c) { case 0x7e: pMIDIStream->sysExState = eSysExUnivNonRealTime; break; case 0x7f: pMIDIStream->sysExState = eSysExUnivRealTime; break; case 0x00: pMIDIStream->sysExState = eSysExMfgID1; break; default: pMIDIStream->sysExState = eSysExIgnore; break; } break; /* process GM message */ case eSysExUnivNonRealTime: if (c == 0x7f) pMIDIStream->sysExState = eSysExUnivNrtTargetID; else pMIDIStream->sysExState = eSysExIgnore; break; case eSysExUnivNrtTargetID: if (c == 0x09) pMIDIStream->sysExState = eSysExGMControl; else pMIDIStream->sysExState = eSysExIgnore; break; case eSysExGMControl: if ((c == 1) || (c == 3)) { /* GM 1 or GM2 On, reset synth */ if (parserMode != eParserModeMetaData) { pMIDIStream->flags |= MIDI_FLAG_GM_ON; VMReset(pEASData->pVoiceMgr, pSynth, EAS_FALSE); VMInitMIPTable(pSynth); } pMIDIStream->sysExState = eSysExEOX; } else pMIDIStream->sysExState = eSysExIgnore; break; /* Process Master Volume and SP-MIDI */ case eSysExUnivRealTime: if (c == 0x7f) pMIDIStream->sysExState = eSysExUnivRtTargetID; else pMIDIStream->sysExState = eSysExIgnore; break; case eSysExUnivRtTargetID: if (c == 0x04) pMIDIStream->sysExState = eSysExDeviceControl; else if (c == 0x0b) pMIDIStream->sysExState = eSysExSPMIDI; else pMIDIStream->sysExState = eSysExIgnore; break; /* process master volume */ case eSysExDeviceControl: if (c == 0x01) pMIDIStream->sysExState = eSysExMasterVolume; else pMIDIStream->sysExState = eSysExIgnore; break; case eSysExMasterVolume: /* save LSB */ pMIDIStream->d1 = c; pMIDIStream->sysExState = eSysExMasterVolLSB; break; case eSysExMasterVolLSB: if (parserMode != eParserModeMetaData) { EAS_I32 gain = ((EAS_I32) c << 8) | ((EAS_I32) pMIDIStream->d1 << 1); gain = (gain * gain) >> 15; VMSetVolume(pSynth, (EAS_U16) gain); } pMIDIStream->sysExState = eSysExEOX; break; /* process SP-MIDI MIP message */ case eSysExSPMIDI: if (c == 0x01) { /* assume all channels are muted */ if (parserMode != eParserModeMetaData) VMInitMIPTable(pSynth); pMIDIStream->d1 = 0; pMIDIStream->sysExState = eSysExSPMIDIchan; } else pMIDIStream->sysExState = eSysExIgnore; break; case eSysExSPMIDIchan: if (c < NUM_SYNTH_CHANNELS) { pMIDIStream->d2 = c; pMIDIStream->sysExState = eSysExSPMIDIMIP; } else { /* bad MIP message - unmute channels */ if (parserMode != eParserModeMetaData) VMInitMIPTable(pSynth); pMIDIStream->sysExState = eSysExIgnore; } break; case eSysExSPMIDIMIP: /* process MIP entry here */ if (parserMode != eParserModeMetaData) VMSetMIPEntry(pEASData->pVoiceMgr, pSynth, pMIDIStream->d2, pMIDIStream->d1, c); pMIDIStream->sysExState = eSysExSPMIDIchan; /* if 16 channels received, update MIP table */ if (++pMIDIStream->d1 == NUM_SYNTH_CHANNELS) { if (parserMode != eParserModeMetaData) VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth); pMIDIStream->sysExState = eSysExEOX; } break; /* process Enhancer */ case eSysExMfgID1: if (c == 0x01) pMIDIStream->sysExState = eSysExMfgID1; else pMIDIStream->sysExState = eSysExIgnore; break; case eSysExMfgID2: if (c == 0x3a) pMIDIStream->sysExState = eSysExMfgID1; else pMIDIStream->sysExState = eSysExIgnore; break; case eSysExMfgID3: if (c == 0x04) pMIDIStream->sysExState = eSysExEnhancer; else pMIDIStream->sysExState = eSysExIgnore; break; case eSysExEnhancer: if (c == 0x01) pMIDIStream->sysExState = eSysExEnhancerSubID; else pMIDIStream->sysExState = eSysExIgnore; break; case eSysExEnhancerSubID: pMIDIStream->sysExState = eSysExEnhancerFeedback1; break; case eSysExEnhancerFeedback1: pMIDIStream->sysExState = eSysExEnhancerFeedback2; break; case eSysExEnhancerFeedback2: pMIDIStream->sysExState = eSysExEnhancerDrive; break; case eSysExEnhancerDrive: pMIDIStream->sysExState = eSysExEnhancerWet; break; case eSysExEnhancerWet: pMIDIStream->sysExState = eSysExEOX; break; case eSysExEOX: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Expected F7, received %02x\n", c); */ } pMIDIStream->sysExState = eSysExIgnore; break; case eSysExIgnore: break; default: pMIDIStream->sysExState = eSysExIgnore; break; } } if (pMIDIStream->sysExState == eSysExIgnore) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Ignoring SysEx byte %02x\n", c); */ } return EAS_SUCCESS; } /* end ProcessSysExMessage */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_pan.h0000644000000000000000000000013214200302440025660 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.269324464 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_pan.h0000644000175000001440000000422714200302440026446 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_pan.h * * Contents and purpose: * Calculates left and right gain multipliers based on a pan value from -63 to +63 * * NOTES: * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine * whether the parser works for those particular file formats. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_PAN_H #define _EAS_PAN_H #include "eas_types.h" /*---------------------------------------------------------------------------- * EAS_CalcPanControl() *---------------------------------------------------------------------------- * Purpose: * Assign the left and right gain values corresponding to the given pan value. * * This routine uses sin/cos approximations for an equal power curve: * * sin(x) = (2-4*c)*x^2 + c + x * cos(x) = (2-4*c)*x^2 + c - x * * where c = 1/sqrt(2) * using the a0 + x*(a1 + x*a2) approach * * Inputs: * pan - pan value (-63 to + 63) * * Outputs: * pGainLeft linear gain multiplier for left channel (15-bit fraction) * pGainRight linear gain multiplier for left channel (15-bit fraction) * * Side Effects: *---------------------------------------------------------------------------- */ void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight); #endif /* #ifndef _EAS_PAN_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_wtengine.c0000644000000000000000000000013214200302440026715 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.269324464 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_wtengine.c0000644000175000001440000004741514200302440027511 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_wtengine.c * * Contents and purpose: * This file contains the critical synthesizer components that need to * be optimized for best performance. * * Copyright Sonic Network Inc. 2004-2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 844 $ * $Date: 2007-08-23 14:33:32 -0700 (Thu, 23 Aug 2007) $ *---------------------------------------------------------------------------- */ /*------------------------------------ * includes *------------------------------------ */ //#include "log/log.h" //#include #include "eas_types.h" #include "eas_math.h" #include "eas_audioconst.h" #include "eas_sndlib.h" #include "eas_wtengine.h" #include "eas_mixer.h" /*---------------------------------------------------------------------------- * prototypes *---------------------------------------------------------------------------- */ extern void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame); extern void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame); #if defined(_OPTIMIZED_MONO) extern void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame); #else extern void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame); extern void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame); #endif #if defined(_FILTER_ENABLED) extern void WT_VoiceFilter (S_FILTER_CONTROL*pFilter, S_WT_INT_FRAME *pWTIntFrame); #endif #if defined(_OPTIMIZED_MONO) || !defined(NATIVE_EAS_KERNEL) || defined(_16_BIT_SAMPLES) /*---------------------------------------------------------------------------- * WT_VoiceGain *---------------------------------------------------------------------------- * Purpose: * Output gain for individual voice * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ /*lint -esym(715, pWTVoice) reserved for future use */ void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) { EAS_I32 *pMixBuffer; EAS_PCM *pInputBuffer; EAS_I32 gain; EAS_I32 gainIncrement; EAS_I32 tmp0; EAS_I32 tmp1; EAS_I32 tmp2; EAS_I32 numSamples; #if (NUM_OUTPUT_CHANNELS == 2) EAS_I32 gainLeft, gainRight; #endif /* initialize some local variables */ numSamples = pWTIntFrame->numSamples; if (numSamples <= 0) { //ALOGE("b/26366256"); //android_errorWriteLog(0x534e4554, "26366256"); return; } pMixBuffer = pWTIntFrame->pMixBuffer; pInputBuffer = pWTIntFrame->pAudioBuffer; /*lint -e{703} */ gainIncrement = (pWTIntFrame->frame.gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS); if (gainIncrement < 0) gainIncrement++; /*lint -e{703} */ gain = pWTIntFrame->prevGain << 16; #if (NUM_OUTPUT_CHANNELS == 2) gainLeft = pWTVoice->gainLeft; gainRight = pWTVoice->gainRight; #endif while (numSamples--) { /* incremental gain step to prevent zipper noise */ tmp0 = *pInputBuffer++; gain += gainIncrement; /*lint -e{704} */ tmp2 = gain >> 16; /* scale sample by gain */ tmp2 *= tmp0; /* stereo output */ #if (NUM_OUTPUT_CHANNELS == 2) /*lint -e{704} */ tmp2 = tmp2 >> 14; /* get the current sample in the final mix buffer */ tmp1 = *pMixBuffer; /* left channel */ tmp0 = tmp2 * gainLeft; /*lint -e{704} */ tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS; tmp1 += tmp0; *pMixBuffer++ = tmp1; /* get the current sample in the final mix buffer */ tmp1 = *pMixBuffer; /* right channel */ tmp0 = tmp2 * gainRight; /*lint -e{704} */ tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS; tmp1 += tmp0; *pMixBuffer++ = tmp1; /* mono output */ #else /* get the current sample in the final mix buffer */ tmp1 = *pMixBuffer; /*lint -e{704} */ tmp2 = tmp2 >> (NUM_MIXER_GUARD_BITS - 1); tmp1 += tmp2; *pMixBuffer++ = tmp1; #endif } } #endif #if !defined(NATIVE_EAS_KERNEL) || defined(_16_BIT_SAMPLES) /*---------------------------------------------------------------------------- * WT_Interpolate *---------------------------------------------------------------------------- * Purpose: * Interpolation engine for wavetable synth * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) { EAS_PCM *pOutputBuffer; EAS_I32 phaseInc; EAS_I32 phaseFrac; EAS_I32 acc0; const EAS_SAMPLE *pSamples; const EAS_SAMPLE *loopEnd; EAS_I32 samp1; EAS_I32 samp2; EAS_I32 numSamples; /* initialize some local variables */ numSamples = pWTIntFrame->numSamples; if (numSamples <= 0) { //ALOGE("b/26366256"); //android_errorWriteLog(0x534e4554, "26366256"); return; } pOutputBuffer = pWTIntFrame->pAudioBuffer; loopEnd = (const EAS_SAMPLE*) pWTVoice->loopEnd + 1; pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum; /*lint -e{713} truncation is OK */ phaseFrac = pWTVoice->phaseFrac; phaseInc = pWTIntFrame->frame.phaseIncrement; /* fetch adjacent samples */ #if defined(_8_BIT_SAMPLES) /*lint -e{701} */ samp1 = pSamples[0] << 8; /*lint -e{701} */ samp2 = pSamples[1] << 8; #else samp1 = pSamples[0]; samp2 = pSamples[1]; #endif while (numSamples--) { /* linear interpolation */ acc0 = samp2 - samp1; acc0 = acc0 * phaseFrac; /*lint -e{704} */ acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS); /* save new output sample in buffer */ /*lint -e{704} */ *pOutputBuffer++ = (EAS_I16)(acc0 >> 2); /* increment phase */ phaseFrac += phaseInc; /*lint -e{704} */ acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS; /* next sample */ if (acc0 > 0) { /* advance sample pointer */ pSamples += acc0; phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK); /* check for loop end */ acc0 = (EAS_I32) (pSamples - loopEnd); if (acc0 >= 0) pSamples = (const EAS_SAMPLE*) pWTVoice->loopStart + acc0; /* fetch new samples */ #if defined(_8_BIT_SAMPLES) /*lint -e{701} */ samp1 = pSamples[0] << 8; /*lint -e{701} */ samp2 = pSamples[1] << 8; #else samp1 = pSamples[0]; samp2 = pSamples[1]; #endif } } /* save pointer and phase */ pWTVoice->phaseAccum = (EAS_U32) pSamples; pWTVoice->phaseFrac = (EAS_U32) phaseFrac; } #endif #if !defined(NATIVE_EAS_KERNEL) || defined(_16_BIT_SAMPLES) /*---------------------------------------------------------------------------- * WT_InterpolateNoLoop *---------------------------------------------------------------------------- * Purpose: * Interpolation engine for wavetable synth * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) { EAS_PCM *pOutputBuffer; EAS_I32 phaseInc; EAS_I32 phaseFrac; EAS_I32 acc0; const EAS_SAMPLE *pSamples; EAS_I32 samp1; EAS_I32 samp2; EAS_I32 numSamples; /* initialize some local variables */ numSamples = pWTIntFrame->numSamples; if (numSamples <= 0) { //ALOGE("b/26366256"); //android_errorWriteLog(0x534e4554, "26366256"); return; } pOutputBuffer = pWTIntFrame->pAudioBuffer; phaseInc = pWTIntFrame->frame.phaseIncrement; pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum; phaseFrac = (EAS_I32)pWTVoice->phaseFrac; /* fetch adjacent samples */ #if defined(_8_BIT_SAMPLES) /*lint -e{701} */ samp1 = pSamples[0] << 8; /*lint -e{701} */ samp2 = pSamples[1] << 8; #else samp1 = pSamples[0]; samp2 = pSamples[1]; #endif while (numSamples--) { /* linear interpolation */ acc0 = samp2 - samp1; acc0 = acc0 * phaseFrac; /*lint -e{704} */ acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS); /* save new output sample in buffer */ /*lint -e{704} */ *pOutputBuffer++ = (EAS_I16)(acc0 >> 2); /* increment phase */ phaseFrac += phaseInc; /*lint -e{704} */ acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS; /* next sample */ if (acc0 > 0) { /* advance sample pointer */ pSamples += acc0; phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK); /* fetch new samples */ #if defined(_8_BIT_SAMPLES) /*lint -e{701} */ samp1 = pSamples[0] << 8; /*lint -e{701} */ samp2 = pSamples[1] << 8; #else samp1 = pSamples[0]; samp2 = pSamples[1]; #endif } } /* save pointer and phase */ pWTVoice->phaseAccum = (EAS_U32) pSamples; pWTVoice->phaseFrac = (EAS_U32) phaseFrac; } #endif #if defined(_FILTER_ENABLED) && !defined(NATIVE_EAS_KERNEL) /*---------------------------------------------------------------------------- * WT_VoiceFilter *---------------------------------------------------------------------------- * Purpose: * Implements a 2-pole filter * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ void WT_VoiceFilter (S_FILTER_CONTROL *pFilter, S_WT_INT_FRAME *pWTIntFrame) { EAS_PCM *pAudioBuffer; EAS_I32 k; EAS_I32 b1; EAS_I32 b2; EAS_I32 z1; EAS_I32 z2; EAS_I32 acc0; EAS_I32 acc1; EAS_I32 numSamples; /* initialize some local variables */ numSamples = pWTIntFrame->numSamples; if (numSamples <= 0) { //ALOGE("b/26366256"); //android_errorWriteLog(0x534e4554, "26366256"); return; } pAudioBuffer = pWTIntFrame->pAudioBuffer; z1 = pFilter->z1; z2 = pFilter->z2; b1 = -pWTIntFrame->frame.b1; /*lint -e{702} */ b2 = -pWTIntFrame->frame.b2 >> 1; /*lint -e{702} */ k = pWTIntFrame->frame.k >> 1; while (numSamples--) { /* do filter calculations */ acc0 = *pAudioBuffer; acc1 = z1 * b1; acc1 += z2 * b2; acc0 = acc1 + k * acc0; z2 = z1; /*lint -e{702} */ z1 = acc0 >> 14; *pAudioBuffer++ = (EAS_I16) z1; } /* save delay values */ pFilter->z1 = (EAS_I16) z1; pFilter->z2 = (EAS_I16) z2; } #endif /*---------------------------------------------------------------------------- * WT_NoiseGenerator *---------------------------------------------------------------------------- * Purpose: * Generate pseudo-white noise using PRNG and interpolation engine * * Inputs: * * Outputs: * * Notes: * This output is scaled -12dB to prevent saturation in the filter. For a * high quality synthesizer, the output can be set to full scale, however * if the filter is used, it can overflow with certain coefficients. In this * case, either a saturation operation should take in the filter before * scaling back to 16 bits or the signal path should be increased to 18 bits * or more. *---------------------------------------------------------------------------- */ void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) { EAS_PCM *pOutputBuffer; EAS_I32 phaseInc; EAS_I32 tmp0; EAS_I32 tmp1; EAS_I32 nInterpolatedSample; EAS_I32 numSamples; /* initialize some local variables */ numSamples = pWTIntFrame->numSamples; if (numSamples <= 0) { //ALOGE("b/26366256"); //android_errorWriteLog(0x534e4554, "26366256"); return; } pOutputBuffer = pWTIntFrame->pAudioBuffer; phaseInc = pWTIntFrame->frame.phaseIncrement; /* get last two samples generated */ /*lint -e{704} */ tmp0 = (EAS_I32) (pWTVoice->phaseAccum) >> 18; /*lint -e{704} */ tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18; /* generate a buffer of noise */ while (numSamples--) { nInterpolatedSample = MULT_AUDIO_COEF( tmp0, (PHASE_ONE - pWTVoice->phaseFrac)); nInterpolatedSample += MULT_AUDIO_COEF( tmp1, pWTVoice->phaseFrac); *pOutputBuffer++ = (EAS_PCM) nInterpolatedSample; /* update PRNG */ pWTVoice->phaseFrac += (EAS_U32) phaseInc; if (GET_PHASE_INT_PART(pWTVoice->phaseFrac)) { tmp0 = tmp1; pWTVoice->phaseAccum = pWTVoice->loopEnd; pWTVoice->loopEnd = (5 * pWTVoice->loopEnd + 1); tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18; pWTVoice->phaseFrac = GET_PHASE_FRAC_PART(pWTVoice->phaseFrac); } } } #ifndef _OPTIMIZED_MONO /*---------------------------------------------------------------------------- * WT_ProcessVoice *---------------------------------------------------------------------------- * Purpose: * This routine does the block processing for one voice. It is isolated * from the main synth code to allow for various implementation-specific * optimizations. It calls the interpolator, filter, and gain routines * appropriate for a particular configuration. * * Inputs: * * Outputs: * * Notes: *---------------------------------------------------------------------------- */ void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) { /* use noise generator */ if (pWTVoice->loopStart == WT_NOISE_GENERATOR) WT_NoiseGenerator(pWTVoice, pWTIntFrame); /* generate interpolated samples for looped waves */ else if (pWTVoice->loopStart != pWTVoice->loopEnd) WT_Interpolate(pWTVoice, pWTIntFrame); /* generate interpolated samples for unlooped waves */ else { WT_InterpolateNoLoop(pWTVoice, pWTIntFrame); } #ifdef _FILTER_ENABLED if (pWTIntFrame->frame.k != 0) WT_VoiceFilter(&pWTVoice->filter, pWTIntFrame); #endif //2 TEST NEW MIXER FUNCTION #ifdef UNIFIED_MIXER { EAS_I32 gainLeft, gainIncLeft; #if (NUM_OUTPUT_CHANNELS == 2) EAS_I32 gainRight, gainIncRight; #endif gainLeft = (pWTIntFrame->prevGain * pWTVoice->gainLeft) << 1; gainIncLeft = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainLeft) << 1) - gainLeft) >> SYNTH_UPDATE_PERIOD_IN_BITS; #if (NUM_OUTPUT_CHANNELS == 2) gainRight = (pWTIntFrame->prevGain * pWTVoice->gainRight) << 1; gainIncRight = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainRight) << 1) - gainRight) >> SYNTH_UPDATE_PERIOD_IN_BITS; EAS_MixStream( pWTIntFrame->pAudioBuffer, pWTIntFrame->pMixBuffer, pWTIntFrame->numSamples, gainLeft, gainRight, gainIncLeft, gainIncRight, MIX_FLAGS_STEREO_OUTPUT); #else EAS_MixStream( pWTIntFrame->pAudioBuffer, pWTIntFrame->pMixBuffer, pWTIntFrame->numSamples, gainLeft, 0, gainIncLeft, 0, 0); #endif } #else /* apply gain, and left and right gain */ WT_VoiceGain(pWTVoice, pWTIntFrame); #endif } #endif #if defined(_OPTIMIZED_MONO) && !defined(NATIVE_EAS_KERNEL) /*---------------------------------------------------------------------------- * WT_InterpolateMono *---------------------------------------------------------------------------- * Purpose: * A C version of the sample interpolation + gain routine, optimized for mono. * It's not pretty, but it matches the assembly code exactly. * * Inputs: * * Outputs: * * Notes: *---------------------------------------------------------------------------- */ void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) { EAS_I32 *pMixBuffer; const EAS_I8 *pLoopEnd; const EAS_I8 *pCurrentPhaseInt; EAS_I32 numSamples; EAS_I32 gain; EAS_I32 gainIncrement; EAS_I32 currentPhaseFrac; EAS_I32 phaseInc; EAS_I32 tmp0; EAS_I32 tmp1; EAS_I32 tmp2; EAS_I8 *pLoopStart; numSamples = pWTIntFrame->numSamples; if (numSamples <= 0) { ALOGE("b/26366256"); android_errorWriteLog(0x534e4554, "26366256"); return; } pMixBuffer = pWTIntFrame->pMixBuffer; /* calculate gain increment */ gainIncrement = (pWTIntFrame->gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS); if (gainIncrement < 0) gainIncrement++; gain = pWTIntFrame->prevGain << 16; pCurrentPhaseInt = pWTVoice->pPhaseAccum; currentPhaseFrac = pWTVoice->phaseFrac; phaseInc = pWTIntFrame->phaseIncrement; pLoopStart = pWTVoice->pLoopStart; pLoopEnd = pWTVoice->pLoopEnd + 1; InterpolationLoop: tmp0 = (EAS_I32)(pCurrentPhaseInt - pLoopEnd); if (tmp0 >= 0) pCurrentPhaseInt = pLoopStart + tmp0; tmp0 = *pCurrentPhaseInt; tmp1 = *(pCurrentPhaseInt + 1); tmp2 = phaseInc + currentPhaseFrac; tmp1 = tmp1 - tmp0; tmp1 = tmp1 * currentPhaseFrac; tmp1 = tmp0 + (tmp1 >> NUM_EG1_FRAC_BITS); pCurrentPhaseInt += (tmp2 >> NUM_PHASE_FRAC_BITS); currentPhaseFrac = tmp2 & PHASE_FRAC_MASK; gain += gainIncrement; tmp2 = (gain >> SYNTH_UPDATE_PERIOD_IN_BITS); tmp0 = *pMixBuffer; tmp2 = tmp1 * tmp2; tmp2 = (tmp2 >> 9); tmp0 = tmp2 + tmp0; *pMixBuffer++ = tmp0; numSamples--; if (numSamples > 0) goto InterpolationLoop; pWTVoice->pPhaseAccum = pCurrentPhaseInt; pWTVoice->phaseFrac = currentPhaseFrac; /*lint -e{702} */ pWTVoice->gain = (EAS_I16)(gain >> SYNTH_UPDATE_PERIOD_IN_BITS); } #endif #ifdef _OPTIMIZED_MONO /*---------------------------------------------------------------------------- * WT_ProcessVoice *---------------------------------------------------------------------------- * Purpose: * This routine does the block processing for one voice. It is isolated * from the main synth code to allow for various implementation-specific * optimizations. It calls the interpolator, filter, and gain routines * appropriate for a particular configuration. * * Inputs: * * Outputs: * * Notes: * This special version works handles an optimized mono-only signal * without filters *---------------------------------------------------------------------------- */ void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) { /* use noise generator */ if (pWTVoice->loopStart== WT_NOISE_GENERATOR) { WT_NoiseGenerator(pWTVoice, pWTIntFrame); WT_VoiceGain(pWTVoice, pWTIntFrame); } /* or generate interpolated samples */ else { WT_InterpolateMono(pWTVoice, pWTIntFrame); } } #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_tcdata.h0000644000000000000000000000013214200302440026342 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_tcdata.h0000644000175000001440000000471314200302440027130 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_tcdata.h * * Contents and purpose: * SMF File Parser * * This file contains data declarations for the ToneControl parser. * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef EAS_TFDATA_H #define EAS_TCDATA_H #include "eas_data.h" /*---------------------------------------------------------------------------- * * S_TC_DATA * * This structure contains the state data for the ToneControl parser *---------------------------------------------------------------------------- */ typedef struct { EAS_FILE_HANDLE fileHandle; /* file handle */ S_SYNTH *pSynth; /* synthesizer handle */ EAS_I32 fileOffset; /* offset to start of data */ EAS_I32 time; /* current time in 256ths of a msec */ EAS_I32 tick; /* tick based on current tempo and resolution */ EAS_I32 length; /* length of current note */ EAS_I32 restorePos; /* return to here after block */ EAS_U8 state; /* current state EAS_STATE_XXXX */ EAS_U8 volume; /* volume */ EAS_I8 note; /* current note */ EAS_I8 repeatCount; /* note repeat counter */ EAS_I8 tempo; /* tempo from file (bpm = tempo * 4) */ EAS_I8 resolution; /* resolution from file */ EAS_I8 dataByte; /* storage for characters that are "put back" */ EAS_BOOL8 byteAvail; /* char in "put back" buffer */ } S_TC_DATA; #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_wtengine.h0000644000000000000000000000013214200302440026722 xustar0030 mtime=1644266784.809324171 30 atime=1644266785.269324464 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_wtengine.h0000644000175000001440000001367414200302440027516 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_wtengine.h * * Contents and purpose: * This file defines the interface for wavetable synthesis engine * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 818 $ * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_WTENGINE_H #define _EAS_WTENGINE_H /* option sanity check */ #if defined(_OPTIMIZED_MONO) && defined(_FILTER_ENABLED) #error "Incompatible build settings: _OPTIMIZED_MONO cannot be used with _FILTER_ENABLED" #endif #if defined(_OPTIMIZED_MONO) && (NUM_OUTPUT_CHANNELS != 1) #error "Incompatible build settings: _OPTIMIZED_MONO can only be used with NUM_OUTPUT_CHANNELS = 1" #endif #include "eas_wt_IPC_frame.h" /*---------------------------------------------------------------------------- * defines *---------------------------------------------------------------------------- */ #define WT_NOISE_GENERATOR 0xffffffff /*---------------------------------------------------------------------------- * typedefs *---------------------------------------------------------------------------- */ /*---------------------------------------------------------------------------- * S_WT_INT_FRAME * * This structure includes S_WT_FRAME plus the bus mixing * parameters for the internal voices. *---------------------------------------------------------------------------- */ typedef struct s_wt_int_frame_tag { S_WT_FRAME frame; EAS_PCM *pAudioBuffer; EAS_I32 *pMixBuffer; EAS_I32 numSamples; EAS_I32 prevGain; } S_WT_INT_FRAME; #if defined(_FILTER_ENABLED) /*---------------------------------------------------------------------------- * S_FILTER_CONTROL data structure *---------------------------------------------------------------------------- */ typedef struct s_filter_control_tag { EAS_I16 z1; /* 1 sample delay state variable */ EAS_I16 z2; /* 2 sample delay state variable */ } S_FILTER_CONTROL; #endif /*------------------------------------ * S_LFO_CONTROL data structure *------------------------------------ */ typedef struct s_lfo_control_tag { EAS_I16 lfoValue; /* LFO current output value */ EAS_I16 lfoPhase; /* LFO current phase */ } S_LFO_CONTROL; /* bit definitions for S_WT_VOICE:flags */ #define WT_FLAGS_ADPCM_NIBBLE 1 /* high/low nibble flag */ #define WT_FLAGS_ADPCM_READY 2 /* first 2 samples are decoded */ #define WT_FLAGS_USE_ADPCM 4 /* sample is ADPCM encoded */ /* eg1State and eg2State */ typedef enum { eEnvelopeStateInit = 0, eEnvelopeStateDelay, eEnvelopeStateAttack, eEnvelopeStateHold, eEnvelopeStateDecay, eEnvelopeStateSustain, eEnvelopeStateRelease, eEnvelopeStateMuting, eEnvelopeStateMuted, eEnvelopeStateInvalid /* should never be in this state! */ } E_ENVELOPE_STATE; #define DEFAULT_EG1_STATE eEnvelopeStateAttack #define DEFAULT_EG1_VALUE 0 #define DEFAULT_EG1_INCREMENT 0 #define DEFAULT_EG2_STATE eEnvelopeStateAttack #define DEFAULT_EG2_VALUE 0 #define DEFAULT_EG2_INCREMENT 0 /*---------------------------------------------------------------------------- * S_WT_VOICE * * This structure contains state data for the wavetable engine *---------------------------------------------------------------------------- */ typedef struct s_wt_voice_tag { EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */ EAS_U32 loopStart; /* points to first sample at start of loop */ EAS_U32 phaseAccum; /* current sample, integer portion of phase */ EAS_U32 phaseFrac; /* fractional portion of phase */ #if (NUM_OUTPUT_CHANNELS == 2) EAS_I16 gainLeft; /* current gain, left ch */ EAS_I16 gainRight; /* current gain, right ch */ #endif #if defined(_FILTER_ENABLED) S_FILTER_CONTROL filter; /* low pass filter */ #endif S_LFO_CONTROL modLFO; /* modulator LFO */ #ifdef DLS_SYNTHESIZER S_LFO_CONTROL vibLFO; /* vibrato LFO */ #endif /* envelope control */ EAS_I16 eg1Value; EAS_I16 eg2Value; EAS_I16 eg1Increment; EAS_I16 eg2Increment; EAS_U8 eg1State; EAS_U8 eg2State; EAS_U16 artIndex; /* index to articulation params */ } S_WT_VOICE; /*---------------------------------------------------------------------------- * prototypes *---------------------------------------------------------------------------- */ EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, EAS_BOOL update); void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame); #ifdef EAS_SPLIT_WT_SYNTH void WTE_ConfigVoice (EAS_I32 voiceNum, S_WT_CONFIG *pWTConfig, EAS_FRAME_BUFFER_HANDLE pFrameBuffer); void WTE_ProcessVoice (EAS_I32 voiceNum, S_WT_FRAME *pWTParams, EAS_FRAME_BUFFER_HANDLE pFrameBuffer); #endif #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_mdls.c0000644000000000000000000000013214200302440026034 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_mdls.c0000644000175000001440000026326514200302440026633 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_mdls.c * * Contents and purpose: * This file contains DLS to EAS converter. * * Copyright (c) 2005 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 818 $ * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $ *---------------------------------------------------------------------------- */ /* * NOTES: * * Processor Endian-ness: * * We use the EAS_HWGetDWord() and EAS_HWGetWord () functions * extensively in this module. It would probably be faster to read * an entire data structure, but this introduces the problem of * sensitivity to processor endian-ness to the parser. By utlilizing * the host wrapper functions, we avoid having to flip bytes around * for big-endian processors. The default host wrapper versions of * these functions are insensitive to processor endian-ness due to * the fact that they read the file as a byte stream. * * Dynamic Memory: * * Dynamic memory allocation is a risky proposition in a mobile * device. The memory can become fragmented, resulting in an * inability to allocate a memory block, or garbage collection * routines can use many CPU cycles. Either can contribute to * failures of critical systems. Therefore, we try to minimize the * number of memory allocations we make. * * We allocate a single large block of memory for the entire * converted DLS collection, including the articulation data and * samples. This block is then sub-allocated for the various * data structures. * * Parser Overview: * * We make two passes through the file, the first pass to count the * number of instruments, regions, etc. and allocate memory for * them. The second pass parses the data into the allocated data * structures. * * Conditional chunks are challenging in that they can occur * anywhere in the list chunk that contains them. To simplify, we * parse the blocks in a list in specific order, no matter which * order they appear in the file. This way we don't allocate memory * and parse a block that we end up throwing away later due to * a conditional chunk. * * Assumptions that may bite us in the future: * * We make some assumptions to simplify things. The most fundamental * assumption is that there will be no more than one of any type of * chunk in a list. While this is consistent with the block diagram * of the file layout in the mDLS spec, there is nothing in the * spec that precludes having mulitple lar2 or rgn2 chunks, with * conditional blocks that dictate their usage. * * DLS -> EAS Conversion Process: * * Another challenge is that the DLS structure does not map well to * the current EAS sound library structure. Not all DLS constructs * are supported, and data from DLS structures must sometimes be * mapped to multiple EAS data structures. To simplify the process, * the EAS region, articulation, and envelopes are treated as a * single combined unit. Thus for each region, there must be one * articulation element and two envelope elements. * * The sample processing is also a multi-step process. First the * ptbl chunk is pre-parsed to determine the number of samples * in the collection. The next step is to parse the instrument data * to determine which samples are actually used by instruments. * Some samples may not be used because they are used only in * conditional blocks that the synthesizer cannot parse, or the * author neglected to remove unused samples from the collection. * In the next step, the active samples are read into memory and * converted to the appropriate playback format. Finally, as the * instruments are processed, the links are made to the samples and * wsmp data is extracted for the region and articulation data * structures. */ #ifndef _FILTER_ENABLED #error "Filter must be enabled if DLS_SYNTHESIZER is enabled" #endif /*------------------------------------ * includes *------------------------------------ */ /* this define allows us to use the sndlib.h structures as RW memory */ #define SCNST //#include "log/log.h" #include "eas_data.h" #include "eas_host.h" #include "eas_mdls.h" #include "eas_math.h" #include "dls.h" #include "dls2.h" #include "eas_report.h" #include //2 we should replace log10() function with fixed point routine in ConvertSampleRate() /* lint is choking on the ARM math.h file, so we declare the log10 function here */ extern double log10(double x); /*------------------------------------ * defines *------------------------------------ */ // #define _DEBUG_DLS #define DLS_MAX_WAVE_COUNT 1024 #define DLS_MAX_ART_COUNT 2048 #define DLS_MAX_REGION_COUNT 2048 #define DLS_MAX_INST_COUNT 256 #define MAX_DLS_WAVE_SIZE (1024*1024) #ifndef EAS_U32_MAX #define EAS_U32_MAX (4294967295U) #endif #ifndef EAS_I32_MAX #define EAS_I32_MAX (2147483647) #endif /*------------------------------------ * typedefs *------------------------------------ */ /* offsets to articulation data */ typedef enum { PARAM_MODIFIED = 0, PARAM_MOD_LFO_FREQ, PARAM_MOD_LFO_DELAY, PARAM_VIB_LFO_FREQ, PARAM_VIB_LFO_DELAY, PARAM_VOL_EG_DELAY, PARAM_VOL_EG_ATTACK, PARAM_VOL_EG_HOLD, PARAM_VOL_EG_DECAY, PARAM_VOL_EG_SUSTAIN, PARAM_VOL_EG_RELEASE, PARAM_VOL_EG_SHUTDOWN, PARAM_VOL_EG_VEL_TO_ATTACK, PARAM_VOL_EG_KEY_TO_DECAY, PARAM_VOL_EG_KEY_TO_HOLD, PARAM_MOD_EG_DELAY, PARAM_MOD_EG_ATTACK, PARAM_MOD_EG_HOLD, PARAM_MOD_EG_DECAY, PARAM_MOD_EG_SUSTAIN, PARAM_MOD_EG_RELEASE, PARAM_MOD_EG_VEL_TO_ATTACK, PARAM_MOD_EG_KEY_TO_DECAY, PARAM_MOD_EG_KEY_TO_HOLD, PARAM_INITIAL_FC, PARAM_INITIAL_Q, PARAM_MOD_LFO_TO_FC, PARAM_MOD_LFO_CC1_TO_FC, PARAM_MOD_LFO_CHAN_PRESS_TO_FC, PARAM_MOD_EG_TO_FC, PARAM_VEL_TO_FC, PARAM_KEYNUM_TO_FC, PARAM_MOD_LFO_TO_GAIN, PARAM_MOD_LFO_CC1_TO_GAIN, PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN, PARAM_VEL_TO_GAIN, PARAM_TUNING, PARAM_KEYNUM_TO_PITCH, PARAM_VIB_LFO_TO_PITCH, PARAM_VIB_LFO_CC1_TO_PITCH, PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH, PARAM_MOD_LFO_TO_PITCH, PARAM_MOD_LFO_CC1_TO_PITCH, PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH, PARAM_MOD_EG_TO_PITCH, PARAM_DEFAULT_PAN, PARAM_MIDI_CC91_TO_REVERB_SEND, PARAM_DEFAULT_REVERB_SEND, PARAM_MIDI_CC93_TO_CHORUS_SEND, PARAM_DEFAULT_CHORUS_SEND, PARAM_TABLE_SIZE } E_ART_INDEX; /* temporary data structure combining region, articulation, and envelope data */ typedef struct s_art_dls_tag { EAS_I16 values[PARAM_TABLE_SIZE]; } S_DLS_ART_VALUES; /* temporary data structure for wlnk chunk data */ typedef struct { EAS_I32 gain; EAS_U32 loopStart; EAS_U32 loopLength; EAS_U32 sampleRate; EAS_U16 bitsPerSample; EAS_I16 fineTune; EAS_U8 unityNote; } S_WSMP_DATA; /* temporary data structure used while parsing a DLS file */ typedef struct { S_DLS *pDLS; EAS_HW_DATA_HANDLE hwInstData; EAS_FILE_HANDLE fileHandle; S_WSMP_DATA *wsmpData; EAS_U32 instCount; EAS_U32 regionCount; EAS_U32 artCount; EAS_U32 waveCount; EAS_U32 wavePoolSize; EAS_U32 wavePoolOffset; EAS_BOOL bigEndian; EAS_BOOL filterUsed; } SDLS_SYNTHESIZER_DATA; /* connection lookup table */ typedef struct s_connection_tag { EAS_U16 source; EAS_U16 control; EAS_U16 destination; EAS_U16 connection; } S_CONNECTION; static const S_CONNECTION connTable[] = { { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_FREQUENCY, PARAM_MOD_LFO_FREQ }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_STARTDELAY, PARAM_MOD_LFO_DELAY}, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_FREQUENCY, PARAM_VIB_LFO_FREQ }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_STARTDELAY, PARAM_VIB_LFO_DELAY }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DELAYTIME, PARAM_VOL_EG_DELAY }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_ATTACK }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_HOLD }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_DECAY }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SUSTAINLEVEL, PARAM_VOL_EG_SUSTAIN }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_RELEASETIME, PARAM_VOL_EG_RELEASE }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SHUTDOWNTIME, PARAM_VOL_EG_SHUTDOWN }, { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_VEL_TO_ATTACK }, { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_KEY_TO_DECAY }, { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_KEY_TO_HOLD }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DELAYTIME, PARAM_MOD_EG_DELAY }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_ATTACK }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_HOLD }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_DECAY }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_SUSTAINLEVEL, PARAM_MOD_EG_SUSTAIN }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_RELEASETIME, PARAM_MOD_EG_RELEASE }, { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_VEL_TO_ATTACK }, { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_KEY_TO_DECAY }, { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_KEY_TO_HOLD }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_INITIAL_FC }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_Q, PARAM_INITIAL_Q }, { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_TO_FC }, { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CC1_TO_FC }, { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CHAN_PRESS_TO_FC }, { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_EG_TO_FC }, { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_VEL_TO_FC }, { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_KEYNUM_TO_FC }, { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_MOD_LFO_TO_GAIN }, { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_GAIN, PARAM_MOD_LFO_CC1_TO_GAIN }, { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_GAIN, PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN }, { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_VEL_TO_GAIN }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_TUNING }, { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_KEYNUM_TO_PITCH }, { CONN_SRC_VIBRATO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_VIB_LFO_TO_PITCH }, { CONN_SRC_VIBRATO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_VIB_LFO_CC1_TO_PITCH }, { CONN_SRC_VIBRATO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH }, { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_LFO_TO_PITCH }, { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_MOD_LFO_CC1_TO_PITCH }, { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH }, { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_EG_TO_PITCH }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PAN, PARAM_DEFAULT_PAN }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_DEFAULT_REVERB_SEND }, { CONN_SRC_CC91, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC91_TO_REVERB_SEND }, { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_CHORUS, PARAM_DEFAULT_CHORUS_SEND }, { CONN_SRC_CC93, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC93_TO_CHORUS_SEND } }; #define ENTRIES_IN_CONN_TABLE (sizeof(connTable)/sizeof(S_CONNECTION)) static const S_DLS_ART_VALUES defaultArt = { { 0, /* not modified */ -851, /* Mod LFO frequency: 5 Hz */ -7973, /* Mod LFO delay: 10 milliseconds */ -851, /* Vib LFO frequency: 5 Hz */ -7973, /* Vib LFO delay: 10 milliseconds */ -32768, /* EG1 delay time: 0 secs */ -32768, /* EG1 attack time: 0 secs */ -32768, /* EG1 hold time: 0 secs */ -32768, /* EG1 decay time: 0 secs */ 1000, /* EG1 sustain level: 100.0% */ -32768, /* EG1 release time: 0 secs */ -7271, /* EG1 shutdown time: 15 msecs */ 0, /* EG1 velocity to attack: 0 time cents */ 0, /* EG1 key number to decay: 0 time cents */ 0, /* EG1 key number to hold: 0 time cents */ -32768, /* EG2 delay time: 0 secs */ -32768, /* EG2 attack time: 0 secs */ -32768, /* EG2 hold time: 0 secs */ -32768, /* EG2 decay time: 0 secs */ 1000, /* EG2 sustain level: 100.0% */ -32768, /* EG2 release time: 0 secs */ 0, /* EG2 velocity to attack: 0 time cents */ 0, /* EG2 key number to decay: 0 time cents */ 0, /* EG2 key number to hold: 0 time cents */ 0x7fff, /* Initial Fc: Disabled */ 0, /* Initial Q: 0 dB */ 0, /* Mod LFO to Fc: 0 cents */ 0, /* Mod LFO CC1 to Fc: 0 cents */ 0, /* Mod LFO channel pressure to Fc: 0 cents */ 0, /* EG2 to Fc: 0 cents */ 0, /* Velocity to Fc: 0 cents */ 0, /* Key number to Fc: 0 cents */ 0, /* Mod LFO to gain: 0 dB */ 0, /* Mod LFO CC1 to gain: 0 dB */ 0, /* Mod LFO channel pressure to gain: 0 dB */ 960, /* Velocity to gain: 96 dB */ 0, /* Tuning: 0 cents */ 12800, /* Key number to pitch: 12,800 cents */ 0, /* Vibrato to pitch: 0 cents */ 0, /* Vibrato CC1 to pitch: 0 cents */ 0, /* Vibrato channel pressure to pitch: 0 cents */ 0, /* Mod LFO to pitch: 0 cents */ 0, /* Mod LFO CC1 to pitch: 0 cents */ 0, /* Mod LFO channel pressure to pitch: 0 cents */ 0, /* Mod EG to pitch: 0 cents */ 0, /* Default pan: 0.0% */ 0, /* Default reverb send: 0.0% */ 1000, /* Default CC91 to reverb send: 100.0% */ 0, /* Default chorus send: 0.0% */ 1000 /* Default CC93 to chorus send: 100.0% */ } }; /*------------------------------------ * local variables *------------------------------------ */ #if defined(_8_BIT_SAMPLES) static const EAS_INT bitDepth = 8; #elif defined(_16_BIT_SAMPLES) static const EAS_INT bitDepth = 16; #else #error "Must define _8_BIT_SAMPLES or _16_BIT_SAMPLES" #endif static const EAS_U32 outputSampleRate = _OUTPUT_SAMPLE_RATE; static const EAS_I32 dlsRateConvert = DLS_RATE_CONVERT; static const EAS_I32 dlsLFOFrequencyConvert = DLS_LFO_FREQUENCY_CONVERT; /*------------------------------------ * inline functions *------------------------------------ */ EAS_INLINE void *PtrOfs (void *p, EAS_I32 offset) { return (void*) (((EAS_U8*) p) + offset); } /*------------------------------------ * prototypes *------------------------------------ */ static EAS_RESULT NextChunk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 *pPos, EAS_U32 *pChunkType, EAS_I32 *pSize); static EAS_RESULT Parse_ptbl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 wsmpPos, EAS_I32 wsmpSize); static EAS_RESULT Parse_wave (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U16 waveIndex); static EAS_RESULT Parse_wsmp (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p); static EAS_RESULT Parse_fmt (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p); static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_WSMP_DATA *p, EAS_SAMPLE *pSample, EAS_U32 sampleLen); static EAS_RESULT Parse_lins(SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size); static EAS_RESULT Parse_ins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size); static EAS_RESULT Parse_insh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pRgnCount, EAS_U32 *pLocale); static EAS_RESULT Parse_lrgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex, EAS_U32 numRegions); static EAS_RESULT Parse_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex); static EAS_RESULT Parse_rgnh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_REGION *pRgn); static EAS_RESULT Parse_lart (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_DLS_ART_VALUES *pArt); static EAS_RESULT Parse_art (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_ART_VALUES *pArt); static EAS_RESULT Parse_wlnk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pWaveIndex); static EAS_RESULT Parse_cdl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 size, EAS_U32 *pValue); static void Convert_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_U16 regionIndex, EAS_U16 artIndex, EAS_U16 waveIndex, S_WSMP_DATA *pWsmp); static void Convert_art (SDLS_SYNTHESIZER_DATA *pDLSData, const S_DLS_ART_VALUES *pDLSArt, EAS_U16 artIndex); static EAS_I16 ConvertSampleRate (EAS_U32 sampleRate); static EAS_I16 ConvertSustain (EAS_I32 sustain); static EAS_I16 ConvertLFOPhaseIncrement (EAS_I32 pitchCents); static EAS_I8 ConvertPan (EAS_I32 pan); static EAS_U8 ConvertQ (EAS_I32 q); #ifdef _DEBUG_DLS static void DumpDLS (S_EAS *pEAS); #endif /*---------------------------------------------------------------------------- * DLSParser () *---------------------------------------------------------------------------- * Purpose: * * Inputs: * pEASData - pointer to over EAS data instance * fileHandle - file handle for input file * offset - offset into file where DLS data starts * * Outputs: * EAS_RESULT * ppEAS - address of pointer to alternate EAS wavetable * *---------------------------------------------------------------------------- */ EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_DLSLIB_HANDLE *ppDLS) { EAS_RESULT result; SDLS_SYNTHESIZER_DATA dls; EAS_U32 temp; EAS_I32 pos; EAS_I32 chunkPos; EAS_I32 size; EAS_I32 instSize; EAS_I32 rgnPoolSize; EAS_I32 artPoolSize; EAS_I32 waveLenSize; EAS_I32 endDLS; EAS_I32 wvplPos; EAS_I32 wvplSize; EAS_I32 linsPos; EAS_I32 linsSize; EAS_I32 ptblPos; EAS_I32 ptblSize; void *p; /* zero counts and pointers */ EAS_HWMemSet(&dls, 0, sizeof(dls)); /* save file handle and hwInstData to save copying pointers around */ dls.hwInstData = hwInstData; dls.fileHandle = fileHandle; /* NULL return value in case of error */ *ppDLS = NULL; /* seek to start of DLS and read in RIFF tag and set processor endian flag */ if ((result = EAS_HWFileSeek(dls.hwInstData, dls.fileHandle, offset)) != EAS_SUCCESS) return result; if ((result = EAS_HWReadFile(dls.hwInstData, dls.fileHandle, &temp, sizeof(temp), &size)) != EAS_SUCCESS) return result; /* check for processor endian-ness */ dls.bigEndian = (temp == CHUNK_RIFF); /* first chunk should be DLS */ pos = offset; if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS) return result; if (temp != CHUNK_DLS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected DLS chunk, got %08lx\n", temp); */ } return EAS_ERROR_FILE_FORMAT; } /* no instrument or wavepool chunks */ linsSize = wvplSize = ptblSize = linsPos = wvplPos = ptblPos = 0; /* scan the chunks in the DLS list */ endDLS = offset + size; pos = offset + 12; while (pos < endDLS) { chunkPos = pos; /* get the next chunk type */ if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS) return result; /* parse useful chunks */ switch (temp) { case CHUNK_CDL: if ((result = Parse_cdl(&dls, size, &temp)) != EAS_SUCCESS) return result; if (!temp) return EAS_ERROR_UNRECOGNIZED_FORMAT; break; case CHUNK_LINS: linsPos = chunkPos + 12; linsSize = size - 4; break; case CHUNK_WVPL: wvplPos = chunkPos + 12; wvplSize = size - 4; break; case CHUNK_PTBL: ptblPos = chunkPos + 8; ptblSize = size - 4; break; default: break; } } /* must have a lins chunk */ if (linsSize == 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No lins chunk found"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* must have a wvpl chunk */ if (wvplSize == 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No wvpl chunk found"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* must have a ptbl chunk */ if ((ptblSize == 0) || (ptblSize > (EAS_I32) (DLS_MAX_WAVE_COUNT * sizeof(POOLCUE) + sizeof(POOLTABLE)))) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No ptbl chunk found"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* pre-parse the wave pool chunk */ if ((result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize)) != EAS_SUCCESS) return result; /* limit check */ if ((dls.waveCount == 0) || (dls.waveCount > DLS_MAX_WAVE_COUNT)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #waves [%u]\n", dls.waveCount); */ } return EAS_ERROR_FILE_FORMAT; } /* allocate memory for wsmp data */ dls.wsmpData = EAS_HWMalloc(dls.hwInstData, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount)); if (dls.wsmpData == NULL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc for wsmp data failed\n"); */ } return EAS_ERROR_MALLOC_FAILED; } EAS_HWMemSet(dls.wsmpData, 0, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount)); /* pre-parse the lins chunk */ result = Parse_lins(&dls, linsPos, linsSize); if (result == EAS_SUCCESS) { /* limit check */ if ((dls.regionCount == 0) || (dls.regionCount > DLS_MAX_REGION_COUNT)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #regions [%u]\n", dls.regionCount); */ } EAS_HWFree(dls.hwInstData, dls.wsmpData); return EAS_ERROR_FILE_FORMAT; } /* limit check */ if ((dls.artCount == 0) || (dls.artCount > DLS_MAX_ART_COUNT)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #articulations [%u]\n", dls.regionCount); */ } EAS_HWFree(dls.hwInstData, dls.wsmpData); return EAS_ERROR_FILE_FORMAT; } /* limit check */ if ((dls.instCount == 0) || (dls.instCount > DLS_MAX_INST_COUNT)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #instruments [%u]\n", dls.instCount); */ } EAS_HWFree(dls.hwInstData, dls.wsmpData); return EAS_ERROR_FILE_FORMAT; } /* Allocate memory for the converted DLS data */ /* calculate size of instrument data */ instSize = (EAS_I32) (sizeof(S_PROGRAM) * dls.instCount); /* calculate size of region pool */ rgnPoolSize = (EAS_I32) (sizeof(S_DLS_REGION) * dls.regionCount); /* calculate size of articulation pool, add one for default articulation */ dls.artCount++; artPoolSize = (EAS_I32) (sizeof(S_DLS_ARTICULATION) * dls.artCount); /* calculate size of wave length and offset arrays */ waveLenSize = (EAS_I32) (dls.waveCount * sizeof(EAS_U32)); /* calculate final memory size */ size = (EAS_I32) sizeof(S_EAS) + instSize + rgnPoolSize + artPoolSize + (2 * waveLenSize) + (EAS_I32) dls.wavePoolSize; if (size <= 0) { EAS_HWFree(dls.hwInstData, dls.wsmpData); return EAS_ERROR_FILE_FORMAT; } /* allocate the main EAS chunk */ dls.pDLS = EAS_HWMalloc(dls.hwInstData, size); if (dls.pDLS == NULL) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc failed for DLS memory allocation size %ld\n", size); */ } EAS_HWFree(dls.hwInstData, dls.wsmpData); return EAS_ERROR_MALLOC_FAILED; } EAS_HWMemSet(dls.pDLS, 0, size); dls.pDLS->refCount = 1; p = PtrOfs(dls.pDLS, sizeof(S_EAS)); /* setup pointer to programs */ dls.pDLS->numDLSPrograms = (EAS_U16) dls.instCount; dls.pDLS->pDLSPrograms = p; p = PtrOfs(p, instSize); /* setup pointer to regions */ dls.pDLS->pDLSRegions = p; dls.pDLS->numDLSRegions = (EAS_U16) dls.regionCount; p = PtrOfs(p, rgnPoolSize); /* setup pointer to articulations */ dls.pDLS->numDLSArticulations = (EAS_U16) dls.artCount; dls.pDLS->pDLSArticulations = p; p = PtrOfs(p, artPoolSize); /* setup pointer to wave length table */ dls.pDLS->numDLSSamples = (EAS_U16) dls.waveCount; dls.pDLS->pDLSSampleLen = p; p = PtrOfs(p, waveLenSize); /* setup pointer to wave offsets table */ dls.pDLS->pDLSSampleOffsets = p; p = PtrOfs(p, waveLenSize); /* setup pointer to wave pool */ dls.pDLS->pDLSSamples = p; /* clear filter flag */ dls.filterUsed = EAS_FALSE; /* parse the wave pool and load samples */ result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize); } /* create the default articulation */ if (dls.pDLS) { Convert_art(&dls, &defaultArt, 0); dls.artCount = 1; } /* parse the lins chunk and load instruments */ dls.regionCount = dls.instCount = 0; if (result == EAS_SUCCESS) result = Parse_lins(&dls, linsPos, linsSize); /* clean up any temporary objects that were allocated */ if (dls.wsmpData) EAS_HWFree(dls.hwInstData, dls.wsmpData); /* if successful, return a pointer to the EAS collection */ if (result == EAS_SUCCESS) { *ppDLS = dls.pDLS; #ifdef _DEBUG_DLS DumpDLS(dls.pDLS); #endif } /* something went wrong, deallocate the EAS collection */ else DLSCleanup(dls.hwInstData, dls.pDLS); return result; } /*---------------------------------------------------------------------------- * DLSCleanup () *---------------------------------------------------------------------------- * Purpose: * * Inputs: * pEASData - pointer to over EAS data instance * pEAS - pointer to alternate EAS wavetable * * Outputs: * EAS_RESULT * *---------------------------------------------------------------------------- */ EAS_RESULT DLSCleanup (EAS_HW_DATA_HANDLE hwInstData, S_DLS *pDLS) { /* free the allocated memory */ if (pDLS) { if (pDLS->refCount) { if (--pDLS->refCount == 0) EAS_HWFree(hwInstData, pDLS); } } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * DLSAddRef () *---------------------------------------------------------------------------- * Increment reference count *---------------------------------------------------------------------------- */ void DLSAddRef (S_DLS *pDLS) { if (pDLS) pDLS->refCount++; } /*---------------------------------------------------------------------------- * NextChunk () *---------------------------------------------------------------------------- * Purpose: * Returns the type and size of the next chunk in the file * * Inputs: * * Outputs: * * Side Effects: *---------------------------------------------------------------------------- */ static EAS_RESULT NextChunk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 *pPos, EAS_U32 *pChunkType, EAS_I32 *pSize) { EAS_RESULT result; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, *pPos)) != EAS_SUCCESS) return result; /* read the chunk type */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS) return result; /* read the chunk size */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pSize, EAS_FALSE)) != EAS_SUCCESS) return result; if (*pSize < 0) { //ALOGE("b/37093318"); return EAS_ERROR_FILE_FORMAT; } /* get form type for RIFF and LIST types */ if ((*pChunkType == CHUNK_RIFF) || (*pChunkType == CHUNK_LIST)) { /* read the form type */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS) return result; } /* calculate start of next chunk */ *pPos += *pSize + 8; /* adjust to word boundary */ if (*pPos & 1) (*pPos)++; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_ptbl () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_ptbl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 wtblPos, EAS_I32 wtblSize) { EAS_RESULT result; EAS_U32 temp; EAS_FILE_HANDLE tempFile; EAS_U16 waveIndex; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* get the structure size */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &temp, EAS_FALSE)) != EAS_SUCCESS) return result; /* get the number of waves */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSData->waveCount, EAS_FALSE)) != EAS_SUCCESS) return result; #if 0 /* just need the wave count on the first pass */ if (!pDLSData->pDLS) return EAS_SUCCESS; #endif /* open duplicate file handle */ if ((result = EAS_HWDupHandle(pDLSData->hwInstData, pDLSData->fileHandle, &tempFile)) != EAS_SUCCESS) return result; /* read to end of chunk */ for (waveIndex = 0; waveIndex < pDLSData->waveCount; waveIndex++) { /* get the offset to the wave and make sure it is within the wtbl chunk */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, tempFile, &temp, EAS_FALSE)) != EAS_SUCCESS) return result; if (temp > (EAS_U32) wtblSize) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Ptbl offset exceeds size of wtbl\n"); */ } EAS_HWCloseFile(pDLSData->hwInstData, tempFile); return EAS_ERROR_FILE_FORMAT; } /* parse the wave */ if ((result = Parse_wave(pDLSData, wtblPos +(EAS_I32) temp, waveIndex)) != EAS_SUCCESS) return result; } /* close the temporary handle and return */ EAS_HWCloseFile(pDLSData->hwInstData, tempFile); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_wave () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_wave (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U16 waveIndex) { EAS_RESULT result; EAS_U32 temp; EAS_I32 size; EAS_I32 endChunk; EAS_I32 chunkPos; EAS_I32 wsmpPos = 0; EAS_I32 fmtPos = 0; EAS_I32 dataPos = 0; EAS_I32 dataSize = 0; S_WSMP_DATA *p; void *pSample; S_WSMP_DATA wsmp; /* seek to start of chunk */ chunkPos = pos + 12; if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* get the chunk type */ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS) return result; /* make sure it is a wave chunk */ if (temp != CHUNK_WAVE) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Offset in ptbl does not point to wave chunk\n"); */ } return EAS_ERROR_FILE_FORMAT; } /* read to end of chunk */ pos = chunkPos; endChunk = pos + size; while (pos < endChunk) { chunkPos = pos; /* get the chunk type */ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS) return result; /* parse useful chunks */ switch (temp) { case CHUNK_WSMP: wsmpPos = chunkPos + 8; break; case CHUNK_FMT: fmtPos = chunkPos + 8; break; case CHUNK_DATA: dataPos = chunkPos + 8; dataSize = size; break; default: break; } } // limit to reasonable size if (dataSize < 0 || dataSize > MAX_DLS_WAVE_SIZE) { return EAS_ERROR_SOUND_LIBRARY; } /* for first pass, use temporary variable */ if (pDLSData->pDLS == NULL) p = &wsmp; else p = &pDLSData->wsmpData[waveIndex]; /* set the defaults */ p->fineTune = 0; p->unityNote = 60; p->gain = 0; p->loopStart = 0; p->loopLength = 0; /* must have a fmt chunk */ if (!fmtPos) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no fmt chunk\n"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* must have a data chunk */ if (!dataPos) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no data chunk\n"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* parse the wsmp chunk */ if (wsmpPos) { if ((result = Parse_wsmp(pDLSData, wsmpPos, p)) != EAS_SUCCESS) return result; } /* parse the fmt chunk */ if ((result = Parse_fmt(pDLSData, fmtPos, p)) != EAS_SUCCESS) return result; /* calculate the size of the wavetable needed. We need only half * the memory for 16-bit samples when in 8-bit mode, and we need * double the memory for 8-bit samples in 16-bit mode. For * unlooped samples, we may use ADPCM. If so, we need only 1/4 * the memory. * * We also need to add one for looped samples to allow for * the first sample to be copied to the end of the loop. */ /* use ADPCM encode for unlooped 16-bit samples if ADPCM is enabled */ /*lint -e{506} -e{774} groundwork for future version to support 8 & 16 bit */ if (bitDepth == 8) { if (p->bitsPerSample == 8) size = dataSize; else /*lint -e{704} use shift for performance */ size = dataSize >> 1; if (p->loopLength) size++; } else { if (p->bitsPerSample == 16) size = dataSize; else /*lint -e{703} use shift for performance */ size = dataSize << 1; if (p->loopLength) size += 2; } /* for first pass, add size to wave pool size and return */ if (pDLSData->pDLS == NULL) { pDLSData->wavePoolSize += (EAS_U32) size; return EAS_SUCCESS; } /* allocate memory and read in the sample data */ pSample = (EAS_U8*)pDLSData->pDLS->pDLSSamples + pDLSData->wavePoolOffset; pDLSData->pDLS->pDLSSampleOffsets[waveIndex] = pDLSData->wavePoolOffset; pDLSData->pDLS->pDLSSampleLen[waveIndex] = (EAS_U32) size; pDLSData->wavePoolOffset += (EAS_U32) size; if (pDLSData->wavePoolOffset > pDLSData->wavePoolSize) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Wave pool exceeded allocation\n"); */ } return EAS_ERROR_SOUND_LIBRARY; } if ((result = Parse_data(pDLSData, dataPos, dataSize, p, pSample, (EAS_U32)size)) != EAS_SUCCESS) return result; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_wsmp () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_wsmp (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p) { EAS_RESULT result; EAS_U16 wtemp; EAS_U32 ltemp; EAS_U32 cbSize; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* get structure size */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &cbSize, EAS_FALSE)) != EAS_SUCCESS) return result; /* get unity note */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS) return result; if (wtemp <= 127) p->unityNote = (EAS_U8) wtemp; else { p->unityNote = 60; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid unity note [%u] in DLS wsmp ignored, set to 60\n", wtemp); */ } } /* get fine tune */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->fineTune, EAS_FALSE)) != EAS_SUCCESS) return result; /* get gain */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->gain, EAS_FALSE)) != EAS_SUCCESS) return result; if (p->gain > 0) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Positive gain [%ld] in DLS wsmp ignored, set to 0dB\n", p->gain); */ } p->gain = 0; } /* option flags */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, <emp, EAS_FALSE)) != EAS_SUCCESS) return result; /* sample loops */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, <emp, EAS_FALSE)) != EAS_SUCCESS) return result; /* if looped sample, get loop data */ if (ltemp) { if (ltemp > 1) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS sample with %lu loops, ignoring extra loops\n", ltemp); */ } /* skip ahead to loop data */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + (EAS_I32) cbSize)) != EAS_SUCCESS) return result; /* get structure size */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, <emp, EAS_FALSE)) != EAS_SUCCESS) return result; /* get loop type */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, <emp, EAS_FALSE)) != EAS_SUCCESS) return result; /* get loop start */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopStart, EAS_FALSE)) != EAS_SUCCESS) return result; /* get loop length */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopLength, EAS_FALSE)) != EAS_SUCCESS) return result; /* ensure no overflow */ if (p->loopLength && ((p->loopStart > EAS_U32_MAX - p->loopLength) || (p->loopStart + p->loopLength > EAS_U32_MAX / sizeof(EAS_SAMPLE)))) { return EAS_FAILURE; } } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_fmt () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_fmt (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p) { EAS_RESULT result; EAS_U16 wtemp; EAS_U32 ltemp; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* get format tag */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS) return result; if (wtemp != WAVE_FORMAT_PCM) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS sample format %04x\n", wtemp); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* get number of channels */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS) return result; if (wtemp != 1) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No support for DLS multi-channel samples\n"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* get sample rate */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->sampleRate, EAS_FALSE)) != EAS_SUCCESS) return result; /* bytes/sec */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, <emp, EAS_FALSE)) != EAS_SUCCESS) return result; /* block align */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS) return result; /* bits/sample */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->bitsPerSample, EAS_FALSE)) != EAS_SUCCESS) return result; if ((p->bitsPerSample != 8) && (p->bitsPerSample != 16)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS bits-per-sample %d\n", p->bitsPerSample); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } return EAS_SUCCESS; } #if defined( _8_BIT_SAMPLES) /*---------------------------------------------------------------------------- * Parse_data () *---------------------------------------------------------------------------- * Purpose: * * NOTE: The optimized assembly versions of the interpolator require * an extra sample at the end of the loop - a copy of the first * sample. This routine must allocate an extra sample of data and * copy the first sample of the loop to the end. * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_WSMP_DATA *pWsmp, EAS_SAMPLE *pSample, EAS_U32 sampleLen) { EAS_RESULT result; EAS_U8 convBuf[SAMPLE_CONVERT_CHUNK_SIZE]; EAS_I32 count; EAS_I32 i; EAS_I8 *p; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* 8-bit samples in an 8-bit synth, just copy the data, and flip bit 7 */ p = pSample; if (pWsmp->bitsPerSample == 8) { if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pSample, size, &count)) != EAS_SUCCESS) return result; for (i = 0; i < size; i++) /*lint -e{734} convert from unsigned to signed audio */ *p++ ^= 0x80; } /* 16-bit samples, need to convert to 8-bit or ADPCM */ else { while (size) { EAS_I8 *pInput; /* for undithered conversion, we're just copying the 8-bit data */ if (pDLSData->bigEndian) pInput = (EAS_I8*) convBuf; else pInput = (EAS_I8*) convBuf + 1; /* read a small chunk of data and convert it */ count = (size < SAMPLE_CONVERT_CHUNK_SIZE ? size : SAMPLE_CONVERT_CHUNK_SIZE); if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, convBuf, count, &count)) != EAS_SUCCESS) return result; size -= count; /*lint -e{704} use shift for performance */ count = count >> 1; while (count--) { *p++ = *pInput; pInput += 2; } } } /* for looped samples, copy the last sample to the end */ if (pWsmp->loopLength) { if (sampleLen < sizeof(EAS_SAMPLE) || (pWsmp->loopStart + pWsmp->loopLength) * sizeof(EAS_SAMPLE) > sampleLen - sizeof(EAS_SAMPLE)) { return EAS_FAILURE; } pSample[pWsmp->loopStart + pWsmp->loopLength] = pSample[pWsmp->loopStart]; } return EAS_SUCCESS; } #elif defined(_16_BIT_SAMPLES) static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_WSMP_DATA *pWsmp, EAS_SAMPLE *pSample, EAS_U32 sampleLen) { EAS_RESULT result; EAS_U8 convBuf[SAMPLE_CONVERT_CHUNK_SIZE]; EAS_I32 count = 0; EAS_I32 i; EAS_I16 *p; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; p = pSample; while (size) { /* read a small chunk of data and convert it */ count = (size < SAMPLE_CONVERT_CHUNK_SIZE ? size : SAMPLE_CONVERT_CHUNK_SIZE); if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, convBuf, count, &count)) != EAS_SUCCESS) { return result; } size -= count; if (pWsmp->bitsPerSample == 16) { memcpy(p, convBuf, count); p += count >> 1; } else { for(i=0; iloopLength) { if( (pDLSData->wavePoolOffset + pWsmp->loopLength) >= pDLSData->wavePoolSize ) { return EAS_SUCCESS; } pSample[(pWsmp->loopStart + pWsmp->loopLength)>>1] = pSample[(pWsmp->loopStart)>>1]; } return EAS_SUCCESS; } #else #error "Must specifiy _8_BIT_SAMPLES or _16_BIT_SAMPLES" #endif /*---------------------------------------------------------------------------- * Parse_lins () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_lins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size) { EAS_RESULT result; EAS_U32 temp; EAS_I32 endChunk; EAS_I32 chunkPos; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* read to end of chunk */ endChunk = pos + size; while (pos < endChunk) { chunkPos = pos; /* get the next chunk type */ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS) return result; /* only instrument chunks are useful */ if (temp != CHUNK_INS) continue; if ((result = Parse_ins(pDLSData, chunkPos + 12, size)) != EAS_SUCCESS) return result; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_ins () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_ins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size) { EAS_RESULT result; EAS_U32 temp; EAS_I32 chunkPos; EAS_I32 endChunk; EAS_I32 lrgnPos; EAS_I32 lrgnSize; EAS_I32 lartPos; EAS_I32 lartSize; EAS_I32 lar2Pos; EAS_I32 lar2Size; EAS_I32 inshPos; EAS_U32 regionCount; EAS_U32 locale; S_DLS_ART_VALUES art; S_PROGRAM *pProgram; EAS_U16 artIndex; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* no chunks yet */ lrgnPos = lrgnSize = lartPos = lartSize = lar2Pos = lar2Size = inshPos = artIndex = 0; /* read to end of chunk */ endChunk = pos + size; while (pos < endChunk) { chunkPos = pos; /* get the next chunk type */ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS) return result; /* parse useful chunks */ switch (temp) { case CHUNK_INSH: inshPos = chunkPos + 8; break; case CHUNK_LART: lartPos = chunkPos + 12; lartSize = size; break; case CHUNK_LAR2: lar2Pos = chunkPos + 12; lar2Size = size; break; case CHUNK_LRGN: lrgnPos = chunkPos + 12; lrgnSize = size; break; default: break; } } /* must have an lrgn to be useful */ if (!lrgnPos) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no lrgn chunk\n"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* must have an insh to be useful */ if (!inshPos) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no insh chunk\n"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* parse the instrument header */ if ((result = Parse_insh(pDLSData, inshPos, ®ionCount, &locale)) != EAS_SUCCESS) return result; /* initialize and parse the global data first */ EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES)); if (lartPos) if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS) return result; if (lar2Pos) if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS) return result; if (art.values[PARAM_MODIFIED]) { artIndex = (EAS_U16) pDLSData->artCount; pDLSData->artCount++; } /* convert data on second pass */ if (pDLSData->pDLS) { if (art.values[PARAM_MODIFIED]) Convert_art(pDLSData, &art, artIndex); /* setup pointers */ pProgram = &pDLSData->pDLS->pDLSPrograms[pDLSData->instCount]; /* initialize instrument */ pProgram->locale = locale; pProgram->regionIndex = (EAS_U16) pDLSData->regionCount | FLAG_RGN_IDX_DLS_SYNTH; } /* parse the region data */ if ((result = Parse_lrgn(pDLSData, lrgnPos, lrgnSize, artIndex, regionCount)) != EAS_SUCCESS) return result; /* bump instrument count */ pDLSData->instCount++; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_insh () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_insh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pRgnCount, EAS_U32 *pLocale) { EAS_RESULT result; EAS_U32 bank; EAS_U32 program; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* get the region count and locale */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pRgnCount, EAS_FALSE)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &bank, EAS_FALSE)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &program, EAS_FALSE)) != EAS_SUCCESS) return result; /* verify the parameters are valid */ if (bank & 0x7fff8080) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS bank number is out of range: %08lx\n", bank); */ } bank &= 0xff7f; } if (program > 127) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS program number is out of range: %08lx\n", program); */ } program &= 0x7f; } /* save the program number */ *pLocale = (bank << 8) | program; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_lrgn () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_lrgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex, EAS_U32 numRegions) { EAS_RESULT result; EAS_U32 temp; EAS_I32 chunkPos; EAS_I32 endChunk; EAS_U16 regionCount; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* read to end of chunk */ regionCount = 0; endChunk = pos + size; while (pos < endChunk) { chunkPos = pos; /* get the next chunk type */ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS) return result; if ((temp == CHUNK_RGN) || (temp == CHUNK_RGN2)) { if (regionCount == numRegions) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS region count exceeded cRegions value in insh, extra region ignored\n"); */ } return EAS_SUCCESS; } if ((result = Parse_rgn(pDLSData, chunkPos + 12, size, artIndex)) != EAS_SUCCESS) return result; regionCount++; } } /* set a flag in the last region */ if ((pDLSData->pDLS != NULL) && (regionCount > 0)) pDLSData->pDLS->pDLSRegions[pDLSData->regionCount - 1].wtRegion.region.keyGroupAndFlags |= REGION_FLAG_LAST_REGION; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_rgn () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex) { EAS_RESULT result; EAS_U32 temp; EAS_I32 chunkPos; EAS_I32 endChunk; EAS_I32 rgnhPos; EAS_I32 lartPos; EAS_I32 lartSize; EAS_I32 lar2Pos; EAS_I32 lar2Size; EAS_I32 wlnkPos; EAS_I32 wsmpPos; EAS_U32 waveIndex; S_DLS_ART_VALUES art; S_WSMP_DATA wsmp; S_WSMP_DATA *pWsmp; EAS_U16 regionIndex; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* no chunks found yet */ rgnhPos = lartPos = lartSize = lar2Pos = lar2Size = wsmpPos = wlnkPos = 0; regionIndex = (EAS_U16) pDLSData->regionCount; /* read to end of chunk */ endChunk = pos + size; while (pos < endChunk) { chunkPos = pos; /* get the next chunk type */ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS) return result; /* parse useful chunks */ switch (temp) { case CHUNK_CDL: if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS) return result; /* if conditional chunk evaluates false, skip this list */ if (!temp) return EAS_SUCCESS; break; case CHUNK_RGNH: rgnhPos = chunkPos + 8; break; case CHUNK_WLNK: wlnkPos = chunkPos + 8; break; case CHUNK_WSMP: wsmpPos = chunkPos + 8; break; case CHUNK_LART: lartPos = chunkPos + 12; lartSize = size; break; case CHUNK_LAR2: lar2Pos = chunkPos + 12; lar2Size = size; break; default: break; } } /* must have a rgnh chunk to be useful */ if (!rgnhPos) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no rgnh chunk\n"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* must have a wlnk chunk to be useful */ if (!wlnkPos) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no wlnk chunk\n"); */ } return EAS_ERROR_UNRECOGNIZED_FORMAT; } /* parse wlnk chunk */ if ((result = Parse_wlnk(pDLSData, wlnkPos, &waveIndex)) != EAS_SUCCESS) return result; if (waveIndex >= pDLSData->waveCount) { return EAS_FAILURE; } pWsmp = &pDLSData->wsmpData[waveIndex]; /* if there is any articulation data, parse it */ EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES)); if (lartPos) { if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS) return result; } if (lar2Pos) { if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS) return result; } /* if second pass, process region header */ if (pDLSData->pDLS) { /* if local data was found convert it */ if (art.values[PARAM_MODIFIED] == EAS_TRUE) { Convert_art(pDLSData, &art, (EAS_U16) pDLSData->artCount); artIndex = (EAS_U16) pDLSData->artCount; } /* parse region header */ if ((result = Parse_rgnh(pDLSData, rgnhPos, &pDLSData->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK])) != EAS_SUCCESS) return result; /* parse wsmp chunk, copying parameters from original first */ if (wsmpPos) { EAS_HWMemCpy(&wsmp, pWsmp, sizeof(wsmp)); if ((result = Parse_wsmp(pDLSData, wsmpPos, &wsmp)) != EAS_SUCCESS) return result; pWsmp = &wsmp; } Convert_rgn(pDLSData, regionIndex, artIndex, (EAS_U16) waveIndex, pWsmp); /* ensure loopStart and loopEnd fall in the range */ if (pWsmp->loopLength != 0) { EAS_U32 sampleLen = pDLSData->pDLS->pDLSSampleLen[waveIndex]; if (sampleLen < sizeof(EAS_SAMPLE) || (pWsmp->loopStart + pWsmp->loopLength) * sizeof(EAS_SAMPLE) > sampleLen - sizeof(EAS_SAMPLE)) { return EAS_FAILURE; } } } /* if local articulation, bump count */ if (art.values[PARAM_MODIFIED]) pDLSData->artCount++; /* increment region count */ pDLSData->regionCount++; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_rgnh () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_rgnh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_REGION *pRgn) { EAS_RESULT result; EAS_U16 lowKey; EAS_U16 highKey; EAS_U16 lowVel; EAS_U16 highVel; EAS_U16 optionFlags; EAS_U16 keyGroup; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* get the key range */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowKey, EAS_FALSE)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highKey, EAS_FALSE)) != EAS_SUCCESS) return result; /* check the range */ if (lowKey > 127) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low key out of range [%u]\n", lowKey); */ } lowKey = 127; } if (highKey > 127) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High key out of range [%u]\n", lowKey); */ } highKey = 127; } /* get the velocity range */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowVel, EAS_FALSE)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highVel, EAS_FALSE)) != EAS_SUCCESS) return result; /* check the range */ if (lowVel > 127) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low velocity out of range [%u]\n", lowVel); */ } lowVel = 127; } if (highVel > 127) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High velocity out of range [%u]\n", highVel); */ } highVel = 127; } /* get the option flags */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &optionFlags, EAS_FALSE)) != EAS_SUCCESS) return result; /* get the key group */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &keyGroup, EAS_FALSE)) != EAS_SUCCESS) return result; /* save the key range and key group */ pRgn->wtRegion.region.rangeLow = (EAS_U8) lowKey; pRgn->wtRegion.region.rangeHigh = (EAS_U8) highKey; /*lint -e{734} keyGroup will always be from 0-15 */ pRgn->wtRegion.region.keyGroupAndFlags = keyGroup << 8; pRgn->velLow = (EAS_U8) lowVel; pRgn->velHigh = (EAS_U8) highVel; if (optionFlags & F_RGN_OPTION_SELFNONEXCLUSIVE) pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_NON_SELF_EXCLUSIVE; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_lart () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_lart (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_DLS_ART_VALUES *pArt) { EAS_RESULT result; EAS_U32 temp; EAS_I32 endChunk; EAS_I32 chunkPos; EAS_I32 art1Pos; EAS_I32 art2Pos; /* seek to start of chunk */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* no articulation chunks yet */ art1Pos = art2Pos = 0; /* read to end of chunk */ endChunk = pos + size; while (pos < endChunk) { chunkPos = pos; /* get the next chunk type */ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS) return result; /* parse useful chunks */ switch (temp) { case CHUNK_CDL: if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS) return result; /* if conditional chunk evaluates false, skip this list */ if (!temp) return EAS_SUCCESS; break; case CHUNK_ART1: art1Pos = chunkPos + 8; break; case CHUNK_ART2: art2Pos = chunkPos + 8; break; default: break; } } if (art1Pos) { if ((result = Parse_art(pDLSData, art1Pos, pArt)) != EAS_SUCCESS) return result; } if (art2Pos) { if ((result = Parse_art(pDLSData, art2Pos, pArt)) != EAS_SUCCESS) return result; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_art() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_art (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_ART_VALUES *pArt) { EAS_RESULT result; EAS_U32 structSize; EAS_U32 numConnections; EAS_U16 source; EAS_U16 control; EAS_U16 destination; EAS_U16 transform; EAS_I32 scale; EAS_INT i; /* seek to start of data */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; /* get the structure size */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &structSize, EAS_FALSE)) != EAS_SUCCESS) return result; pos += (EAS_I32) structSize; /* get the number of connections */ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &numConnections, EAS_FALSE)) != EAS_SUCCESS) return result; /* skip to start of connections */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS) return result; while (numConnections--) { /* read the connection data */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &source, EAS_FALSE)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &control, EAS_FALSE)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &destination, EAS_FALSE)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &transform, EAS_FALSE)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &scale, EAS_FALSE)) != EAS_SUCCESS) return result; /* look up the connection */ for (i = 0; i < (EAS_INT) ENTRIES_IN_CONN_TABLE; i++) { if ((connTable[i].source == source) && (connTable[i].destination == destination) && (connTable[i].control == control)) { /*lint -e{704} use shift for performance */ pArt->values[connTable[i].connection] = (EAS_I16) (scale >> 16); pArt->values[PARAM_MODIFIED] = EAS_TRUE; break; } } if (i == PARAM_TABLE_SIZE) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "WARN: Unsupported parameter in DLS file\n"); */ } } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * Parse_wlnk () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_wlnk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pWaveIndex) { EAS_RESULT result; /* we only care about the the index */ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + 8)) != EAS_SUCCESS) return result; /* read the index */ return EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle,pWaveIndex, EAS_FALSE); } /*---------------------------------------------------------------------------- * PopcdlStack () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT PopcdlStack (EAS_U32 *pStack, EAS_INT *pStackPtr, EAS_U32 *pValue) { /* stack underflow, cdl block has an errorr */ if (*pStackPtr < 0) return EAS_ERROR_FILE_FORMAT; /* pop the value off the stack */ *pValue = pStack[*pStackPtr]; *pStackPtr = *pStackPtr - 1; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * PushcdlStack () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT PushcdlStack (EAS_U32 *pStack, EAS_INT *pStackPtr, EAS_U32 value) { /* stack overflow, return an error */ if (*pStackPtr >= (CDL_STACK_SIZE - 1)) { //ALOGE("b/34031018, stackPtr(%d)", *pStackPtr); //android_errorWriteLog(0x534e4554, "34031018"); return EAS_ERROR_FILE_FORMAT; } /* push the value onto the stack */ *pStackPtr = *pStackPtr + 1; pStack[*pStackPtr] = value; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * QueryGUID () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_BOOL QueryGUID (const DLSID *pGUID, EAS_U32 *pValue) { /* assume false */ *pValue = 0; if (EAS_HWMemCmp(&DLSID_GMInHardware, pGUID, sizeof(DLSID)) == 0) { *pValue = 0xffffffff; return EAS_TRUE; } if (EAS_HWMemCmp(&DLSID_GSInHardware, pGUID, sizeof(DLSID)) == 0) return EAS_TRUE; if (EAS_HWMemCmp(&DLSID_XGInHardware, pGUID, sizeof(DLSID)) == 0) return EAS_TRUE; if (EAS_HWMemCmp(&DLSID_SupportsDLS1, pGUID, sizeof(DLSID)) == 0) { *pValue = 0xffffffff; return EAS_TRUE; } if (EAS_HWMemCmp(&DLSID_SupportsDLS2, pGUID, sizeof(DLSID)) == 0) return EAS_TRUE; if (EAS_HWMemCmp(&DLSID_SampleMemorySize, pGUID, sizeof(DLSID)) == 0) { *pValue = MAX_DLS_MEMORY; return EAS_TRUE; } if (EAS_HWMemCmp(&DLSID_ManufacturersID, pGUID, sizeof(DLSID)) == 0) { *pValue = 0x0000013A; return EAS_TRUE; } if (EAS_HWMemCmp(&DLSID_ProductID, pGUID, sizeof(DLSID)) == 0) { *pValue = LIB_VERSION; return EAS_TRUE; } if (EAS_HWMemCmp(&DLSID_SamplePlaybackRate, pGUID, sizeof(DLSID)) == 0) { *pValue = (EAS_U32) outputSampleRate; return EAS_TRUE; } /* unrecognized DLSID */ return EAS_FALSE; } /*---------------------------------------------------------------------------- * ReadDLSID () *---------------------------------------------------------------------------- * Purpose: * Reads a DLSID in a manner that is not sensitive to processor endian-ness * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT ReadDLSID (SDLS_SYNTHESIZER_DATA *pDLSData, DLSID *pDLSID) { EAS_RESULT result; EAS_I32 n; if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data1, EAS_FALSE)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data2, EAS_FALSE)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data3, EAS_FALSE)) != EAS_SUCCESS) return result; return EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pDLSID->Data4, sizeof(pDLSID->Data4), &n); } /*---------------------------------------------------------------------------- * Parse_cdl () *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static EAS_RESULT Parse_cdl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 size, EAS_U32 *pValue) { EAS_RESULT result; EAS_U32 stack[CDL_STACK_SIZE]; EAS_U16 opcode; EAS_INT stackPtr; EAS_U32 x, y; DLSID dlsid; stackPtr = -1; *pValue = 0; x = 0; while (size) { /* read the opcode */ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &opcode, EAS_FALSE)) != EAS_SUCCESS) return result; /* handle binary opcodes */ if (opcode <= DLS_CDL_EQ) { /* pop X and Y */ if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS) return result; if ((result = PopcdlStack(stack, &stackPtr, &y)) != EAS_SUCCESS) return result; switch (opcode) { case DLS_CDL_AND: x = x & y; break; case DLS_CDL_OR: x = x | y; break; case DLS_CDL_XOR: x = x ^ y; break; case DLS_CDL_ADD: x = x + y; break; case DLS_CDL_SUBTRACT: x = x - y; break; case DLS_CDL_MULTIPLY: x = x * y; break; case DLS_CDL_DIVIDE: if (!y) return EAS_ERROR_FILE_FORMAT; x = x / y; break; case DLS_CDL_LOGICAL_AND: x = (x && y); break; case DLS_CDL_LOGICAL_OR: x = (x || y); break; case DLS_CDL_LT: x = (x < y); break; case DLS_CDL_LE: x = (x <= y); break; case DLS_CDL_GT: x = (x > y); break; case DLS_CDL_GE: x = (x >= y); break; case DLS_CDL_EQ: x = (x == y); break; default: break; } } else if (opcode == DLS_CDL_NOT) { if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS) return result; x = !x; } else if (opcode == DLS_CDL_CONST) { if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &x, EAS_FALSE)) != EAS_SUCCESS) return result; } else if (opcode == DLS_CDL_QUERY) { if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS) return result; QueryGUID(&dlsid, &x); } else if (opcode == DLS_CDL_QUERYSUPPORTED) { if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS) return result; x = QueryGUID(&dlsid, &y); } else { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported opcode %d in DLS file\n", opcode); */ } /* push the result on the stack */ if ((result = PushcdlStack(stack, &stackPtr, x)) != EAS_SUCCESS) return result; } /* pop the last result off the stack */ return PopcdlStack(stack, &stackPtr, pValue); } /*---------------------------------------------------------------------------- * Convert_rgn() *---------------------------------------------------------------------------- * Purpose: * Convert region data from DLS to EAS * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static void Convert_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_U16 regionIndex, EAS_U16 artIndex, EAS_U16 waveIndex, S_WSMP_DATA *pWsmp) { S_DLS_REGION *pRgn; /* setup pointers to data structures */ pRgn = &pDLSData->pDLS->pDLSRegions[regionIndex]; /* intiailize indices */ pRgn->wtRegion.artIndex = artIndex; pRgn->wtRegion.waveIndex = waveIndex; /* convert region data */ /*lint -e{704} use shift for performance */ pRgn->wtRegion.gain = (EAS_I16) (pWsmp->gain >> 16); pRgn->wtRegion.loopStart = pWsmp->loopStart; pRgn->wtRegion.loopEnd = (pWsmp->loopStart + pWsmp->loopLength); pRgn->wtRegion.tuning = pWsmp->fineTune -(pWsmp->unityNote * 100) + ConvertSampleRate(pWsmp->sampleRate); if (pWsmp->loopLength != 0) pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_IS_LOOPED; } /*---------------------------------------------------------------------------- * Convert_art() *---------------------------------------------------------------------------- * Purpose: * Convert articulation data from DLS to EAS * * Inputs: * * * Outputs: * * *---------------------------------------------------------------------------- */ static void Convert_art (SDLS_SYNTHESIZER_DATA *pDLSData, const S_DLS_ART_VALUES *pDLSArt, EAS_U16 artIndex) { S_DLS_ARTICULATION *pArt; /* setup pointers to data structures */ pArt = &pDLSData->pDLS->pDLSArticulations[artIndex]; /* LFO parameters */ pArt->modLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_MOD_LFO_FREQ]); pArt->modLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_MOD_LFO_DELAY]); pArt->vibLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_VIB_LFO_FREQ]); pArt->vibLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_VIB_LFO_DELAY]); /* EG1 parameters */ pArt->eg1.delayTime = ConvertDelay(pDLSArt->values[PARAM_VOL_EG_DELAY]); pArt->eg1.attackTime = pDLSArt->values[PARAM_VOL_EG_ATTACK]; pArt->eg1.holdTime = pDLSArt->values[PARAM_VOL_EG_HOLD]; pArt->eg1.decayTime = pDLSArt->values[PARAM_VOL_EG_DECAY]; pArt->eg1.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_VOL_EG_SUSTAIN]); pArt->eg1.releaseTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_RELEASE]); pArt->eg1.velToAttack = pDLSArt->values[PARAM_VOL_EG_VEL_TO_ATTACK]; pArt->eg1.keyNumToDecay = pDLSArt->values[PARAM_VOL_EG_KEY_TO_DECAY]; pArt->eg1.keyNumToHold = pDLSArt->values[PARAM_VOL_EG_KEY_TO_HOLD]; pArt->eg1ShutdownTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_SHUTDOWN]); /* EG2 parameters */ pArt->eg2.delayTime = ConvertDelay(pDLSArt->values[PARAM_MOD_EG_DELAY]); pArt->eg2.attackTime = pDLSArt->values[PARAM_MOD_EG_ATTACK]; pArt->eg2.holdTime = pDLSArt->values[PARAM_MOD_EG_HOLD]; pArt->eg2.decayTime = pDLSArt->values[PARAM_MOD_EG_DECAY]; pArt->eg2.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_MOD_EG_SUSTAIN]); pArt->eg2.releaseTime = ConvertRate(pDLSArt->values[PARAM_MOD_EG_RELEASE]); pArt->eg2.velToAttack = pDLSArt->values[PARAM_MOD_EG_VEL_TO_ATTACK]; pArt->eg2.keyNumToDecay = pDLSArt->values[PARAM_MOD_EG_KEY_TO_DECAY]; pArt->eg2.keyNumToHold = pDLSArt->values[PARAM_MOD_EG_KEY_TO_HOLD]; /* filter parameters */ pArt->filterCutoff = pDLSArt->values[PARAM_INITIAL_FC]; pArt->filterQandFlags = ConvertQ(pDLSArt->values[PARAM_INITIAL_Q]); pArt->modLFOToFc = pDLSArt->values[PARAM_MOD_LFO_TO_FC]; pArt->modLFOCC1ToFc = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_FC]; pArt->modLFOChanPressToFc = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_FC]; pArt->eg2ToFc = pDLSArt->values[PARAM_MOD_EG_TO_FC]; pArt->velToFc = pDLSArt->values[PARAM_VEL_TO_FC]; pArt->keyNumToFc = pDLSArt->values[PARAM_KEYNUM_TO_FC]; /* gain parameters */ pArt->modLFOToGain = pDLSArt->values[PARAM_MOD_LFO_TO_GAIN]; pArt->modLFOCC1ToGain = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_GAIN]; pArt->modLFOChanPressToGain = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN]; /* pitch parameters */ pArt->tuning = pDLSArt->values[PARAM_TUNING]; pArt->keyNumToPitch = pDLSArt->values[PARAM_KEYNUM_TO_PITCH]; pArt->vibLFOToPitch = pDLSArt->values[PARAM_VIB_LFO_TO_PITCH]; pArt->vibLFOCC1ToPitch = pDLSArt->values[PARAM_VIB_LFO_CC1_TO_PITCH]; pArt->vibLFOChanPressToPitch = pDLSArt->values[PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH]; pArt->modLFOToPitch = pDLSArt->values[PARAM_MOD_LFO_TO_PITCH]; pArt->modLFOCC1ToPitch = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_PITCH]; pArt->modLFOChanPressToPitch = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH]; pArt->eg2ToPitch = pDLSArt->values[PARAM_MOD_EG_TO_PITCH]; /* output parameters */ pArt->pan = ConvertPan(pDLSArt->values[PARAM_DEFAULT_PAN]); if (pDLSArt->values[PARAM_VEL_TO_GAIN] != 0) pArt->filterQandFlags |= FLAG_DLS_VELOCITY_SENSITIVE; #ifdef _REVERB pArt->reverbSend = pDLSArt->values[PARAM_DEFAULT_REVERB_SEND]; pArt->cc91ToReverbSend = pDLSArt->values[PARAM_MIDI_CC91_TO_REVERB_SEND]; #endif #ifdef _CHORUS pArt->chorusSend = pDLSArt->values[PARAM_DEFAULT_CHORUS_SEND]; pArt->cc93ToChorusSend = pDLSArt->values[PARAM_MIDI_CC93_TO_CHORUS_SEND]; #endif } /*---------------------------------------------------------------------------- * ConvertSampleRate() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * * Outputs: * * Side Effects: *---------------------------------------------------------------------------- */ static EAS_I16 ConvertSampleRate (EAS_U32 sampleRate) { return (EAS_I16) (1200.0 * log10((double) sampleRate / (double) outputSampleRate) / log10(2.0)); } /*---------------------------------------------------------------------------- * ConvertSustainEG2() *---------------------------------------------------------------------------- * Convert sustain level to pitch/Fc multipler for EG2 *---------------------------------------------------------------------------- */ static EAS_I16 ConvertSustain (EAS_I32 sustain) { /* check for sustain level of zero */ if (sustain == 0) return 0; /* convert to log2 factor */ /*lint -e{704} use shift for performance */ sustain = (sustain * SUSTAIN_LINEAR_CONVERSION_FACTOR) >> 15; if (sustain > SYNTH_FULL_SCALE_EG1_GAIN) return SYNTH_FULL_SCALE_EG1_GAIN; return (EAS_I16) sustain; } /*---------------------------------------------------------------------------- * ConvertDelay () *---------------------------------------------------------------------------- * Converts timecents to frame count. Used for LFO and envelope * delay times. *---------------------------------------------------------------------------- */ EAS_I16 ConvertDelay (EAS_I32 timeCents) { EAS_I32 temp; if (timeCents == ZERO_TIME_IN_CENTS) return 0; /* divide time by secs per frame to get number of frames */ temp = timeCents - dlsRateConvert; /* convert from time cents to 10-bit fraction */ temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2); /* convert to frame count */ temp = EAS_LogToLinear16(temp - (15 << 10)); if (temp < SYNTH_FULL_SCALE_EG1_GAIN) return (EAS_I16) temp; return SYNTH_FULL_SCALE_EG1_GAIN; } /*---------------------------------------------------------------------------- * ConvertRate () *---------------------------------------------------------------------------- * Convert timecents to rate *---------------------------------------------------------------------------- */ EAS_I16 ConvertRate (EAS_I32 timeCents) { EAS_I32 temp; if (timeCents == ZERO_TIME_IN_CENTS) return SYNTH_FULL_SCALE_EG1_GAIN; /* divide frame rate by time in log domain to get rate */ temp = dlsRateConvert - timeCents; #if 1 temp = EAS_Calculate2toX(temp); #else /* convert from time cents to 10-bit fraction */ temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2); /* convert to rate */ temp = EAS_LogToLinear16(temp); #endif if (temp < SYNTH_FULL_SCALE_EG1_GAIN) return (EAS_I16) temp; return SYNTH_FULL_SCALE_EG1_GAIN; } /*---------------------------------------------------------------------------- * ConvertLFOPhaseIncrement() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * * Outputs: * * Side Effects: *---------------------------------------------------------------------------- */ static EAS_I16 ConvertLFOPhaseIncrement (EAS_I32 pitchCents) { /* check range */ if (pitchCents > MAX_LFO_FREQUENCY_IN_PITCHCENTS) pitchCents = MAX_LFO_FREQUENCY_IN_PITCHCENTS; if (pitchCents < MIN_LFO_FREQUENCY_IN_PITCHCENTS) pitchCents = MIN_LFO_FREQUENCY_IN_PITCHCENTS; /* double the rate and divide by frame rate by subtracting in log domain */ pitchCents = pitchCents - dlsLFOFrequencyConvert; /* convert to phase increment */ return (EAS_I16) EAS_Calculate2toX(pitchCents); } /*---------------------------------------------------------------------------- * ConvertPan() *---------------------------------------------------------------------------- * Purpose: * * Inputs: * * Outputs: * * Side Effects: *---------------------------------------------------------------------------- */ static EAS_I8 ConvertPan (EAS_I32 pan) { /* multiply by conversion factor */ pan = FMUL_15x15 (PAN_CONVERSION_FACTOR, pan); if (pan < MIN_PAN_VALUE) return MIN_PAN_VALUE; if (pan > MAX_PAN_VALUE) return MAX_PAN_VALUE; return (EAS_I8) pan; } /*---------------------------------------------------------------------------- * ConvertQ() *---------------------------------------------------------------------------- * Convert the DLS filter resonance to an index value used by the synth * that accesses tables of coefficients based on the Q. *---------------------------------------------------------------------------- */ static EAS_U8 ConvertQ (EAS_I32 q) { /* apply limits */ if (q <= 0) return 0; /* convert to table index */ /*lint -e{704} use shift for performance */ q = (FILTER_Q_CONVERSION_FACTOR * q + 0x4000) >> 15; /* apply upper limit */ if (q >= FILTER_RESONANCE_NUM_ENTRIES) q = FILTER_RESONANCE_NUM_ENTRIES - 1; return (EAS_U8) q; } #ifdef _DEBUG_DLS /*---------------------------------------------------------------------------- * DumpDLS() *---------------------------------------------------------------------------- */ static void DumpDLS (S_EAS *pEAS) { S_DLS_ARTICULATION *pArt; S_DLS_REGION *pRegion; EAS_INT i; EAS_INT j; EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000022 , pEAS->numPrograms); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000023 , pEAS->numWTRegions); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000024 , pEAS->numDLSArticulations); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000025 , pEAS->numSamples); /* dump the instruments */ for (i = 0; i < pEAS->numPrograms; i++) { EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000026 , pEAS->pPrograms[i].locale >> 16, (pEAS->pPrograms[i].locale >> 8) & 0x7f, pEAS->pPrograms[i].locale & 0x7f); for (j = pEAS->pPrograms[i].regionIndex; ; j++) { EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000027 , j); pRegion = &pEAS->pWTRegions[j]; EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000028 , pRegion->gain); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000029 , pRegion->region.rangeLow, pRegion->region.rangeHigh); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002a , pRegion->region.keyGroupAndFlags); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002b , pRegion->loopStart); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002c , pRegion->loopEnd); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002d , pRegion->tuning); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002e , pRegion->artIndex); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002f , pRegion->waveIndex); if (pRegion->region.keyGroupAndFlags & REGION_FLAG_LAST_REGION) break; } } /* dump the articulation data */ for (i = 0; i < pEAS->numDLSArticulations; i++) { /* articulation data */ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000030 , i); pArt = &pEAS->pDLSArticulations[i]; EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000031 , pArt->m_nEG2toFilterDepth); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000032 , pArt->m_nEG2toPitchDepth); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000033 , pArt->m_nFilterCutoffFrequency); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000034 , pArt->m_nFilterResonance); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000035 , pArt->m_nLFOAmplitudeDepth); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000036 , pArt->m_nLFODelayTime); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000037 , pArt->m_nLFOFrequency); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000038 , pArt->m_nLFOPitchDepth); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000039 , pArt->m_nPan); /* EG1 data */ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003a , pArt->m_sEG1.m_nAttack); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003b , pArt->m_sEG1.m_nDecay); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003c , pArt->m_sEG1.m_nSustain); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003d , pArt->m_sEG1.m_nRelease); /* EG2 data */ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003e , pArt->m_sEG2.m_nAttack); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003f , pArt->m_sEG2.m_nDecay); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000040 , pArt->m_sEG2.m_nSustain); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000041 , pArt->m_sEG2.m_nRelease); } /* dump the waves */ for (i = 0; i < pEAS->numSamples; i++) { EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000042 , i); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000043 , pEAS->pSampleLen[i]); EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000044 , pEAS->ppSamples[i]); } } #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_sndlib.h0000644000000000000000000000013214200302440026355 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_sndlib.h0000644000175000001440000003104614200302440027142 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_sndlib.h * * Contents and purpose: * Declarations for the sound library * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 550 $ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_SNDLIB_H #define _EAS_SNDLIB_H #include "eas_types.h" #include "eas_synthcfg.h" #ifdef _WT_SYNTH #include "eas_wtengine.h" #endif /*---------------------------------------------------------------------------- * This is bit of a hack to allow us to keep the same structure * declarations for the DLS parser. Normally, the data is located * in read-only memory, but for DLS, we store the data in RW * memory. *---------------------------------------------------------------------------- */ #ifndef SCNST #define SCNST const #endif /*---------------------------------------------------------------------------- * sample size *---------------------------------------------------------------------------- */ #ifdef _16_BIT_SAMPLES typedef EAS_I16 EAS_SAMPLE; #else typedef EAS_I8 EAS_SAMPLE; #endif /*---------------------------------------------------------------------------- * EAS Library ID - quick check for valid library and version *---------------------------------------------------------------------------- */ #define _EAS_LIBRARY_VERSION 0x01534145 #define NUM_PROGRAMS_IN_BANK 128 #define INVALID_REGION_INDEX 0xffff /* this bit in region index indicates that region is for secondary synth */ #define FLAG_RGN_IDX_FM_SYNTH 0x8000 #define FLAG_RGN_IDX_DLS_SYNTH 0x4000 #define REGION_INDEX_MASK 0x3fff /*---------------------------------------------------------------------------- * Generic region data structure * * This must be the first element in each region structure *---------------------------------------------------------------------------- */ typedef struct s_region_tag { EAS_U16 keyGroupAndFlags; EAS_U8 rangeLow; EAS_U8 rangeHigh; } S_REGION; /* * Bit fields for m_nKeyGroupAndFlags * Bits 0-2 are mode bits in FM synth * Bits 8-11 are the key group */ #define REGION_FLAG_IS_LOOPED 0x01 #define REGION_FLAG_USE_WAVE_GENERATOR 0x02 #define REGION_FLAG_USE_ADPCM 0x04 #define REGION_FLAG_ONE_SHOT 0x08 #define REGION_FLAG_SQUARE_WAVE 0x10 #define REGION_FLAG_OFF_CHIP 0x20 #define REGION_FLAG_NON_SELF_EXCLUSIVE 0x40 #define REGION_FLAG_LAST_REGION 0x8000 /*---------------------------------------------------------------------------- * Envelope data structure *---------------------------------------------------------------------------- */ typedef struct s_envelope_tag { EAS_I16 attackTime; EAS_I16 decayTime; EAS_I16 sustainLevel; EAS_I16 releaseTime; } S_ENVELOPE; /*---------------------------------------------------------------------------- * DLS envelope data structure *---------------------------------------------------------------------------- */ typedef struct s_dls_envelope_tag { EAS_I16 delayTime; EAS_I16 attackTime; EAS_I16 holdTime; EAS_I16 decayTime; EAS_I16 sustainLevel; EAS_I16 releaseTime; EAS_I16 velToAttack; EAS_I16 keyNumToDecay; EAS_I16 keyNumToHold; } S_DLS_ENVELOPE; /*---------------------------------------------------------------------------- * LFO data structure *---------------------------------------------------------------------------- */ typedef struct s_lfo_params_tag { EAS_I16 lfoFreq; EAS_I16 lfoDelay; } S_LFO_PARAMS; /*---------------------------------------------------------------------------- * Articulation data structure *---------------------------------------------------------------------------- */ typedef struct s_articulation_tag { S_ENVELOPE eg1; S_ENVELOPE eg2; EAS_I16 lfoToPitch; EAS_I16 lfoDelay; EAS_I16 lfoFreq; EAS_I16 eg2ToPitch; EAS_I16 eg2ToFc; EAS_I16 filterCutoff; EAS_I8 lfoToGain; EAS_U8 filterQ; EAS_I8 pan; } S_ARTICULATION; /*---------------------------------------------------------------------------- * DLS articulation data structure *---------------------------------------------------------------------------- */ typedef struct s_dls_articulation_tag { S_LFO_PARAMS modLFO; S_LFO_PARAMS vibLFO; S_DLS_ENVELOPE eg1; S_DLS_ENVELOPE eg2; EAS_I16 eg1ShutdownTime; EAS_I16 filterCutoff; EAS_I16 modLFOToFc; EAS_I16 modLFOCC1ToFc; EAS_I16 modLFOChanPressToFc; EAS_I16 eg2ToFc; EAS_I16 velToFc; EAS_I16 keyNumToFc; EAS_I16 modLFOToGain; EAS_I16 modLFOCC1ToGain; EAS_I16 modLFOChanPressToGain; EAS_I16 tuning; EAS_I16 keyNumToPitch; EAS_I16 vibLFOToPitch; EAS_I16 vibLFOCC1ToPitch; EAS_I16 vibLFOChanPressToPitch; EAS_I16 modLFOToPitch; EAS_I16 modLFOCC1ToPitch; EAS_I16 modLFOChanPressToPitch; EAS_I16 eg2ToPitch; /* pad to 4-byte boundary */ EAS_U16 pad; EAS_I8 pan; EAS_U8 filterQandFlags; #ifdef _REVERB EAS_I16 reverbSend; EAS_I16 cc91ToReverbSend; #endif #ifdef _CHORUS EAS_I16 chorusSend; EAS_I16 cc93ToChorusSend; #endif } S_DLS_ARTICULATION; /* flags in filterQandFlags * NOTE: Q is stored in bottom 5 bits */ #define FLAG_DLS_VELOCITY_SENSITIVE 0x80 #define FILTER_Q_MASK 0x1f /*---------------------------------------------------------------------------- * Wavetable region data structure *---------------------------------------------------------------------------- */ typedef struct s_wt_region_tag { S_REGION region; EAS_I16 tuning; EAS_I16 gain; EAS_U32 loopStart; EAS_U32 loopEnd; EAS_U16 waveIndex; EAS_U16 artIndex; } S_WT_REGION; /*---------------------------------------------------------------------------- * DLS region data structure *---------------------------------------------------------------------------- */ typedef struct s_dls_region_tag { S_WT_REGION wtRegion; EAS_U8 velLow; EAS_U8 velHigh; } S_DLS_REGION; /*---------------------------------------------------------------------------- * FM synthesizer data structures *---------------------------------------------------------------------------- */ typedef struct s_fm_oper_tag { EAS_I16 tuning; EAS_U8 attackDecay; EAS_U8 velocityRelease; EAS_U8 egKeyScale; EAS_U8 sustain; EAS_U8 gain; EAS_U8 flags; } S_FM_OPER; /* defines for S_FM_OPER.m_nFlags */ #define FM_OPER_FLAG_MONOTONE 0x01 #define FM_OPER_FLAG_NO_VIBRATO 0x02 #define FM_OPER_FLAG_NOISE 0x04 #define FM_OPER_FLAG_LINEAR_VELOCITY 0x08 /* NOTE: The first two structure elements are common with S_WT_REGION * and we will rely on that in the voice management code and must * remain there unless the voice management code is revisited. */ typedef struct s_fm_region_tag { S_REGION region; EAS_U8 vibTrem; EAS_U8 lfoFreqDelay; EAS_U8 feedback; EAS_I8 pan; S_FM_OPER oper[4]; } S_FM_REGION; /*---------------------------------------------------------------------------- * Common data structures *---------------------------------------------------------------------------- */ /*---------------------------------------------------------------------------- * Program data structure * Used for individual programs not stored as a complete bank. *---------------------------------------------------------------------------- */ typedef struct s_program_tag { EAS_U32 locale; EAS_U16 regionIndex; } S_PROGRAM; /*---------------------------------------------------------------------------- * Bank data structure * * A bank always consists of 128 programs. If a bank is less than 128 * programs, it should be stored as a spare matrix in the pPrograms * array. * * bankNum: MSB/LSB of MIDI bank select controller * regionIndex: Index of first region in program *---------------------------------------------------------------------------- */ typedef struct s_bank_tag { EAS_U16 locale; EAS_U16 regionIndex[NUM_PROGRAMS_IN_BANK]; } S_BANK; /* defines for libFormat field * bits 0-17 are the sample rate * bit 18 is true if wavetable is present * bit 19 is true if FM is present * bit 20 is true if filter is enabled * bit 21 is sample depth (0 = 8-bits, 1 = 16-bits) * bits 22-31 are reserved */ #define LIBFORMAT_SAMPLE_RATE_MASK 0x0003ffff #define LIB_FORMAT_TYPE_MASK 0x000c0000 #define LIB_FORMAT_WAVETABLE 0x00000000 #define LIB_FORMAT_FM 0x00040000 #define LIB_FORMAT_HYBRID 0x00080000 #define LIB_FORMAT_FILTER_ENABLED 0x00100000 #define LIB_FORMAT_16_BIT_SAMPLES 0x00200000 #ifdef DLS_SYNTHESIZER /*---------------------------------------------------------------------------- * DLS data structure * * pDLSPrograms pointer to array of DLS programs * pDLSRegions pointer to array of DLS regions * pDLSArticulations pointer to array of DLS articulations * pSampleLen pointer to array of sample lengths * ppSamples pointer to array of sample pointers * numDLSPrograms number of DLS programs * numDLSRegions number of DLS regions * numDLSArticulations number of DLS articulations * numDLSSamples number of DLS samples *---------------------------------------------------------------------------- */ typedef struct s_eas_dls_tag { S_PROGRAM *pDLSPrograms; S_DLS_REGION *pDLSRegions; S_DLS_ARTICULATION *pDLSArticulations; EAS_U32 *pDLSSampleLen; EAS_U32 *pDLSSampleOffsets; EAS_SAMPLE *pDLSSamples; EAS_U16 numDLSPrograms; EAS_U16 numDLSRegions; EAS_U16 numDLSArticulations; EAS_U16 numDLSSamples; EAS_U8 refCount; } S_DLS; #endif /*---------------------------------------------------------------------------- * Sound library data structure * * pBanks pointer to array of banks * pPrograms pointer to array of programs * pWTRegions pointer to array of wavetable regions * pFMRegions pointer to array of FM regions * pArticulations pointer to array of articulations * pSampleLen pointer to array of sample lengths * ppSamples pointer to array of sample pointers * numBanks number of banks * numPrograms number of individual program * numRegions number of regions * numArticulations number of articulations * numSamples number of samples *---------------------------------------------------------------------------- */ typedef struct s_eas_sndlib_tag { SCNST EAS_U32 identifier; SCNST EAS_U32 libAttr; SCNST S_BANK *pBanks; SCNST S_PROGRAM *pPrograms; SCNST S_WT_REGION *pWTRegions; SCNST S_ARTICULATION *pArticulations; SCNST EAS_U32 *pSampleLen; SCNST EAS_U32 *pSampleOffsets; SCNST EAS_SAMPLE *pSamples; SCNST S_FM_REGION *pFMRegions; SCNST EAS_U16 numBanks; SCNST EAS_U16 numPrograms; SCNST EAS_U16 numWTRegions; SCNST EAS_U16 numArticulations; SCNST EAS_U16 numSamples; SCNST EAS_U16 numFMRegions; } S_EAS; #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_midi.h0000644000000000000000000000013214200302440026024 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_midi.h0000644000175000001440000000440614200302440026611 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_midi.h * * Contents and purpose: * Prototypes for MIDI stream parsing functions * * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_MIDI_H #define _EAS_MIDI_H /*---------------------------------------------------------------------------- * EAS_InitMIDIStream() *---------------------------------------------------------------------------- * Purpose: * Initializes the MIDI stream state for parsing. * * Inputs: * * Outputs: * returns EAS_RESULT (EAS_SUCCESS is OK) * * Side Effects: * *---------------------------------------------------------------------------- */ void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream); /*---------------------------------------------------------------------------- * EAS_ParseMIDIStream() *---------------------------------------------------------------------------- * Purpose: * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled) * so the interface works equally well for both file and stream I/O. * * Inputs: * c - character from MIDI stream * * Outputs: * returns EAS_RESULT (EAS_SUCCESS is OK) * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode); #endif /* #define _EAS_MIDI_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_reverbdata.c0000644000000000000000000000013214200302440027214 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_reverbdata.c0000644000175000001440000000215114200302440027774 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_reverbdata.c * * Contents and purpose: * Contains the static data allocation for the Reverb effect * * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 550 $ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $ *---------------------------------------------------------------------------- */ #include "eas_reverbdata.h" S_REVERB_OBJECT eas_ReverbData; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/dls2.h0000644000000000000000000000013214200302440025116 xustar0030 mtime=1644266784.809324171 30 atime=1644266785.269324464 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/dls2.h0000644000175000001440000001147614200302440025710 0ustar00pedrousers00000000000000/* dls2.h Description: Interface defines and structures for the DLS2 extensions of DLS. Written by Microsoft 1998. Released for public use. */ #ifndef _INC_DLS2 #define _INC_DLS2 /* FOURCC's used in the DLS2 file, in addition to DLS1 chunks */ #define FOURCC_RGN2 mmioFOURCC('r','g','n','2') #define FOURCC_LAR2 mmioFOURCC('l','a','r','2') #define FOURCC_ART2 mmioFOURCC('a','r','t','2') #define FOURCC_CDL mmioFOURCC('c','d','l',' ') #define FOURCC_DLID mmioFOURCC('d','l','i','d') /* Articulation connection graph definitions. These are in addition to the definitions in the DLS1 header. */ /* Generic Sources (in addition to DLS1 sources. */ #define CONN_SRC_POLYPRESSURE 0x0007 /* Polyphonic Pressure */ #define CONN_SRC_CHANNELPRESSURE 0x0008 /* Channel Pressure */ #define CONN_SRC_VIBRATO 0x0009 /* Vibrato LFO */ #define CONN_SRC_MONOPRESSURE 0x000a /* MIDI Mono pressure */ /* Midi Controllers */ #define CONN_SRC_CC91 0x00db /* Reverb Send */ #define CONN_SRC_CC93 0x00dd /* Chorus Send */ /* Generic Destinations */ #define CONN_DST_GAIN 0x0001 /* Same as CONN_DST_ ATTENUATION, but more appropriate terminology. */ #define CONN_DST_KEYNUMBER 0x0005 /* Key Number Generator */ /* Audio Channel Output Destinations */ #define CONN_DST_LEFT 0x0010 /* Left Channel Send */ #define CONN_DST_RIGHT 0x0011 /* Right Channel Send */ #define CONN_DST_CENTER 0x0012 /* Center Channel Send */ #define CONN_DST_LEFTREAR 0x0013 /* Left Rear Channel Send */ #define CONN_DST_RIGHTREAR 0x0014 /* Right Rear Channel Send */ #define CONN_DST_LFE_CHANNEL 0x0015 /* LFE Channel Send */ #define CONN_DST_CHORUS 0x0080 /* Chorus Send */ #define CONN_DST_REVERB 0x0081 /* Reverb Send */ /* Vibrato LFO Destinations */ #define CONN_DST_VIB_FREQUENCY 0x0114 /* Vibrato Frequency */ #define CONN_DST_VIB_STARTDELAY 0x0115 /* Vibrato Start Delay */ /* EG1 Destinations */ #define CONN_DST_EG1_DELAYTIME 0x020B /* EG1 Delay Time */ #define CONN_DST_EG1_HOLDTIME 0x020C /* EG1 Hold Time */ #define CONN_DST_EG1_SHUTDOWNTIME 0x020D /* EG1 Shutdown Time */ /* EG2 Destinations */ #define CONN_DST_EG2_DELAYTIME 0x030F /* EG2 Delay Time */ #define CONN_DST_EG2_HOLDTIME 0x0310 /* EG2 Hold Time */ /* Filter Destinations */ #define CONN_DST_FILTER_CUTOFF 0x0500 /* Filter Cutoff Frequency */ #define CONN_DST_FILTER_Q 0x0501 /* Filter Resonance */ /* Transforms */ #define CONN_TRN_CONVEX 0x0002 /* Convex Transform */ #define CONN_TRN_SWITCH 0x0003 /* Switch Transform */ /* Conditional chunk operators */ #define DLS_CDL_AND 0x0001 /* X = X & Y */ #define DLS_CDL_OR 0x0002 /* X = X | Y */ #define DLS_CDL_XOR 0x0003 /* X = X ^ Y */ #define DLS_CDL_ADD 0x0004 /* X = X + Y */ #define DLS_CDL_SUBTRACT 0x0005 /* X = X - Y */ #define DLS_CDL_MULTIPLY 0x0006 /* X = X * Y */ #define DLS_CDL_DIVIDE 0x0007 /* X = X / Y */ #define DLS_CDL_LOGICAL_AND 0x0008 /* X = X && Y */ #define DLS_CDL_LOGICAL_OR 0x0009 /* X = X || Y */ #define DLS_CDL_LT 0x000A /* X = (X < Y) */ #define DLS_CDL_LE 0x000B /* X = (X <= Y) */ #define DLS_CDL_GT 0x000C /* X = (X > Y) */ #define DLS_CDL_GE 0x000D /* X = (X >= Y) */ #define DLS_CDL_EQ 0x000E /* X = (X == Y) */ #define DLS_CDL_NOT 0x000F /* X = !X */ #define DLS_CDL_CONST 0x0010 /* 32-bit constant */ #define DLS_CDL_QUERY 0x0011 /* 32-bit value returned from query */ #define DLS_CDL_QUERYSUPPORTED 0x0012 /* 32-bit value returned from query */ /* Loop and release */ #define WLOOP_TYPE_RELEASE 1 /* DLSID queries for */ DEFINE_DLSID(DLSID_GMInHardware, 0x178f2f24, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); DEFINE_DLSID(DLSID_GSInHardware, 0x178f2f25, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); DEFINE_DLSID(DLSID_XGInHardware, 0x178f2f26, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); DEFINE_DLSID(DLSID_SupportsDLS1, 0x178f2f27, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); DEFINE_DLSID(DLSID_SupportsDLS2, 0xf14599e5, 0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6); DEFINE_DLSID(DLSID_SampleMemorySize, 0x178f2f28, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); DEFINE_DLSID(DLSID_ManufacturersID, 0xb03e1181, 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8); DEFINE_DLSID(DLSID_ProductID, 0xb03e1182, 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8); DEFINE_DLSID(DLSID_SamplePlaybackRate, 0x2a91f713, 0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8); #endif /* _INC_DLS2 */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_imelodydata.c0000644000000000000000000000013214200302440027371 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.269324464 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_imelodydata.c0000644000175000001440000000257414200302440030162 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_imelodydata.c * * Contents and purpose: * SMF File Parser * * This file contains data definitions for the SMF parser. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 547 $ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $ *---------------------------------------------------------------------------- */ #include "eas_types.h" #include "eas_imelodydata.h" /*---------------------------------------------------------------------------- * * eas_iMelodyData * * Static memory allocation for iMelody parser *---------------------------------------------------------------------------- */ S_IMELODY_DATA eas_iMelodyData; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_dlssynth.h0000644000000000000000000000013214200302440026752 xustar0030 mtime=1644266784.809324171 30 atime=1644266785.269324464 30 ctime=1644266784.809324171 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_dlssynth.h0000644000175000001440000000331614200302440027536 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_dlssynth.h * * Contents and purpose: * Implements the Mobile DLS synthesizer. * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 143 $ * $Date: 2006-07-17 14:09:35 -0700 (Mon, 17 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_DLSSYNTH_H #define _EAS_DLSSYNTH_H /* prototypes */ void DLS_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum); void DLS_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum); void DLS_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum); EAS_RESULT DLS_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex); EAS_BOOL DLS_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples); #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_parser.h0000644000000000000000000000013214200302440026376 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_parser.h0000644000175000001440000000725214200302440027165 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_parser.h * * Contents and purpose: * Interface declarations for the generic parser interface * * This header only contains declarations that are specific * to this implementation. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 767 $ * $Date: 2007-07-19 13:47:31 -0700 (Thu, 19 Jul 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_PARSER_H #define _EAS_PARSER_H #include "eas_types.h" /* metadata callback */ typedef struct s_metadata_cb_tag { EAS_METADATA_CBFUNC callback; char *buffer; EAS_VOID_PTR pUserData; EAS_I32 bufferSize; } S_METADATA_CB; /* generic parser interface */ typedef struct { EAS_RESULT (* EAS_CONST pfCheckFileType)(struct s_eas_data_tag *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset); EAS_RESULT (* EAS_CONST pfPrepare)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData); EAS_RESULT (* EAS_CONST pfTime)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime); EAS_RESULT (* EAS_CONST pfEvent)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_INT parseMode); EAS_RESULT (* EAS_CONST pfState)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState); EAS_RESULT (* EAS_CONST pfClose)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData); EAS_RESULT (* EAS_CONST pfReset)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData); EAS_RESULT (* EAS_CONST pfPause)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData); EAS_RESULT (* EAS_CONST pfResume)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData); EAS_RESULT (* EAS_CONST pfLocate)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate); EAS_RESULT (* EAS_CONST pfSetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); EAS_RESULT (* EAS_CONST pfGetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); EAS_RESULT (* EAS_CONST pfGetMetaData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength); } S_FILE_PARSER_INTERFACE; typedef enum { eParserModePlay, eParserModeLocate, eParserModeMute, eParserModeMetaData } E_PARSE_MODE; typedef enum { PARSER_DATA_FILE_TYPE, PARSER_DATA_PLAYBACK_RATE, PARSER_DATA_TRANSPOSITION, PARSER_DATA_VOLUME, PARSER_DATA_SYNTH_HANDLE, PARSER_DATA_METADATA_CB, PARSER_DATA_DLS_COLLECTION, PARSER_DATA_EAS_LIBRARY, PARSER_DATA_POLYPHONY, PARSER_DATA_PRIORITY, PARSER_DATA_FORMAT, PARSER_DATA_MEDIA_LENGTH, PARSER_DATA_JET_CB, PARSER_DATA_MUTE_FLAGS, PARSER_DATA_SET_MUTE, PARSER_DATA_CLEAR_MUTE, PARSER_DATA_NOTE_COUNT, PARSER_DATA_MAX_PCM_STREAMS, PARSER_DATA_GAIN_OFFSET, PARSER_DATA_PLAY_MODE } E_PARSER_DATA; #endif /* #ifndef _EAS_PARSER_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_dlssynth.c0000644000000000000000000000013214200302440026745 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.269324464 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_dlssynth.c0000644000175000001440000005226214200302440027535 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_dlssynth.c * * Contents and purpose: * Implements the Mobile DLS synthesizer. * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 795 $ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $ *---------------------------------------------------------------------------- */ // includes #include "eas_data.h" #include "eas_report.h" #include "eas_host.h" #include "eas_math.h" #include "eas_synth_protos.h" #include "eas_wtsynth.h" #include "eas_pan.h" #include "eas_mdls.h" #include "eas_dlssynth.h" #ifdef _METRICS_ENABLED #include "eas_perf.h" #endif static void DLS_UpdateEnvelope (S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, const S_DLS_ENVELOPE *pEnvParams, EAS_I16 *pValue, EAS_I16 *pIncrement, EAS_U8 *pState); /*---------------------------------------------------------------------------- * DLS_MuteVoice() *---------------------------------------------------------------------------- * Mute the voice using shutdown time from the DLS articulation data *---------------------------------------------------------------------------- */ void DLS_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum) { S_WT_VOICE *pWTVoice; const S_DLS_ARTICULATION *pDLSArt; pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex]; /* clear deferred action flags */ pVoice->voiceFlags &= ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF | VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF | VOICE_FLAG_DEFER_MUTE); /* set the envelope state */ pVoiceMgr->wtVoices[voiceNum].eg1State = eEnvelopeStateRelease; pWTVoice->eg1Increment = pDLSArt->eg1ShutdownTime; pVoiceMgr->wtVoices[voiceNum].eg2State = eEnvelopeStateRelease; pWTVoice->eg2Increment = pDLSArt->eg2.releaseTime; } /*---------------------------------------------------------------------------- * DLS_ReleaseVoice() *---------------------------------------------------------------------------- * Release the selected voice. *---------------------------------------------------------------------------- */ /*lint -esym(715, pVoice) standard API, pVoice may be used by other synthesizers */ void DLS_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum) { S_WT_VOICE *pWTVoice; const S_DLS_ARTICULATION *pDLSArt; pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex]; /* if still in attack phase, convert units to log */ /*lint -e{732} eg1Value is never negative */ /*lint -e{703} use shift for performance */ if (pWTVoice->eg1State == eEnvelopeStateAttack) pWTVoice->eg1Value = (EAS_I16) ((EAS_flog2(pWTVoice->eg1Value) << 1) + 2048); /* release EG1 */ pWTVoice->eg1State = eEnvelopeStateRelease; pWTVoice->eg1Increment = pDLSArt->eg1.releaseTime; /* release EG2 */ pWTVoice->eg2State = eEnvelopeStateRelease; pWTVoice->eg2Increment = pDLSArt->eg2.releaseTime; } /*---------------------------------------------------------------------------- * DLS_SustainPedal() *---------------------------------------------------------------------------- * The sustain pedal was just depressed. If the voice is still * above the sustain level, catch the voice and continue holding. *---------------------------------------------------------------------------- */ /*lint -esym(715, pChannel) pChannel reserved for future use */ void DLS_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum) { S_WT_VOICE *pWTVoice; const S_DLS_ARTICULATION *pDLSArt; pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex]; /* don't catch the voice if below the sustain level */ if (pWTVoice->eg1Value < pDLSArt->eg1.sustainLevel) return; /* defer releasing this note until the damper pedal is off */ pWTVoice->eg1State = eEnvelopeStateDecay; pVoice->voiceState = eVoiceStatePlay; pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF; #ifdef _DEBUG_SYNTH { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "DLS_SustainPedal: defer note off because sustain pedal is on\n"); */ } #endif } /*---------------------------------------------------------------------------- * DLS_UpdatePhaseInc() *---------------------------------------------------------------------------- * Calculate the oscillator phase increment for the next frame *---------------------------------------------------------------------------- */ static EAS_I32 DLS_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *pDLSArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents) { EAS_I32 temp; /* start with base mod LFO modulation */ temp = pDLSArt->modLFOToPitch; /* add mod wheel effect */ /*lint -e{702} use shift for performance */ temp += ((pDLSArt->modLFOCC1ToPitch * pChannel->modWheel) >> 7); /* add channel pressure effect */ /*lint -e{702} use shift for performance */ temp += ((pDLSArt->modLFOChanPressToPitch * pChannel->channelPressure) >> 7); /* add total mod LFO effect */ pitchCents += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue); /* start with base vib LFO modulation */ temp = pDLSArt->vibLFOToPitch; /* add mod wheel effect */ /*lint -e{702} use shift for performance */ temp += ((pDLSArt->vibLFOCC1ToPitch * pChannel->modWheel) >> 7); /* add channel pressure effect */ /*lint -e{702} use shift for performance */ temp += ((pDLSArt->vibLFOChanPressToPitch * pChannel->channelPressure) >> 7); /* add total vibrato LFO effect */ pitchCents += FMUL_15x15(temp, pWTVoice->vibLFO.lfoValue); /* add EG2 effect */ pitchCents += FMUL_15x15(pDLSArt->eg2ToPitch, pWTVoice->eg2Value); /* convert from cents to linear phase increment */ return EAS_Calculate2toX(pitchCents); } /*---------------------------------------------------------------------------- * DLS_UpdateGain() *---------------------------------------------------------------------------- * Calculate the gain for the next frame *---------------------------------------------------------------------------- */ static EAS_I32 DLS_UpdateGain (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *pDLSArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain, EAS_U8 velocity) { EAS_I32 temp; /* start with base mod LFO modulation */ temp = pDLSArt->modLFOToGain; /* add mod wheel effect */ /*lint -e{702} use shift for performance */ temp += ((pDLSArt->modLFOCC1ToGain * pChannel->modWheel) >> 7); /* add channel pressure effect */ /*lint -e{702} use shift for performance */ temp += ((pDLSArt->modLFOChanPressToGain * pChannel->channelPressure) >> 7); /* add total mod LFO effect */ gain += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue); if (gain > 0) gain = 0; /* convert to linear gain including EG1 */ if (pWTVoice->eg1State != eEnvelopeStateAttack) { gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT; /*lint -e{702} use shift for performance */ #if 1 gain += (pWTVoice->eg1Value - 32767) >> 1; gain = EAS_LogToLinear16(gain); #else gain = EAS_LogToLinear16(gain); temp = EAS_LogToLinear16((pWTVoice->eg1Value - 32767) >> 1); gain = FMUL_15x15(gain, temp); #endif } else { gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT; gain = EAS_LogToLinear16(gain); gain = FMUL_15x15(gain, pWTVoice->eg1Value); } /* include MIDI channel gain */ gain = FMUL_15x15(gain, pChannel->staticGain); /* include velocity */ if (pDLSArt->filterQandFlags & FLAG_DLS_VELOCITY_SENSITIVE) { temp = velocity << 8; temp = FMUL_15x15(temp, temp); gain = FMUL_15x15(gain, temp); } /* return gain */ return gain; } /*---------------------------------------------------------------------------- * DLS_UpdateFilter() *---------------------------------------------------------------------------- * Update the Filter parameters *---------------------------------------------------------------------------- */ static void DLS_UpdateFilter (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, S_SYNTH_CHANNEL *pChannel, const S_DLS_ARTICULATION *pDLSArt) { EAS_I32 cutoff; EAS_I32 temp; /* no need to calculate filter coefficients if it is bypassed */ if (pDLSArt->filterCutoff == DEFAULT_DLS_FILTER_CUTOFF_FREQUENCY) { pIntFrame->frame.k = 0; return; } /* start with base cutoff frequency */ cutoff = pDLSArt->filterCutoff; /* get base mod LFO modulation */ temp = pDLSArt->modLFOToFc; /* add mod wheel effect */ /*lint -e{702} use shift for performance */ temp += ((pDLSArt->modLFOCC1ToFc * pChannel->modWheel) >> 7); /* add channel pressure effect */ /*lint -e{702} use shift for performance */ temp += ((pDLSArt->modLFOChanPressToFc* pChannel->channelPressure) >> 7); /* add total mod LFO effect */ cutoff += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue); /* add EG2 effect */ cutoff += FMUL_15x15(pWTVoice->eg2Value, pDLSArt->eg2ToFc); /* add velocity effect */ /*lint -e{702} use shift for performance */ cutoff += (pVoice->velocity * pDLSArt->velToFc) >> 7; /* add velocity effect */ /*lint -e{702} use shift for performance */ cutoff += (pVoice->note * pDLSArt->keyNumToFc) >> 7; /* subtract the A5 offset and the sampling frequency */ cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS; /* limit the cutoff frequency */ if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS) cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS; else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS) cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS; WT_SetFilterCoeffs(pIntFrame, cutoff, pDLSArt->filterQandFlags & FILTER_Q_MASK); } /*---------------------------------------------------------------------------- * DLS_StartVoice() *---------------------------------------------------------------------------- * Start up a DLS voice *---------------------------------------------------------------------------- */ EAS_RESULT DLS_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex) { S_WT_VOICE *pWTVoice; const S_DLS_REGION *pDLSRegion; const S_DLS_ARTICULATION *pDLSArt; S_SYNTH_CHANNEL *pChannel; #ifdef _DEBUG_SYNTH { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "DLS_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ } #endif pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; pChannel = &pSynth->channels[pVoice->channel & 15]; pDLSRegion = &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK]; pWTVoice->artIndex = pDLSRegion->wtRegion.artIndex; pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex]; /* initialize the envelopes */ pWTVoice->eg1State = eEnvelopeStateInit; DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State); pWTVoice->eg2State = eEnvelopeStateInit; DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State); /* initialize the LFOs */ pWTVoice->modLFO.lfoValue = 0; pWTVoice->modLFO.lfoPhase = pDLSArt->modLFO.lfoDelay; pWTVoice->vibLFO.lfoValue = 0; pWTVoice->vibLFO.lfoPhase = pDLSArt->vibLFO.lfoDelay; /* initalize the envelopes and calculate initial gain */ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State); DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State); pVoice->gain = (EAS_I16) DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity); #if (NUM_OUTPUT_CHANNELS == 2) EAS_CalcPanControl((EAS_INT) pChannel->pan - 64 + (EAS_INT) pDLSArt->pan, &pWTVoice->gainLeft, &pWTVoice->gainRight); #endif /* initialize the filter states */ pWTVoice->filter.z1 = 0; pWTVoice->filter.z2 = 0; /* initialize the oscillator */ pWTVoice->phaseAccum = (EAS_U32) pSynth->pDLS->pDLSSamples + pSynth->pDLS->pDLSSampleOffsets[pDLSRegion->wtRegion.waveIndex]; if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED) { pWTVoice->loopStart = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopStart; pWTVoice->loopEnd = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopEnd - 1; } else pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pDLS->pDLSSampleLen[pDLSRegion->wtRegion.waveIndex] - 1; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * DLS_UpdateVoice() *---------------------------------------------------------------------------- * Purpose: * Synthesize a block of samples for the given voice. * Use linear interpolation. * * Inputs: * pEASData - pointer to overall EAS data structure * * Outputs: * number of samples actually written to buffer * * Side Effects: * - samples are added to the presently free buffer * *---------------------------------------------------------------------------- */ EAS_BOOL DLS_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples) { S_WT_VOICE *pWTVoice; S_SYNTH_CHANNEL *pChannel; const S_DLS_REGION *pDLSRegion; const S_DLS_ARTICULATION *pDLSArt; S_WT_INT_FRAME intFrame; EAS_I32 temp; EAS_BOOL done = EAS_FALSE; /* establish pointers to critical data */ pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; pDLSRegion = &pSynth->pDLS->pDLSRegions[pVoice->regionIndex & REGION_INDEX_MASK]; pChannel = &pSynth->channels[pVoice->channel & 15]; pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex]; /* update the envelopes */ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State); DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State); /* update the LFOs using the EAS synth function */ WT_UpdateLFO(&pWTVoice->modLFO, pDLSArt->modLFO.lfoFreq); WT_UpdateLFO(&pWTVoice->vibLFO, pDLSArt->vibLFO.lfoFreq); /* calculate base frequency */ temp = pDLSArt->tuning + pChannel->staticPitch + pDLSRegion->wtRegion.tuning + (((EAS_I32) pVoice->note * (EAS_I32) pDLSArt->keyNumToPitch) >> 7); /* don't transpose rhythm channel */ if ((pChannel ->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL) == 0) temp += pSynth->globalTranspose * 100; /* calculate phase increment including modulation effects */ intFrame.frame.phaseIncrement = DLS_UpdatePhaseInc(pWTVoice, pDLSArt, pChannel, temp); /* calculate gain including modulation effects */ intFrame.frame.gainTarget = DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity); intFrame.prevGain = pVoice->gain; DLS_UpdateFilter(pVoice, pWTVoice, &intFrame, pChannel, pDLSArt); /* call into engine to generate samples */ intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer; intFrame.pMixBuffer = pMixBuffer; intFrame.numSamples = numSamples; if (numSamples < 0) return EAS_FALSE; /* check for end of sample */ if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd)) done = WT_CheckSampleEnd(pWTVoice, &intFrame, EAS_FALSE); WT_ProcessVoice(pWTVoice, &intFrame); /* clear flag */ pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET; /* if the update interval has elapsed, then force the current gain to the next * gain since we never actually reach the next gain when ramping -- we just get * very close to the target gain. */ pVoice->gain = (EAS_I16) intFrame.frame.gainTarget; /* if voice has finished, set flag for voice manager */ if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted)) done = EAS_TRUE; return done; } /*---------------------------------------------------------------------------- * DLS_UpdateEnvelope() *---------------------------------------------------------------------------- * Purpose: * Synthesize a block of samples for the given voice. * Use linear interpolation. * * Inputs: * pEASData - pointer to overall EAS data structure * * Outputs: * number of samples actually written to buffer * * Side Effects: * - samples are added to the presently free buffer * *---------------------------------------------------------------------------- */ /*lint -esym(715, pChannel) pChannel not used in this instance */ static void DLS_UpdateEnvelope (S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, const S_DLS_ENVELOPE *pEnvParams, EAS_I16 *pValue, EAS_I16 *pIncrement, EAS_U8 *pState) { EAS_I32 temp; switch (*pState) { /* initial state */ case eEnvelopeStateInit: *pState = eEnvelopeStateDelay; *pValue = 0; *pIncrement = pEnvParams->delayTime; if (*pIncrement != 0) return; /*lint -e{825} falls through to next case */ // fall through case eEnvelopeStateDelay: if (*pIncrement) { *pIncrement = *pIncrement - 1; return; } /* calculate attack rate */ *pState = eEnvelopeStateAttack; if (pEnvParams->attackTime != ZERO_TIME_IN_CENTS) { /*lint -e{702} use shift for performance */ temp = pEnvParams->attackTime + ((pEnvParams->velToAttack * pVoice->velocity) >> 7); *pIncrement = ConvertRate(temp); return; } *pValue = SYNTH_FULL_SCALE_EG1_GAIN; /*lint -e{825} falls through to next case */ // fall through case eEnvelopeStateAttack: if (*pValue < SYNTH_FULL_SCALE_EG1_GAIN) { temp = *pValue + *pIncrement; *pValue = (EAS_I16) (temp < SYNTH_FULL_SCALE_EG1_GAIN ? temp : SYNTH_FULL_SCALE_EG1_GAIN); return; } /* calculate hold time */ *pState = eEnvelopeStateHold; if (pEnvParams->holdTime != ZERO_TIME_IN_CENTS) { /*lint -e{702} use shift for performance */ temp = pEnvParams->holdTime + ((pEnvParams->keyNumToHold * pVoice->note) >> 7); *pIncrement = ConvertDelay(temp); return; } else *pIncrement = 0; /*lint -e{825} falls through to next case */ // fall through case eEnvelopeStateHold: if (*pIncrement) { *pIncrement = *pIncrement - 1; return; } /* calculate decay rate */ *pState = eEnvelopeStateDecay; if (pEnvParams->decayTime != ZERO_TIME_IN_CENTS) { /*lint -e{702} use shift for performance */ temp = pEnvParams->decayTime + ((pEnvParams->keyNumToDecay * pVoice->note) >> 7); *pIncrement = ConvertRate(temp); return; } // *pValue = pEnvParams->sustainLevel; /*lint -e{825} falls through to next case */ // fall through case eEnvelopeStateDecay: if (*pValue > pEnvParams->sustainLevel) { temp = *pValue - *pIncrement; *pValue = (EAS_I16) (temp > pEnvParams->sustainLevel ? temp : pEnvParams->sustainLevel); return; } *pState = eEnvelopeStateSustain; *pValue = pEnvParams->sustainLevel; /*lint -e{825} falls through to next case */ // fall through case eEnvelopeStateSustain: return; case eEnvelopeStateRelease: temp = *pValue - *pIncrement; if (temp <= 0) { *pState = eEnvelopeStateMuted; *pValue = 0; } else *pValue = (EAS_I16) temp; break; case eEnvelopeStateMuted: *pValue = 0; return; default: { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Envelope in invalid state %d\n", *pState); */ } break; } } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_mixer.h0000644000000000000000000000013214200302440026226 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_mixer.h0000644000175000001440000001105114200302440027005 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_mixer.h * * Contents and purpose: * This file contains the critical components of the mix engine that * must be optimized for best performance. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 706 $ * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_MIXER_H #define _EAS_MIXER_H //3 dls: This module is in the midst of being converted from a synth //3 specific module to a general purpose mix engine #define MIX_FLAGS_STEREO_SOURCE 1 #define MIX_FLAGS_STEREO_OUTPUT 2 #define NUM_MIXER_GUARD_BITS 4 #include "eas_effects.h" extern void SynthMasterGain( long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 nNumLoopSamples); /*---------------------------------------------------------------------------- * EAS_MixEngineInit() *---------------------------------------------------------------------------- * Purpose: * Prepares the mix engine for work, allocates buffers, locates effects modules, etc. * * Inputs: * pEASData - instance data * pInstData - pointer to variable to receive instance data handle * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_MixEngineInit (EAS_DATA_HANDLE pEASData); /*---------------------------------------------------------------------------- * EAS_MixEnginePrep() *---------------------------------------------------------------------------- * Purpose: * Performs prep before synthesize a buffer of audio, such as clearing * audio buffers, etc. * * Inputs: * psEASData - pointer to overall EAS data structure * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ void EAS_MixEnginePrep (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd); /*---------------------------------------------------------------------------- * EAS_MixEnginePost *---------------------------------------------------------------------------- * Purpose: * This routine does the post-processing after all voices have been * synthesized. It calls any sweeteners and does the final mixdown to * the output buffer. * * Inputs: * * Outputs: * * Notes: *---------------------------------------------------------------------------- */ void EAS_MixEnginePost (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd); /*---------------------------------------------------------------------------- * EAS_MixEngineShutdown() *---------------------------------------------------------------------------- * Purpose: * Shuts down effects modules and deallocates memory * * Inputs: * pEASData - instance data * pInstData - instance data handle * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_MixEngineShutdown (EAS_DATA_HANDLE pEASData); #ifdef UNIFIED_MIXER /*---------------------------------------------------------------------------- * EAS_MixStream *---------------------------------------------------------------------------- * Mix a 16-bit stream into a 32-bit buffer * * pInputBuffer 16-bit input buffer * pMixBuffer 32-bit mix buffer * numSamples number of samples to mix * gainLeft initial gain left or mono * gainRight initial gain right * gainLeft left gain increment per sample * gainRight right gain increment per sample * flags bit 0 = stereo source * bit 1 = stereo output *---------------------------------------------------------------------------- */ void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags); #endif #endif /* #ifndef _EAS_MIXER_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_synth_protos.h0000644000000000000000000000013214200302440027655 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_synth_protos.h0000644000175000001440000000456114200302440030444 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_synth_protos.h * * Contents and purpose: * Declarations, interfaces, and prototypes for synth. * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_SYNTH_PROTOS_H #define _EAS_SYNTH_PROTOS_H /* includes */ #include "eas_data.h" #include "eas_sndlib.h" #ifdef _SPLIT_ARCHITECTURE typedef struct s_frame_interface_tag { EAS_BOOL (* EAS_CONST pfStartFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer); EAS_BOOL (* EAS_CONST pfEndFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain); } S_FRAME_INTERFACE; #endif /* generic synthesizer interface */ typedef struct { EAS_RESULT (* EAS_CONST pfInitialize)(S_VOICE_MGR *pVoiceMgr); EAS_RESULT (* EAS_CONST pfStartVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex); EAS_BOOL (* EAS_CONST pfUpdateVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples); void (* EAS_CONST pfReleaseVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum); void (* EAS_CONST pfMuteVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum); void (* EAS_CONST pfSustainPedal)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum); void (* EAS_CONST pfUpdateChannel)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel); } S_SYNTH_INTERFACE; #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_smfdata.c0000644000000000000000000000013214200302440026514 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.269324464 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_smfdata.c0000644000175000001440000000441214200302440027276 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_smfdata.c * * Contents and purpose: * SMF File Parser * * This file contains data definitions for the SMF parser. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 778 $ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $ *---------------------------------------------------------------------------- */ #include "eas_miditypes.h" #include "eas_smfdata.h" /*---------------------------------------------------------------------------- * * S_SMF_STREAM * * Static memory allocation for SMF parser *---------------------------------------------------------------------------- */ static S_SMF_STREAM eas_SMFStreams[MAX_SMF_STREAMS]; /*---------------------------------------------------------------------------- * * eas_SMFData * * Static memory allocation for SMF parser *---------------------------------------------------------------------------- */ S_SMF_DATA eas_SMFData = { eas_SMFStreams, /* pointer to individual streams in file */ 0, /* pointer to next stream with event */ 0, /* pointer to synth */ 0, /* file handle */ { 0, 0, 0, 0}, /* metadata callback */ 0, /* file offset */ 0, /* current time in milliseconds/256 */ 0, /* actual number of streams */ 0, /* current MIDI tick to msec conversion */ 0, /* ticks per quarter note */ 0, /* current state EAS_STATE_XXXX */ 0 /* flags */ }; drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/PaxHeaders.27918/eas_pcmdata.h0000644000000000000000000000013214200302440026513 xustar0030 mtime=1644266784.805324168 30 atime=1644266785.269324464 30 ctime=1644266784.805324168 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/lib_src/eas_pcmdata.h0000644000175000001440000001701514200302440027300 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_pcmdata.h * * Contents and purpose: * Data declarations for the PCM engine * * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 847 $ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_PCMDATA_H #define _EAS_PCMDATA_H /* sets the maximum number of simultaneous PCM streams */ #ifndef MAX_PCM_STREAMS #define MAX_PCM_STREAMS 16 #define PCM_STREAM_THRESHOLD (MAX_PCM_STREAMS - 4) #endif /* coefficents for high-pass filter in ADPCM */ #define INTEGRATOR_COEFFICIENT 100 /* coefficient for leaky integrator */ /* additional flags in S_PCM_STATE.flags used internal to module */ #define PCM_FLAGS_EMPTY 0x01000000 /* unsigned format */ /*---------------------------------------------------------------------------- * S_PCM_STATE * * Retains state information for PCM streams. *---------------------------------------------------------------------------- */ typedef struct s_decoder_state_tag { EAS_I32 output; /* last output for DC offset filter */ EAS_I32 acc; /* accumulator for DC offset filter */ EAS_I32 step; /* current ADPCM step size */ EAS_PCM x1; /* current generated sample */ EAS_PCM x0; /* previous generated sample */ } S_DECODER_STATE; typedef enum { PCM_ENV_START = 0, PCM_ENV_ATTACK, PCM_ENV_DECAY, PCM_ENV_SUSTAIN, PCM_ENV_RELEASE, PCM_ENV_END } E_PCM_ENV_STATE; typedef struct s_pcm_state_tag { #ifdef _CHECKED_BUILD EAS_U32 handleCheck; /* signature check for checked build */ #endif EAS_FILE_HANDLE fileHandle; /* pointer to input file */ EAS_PCM_CALLBACK pCallback; /* pointer to callback function */ EAS_VOID_PTR cbInstData; /* instance data for callback function */ struct s_decoder_interface_tag EAS_CONST * pDecoder; /* pointer to decoder interface */ EAS_STATE state; /* stream state */ EAS_I32 time; /* media time */ EAS_I32 startPos; /* start of PCM stream */ EAS_I32 loopLocation; /* file location where loop starts */ EAS_I32 byteCount; /* size of file */ EAS_U32 loopStart; /* loop start, offset in samples from startPos */ /* NOTE: For CMF, we use this to store total sample size */ EAS_U32 loopSamples; /* total loop length, in samples, 0 means no loop */ /* NOTE: For CMF, non-zero means looped */ EAS_U32 samplesInLoop; /* samples left in the loop to play back */ EAS_I32 samplesTilLoop; /* samples left to play until top of loop */ EAS_I32 bytesLeft; /* count of bytes left in stream */ EAS_I32 bytesLeftLoop; /* count of bytes left in stream, value at start of loop */ EAS_U32 phase; /* current phase for interpolator */ EAS_U32 basefreq; /* frequency multiplier */ EAS_U32 flags; /* stream flags */ EAS_U32 envData; /* envelope data (and LFO data) */ EAS_U32 envValue; /* current envelope value */ EAS_U32 envScale; /* current envelope scale */ EAS_U32 startOrder; /* start order index, first is 0, next is 1, etc. */ S_DECODER_STATE decoderL; /* left (mono) ADPCM state */ S_DECODER_STATE decoderR; /* right ADPCM state */ S_DECODER_STATE decoderLLoop; /* left (mono) ADPCM state, value at start of loop */ S_DECODER_STATE decoderRLoop; /* right ADPCM state, value at start of loop */ E_PCM_ENV_STATE envState; /* current envelope state */ EAS_I16 volume; /* volume for stream */ EAS_I16 pitch; /* relative pitch in cents - zero is unity playback */ EAS_I16 gainLeft; /* requested gain */ EAS_I16 gainRight; /* requested gain */ EAS_I16 currentGainLeft; /* current gain for anti-zipper filter */ EAS_I16 currentGainRight; /* current gain for anti-zipper filter */ EAS_U16 blockSize; /* block size for ADPCM decoder */ EAS_U16 blockCount; /* block counter for ADPCM decoder */ EAS_U16 sampleRate; /* input sample rate */ EAS_U8 srcByte; /* source byte */ EAS_U8 msBitCount; /* count keeps track of MS bits */ EAS_U8 msBitMask; /* mask keeps track of MS bits */ EAS_U8 msBitValue; /* value keeps track of MS bits */ EAS_U8 msBitCountLoop; /* count keeps track of MS bits, value at loop start */ EAS_U8 msBitMaskLoop; /* mask keeps track of MS bits, value at loop start */ EAS_U8 msBitValueLoop; /* value keeps track of MS bits, value at loop start */ EAS_BOOL8 hiNibble; /* indicates high/low nibble is next */ EAS_BOOL8 hiNibbleLoop; /* indicates high/low nibble is next, value loop start */ EAS_U8 rateShift; /* for playback rate greater than 1.0 */ } S_PCM_STATE; /*---------------------------------------------------------------------------- * S_DECODER_INTERFACE * * Generic interface for audio decoders *---------------------------------------------------------------------------- */ typedef struct s_decoder_interface_tag { EAS_RESULT (* EAS_CONST pfInit)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState); EAS_RESULT (* EAS_CONST pfDecodeSample)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState); EAS_RESULT (* EAS_CONST pfLocate)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time); } S_DECODER_INTERFACE; /* header chunk for SMAF ADPCM */ #define TAG_YAMAHA_ADPCM 0x4d776100 #define TAG_MASK 0xffffff00 #define TAG_RIFF_FILE 0x52494646 #define TAG_WAVE_CHUNK 0x57415645 #define TAG_FMT_CHUNK 0x666d7420 /*---------------------------------------------------------------------------- * EAS_PESeek *---------------------------------------------------------------------------- * Purpose: * Locate to a particular byte in a PCM stream *---------------------------------------------------------------------------- */ EAS_RESULT EAS_PESeek (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation); #endif /* _EAS_PCMDATA_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440025224 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.269324464 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/CMakeLists.txt0000644000175000001440000000365614200302440026017 0ustar00pedrousers00000000000000set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter -Wno-unused-value -Wno-unused-variable -Wno-unused-function -Wno-misleading-indentation") set( SOURCES host_src/eas_config.c host_src/eas_hostmm.c #host_src/eas_main.c host_src/eas_report.c host_src/eas_wave.c lib_src/eas_chorus.c lib_src/eas_chorusdata.c lib_src/eas_data.c lib_src/eas_dlssynth.c lib_src/eas_flog.c #lib_src/eas_ima_tables.c #lib_src/eas_imaadpcm.c #lib_src/eas_imelody.c #lib_src/eas_imelodydata.c lib_src/eas_math.c lib_src/eas_mdls.c lib_src/eas_midi.c lib_src/eas_mididata.c lib_src/eas_mixbuf.c lib_src/eas_mixer.c #lib_src/eas_ota.c #lib_src/eas_otadata.c lib_src/eas_pan.c lib_src/eas_pcm.c lib_src/eas_pcmdata.c lib_src/eas_public.c lib_src/eas_reverb.c lib_src/eas_reverbdata.c #lib_src/eas_rtttl.c #lib_src/eas_rtttldata.c lib_src/eas_smf.c lib_src/eas_smfdata.c lib_src/eas_tcdata.c lib_src/eas_tonecontrol.c lib_src/eas_voicemgt.c #lib_src/eas_wavefile.c #lib_src/eas_wavefiledata.c lib_src/eas_wtengine.c lib_src/eas_wtsynth.c #lib_src/eas_xmf.c #lib_src/eas_xmfdata.c lib_src/jet.c lib_src/wt_22khz.c ) add_library( sonivox STATIC ${SOURCES} ) target_compile_definitions( sonivox PRIVATE UNIFIED_DEBUG_MESSAGES EAS_WT_SYNTH #_IMELODY_PARSER #_RTTTL_PARSER #_OTA_PARSER #_XMF_PARSER NUM_OUTPUT_CHANNELS=2 _SAMPLE_RATE_22050 MAX_SYNTH_VOICES=64 _16_BIT_SAMPLES _FILTER_ENABLED DLS_SYNTHESIZER _REVERB_ENABLED _CHORUS_ENABLED ) target_include_directories( sonivox PRIVATE host_src lib_src ) set_target_properties( sonivox PROPERTIES POSITION_INDEPENDENT_CODE true VERSION 3.6.10 ) if (STATIC_DRUMSTICK) install( TARGETS sonivox EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) endif() drumstick-2.5.1/library/rt-backends/eassynth/sonivox/PaxHeaders.27918/sonivox.pro0000644000000000000000000000013214200302440024713 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.269324464 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/sonivox.pro0000644000175000001440000000461214200302440025477 0ustar00pedrousers00000000000000#------------------------------------------------- # # sonivox library # #------------------------------------------------- QT -= core gui QMAKE_LINK = $$QMAKE_LINK_C #QMAKE_LFLAGS_RPATH = QMAKE_CFLAGS_WARN_ON += -Wno-unused-parameter -Wno-unused-value -Wno-unused-variable -Wno-unused-function -Wno-misleading-indentation TARGET = sonivox TEMPLATE = lib DESTDIR = ../../../../build/lib VERSION = 3.6.10 CONFIG += staticlib \ create_prl \ stdlib \ warn_on DEFINES += \ UNIFIED_DEBUG_MESSAGES \ EAS_WT_SYNTH \ # _IMELODY_PARSER \ # _RTTTL_PARSER \ # _OTA_PARSER \ # _XMF_PARSER \ NUM_OUTPUT_CHANNELS=2 \ _SAMPLE_RATE_22050 \ MAX_SYNTH_VOICES=64 \ _16_BIT_SAMPLES \ _FILTER_ENABLED \ DLS_SYNTHESIZER \ _REVERB_ENABLED \ _CHORUS_ENABLED TARGET = sonivox INCLUDEPATH += host_src lib_src HEADERS += host_src/eas.h \ host_src/eas_chorus.h \ host_src/eas_reverb.h \ host_src/eas_types.h SOURCES += host_src/eas_config.c \ host_src/eas_hostmm.c \ # host_src/eas_main.c \ host_src/eas_report.c \ host_src/eas_wave.c \ lib_src/eas_chorus.c \ lib_src/eas_chorusdata.c \ lib_src/eas_data.c \ lib_src/eas_dlssynth.c \ lib_src/eas_flog.c \ # lib_src/eas_ima_tables.c \ # lib_src/eas_imaadpcm.c \ # lib_src/eas_imelody.c \ # lib_src/eas_imelodydata.c \ lib_src/eas_math.c \ lib_src/eas_mdls.c \ lib_src/eas_midi.c \ lib_src/eas_mididata.c \ lib_src/eas_mixbuf.c \ lib_src/eas_mixer.c \ # lib_src/eas_ota.c \ # lib_src/eas_otadata.c \ lib_src/eas_pan.c \ lib_src/eas_pcm.c \ lib_src/eas_pcmdata.c \ lib_src/eas_public.c \ lib_src/eas_reverb.c \ lib_src/eas_reverbdata.c \ # lib_src/eas_rtttl.c \ # lib_src/eas_rtttldata.c \ lib_src/eas_smf.c \ lib_src/eas_smfdata.c \ lib_src/eas_tcdata.c \ lib_src/eas_tonecontrol.c \ lib_src/eas_voicemgt.c \ # lib_src/eas_wavefile.c \ # lib_src/eas_wavefiledata.c \ lib_src/eas_wtengine.c \ lib_src/eas_wtsynth.c \ # lib_src/eas_xmf.c \ # lib_src/eas_xmfdata.c \ lib_src/jet.c \ lib_src/wt_22khz.c drumstick-2.5.1/library/rt-backends/eassynth/sonivox/PaxHeaders.27918/res0000644000000000000000000000013214200302440023200 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.269324464 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/res/0000755000175000001440000000000014200302440024036 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/eassynth/sonivox/res/PaxHeaders.27918/test.ota0000644000000000000000000000013214200302440024741 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.269324464 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/res/test.ota0000644000175000001440000000003614200302440025521 0ustar00pedrousers00000000000000J:Qѕ Ua`UPT@Idrumstick-2.5.1/library/rt-backends/eassynth/sonivox/res/PaxHeaders.27918/abba.imy0000644000000000000000000000013214200302440024662 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.269324464 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/res/abba.imy0000644000175000001440000000066614200302440025453 0ustar00pedrousers00000000000000BEGIN:IMELODY VERSION:1.2 FORMAT:CLASS1.0 NAME:DanceQueen COMPOSER: downloaded at www.ringtones.perbang.dk BEAT:112 STYLE:S1 VOLUME:V10 MELODY:*5#c1*4b2*5d1*5#c4*4b3*4a4*4b3.*5#c3*5#c2*5a4*5a3*5#g4*5#g3*5#f4*5#f1*5#c1*4b2*5d1*5#c4*4b3*4a4*4b3.*5#c3*5#c2*4b2*4a1.r2*5#c2*4b3*4b1r4r5*5#c2*4b3*4b2*5#c2*4a3.*4b3.*4#g3*4a3.*4b3.*4#g3*4a4*4#g4*4#f2.*5#c3*4b3.*4a3*4#g2*4a3*4a1r4*4#g2*4a3*4a2.*4b4*4a3*4#g4*4#g3.*4a3.*4a1 END:IMELODY drumstick-2.5.1/library/rt-backends/eassynth/sonivox/res/PaxHeaders.27918/ants.mid0000644000000000000000000000013214200302440024715 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.269324464 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/res/ants.mid0000644000175000001440000000561414200302440025504 0ustar00pedrousers00000000000000MThdxMTrk vuntitledCopyright 2001 by davedaveXYQu A*v$! A&dd (x 2CZ xAZ Z>Bi A A7z39>]2vJd37*$92J>> *%& *-*v(*(=Z%X*b$*&]%>B=$ *zBZ*K &>*B*%]=O9>2g*V *29> &X>R%=*v(*Bd >& *>v92o( >X&r**]$ B*'>$7]&*Z+j>~;~2*9>>+;7*D */(**#%j=K*b(*&X>N=%L*+CbNd&>L* NC+L0JbLCI;+g**Q+z>LoJ** ;L+>G]C$n+ G$JrCg+z*(*-o>~Ez;++bCJL*]$l(Ng*L $>N >b>E*v$2d&z9j;+- *>92>$ *K&* (*r*(=2*b$%g*=>8&j%$B]*Z*z>&*%B=K9~2o*D>*%r* 29> =&r>\%*z(Bd*z >&*9r>2g (B>^Qz*&v*^$X8X*Q So S$>7d*VSz+j;r>&2>9*TmSSoT+;7>S*%Qo*QS*(SQo*QOvO%r=:Nz*g(*N&g>Q%=JQJC\+v*LB&>*LC+*<Nr*NJv;+v>CV*b+~;J>*+GFC+$u G $L+~Cd(*9~1v 19 *ErC-b>L+J;+dJGm*b$^( *EbG$> 2m*r$&>b9m>7b3-E;+73*29>$>&EGm*Q*G)(*v*(*g$=?%r*&Z=%>F$BR*v*b &>*#BS2r>T9~%m=I*7*S2>9*%&g=>VB^(*v*v >&*9z>2o(B>\*b$&v**>$7d+m;~>*d2SD9&>T S*TbSv>+;7T *^SQ*Q (*m*!(=:*^$%o*$&X>N%=CX*o$+zO >&*OC+Q$Q;>*$CK+d+z>;+$C+*$Cb*r(+~JJ*Eo>+bC-m;z+ ( *d$L*$NL >&*o$>^3v72b>E9m;N-37+ *92>$> *X&*!*v(*&*j$=I%r(*=%&j>I$BX*r*Z >& *B *=QJVNv9v2j>*R%r *NJ29>&Z%>R=BZ*z(*v >& *9rN2]JX>B*j$>Z&v* ( *J $ N>Jv7bOr;v*b+d>92j>*JO&+ ;>7 *V9g1v* 19%*z(*(=D*]%z7U *7 >:=&b%( CZ+z*37>&73*C**+*OJb*mCU+z;~>+\ OJ;>+C$x*+$+z*(Cz9~1z19 -rE\Oo>vJOC*;++g(*b* J>Nr>VJ^2m3v7&~>-O9~E;+37 NJ29>>&/drumstick-2.5.1/library/rt-backends/eassynth/sonivox/res/PaxHeaders.27918/test.mid0000644000000000000000000000013214200302440024727 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.269324464 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/res/test.mid0000644000175000001440000000025714200302440025514 0ustar00pedrousers00000000000000MThdxMTrk/Copyright (C) 2006-2022 Pedro López-CabanillasQ 'X$Y AB@Ax<>@x<@AxM%;qHb%?i=V Ia #^-S aI#P;k9m LJ e * gE1$*0Kj&{QU !#+%&(&*+}-,/0h23S4:4K474E404?4)4<4#4944644444;43V43&5*r`Z#Ixhl'H4jNgvSy9RR9D*bx>V-Wu)Dg /NtNXRC) j'D6uL}=e.b3z'( f % r <jb " $%Q')*r,./G123@44;4 4744643443343543<43J43k4o3Z3[ d7'jwtFN5qe{ E2eO`fhWvq7}n^[;B!Yk+=r s@m"R*lPk  o 3 >hyc}!"$B&()Y+,.<01M3(43&43"43 43 43!43#43-43E4s3425HwLTc-9FK<^Qn ""?;Z^l_kD~9_Hi$Gn!Cb6[{%Dg (D h-QW;t:i)U S79 W  { X=-""/Hm/bh !#;%&(3*+-4/0e2343333333333333333334,tBDQ& &3)VOik(L w-ܭrB!qWFF#1m{EV1`w,An 3Lv(iuqf@k/94q9e.ZF)m f$ R % t|vY ge!"7$%')*k,../j12333333333333333~34U3?4244 QD} (Q$eC[w7Z V6J.+huAX2az.Qv?_#DdBkf9q x!bZ6a6S~$Jh1Xu4Vv9JLE1G^ Z=n 8dQzK23 V  ]E2-.AXH "#^%'(V*+-M/0v233333333333333333333.a6P'D,_J[{'`ilb߷' kjER1cy4PzFb *Mh *ZJj? CN:qAp)R|Oft c ! 9i !"J$ &'^)*,3./g1333333333y33k33Y33>333'424a*,rr>SVt1<ETavv] iaSD)*ov DT&Xj%7jx+?n~v " W77r@o8eK|!`Je  w > ".kD$ !M#$&C()+0-.p02J33333333z33o33b33N33)3325t%m:Asbz+Pa)5CP]ivf'YcjA];f:[)Nj4Wv3Yz)jhAd!sK{Do)PY2< ] * vRP@PXzG= `"#%,'(*A,-/12y3333{33t33l33c33W33I33933O303>&i.jiX.(L<jRftvK-x< m@4.|y QW+es/?q 7Jv 6Lv2bk(e \OFo7aK2xp3 c : HaG[!"$&'g),+,x./123m33f33]33S33G334333324\2 5dgc&,[}-s!}Yk1D$b:Ncu9ٖ.C*Qc(9i:W~"Fa (Ij 'FF[he[>}?XE XCl,Y$j_s + [ 5 0[~Yd !#%%&o( *+l-/0&2X3z33q3}3j3x3b3u3Z3t3Q3u3B3}3'3324(;y?;}S FR"FVf`9/RDrYiH1cJڈw /Qx .Tt$Gn<[$Eb%Hc6QxK A?.b&S~;h,dOH ~ : ipn[ln !"7$%}')*^,./L123]33W3~3P3{3G3{3<3|3.3333232\2 :6%@yskDa2eL_ $; e.+u\0&ttCT$Ul 8c{&?d'Bd~i.COKA*g"?+i <H R 4 -IE~ !G#$& ()Y+-.b0143Y3}3L3}3A3}373~3*33332323A250SZo)/443BCe[vx!8.VAuPfQݎx bY.3sx4>Olf1$ >"#{%'(d* ,-P/0g2U3`3`3Z3Z3U3S3P3N3L3I3I3@3G313T323t,L`;,0#8?VVlt =%`/*{ -Wr&Ei9Y|"?a$Aa;\< $/1"Mo"q LJx*O{Oaq h %  U@(8!"g$+&'t)*,6./^12F3n3;3o333p3&3q33u3332323^23sK}>4]q40 )(D>^ZlzEj 8 ڌ۫j0eWJ ad-3lv0?q/@my&85kiO_ j[([#Lp&S(jU w ( T :9T+vSX !#0%&s(*+M-/0&2"3f3>3a383_3/3_3$3b33h32y323T24",$  ?&S=kUo4 Ue?4@_&zgef9t >gAk9jNW { G {|s"c!"3$%p'#)*m,-/'12G3S3A3O383L313J3*3G3"3D33B33/3Y3/k"$IM)r -)BFV`ox8 aA9ޯ>FtF[(Qj2Yq3[q)Sg2kfB U_ RIx>^@qU=^ m 3 )pB !?#$t&4()|+-.5012e3+3_3#3^33_3 3c32n32323.2z4f;@4D"]4uPd}-Wl`Zr A!wj9F|>QD[@Y7Qs $  l0V S.f'Pw .W R;7 e $ wbOTNn2}F8 S"#%5'({*,-O/0Y2J343R3.3O3&3M33M33O32\323u24&cUq}z+1BJY_qu &7*Dy0gY'.gq*>l}+?n%?gz0Unv(g{^5FT>yAn)Hs1d?.A | J  ?ri!#$:&'z)5+,u./12W3-3P3%3L33K33K3 3M32S32`321fCU2WB81,p*?1UBn^s!P݃٢x ?f-Jp2Ru2Pp 'Fe;W d#NF,X@c&Qu={*~ R  PG&4#GSE "#>%&{(C*+-.0 2D3&3\33\33\33b32m3232324u*#.J#v$+=@Mabvw'_3i4ߌ1mW)$kg*2is"-`q(Vesm'fwr])9N5m >_?_$U*nw) l - MF*7!"a$&'E)*,"./F12A3>3:3<34383+353#3433833P324h*l ~f31KGb]wsOؙܲߌS[!Ub$Ma !I]=Ry  dJ>$S6[Fr3n pz ? n ?/ .7qgi !#%&G( *+O-.01+3)3U33U33V3 3Z32a32q323x22 rSvy0@jy 42FHZ^px/;Sp\=߫ߪ"/dl'7hq"3`u+Rg GYSv/fu\,7O2l 5_5Z"Q`k [  3h "&$%^')*[,-/02-3P3'3O33Q33U33^32s323124 R*m 6L,c?|Tm}R 7-݀R߯߇!\Z"Xh O`AT|.Cf+]E<{ O| 3Tz4e0eWl ) x P ,It\., !K#$&()Z+-.6012A3A383>31393)353%313 3'3"333-2p@N*C6VMkat0]qxJߖ߇ HO>S5Ns&?c|,Kf/y0]|sT)~3E,f.T~/OyF{W^ x I  vva|{ <e_ r"#%'(_*%,-c/0j23Z3"3[33]3 3a32k32323>24og*$\^pt) @$Q8mL}cv. H.A_kߑ߫)Ok (Hg!=Zz,Ji1M7[CALq 4Wz-U'dLg  q 4   \+!#$<&'})6+,r./12_3)3W3"3W33W3 3^32m323X24N$lWL42FDbTvjx2}eۭHuAߧ߆UO JP8Er|#1Zo[+?iX1~;G1j+Vx /Sw:t RR q 7 d_P_e|?. >"#p%&(3*+j-/0/23W333S3*3P3"3P33R3 3U32T33O0e}M*Kk%-7AMX_nuW= 93= \@ߏ߆ BF1As!1Ym DX~H\&ACIp 2Xz)R~&a@_  h ( Gh}]h!"$ &'A) +,F./h12m3%3l33l33o32z32323&24)(F{o[r $ 45GKZfh|84(eeߢߢ%U^ GT 4Gm~.Te11Jn^8?G6l1Q|3Tx 7oRI s , v`LHI[u] "#9%&p(*+V-.|01&3I3Q3@3O383M3-3N33U33v32Y4(5 $zNn| $;&O7fJz^l~/q*ځBnRߣߕSS =Iy*7\nCU{d +(/k4NK"N>\ -W(aC`  a ' 6]gCK!"p$%'))*d,./B12e363f3-3f3#3f33k33x3232%2 A6Imu)>.P@bTyfx#W]ߒߠ BX| -Jh*Pj-KfJ[lFNWBq4Y7Z :lVD r & iX=C5MY;us !# %&A()x+9-.g01(3B3n333o3$3s33}32323?25=-yXwh$ 9 J4`IrWk|mi*ܒ-9ivߣ߳.Th:Os9[r4Ql y6;6%w7ZS+^8]|4Z _FQ P $ N:!"3$%h' )*H,-v/0y2O3[3W3W3P3R3I3O3@3P313^323$,0U'D@o!:%K9bGu\k{"jSޠ7jZߢߖJM.;gxHX~$8bZ&dvJQ[Cz3o383b3t3l/b",1J1Ol#!9/JEaStds~rt.fؽ+ݰtި B(ueߩߢPP,2di:Gt~FIT_LGKt`@v&HcFm#_ TQ  E $ ;dr "#%'(N*,-I/0T2.33J33=33-333323a24#n5c|wkio 5G3UFhU~h|ݥފ޾,9duߘ߬ >Vw1Rk+C]|'Wk7qy\,Wz &Lf"O~WR h + cB4'+E]X! !&#$N&'~)*+,[./w123f33^33S33C33"3324+'s<FcXy  1!<3U@gTyctd6ُHuޫޝ HP|߅߽߰"1Zg 0Cdw8Lnf 7dnxh]8`#)rP5Yr +Mu1hVV  M % 0]qV ^"#%'(>*+o- /0+2533e33\33P33A33*3331o ;2&%+% S}+9O.^@sP`n|%qfQئ݊T޳މC=xx߭߯!OW%5Wk +?]sH(sJ3,o =e7Qs 1Y] ] j 9 n=9*#ENJ!#$-&'])!+,S./o123_33T33B33'3324l2*5l,65J i}2'@<QJe_pvLۧ݇cޤޓ ;Eu|ߨ߱$LU|0Qa&6Vi(`yoR(2C([$Np2WFx[h  ^ & #gaB M"#k% '(<*+p-.02M33333x33k33W333k4*Ht_ + 52KAYOra~r}"fj/z1Pޒz޸ް"#Q[ߊߕ߿'6\k-?`r.DmqM e(IB~Pw(K^=i/gc p ? wD<-$HRJ !"$ &'Q)+,C./]123r33f33W33C33"332 3 ~GI q~ "39>ML\aqjzx/ޝ`ޠ$ZKߍ߃߾߻&$ZZ'+[d'0K Fn=CW4m<^$@`(Uds  k ( hR/ 1"#O%'~(>*+o-.01^333u33c33J33342O5>&G-w  );-GA\Mmbxr-hۢ[Mz|ާ޷&D]}ߑ߬-Ga0Ja|Q9w$6?;, AaX5a<]y.Lt >{"m F  yTA/,/I`Q!#$#&'X)*,%./>123333333333a3 46-}C8tq$ 62FBVPi^|k}/hnSr#+uUޞޏ63dhߙߚ09cm.:[k }9nX+_rN$Op(>AhSnf!#|$%&'U)*,-/12333333p33I342D5#,e~!*)<6OHX[ley}Iۄ<,[]ދސ޹+N`߂ߓ߳+I\}"?Uu$Rt?|,)f2_|0LkBm=. 8 { < ^N& &"#?%&h( *+A-.e01?333333333333/X:<7Q3Xz  -:)P5]IlU~fs @f KUQ6vlީޠ 6(=c>yb6 '%38CERSddnuU׮n8ra!"q$%')*-,-M/ 1M23343&43843o435"*(2V\1"''66?CQPYhfqw| @rרڮ )M)uYޡލ޼#PM{{ߧ߬,3W_"XNObr`W4j)6#Y?]z $E_~D~a m # m 9/]K "#(%&J()r+,.01 34343 4343374v/|h[ `@'40<@LG[\fdzrp׍: 18\hމޔ޺ !>Khzߗߣ,OVwr1 [P?C}Ch%D`w?b <ze " ?  yP]Dig;qa!"q$%'(*,-=/19233:43E43\4343'5J0EH2<4@@RK^Xkmq{*T@ܽݶ *TAނoޫޞ+*XT߄߃߭߰ /3Zb wCp~yO2FJ=v-Rq%<Z{$W3t z 5 w N.kD "#%&8()`+-.*01 33-43.43943a4g3a5}'tZJAr9%0 #4$?0L=]HhZsep}1I6יڙݯ + S?|mޡޚ% NOyߨߩ&-OW{\8~i8U[,[UB׎ڃݕ5!_Lރzޫާ*)NU|߂ߥ߫!)EU{fd!`f:w+*h5^/H`~+OrR5 S  h2/x@  !#%&()D+-b.#0o133f4 4j43y43434_=rVi}#>G(?3Y:_PiXxgu#=stݲ,1Q^{ކާ޴".HYu߄ߞ߫#@LB2?Si`Q4k-;-bB]~+Bb 7dO F  } 2 hzrdZB!"F$%]')*:,-]/0g23m44u43434Y35"+xs^K?Q9?C9YH[^fdvs{ 1Lst;ۖݏݳ"E9nbޓޏ޼޼ 69`d߈߇߯ߵ$-i.Y_PE$U| *G`y %Ei(hU j  |L,  0K W" "#%&7()\+,|.0134Z4B4Q4<4H4B4&44.l<i~O0'PGCV[Zdphw|&7I`לځ݊ݳ'K:sfޚލ޺޷53[]߁߄߫߮#+oCtY;QU K9[x+F`|$Lz$f [  E |w hM!"J$%e' )*G,-f/0q234!44 443434`6W L6Y\?ZDoQpd~jz .Elݟݪݼ,EUkޗޥ޼ 2B\k߂ߐ߽߫ XWT1 }=ja>n#BYw;Z<sg  t 6 c5'   -a k0 #"#-%&G()k+,./12A4E44/44 4435%]" ,8RvSZ #l#MN]GoVucpx#0E]Lsݛ'KEqkޙޕ55U^߄ߣ߬ %*=k}Z#mt!`+Tu %@Ws:b3x l & W *(quT!"X$%j' )*3,-S/0V23y4P4}4D4484{4_4?1F 7I+TV.mMd\u^l{&3FYg=גrܩqݙ'KFqmޕޔ޹޺ +4PZv߁ߝߧ߿Vb9AG6_1~Y;\u6SpO+  H uA703q xB ."#5%&S()x+,./12[4E44(443435R#bC$Ev-nVoXfr} '1 C\/b܏ݍݪݭ%?Icrއޔެ޺/EUkzߑߣ߷_b!cuG ;9xKn8Sk/R} J+ 0 o 2 8sl!"j$%'(*,-:/0823c44^44D44359*H?@vLRtchzzw-= M h'>m^ݯݭ /&QIvrޛޙ޿ .1QYt}ߚߥ^4%:[efP<{4J4n0Nn-Ee3bA * W  ~M@$4;swA '"#-%&G()l+,./12U4_44J44-4443B|y`67goBhuoy#-9M`q|MܓQݱvݢ -MBpgޖސ޸޲'&HGllߑߓMg"[N1a ,K]{-GiQ> 9  ;!Fpk!"m$%'(* ,-/023U44K44 4536 ^V3o1XE}s}lz &++<2C6`q Dqt݌ݕݮ*9Rbrނޘެ޾%5K_n߮|jY=c}uZ9 Qb SCi.@[y"IwS A b  ]H1-(:Mtv: !"#$%&=()[+,z./12=444444`45a.4Y4<Qeg}~ $-;I]y :ZEݝjݰݐݹ7+WPzuޞޚ)*MKkt 9F~!D vgMx&Ea{ '>^}1bW M  J,Qwx!"q$%'(* ,-/023`44\4474535|n3L(ZSPtPv{ . 6DT`$tzrFyEݘjݯݏݺ*)NMooޑޔ޶޺$:E^ߠߥ2e^(u"'i4`)>Yp:a$b W o 8 yQH6A>dz2r5 "#%&0()M+,f.0n13"44q44O4536~%PbFh` #*#7(A5K9]9q(=`aw~ݗݥݺ -AOeuއޖި޶1?b {]7EG<#i'<*e%Dc <Sn L"j j ' g<!^2~!"y$%')*!,-;/0<234444444098/y?4'Ohk + 7DJ%^n"bFI6݅Tݘ{ݷݣ60UUxxޗޛ޻޾ &>ߩY[iRFD%S| ,AZp7W{:y$ w   M _aE[P~OB &"##%&3()M+-c..0g1/344n45D495355@",s;bm (1&=,H2T9c:q6:AׅSq'J~U  `  x Er+Wx Z"#Y%&l()+,./124454M54V69$*od1,#*)5)=6C<O<YDeGrJ|LFHo_;V f?cݛ݆ݶݥ%!BAaa}~ޗޗqXYl\'QV.`4Rcw5Nt6j Y  m , uT.,Xb& !#$&'!)*=,-S/0U2344444!50YhrtKi  #!,&6/=6B=N?VN[RgVmXR-Yۙ-4GVgr}݌ݞݪݻ 28HZkxޅޖ /@/!JhsyjS2O h O%Il&<Sc<_$b  r  \z2X c"#c%&s()+,./1244954l5)45-H#{i}!&'#7,;5@8P9XCbDkHyID4_&w:K#eC݀eݙ݁ݯݠ:4URqn޵ލ "G tBk oDr/Pez)CaL g   3 \C ?]a# ! #$ &')*/,-?/0?234!54C5c4,6(lJ,T   '.8);/E2M:W@\JhEqPxPROTLqN2@!YCtb݋|ݦݛݷ ,,EEdmZqZMnwL&j'$i ;b "=Rcz*Mt:v (  ( i-@m g"#e%&s()+,.01244%54*542l :^X^Zb3 #!*'/.46<9CEHMRST^Zabkdwf_6_ڃ&7AV^rzݍݓݦݯݿ/7KSް޿BV-z*2$d9$b'Jgw)@Yp 2_. { . E jV--)'Rf-h* ! #$ &')*-,-:/10234O54554V6U5TEjt! "--6A&D,O2S8]9eDhFxENKF6"l%2 D)\Fsfݎ݀ݥݟݺ ('?`:ߘ328zqJF@&V{ #ASh %:\N 4 > xAA+ e"#\%&h()~+-.#013[4"547545p,153J(  )*(5+;2@7J=OCWG_LeSpYvY[_Z`% D%7#M=hZ݀xݘݓݳݫ:޶{_%@XXQ8BVD~?]z2AYt EvD C Z &mAA/@6dy@~? !#$&'')*7,-B/1?234O54e54E4:WtRe8]H  *+!3%8*@2E:K>QB]IZRiSl]s^~ab\* %o 0:MXeo|݈ݗݤݱ `_gi)rg2`e=l'D[p4Oo4h E Y  ^! ,LI!j"$]%'d(*v+4-.J01H3C4\545T46"`IgAwvJ6    #$(*051>8B<JANF]J_KiVmT|VX[S?l~)Tܫ&; P=fU݀rݚݐݴݨݾ$8UA"Zm~y\Eet"e,Vv 8J`t7Y$`  V v 8aQFO^vL[ !B#$?&'J)*_,-s/0n234!5(545/ OlC$)%0+61;7B:JALFTMZQaUiXpauecihet?ܬ 1!F:_Ruo݋݆ݦݟݾݼmގ4 Z V |2V@`s0H`J Y  t  v8?][*!z"$k%'u()*+C-.[01Z3I4l5454v5|"G ^P  %$.$0(81:7??GAMGQPRZZYab`lhpjxpnqf6M_ܹ+*EE[_su݌ݐݢݣݺvy Wf46<Gn.A7F;L@RDVGZOdRdXo]pa|djloppcytAܖܰ 51JE^bzyݍݑݤݧݼ>ߺPO U]&[[8fQ@VH\IaSaTnXn^sb~ckinj`)$Kܚܸܱ 16DM_ap|ݎݓݠݫ,z?^jrfP0U h]+Ko1:Thz!Dp E 2 S q?+  <Z.q=!" $% '(-*+;-.?01'34 554`6L)&hlAu`mO1"# #*'-,1473?9>AI=MERIWK^OdWhXo[w\xh_ggbZJwiF<ۧn܉ܨ  1$E9ZOnh݃|ݡ!tHA x$sQ1Qgu*=Wv3d ? H u?H* !#$&')*,./123:55p5$53 78nt)!."03)-1;2::@<BFGEMONRTVY\]_`gfjiriypzut{||~f:ڷ۬{ܽܒܯ &>6PNgb|wYx_ ;usZ%|)6w;d6HWl4W$b D k RH% .'\iG H!",$%''(0*+;- />0234454r6~ [s_-=-#*9#6,:0<4C6H?JFLKRMTVYW\`\cckdpiprxoruturc*+Fyܥ܎ܸܥܷ&%:;RQddݐP޽AQ+540i-D8p+Ki}2EUrBx Y [  P%UJ "#%&()+,../812"45{54"6,uW: l D$.+&8(:2;4B:D<ICNBVGUP\ObPgYg^qZxaxfdhmjlicO _I+ےZܹqܻ܍ܣܼ#6)H9ZTߠ#ClFGS'V3O]o.Gl;r X  /f\4;$>AqZ \!"A$%>'(E*+R- /X02834554Z4 s2C@(5'E'@6F3L9N?PAXCXJ]N`U`ZkXp_lavgwkkusw{~h7ڭۄcܛ{ܤܕܵܧܽ!#7=J݂݂߉f%HZaUB$Lc Q!Eg#1D[n1U+ u  j , e@>bh ;"#(%&+()>+,U./g12W44546m"!$^}aL"V =0;*E1E6K8P8RBSE[F[O]PcUfWoXp`rayf|hlnsqtpl`"/bض-Y܆oܑ܄ܢܕܰܩܼ#!/BOkc'ql>hn Ds)F\p0CeH % u " FePFCN`~_ ~!"d$%a'(j*+z-/01s34p5'55.T&a%L3"G38<G4K?GDP@UITL\MaRaXgVl\n_raybh~iklomnlaS+HW t7ܖQܜiܤ}ܰܗܬ+݇ݺ.M9/Qx~{gDd#'k9^~ $5JXl $Dg? % ~ ; tPTw| J"#9%&A()N+,b./o12`4454I57Zc\Q1/<QK8=5O7J>OAQGUIVPWS_S`Yc]fch`liknorystz{{|zT)ڕd?sT{i܌}ܙ܍ܩܢܺܶ:ސ*bT4*aEJFLJMQOQRUUXY\Va]d_h_obqfrexkxmjntkqrlgS+Y-?J k#o;vN܆cܔvܟ܈ܯܚܾܰܿ?>NX/ ?8?m9JCy-Qk$7E]r7c L < u)|~dqdM$ !"$%'(*+-.013454 67%lN@f!SDJ>X@WD[IZL`OaReVeZfZn`igo`wirk|lyr{st{{|{Et5C+K?YQjfvt܅܅ܔܓܠܤܷܸܹ߮=:HV#RV4a5H[n|,Lj$^ L W hC Bh; U"#?%&=()C+,J./D12455y6)]fm0XJ/s2FQR@[GUPWO^P]W`Vd\g\k_lapereviwj|lp~qossutqgV%Qz9A+R9YJg^xl܇}ܖ܏ܤܝܴܳGu %f3Lf_aD-TaW"Gg$5FSj$Hw Z P  ;v| [B !#$&')* ,- /02345X5;33>$4-[^/bJUJaJaLaRfPhVhWlZm]qat^xdwdg~hnlpompopgdT& ,)DFJ*Y?hOq_܁s܌ܛܗܬTxp-~tDn&uK|1I`l,B_{4k  `  f 1yW,  (]x_!`"#I%&D()E+-F.0<13354t6^.N&=Cl(Jq8\SVObL`U`UgXe_j]lajglfqkrmsoxowwyrz|{z|~p=:b$ +6.E>SNa]njzy܈܍ܰ_JfK9csL)q,.r@d &7KVe{"<c) k  m  Y.fj !9#$$&'))*5,-?/0D23505D6, ##kg 4(=uNFeUUV`X^^aYf]bdfbldmeneskqlxlzm~omsquqtvmkfP Q'd'1<.IPUO6D\ H@^x$5DVj9` < / TaL857Kd5B!"$% '( *+-.0134956.v6(H)0CA[RpeYigcglalllevhnmqjymsswoznr~qrvrsqttqnjaJb0Oڿ۲ %+7%B6ܪܻOqe#as.j` Ds9Jbl{ 4KfO A A D'c- !}#$e&'c)*r,-~/023V5(55A2e_=k?y^k\sXu^r^z`rfxc{gsh}ixk~kiomomroppsqnkbUAQ{5ٷ۝۴ (1J8ݕ7K2OcywX?dv!g.Qq'6EUf| $Ht H G _)rSN?QTyMK!"$%'(*+-.012446&$m<WQgpj]velhtgnlulsjwkussozsvuysyw}qz{}}wz{~~}~rI..5۽۷ "ܵ݅&R P.!W5Uet +@[v1d  L U [5 5qI "#$q&'m)*q,-y/0s2355 1 vy\AKNsT}enhwbvkvdxkwk}kyl}nxqlmqqmrnqrqopjjdZH! 0ڛۇۛ۫۶LjzoJ}g02<{Dl)>JZhz8] [  [  u;jgRkg k ]!"7$%%'(*+-.0124459Fq T2AsOvtne{jsounuqtpxrtvtuvqyysyvzxxtv}w}uuwuvtqrgdZDL&ٔڷsۈەۤ۱<޸]`6y!)<(!r*M1f ,Ogx)6NaCv U  i q< Pzb )"# %t&(l)+g, .c/1H2446)kpGb_kyniynostnurtqturuwrvvtywszzuxv}zvw~xz{|z}y}||zvyxnj6$׻ۋی۔ۖۛ۞ۦۭۨ۲۷ۼ^ܐ߯>4?z~OPS0Y ':NYgv+Fo. h  f  K {xdvy#w" p!"K$%:'(8*+0-.'013452JR5aKz[ukrxovqwrusxuuvtvvyr{uxt|q|t}v{tprqptljif^R> rUۨlۥtۧۅ۰ۏ۸ۜ۽ۣ۰ۼ~ߡo$ORfPFF eGGd{*9D`u 0V  g  } +L7 ,f H"#-%&"(x)'+r,*.e/71B2?44;6]qvOx4#JtTyxhj}o}lj}qjq~oomq~qnrqlqqmnlnlie`UN;DـڈPۙaۖnۛx۠ۄۥۑۮۚ۶ۦۺۄm{8vt:oiIt!;Rak~&=W~D ' u ( ^# H1 !"q$%d'(b*+g-.e01h3W4D6,=|Y;aPbmpuu~uzwvyxu~szyxu|wxw{xyv}uyyzwzx}v{v|w{v}s~v|tspri[+hמ]glolsuۀ~ۆۅۑۏەۖ۟ۛ 3ݾM]F,W{zhEf"|%d4Xy"0@P`n=h 6 } - D hL" 3H5 ^"#A%&9()9+,D./>1q2$4537b?NZeuV[|{olq}umq~pnq|rpnrqlmkiiieec][TD1*Q(y8rDxRzYۀfۅpێ~ے۳۱ޱ4=n#Y3+a:Qcw '7Pj%V 4 @ p@c@ ! #$%'(*+-.01304K6!%v 2%Pyczuu~|yx~y|x{zxw{zxyyxwzzyt}uztzuyspysxm~szhj}mfb`Tc b^$e.b=hJhPm\sd|jێ܀ޠ2`o8 8CDl,>IYet/Gv L < ZZA/$"1EiU !k"#L%&>()C+,?./01235-hAEtKU]gzpyz}v}}z}{|x~x|y|w~xzx~r|t{u}rxr}p|rwrynyn{k|i|i}gdZF/׆(<7D7G?KHWQ[Vc^hۿ] O1EHC-}:T=w 2Ofy &1L]x9g A Q ~R ,zV !#$&'(*+-.013y4t4A]Ray}yyz}z|z|yw}zwx{sytztws{n{oyo|hxmxg|g}ba~^~\WL@,v@)KFIJ%J+P3U=~9ܻ5TI^S)N ])W{)=O\ju2\~" Z E lbT86.GM~n!q"#O%&?():+,0./1336`%V'#BWriwvzvwuuu~rzuzq|r{o{owpxixkyhulwdwfvduft`x_v\yY{UzNta9A<'1- ,.3 ;'>9ݡ$:6\es_Q*O j OGcx %4DXmHq  S ` ^( Dm !;#$&')*,-/0 2j350 .8:d/Anenz}|{|{~z|{zxyyuxyrwutvwmvsrkykooqfwephqdrbq[y[tWzO<:[ٲ  &oly<tBkoCk%;O[nz +Gi1 j  W  ~4vhGK@\d$7!" $b%&T()K+,A.0$1335*`vu|{{z||zyxyztyuqtxmumsmsnoiqinhp`pcjan^j^mWjYlPnNmHb_j۩#IIu"V1|&Z5I[ku )>Zw < x  i  Iw^\Wiy?G!"$%'p(*l+,d./_12l41L -[lL4ujn|y}~zu{}t~r|tyo}lxnvnshthscqfobq^l^oZkXmSmSmNpEs@{'4وڷ܁ߤ7(,kj>=>{De%2?LYfx:\ 6 x  z 7tT&3{8 !w#$[&'Y)*^,-g/0w2,344#y]H]p}w}||x|ws}rtrunvnrnpevdqeoan`oZmZnSmTkNpFsDt9~. ؊ڔڟڭڱڸھڇi% V$1SLL'z@LEq&C]mx #,BPoH - + ^yjw{] U!"%$%'(*+,./12 5*:3F hv~~|{~z|x|t}rtsymuqplrimjiflck`h_e_f[fV`Y`RcM^R\I\IXFFj&|zַٽڔڝڣھڧڿکڿڰڴ)@Up_gZ'RU*Vw !8EPaix)Gk B , Gg3  2MS "#$r&'i)*k,-n/0b23 2=e?4uj'bq}zz|xxypwwnpprknlodoghdiagad[fVcWaPcQ_L`Fd>e:e/s{fyګچګڌڪڊکړڧڑڦړګ+ݯO\=N_xomN8YcV9Tl| '.:V`,Y ? ; t0{+|$ g!"8$%'( *+-./124{K6ek}yytuqo~p|h|jwgvctco_o]pZk[hUkMiPdMeGgDb@f8f7g+ot \cٛZڮeڥpڡtڝvښ|ژڋFyޛ>= MxJl$q @l#8%umqy|yturk}oujzerhq_n_k^i[kTfWaNeN]MaD\DY@Z9^5Y1]'cl!@CQvSqVsZq]pڃfۻ]xC"-6)f!:$V1FYcqz 0Ki% \  Q e)d?4$#BT, Q"#-%&(t)+d,$.M/>11x4"fe%'0 cz}x~yuxwrssoreqkkei`hcbYgW`U`N]P[HYGUCW@R<X5R1W(V!^cs.m;g#x-j2d9^;]>c$ܖD߽ZI7iG@6wGc$0<FWg{'G{  V _ R$!U@ !#n$%U'(G*+F-.G013-M;mj5\rzy}}y|wxsxrqprkmleii`cd^__[Z\TWTRRTLLNJHHEGBBA?<<:9748-< xM5qإE+I-E0=0@0<1x܄.f$;NKI/w9I9lP:K3M0H*J#LPZuyֹ E@96.EW|v/c_YK)Uu$0?ET_p5Y  a  k `, ,mH ! #$%n'(h*+n-.0f13&MT%2 l||zw~q}rwjxjqdmfi_k[h[cUcN\NZJXFWASBS9M8L3M+J+F#HLNTa 2;-(& ڑڣDkmKU]{llK6UZ N .I`o| "*9Oh= v  l  F]R=GEdu [!t"#S%&B()7+,5./12/ ^Rm2{TFrv|wx{szrtorkoembff`\eZ[XYTSSSLMMHFLAEAC;<::6842/3-+)'-1p'N؁ 1%ۏ$޹HB] y@ka8c%8DQ\br'?j . p  } ({?!?\ !#$%'(*+-.0o1^3t@AqUjs~zxynpzkyfqcrdg\nVgV_TaK[NUIXAQBO:M5J4F.G)C&C<?CBOk֎٣ۀߢ {HymRkq`?\s  )6CUoN ' s " JmWRLVh#p!x"#L%&6()&+,./093i); $Pnx}yw}owqqlqekbj`e\aZ[U[OXIUHPCM?K:I6C3A,@(<%<;98 ::@K֘ٲںٺټپP۶e߀x@{-\x/uFk4ATXdpz*Jo : z ) 3I&)L#h !&#$&'(*+-.010_dhx}*iq~wxryqxhskpbj`fb`V`XXTWPPMMGOAGB??>6<3532,-**",&(i{FٽٹٸٷٽٴٴܭI\E=wd:|5.m 4Sq(7=O`t1\ / 7 Y(hj[tz/>!"$W%&?()++,.00'3 l~O>bv}}tzwroukglhebca]X]UWQQKPHNDI=I;D5B.?+:'6#33.,0-3=Wu:wٰ\ةٕٙٙ٘ٵٗ2ڌܪ&2 yIHT=2w)H$Y4HV_lw#8R} J 6 H_4=l8 !S#$0&')*,-/Y0|2E+jGnV1c,nzr|}}tysqorgkgfbf[aX^SXQRNQGO@G>E7@3?0:'7'3 /-*( (#(&-9Dւ׬عr~ٴ{٩}٠|hݍ 6f|[N=yGi%2>JXh=g : B e5uzk@M!"$i%'N()<+,#.01k1)rhn{v~vkunpikdkaaZcYVWZLQPLDLEC?A:;592.3,)*)!""   gللنـ{{wqُRڵCeqC"Iems`J'CW:j&?Tenx /@c" W B Vn>%,J= !m#$O&'?)*?,q-S/(028#AI7grxtvzoyiqin_h\gU`V[MVLUDSDF@H4B5>09';#32*'& %  $+FnO1ؚ)nNٖVنR}UzW۩%G>ht/dN/Wt07AHWfs #Dv  J N s=~%\Y!"'$% 'r()e+,a./1I- R[lDSxst~r~owntimdj^eZ`T\SVLVDQCJ>F7C4:1=&5&/!-$"!   ^{z:~;n@e<[xيې߱%EudD_ eO3K_ny(=Nm. b L  hO:AXQ "#$e&'[)*[,}-o/K01>Kw)=b bkwq|pvjvcmdjWgX\RXMVGQFHBD<@8;26+4(+#)$    Z`޵ռIHGF>;83DJlߋx>"#I pk;_!1?HMYdw(Ow  V S G/w ]!")$%'()+,./2 &s <#9 dzz}y~vtspqkjfe`a[XV[MULOFJBE<C4>04/3"1!'(#   ,]"Uz1SE81vپK]COqf&w x$b"=[ly  &5D^z 7 m Y o.]B("$*Pm(h "#$q&'h)*Z,-J/0G. Eq+vS=hjyv|qvoohige]^]XTVSNMHGE>@@7855,0*+!(  L8G7>/ Jڗ ݼ4:~EET6.m:Jq 3HP[eku4V ) m  a T.>2 o!"9$%'()+,./1Wt> lJZi|o{kqlo`gac]ZUXQPLLFGB@=<7242*)*'"#   rTݧՎ׺ ؗoޙ)#2xJ=8t1Qh{$*6BRmD {  h  ~:qQ?./2Ea3 :"#%x&'`)*F,-/f1':"#Gfqvy{pwpqhkbj]`Y^SUQRGLBG<B8;29+6%/ )#HaֿB1Fi nA(?k`qPH2K#V|1ASWdju !>_ 5 w  n +`;)PA !"N$%('(*+,./emq&ectvozeqdi_fW`QZMSJQ@J<C6?08*3%/$# ؼعض۷8TFed$RD}Acw&)8>J`u!N  * t  LZQ;D>\jB X"#3%}&(^)+A,,..^1^lL3^hygzhobj^cY[U[JUIKAF>B5<16+1$+ "    Y>F܂X~ؽػرؾصCw ܔ3߶A&Plzd: M]:l$:M[emu 3Jt > } # { 4wF 9pM ! #t$%U'(G*+E-.0$*5^O+Q"gbp}jorrodo]c^aQ[RSIOCJ>D6?/6-2&/&" l6:L֏؆؍؈رOw')@ /= i U,Zq ',<>LZk .Y 4 , [mfPYPn~$V w"#M%&7(u).+[,:.;//uJ k^^wtgudj^bX_WTLTHEHD8>7700-*$(  +D״~زy؞wذJ8bkQMqz]$mhR ,AVbpq}*B] H 6 ?L/(EY !#$%'(x*+-_.0F"2 H+  Ryfq}linbda\WXSNMJFDB?:7502+&'"  y1/(aHp،n؂g{ ڒ7ݼXX*t%6N?:X}!l ?e| ,2<CMWaw7g  > 9 g&qcfg6v!"#U%&;()++, ./+'=]`.Ledxa~ohhh\^_YRSOIKCB<>9512**$'!  y\$<m*Q7،Nk Q E I_G   G]9o !/#$%'(*+-./ L\NR{pg[nU^WYLRDN>E9?4504$+"$  zձ֯`8_6JD IoߌW(JhjpV?v+<Lp-8DIPWdo~ $Hs N K s:{tD?9?/4,.$)#  sPkUI;؝ؤ>۽cxf$_U":=q+G]o} $4@Xr* [  N YoN%"PsG !D#$&')*+-/N,8 LrM5]:0aXwQwcbWcQWISAM;D8;07(0!.# |o]Dv 7?(8v1ܥT\<[ioc- =R+Y}&;EQX\cmx.P  U W |N-S[!"*$l% 'C(*"+--/ D- PsFJvRpccTaOVMLEJ<@6<,3*,!'   {tNԃ؜nݘ0-O%x5XLD^t&0;J_~; n Z  o$Y;! ?[O "o#$J&'5)*<,J-/%ZT"wIf`^lZW\SOOGI?B7833*,"&  ~mdP5].ի%\ٸh݌k?xG P `6f2DNZ]dkw ;]  _ e V9ej!"2$|%'^(*@+,B.U- 4YPeLqLr[SUXHQEC>?66.0&&& xodVG/APףץأ7ږWoi8o()I04 Ar R%Sm "+0@L`}E {  Z  |+\N*),+We(X "#$j&'\){*h,6-/SXB)?eH^`SKVBNC@9>-6*+!%{|xsmlhebTe,A8ק׻תAnێ'ޯ;-2rb-iiHv";HV]elp#?d ' h  k _&@{ p!"6$%'()+,. (6}?|1TGQ~XMcRIOHC@?670/)'!!  zvj^U~E3i֕׼{iۓߩiMMhRP%[` 8[y!!02;GXl$L  d  6l[27#76fv9k "#$|&'j)*h,v--0q/Mdf;rr;cNPDQ6E59,7#.$  utf[|PwFs9s*t{Oթ՚֢XסwlؑG۶n~eR= ~'u$X -AR_hksx +Hh 3 q  n %d6I+ q!"1$% '()+,/Q %35XxBOTK@K::17*/"$ }z|qqofedW^URKNCH0O_l[m ق!ܮCI#{ A`tzs^Dp(0s=_z+/3<FR\u%L ! m  @u\B;/<Eg<| ,"#$v&'])*8,-)(8GgQ7/@BsX:]D@?C/:,1#*   zoiz]xWkKk>f6c&ffo!F0hi׊لܪJ~W#:/h7N`hrwz4Os > }  w 3mD9UF !#@$%'()+, ..):{i1aj2UK>9@08*/!%  |n|lq^rWeN`EZ9W+R"PRRvaxYV jU٩nݍc0pvqc(4HEg$/9?AIQ[j+U 2 z $ PbYBEC_qC N"#%r&(G)+,u.e#&qh+Hr??O@7:41('$  }ysqog`d[WWTEMD@9>.5%19zR3շ'׈לڨD\Sm !*%p-L:p.E\irz &5Rx F # ~ <sK>cP ! #T$%)'(*+#-D+ /(B>! C3bS2K=926'*$ ~q}nt`n\hO`FZ;S0O)EHDKctשP׈ک޿$.P|>GW"Qo .6DHMPZct .V 8 & XiaGVLpwG f"#:%l& (A)/++$.t[*TCp%Me*G<5+8#)" yp{hs^kTdOYCV7L6D%C98420:9֧ץbۉޘN14M24;_@t8Oeq~ (?W} E . A~R&>uO !#n$%L'(A*v+-&a @&9`8/E1(,&wuqngdb\WRNKGB<?03,+  ZBtg&ؑ*ۻQ_AB{U%SZ1Z} -:>GJRYfq2^ 8 . `ogKXQq|"N l"#>%|&&(R) +8,T,V_y3<E!PRB/.1zp{mr_nQfL\DS8M1B&<50-'&,DkRfԏծִ֫؎۷&rLMdIJE iK~AFOP\ju>e = : c&~l]]f{(c !p"#:%&()*,(H]"F(Q19"  zvpqff]_RVMMBE8;31&+  IJ\2#ִ(ٸMhk=!Lgyzp[>bu]$E]o| !,;Mk O C G]B>T2^ !#$%'(*w+,)) PFBD4& wynoeg^aOXJM?J2?+3!-' #L+:G{ןٺ1.cE"oQz.;BLRWWdo(Hs  D H p7wyj}50!y"#=%& ()*8- i;Xz,O", ~x|fs`hV^NUDL:F09)2* wgԿԆֹׁڞ޶{:{n] ~#2r)Qbu !'*7EWr% V  K VhKIj=y !0#$%'(k*+) fySC. )  zztmjf]\WTKNA;?8-0'$" g4 ܘGIo߁r2*)-a%9,Z'8HRTZadnv0S~  P U wJ z&LS!"$K%&()*,pA6VR Y@-?${w~jsbkVdOVFM:C1=$3*$q-  !Y#$0&s'$).*,"3c{E6p;  ztoncdZ[PSDI<@07'+!# dMӇԪՍؤ'(o>AP<4 ~1P1b2LR\a`hor1X  W  Z O1Z]!""$f%&=()@+) k4 "|~ovghb^P[JJBE3=..#' w0%cԮ?nݔ%q$mZ&NMLj)'(29@Pb? s  X t(]I%%('Ra"N !#$f&}'a),*H,N am:$+ |ytqgj]\UVFIAB18*,"'  oT9>74,'## |vTFӛs֘1E<]u3h V2Xw%*+23<FQgL |  \  |2eT-163bp1^ "#$o&'V)*&*d/u # }yumic_[VMME?<:,/)! |eMZLղRۉ5ޠ<fHawi:Us I|6N[invv|!=c 0 t  g '_6$B1 i!"$%&()+e.LozRqI< {sugo\cSYGO?C2<(0$reP3)F> U k^! ?w_Gg9{ )"#$a&'")+h%h!9`ytuig`^WSLK?@82.(!! {nych`HfEM]pE ~  m  CZI398Td2 C"#%B&((\+89<#|%4 {tmm`_XVNKCC69.-!" xh^M}?y+z ;2`"jFUi}k+|x)d:N_hnut|,Eh 3 q  t 'i; 3Y? !">$%'(!*' yQ\ qrlh`aUOMJ==8/,( u}omchS\LS=K.%g5|@g&05=@ABITcwF z # t  MXV8H;_c0 X"}#(%<&((*zp# "{Cy{rmccZWSJDG:41+% xjv`kRhB^7W%Xg@Hو;ݪE2%u~?00n'@Vervy| !2Nm 4 x  { .sB5p? !"h$%Q'a(*v!"? cz4vqkk]\STIJ=<24') }ocxYlJk8a-XTYc> d`Aހ:xG5:t_xPN,LRm%3?DGMIQWak#P 4 $ \igP]Qy#L n"#:%o&(j)'s x"J}rthi[_QRFJ:;12$% r|gi\cNWFM8C.5/$ #G׮ZgWkc"K;x7Sev}  '<Wx < ~ - 9J,/DI !"$%'W(t*\ig,twon]fTZIJ?A29&( |q|crXfK\@R2J$>;65GنY ۧc`9z Sdm`, ?V+[})2AJESLSY]r.Z 6 / ] ndci*r!h"#%%&'*!~fv=h*uzkgccTVHK?<42'(xmy_rTbJ\8S.H">8--*8|׃3zVߎBu,% z+aE}B_s| +=[ E 1 AX7 @W.] ! #$%'(J( o4z3ypskfY`OLHC89/-!#wumegZURKG@;7-($ MH`EPutPDeoN_Z>n(=>IMKNRXcq:j 7 > ]3u{k6>!f" $%&'* a>RyvplcbXRNJ@;9-,# rxcoZ`NX@M3B$=. ',[57{vB݉o7e""G-2ApV/Me}!3F_ R 7 N jD! %Gt5 !G#$&T'X)#ICEE{\snmd]\OPJ?850, zst`lU_NR?J0>$7) 4s,eݧwS (u+zk!W!6?KOTUW^ajy )Ju  A Q pF{4Oc!"'$A%'(:( ,0Ti!rzhi_`ORJD<;,/"# xqpjb]WNLH=86,($/}5,޲/a#JZe\Q0 b#*i5[v "(.@Om, e J fQ> #"O^I !#$p&=')`|9&|;yzmuaeYWHQ=@15#) yqz_nVaLT?J2A!6% ! p׾ڕ޹D19+)#5~,ܐߋX`jk[$4BEi}$%+).14?L^z5 p W  x/gY7:*A@sIm "#$&''j *IX |sgp^^NYDJ7>*/"& wxjnZcPSGF7>)0(iNXڪL?o!$ h6IX`jnqnuv} "6[ ) i f "c:>XN v!#%$%&)!Y`@k*ptvqtab_TLM@:9/('qrhjZ_KRBF4;$,# n[Pdi{BC"=H@"H a+Qr-3:>5?BANZqC w  n  H iWLJRc[ U"#%%]&\(+"G)(UP8purnhbV\IJ@@/3'# }wmhf]VTIF=83(% wWXXT ڞݶ\8BSA;Jh N=Yjrx )Ac 9 |  t 8tT _xx !6#N$&'E'_ 4FlepicdOUKG8;0,"# |xmm_aURFG9<.0& tUWQ ٱf HqaC`$q:e/=FBKFKOT[i~!M 0 & _yw]niFj!"#x%E&(7+$O'X`cwseX`QQAD86'+txmj[dPRBF7;*/! zeR^׋r@$(n^\e']"Y.Odv 0Nq H ' E`1:p' !2#$%'X"5FC)~^rq`r_\QOE@;9(%"wymce\ONK<>10( xiyXxM1 EJ R }2Ot'4BJOOQPVW`t ,W ; 1 m#p{b!"#%&& is,u_{OqYWES6@/3' z~lr[eSVEL4?,2(  vgV?) gH6MYW|J8p9)n>]q  ,A[ K 8 NhJ' $/d~\ ",#$%({3k?HtL[]PCG77,,xqlb_VQIE9<3(""wfuWhKZAmc)$5e'7)3e2B7h/@ISTTXYY`jv<l  D I }B6v Z!"$i%>'C"/2eH_\HcFG;>*.$u{hmZaPPGF1;(+ wiXyFq6j 8ޮ#2wd]L1Xs"&(&)26GZx2 g `  v9WU7I?dm< k"#A%6&&u@SieJpo:`EC6@!. vvgnT_NP?D3<#, uhWHm6ozr}6a1@@kip6$`$X.Japw0Iq < , ?[; TpO} "!#$%(6J$U%;aw?RL@2?&'! vyhj_`LTCA69&,! {iZG{5u"|uf_p/G*zP)Y!7GTXZa]_bht@k  R M M%,T< !"H$%a'"en[7y%. U?LrP=Q:63.!  zvjl]^QOFG3:*,zl^L{8u#v?BLi@w=VW+0% tbS?',5'g AmLw%38DDCGIT]l 1] B A ~@-IF l!#!$%&6' J`?IN2ZZ$J1/-vzlo\eRUDM7@-1 %tiUJ* #8TׂYތ`/jTQC&Kl ('+6I[| 9 p  i  JtpbnlV!"#%e&(#qI|'Nd'@:-!+ zmrbgU[JO=B53'+# o]Q8L3Hg b60?xofi4Y%X(Fal{ "7Rw N ; ^YG/*$6EiC >"#%K&M(! l S)?h6.D."(  }vqghYXQOCE76,,! |eZB m֜nݶT.)B')w+S0^#DFGIMR`p *`  I D B$?Z\ !#2$&& )qRX't P^%?5(#&}yojcbTWIGA>42&'veS0USڪ؋.=2Un89E>aq#&)1:H] > t  n  V{vz#gK!"$%&( HX^$G_53C+%$  }qqffX\PNBE58-+! ~o]=PN_uk<CQofhL6\ kY.a3?PYY_bajp6X , q  u 9`0!  >SE !#$~&I'R)R&l(h!Q]A7' * wxoo`eSULL>C52+*" qR*ۣԌەߖw(fk2e]>c+49>==HOYg3g F O R%Exd !!#h$&'Z) % f_$>`1-=+#$ {{qmfe\UPKE@7:+-# wb'[Tקَ(ݩ.r Nt\6~<5wB^w "+6D`zF   o & U*Ak {!"D$%'(&{*x1./62ZI#C.&#& }tpqgaYWNKE=<20-  l6Գ4&۸EDp&JU`UF$L h N;Wfqz %<V [ E w&ogEQAcc5!Z"$%&')m]K1vb$TZ$E1,")xqlk`]VSLIA<63*%$ {DDPYغK]Mea>)]0ETU^_ehls 7_ 1 | " DhG/,Rp2p "#$&')R5t$Hc45?0(, xsmgb\WTLGB?32-%  OBݔQGpuU M]'a ]5c )3>>=DHQ\n@o  N [ d,6Q4j !'#$%')&4lr+;068aK*G2/'* yxuqhe\^SQHE:=3+((]Gma|wO1X}oJ't,/k 8\p)+7J\H  t . Y3Vx !"h$|%^',(*~ty2m-Va+I96+1" |vomf`YWRKDC:45*'! ,߸7fڑݛI)6H9. ;ZDr2L^kuy| #>Y Y K k+xcNJM\o+{)!z"#9%&'0*H!|c+Kl;9L303)" ~zlqe`[YNPCE<:.2"* sԟS~(ߊn#zsHs*xKw'7DKSXVZbix6[ & m  0W? )8ty 2"i#%6&'!)W( gZ ] >9I9dY0S9;)8( ~pvkm]fTYIP=E3?*0' o m٠ܱ {=~l3 ;HIk%/248?IRcx 1a ? P S"?"T !#$%'s(*[K/Q}P$/]m5NB?0;'.$ xrqho\_TZ?S>B/?%2)  wӞӃL/ۀ@ޓ>N*3`Q^:/[h!`BYk{'1E\z 5 q  p  W}3y m!"3$%'W(f*#!S=LsL?SA7=4/&% y{rvcj[cOZEL:J.;+/+ms[Ջ+#g !Y-:;q7LV`gjptv '?Y G K ^.|PP7QGv}:`!"#j%&U(l)w)B q\QR ]>ra;[GB?=11)("w|prdgZ\MYBM:E/;%2* $ k8ӸgUڣqwY5n&rbIv)6BDOSV\en:^ $ n # 1ZE/:~ ?"n#%2&((B+EG-8gzCVWE@G851,$"{txot\lX]NUCO7B.>!4* % fuh iԱ0SW65F~zJ6v?9z%Qq"+.48>KPd8i  J R Y-(X!w !7#$&'(*$G0 UBV{YIcIEAF1;-0!' xu{dq\iRaGX@K5G(?2-'"#2`u"0IօmٿڎݚR74U9=D n Q(Iax )8D\}A z $ x & c%:8 l!",$%&()$*#.WfiLxt?mMPFO5D2:"/& xk{ir[kQbIV xedfuQJ!"$x%&h()+%rs9/I"c]gq]yd[[^LTGH<?75-0%$wswdp]gTaGY=P3L$KKU7cMKշ0Zw }XGqqNY _>m 4BNUYbgjx  >h ? * P{MB!*7:q[!>"#%&')*q+i*EoZX}ng]kSXMTAJ<?39(0$# oyhlbeUaLUBR3J,IW\JխpR}ޓXEZb^Q2j'0xCg"'4=?FIVcsBu  [  a iB$=< !p#$R&'T)1*,6Hh'H(^luxlcn\`VVMNEE;=24*+#" }wxmmfe]^RWLM=M*PW}pX4l؀ܥ/߲+S! {:` T Hbt &,5ASk#V 2 B tC/qM ! #$%]'(8*+'%'8~Gd>hqwltkos^b^\QQLJCA<8.1+' tutiig`[YSRDQL,ӊp}ڧEQ?GL3,j(FYjx%6Nj4 r c  Emxo5[y!"C$x%,'J(.*+H,c1 0x%ok}}q~bnbeV_OSEO?F5=/0),  |w}mtfnYfTXO7://(%" ~tmzauWjOThckӟs/֟֟Bٺl݀}G >H`XP*g36yQu&3;BJHV^g1T  h  } ,U9 !9mu -"~#$Y&'A)*o,(RRs_zPo|}~ttllea^^SOQKCB?823.&'!  zwj`zPtXFRӯԁU֊DHr߆s1{9h O)Sp#(/1>I`v7h ? W `!/I6h ! #$%'(*+, V;/0v{s}uqhmcd[YURLLC?><211&'# zpaPKӵԊp'րyٖݵ,c /Kdu/?WxC  r ' X-L| !"^$%G'z(M*3+- B;RxV12'y~{urmoea^]VSPJGD:?95+0"&  taUr -:V]gmuw$8[ T M m0}`SGRZz=})!"#l%&R()1+,a)2Fmcp{w{nuhnaiU_QWHOAG8B/8+0 ("  {lT28Թԡդ\֦֖־ض$CCLGU80s$?Ir /?IMSXdkz9d / w ' >dL'" :L- V"#.%d&(<)!+,}-O;JI6 smvjp_hWaRYFS>K8C4;)3-$  rZ*`ԸԪվr։r׋Fڳm|k._oB]^'Pm"*0<>GNbs?q  V d h>CkF "P#$&&'(*+2.!?3C_4M0|z}mvjjbgY_SXJOEI9D27.3!-# `)$YչԼ֓֗A-Fq}_ h|=.6v-G_v%,5EXnH 4 3 w62\V !#i$%G'(5*+^-1* #r{wvtlifdZ^VYLNIH@B79/4(- &   f)ձ֬װsږ޳|2qt{VE_]R(AU`gpw~ #4Sp# `  i vMqu^wno E!" $%&()+,*.EjWnGwyskogdc]\YRNLK@D9<45,0"+  u/wֱ #"וl,ܛL߰L"_&-T@E d13~)[ !7EKU]_lx-Lv C ; R{d?8*37XoW s"#K%&9({)<+7,.\#y$6e8`E ||urlrcbabS^LTJJ@D;<1<)1"-#   80ן8&\ץٴ*C:bx1k Z7^z%-;@DPVi (L ! c  p ,xO( 1QW "#$e&'Q)*B,-}+8 X>~,|x}q{gsdh\eV[NYEPAF9D0=,4$-)"  HG<؈N9@=؉6۵_oR;~bA~50m 5Vk}'.:F]w*Z ? B F"Lnt !8#~$&X')4*",,.r/Qr]Iyt{ivdn_dZaMZMNBP9F1>27(2 /&  \`ق 3>j:TB,Ss rJ2Lsyj^5Q lK{5Rap +>Tv > w  n  T|7y" w!"?$%'()+,'/%hu'X}syvtkneg_cT[SQGR?E?D2:15%."&$ pl)Be׈bx\dی ߡW/3C-!n%?%V2CT^gmt~1U{ Y E o%lbIOD`i)9!" $Y%&;()(+,7., nz4y<~}wssjjjbc_[XVNMKJA@==360.** %  t{4S׋ן׉ג{ײ׀~"ݩ;4Dq;cd1^}'4?HNV`j|/] 6 { # | Cj</#Uj?u +"#$&')*,n-/,>L_+Y!~{ysoopcbf`XXUQNKIE@>@4650).%#  f7mt7O׬׭שץםק<؈ ۥ5E03gi946y6^u &*2?EUj;j M Y _1 +a- !P#$.&'")~*),@-/}&YBO}!i4wx|qlpjed`^YYSQNIIG>E=874./')!# e*muLY׹׿ײ&٧9^a;DhqulY.Y mQ?Uh{)7JdR *  9 e;c9 !"$%i'(`*+Z-.- ,^<\kK{w{nmnjef^[\WTPLOEGA=>8621-,#%" Q Za>gރy?-7)l$C)_6OWipw )Eb* i  Y  : |_h\y!Ma!"2$|%!'Z(*>+,-->0']Ge'|wuvopjhec]\YWRTINEL@A8?47.0#3)#=^e ؀Jxq"rf5_b3b%9DLS]gs  >f > . O yR:',EfO ["#/%&()*,-00(7k' H x~uypqjobh]bU^OYJRFL<J7D,D'= 96&"u[c55!IuڅިM~e14;x:bw"*4<DO_t$F  [ p yA' RwZ "f#$?&'))*,-/.)xYSyszn|dsdm]kSeQ_F\CY<Q8O+M$KJ>{^kRSB33!mܔ9߱Bh0Ig]\B,UcQ;Vg| *2BUl$Z 9 E uG 1|S !#$%'(*+-k.0~6pWMel/$~ur~lyft`qZmSgMeDc;]9W,]_Y P1j{t/w8g4Y9 ڳ+LH}'' ^*90f7O\huz $=Vs3 r  l  V}v~0u t!"D$%*'( *+)-[.0);Uyx~oh|ds_sSrMiHl:i4g#ms@\{דJؖM؅JwGػإA۸k}i%Um)o\ Bn);GR\apw9U H M _/zNM7KKs@r!"#|%&j()g+,k./I/I(8Wa wsl~g|^yWwNtJs:u0zU\փת`صfأfؔbرYOw~]PgV;zC5zQo -6:JQ\o7` $ r # 8]H 5?~# O"#-%x&"(a)+@,2..j1R;Xqx|:;!~|vpdcWPF50MY֔؈؅ص؄ص|ۛ߷rUTmUQ"NsU'Me|+2ARa|:o  P [ a14c: !W#$9&'$)*,-. 1)9)e!|yshaVN>#"P֣؜ئئآu+ݡKJW(j I/e'G\i{5F^K ~ -  , i.#OQ !#k$%L'(3*+#-. 00z4ATUp"|vvj_UG){wo<֬ػ ؿ۽;RBZd;foEp%;KXemr%Ae& `  Z x?leWej _ L!"$%&()+,./1 nOBH 2  wjeS5 -ֺ%؍٪Pv^/qxc0:GKl2:q&E[oz$5EVq"T @ > @Is t !A#$'&x')h*,H-4/02"25>Y9   ~^ "3 ";hEaDYAU>T ۂ)ޫC74}g,kfHx&;N[fr} 2On2 q  f  Nxuy7w }!"P$%:'(-*+%-.01,eb9L{1  =$ ,   y:1,0gقiyhtbpfn٤ٯܴAQ7)QyvV0!"$d%&O()?+,(. 001O!=>L:1A-  &  M1A9ًًْْٛٔويميٝaڸKqp@ 0FQI9 W r`.Wl!+3@NZi,S * s  z :`;#  Km8| 9"#%&')*,-/03%7 $?qN!-$(    xP߼/٫٢٭٣٪٣٥٣٣ٟ٣Da}l,sX>1l*Icw )4>[w .f E R W%&T3 !M#$-&'#)*,-/0>2.Z lI3:'!"*"  D-ٵٰٳٷٽٲٵU~ mX{U`c@p!AQbk{#7Oo ; }  n & V%S) !"y$%i'(h*+n-.0P12e[ oK 5K4,,/(&%!   r)٠ۂ ߣ"s3]q{pdCw16Ms0?HUdk}/S} U K o+ufQLLbu@O!""$%'t( *h+-S.!0 138'Gaj<$Y$+83#3()%*&# #    ?5 rڌݥDLg)=3/ DlZ+Uv+2?OYm:_ - w ( ? hM,#!AYJ n"#J%&>();+,5./%12/' LV%-R?"B3.02,-+*#)#&#    &7,2("Q&ۭ1MEdW?*f1Shy);I]{=o  N e m/ Lm\ !"j#$N&';)*-,-/113%+'{^ AX>=0,9(/+.&)%)"""  >J4CKC;56DIܼhw] <~}F!Uh@o .C\it )>ZL % 4 l=/w[ !(#$&'(*+-.014(O IY{6,`5/G:/:9-603-+)/#,$%!'        ;`h!])Z3X3R4WڦNxzM.DifmQEw*@Ks!9FT^kv !@_$ `  Z ~@wngq}+u u!"B$%.'(%*+"-.01307(5#WO&Q9=5A/D0:.:(8(5'1$-"-(((#!     !1Cu1ډ>{EvQuRqRnڇڌ܎ [&".|F_Y'Pp$2?IWfu >i : 3 OzaC;)67^s+i!"#}%&s()v+,./1S2Q4O<EicjBi$ODA5N/E4B.B.:.<(9&6$5#/2,)*&&# " !!#1CtFيMڥYڗ^ڑeڎlڐoڐڄF{ޙ?6?I53o*Lbw!*7FXkFu  a  m %{N*8b"y B"# %&()+w,.g/!1#24*fMm ;)/m9?LD;H;B9?9@4>1<28.8+6+2(1%3!,!-.&)(% % # "#"'/:O1רFٛbڶpڰxگځڮچڪچکڎܲ-D0<\gN^] Lz'AVdu|(;QmR A @ H$], !f#$N&'G)*J,-P/0@231G.lV2(H&`W5QIDFH@FAB>@>8@:5:73:2314-2(2*-&,"1 *++(&)' $**/1@])ci؝Wٮ{ډڑڙڝڠکNqyKKQnXZ2m04'W|:DUbmx 4Ms/ m  q  _~EQ !#l$&[')R*,I-/.0&224LmYx x#Oj7MQIAPCFAIBDBA?>@;;:=6<3846/915+5+4$2'1 1 -0+,., 25;GckA8}\ٸڜګڴڸھ|U{r7 '9i U,[{"7GL[mz*Kw I F d-x\UIU\~TU!")$%'( *+ -./125+QRlk8/;sJ@]NFOOFNHKBKFFCE?J;B>A6C8<2@1>3:/<-;*8)9(6$573848 <BQkbgڼJ~ݑ :ktK 80j5Pn#0?K^v$M # r  } :h=)%4_Y !e"#A%&2()0+,,./1232,4)8j2?O/ch4`OPGUETFOBS>PBL?M>K>F<J8G8C5D4B1B1=0?+@-<)?$:&<=:@A HPm@p  1%܄"ߩ<&ZvlAQ dFv.Icq{/>Yv+_  L T `7 !>V "#$&')*,-/02L3v5y [J* ,Sw<[UXI\JZGXKQGVCRGNBS@LDL@N>H?K;I9G:F5D8F1F/E1?-E*A(B$F GKXp3}%' &)*.15(ݼDS+3TX`G7q'=!Q},>Vak~ $8SxA % 0 l9  ?|w !F#$-&'))*),-1/072@3e5$,RKPVNRb$=<DyRO`ZO^TUTTQVNUOTKQMSHPMLFRFIHMAJFG@N>GBI<H;G9C7E3F4G,H+I&M"R q2׀8#8%=,A3D7I?ME۰Ikg0r  s=_[(Ys !4@M]fz1N~ ] O ~8 ~fph;o !"r$%`'(d*+j-.o01e3Q43=U_2mn@f[YUbN]U[O[OVOUPVPRRUKRQNJTMILMKHLIIHIGIDGEDBG@H;G>F:M3L-V hր8KAJBRKXQ[V^\g_ۑkfi fvA 31p/Pq*9E^j1Y 9 ' QTJ08,HW(C!"$w% 'k(*e+-b.*0A1.336|#-6UJ[a`ReW]Z^S^S^T\UZSXSZQWSSRWPTPTQQMNSLKTMJNNKMIKNGLIKFMBN?R2b.ք^XaZbcklrsrs|{ۀێ&pޏm @iw^7Q`Fu +Kaq #5C]x6l S  e vE'8g. L"#+%&%()'+,'./1235._5_S73*HAz`Nh`Z^`Y^]\Y]\YX\TXY[QXYUTWVSUVTTRSSQQRRPMQRNPNMOPMNMMMNKIP>Y pzx_h{oxۆ~ۋۃۑۋۖۓ݃#f5>F4c2}Is %;R_kz 7QuJ % } < iA !E: !O#$:&'1)*-,-&/02344yji2uj8jxAkb^WjUbZ`XaXaVaW]U]Z]T[XZU\VW[WVWZUTWWSXUSUWPVSWRVNXNWOVMXM<~vږlۜ{۝ۄ۟ۊۥےۨ۞۰ۣ۵۬ۤޞ<: L`/SR Ml-:LXgv-P! a  Q  ?nzrO/ !#$%'(*+-.013&4C6%I ,M6s<TO^gaZg]^`c\d^_^aa^^^^c]]`]^[cZ\_^ZcW^[`XaV_YbSeS^XdOcRdMhKfIZclڰۀۼۍۺۚۺۢۮ۹ۿ]ܯ*H6Sh|3_ 4 - PdH?4CNmFM!"'$%'(*+-.012W450# WP>LEnGw`cbmZj`d`kZkae\m[h]e]j[f\lYe^hWmYf\lWjVlWiWoSnSoQqOtKwI~:;Uێۢ۰ۺ2KݷXhDJ[qgaA&@P:m AYg|.>Xz 7s  S  i |I3  *>~2 o"#W%&R()[+,f./j1m2e4459O$w=gCrakYtZnYr[n[o^m]p]l]o_oXq_o[o^p[p]n_q[s\sXvWvVwUyT|MO@8%P;ۣ۲ۿ Fhf6'" JujCp3AVes "6SyF + 9 wF._N "s#$`&'\)*\,.R/11234K6(t } kCQUein[pbjcq_nbo`lfnas]ncpar`rdpbsau_rav_tbv\{_w^~Z~XTPG1]r%ٽ۲   'ܳw0czWI:y Lm !-?MYl7V Z  ^ }O {#Ua !1#$!&')*%,-&/{0#2\34h51l m4H% SDoRve`klakjfkiikjhkjijkgrhniqhqgthtftiuf{dyczb|dc]ZWJ5I ٸ $&+ 4;"G-܍y߄%o Wqv@"\wP'Kgx )9I^w6b , | 7 N vKS;WPd V!"4$%('( *+-.012445 WJ7=iLrmheugmiojohrkmppmqomroslunuotlymyn{n|mj|nefgbYP7a]ع<77BG'O7V@_L܂%ݙ'wJKY@3 z(J'Y ARlz(;Yt7q  V  m Q7  5N O !"#i%&f()i+,j./q12f44(6+vSTDTb^uihkqhnlqjqooltjvnukwowl}kzp|o~lnlonmljie_T;ٜخFBJ&O1Y?aMkVsb܀!ޕ7= Rn:``6_,&'@)*E,-Z/0d2U3=54T6!SXEaMwmub~d|h}j|j~m~klpqvsrvvrzyxvxutsscV #o>ر&7nBnQs^n܊zܓ܇ܞܔܨܝܻܲxݾVjH"Si}upQ6O[ K8Rm} ):Gdz*Z 6 - Xr]NNYj k ~!"c$%V'(Q*+V-.[01:3455-'8O?a3GQRibzqkynuovuur|uzw|u}||{z~~~~{ub"-ذ)R}_l܉wܒ܄ܟܒܨܠܴܩܵ;Sei82+-W,{X -CWex(<\x-a  ^ e -wa3)  -2k u5!"$p%'a( *c+-j.)0Z1&34544S@jmGzQnsjjxq~p}suv~z}}v>"ץ!n܉w܏܆ܛܓܦܠܴܭܹܿmx2m` WO,[| 3EXbs1Oz?  1 7 I)$B f ."#%&() +,./123v54x6Q%"DbVottj|jyq{u}qw{wz}y[P߮ח܌܊ܓܕܞܤܩܮܶܿ ݥy nJqqLfx!`,Mo1>Tf|%Gx Y U G/xr !I#$4&'4)*?,-H/0@234A55f04 kp0:)ROtZ{rmqxmwtzq}x{x{}~t\׊ۤ܏ܮܝܴܫܿܺn݃ a";QME1q:I5m(A[p1DZx N 4 % YleJVNx5h !"$%t'(*+-.013j4545d .0g1xEqOrqli}t~nuy|xDܝܬܾ *$\*ޛ!+Z{=rg Dq8K^l 4Oq,a V f +}b4(1@wD!""$%'(!*+6-.B01?3>454o6'qARzC^]oyuj~vwvv~~| sܪܿ(64E@Z.߱L@B|oE @ ' ? Q"&\% U"#;%&A()J+,_./b12B45\5Y5 2l (! B%QT~Uqvrntvx}|2Rܽ +9+C\Pn^zp݅ݛyfo;"+9'e=\=Wi"9Oj N ) { * Wt`VZ_w74 !#$%'(*,-/0234{54467+$:oL_HU\nyxlqyvx|~}aoG./;H&T8`JmZ~oݍ݃ݟݔ&Rf_pX+O Z*W|1A\kv ?`-d J  n SD!$&Vi;w3!"$%'(*+#-.)01 345x553B=:[G}Xouq|t}w{TM(?FM"[;iJza݆oݒ݂ݧݓݷݥwEn[!w}/q1Yt$8HWm9b?  } C vY#p& n"#`%&d()z+,./124454r6 [;^\Sm$ BiTxwuls|{xN'ٹ5V\'c=rP݂cݏwݞ݌ݯݜݳݤ)b1CaXZ5!~EOE~ 1Pj"5E\r@t X X  M"!UC "#%z&()+,!.//1244k54 6,]CKB[gbpty{wzEٻ6c%iT !2#$.&'9)*K,-^/0g2355544VJ: h4\_JsLm|kjtww~HJ6ٱ.(k8pP~fݏ}ݡݑݱݤݻ;>ߨ>:?tKGC$Qw!7I]q| =^"` H i XD&$+4c|DM!"2$%.'(8*+F-.E02+344546#-EC\Qxp{dktrzzNi1ؤ+?uRfݎyݟݑݰݣݹ +4H1#Kpwk^6TpW)Nl !5CVn;c2 u $ 4 M)<gB!p"#_%&f()y+-.013`435=555/I@>E/0HQi`so|~u|nk>Iݽ؛&X݂lݍ~ݠݔݲݩݿ ! 65ޫR`4"*9'i @&a(Hc| !/Hc{Bt F X  }VdA "#%&() +,./123]54545;l z.xjIpRsxnpzzeބؕ$zݐ݉ݠݟݵݭ*+9:NNލlhc"pe/[`8g:Qbz  ;ZxE p ) Pfg^xHh !H#$C&'P)*c,-y/023&5454u6'%Q'AZWs}tnv|O[N؅ݚݚݦݪݷݹ&.7>KWbl kiKyzX-w//o@c):Q_t6WS N a %cB6$*)N^M ~!"j$%m'({*+-/0234Q55B5O51 f_0MPxZsvvt}>1 ݴݟݲ 36EJ_`swފދk&IX`Q>@_GyA_~';Md|8b) p & 0 J5 Olj5!""$z%"'~(4*+M-.f01b3R4y545t46BSkBlMmzmmz}$ !pݨݺ21JF\[rpޅއޜޜޭ/ V T}/V=Sn-B^z<o J V  T1xf ="#,%&4()C+,Y.0_13-4N54~54[6G)k aVi<R]i{slx{,Vݰ /(D=YUljރކޙޗެްZ߫).Cx{IIM)X,CXi{;Xy <} " z $ Z{hxyou !V#$R&'^)+s,./*1|244U55U552 E'.!FKzxKhtomx|V'5ݴ'=1PNeb||ޒޓާާ޹޿$EJ8 Uiu^>bu a.Wz5CWn.[O N a ,oHD+<1Vd*` !"$%'(*,-"/0234y545f4S6,= k@[Ezj|bhswy !=ݼ *>+QEi`}uޑގީާ޿޼ EV0465h.C6l*Mi 4Fby,U- s  5 W0 (Wq?!"-$%4'(I*+_-.p01i34I55a54 6+P21V:GUattf}r|x| '=y )>T8bMzjޓނާޛ޽޳ߞig(fl.h ^ Gt @Tj)?Vw&[ L F G(Go c"#^%&k()+,./1244^54r544b+(/J<qvFyiml~s{y~ ;Zجگ1<N$_D{[ލzޣޏ޹ުplmYTqQ5u8/uJq.DXk1Qv1q & w  Z~a~u&: "g# %f&(w)4+,L./`12O44n545Y46%!CM[Y}2VHjlpdp|z}#GmxڥBO`9sVތsޣސ޸ީ/'\kKSbLDCcKIh $5K`y 'NyJ D a 'lQ=06?[~1? !"#$"&'6)*I,-_/0b234455>545 .C^ /2K{`T}dnp|py-Kz83ڙLX/kPށiޖބޮޠ޻ *(>B]!H R}/X=[q(<Ts"K% t  x : ~], >X;}J!":$%?'(O* ,h-%/s052\344^54545 @t8(IJF<c9ct^aoqy .OzqٓY$bCwbޏ}ަޗ޿޶ #<=SXlߪ߰(Bu|KHN+]4L_y/Mi ^ K L M(], "#%&()+-.01344X545`46O$q6 z2KAngrXepu}+Q۹ٌ#d9oYއvޜލ޵ެ42OQjj߃ߘZ@4Oh|y[Bcsk4\v$@Siz@e4u  i  P sxwKB "#%& ()7+,Q./_12=4 55$55 5l5=0 .&5<xaLqhfpup|}"Cpx;nNkޘވެޥ޿0.JKfg߁߁ߚߟFK)405j3E=x1Mp/FWx9iM ; j \X5C/UZ 6k !T#$[&'r)*,-/023254d545Z45Ja_Q4[~8qbma~er| 6C4i On`ބ{ޟޘ޺޷ %#F݂tޒތިެ!2:TZkq߉ߔߨ߰Vv{S!=XUP7E[ TGg.FZv2Z/p  ` ! E!tya L '"##%&.()G+ -].#0f1)344H54_54554G6M1.rQ.K{3jZkU|dwmr}K "ݚsޥތ޼ޯ *&EG_c|ߝߣ߶ߺ1 }G H |$v Y>Xs1Hav .]; . Y \G475LaAl !S#$[&'s)*, ./12354.54L546*5?S|=;r@Me\[khisxu}  !:ܹݥu޵ޔ޶55PQmrߊߐߧߪ &|*hnE FK)]4Ohy2Nt :r X q " xE,%;}C !"$%')*,-2/0;234654;54M543];u#/We/mNgSx\zhly{$'cۢݱxޚ޼ $CCb`}߀ߙߟ߹߽.~ 9^nwiS0 Yr^-_y'?Vk (NwI ) ? nG 7]c8!"-$%='(Z*+-.0134B54S545(46$&R":w(cPeKvWvdho{1=Cآۏރޢ ;/WOtoߒߎ߲߯ *.FfI6e-"f D0j4Zq,CZt $Q~Z  Z | B |x[l K"#J%&]()}+-.!013u45454545~-H^P#-lAF]\Qgdiixo|||&1O/nwފި0M6gY߃yߢߙ߿߼@9Z_.4WY/Yh8l .Qi/Gf,^) u 8 D xk>C)LF}c!k "W#$`&(u)4+,V./r12Z44654E54l5a44)"N^,dN^Vh_thzsz%:[}T/aޑޭ&A"\F{iߛ߈߳ߦ2-PLqlHD%budNv0{>f#@Ul >^-h H e  u=--<N !"$%')*4,-K/ 1L234154?54q5-46_$W#vyce 4k+MYUNi\clsl{}!>c)Jޡ/J1jV߈xߢߙ߻#!EEa^gL1%@<="s:KE?b*@Xp>g8y | * l8-m_3!"+$%<'(W*+v-/0"234454544<5p0 'VH/cHYOmUpbzls~ )Be|%ڄ7޴3OApbߏ߆߫ߨ .3LRku#`\'it9opO7Zr0C`}=rI S j >x|i$T| a"#f%&~()+-.01344,54B54w5$45VoNB@*4ea=[DqGuY}`jq*=e ='ݿ7*WMtsߕߒߴ߶7?Zb{f] P{^;=?V/Oey:WG p  > wY=7/?Gp f} "n#%x&():+,a./w12\4454 54J5K4G6'0 C`  b!FHSBdNg\razlq 5Z2ݴ ?:bZ߀ߡߟ ',GKgpz_"GSaOCFi T.Sz!8Qi7XN F M  cE Vxi4 !&#$/&'J)*q,-/02344545454w2 zjN HD%WAOM^Ugaoizu(Hޜܩ &!GFlhߌߐ߮߭8>[a~c E X6!`)Tp#?[s1b#d  q  o++}a:!"5$%C'(c*$,-I/0Z2344)54>5|4x54V6jmpVvy3*\P?P>dIf\r^ny 8Oܔ,4NUpyߕߟ߷,GNfp>"5pzMLW7g&Eay1Rl/`< > g 2xrm#c g"#o%&(*+0-.I01G34444545w45+H<|QlR&3EF>RSTYjbmsyy 'Sٿw"'CHdo߉ߕ߽߭%=L_l(x>`ntjW3Zyc :d.K_x *Gp+d _  o = qIB&8*S`Q !#$& ()-+,L.0]13.45454&54F5T4n4Vjl 5FN8H=]FdRmcqjt N؎L-@"ZL{qߞߘ߽ ,2PSsz ,0 [(eC0k 9a 6Ni Aq8y / 7  P9 Rpk; !-#$;&'[)*,-/0235454+5{4b536N": miU9Q;:D7YEZU`_qgvz~"Y*5HdK߅uߧߜ77[\3>t;!JV&XbBo0Qm(D`@vS Y  T#-i mI!"G$%]'(|*,-+/092344444444@5/ kx<-J.F?UF]Wf^rgs#.@W"FX+uZߖ߀߷ߪ!GGhl *ERp60 ZsfJn%-sEt$?[s<_E-  ) ` {w`smr&q Y"#e%'|(3*+^-.013u45454'5n4Z5 45 <=uLL*L,`6eFqQz]hu+=]zNj7߄eߥߍߴ 11UX}~5A^f;*";8:#u6REHi4Kd0UV N g + hC4#(1Kb_ "# %&#()J+,j.013I444445415%476s'@Tkb/C L 3/C-R?WIhQp_|iy~*Bf4lُXu:ߏh߯ߖ߽E]{*B\|'T.z  y ; }U!&B`1 !"#$1&'O)+v,(./H1214444444444(2 #vp0,<.7:JFRR\^dmqxz'AfyAW}?ߘn߸ߝ'PCti 20XZ,KCFiR7y;6|&Z *Jg4Qv&ZO B ?!7Za!"b$%'(*,-'/032345454%5W4b53K6 Zo._\=1,7*L5QJZTg_oq{y?dnڣI}Aߘr߻ߠ*NFvo:;af_KAFXC:AgO)W{#?Vt&Go.q n  M sg\gmf{ j"#v%'(6*+_-.01~344444445K45*X?V<dP11%-9C>KMYVdaul|} 9hۊڎ93yOߔ߀߽ߪ -'VV"BJhr]1|J y,}$^'Ni1Mk?mI 6 Y  L<#.3fi/ "#$%&C()o+,./134444445w45M4388\q$@4$L'T;`FiRx]jy 7^4z"Atbߒ߉߷߷ .8Wb #1N[tSvj]pA FN3h"B^} 'BcArf  j * mK&=^5 !*#$<&'])+,B./c12K4444445W4L53l6 \3z<BL 7-0F&L9YBgMt\}lt-Q^Wupߔߙ߼ 8Eap 2AZi}0zg2ShebL/Vpe9e9Xn9YN5 > r = +qx]!"b$%|')*7,-`/0o2344444444z4f5-jK> _I' $ 156ADJT[^fno|}?t6ߔEcwyߗߪ#COk|%BOhw# \^$:8v 7Z~1Md ,U*j W  8 {WdUw},` "#% '(2*+Z-/x052p344444y45Q45535p{<b_#.(@"F5S@bPk\wn| (2Kos߈ߚ߭!.FZr /HZu)A[ _ `E{ 2St!AZy (Y< . W  }J=%4=szD 5"#D%&g()+-.%01&34444444W4/53V6#WM:C>xjM3%*$8#?3K=^Of[tht[ބpߗߖ:Mgx'BRi})AmD$Wr{cGn%0vGu ,Mj,Mp 5lS  g  m;M|U !U#$i&')+,F./c12644444444444N0f4kK$#0'<:FGUV_doux 9 ܥޗkߪߎ ILwz$.OYz (3Qb(~765p6MMEm&B^| ?iE y 5 a = %/v a!"c$&}'A)*n,-/023444{44c4 544D535v?J  5=.IAQLc\ohz{&J؜܀ޥa߸ߋ/"XM} 13]a 6@bn:Zq3okV@d2Oq?sW H  y 3 }pV[Tq+k#!"$%''(Q*+--/0D234444444c4536(Y4v<:Y2#"*57AHNSc\on|y'9<Xcާdߑ8(bW@Dko)ANm}h=AjX2}:@&];`x #>`J#s ! >  hK* "F_&p9 -"#9%&^(*+9-.`01h3k44444444j44j42 O9sL  1<&I0[CfMv[kw6S:/ Kީjߔ=1g`ENq{#4VaXC;HRH5Cb Y-X5Ql8U"`@ ]  c,Tyh !g#$&')!+,L. 0g13*4444t44\44-4653E6.]y9w!4/>I*X8fGuWbq6Xٮ'ޥlߗ@4lf!'MS| 1<^nO*{{I x/a.Uw&?]z/`+l o ! ^ %8z%|!"$&'8)*i,./&124444444444C4q5|,rp(n/ '"7.G?UMgWuiv2^DdIޟsߝG8ul..Y[CJqvXIk4 ;N+a,Ir*Fi5d6 D X - zPX=ZTw9#!"+$%M'(|*+-/0%23x44}44l44V44/4534[*Mp!C= )%7.FFRS^fnr} &Y<ݕ|ߠ" P>zl57ed%MTzQ`I*@^W^>(Xgf1`#Be{>f8wX  } $ TABS#e1 &"#9%&`(*+K-.v01}3]44}44n44W44-453G6#}-&PK!2,?BKMYbeqvNvrtڿ{ߊ߱ MI~| 9@iq*3Vd,lD S61p8]2PkBoC1 >  N#=vT !Y#$s&()@+,u./13T444444444444 0WM|kK* -8,D?VEg\tiw"ARڤaߟ#JX~"@Po3Gcw&r/n}PT a]qvnZ: e|+rGv2Pm2X~Q+} 1 S  mONATY!}@,!"8$%\'(*,-?/0M234444r44`44<4435A'Ec%.+93IBVUeewq"nd-߼߹6Ki3If{(C_x4c-g %,$k)KAHuJ`|5a \S c ( yZ," #4eW R"#h%&(*+I-.r02p3444v44k44_44N44]41t_riL[" .!<4KEYUkcyvVG17߿߳8Kl6Oi/Nf'B\N_0enN"Jm6Mu 8`.s* / } ;$ ;4{_ !c#%&>()q+,. 01 3y4q44a44O445444536v3ZY+=!J8YDoVyhy3Jn߭ ALo ;Pn :Sk.Jd!0c}sO$y/dT5^7St+Q{:z%|  W b]>KGl};y<,!"<$%a')*L,-~/0234h44_44S44A44%44 4*3 gq"4]N6  -*8>LOWfhq|hثܫߚ% XEy!SU"(U^!,S^<wwKu0_7a'Ka"SIL V $ lZ&"*.t$t q"#%&(0*+a-'/0G234_44Q44@44'4435k366l2Y:'(5:FHT`crsevj܌ߗ* WC|%#YY)3^c,:`iOOn>BU6n 5Y{Bb%T'm | 0 z D$S@ "#&%&T()+-.L01N3f4}44s44k44`44M444J5B,,/(o -#<5W?dWrgp3 :sߙ*_L+*`e1 R){*8T-^DvOdtFm,q6ߤ+_U49is AOw)M_ j/xY^ c OAh:[ 7m G9 W  vF."JlF u u"$%:'(p*+-1/0H23m4y4k4v4d4q4^4k4Z4c4_4>44.V1h-^e%#<7OCdVsgw 9nN$ߤ-eR98mqKS"/Wf}!Fpwth?!h*1|$[;_x9[ :w!n i . e H  n: "#0%&^(#*+_-.013B44H44<44,444434}3 5( 19btu'-:=JWVij~v,mnd_ݸߧ+bN?;uvSZ+5ank,<*$|0YJ/_7Pt 3[IA 7 z 4 #NlS !e#$& ();+,t.101?3-44N44B44444 4434w36$v[  ),<AOOea{q'srsݝ߯ ZU:Es{*R` 0Dkx X/Zl:n$w_,\|+Oq)U&i [  < lTOE[o Kwt!"$&'I)*,,./W124e4q4Y4n4Q4l4G4j4>4k464]4o40&BS!+Lz *>0PDdSzexzڵw߻!N\5Ln3Sm1Mk)G!2c{U,~7B,g%Kj$Fk&R=& O  o<0 TlV$z!"-$%['(*,-B/1W23L44@44244 444434S35*j._uuhfm&9&R9_Ox]s {?ߤٓZ ,De6Sm9Vs"=Yq7O&0CME6Ad[9i&Ai@k.hU ^  d 3'hO+ +"#N%&(/*+h-.023Q4n4P4k4G4l4<4o4+4{4 4435:(L'2G~Mpz&)>>OScdyuO&N^3,=g~3Wr#B]y 'Dc&?\T!zK11r ;dD`=hB%} 9 c 3 ` bK !\#%&5()v+,.,0133X4N4r4C4p474p4+4s44|4443q2 (l Ceq "2+E;YRmgx%{50Eq 9Zx,Hg2Ql8MnG[oGOVD|<[>b=u\N z 1  wlISDbkP!#$)&'^)+,]./12>4B4w444z4(4~4443434<35:.cRub  2K3YJl\o 8Es+Bcy1Pk?Xt#>\vO2VfmfP3^~(tP}6_7ZO.{' I  pD+2Z e8/!"J$%x')*Q,-/%123X4W4M4V4E4T4<4V4.4[44w43L5*D1_:]r#<1MKcU~n߸ ?5yv*7jv,Ym FW -Dh|O"_,FHSx8[}.X,dJ `  i +Fk |` e"#% '(D*,~-=/0_23p444p4,4n4 4p44w4343433 /  <U|j.1@HYYol{ؗܪ߮I-p66tw)1en#R`9ItFi6b$eh["Iq /Ww*W5{o 2 [ 1 p$pa "w#(%&]()+-.H02Q3b404m4&4n44r44z43434336e{-f7a[$';<TNm[t}H܁ߡF'}j31qr'2gm%TbBTzs"Jt~ynE"r0:*aIl'Kw3h LI m 1 ~fPNRe|j- !/#$Y&')8+,w.01304K4K4C4G4=4C464A4.4@44O434,Bm~nd*Tmj+A,Y>nNdsz~lznߦ >)ym56nt,8fu2Zj!Ha q&7C9+ =`^8i&Nn"KrCm# :  fM%! A^(qB@!"\$ &'K)*, ./5123d4+4_4 4]44a44j43|434u3D4``%C_Cv+HY2o@ThmlQ{]oٻTߩ:+zr09mx.=h!9bx,NlobuDz*'k35!/*vW,FDv| "=P*i=S_ef?T(ߣ8&rl19lx-?n}&;fx1Yp C3?th7 DS=o>f<`&U&jt c & ?z,  "#?%&v(%*+e-.02384F454C4-4A4'4<4!48441444z4 /Xm`6t\_$>.ZBqUdkg?%޺ߤ9!ti33ry4As1?o(7et69YWV;)U m%n Cn;e2[,d=I ] 3 ZbHa]!QD !_#$&()I+-.R01\34\44Z4 4[43a43k43434/3%5HI("Sx<r/2GDdUfnn?E۟ݨߡ1vh46ty8@t5Iw1Al"4-| T"<@Fs:Z 6_5u^ . ]E  D^/|UT!"t$#&'d)*,/./\123N4!4J44I44I44N43]434W35% 9lzpJ`:v@_xyy'&F6[Qr\hmCX;ڬzߤ!bg(3iy0Ao3Hp,Dl";zP]uOUeNIt)Uw :l>4 D  P +G1t!"%$%X'(*0,-k/123/4>4#4>44<44;44=43?43@44C1,? R(S_8d}*C-^BtVemFO ޸ٍY߹+Vq?e .Op5Wu7Wt/NqF6WprkT9k4Q%Lw&PxD\ j  _  M8 *"#R%'(U*+-/0.234J44J44M43Q43\43t43435Z w;",l6r'{\n'@*UCmUevV>tit? 4S}$Lh2Yw =d>d8_zI")$j1UQ'`#Nr'Q~S4; _ ' ~^YUeq<c\ !u#%&>()+5-.q01r3#454!4344144/44243<43`4y3U5(w{Xac*](g1Wjmr//CFaZwrl &D3N{Jf5Zx!?c*Gk %IcCf7n'}`7d Fk.[$b _ o 5 f<-5E~9! #$9&'z)4+,|./13)44<44;44:43;43>43H43^432 |0=:V=Y'qWzk!30NDe`yyoi ߻-EsEb5V{'He+Ol -Pk9p*_xrU&7J,l ;d<g1a2|0 ?  M 01UQ.0!"U$%')*V,./U12 44=44?43@43D43O43f43435D,NjddNrYr 0"L7eO{g}Z޺ߪ'8n=] 0Vs&Eg .Mo0Qp q*?HC0Hga=t 6_Ei3p [`  V  S]G V"#%*'(p*,-L/0q23'4$44!444 44443!43<435x*W]}-4MHL!?R]Z|u #B.WKwWp_{؟ܤ޽ߒ('ku@O*Wm&>k 5Mv;S}mR<1oI 7^ HzC2+ f  xrWgb_pq "#;%&(*+N-/062z3:44643543343443:43H43g4w3'36 1x3:Sro1<\JXh~s51PCoUe)s܁߅3ukIK)`o0CtAUJZn PxCO hE%T 6T!NX ^ k 7 n@8)IRS !2#$d&'()q+,.00163143643643743;43E43[43425}g$;EHIHYWzt2&Q9nKU]5_߂2xkLK*fr8HzI^%Qh@84NijiP7 g8yR(X~5\"W0~. B  \ 5 EwoKW!"$&'^)+,M./1244444444 43 43 43434A,7vV }TQ2%UA\a{n7U'v8<3B޷)qgHM0dw ;O| Ng5Yu,4! h.SJ-c&S{:b(hWX  T , 5j| "$%S')*[,-/123-43'43&43%43(43/43A43n4>33K\UBWg @\+b@\v 9Vz%)72ى ަ{ fiAQ3ex :R'Pn:`|'-}c/kr`9g%Lu 8i9}&& a  }rajoq, 2"#d%&(7*+-8/0d23(43!434343"43(43:43u435"m<^X8)E@+U;yRq0Rr$ݑu߸ bb=L.cx =R'Un%?e1n`Io}}kD%v5>4o4f-O| ;nTH n % `K+,!3?msFF !g#$&6()+9-.u01v344443 43 434343333/43/~.jkN?(<<BZ\ry@]&# کڽ{o߱[Z>F(fs @Q([o,@pa7Z~ .Kt6v=T\RC#Vy uZ%Pz?j'`OB k ! [P-2$CH~#ik !#%&Z("*+p-.02334343434343#43;4a3|42O5J]e5 0<*^:z]{6c A3zߔߺ,X}Fp2V=cAi?e:X{u_ED-c)U{@q:w oz ; X .9[>} !5#$v& ()Z+-.X01Z3343333333333343.483-5'&`Z@5&(JBafx|$D.ps5|߃߶%QuCg2V;a Gi#Di<_dW&_o`3h1XBvU@U  X  KQ7E!"x$&'P) +,W./1233434343333343 43432D 7LSaQM/& -(P@k]y "(;J9ؾܰuuߩ߿Jj:d*Ryp'91n9g0ZG~)l d" I  mroKQF a"$%Y'(*3,-}/7123343434343 4343.4U3q425D3@iE,O-cPm&E1G|u؃܃ocߥ߱F`5W%Ht8` Cj$Ij"Gj+/ )'t2[ \>s @j+U!X@; _ ! fI907A\E| "#N%&(D*+-3/0\233333333333333333b34* . 96MPnk CWOFSJSuO߰ߠIS;M-G{6gNi.Ly )Ro %o8v!/wBzFq*Y4r Z| & K 9 4vA !F#$&F()+"-.h02_3 434333333343434d3<4)3W3 V\VR';9S[nv<Z1D(u<߲ߌID=H-? 2m !Xn8P/_w*^X8FSLNIv1cH-O y V  1WmYo!"$-&'v)A+,.013334333333343 4~3 4M3`425Mm '"& 10FV`p|@lY]ؿl.ߨA46=,9|0l~Wl9T0c~bT.;L@8F uqZ#U~Gt ?vad S  zw|Xzw!"6$%'&)*y,"./\12333333333333333333\48-2rwko :&YDud{IxacP#ߘv2/(7}#:q0fPp L[k{YmRߺ߱ gijz*l|'h #_wOh5Q3a|ka(o!z1uLSx 6i G)z3 S # oNI=KS{II m"#%B')*\,-/,123333333333333333[34255%6)cZ :>Y[yxL5ۋSOߤ߫Ue]s (`*b~(XvKg 0W;dIvoL#}=NE"XNyH\Wn * ~ \ 5 2b$p~ "#E%&(U*+-C/0l233333333333333333v3330gXFU P;)ZC|cC 'ܨ 9Oߋ߮CgOx,Y/Z,S~#Mt:bGiY4=;) Gq$xW-c"M}S+v,8 E % B?) !X#$&2()+W-.0 23333333333333r33W34%3I42D5.lX7pjk3R:uZ|-ز{&Uyߴ 6jFz+R0Y1V)Ny:i&Mp"3}L@G,c7f(Y*hP[ P  FG;T!"$@&')=+,.D01C33333333333333333h33 34Q(>pLv ;<[\{||{TIhߣ(]>m#M}-V,W~'Py@f.Ry#qi=Q i[:r5f-f8y(}% Z  lbJOOpB^_!"<$%'&)*,>./{123333333333333{33h33L3303K2 $.yw@b )E=g]Kx\><0<^ߕ߾P}7eKu)U{*V)RwIm 4VF\[^B(d?0nG{ =i ;x OPg / b 1*1A}>   /"#y%7'(*$,-v/,1233333333333|33j33O333<42g5[s_Quq $@(cOn 8Kߑ߫Jt1aDq$Q})V&Ry#Jo 7_RZc-X`DQ~BuM'v$8 P ' 2_Y=N !#%&w(2*+-"/0Q2333333333333333k33G342"5o%ADws:do:"VIvd58ߏߝFb#\:r%N|+Q+U'Lx=h7R]+r'0|U$UK"^KX Q  d hc!,#$x&()t+3-.}01i3333333333333|33i33F3324R}~yd8Xb .W8tZrׄۥ-'߆ߐBY\~5s(L1T5V.T#Dp /BkvcJ:XI/e)[)^/v$% c  wlWeb c&7!"y$ &'g),+,.01333333333333w33h33P333c4,.f]Y4}f{ @?e\w eIw޲4ߎBH `r.s,B6Q=U7T-G|2:36"Tu.]=t0a<s HUh 4 n ::*"KX]34 b"&$%|')*e,4./s12333333333u33e33O33,342+4!r J=t$Unt6=[Ur )Eޢ-߂oAA^j(s+?7QBY:\1U>{1TJS;uJ}>wJ,z(E ^ 5 %J"~h| "#h%'(j*",-|/ 1233333333333333j33*3f4,Z_ 9hOS0LBml(A%p>[v*mء(ݿޤws4D Vo/o)L=^DjHj>b*T}"xzQ$h!'tX$X%U%e ]a$ a 8  Q6/ !j#!%&~(*+s-7/0l2333333333333n33U33-3v3 SN2 U_vjr+Ou:Zr|3bxUݳެ sv5IYv:v/T EhPu%SxNt>b`mpneC"|BV S3i 9n0i K5E t C   S_X~!)#$z&()|+;-.0 2v3333333333333n33%34 +d 0`o}]?I} ?.dHg{,fMܭަ zt;F`y"<~@_Vq (`3h0a"Vs'30, U/1zLzOC*rj% M  |[\PkuU -!"p$4&')'+,.F01O3333333333333v33`3 3Z A ) e~p8\t194cXu)q{ڴܢޮ yyBNk,I Li%b8o%Ex#Dv;mTma%] bT/_*a-g PNs . g G3''/Eg wMV ",$%'1)*,F./133333333333333134n* <'K|/P_D7hXv+}Zٻ܊wߊB],p4[X9r*K4\ 9]0Y=!ub67B4t EzCwP54P  m D "7e7 B"#%>'(*N,./L123333333333333326N S s|pJQ ^uqHJ>m`})٦x-yߚEksBxFzXKZ X * 3t& ! !\#%&e(*+v--/0i233333333333332~W CVJ"E^c"8f)2KUqv߂oOO{߸S'[)\#THz5bJv)U|(Y|!LvQ9? [1g-e L1F r A  ~NOHt!.#$&()y+Q-.0233 43 4343 43F4235-)  `+2l pY 86V_}pbR\8l߆;^6uAi 8r5`!V~5iDt%IyDnVi4o!v&o H~NQ2zv- X # f`[q}_!:!"$?&')E+ -.e01y33 43 43 43434323e C ntBg1T{ y (7NXvz c2=;,)$}ߌMp FZ&QMz9n)V ;e=i=g6;qBO_P1s9e A~_f| G VO1A=`p:|Tb!"W$%'F)+,.01(3&43,43043<43c4N305) ,  [{9.!5I?+B0oPv *F?:#=5ߐߞa6]2m:k/c)WGq+T 3` 3]5OoP#|6N="\(_2l NTl 1 i =2?QY08 i"$%}')*,M./1 3!44/43.43543D43Y3J| _ IG* uYx. # )!D>w\? `9FQ:ߨߨ{LnBT|!GIq 0f"I|0S2S+HN`eWI'\ 1/tCwSQC3_  { C 2  :Q>q H"#%)')*l,-/?1 33K43N43Z43~4u3K5)   U'&Zc:fs3'E DHSvH{2asB߱2& k|BV(zBa&j+MCeQs!VyRh0>,+?rof2g?vB9"N f * ,}[B^ "#h%&(Z*>,-/123[4 4[43c43w433 2 u=W %pD<zx!$ M\d-^#&XRش݃SF7 Xn)E[x)H Mn .g>u#D{ Csg&W\J&_)d=~o|3 { B DB'@ !#%&|(G*+-G/12 434]44i4443X5E* >  h J m>T\t@w_x9'B@]!Qq x݈rVW+@!qCgfFoFoh{G@N:wQR/p X o j * mqj !O#$&=(*+- /0P23<4y4(44 4434 c ;?aG )^;8b>h:h&9ݔߍfr?]9]0Y%`(RHv.d;mAl VUW+o,4)k>vK^SV M  8QKr!#$`&"()+5-.0N234F44/443^5+" $ O ] n 4)\Td'RrTBu2B%Yݡߢ \q7Q2 Pu!CNq7o,S?dEg6b"Yvd:U}$o[.dAv IHA { 2  gyj p.%M!"$ &')l+,.[082{34C44%4434; / I ' ! )l Hq.@^`uF3~NbBK;C۵ݮ߾8* ~Zq3O,vEg4v:`W|3e=o0``pkSEAic M \/gC4: i - yfUUWm?lu !"S$&'o)%+,.K013r44q4434N5=- & Hx 7 A[R]EyV7<]-$`Igw ]xMZrݴJK#9%tOv,P$e3Y"]F|3\?h=Z,KF6#q.QSFat%٫ݡS}wV*]*d,ZQ} 9e?re 0p5[Rv*_(]E-8Z>z H9"~? h > ~^ip"!"q$%'g)X+,.@0d2f34; u   V C % R]R #;_h> +^4Um_ܒI6+,1 )|gIk&N&e4]%bI~3Z.W6j2n#},w\6n F,y~/ d - {pq3SW "1$%'Z)+,.[014. #G  f M b  #(B}i< -]*H"Eh|7k<ۜܟ]_IV=\'Q@'o Ny'V*a-YLx2f8b;eW"avjS+fE%m!y, f ! ~u_kkzGH " $%j'T)*,C.{0v14!3 a n z f % v|Gzq7^;bNTcܟlh~]}Nv?g$S6yQ'O#ZH~9aEgEkyqHW mf M)dC$nt& X  rbYXZxW P"#%M')*,>.01W0!} ;< t  5 } Y ' >tz &<?k_\03ܟ߀ocMw.V;~U|#JLr 5gDy!Duj||[:M_eE)c7x#o f# H  pPQ<V\2 "#p%O'(*H,j./m2& r N $ Y:^p.]B^+7,?d}~!gj6ܞߒ19&BD:*x^>f@Nw@};`MxPt mLiD)GV^@(c5x"l d& F  |lDJ/LMs !#O%='(*$,Z./0 =5 !! T # KJ=_&ln0EXUv7{ L{ۦߛOkFoBo8j,\D$iDpA}Hv 6k$P)S1X-]pW3t6TS@~\6vc b C v[C1,4@fkHX !#G%&(q*C,-)0*-o`LC M  [ (  zy )>M3FkTr|}P&ۯߢ5f`"aZN=v"Y:pBzHw >n(T2Z 9]#,XCk'PK?U=uXf | H ~KB+CJ E' !e#K%&(#*m,n--0w  Bp  #  e 5 `2 nzAR6U2"eJQ[ۯߠiRNJAu/dJ,iAo?u?i'Y8d>l.3.\C?7yN3r Wc u 8 k=1 /6t, !D#%&(*,-,: j> P e ? u?2W0`OR!=Pg| }8ۙߡs$y&u"hZEx([5m Ao 7q,\EmGrLJ 8B/lM'lYX v 0 \:2Q%}i !E#$&6(>*+M.D$ _+4msP ^ o E -Ji |XJ`Ee)IF{l 0zߤ;HOL D.oT.b7l9h.\EqKv"Pxq7w'6#i O` WL s  G4%0~Q7U!2#$&';*A+~-3 LW J | 6 +AiM=\A$mMvn ;PߚCT>f?q:k2f S =zZ/e/c*\GsN{*R}`'j-|`CeSI h w E( $dE(F!#$d&')+(5):, 8J  1 nz!219MoMK.K1Rm PP ߔ6 -75 +jKr*Lb.NOr 'Y{0f0pc1 Gtd[,r`:M P  U <-`^;!"$%(&)*$T&^np  v < du"x!J \xo0!UTgw(t$ދI#99:M>U5S/O?'r Pu$IW}?z3U<^@bJ{qH?e ^ O,hQ5; E  O +\VR ":$%')$%IhqDz r %  m F ?E#G!E4(e9::scjuMy ܎ސVMR_UtW|W}M{=j'V ;xM|IHr/`:hEn;Ob; u:X XE0mM=. P X 3`a "#& '*y~ K [Q o 8  { I 3gv X! 0 nlfz|'npUޛauh n!v(s)pe L.^ :uHv>r0\ =jFq:F(e(IS=+hA7% H s P LI "#%.'d' /l7(} K  G 9[vv #,NvxKgf4~,k*\6m!Hz"PZ@G;^F,}* < s : Y $"#W%': pL=peXju S D &Jq,, "Q *#Y^v@A0Xvzݍ%60S=gBnEp;i,ZB%e;f 3l-T?cQu Uw wP{;68|SDl- * w # ix+ !$$'AWpW`V ] I &Ph !"# <|>,,'ODf[iz݆I]Qw`lmeXAl&P)j5`%_?q(L0Se?p1-.u L>i$ ' q }^}il !##%$%iOf# _ T 6r" "$O2 8.R3j]o*wSc+y< BC7y%g I{#S)]%SDo#Rz+XU%e})gM0ujq ' [ # i_Wkb+' !;#%l u * ~ T X :1 \"$ "wP~p^%<)->6st:p}E]=wQe#k%h"cR:lDSL BkP{)` /o@ Z m%yYIgka ) F $ F[7kT$""%k: F Q #|8s:m "|#%8_`U<@^N`]qurf|3>G@5z"b@nE~Ku 6m I4V5XZ`/K`l O@_c\  :  ur>O*XD!#L" -TLPs3 >  O ,#e  V"#,&"o 1=.2(_OJmwERl>s9dFx.\ 6^;TSz4X[L3vaOW x ? zQ?*.,I_#f9 "!#B_zf;h_/gB L  O ''Q "#s%$ ~JSu{K*3 q/0[ByS XV L8pR/d3h0bBq-X4c:!;q#PKJ'h_A] k @ x7? 3 J4)(' }# S>G@8$xJ d  a W ! $%'q{ H} 8*M[v4w{m7HLse!w+z1x/r bFy$V)_(ZFn+Y 7d C_BF@`R<O b 2 }j..3(~#!YFn_hT v k   em~ #"#W%' ![ mQ~I^g|HH `\[s=K"R KD+p L|#LXAq+T8^ >`|K3C/uaHD: f  J9   8EBn:.!fY o  f kUX F"#%&q'  sz\#OWݐP o 66T?dIoFh9^"L +tJo<|@cTw )d0ed+rx7]Y,{:% b  |'/5 zEP! XN_V]P^ \  T TKK -"~#%&)'+ =I'xvz-<%4LIk^~` ^XBm)P*m%bT! B5^Vt9HOK A}*d BrG{Dy0_Jv*U%m8Ux&OGE hdN z  v %UeF 1pEK! S v N }|ke/9 !~#%'U(+U 3  m#YC{:_=ug7Q%c/j.f'^I(_5j8g)Q=o&Mz(L+ dC:9[ZA k  k pn<7rO[.Eu5}fp4 [ j T oYv)L !P#8%&(p*c(a s~AXeY8uG~h9]yV&O2kGO QF~2hK%\.\Qv5gKv'KyzK u+/}!jTB@ X  L ypymP]3N;AA`@$ L l H lrWyqA!3#8%&()^,zd 9 reA3a|mVEb?)hJ`"l'm!cR7iDP{@s1XBjJpd*el%pUP5~= 8  + vKzGh  iV>q6p> 7  | 1 w^b^wJ  !D#$&( *,o$ Y+fm iUUYLݰ5j a8\0u?DA~3lV2e 8m8aQ~ 2h?oJLUcE@j, # s  Vt$b9/E**[D %  ~  nxAgCxmNvR p!Q#$&0(c*++{& ?MB3RnC2kOag`T;qM$X"T Bo,Y 8b 9pt7x4CH5~(vbt  W  MM9N>f@Iz9e2_C ( v  jm;Y:kg<lJ `!C#$&(i*q+c.A ,=a:?Njv(SMk'}37-v^=mBIs.h%L3[ 5X:Pk;10tYXV  6 aV,'^5l$"ewd{<u%y 5 _ # pTE<?SntOi!#$|&7(*+.(E_ OXIII.Ahg$ @KQJ 6{_8`1n'OIm![{ *]|* \m0m#qDTA    ?W.0lS-OT,eq)wCm = P - yBI,I?ouXy!"$U&Y() ,d-._F) T;Q=r&f1&?Q|z :"P6f9i4e!O6{S}"IFh 0e!@x(H~`=Xr T[4C/  n *9  6[MFg8! x)} e 3 J  yd:9!47_w\8V!"$G&8()+0-0T"f| P];odF{l$2Gd I6hExN|Hu9k!O-k|8)!"y$X&')+-}/J, 7[1"[AnlL.ARu 00^L}_ic U)o&q ^& -  7,R{mO a}a9 Ow  t V 9A )8'}!"R$]&')U+-.0'^ UV")c&<u_<,)PcDDo`r-~-y&mU9e ;u=j+]Iv'Y}(Xdc)^!v/}[cH ~   vTT9h+*M8APw: m g H }u*/!_v  "C$/&')N+-.1& 3,#1'~oBCKrQIg,= ?=}+j K|"T#WFu4`DpFu20Fh _cDH8 _ y X mOao:}2KAZ<S b 2 |X*>lk] "I$%')l+&- /0/W Xpj-v9D0[J(#eR'sCRYQ A'a;m =q3` Q 5f;g b1LTF;*}2 ; z 1 v}Go1!\ o}0  :8?< j  zA,(lOD v"D$%'])u+,F/n03yR I%8 (r|mP:1wd;W(g5l1h!Y<S&SPw 9o)N1P?'D%q2 [)  x  B@MfGH-=}?. g x7"_D9 l"($%'a)O+-/0B3*?oH RK:3U5#߸{VC?nF)f>vEE{8j"P0o>h(g,Q BgPnk l' [lIy o _ |'e` )}0 K/5u+! V  d-A9* f"#%x'h)+-.0n2a2FA  uojJxRފ[NF'{S7vNYY M9jHZH Do*]7k6khPZbRR=X k ; k-( z{2 Gw {#qz H V(1x* R"#%a'U)* -.024%# |2&,J&EV|}^Y`L9h=X%f*e ]I+f:h,e*UHoW|'Y:8|.NBD'{4' h  ,;7e "?]76A)sclh 3 ~ E_  -"#%]'#)*,.0D24.J lO h%#&~pc,8nY2)InFGw B'^7m=q6e%T 7zPw>xBg&`5r%8v\h9n4 V) m ` ^ =`C7@`AClKaQ y & o 7Co "#j%W'(*,.B0234ff W]z6V9={EXI:gJ{M~Kz9dH&e4M[|;y3Q9Sq4MvXhBj U B M ^ZVKQ6L@ D<Z?QE i  b &1Xj !#R%;'(*,./0236' 5['4W?ާ8BC(Ja'#TEuV _ZJy1^9w Ii 4n0YCkLs^;QGG9F T  L %avQK''E7>< X S |!o=K !#I%'(*,j.F0.236I2Y 2Q~YsE =K&Te71fOb$l#fW@tP"WM?q+Z 6b taSq)+;"l.{ M Z P .yJ*;,T @^@(8!z5 @  9 ~jjn X) !q#3%&(*,7.I01#4`5=7} Qqab9%|9Q(_gC3tV$l2w2y*iO-d9j3g,SHiVtn&1Jq d"yQsR A 0 H Q2$k%7P`8_/ ' w ytL_Qw~Iy !`# %&(~*S,3.013Y58, gNmph\L^=O(Zn D;x _(w:@6w"a=wFzBu9i"Y| 2h7kn"MGW7U<    >rRiI e'FO+xP  g [d3R4je7lQ {!R#$&j(w*,4./135575O'  l/:F,VtBCv i+ ?D<-nP'TVJ ;fNy#PzKy'34,}.7 `  }L+hI~r0$++`J _F j | U  PO&<"RQY=^!9#$&N(c*+$./1Y356#9#+Z4 n tUE@o4E/[xGOt5J!RN <`9e+m3YOv ,d4i}.id!x ]t]/ /  8hMQv1}R-G$-zC? J<EN } 8 lL6# 2KwT6_!#$&P(2*,-/1w356 90 r~?x[ ;/Pl%Iz#] sNNw=R%Z'XD/l Gs;Ci)d>v*CF]xM@\7Z4  y \N yL"NExGuA,  r  JC  =M@$M!"$O&C()+-/e135L777F C"_;&E$9 O hfd UH)wJ `,f+_U?vSNRz8w/Q;Y' Q* y<l? z j _ 3z()ix0> b5_- b  ~7/(3(t v/!"$0&$()+-/H1}34F779($W t[zKT _fc ZE-vS$g0m/m&`C#]%Y%["O;aIn"-\ [jWmi 9 X ? 5N0]cE'fWcU i  @ [* #X_d "V$ &')+-]/S1!356688\4{[ 'pޟHT]\QA't Q&f3u4q+gQ0g0f5e-aGv+V-h1F@HBc  w X 2 r-,=QANG u # ~ ="7RU ")$&')f+-(/X12)5k687"9 J`HN^\UD/x Y-t8>6r$]>o9|Is8r.VD`HdAtk2k4 lW ; Z 0H_e^b=M+~G*~B4 g j $%v/0 r"$%')X+Y-!/&124r6[88t9-{K E58v _#Nz:_L[?6u `*~; D;)l Nw!DW|@C\Vq ]w-oQEnFyH@  D FB/:k, h4m)& N  S N ?"$%'[)[+-0/024678@86> !l(&&R\g(mDh <@r n.@KG 3z^4S&h2VUr %i1sM'&J*O2   V*qs9h[l \j 3 u 8 t-y "#%'4)M+,/02c467879#c*`  1ދ![Z l@i 6Hv p1H"R M>#gzl8O![XH4i=oGz@w9cQv(]zh/@`JdL(   { j<`QiCA4D9Z  M  n^PKWmU-G !#p%/')*,.0i246 8A888*8AhT sދ*SF@K>3|eAY a_V;nH|U~'G Nl'f2rS'tmD oP t  I gp-M _ D`z_3l1I e < ~SF0;9Wo<+ !#L%'(*,.0S2_467=8879(a ?W/atC<8I9/zgB[(h'gZ Av&R [(ZQ|4m$C~=FKuR+cZ 5 e 4{"RPKsbCtO#zg> M 1 zp5=+JN-ri !u#% '(*,.N0`24$678L8r883 ?} \ El^k}+9m%N+4r i9X,d.c%[C$^0`/h)WIr,U4t3F@SU 8   ;,CUa=2[@`Q" 4  ^X&2-I? t!`#$&(*N,.0Y23)6_78787I9 )OI oSd~6\Hv!6io4#R5_6e.]H(j?e7w=bZ}3m 8wbht2 ~R J G ;G* xrOXJY{.76=K x - U: #b@-j!7#$&(*B,U. 0-235k788879+  Qyu})ii'^@z$3k l8"Y7i?j6c"R5sIo? Jh )g$=|.F2B< kH$zMJ  L p  VgLlSO%i.|B Y & m O :8)b!#$&(O*G,.01357N8t8C8q8`85  7:wrH[u'w!|!l _;X0n7r4i$V8vLw"IRv4p,J:SmqD$za)) 2 I q|q8CB1qLw_1 6  L ?p jzJ!"$^&j(*/,- 013q57 887879> 7X, F<<߸rh.Xcx!oo T<^.s6u3p%] @|N'R!S}?y5UEaJT|\3qs H I rLS-N6UN ' 9 JRi!"$M&9(*+-/13v5h7>8o8/887P9.~ KR&zp^[ H\eicR5\.o8w5m'cG~!V0Y(_!I %46e^tk1@ >  hud]$: "+$&')+-r/1K3k56r88878m79$va R5ݭ13m2a CNYPG.x T)o4y;w-kS,_4q>h+f%G>T $ _C#H\ ( HCbso qlzPD`]* m + lSTUi7{  ["!$%')+p-o/X1R3*5 758J8F8>8O8881 AxDV_@? g+d'QBY84o]%v32*u\9^5Kk/u5KLZ yiBogA} p uLM}_j4+AEa O  iKE-CAp zk '"$%'`)+9-k/1T347787878|78Tg g[6] Bg~$EO{,U(5a^w*3&{d>c: Sr4~AUVf s^N\8  n  T )Wy0+d>Txs+1J { : qU/-*'Tj\Fv "#%'I)b+-L/153467t87878Z79L({ ?]$1ݤM"Rn5?m%Hy#*^Sq+}1)w[:fDNzC;aWv #|;/|/JBbm9 bi]dt>KK;Y[lu3 ] ! \41W1E !#w%T'6)(+-/12468<84838.848883 S B5.^(h/k%m"1t#{[Fe0y6z2q [:nJ}OO;v0PBfApj4"~t  6 FN4/l6l!6ENa G h > =j~ !~#Y% ')*,.024~6!88Y87l878^789}Y Siyp4['Lcsti[9\0n7t2i$X4vT~&R Z|?;Y Pd T9?l M R0;q7:"? u p5+Me 1 q P PMV!_##%'(*,.024t67+8488=87`87R9], <+Nߛ^%j> @PjcgO9\'m3w2l([9xV,U#d'DCbZlix_1gbO` rj)12hu bIxe?? N A <Xb!I#$&(*,.p02P4{67[87[87e87u87{6L tw\c#B~@u5hOe?;r]"s+x+r`@zW.`)d-Q Hm"`{0C7 mI8U 4 >gDZ~jhI0gN++  2 ( y"8;!,#$&|(*],.G02'4j67e87j8787879 ` ]&;Aaz:m h !  bsn#c!"$&f(i*I,W.80J2467788087387I878/ CE"uA Y;?D0#gMc(o*l^<2Ud @ߠr(gk >"B|}>@j S V@$$5Yz {"H$"&()+-/135t787 8787777}81 C/j6rP&SN Zt!ij O8vYh#icFt.W 3xNn7AXem* ~f)FZ =6zr,bh%*Oy : h D#$;v_N i"$&')+-/135I7,87+87287F87w8(7b8y  \QY>_@_/@BlVf@3kUihbFs1Y4 So;G]jy#0g<x ;W YRjHQ nx>b & } Q /([I7 O" $%')+-/135C7878787287l8 79&EZ &_8xQ%g)|;[TY<,jL]b_Cz+^O#WS <#iFtHS{A{@aU8^<4qbޝj=__iVGZ)N t{9Ay% A *  j` W !#%'`)+S-/H13(5N7787 87,87D8V7868uI yl'! oGhAv1bN}(9ik*A!KG1mSr*Gax%EO] lu'Jj/ ?D3= sE{8Qf3^ d -  DBb' !#m%x'E)d+:-g/51f35)7787 8787%8p7Z86|9)h DoKr$W,^S ;s/b`)?IF /kPp*Fc~.DUdsxtkScy \~'F-O#*UX!7 C  wywf2S!|#`%<'8)&++-'/,1$3567777777777774 = :rP2nL'n5K l!pt`O$wCLK.#iLs(Mc5I Ym!~U|IF(@jۚPpjzEG}|/ u p?: v q   ywXeR|I2!M#D%')*-.12 56777777778^7K869]8 "%ޣ;t[=}O>X dcVDk< I J0y$h Jy'P"e1Q\t-z"?#z2trPP%>}YPlOU}%X O aS::<Pdpaa!.# %&(*,.024677777777777B78,G q%` L=) j< \EJVC6{e0x> =(xbHs#O!d1S[~!4hc: n4>y|AOwme5t@n&@X w+i " ` L#$MfRH! #$&(*,.024677777777k7 8H7/876E ].e4?u-S*2f_{15"rcGp(N$d0U^F|>Kh!Be@ZR\$GOUL2WNf*6`{Q  z 9 /29/ a "$&c(*[,.^02U46777777n78O7$87n8}69!Ln ]uRiCrJl+d@v,]Tr*|1}&m_Gw$V,c.a.YSzeacD3BK+PVd4)' h>s9M uAi3 } Z '  _ax0 "x$q&M(c*L,g.O0o2I4W67777777777o77$78/M7 ړz{iO4h@L _y%uv[B^/q6v*aT ;|\4_+n7Weu'<'/3Z+݊1- hOv?S0Tf'P h 6  3M[ ~"[$;&6(#*3,+.@012=46777777777y77Z777~7T@/&^6\"V Z oXT.O*d4f)[O8b٭߁ bFrC EJ`LK$}F'Z/`&SM5c>^-wH\t?2b2WkkY:#la}EBhOZ*g k $  p}.X 3"#%')+-/135`7777777777}77u777)3<|"W9Stj_L6g8f'>JF< pEZ(c"WM<c=b3yIc$xAA#R'SUؒݨQ-7+ZTbbD^.5o xLp O  klKfSw[' "#%')+-/13577777z77l77[77B777!868 cN#A;6.wQ"{G v04?)b@X aUM8yY:i8vJj/v@NeD_J0ج݄FCL~F4S)5AG xLb,[ + { NG.:7RiH)[ !#%x')y+-/135177777777w77f77F7768*a&,))" v`I#g3Ut(y$zjS1~ KVMH9y\`fO d,t+R r'OG  P D  %&_~#!#\%l'G)o+M-}/_13V5?777z77m77b77S77?77%77#7T5 G;)2;%CA<-e.t6o%b yYT$|>OED0x[:lA{HvCz=mtngI>d7%؄M4$jy;M/_o>^6 l 1 ,  FZus!t#+%L')R+!-d//1u3&527v77e77U77D77/77776=8;6L9{ivHT]Ok GKs5 GA C2vZ6pDwHOs5y'HP5b SLv/c'~gTz+j|ASC a L  9GLN!;#%'(+,)/1<35777u77k77`77R77=777768 - joK"{Lh.Cp!Y h 2  DmG !"$&(*,.02467o77h77`77U77G77377 7768!"ҚI-.:85#wV$}Dw.y'0rrF)b>uApBn9b&M ,{ Vs/Gkt<7/qm^ؗY"V)*?l;#N2<"B"^qEu T  i(b9\$ "$&r(*,.0246o77g77_77U77L77@77477.7h770umnLBZ7n82-}qZG t<O s!ksXBa1v4p3r.gO/zTy,Kjz8E EZ]LߵQE5(% |sljGN0N @ ^tCw]3) "N$&<(*I,._02i46I77?7707777 776767|6`858R:eJA)99,;6)p8g0p"QoCDve!z$u/u(jY:tO)V%i:U p\Xy܋\vWQksTU096 ( z CV$ZAq "&$Z&(]*,|.:02?46@77;77,777777676 8`68`5:;8  W%V_Ac7>h^r"p't'kY=sR+c1h8a$nc}ԥ xN=5l/Uz@%o?c.Cx#p( m Z 3'-.]xng` A"$&(*,:.50[2E4Q6]7y7a7v7X7s7O7s7E7r787v7!7767x6!9(%,؎ "  tO&U9CH:%nP"d&g,q+iW>wZ1d6n@k 5kTep)Obؿۖ޿/]|qH-_Um:NG# t f ( .-&r3&n^ !$%(),-;02W457:77-77 7777676767x6;866+qMtSN&H7=D3>3%]$O Gv%@lo6$S*V3`,^ N 4}[8d6r ?wHdDu4\5 {ipAUVKlGMdFh@I) Q P   Z]29 !#%')+-019457(777777676767}638684j;s٥Ba42( {Ij1')L+-r/13577 7777776767676 8'68Y58qNhf^Z&T5F767!' Gd #x"8+'y"ޒ+Kiy ~|hP2p=`t'|)ugI*i8sHQIw9i)K1^p7@ lxJjaEe?Pd( \?W!+z$"m Y}Y Q V $6D9+G# "$&(*,/0435627`7#7`77`7 7`76d76j76x767q6 83"`Tօw$6::/i2y=n\ oQHf*s;@=z7gT0yWz4N}kUZӐ{d$k_$&fR^xL^8]; l 3 4 Yl "d$&i(*,.0346/7Y77[77\77]76a76k76767.6m8*+ئܒyzrFc.X S]E8x[#k7}?~;w3k!N2}Z5T#Rл;_lvtUXR's7k'RP w C * &dW^ ^"[$H&a(]*,.0246[7'7P7!7K77H77G77G76H76V7673< ( Le)x,|*|n ]@n27]EP&P-`?tHzDw=i*W:b=b:BXtfڔܾ2]\Sg2ubAeZ{HoE i )  Uv-4 /"Q$&X(4*,^.024p6r7 7m77l76n76u76767676\8(jRi݁v %@"M#MD5i0d#Y9PH0[BsLyJzAo-]C$e?tN}7%ۧѹy׾"\ޥ!@sjDB8n%]'{ C  (f"zF ""$ &(#*:,X.q024z6F737;70757,707&7(7!7!777"76g73|TsLamIf$?9/|nRk6F{ vu֪Geui :-;o'3{i|+  mptJu!#%')+-)0"2S4&6U77V77T7 7T77X76c76767&fwH!/u@ۢ4\7Zny^=p;j$q%(ufJ'f; HJF;&n[y@R, !πВӤV_xyg<>uuXsg\f }  Yo]`2W!#%')+-02?46R7%7Q77K77G77@77477 7~720N$0MMft}~{nS8\(fm)rkG*iBKQND -~iTZA,<4t2KWDڥܦ,(a, yJaFa QyJQ u k RXQnF@!}#u%')+-/246@7=7@7;76797*7;77C77`767%1@ cpӏJ x/ER\WL;W,Xn#z!wcO)tBO%V%U#H8yfdQ8NFX^2Բ׫SQ:DC%K0yL{Fo9tD k ] DKH`t4 0}!s#g%y')+-/246H777K727H7)7G77J7 7\767v1An=ϒڜ^:[ #/1.\*Io%o|_V*x B$S+\1`2O!>& ut_J[3zЈ-ҐRI݇bzt:i7i3b+k- ~ ` L 868Kh|wh!R#P%X'n)+-/146B7A7K777H7.7I7 7R77q767$P< DI@^} Z,t8v'e"\a)F/[=c?d;[3K!5q]ie+гJЮBؗۧ.8t\5XmZ)V&^#Y] p S 7 . 02]~rkl]!3#I%8'k)f+-/136)7b707a7%7b77h76768u1 yCJkPx qխ! >+sUy{T&r:u(j*ff1N6cFpKqDk:_0H/ }wp@=υАӖ֚:QH@m9"S6qu}{UDIKD G g D - .Iw_VgG!*#1%1'S)_+-/13657^7=7]7/7b77n76767# ] 0=gEx,Um{ ~oY9|Fdw'y!t bB_7xI LSDu5_$I,tmIВNM݉ߜ3|,|ZX~_o>80502 r h - 3  2.};2q !6#%C'%)w+f-/145k7.7~7 7777676-81K V!CI!b֑)k8KUWN?OR4p#[Qp8JVSN@{,dL)oTG'D!џү؎ڸ6VLV;=bIT+"o&,&~&  g ] ! '  !l(!jZ !##$+')f+T-/135n7/7777 776768P#I #APB!xD"8tѶH/W0FRQL8yA R|/ucTsBTb"`UJ8s%Z =xGy.^iѳҝәլ`Tri1 (76/Sg+d&a+ k ; )  ,D5.y&!"%&-))+t-q/135.7|7A7z7477 77681y " gXߕR:TenlfM6Y)j$k4sxL1pUi'r)r'maN8p]TKχҼTpn9IU*f(7Q+N$I(w m & ) ,.9v-x!"%&/)+y-K/13677"77 77676d8#% x#G93Z#0SOu^jjbN6oIn.b:sP;wb#x7~67~2n$[C @p϶ &.ky]Ck3LNM| Y ,  8wY "$& )'+Q-s/135M7n7n7c7m7T7y7'77_2M Rt* Y$_fІPLt*;@f6L*%Bee؟lGك1o4&wS,zJM|O C 1 >T3& "$'(<+-/l1357;77!776768$ X*hU!"s!7cͰ1MUv vIH E{%Aq96dS}g mmg^qRQJ-j%ѿ~h#Aۂ!pf[uLu;y>w>x @ % -U|6 "$&(#+0-w/135e7o77h7~7l7]77<3}e+wQ>kF!!&'4A'DW|qBQF}/HB?m]nz |v qcjdB &Wӱӹ>շւ%ݧ09nE6zCk\Fs#}){+ \ F   ^ YtD "$&)*M-A/135)77D77 7768b&j 5 oA `>x@e!"F&;$ۨyI|(Sw qR+f$9B>/Y<](u10, zvUvhЈalջCش_߂5 U'FL8jvu!V D  [Mi< "$&(*F-C/135=77e77b7774aCAI- #}$%WwXF]'m*s#jY>p0u0QA>gBk5BE=3 hJӱпѬEգ f|3m*(v~xp<)ZfdQ 3  FRo "$&(+-Y/t135w7t77M7768N( a-B'. K$ $#J) >5]]D_ qv paF e'>SJB(nT*v@N%S*N&B$/$z3&TԀ"/Yh=_ ]e}h],wOXS}P % 5Jh  "$&(*-\/q135u777v7775 [hI}JHJ!n#%K(>NΙڎg2 r9Yr~nS2TMF^=9%M~6B0ԐԿ%2wޝ$uXd 5=KtfvTKiAPOwE ! 4s8U  "$&(*-5/135C77a7778* : bx!!"2&&(QוJR88lYtqV5sGS ?h ?Ht z3)P>\KePcR`NSO8`>7 zчv`pؾ٢*T6 0 3_Qf?= ]7xGwJ r9  *k0G "$&(*-4/~135R77}77k76x`  EE*>!"E&t&+NьBgq5 i3Rfko_F)uMPIbIO~{>-\HqWu]u]t_d_Kl bѯѾҪ;֛֭$ؚQvnm?2K*#N&l6hAg0 Z#; y"s$&(*,>/W135777678. >6 L+N YCi!#q%'9*!#`*|R0?E<* V"D[^YI#zP4rK[ h jj}kex85D{b؝ۄݧ+GnCH)9@_-`6^' O.| h"l$}&(*,1/P135777H77 y> D J7`,H40 !6$$((,H$pK l}|/uc 9"T$J&(*,.\1I35 7'8&78#  n@"y#!&'k*,(0NW|6 Z&x5=:({`: RSt Ze/1dYu,678!-(-PїӒ"סן1ڶ:r;"|pLz=Mn< t ug}6lK J"<$`&n(*,/71}35{77 83cZ K 6 b/okD"h#~&Z'++/\Ϥ݄M)s @ `4s<:y,kR2WR)au =Bqi"8H,K0M2@552LJ!O[u^ۓ܊.sZh;p7tD k0 j ob~8v^= O")$j&](*,0/13T57;78(3 P-k@ "#7&'*+N0lώ_^!Mp|a>N`{'op H@k8M*Y4^7b;]:X0?Ql ֑֝*ٹ٤HیPެC]hM?pT4k"w;Z3 x o ]fj"llJ 5";$Q&r(*,/?135775C?& X C3[xh !f$%(**-y.,WHQOAktP&p,hKf-v:z@E}Dy-`HӮEhaڇۘbK.\!Lxv<*`u&J0 e l HgS~jEN "D$!&(h*,.n1-3568k,@  x tey !$%()--2W rӈݗ.},/m^ztN$k2t/k0n f E7tZ s< FOQO65vzr اؕ: ۸H*(gvf_.wM d!@ _ ] DUNylVE: "2$&l(k*,.Z133577U[v Fb"kXrL 6"G$M&(*-.2#gvCI;YhlcO2 wAd{+|&}bS9Z4vHY`ec(C )ߛѦ0ՠL=}RUXnDdovk[@#q6JjC  l b A D<TYK.mI "#1&3(*,/13B580P Ey [ - |CEM<5| "$&&(7+`,/01:G:e{(2c2A;.OQ A# e"$&(*2-i/}14E*z;p k^O /CMH8$]0f"w)9&z_Q*{ K*g?wJX aO2*B>؟y7ܤbx3utg ,&2 |;Z6] k _ , 5 .NW>&g !$%F(3*,.Y12L6*] n M Az J"$]&=)*-.2256߳Lx|I;rQWVJ1kIs2jE{ )`b.!N=iR}` nN$ 9~>uG"ٻ~Qݥގ 3rHCi2Q+uM  b U & . #GO7|b !#%C(+*,.P134zm@ VnB - |"$&B)*-&/22Y8Ѷ܁!+|yFn.;<0nKm)n&C**id3%]Iv\o|!WndҦ~ׂ֡M!ھUޮ/dfsR&yNq; ~ b @ .  (U<!#% (P*v,.03J.  q 2 >n9j "$'(m+_-/1G46. ͲDSuS2a|W-Kz50;{!v\C!nC`!p+ 0']ڣvb۰ܙJ.SB5Xy6$eLr! i b $ ,  Wa!# &'t*5,/}03!U6F a gX^" #$R'(+#-y0h1K5358meG,R]{]1r9:t';xZN tHc2y994(gA;أٙD3}d p T,au`& T8b] P   C[r!#%'O*B,.004  (& C  FxS~ "$8')+{-P01559$!H6E!qMbKix|u]@wC o-05!veO-vSr1@-BN,l+.(&(f޼ޚU-VP}s>xgCQ|D` 4   !aL]!#%(*,Q.1M(  # : w H?]0ZX!"3%&)X+./2-4$77 3@m`'M}!9C>3TTDy%0f s?Akf2(=<A_3kF\UWQںۚY3ߐ^X 0gs>jOzfV# eEu& jS   Yo(3`!#t%(), .1~ ,   P hCT*Sm6!"T%&)=+T./337F6::-v7Er#'SEDn7bz=Hnl 74DLJr;zV*4ӇՊׄ؅=+܊j+g(A<>4YqzzkW=Y2`"bC  Bv-8l!#%')T,.,= F  S G G 1~YW!#9%:')+*.02u4_779&"g6wd`"-." f6S |1|((otMB{ l.G7SS[}F+k%sӬרck ݺݯ\J  3aWkJNwXB%zh'   >Ne!Z#%'A*+V/"|    j b 6c ^# %'\)),-0F2e5h68 75xIpxAL/Z3v@<1t]; \`4v{bW4c;S4bOn}Z3oCؒيڞ8Cދ߂'_ch G7T-9bJ-f^  z4uGB!0#%c'C*+(.k#C7  y T w$Dw!x#%'g)K,-0B25E696:dS$h>!Z0n-m%d R.ZZ2tya]=!gD"[AjbsaA0(ڿsv߸_N6^fZ/=$8P4l%dD Yz#S`!O#%')j,(+7 '  o c K|XN!T#l%'),S.02=57/8O7L9f*}a=[D+Tq|~t\?s;e#k%gpNIy :4SQgqu]\-.].SۤܢRG{3#*K& b  yFO"_' 0Yp!~#,%'Q),xJ  u  b yj)bB9!/#%l'1*+.X0x347)7867<Vr!A`iiIv Ks+R-R}AZs 5@Sagr]kl\փVx#'݈t4j@%\9\6w7lR q w;g!r#%'i)*5m  Ea ` xi(sCP!K#%'>*+.|0347 78.6;Pnҍ FS IBx_msiU7k?e#N'Tv?Uy9@Wbn|kvX/{֯}٤CUޱޫ^Ly5ckN[1e2 r n nwlKH%! #G%Q'*$[E . ~ r B]!#%')f,.035F7877v86/ ʹ[/Z]Ok #J$'V e89 ` \ r;{bl!t#&'*F,PTO<c,Pfl#nv_^12^e7 ~ٚzܠH_tc2(BXteQ.]'pN" OweR "W/0z ] o RoDn!#?&(*,x/D1 458S778,7]868s6^7@.'1XQybeZFt)R-[Bw)S"De9NnrD Ֆܴ۟qv6/F^zQh~}_N,v1zc& #eL: |XX)3f S m q [c4e!#C&(*,}/L12458?7@8 7x8695c;|ЀެOMN .,P@hHq?j0X:Oo /j Ar;`y9FjnA'թݏޕVNfAD z]6N$BXZWB,wSeE i p_\~p!Vh(#h$ p k A ve40 !#&`(*,5/13C67777777E78,t{;Y-u` ?]s|o^@Wu3EEUAB~OXv 0Gկ/ݚ޵iu&*nmN!n!'?&+g*sY e e Z jtDN+ L.{7.! M V & J/!($%(d*E-.23697!8%7>86q8685W9˵7B9Jomz}ydG W*{9v"H8?0 p WF!+w&տ9M޷߅CQ7#*:J/ WRNFl y ; _ - bB F9 z&?2>mH ` U ; jR!$%(|*5-!/136R77;787D8685;sчD sFtV6PYS@(lId$k;29&yh LDy $'!Cc0ߣclXBP4nfl~@99/U b # H  K+nAMZFa g-l e w & _ AsmN#V!#F&c(*-/1D4U67z77p77g77h77720xHh/N236 7777686[8:685;$ ̭OoFP4U   7#EQ:!#L&L(*-/14a67 7777676768n6o5{pDZdE[ ['`"^M/] $Rl /Me^ dڛ۰܏ݓmpK@|Wdv(i(oVA cJ U n G p P o\ ;GDUF   2m&38{!#S&3( +,/14C676767676386847; lu\-4LmnEp=Nw 4nGpB_%DV{L۶Xڧۯܚݖ}sVD& g,w)5d:_hY,yE'ec 7 F ( E 8srycukKQ08,  T|6D!#&W(* -/1l46s767h7/7f7#7k77{767a69(L۶:f$WR-QaebK1 m7io2ICJ=C"+Yx2rSܜLڦ۲ܡݟބbU/y> ;Ie)QTaaU@,uS"kN8 #    .5oz\%{[07: %Vdu{!#%(*c-a/B2%467767676767I6I857\hؚT8,\~f8n9r.i"B.;)$n[dRܖRڱۼܭݬސߌmc>+P N]s*1:({W( r>8   iH_lK  H5. Pjy!$&(*-/2^4767676767z67685;ЌҬvk ڲ^<*h;Y_ZN1a*t(^W y(g ~#Yq:s^3/5ؘ}mB'b E?czd8zK+ ;hn @2S6~# q $b1!u#&(*,/1436}76{76767~67J675w849փFN0>TyS"^$^_1|-).kz"9MZMe%֗4L,x=L~X' tB+I'<G>^\%+   BEgT=z O_^"n4J* '8f  !=$J&(+-/2466D76K76V76i767868M5=:qЬܝ67 U{ Y9\hndN1p EiWG|*O{Bh0?h-Y 1WS1 VJvP?-Di`Y(yC$uk I S @ [ \%['4 O k|aB &  '#l~%yv:f T"$&f)+7.k03(576276576976B76P76^762i ˼ٝ72niPwtN(r<z,~1OFTD;)|oD)9ԓR^KK.(I(o=D7:T?bK !Z-iwv>)^r B _ 0 i H + *#%'),r.a14366O76]76q7a67*675i84:<"ՂjL-%3M^e{op_Fb#@Ri"u'A*=x&a\a.RjI={]ۣW}>T"T;vAJ8q#DCNE@$Q.aG' FyC5EXC&:!W} x *wbb:l!j#%'*,R/146'7676"76,76H7Z675`9$nٵ#'ZFalk\D"c/P^u&u*g vE`{[&&eֆohݬO~.GaS}PK .-spd:vI#r_ L @ D H [x5jrt|ZZ 0  ]p.I8"#n&p()+5-014J6:76876D7t6W7N6|7 675$6Zʈ؎/84:FJv/N:k?W1 :>-[^J=VFK;$|WdyM$%dbݰ߅KI P*J {7$FbdeXO4\-g<& B[(8:4k A Y C N Z/3 "%b'),w.0<356666666666c67,8ڠ>$.Z5g"a; g-TTlbsM^!FPm=;>ՀNQ޿ߕ_lX?K[,ZsD+}G+p[ B ? < > Rm)vs% q[!X e f _^<)ws!#m%+(*,.1q3V6667k6J7H6g7675848jrRfv ]Z ' *)Qr89`Gl:T}+T_5=4}Yvx-c1u@u=dVT$(-iP_P n. [#6^ V{>P*!#Y&Y(* -/146!76&7g6>7=6l7574?:@Ч܁Q1P&;woh7v B Av0W9L)2eh8;e[.ݚهvmQ?" X&Bn&J ]xqrG:^D]W (+H%Z{A"![`MRCK 2    &CmE<STF t"$&)}+-E0w24666666666660Uڿ3GJhn3z*o\s \ ThU!#%(4*,.1366667h6'7(67d5r9B",nBOP(OfpkYAl:}C8WHV7:sr D:rj: 4lt9ݝޡd\dFo<<_!yF>D<GT %  $cMryV/-  C_!7$1&(*e-i/%24667m67L6376e75|4b8#N]|S#b*eU vbg SG0|f4;Rl+Pޠߜ_RC6G d 3$!_*yLr g P Y N mw@p`Q7wIJ;Mf 1 u  h $_J/ "q$1'(+-0&295 6@716Y7575&84m:F&T&)>YrvkPu&J=^QlNb+>en5#o:Y9׏Aډ%K߼߾wl&X)g,8ew`A)L+w9- 14)L!:&ot/? o  i<h( #J%~'),x.0"3L566666[6.758 'p}8QE gn/^i ;:kg)&Ii3@nք۠ܐcKuF V kxFcpto^A_+pE z l {B(= -#1 :.0[? ? ] Z&{Cu] !$J&)*-j/u236@6K767584`:KӾ:2!)+\FzQVH2pI&z<}6QDN8+x]I~8MCN28܎ݬH^ G:TKf7#QREC.|;4 #"Oa/ 0$ig M h m i R F "$*'w)+.i024666666!6 8*"){B<IcsoeI+q:N r"av]d:8kk"/?eJ D<ב nݪe߁&YPd_~!/%#W6T,JA+%H \  J  X48~ !%;^ GmKM    w,b1d !#L%'),c.S125G6676f757$57MN5f8 2Ea]ygbY|;b@~;bQt'Ip%LX}==[az tYסUj"$ޜ߆G'P `U;w3i|Q/T!d9 q?h!p"%[ 9  < E/5ScW"#\&,(*,/L1845?76h7574$:>ҼDݯOW} 5O"a#]O4~G{;tJmDV $QRv u &69̣IBLK8L[SI+ Z+n*j$>t8f v>Edr.*\3jY{Խٶڇ۪G[R>uFL.%S @psY5 [1n2 b _ I a Qse;` "#r'; j $|3&!"k%!')+.50I34(76y75748i\gߵN'W*>4X:d2b%W8{Bx3cFZ@5}fJt=-RZ]O&Z,b,ۢd݆)_[|Z9 m1rWQA 1\|! #$' Y* - AEckdV!#%+( *,.v135J6;767)59 vAj1tr6:;* xEK 2q+j oH>yg5U8rM*K&m/.ܤ݋O1a=aclWP1m1 iAaO ( $   1A \]!#%(""B 5hXiE  N F * faA"aQ$ !N$D&(*[-T/13O666h66601ٟTOo17.lK)s39VBI0 lM2x[ 32>Q؅2{eل(6ݒވ7#dH2piJ Q0d) q z m 4}czMM P"$&F)L%flq U t A4'[ "$H'(+o-014557574l9lށXBz2: 4"Rz88[+Hk(F@;#xXFm1G@Va^^[F&٪mۇ!'o^ve:ynJ%f/]6c \ 5 > % C<x!#%i([*(*7 & i . > X J !Xm;V!#1&(*,Q/"13p5$786>7:6M34])3$Yi* JX]Q:K Gz$^mIP"O:wXs/A?#Jz9ڮۖ[9ߚp,lw'.$!}QQ].  T)pz j"$&()"++cO .d NC  u tnf4HG$ "$W&=)*-A/2365749 +ԣMl'eu PTE4@{^O(tNn/8A: _׮i*[ܓܢ;=r`Nxo2_cmxzH<~=dKSJ   aw_aJ!#%Z'*+-(I = V  4btI #%X'})+.}02 5F6 75{8&WV/v#Tz~cCi-\YoMR)%\T~ v$7;@b9B\'ԁr:ٌ)ܦL\}jeHRq L>pH= d y A l Iy]>t"#W&(*[,M/   W p  X$alhI!#z%$(),V.[125 6{75{5G)ئ.VG++ YM Gv=b }=Hnm84KHW`Wm+sٜ-7xg~ZG0 <"P]n`_A,JyH }Q0 3n,?} "$&(+6-`06!h iI    wsKF"#&2(+,/1e457 59zpAqv{P a%]Kf>D{J9mUj(~7?=I,VݯҢՒغ٩gFݢz7 - ^.~_;k0^3Z F '  "!FeNCMN,!a#Y%')[,-`1"UO ,  @ Cx8L  "$&)d+-/,2T4i6h67*\S. cG)G]_\G+Na8z&+bg8.cVt"0,5K*%׌+ڦګJBރc}l#8E@5 ^*TL* { o $Z2^@ !$ &(k*'-.@2Q&d R " * u  L&zwWf!"%;'*+. 0]3:47t57i**G?| W#a#YI\62ta>_-z;"C5JX; fB։GکOjކ߇*Zmpn.pIx+ iX  U@U "$&)W+-/2*y Yt  = Jc (!!#%Z(*,u.12T6]5>9VВ~!cIljFd/m%c*be<;ke! 8%F7PCXXYoh֦)Qywߡߊ8qQJ l/ P0}Wr e = > ( <:aze]cZA!d#k%')",`.0B3. Z  4 .  \p)=Y *"x$[&(*V-@/136 7/Y[.L(+"}Td%LCM("^Nu?W-k8q9B)-2BݍaQקsM۬xBߎO{`x Kt}|pR;P$w@p= )]?" $;&e(*,,/_131c| P * ;8'4O)]s !#$s'(+L-01z54 8`՗ߖ-0`q|W(\%r&Y(T^$-RRsl$/(.= |,ӦפسOE܂a߰65sX]g> h)U`E  3[e} "$&6)A+-/M2644[ " ^ p v,[eZ Pl!N#%'*+.G0S3(4o8!KE1i7JUPF) p? m&;9<oN;t^ |29*<88P![i,بSo܈݀ l_c3%6WQU?*^(xFj: m e F N B^h#bSCg!E#%')+.b0!346N86  a  "#G&(*h,J/0315V2]Y i#@XpuOc']Qe N?zmI#j9L$Q.T5SJEo'|ҝIUغc~ݓ݉< T0+l7]XB}7 O#zY  9ZB!$/&M(*,&/%13957$k B P >[~n@ ""$E&,)*-.227m#Ӿ!ZF`osfV=V'm'e4p|DBy j.C!S,`5f<f;i%@ 9Pْv"ݴ݌Hߤt] Y*Ic1vJ ,   3g\d "$&(O+g-/1f457+e q # g2P{F' " %'Y)+-01\5(C͙0S*Z} }^5_#AHH8!dL-qM_&p,y0-  4\ڎ'*<)ٺiFyޘNs ^kx\R# oD[; X Z > YL}tdYV)!S#J%'),.025B67a0     sxU!#-%(j),-V1194T#%Mai}w]BtEj"S*Uk(1RQvp !.+' 4jt=j՗9[ndݝ;4%r~Y(Tg._7 9b3!#&/(*,.1p3l56640 c *#l'*"#I&'*<,/0758RKt!/0%sP)d$|1=6'vN8} ^#x4>?'>0,@sunӫ>؀y|&oKXEEWC8vHf'uC U A   '0wVc& "$&(A+?-/1?45)7Y66#%= I BCTBG ] "e$&(<+-/1,K^ 0ZWoqZ3|PU Of MGp J*l>MP#S(R)G+88<_)!rc؉یۄ3޶ &xq2m-znYV,f7\# t _ Z Wk{scjM3!D#O%')+ .k0l24@6#7467S"F*  t(yO!"y%&)*..f3, N դ`I2lCGH6{"e=c!_6r|UAvh0H"Y.^,a*d#^^Rh үԋםs*ڰs?ݟޫ+GV4o "}Gg6qFv?# PQvI!$%F(?*,.71 35k6'767(( U dWO4z!#%')m,-1 BܤUi 1O`gaP8[ w3L@D&|J7oRe!v')$}]6hؖiVnܧ[߷+"5)DSykk7,q 2 F(u : ;  Tf{ v"$&)*s-g/13+667>67A. b X !Z,~K !_$%( *J-_.(." L 9TNs[]RCt%Y3]K*Tm 40UV~ t '(&|&G^n>t>%JckۖSHe@w}Gv?Jh< } t ` kn nfU0!J#I%')+-Q0i24Z666662(  A b'INMU "G$7'T(+,`1d*E X_ZH-Zf%>/-rb5[,v9 ??:2^A{esj},@W^1:YEI$m,H P~P)  S[{E!#%/(7*,. 12d5|66z66]66 + q[AM& !# %A'y)k+.$ V,|AHIC+d9>G\LE$wE)h? JTQL@ 4%|MP0sلr*Ax Kqk=wEUa(m P 6 "  *Kyjp z"$&(*C-]/13566r666a7! %Q {tc">"#?&'*+[.ZIד'FTYQ<"OR .hzQId1HW$^#][ONzKW]?]/ج`=ܾ۠Psl  [8X_}/ c u \}y4jN x"=!#M%8')+./u2A4z6w66K6757(z&h` dCC%? !X$%()k.mG:iu#(rHXC5D{J/iP isuzqg}daq*PA]ҁԒEURڦ\INzF.Y +mhiuA;:L!O+ug$  !>p !#%'J*I,.0346w66\6667`. c a"$q&/)*'ͨ 0H VS H2}Ay5jIa+,ZGvh{#!tsrV)@ҭ2?$}<U"b#t> p d bv$oM^ !#(%)'j)x+-/32)4;666n66T66'6J6~) S&>Pq!i#%C'2+>q@WnpfV=[t3E>4kFc2w?E F70wk YyIfWѴC`_ڻC|+7vsC,Yc o(U2  HYv$!#%'*7,w.0246{66f66B665}7# Mhd)!"#&'(ec ^-o1bXgK=y b#u>MNP L9t+c!BS~ӵ֓@&ٙ\|<6yiMmr y)l f + 1 <9QPP y"M$&(*,G/013\56O66<666657* 5. .| !&"`%%* )'{vkssT#_.z.f7et :2^Hq\ ebc]wPbAJ7)? ՚֩'ؚY]l.IBJq]oE< Q(`7i5oR ~ { c ngy^E* #%2'<)+-/10456b66X66C666M7/ nl8^r5-!+# %'/hψ nBVE6AK=lT dol ibwU_IE?E~4 z*֏ַWWCOMUEGsa;e*m/o:]&  5Yz !#%'* ,b.e024m6_66P66F66;66N64v 0K!g}0 !h$$'dMس{MU~d?vH]EgIJr>P!c)g$jhULnx03@*bE`%l1w9{5t*hS<"hUh`o10ֈ^ߐ;%oUy-(,OB On7R&}!#%')&,.0\2466/66"6666565}7-az 5R*!PZc""B&(L@*. ^TL_hav\{No:bFR{ 7nC] G9[IlRqQrIg?Y0F , vqDXySO՚Zici OL[?=b2t@t:yC~ P ;   %AjVRoN ?"?$Q&k(*,.1*395Z6P6Y6K6R6H6K6G6A6K6!662 8_[1 !4%l۱ ީc6O^fcYB&i3Xjri `:"Y9lD{RM~Ko>_.E)qr=\pt-lFnlJy2dGy:~6t<N | u ] k` qS( "$ ')R+L-/135z6$6q66q6 6u65}65655 p/k ! TڡyU$SPWgTrJp;l#S2 n.bB!*_Y#t9} CM ICz5e$L. ky\I_vBҕәջC1TEQXR/oCk=k>V# *w;P|!o#}%')+.,0F2b46M686G606F6$6I66T65|657&q}yPn$ҙՠ߆$;B?2Ui+NAL%T8pHzR T OEw6` J ,w `z>YuXd՟6ܭ %E.P`rc^A&n2x9t0r4l E &    +R;7@) "$&;(L*,.025&6F6(6F66F66J66U65x65)7F-rs!%*][|rU0m0O^ `U@k< DNUMB-hM9iCqwSm]k֣J݋C _kM}2}-u$~6 x Q W ?_[9D "$&(*:-4/1n35$6A66B6 6A66B65D65R656A2p$*g!2zzDu ;3b+T_: E*L'O$A5vavES++F*`O ֡Ў%1׳OmA>+!b-z8t(k'A  R!yC!X#>%q'l)+-/1645H66@65>65>65C65L65^655 ulwq! QmF!k9{2x)8zzR9zNRZWK 4qUj:D '0AwO׵ڮ>9iQp 8spqmD2q+t.d$a,Y 3  3)j !#% (*T,H.0245865765765;65B65S65~695 7(357T]uJSL;K) ]C ZV`XM5{hIf+Cx'dB"qѕرۓ1O|`-9$c:]2P(Z7 N I , :)Pa/z~/| }"f$&(*,/1=3%5"656565 6565555 656.{Xd9 'jQ-oAS Gk INy >!Q$S/V(PF .~bI_(:sz[<wҫّܓ L *5/5 ar+eXj5 ~ <p i7 ! #%'?)V+-/135665655555555565B62^PWF+=!u[7 }BXqnfN4tQad#b^I3rU2dA}S"mp?mݐ| /e}oT,f'f$XWt@  Of'!#%')+.30P2X4555555555555555555[$K>Q]|sph\F(rL g!j 6u}OCz ckkiaQy9`DiIa'/aN،פ Fގ|'ltMm%eU^ O M  % ([hrsai '"T$*&s(X*,.02 55 65 65656565"6m576B5g6475*;hV\OP#*ZB9AI;N*J3j.aO/?ws:X+c,f*bZ G|2^=d{@R#uԲѼNsߍt-$'R:I an^ MY  s e doiL@ "$&)+?-R/}13f55555555555555555R5l6/5ޘypLLME6|Z3t7EWNA&sKd'n$m"gXJs,U4`u@@d&o]}D:Du5Ajm!U6R,?3WG Kr6Nr!#i%')+-01;455555555555555r55b55g54 PڝjB1)+76 .v@s4v"Sr@Cm_v!yvq bKg-K#Xg48\yeSMKT: uRjZ D{Gx G -    2^HBU+ "$&&(B*[,}.0245555555555555555555]5'Ն_$ qLu>i#r!}#l `<\/n5k-l)aR:oP*kCg= Vm\[%OX ~-UPb?:T$Z D 4C s R U KYbO)[ "$&(*-/<183&555555555555555v55Z55 5c6,  NAPOE4g6_ 27,fE a2o4l-j%]L2oP~*[+mBc)8h'h'dާnA~Y9c_ Ck8zY  o6H\b!1#V%;'y)g+-/1355555}55r55f55W55D55*5556460 e^b8g>K4W22eZp-{*t+o bJ,h Ju!KeAJX"~lv7צreP&-]sVe Oi8_5~f . 1*!h !#%')#,.X0C2h45555}55u55l55b55T55A55)554 6n46tЭܖtVUO=(qR*|=?a JS#K0a;l5b5\%N7eDc9cj;35)9Xװ۴W!9_81qNr6G>">#wv f h " @ H-y~  M"$J&(m*,.124o55b55V55I55;55*555545464l635 nɥ֬%n ftwHT"-m'A*Hk )F?^Ef>]:W+A, fvER%[Z3{Cӣ ٺܜ:SV/IP7]Ke0Vb8 z s v5p]/ !"$')*+?-\/i1x3%55w55s55l5}5e5z5\5x5R5w5F5{5255 5547j'$ڍ7tV5r;\n vm Z;Y0i7o+c*TF,s Ts.NsDQsi)o0Ӳږx&!r6Ft4WDaD  SxC[2r!#d%'{)+-014.55C55755,5555 55454546T4y63Q6Mf[$<7Ygdq]IA"#~8R Li.PX| t!)vd N}3a<~R"U(T\{0[HO%{U]NeaNwLYjQtHU/92f e # + *t5-|q /"#(&'I*!,y.K02B45955055$555555454546F46839#9i W!E))#f+MTx%Io ~8/Y?e@g3^'Q8f@iAO{GIu |~M7D{abX&ruQ~=z)Y|@yH  m d B KLlU6c  "$&(*,.034{5J5p5F5l5@5g585c505b5'5`55^55Z55855-/ ʲ)wo[~Iv5o^?p2{1XHN%M.i>t?s2h!VB#`4l ?o@vHi0{I ل>*?aJ&u%0zXiFrd ~{>SGl!#[%'r)7+-Z/1c3V5&55555545454545p464628ʜӺ܌kH-OR4F#9Tlu*)}hPi0G #sF]'RO'_;*/Cڨ/0Fzlf`2xGw@]>{7j F N3)t4 !#%') ,.302234J5M5K5J5D5F5=5D565A5.5?5"5@55J54v546' o;+ z_;}G c~0(~hN$s< C @/whLq)O rFV"~LC^UHg֠۾ߣZ4 H~d)>t+N5~6 ~ t G P 0HD++ ^"$X&(m*,.024*5l55o5 5q54u545454545?4<6z36'\ԈYx?$ aw'CU},U|#OApT VPx?o(] By"P$e7Xq~9> |'VDܼol!K= hNyPc-:|(@% ErJ!#%')2+3-X/Q1^34Q515G5-5C5&5>55<55;5 5>54I54y5\46T$]΋0X!gI&WFQ]NAj=JPD3zeMp#Dg5Ndy18"Pf\2ޥK.Dn)4zz]W6-j tHe>j + 'wwV!#%')+-/135J5$5G55E55C5 5B54D54F54P54`542>~Ӎ[(+^-p:q$ew#]Z)G$U&UG :$lLq%Kb.Q`w':d9ՀU߂@n^> lIR y:V~7t> b N < ::Kf-.o `"H$S&K(c*f,.02e4I55A55<55:5 5954;54?54N54}5N46 ֣%fCf5s+w*=%^D`"l#iUH{-d AyT}SVF~ DgUL߷֩܄L!5[YaH9LKy&Pp<xO Nxu'!"$&)*#-/=134$5;55:5 5855854:54@54P54}5A46$)Z߇q\D'mM"s6~9TBH$y H!c/n1i V G/f >yR~ GTu7~CUtI ݹ \~l6ZEgBr5_ 7  1c}7!#%')+-/1355355/5 5,55)54(54+54/54454-3 $u>qQ*uMPVl[V5[/m6u2q\ L/d <|OwH No1wADNLs9kYIIn' 2s_ mxLO)* n o 5 K "I7sz kq #"F$ &E(*a,0.062e45A54C54F54K54R54b545W4537[<|tmnL[,G"b!N =l)U[{)6 .p [u;Z3Vl#;Sd!|yH/#<#_{6\QpZfU1H%Yp>tS ~=bU  "$&(*,.1245555 5555454544545E-1?}ߏDa?d2v3{4K55r c- =C=$q\;`8Ti:MZyvC;Zcfe;Dmhrpcw"[n'A|7e 9   !cgx1~!#_%y'b)+x-/}134054-54,54-54254=54S545&45j@bW=uO/gI"~AAjVd?-mLY\O5s!\9mB|Nr:K` ow7"~ $(׿)'cC_Q/i5M ]Ee6@ sLwI \ T 4 >8TctmE 0"$& (*",6.50724555454545454"54S564l6"Y܆kmO'd0Zr'~)|!q\7T!a$`S8|"bBm@}Ms9|AXauVf[9A  'Ulri[7s GX<Q% 9nN "$&(*,.0245 55 555454444454{5]/K~g-8a2U=?G6(lMd-q/l!`D)_=rDx Hv:s8_Vs,;TmN@l0`Ml@@b4T @c A   5]n!\#b%I'b)V+s-e/~1Y34454545454!54154`5,45G:ّPTjD+b(v6cZi M?f+}86|'m Q2`3]7()e!=vWbQevy_FH7cq0F B w J R .KF _S "$%()&,-60144&54&54)54-54654O5p4536I& mWUm:g.6j;qyE4lMRK=pR4p H{MB~Cg'a!9g`zh۟$U}?S8Xl#M ], JjN "$&(*,.0245 54 54 54 54 54 545419 K? u]4Xc$PAM/`C QYQD} ^AlDPzBBafz"0*uDp1 p& 8#j:`#.sknD=wf = <  ,0`n?d!x#=%m'9)r+?-/B1v34.54*54,54254?54[5U4536!( p&ݟ$,c/Xn#T|$S_$E,W5^.S@ pIm#C\t"9IX fq("x9BcbWFA|7*^:K~IV$U) W X CVV~'xmF "$%'),- 0134444444444445p45o*  %]u C$K^;0;zqD%d:pt+\8xT~(QX DCYckt/ZcZDa:h\~15pXfA? on:W2z i / * [u!Q#^%5'W);+b-C/d1+3445454545425z4n536<_} j| kEc/f j-pt M8qR^\Q;dCa-Wb*BGW^nO^V--!]EIR 7C~*JU}0r7 u e \eq=vL "$%'),-013454545454 54%5f45- Uq"N$y9w.T=BtC"^-h+aT=tN&_-^(\ FD^Vp{,(nYFێ>O:qN`1&dXo$4Mz.K ( m$wa "$&(*,.0n2t44545454&54:5q4j54(5$6o`p)E fGzR^+Q5f>q&\0B r m3; 1  e V " + BL>Bi!r#9%W'&)Y+(-]/1C34 5454 54(54<5l4z536}$L] 8 [vLr.gD#.c]'y8A >0pS{)[4h8g.^K4aHrp>B4*\,$4l-uFQqJxO x z `xt >lT "$%')+-/134 54 54 54 54 54441 ov`p"D [Ai BM~v6N"PJ8|[0a6q=j-`N{ 5aA}Vb2(~B3 2cQ<s~@CfJg *  8e @ "$&{(*s,.p02*4545454!5485r4t53(6S Eu(ڿ Ec,]h-uyVC~`!p'ofS2Z4rJm8u9\Xu.o 5gV bs Aߘ} jKLd"%AVI { ` A ( ""(Bh86{!X#H%7'4)-+2-(/&1 34444444454(5T46) |sb+q7]?FJ?.s W+q7z9}-sY5a;{ LuC{;bXu+k H52tNSr" !TzGUM&?k k*2]`% yX/|D "#%')+-/134444444444543h Kkoۙ߁+:w;Hlkp\I#o?JH <}"lChFSC~B]\s*j%0qB6+Ij$-ޑ;H `i|YHy nAM-f X   &.H? "$w&(g*,a.0B2`4454"54.54F5c4536S 4M0H >dP&Anv3"M-X*U!F ,| Np&G^}&?I]`o!rxYg\0'</ 5yQ\H\33[S{*j, r \ @ :7F[~N2Z!k#L%D'1);+*-5/134 545454 54'5e458, /MNtS{M!,X?@v f2)]X s s Ud`^%!#g%g'K)Y+D-O/01(345444444445.S Pq>]$s(h4s~TDe$s+s$jV5h0pFp7s5WPk_{)fW+lF0bKA/?Qd(,^\wx8Ui ?  Vm~ k"9$*&(*+ ./1344545454C5V44siVt^ܲ0'^*QOVH5~a3{EE<}+c DxA~M~By9bM|+[ 2`~,GH!k (#dlzx'=d{FB d\$m ` Y * 5;5rlT!"%&(*,.0o2t4454#54754o546#(% <?{i%O 9q)`].I%V"TH2wR!IWK =eTy,_ /U4z6>B\;% Jbu"^N] 8GOa }5{A   P b$ !#%'z)x+j-k/P1@3454444454n5/G"4*ޖ>i.Y N\<0rU"n/{.t$fL~)Z%\-\!V@s'R4Y`%b">|5N;W[+~#u@/aV[  S 4>L^nj=Bnz).<ZR n ` KPOjQ+H_!M#%'(*,.02F454 54-54\5.4k6&S Im3@RNN8#kE[c[J1e Cs  >xT&QQ|:u3UE_ K^Le1C-{ [:gd6e 0 + U9Ty?saU0q1(Fi3 ^ @ ! ;U@(T n"i$"&3(),-/134354;54O5435`YC 0b;z\݆fQb -M[~x- : 6+qW/Z/d#VJv3^DfHgFZ~g,eH*+ ] . 0 Q1y;mC&`0 j83 5  g}gn=UM!>#$&(*,.`0y23254F54z5)4l6\ z &)CܖFbH?k=T^XE|*`9s>k,d$Q=bIiKhj,f ]*~ `8  ufM if-S' p M F6>JlrX4 "$s&M(H*&,&./1354*54C54c4F/zHAdB8vc-{AF?~*hI{"PQ@s1]CiPlJkSNZtb%}l??- N m / D _?e[5f9_C , ` Sk=!L#`%'*)* -.0X244P545+46m"pT 55Va7[i&C+R-U%I5\1U%` D};\PlRpLj Bpdy e.(  h l ?[W>1D;Ws: i > )  &O} D"$%')+-/_1@3454$545.KC_~.Vo߇OeE7u \&o4~7x,jR3i8k6j"R AjNq"TvNmlYpg#ug%` x ( & N ^e7UD486:Y U  ~ fxBaG!"$&(]*,-.i0144O54o5t44 vbE0^t~Me7mU ?Pk6?D8 kEk>} Fj(a@v'O~+P}$KrJfmjr}9f4 ~ e 4 *w+&y?(o4+` v : "  L|+Z( !#o%r'6)F+-/02C4N54w5M4n6$` rPx4ݦW.pWP+zN `*j)jY;vNTMy7b!Kw*S+T}!Opw_ioiir&H ] ( KA s=rlnrq||<e6 | X O5FKljKp  "i$3&+()+-/1}345 54v5/RG{ zeHY'3g^ x; ? =.qW.[,d+V El%V~0a .\~%Tv Mfinm{1_, { ? ^ 5e*#NI4b!edm>~ P   ?]qj!H#%&(*,.]0m23<54e5495 @ `IJ1Z9Ft@\)OY"EV&]U E(d;l 8n2`Gt*X 4a5[*Kgoqgkm#: E / Ztm g\h~ heZ nR z J ;  #Zy |P 5"#%')Y+}-%/N1244p5b4`63&X Xw9(p6TzD.[>p>t:k%V8xOxE} p9l-U8dEoDm ;^Zft bgY$ (  L/!q&&)2K  P ( =u;=R!"$&(h*p,/.=01345<5W1 K%mO6^Vq ~ 0"J)Q$PC+oJuF~Eo,_:iGrCk)L+,/024v545v b-@v){p| 5'X7k>q;n)^ @}U%SL;fGnQuKm@_Ho epVlf8U @ S2"7v>b/l`~.k 5  tu@j7 "l$X&(*+-/1-354#6W)! '$>d^45(cESU K>rU+b/d'Y>lKv"Px"Po>a]Nhdl WaT/ I L W]n*{DxU k t@ X (  5z/!S##%&(*,._0A235/512|f? pz  ?{ 1O/`2c*^H,l@m 7r5\MoR{&Uv"No>_Kak V]O rc  c 9* nfA!J2UJ7  s v =Q/VH- \ O"#%')>+-.Q124z45] #Jݧ;HLeUrPoFi0T5~ Sr=>^QlXz#[vRm@Z\``sYaFef? i a  Vr _ UYCg6>9^ ` %  +r,%c!!"$y&f(.**,-/1345+ E#cva;S[VJ6qO W$ODq%Ux*\.\$PrC]> h_bK]V$= & t 5k~"  "V(aJ5Af T = Kg^Hs !#u%"'*)*,.092U443:]`?=S޴1DDZIiCh3ZD&c9b*f!H5Y8^1^(Oy?Xm gfPUJ { / ' g2 tOMKMw/9 4  ozx%\w o"U$&')+k-/1e3%45E!" T<}S-/ELmZ ]VEt([8s Bp6j%S 6` 9e 4`'TtMHYbNTA`tO E [My'F. -MVSrF b .  )iml e!%#$&(*V,D. 0 2z35-?6]oe>1:di3U&e+k%`O5l DzH{@l&Z6`7c0c!Pq P] eTQ>MU% W = n9 x/ BtvH4X$X Y$I  i GC5BPs)tN "#%r'D)2+,.02+437 @*#aj7f%+8A`MuHs@o+[;X#ONq-d7f:i4d%Mo0? \ U M:DCx- Z R 10 o>yT P6toLq s #  l){$[ "g$k&($*+-b/12z5#z |9'fJ-CTZhok ]In'O(k3XX~4o;l=m5e$Oo>a[ ]?A8_ ]  u 8*Gh* ] 6  2_8@![#'%&(*,`.[01R4q. \0(4EߪK*f7p8q'cN*g9m5h,Y@kBlBl6g!No/ MX \CA0F\, q a % !#zY ~{VCQkA_R5r&Co @ nsawyT!+r T"#%')8+g-.21p23/ `}gCQPC_l_wZwHh.Q0y Ip;y8ZFiFmAh 8Z Gl5TWO;00D <  ivjg1vUWm:l.I X +  OE<r1!"$n&b(*),-/A14k&|( =;:0LDwbWe} rqjY@kFTK~ )LM?,q%mx,] ! p QE8BNoi(njRzn:y%d~KNt > leZctD[ "#%n'8)+,.0 /r_D+x o#1,>nJF|=o$X9vH|Fx8fOz)W} KvBk0SzdO3KMD1}%ql!7 G #j ; R~d )8 I 7 (>3e "W$g&'*+- /1 "rpo-;5whyk~\vA[;[{%DCdXs$ZxNqB_,Fxs'G^Mz*:L\N`* ^ /  :y>I \"#%')1+R-..OH/|~#DW-]saR|Af$N)m;c(a F~0U/V$Kt;b!Imr A?6a^]9  \ P " BG;pf.0 Ddx^} J 3 4v \RG!"$i&r(*A,}-70 o:XC0[& qUx6[7wHo 2m(N4Z3\!Jt=aBhce?<9}a\Kk _  i-Gb WJ SQn ; a^J\]&g! !#\%)'(*,.**q|,2IW0%0*xa@nB~Iv 8m&R5[ 0WGo 5]8g^ 29"f^BVc0 o [  GIyv t'7V% B ' Yu i"@$%')+-W.U, f+Ur6 d\AY| [Kx2_@}NMDl&X 0`*[}Hf5R{4]gW '7%k^?FG  4  y zPdH}tGj@Js !2"\S/{VdY 7 ?$*qD!9#$&I(*+.p"89 2mJ1SKU"u3 kPe(Cc-KMl%^|._ )\wFa-Mz*^ax4$rgCD6c s +  Wd =!A"w#* {RQP6=d4 K - mli*.k !#~%l' )+ -E*7 ]7~zq#8Cj/4&s P-X-c.YKr+\ 0a(Xw@`)Es#p_s-'s%nDC(F^ 9 FW,R9~wf""$e  P7R${Fs o ?  !CF5j "S$_&'*T+]- IR 7gT<S.i.svizLi/O(sAc+f"G~0W3Z(Oy4_Ai5Ox${%p NA'|7? E / rK FCn "#% F6iu2S 1 x PL5EInjB\!P#/%&(@*-"J}3=vnaD p`\ |]q9T0|Cg -i$F0W.S#Fp ,V{7Y}Gpv&qWE&q$$^  O I+:9~-!#e$'V@ "me. ~ 7  JDJ Y"#%}'r)J+) E6k~Y[F&B20ߧ k1~0oY8lCs@t6cMy)W*TxEe*Ly +YxP n"u[H(n#tr< l @ T[ !>$&%'D8s"+./)sQ g 3 #  Hv hV~B!"$F&l() ,< (&MFeI__>0ߣw&_oOi0S 2w Ir=z<`Ns$Tw TqAV!Ao!Mi~{9`n\L'rh a:  ] E &8W?cS!"$%( [N2Pix 6  [fU{A]t3 !#2%>'(R+#dr_$n~4y #hzreqBX7 Vv>=^PoRtLm8N}6f?b =_ Z L.ub Uk X  wewz?# "s#%&)y|MSs6 [ % 4\ ]"H$%'{)F)f{<q\7>tOD=mW$j^ArJSH{7dHrJuEg*Kp/]| 5T{$WZR4{gKSd, q N  $B?-X ":$\&'*kn F~=!vJ  O A$67u"?!>#$&'*; SSAWkp'|YQDK2 ^z)FSo0h=r>r8eCe'Jq#Xt6QO?cK?Lu 6 ~ dMEGZne9Q!h#%'k(&+!"ak"N 1>VK` a + vxu ]U !#|%!'o)-$}/u`>&#g"[gTl}f`JZ$;b~,IOs +c:n7l ,[~ :_=jmEIC#f N58O S , `im `"$%'P)+%  u @  "AF1_ "3$P&'(NjW7Tot>,// K>}X.X#\Ey3] =b^8M!#/%n&!)F<{!vP }C~'v9MhDB)4g7TdB}5T9Z2S!AkJo(Jq{T~-:*jQ3{s|1 f <  x;7r "#y%d' )*,n* s%Vrc ] 1  6v:8s %"#%')$aGw-}49fK ;:݈uYGL)<e2T\>s)N.S&Kx5`<]9\ Sy.%mY4s!ha0  Z @  2yQ8[&!"$)&(()+m-, 7W^=Q v W ) ,kK4P,!"$%'(2RLU2q>( (rT)\*^#Q=l Mw OwFm/Ny ,Tw +Ms|;mzoZ8yePb O  xp_kq4u !r#V%&(z*,..=W; 04_,N < m rCX<mg4_8G& !#$'(P,MJ1a \2V*ޟP$kx:Og*CDaKiJh ;W"CoHb=j@ ki`:u!bFJZ f >  4-; "($&').+j-.@0(  2 I ;ot /"$%# JX=Nq5K}sަ`.%i}5Sa!E9Y ?b ?].K}6_x 6V'wqZ_]:|$dA?<r # g ^9@/RU G(i!K#$&[(x*+2.F/1Fw N V ; St| #@$[&sHmx,/_Z ,;Zt0La*OGm'^ -_(YzEi&Ik Di-j5MR?~!b>,!B y J ;]^ !"$%').+,./2Z _ T<N'% 9 2  ncT`k4p !B#%WZYS| 1$jBk3'og;Ag,EGcWp"TuLj 7S8Xv5UmuR>K@$c;$rm B  l I $  1LrbB!"$T&<()+f-/03% = Do.x m [ / neg' z"$3#^ 4 /++-UU'X^w-Q\G|:_CmEk 9c%Lo'Fe@gS78&eB%j Wg X  ylx J1 !#b% '(*,&.?0r104h))} rdA q ; ! :S2~g$|!"$e*FlJ'PkW'(G^(NLr,`7h5c+Ty;\/X|0Px_j4o#.~$g G$aONc m B  M8"C "M$&')c+=-.0H245-^rU I zdgaSsU !!$s~/vQ:XD&Ffk-y ]:5 eq)?EaYq$\}$U{Cf*ItDg;b|= l!se H$dG5Bk 3 z VKAGOtoHX!B# %&(S*-,-/n134.0  4. v +  ;e  ]"o" xYo^f#GNp}SgE8\(;Vx>z7[HlLqEg1U6_0Sv$rQSUfaI&`C){'=  B   O_\ M"#%t'S)+,.~023V4|2Lq {t d(  ^ w A @'9+ #gn%(Mr7W+@*W(H߻NYh:Daa{.g6f .\yGc%Dn?\]RPH#_@dk}H m = + +c4!#$~&(*+-1/@12c43Q4?F} N~ @ Y Xw`g*$< H"}VYyXB>z!S">R/9&}|[\ /BWTm ]y"[vKi2R/Zu(DqE@;r4?E"_B}UTQ B  gvf_w O !#@%4'(*N,d./1343*5Vi ,^ 0 e  0~3|(z_ ! VuCeW+Vj);St]|Jެa)dd?a,Vr~5w$/y[>yQA5U c )  Ix# + z"R$%'o)g+,/z02343b5%P k& { N 7 #GRF%hM`!g>"g )lG(f Eެf@=q4M Nj [w +b *YvEg)Gr!Hg2^* QpjW7s K.zu(I  | a >0$27\Z2C!%#$&('*,-/'133e435*" zl  y ]lQgl A r Xz5N$z6.V<uW  *;b:- gt'?=XKgOmDa.M}2Yv 0Ji  7A U   @Z L{C69#Y 5,XbP *ނAPu:r)R5]9]*O{5cD`-Tv6b(AG-hF]NBb q > ! 1pXBi!!"$+&()+<-%/023&43#43'2#m|   H R  'S 4 hfQ|39 [Iv){{rG\c){6R GbNoMk :[$Ak"Ch1Z~esfk/ eES= y7U ' u LQ4QKi!R#6%&(L*L,-/A1;33043Q4a3?4b[ W 8 j n MCATe~H_w?M$)7Y%BCsoG|[Gqy*;9Q@W7S%Ct )Vr.Nv=^n9go_A{L,ubv" n - `ej d"#%v'`)*,}.w013343K4-3 5!c9  rzz888wl~f^,EWw.$0q-[S 7gGv"LsAl3Y}:^3X{DaG^2@[R=|O)fJPh) x V + %Y o4cJh(Bl>[xE2X{+}$gFS1ufz) s :  4|0= "4$%')1+-.02333333330a: v  i o w~4$z1Y[Al8>hfH _*d0UHs&X}/\,U}Ck*Mq)Io:V~FO eYAP,gHQf0 ~ b 2 $ (:u=&g!0#$&H(+*+-I/%123z33k33O3333se - 2Pj5: HvUajEx->(ElߠY84Tj *h9r=r5d&Or2Q{ )Rm3^{b$MG8y F`931i (  ~ u`jhm67l "#g%<'(*h,K./133d33Q33/33245! b H>ZCk K(o/XQft) \+E\# 'N-DM TfYpXsMf8Q/`z4Nx;SSxK` .}.p@{W)jg m0 l F  S8*N!"i$&')k+-.t0M2>33R33@33 3324'H?B ] )e` h91T{ "a B8Xo KC<F0gq,`Kx0b6d3])Nv6\<_~ -Tt;b1ioc=~T#aNGr% [ H $!-0\ pMb!C#%&(4* ,-/12\3x3R3y3D3}30332$4- oj z N D .]33O\!3Igh&`v:;1JTVgXmPf=V :pGb0YqL5U 8`UBM#a;48t 4  w=`g :"#%n'%)*,r.013e3H3]3B3Z3<3U363F3c30bX  ] 4+J_jg y(8:,cKvCn&;Fc$&|1E8R5U/K};jLh%?g5Ntd<|:?6y K|$W)lko6 u N  )scUy9!"$8&()+1-/0c2$3Z3$3[33a33l3232Y3X 2 e eRf'v{oL "%=RhzBW'U}h)K9aDkBf 2W!Go&Im>f/NkN {%z)j C}T%\ OHu* e T 16(@Ey)z !p#C%&([*?,-/2123H33K32R32d323a2E4."V  ma@"T0l_':n$V<dbbSqV$&.:3E+C|8h Oj*GsDa %Dzm: ShdFxOYC(Cm D   iv }0 |"$%'h)*,t.Q0133;32=32B32Q32{3R2O4'  ` aw  "Rih3jb0>[`oogQ> bjfw'i{ #\xLa.Fz%Om =b~+]LN?xL S-rh}6 Q ( Q. X!#${&4()+u-"/0Y23232323232#3236-NS *]J " V6*W`M.z)o =2gUvzVVRu 1f=nB9Q\FF "#f% '(*\,-/R1223232323222220^ -a!y.!p]2ghv(W7UbM۵{Q>VZ YcNc@X*Fx #Sj$@k 5QxQ(\nb@wKQ5&:l =  #t/ E "2$%'v)+,.T01222222222232)3=243 "BNQKPW"9QHn  83_UvUYChn,-0B3J+C{8j"Mn,JnD` )Pj'.j&NQ3sH|G%h\ t% I +   !\7(g!'#$&:(*+-"/0C222222222222c2'323$i  aX_3{X;EUvjAt1<#qnpv+K7Z2Y/O}?g!Il'Dm>\~ywIo#:+gDz DxX:Hg/ u S J5DJpc27j "#a%0'(*L,./n12222222222}22b2223*3 [&|5';V_JX'N(jMjDtR"ZqY r}5u4m +_zHd&Et"Ii1Ywo6gr_;s={L+sx.h 3  .}81T "O$&'z)2+,.O0122222222222222~22/I ^ )>iZ(r*(%FPjs 2(Fl`UKEPfRjKf ;Y"Dl#Ln!Cd2Qr>R_<w5SN/l =r=x`Rm w @ *  )gF';z!:#$&L(!*+-%/0/2222|22t22j22_22P22622 2U2S PQ|3]U K.!Nc+Q8}_&f>޶ Kn Sy%SvLq<_ Cj!Ge8]&Egd1x+8$e;m=lI49^$ n R E4DMr j=Ax "#u%6'(*[, ./k1g22x22q22h22^22R22A22221`3$ Z)tdJ5sbV;(gDl[ރD7BN>P1H4iJg#>j6T{P,$xBi sU3k/iCzbq!b %  @~<2X!"^$&'|)E+,.B01m2y2e2w2]2v2T2t2J2t2>2w2.22221H3?* PV*o} sY`cIhF:laڀs#k/m0`'Vw>^?h:] )Nii{oN'>UJ*f.a5m LI[ i C    8aZ>W!:#$&h(*+-=/0*2]2c2R2`2J2\2E2Z2?2W272U2-2T22]212.! (6fJlb;nku?6cYo c}vbyhbSxu#0v"7v3k "Zt >Z9f8S|Ha}= 0:!Z0l.\=!|2U j H E8IOvyJU "#%H'(*\,(./e1:2Y2>2U262R2.2O2%2O22O22R22W21k211b9 wyRpKHO*h2e:i&CTG>MڨmaHX_Rj G^4J}3b} >V,Tn6`3We;O o&uS0g+]7tYo` # KOCj!!"{$&')Y+,.?0122G2(2F2 2D22B22A22D21I21V21z2q12$ }3uEv0) :*pR} 9)[Q|v"Tw"(=}(Jy!Gt>g)Ru 0Ux +Tu$Bc (g@GYH$_)V)_;=N b <   :mbMf!M#%&k(*+-:/02%2+22(22%22 2 2222121#21=212*.mrka>5RWvA p$#y35=3H+E}6e!Om.Nu"Kf7Ys%L67~U%T"X/soH ] G 99;Pp"vLQ 3"#%A'(*k,./E1222 22221 21 21212121 21H2.x_ tHB%F=j`,`&]l#thft Wg DX(@tLe!IblE3ܤ80R>CK7G'>z&]t;T.[u'Bl <7A0T2,r JyEv E`] v; p M < '(.GanCJ +"#%4'(*Z,-/$1111111111111111111111p12z-n2nWLv* b N - -9<k|Zc %"#}%H'(*C, ./&11111111111x11l11_11L1121112x02fZl@^[ sFd5[0?7+!2;}.62p&Zs?Z;d;X~ &Ih|}S[qc %1*Tf/tO[ E"#%3')*a,-/01j11d11]11U11L11A11311!111102D0*36y-b* %EG[ky"L z26ܕ Z@FA/6z#am=N&Xq*@j2Hw7y!&tFwEp3hF1?p8  Wjg2!"$4&')D+,.%0U1z1y1r1u1l1q1g1m1b1h1Z1d1S1`1K1`1?1e1)1}10>2()h$Wy %+AM\m 6$'Cu;e(Ss 9Y7[} 1PwAa > JslaG-Nnl J!M=pI#k&5 T 9  !]&% !o#2%&(**+-8/01[11T11L1|1F1{1=1z131z1&1|111110100 .X,l7DReo&f~ڳޏ`J@17'gtEY 4g|5NF[{[\_ S$U&TB#i_?  p N RG`lQ& e""$%')*s,../"1`1t1V1r1O1p1E1n1=1n131p1'1s11{10101A03-/xj/R.sJjFMחG߈;',v%\sC] j*7Z|"Jr5_Bi!CiAa 0Yq:^Ki=|8C6q9i5[ VE:] } O 6    +[}h@Cr !#R%'(p*,-@/0S1j1J1h1A1g1:1f111e1&1f11i11r10101`017W"0\j_0 S$rC[qEglRٟZ;)'i|Jg/L{ (Rq%Ch7W|="92)`92vMCk 6h;.2l)  p9[Xu!"L$ &'m)+,L./1o1F1h1?1e161b1/1a1'1a11d1 1k10101I02 ^|oe*Wc28SOwl,f$3 zd Z^>J-bt 9PNg5`tG1yW&p#3}W'VFv B$q|8 U +  Fycv ![#$&U( *+_-.|0L1[1O1W1I1R1B1N1<1K161I1/1D1'1A11>11(1l1,l0Q @roa"A<_U|qkݝngIj 2Y:b@e:] /Ou<[~!!Kn*z_;m&U!U`k|L ` [ ATPwYt z( c"#%B')*e,-/0s181l121j1+1i1"1i11i11o10y10101-0r2q"~- TsE87[KbtxOؔ߂߾0xj YZ7AVe-PDZ%yeIcs&n DxEs.]3kQ b^ ) A7*_!"$J&()X+,.0A1M1\1E1X1>1U171S101Q1&1Q11T11b101v02$&Tob|]?I *v3orz$ @)_C}[shPm܏޺s߷^a;O/by =T*Up">b|)Dev>do S)ZBq =uJOg, f = 1 " CW`14[ "#X%&(K*,-@/0g1C1d1?1_171[101Y1(1X11Y11Y11`10l10/K1C}LP<~f*:FX^yviD^Ayr߆ߘ0e|Gc+EqJc4_z'Ei 0O#n\: Z eb6o 9cMz[:PxJ YYKh!"a$%'I)+,T./'1J1f1>1f171d1-1c1!1e11j11t10101)02J]PJr nzRf~=Z!x7FI(C~[ڼc:ߎu_j;Q-]z4Qz Id,Jjj{j1] bL Nx:f,bB8S o C $ 3Y/q !]#$&P(*+S-.r0J1^1Q1Z1K1W1E1T1>1Q161N1,1O11V11u10G2'uX{35t[NL2GKQ\c 4"W5BG%Di%OߋnaY6< S\1cs+?n/Eo)^x{iS(D_O.c#L{;i:"|%R n V LGRc5\\ "#]%'(e*+-4/0d1f1_1d1Z1_1T1[1N1V1H1P1C1K1A1@1I111-+b1ZL> .SQ[sw4&T?oWfU׸4vk߽ߺNS!2hx 9P N_)Tk+Vv1uf%[SC{=k3\G.{v:l D Gs!"]$#&'y)*,;./11N11G11?1~1511(11110101h023|L=X^)\bA VAaYp+;>]PZ?&llMؙ܎;J߅ߒ(_q5J} !Oh5]y&:c}(>/\v{hV,IgP0a Mr6g4tqH { R ? 01.J`[#8 !u#&%&u( *+V-.p0r1c1~1\1z1U1w1L1v1B1y141~11101}02!e(]UL-+OH:bHd #B _$|3.U 9ާF2߅߂Ze/ApBV %Ld+SlH4n,aXDDj /ZJ'no+d 5   VcPd "1$%}'.)*{, ./01i11d1|1_1x1X1t1P1r1H1r1=1q131h1b1-Nj2y]'.^:^^k; T7tJa׎ަ88|߁߿M_9d/Mv<\}=\}4e{rU4PhR0d#Ks 7f,onz@ o ? 0 4?w*|!6#$w&=()+-.,0r1k11`11X11M11@11.111102X02)T2}A`FZ4bJ`2P+lBG'2'K(sLު޾Bfߌ߰>_5Wx#Dh ,Kn +Ko*7k6chGzIt/X}Jgp^ 8u. N"#%H'(*(,-Y/011{11r11k11b11X11G11(11024&8-B]E9 8+TFXk|v8]*z::ݬnުVFߚߔ"&jq6Av@RBX[q^11"11 1 0O' 9f,3TA[\yt.2KFhZs//ۖݮlޮJFߐߓ _j+:l~6Ct 9Ky 4Eo#M " zIn&|O,U0`*X!jwd  ._  %"#a%+'(x*+-$/0{11}11t11h11Z11I11.1102n0@3i8CPH MC\S|k**D@gMS,00sSR7iޞޕ $doߨ߶0?w?UG\H_@VZsU"o/t Hz=eGq B} o= b ?  (O _44W!"$7&')$+,b./A111111111111x11c111w2(7`Bs1'M?I ^ E  (9zC.!"f$&'k)*,,./1111111111r11Z11*1/20i3/75:BWY _AlTk1 J#e7DF DڀQBvsެ޸3Duߋ߼@Y Ee'Ib!B];67FJ=(m,F8yGo .T{<g>'3i + y GWK` !#.%&v(*+\-.w0111111111111111u102+^){mA;/fOrj} !6V*o5N f C  -a$mt "'$%g')*^,-/01111111111111111- L}YHAmir 'F,]FuR\aM!I@h2ޜ} WNߔߔRY MWBQ3Cl,bMc|olN8[kg6a .T{(L!_4Hh > xn6i  !;#$x&>()+,.011 21 212121 2172Z1w20=3P:C &"u7r'|`m 1(L<_XsjhV!gd#DSނޓ޽>_߁ߠ"@`~9^{5Sn B^6|Cs'w_'W<\FrPE_ u D (  0U"sNS r"$%]'(*2,-^/01 21 212121 2121A281L31%}&$~oM`0}:jpr " =U6jIW`b2R8ٺ.:&sjޫް-5hwߨ߹*:hw#6^r(Ng;h@;qnQ"u(9T}Cm@k7oJX| H v1m$ !;#$r&)()l+,.0122121212121!21+21/ 8e @]pAm4I)d<~L_opl-hEwe޲ޫ.1jrߩ߱!3`r/Tk "Ca-e "-%d A5Fm -Vw(V*mT y! O = =S,rCD d"$%Y'(*,-?/01921621921>21I21a21203RM:1TCv.!B7VNjbw0*O׍a 16lxާ޹(:ezߠ߸!6_s1Ri?Vv\`(nsGKQ,Q?kPcoyrHC20 `QޚޔQUߎߖ EN| 5Do3Vl2CVVmev֝7iMޤގSRߐߓ DM1=jz*UdfRm-om^&Lr4X/Y8v7 c : )6| !>#$w&')3+,d.0^1[2"2c22d2 2g21q21212#13j-P|eDi]'";8LNair{Yݛטt 5Hqބޮ-Cg}ߤ߼3Vq !F\ ,Fe~gEjy~s_=i$3{S9g>g'T63U   X <,#$2Np*UQ m"$%<'(z*,-E/0 2V2O2L2M2F2J2=2H232L22b213)8~YaEh}1#F5_EqYhy+^'f[A$R9ދ|޿::w|߭ߵ&.`k JW*;gq?Y!;@Es 0Pw JzY7P | Q  <B" !D#$y&')7+,g.0g1p2D2y2:2x2.2z2 22 221211 zChw1Qqv 1D)[?mReu6MHއފ4Dq߁ߩ߼6\q>Zx!=Xv 3Hxh> JW@w7b:]<pVCr & e W8=/LU-ea |"#%*'(e*$,-S/0&2Y22L22>22.222212Z1!48W'!c{  0D2XFmWl} ׸v#<\tޙ޲)Lf߄ߠ߿7Po7To4Pjq6=8* Bd]5l(HmDn4m Yb a 4  T> !7#$h& ()F+,w./z1j2}2x2w2r2t2k2p2b2q2T2~223R+Vn@eU &?-TAfQ|fuEשKݭ>%vcެަVZߏߘ:Hs-Ug4Fqi7r_0hs\,Z{2Vv(U*r[ 6 u dEO9WY/fa |"#%'(U*,-N/0.2r22d22W22F22/222212CW(Adz ,":;OM]cryݳ 8(qfެަTWߊߔ 9Bq|&M\)8>N]j\Q+`$.u!Y?a>`E&rr6 k I _2 !#$J&()C+,u./1a22y22n22^22G222 31?4+!,}w*,=@JY`es} 9H(ط~ݲOTވޑ2;izߥ߳&O_(9}Mx -Kq"AtC"s) M  qWWI[j5\S e"#%'(V*,-//022222222222~222-Uc>?Ko.3DCXSmg}u$SJݕ* `Iޔކ=9qr߫߭ RT'1^k|$NV8GQD<_C_3c I*Q b ( 'r@ !##$Q&()I+,./1n222222q22X22*25313YGLk`!):!M5^KnZq Bݽ&Veވޟ2Fh߁ߤ߻+Fd 9VrVhI,*|>e][NoQv7,:*O8aKs^o(Fd>|S"dݎMBނ~޷޳!(V]ߊߕ/GKX^kl| 6T~tٿۉ݊ݹ:.mhޠޟ >Er|ߨ߲FTx"EXxzP?`l[1I[FFs(C] 9b<}u0 ^ 3 v"t` l"$%D'(z*+-/02323232 32)32<32J1% 4<[0 &/G:QTbbox %:[y/5M2X{ݯC)qaޤޙBAvvߧߩBKy@Ju 1z|8nc M{ .Su &MjS;& S  v E= -/k uB6 !J#$r&')+,B.0I122132632A32X32314[U >N:6!='Z;dQr_q" .68Q!8g7ݭݫ/Fdޙް5Og߄ߜ߷6Pi4Qg2k~U+n"%i :m"@az .SO7B y B  4vo y"$%/'(_*+-(/0&2 3 333 333"32:323$*9TE~?0YK@'=>5ZM``tl'; Ts ۇ݄ݱ* ]Zސގ(/V_ߍߖ߽%0Uc-Sk(rY 2OD@# e/<3m/Wx.Mi:rVB m " aS/6%AH}OA !T#${&')!+,J.0R123E33I32O32_32322 *${ +IX6];uNds"7 Lax #;btܵ݃ݰ.%[Xގސ&2Xeߋߙ#1Sf,LT%nVLM.cDa~*Us2jXX  U 7 K{! "#%&'(P*,{-;/0=23]33_33f32|323424# Z^g0bTF]KwYt *?/L<h=#)ޒSݞݚݽ%8Vjދޙ޸ 6Qi߄ߙߵ/Ia|&_F0"OnyvjW.Pf X(Sx)Jg~5a/ld B  y`ODBMa2M> !J#$n&()7+,_./j12M3B3G3?3C383@3*3L323,=,X>-TD9iSki{q$1NX*t(#`.$ۉsݡ LD|wެު =Gqvߠߪ1Acs,[~Ft rPEc3Sp"Q1wt ; p P e1 " $%-'(Y*,-H/0L23}3)3333332323 %Ng4s[uiy" 4,H6[DnKP_H}+׋vܵrݝ%SHބzޱުCDqvߡߧ 3:fkhwi^~V3o0-vOz)Gf8\F1* _  qmR`\OS= !K#$i&()N+,y./123?331333323v25@"D^Atc H|?rmxq #+38DE[Lj\W1 'a݆ݟݪ.<\oޑޟ"3Pd߁ߕ߲'CXrZF -@E<)r+M>w>e5UqCsM7 Q c 5=vL!"$%E'(s*,-D/0B2?33b3}3\3y3U3s3T3Z33.%\S/:(Fd].B&T6e>{HK>0dێdݒC2thޣޘ..]]߉ߐ߼"GOzCW_\TBy.Kl%A_ 1dWF  4  k}vkeN !U#%s&1()_+,./123S33D33,33342n4Lbh2} PGKhLy" 0<'P3_DkOZhn7׶ژܡwݽݢ?Altޛޢ'8Xe߅ߕ߲!=Rl+IfzysW2 [wfZv$Em*g] m - } Y. +^ q=1!"F$%h'(* ,-4/0/2v3z33i33U332332 5$~X'qEfc#0&C0R@bMoWbjj5B؂+~ݠݤ"/ScޅޑޯNOY^bqq{TGڡܙhݷݙ2,Z[ފދ޳޽=Hlpߖߣ'JWwH8.9H=1{8ZF#Vy%B^y.L~ G: 8 { :  M/ !# %&/()Y+ -|.*013333333k3435L'#oNfr&b "50?:QHZWo_|mv|H\_؏:hݡݏݻIKuzޟި$0R^~߉߬߻/>ZlJ&Pc/gnPA`.Kd<hL@ j  dU8<.NX5hY!"f$%'(*%,-C/0>23333333z33w31 \L;W;5x $"05<<RG]Uo^}mqX^3 ܏Nݼ~ݱ*RB}oުޠ)'WW߃߃߯߯ -2Za|9jj~jc6e%$qP|+Dc}6Wv*_X V  W 7m:  "#%&3()Y+!-x.A01/3333 434U3^42[5pTGilOyI! 0:-D9UBcSo`|ky&Ifں܉qݦݞ'GWtހޞ޲ !5L_yߍߡ߷ &9P|r@ ]B9t;f2Ke7Z(k _  | @  lVQU^{ To^!"i$%')*G,-i/0j23333333 4c34=*1,X?D %0(>5MAZQeYwdr| YnN*۠آC^ݞ݅ݳ>v.Lm!5Tz#L1v s < v X"&>\/ %"#0%&P(*v+--.T01>33 434343:4p32 u#6EyB/ %2>!I,V;^GpR|`ix~ (܇Pݭ}ݮ ?;jfޓޓ޼9?bpߍߖ߲ 24$&BKE0Kl`8d:Qp9]C0 + b " ~f{u{+{ f!#o$&'H)*n,-/023+43143D43435-\swb $0#;1E=WJ]Zggxo:ZB܃hݛݒ?Egpޒޙ޹ 6@\n߉ߘ߲߿M&El;s'{\)Ov6RlDkA6 N f? ,UrD 8"#F%&f()+-.901#344 43 43434,i4uA, !($:2G=OL]Un_zmu 7mئDMݗuݱݡ(#OPx|ޡޣ(FMkwߗߢ߽rY7Wqvn]@p):#Z8Wt"9W{._M C  } 9 ~.> r!#}$-&'P)*w,-/023D43H43Y434\34#p7k.SJ  ) 6.?:JISW`birr'6)܀;ݫkݙ -XL~uާޡJKsrߛߝTY[* n)UC$V|#7Tq#Ck^ [ e . {c5/4A})h Z"#o%&()+-.2013943O43_434<35Q"mPMwqH4#& 11)@2KAXM^[lfyp~`N"lh݉ݐݭݹ #4J`sއޙެ'9ebގވ޳޲((NVxyߝߤ_b2E61Lxe GsAYp#C`As&u  } H {IB#1%IP:w k"#y%&()+-.5013R44n43434\3 5k6 _p ;97L#T9[?lNqWdmy,>P;v>ݚlݱݕC@dgދގޱ޷'0MYt{ߖߣ߻wu1ws={/)m7^| *DZr#Hr9~+ 4 | ? &kT( !#$,&'G)*j,./31|23+4d44s43435%c-wv_.; B//9+J<OI]Pf_si|t3o6df}݆ݡݬ"9G[pޅޕެ 1EXi{ߎߤ߈iR/YqyteH$|:E0l&Hd'@]{1c? 5 a  o^GGF^v\ }"#%'(%*+F-.\01E3O4=4c424b4)4X4Y40v&Am86P/H=XDdLm]vdq{-Doy;M8݊]ݦ݇ݱ2-RRywޞޡ2:Xb{߅ߥHQ'oo3[V.^0Le~)Fm)^O P  [= +>-j= !2#$>&'[)+x,E./Z124.444434r356S5% 2WP>RDbOiZrf|v!5> ׌Hw8ݓ\ݩ݉ݱ3(WO{uޟޟ 16XZ|~߯,30q{L%^v T+Pp,HZz .ZY ]  y E pj^qt+;!"$%,'(N*+p-.01y3;44B44%4435~(>m(d-CXRMe^glqs~2OLHI_b~݊ݨݮ6E\gހގަ޵3BXh߈4f6FD7 Y.yP4Pl.FfA|#i m 2 xV%C`@[ !S#$[&(v))+,K./[12 4[44J44744C42g sci&]T1hU]bpdww~*>UyJ/~N݃Cݗlݹݛ >._Vށ|ޫޢ33WYxz4ivP A4tJu-Jct.Rz:v( }  b s>\8!":$%J'(p*+-.013944;444535Q )rJ(F}-o\nX_s| !19DF52צYY/sS݌{ݫݨ7:Xa{ރޞު+:NicM0]o|kM-ESCx4Zu2Kj8h= / K nO,3OO !x#$&()$+,D./Q1244l44V4445(* MP'HMbnuix  /?VtIW1XPutݘݕݺݼ 'GLdkފޑޫ޳8J9Gt<laAr"?Wr4Ku(]L E  A<exY!"U$%h'(*+- /023`44f44O44@43 n6e9LpIjuy .: A [q2ؿLx>݉fݦݐݳ'"IDkgފގޫޫ3߈߮%/>na-u'%m6\ &CRq9c^ Y e 5 wGH)>6bn0g& "# %&()2+,N.0P1344X44/4#536ORc # vCgU~{    (+01=6H<9{ZhN(hI݁rݞݒݾݹ @C^dނކޣީ Gi!EJRB-n'B,]%Hb|8Kj"Lb g  b/ G,e!"]$%o')*!,->/0C2344444E45 ,-CUcZHcyv #/9JUn'܂bS>maݍ݄ݬݦ )2JQmuދޕޭ޴ߟmn+sV!MI'Y)D^p8T| =v% v  M a]DXO{G~@ !"#%&/()E+-`.0e1344v44X45%434S7ILfco  %);G"U%b$)IJn*~Rݚxݸݙݽ3$OGofޑތްޫPNTD9W}}ma/MjJ$Mn '6QjAo5z / 3 H/<[S n!#i$&s'%)*E,-d/0l23445X4653?6 l%t%]s & .(9.>;FBPKR_9|/$ODdi݄݆ݟݪݿ )@M`mހފޝީ޽4Eq L u!oL| 0Nh} !5St,Y< > d &thksZb F"#C%&T()r+-.01 3S444444Y5 .8)|Ghd %-5!F&M,Z,p(  gI \?vcݔ݅ݲݩ,&JKkjފމޥާ\ߎ!'+n^5t5*nCl0AXo<bQ L S  fJWvl2 ! #$%&'=)*],-x/023445u455244&o51mW|y, 0=E!P&Z.e0v*%,K[;w_ݑ}ݮݢ" BEab|ރޜޣ޸t Z 9ONF) q2H4n.Rp#8TlPxT  \  y J }7g  n"#n%&()+,. 0124454F54Q6#+(#w"/%/1<4B>KFSK]OjTx1 v0+IMfi݄ݍݠݧݽ#5BT`sޏޜ޽w`al[#RP1a8Ngx7Sz 7p a u 2 ]5#%>iy> !*#$/&'C)*[,-q/0r234444415/AZf1i }  ! .1 ;$G*N-Y5c6s76&f4E&_Iymݕ݉ݰݩ $'@D]a|ނޖ8L6OezxlU5S dQ$Km(@Tk;e&g  v  `Ho "#}%&()+,. 01244254e5&45(]t  $*(3):2C7M>X?eEpG}DB25#;M b@}cݙ݁ݰݢݼ!>5UQur޼ޚ3 UxPp*zJ{8Um4Jh$T& q ' ? eO,,+-Wn6x= !*#$(&'5)*K,-[/1X234%54I5S4<6'dVn%@   +%.465?D@ILOQ[Wb\jbt_8q)6JSdt~ݎݛݩݻ /:EVg~%rvZ[/{23tCj1F[n5VH 3 5 ;^9!"#%&( *+!-.10134454542 W&Gjem'   ,!5,70E4I?OAbEeLrJ}MG4 d+;Q1iS݃oݘ݊ݷݧ "?:VUh{O 6E@NINN[Sd\g]qdxhid9Bv*1DN`ky݇ݗݠݱݹ $8J$=,HkuylW2WsZ0Rw5CZm<_ c ` } IlhZlnw- "e#$_&(r)+,5./F12.44A54J54:3 J8A~dqK  # $,98*A)L0N9V?_>gGkNsNRUWK@e|4l%="R9iX݀uݗݒݲݩ.xޔ ^N*{W@Zo $4Qg!O e  | ( J5&d[!"M$%W'(g*+-.013r4l545M4j6VXiSz :2 #%(-*728<=?GHIPOVQaZb\o^uf{mmmq|\ܽ 3J9`Ruiݎ݇ݩݣݺ ?rxRd32:Fl%=Oc|/Or@  t ( [&w{x?5 "#$&()+,1./012 4%55S5467,6=KY=  &!%'0+2597B?FDOHUM]T`Xg]mewg}jolb,"Rt%,@CW\ry݌ݏݠݧݹ ފOa9':C: s3N9x9[v(<Qf~<g3 ~ 4 A eL   1:}0v!"a$%c'(v*+-.0134j54~54<4{auQ}W #%,-,424<8BBDFPFYLZScRnXt`vbcea]J^`ܞ !4K0^Nud݋}ݥݙݾݲ?2߽:B^W.Wf6e(EXs.Cf.b 8 K oFfF "#%&()"+,2./2124a545o46m!rXN;-% '(42&<'B1B4M;OATE[M`OhWk\ubvejrsy{kܯ) ;4SOhi݂݁ݙݙݮݰݾ1Agsyl]3\xb4]z3G]m4TW M f %hN7&&3Jia !"v$%x')*,-$/0*23445Q545-pJ=o}V- "$)$-*5177@:EBCIQGXOYV`Wg^laudwmlsqtt^*.Cxܧܿ' =8RPkg݀ݘݘݮݮP~JW~4W"@cu $3Hc~F{ Q f  c%0 e 9"#)%&,()<+,K. 0O1 34i54544G~u1+$576"@%A2G.O7R>X?^FbIhPpTuUza~``gjkjaS%2 |؃d܋ܧ&;-SFe[{xݓ݌ݧݦݼ]|eTzb:$"$45(7/92@7E@HENHTOSV\T_a`djhluosxy{~~v۹ܗܲ(%C?VUim݆݀ݖݝkOZ7#>?<' u;NDz9[y.@Ni/[* o  x . rC#T1 ^"#N%&V()k+,w.0|12Y4?5U5355/w{8 9(+5&82;3A7G<MBOGTJ[MaTbVj\mbtb{h~lpqtsxp_9b^g܁ܺܚܵ+%<;TOhl݂݀ݕ)ߤ>=L_%] ]>l!AXp+D]!T % x 1 Q%^gUqn 8\ !9#$2&'<)*T,-k/0u2z3355545E^(T2 ~,: <%1*;*>2@:F>EGLGPOUSW[]`\idjfokvmytnv|vxyp^<(ؑS۬g܀ܠܸ&<.PDeYyoݵ݅$e;MndgG5] kb'Po 8IXm#>o G ( H ],+o6 ~"#o%&u()+,./124 5546L'o|7|B\Q047+D3?9E:K@OGOMVM[S_YeZhahjqgup{r|uxybےxܢ܍ܳܪܽ&):?NQcqXzp4zNx'~W;Xq+AXw 3b ; D d7zylOf !D#$;&'F)*U,-e/0j235Q5q551 RXK8H76;G<BFKHIQQNSVV^[^adbl`qmknzn|qu{}z{z`$2fmWdܤ|ܯܑܦܹ.&C;TMݶݼHfO4k~r\',;Fk$;N_s6Y$_ ? c zF3  ;KM!"#%&()+,./124554;6*_:5[Q6H3Y6U@XB_EbLbPgQkYoYw]uf|ajmosuxzz{xviMnקSېSܨlܱ܇ܻܛܳ%93JgHޠ>M%q*8)"t/Q?s9Yt!:IZv!Hx X Y I+xr !R#$A&'J)*T,-\/1Q234546)SqL{:(a0:JF?QFMLTPSS[Y^Vd`acgikgrossrx|t}w1fqc܅{ܓ܎ܟܤܳܶ%)>ߑ#$9tSQX9g!=Oiy#7Wt<u  ^  y ,`K*&',Vq0s4!"$%'(*+-.'0134D55i52 4j$$VO&c=MH\@ZM`KdUgTh\l]r`rcxhzlimysxx{{||saeڜH<܈Y܏qܞ܂ܭܘܻܮ%fߋ h*R]k\L)Tr]-Vr/@Ub{:c4 v  n - ]9(FD "c#%U&'X)+^,".c/31P2.44546=(?_ ]Ji)XOOI_K[S_Vd[c`ecihkkonqspyw|wy~uj׸Cq.܉H܎aܛvܨ܋ܷܠܲ 0Vtp3j= z$t [5Ogz,ATq!O , y $ L \H397Ne@Z!"@$%8'(B*+M-.]01W345!5`6 ,go7#2pFAaSP^XW^aZbbafgfmkkrnovws}yx~g^MJ[Yfjy}܆܏ܝܢܭܰܺsݧ1M;*[ymN s&4wCi2EYc{,KrH ' ~ ? sL7\P "v#%c&(h)+p,(.u/41g2%44515_4GO$@)/G/ba;gV[TgVbbd^jcimkkskpxrwx{wz}}}g!Dڒظ.m5rE\܍nܚ܁ܨܕܵܤܵ)ޑ%e%^)=ZOob]jifkjklpqqstvzwv|{^ ߊHڱ+5;>BLP^clo|܀܊ܐܚܠܪܱܾ/NeoC6PPI4JaS!Gl%6FVp %Fy W G  ~0}bka:o !"s$%o'(x*+-.013|45"515o}4\X@h@w`m[x\y`ze|hhqkuutyw{}|q` ٫رI K"S6aInY{j܈xܒ܇ܤܞܱ$IH _i;lo Ix0F`o -B[| 4g  X _ #kK  9Y5x :"#%&()+,./123556%{.?ZVinmeuitoqryswwz|zx~6^׭2>>H+U@dKj]}m܇}ܗ܌ܭ<ݓ.@mvqd;h&(l>c &5EZf~>a' i b  Kyz~F; !#$%v'(*+-/02w34550 Wr4: &LQrW~nrn{nuuzr|v{zy{|I-dޚ>ڤ'(67CEPU_aip{}܆r HZ6,f%E^t 5E[tK~ ( p  r :d2(  VpS !T"#/%&%()'+,,./"133555&%/c8yCuQsrok}uyw}yy~w`(ټؚ)-1 ;G)P:^IjZxhܣa[wWTsbEIE+]#9KZo|  =Uy; x $  % f&'Za !0#$&~')*",-4/0;2U3'5!56( t;jJ_^sxmp|{tx{z{>פ '7"?0L>ULea(޾FQ)=;;"wBTLTlHx  Z  j j: 4hF "p#$Z&'W)*U,-U/0E234X6-jei; NifpzW גڰۅ۹ە۾ۢ۰۽^uߌ'!*pwSWQ4g,@Sgk~!5Sy4 o  n  P rp^qng Z!"0$%'(*+-.0124J5l4,?s/lxgtvc#-۷_v۩ۂ۬ێ۲ۚ۹ۣۿ۰۶ bXBLZLBI k Q&Lj%4@Tf6Z & n   .M0Syi +"# %j&(a)+_, .N/1,2446#VLp  + fuyukU-QڒSۮhۧu۫ۃ۰ێ۴ۙۻۥ۬rܩKh`#]s0qjL|(=Vht/I^C * z - ^!~ry)t v!"N$%='(:*+=-.:01/3e464/zY"of'\qu~wx{_ۈmۉxۍۂۑۈۘېۢ۟ۨۧ۳ݏ-C(Ec{yu^@f{(l 6]|-8HUfy!Bm 7 - C_B!2k{ A"#%|&(p)+l,&.d/'1=2!44?53!5"5h osyyiU F۳:G~U|aۃiۉuۋ}ۓۄۚی۠۷۔ݍS W6-a!BXk~.:Wq*\ 9 = l<K) !"v$%c'(`*+m-.w01|3%4}6&"zt(j|~pljR+Xױ,i%7{EyOہ_ۄgۊnۏ{ۘWvgB|{i05BKk4@L_gx1Oz J = UwS2!4N{2 O"#-%&() +,$./1w23g5X1b 'kkU@wMP|d\٢I3V`& _  K k"aO2-%9FjU!a"#<%&/())+,$./123 6)v( O x~{}vrqg_P7%H׵@KGGH(L.N4R?܃s$SXiTP"Lp W,Jk".>K\s'O}  X  c `$ /uQ !#$%'(*+-.01t34c2m=||xsLBي !!(',01f\`p*stAr#tGu -EXju"8Pm 8 r [  }3raCF5NXn!m"#H%&5(),+,"./1235U!QdQw{}{vurpieaO<ٯד$"%# ݿEV>-P}}nB%k*(k yV%,q+ !f#$M&'F)*I,-S/m0i23h5;!ea1pPHw~vysoljc]ZF+Ve٭oګڴ{QvvB*KIM*}?NE 2Pez-8E`t*V 6 2 ^#skosPJ!"$%'()+,./124,>Txm>y7}~ywpnnhd~eYUGE ֖ڜڨڭڳڸھ-,ܿC[Mc_-\c4d2FRcly3Rw M 1 Sn5"0D F !#$d&'^)*`,-c/0f2p3W3%B-|~}}y}zzt{ryo{kvkvd|^vZC TڣڳڪڶڭڹڬڹڲڹڴڶڬݦAQ3GbxwpW;aqa&Lg{ )0=N]r9g  J E y9$r _!"0$%'(*+,./125Y#b}88N<'}}zuqsqjhd_[YLH6"qA~ؾU٣qڽچڶڌڶڍڮڎڱڠCgދ--DzPw-|Hy 0FTjm~ ,Ed$ _ I _{Q4 "=`f %"#$t&'d)*e,-X/0.2 4B.PLy{zzrq{m|kxhxev`r^sZoUrPuHoFgO=Nւشٟhڣrښtڛ{ڕzڔڃڗMv^Jn|R/u++r;_y'6@JXj~$Gv  W T I9, v!"@$%''(*+ -./123KRO'(~|}uv}txpiwkufxbrbm^mUqRkMr@}./ݾ)jڀsr~n}rt}ڏV۬Cbc.}'.'g%@,a9Sdo{(=Wq, h [ k,d=0 7Jz# ="#%s&(e)+Z, .A/ 114i&;D~tv~v}j~nxjzcvbvZs[sRqRqGt?t;y(:Rا)o4ڋ>~HyJsQpPs܈5߯O=2yjK IB%Os!2@JTbt-V ! c  c X+K7 !"X$%<'(/*+,-.$01D3/p g2vUee |~|y{uxtsoslrhnenam]g_bThU_R`GdG[C\9NRW`؍j4o:d:]A\G\Cڏmq' [$7TMO/zBRF{,KYo$+<Le : t  i u@{KD*6+Q\6 W"#3%&$(n)#+a,,.J/?123!(9u ~}{w~suwsorlokkfkbeafYfU_VcJ]J]Ba=]2ghܣֲ'J+F1E/@/=+LJkn%bf&^Y4c #3DMXgm !Ch / k  p "i1 'cA !#t$%a'(V*+U-.i0i13 )p;c)}~vwr}l{lugv_r^sYi[kQiMdKgBd?c9e1h'jsI׏7O?< 4 0ڒږ3ݰYd@O^}mpP;]gZ9\l}'18K]sK - x QcWCJFdvU q"#I%&:()2+,0.}/)120qr= 1Tx{{u{nxntjpjldk\k\dXaV]O\NWKTGVAMAN7M5D6,[-?k(,!2"ۃޫDB XLv%rHs#6GU`lu 6Pu @  , 7G& >V !#$%'(*+-.0a13>t\ ~{vspzsxftimel]n\hVdReO`H\IWDV>V5U0X%W _wۗ֌ ٦sޝyJzsV'u&*m-Rj#16GVe~ -\ 6 2 \}eYV`s$p!y"#P%&;(),+, ./0$3*S>r9|ysxuyi|hpgq_l^jZfUcPbJ`JWCY;Y:O5S(V XV au7׃ ([۹h߇~J%(;'j>$V4GWfqz *?^ M 9 FY6 5W.p !2#$&'(*+-.011Qs?=z}}wxqvomnnehhc_c[[[XVUPQMJLFIA@C@:=5854.4*'1 ] Dٻ+ܴShQ FtLG=Ji(3>ES`qFp  C H g8ste{ 7B!"$^%&@()1+,.00D3\!Kzy!\Q|z{zwsslsjkfi`g^`V`RYPWJVEQ?N<K5H1H+A%BCKOkvڕaة٦٪٫٫٧:ڏݫ(4}%MTdLBR=L6I4E+G&> =>?@FPwצ}مًٹلٯمqݘ ?ol"\O/^}%4=FR[k{-P  M R uEv%LX!"%$r% 'S()A+--.0 11]k E 2yxxuxmwgpifef[cY]XVQXIQKHDHBC<?7:53/4,(**!$" fqٙىًٞٔنُقمٚ_ڶGpvM,Sm|mZ6 Th M~9Qfw /?Ux6 i  P  g O25QE !q#$P&'B)*C,{-V/002#|HP%tI)8||ws}svnsfobnZhZbTaO[HYGOCO=J7G4>/C!@$664448@Yم.sc٣hٔgٍdكfۯ/SGp A se Bn%4DJT^ov7[ ]  b Q.cb!"1$%'y(*j+,f./1- jr^k zv}symwiren\kZcRaSZHZFRBN:I:F0A,A(8%74/,.+-1; gPx؎HٓOمNzMnهٜ۞1-SwY"s!|'g%Fbu  +0BNjC |  _  }-`I*&&'Rf'\ "#$l&'e)*g,-x/Q01q|@^{$~wwyuuoseoibafX^WZPUNNGNDD>C8>38/2,-(+ $ ` qbYcTZLPG[ \܂S)6;/a4~Sz &:MWdgr~&?e 1 s  l (a1A$ q!"8$%'(*+,./,2g&'\> J'|z{uympmoeg_e[^TXPWHQGI@F<B3B-8-7 8*+*& % $.JmXu?c%X#K"Fٌ0\pU_{@5@v 7Yn%+6?N\s%O # m  @ t]B8+;Ef@} 0"#%&'v)*n,-_/0.O ]HoV~wwupqmihi`d]ZXVPTILIGAF7@89.:(.'-*$  K7NO O A 4Zڦ@G (WUaI@1N,_8L[fow /Jo B  u 5jD/OA !#G$%#'(*+,./1hCg 'jz}{yvxmugnbe_`[\TTMRMHFIA;?;7321)*+ %!   \)]ޞՑ׸ ٨{ަ3'?\'QHFfz &26>HYe~,X / w ) K `K<9?Nj< C"#%&'i)*P,-/f1i(u+;\*~}}yxmtkneh`eY\T[LXJKFL:E8@1;,6#3 -&"      -Y9PXR?Sx{M8Pxvc](F_7m .DZeqz#6Uv G & ~ AyP=`R !#]$%7'(!*+ -.0y/J6h"?~{x~vlxmpen]h]`R]NTIQBM=D;@1=*8'/!,$ G"Kc_!}}:i\6^t%59CJYct8b  = 6 asePURq~S q"#A%&,(q)*+P,?./v1z,fI s}{ulvmndm``\`SYPRHO@I<A:<.7/-&-$   wN)`݀^ׁNكܥJ<=6?';).!.$ Cy1ֈؘؒؐغKx#(@6$)Mwe ?c-9@GP[iy>f  F < j#xnX`Wz*Z u"#L%&6(x)6+X,:.//0O7 %tw~v}zwmthkgf\_YXRPNLJDE>:;530*-&$!  '|؁؅ز{عN3bmTRvi/x"w'b;Tds|/<To T C O Z9-K] !#$%'(v*+-b.0'#2D(l>$k}}zywunmmgbb^]XURNLHDEA9:83*/)'$"  [=\(C؇ؔ؇؎|؈"ڜ;\Y//CTMH+ j%7|Lq.7INUahv *Gv  Q H v3{fom<r!"#W%&?()/+,./d, dazSXxw~}vvrskih`^`\VVOLHJBB9:98)3&)!#  p.Q׋P؟N؋Lذmr1ޠC90B8C7@13+5"(!" yw:թ֣{B|AeMBi߈Y2Nonx\J8L(U*8<.0--'   w5*v>J9?5>+6%/)!  uTYGU ?/:t/ܢW߾Z<`n{k3M`5g7EVZggv{!A\ e f Q*RW!"$e%'?()+--0-tcoS\i~wnxijffZaUXMRFGCE9<51.*'&  {l.+)ؙfݕ4/J+" ?f T)Qm$+39LSlA z  ` v/^>$!=a N !e#$A&'*)*,,Q-/V'{ )C~_twmqksn`f_YXWNNII?B6>31-.) oU ժ 2Yٺb݇jE~R#al Fv (@P]elrw +Gj * i  k [9ag!"0$u%'U(*6+,'.-0<uoo'_a~vlfl`^[\PTHJEA?>531,)"$    vmT>U״ر؟6ڕYrm9r,0P;BM~` ;]~",/=@L]t-R  h  7iT0101Wh&Z "#$g&'W)|*e,2-/e M2Rz\tuiblV`XWJSBH?B59-4&+$#}xgzhY;)׬ׯLjۄ)ީ@+1vp4x#u Z1EYcjry}!3Or 5 p  q $c- Ax n!"5$%'~()s+,.)']G+N_``r]zi_d_TYRMKHD:>911.&(   vl\I0m֔הגlۓ ߮p"U\w`_6j/0sMn)16CDO\g7` , x . F|mBF0HCtHx %"#$&'w)*w,---SP azVQzfdZhNXLT@L:D3<,5"/!  ysbXO=$Iiկդֳk׵׈׀بd܈ߔ}7g S#;9p%CVms{ $0F] I - ?zM7YB !"G$%'()+,%/JZe6IoUig`T`NPIL<E;;/7(&)!   }ywumfmb`Y\Ib Vq ׂm}(٢@ahE*]yy^3DJ'Wx 1;ALOS]j{ 8f : 7 \!x\SNXbS N"#%&'p)*C,0.(@9PCONZiOpYTRUBP?D7>11+,#  }oi~`O|Gx:v%| #1\:x~ת٫;9p(#1r=UP:Wg{ (/<Pi$ Z ; Re.[{k !,#h$&='(*+,-^U"WxwJwzHhYVNVBGA>78,.(&"  ztjvdsXnMeCd8])a[LԖtc|׀ڢ ޻ 8ZO+Uf9h$2CRX^ajsz&It  S F x1grn;i !"#W%&E(r)L+#,.4uO*;fL[\QJOB@?<22.*"# y}rthoaeYaNWCW8L,O[O-ןKx ߎK6QTR=#V o_(Ke|!'/:H\v 3 e  N ctF'!=o" !9#$&r'(_*+-(l'Fo:FEL|WI`KEKE8:8/**%! {r~iz^pUnIdCa2\(V\]qo(QeLjjLp-~Kv2BS^fjmy|3Q # b S =yzW}!"#x%&d()c+K,-Gsj9lk7aHH@I1?./$+" yrzgw]gYeJ^GP<L1I'@A 7%Sl= أ8@7fihc7g&&j 7[q#+/4BRb; k X  f'|V1(SwB !<#$ &'(*+.!^=}1Ox?IQE8?56,0"$  yymxdk]cUZKTAK7E.@ :75Cd$Ԗ՜Q_tݙ.(AY;&Z8IWgjps{#=Y ' h  ^ L"a>!"#~%&^()D+,) x(<5$>@iT4V;?5<'5 % xq~ev\kVcIa=T6N,J!C@9:>PGԻ&Su uOK`U:|@9|Ij')15=DO_rI x " g  t:k@6#6<rh "Q#$&'(*+f-"o_u|5~k*Yg.JD70>$*("#tvmlbd]XPVFJ@A5=,.#,"  ^58׸E^T~)%/h4F>n$=P^iot{~ 2Jl - i  o a';q b!"*$~% 'S(*+l-#x`%Cg99I3/3*!% wzkrcfZaOYIN:J3<-5#2* 0zyPU_kۙ>޳I2"ilINE&Pq -26>CHXbyL } * k  {AvK?$-"AKw ("i#$9&')*,* <C6!=-_K(G3.'+   {wxhqbdW]KYCK8F.>$6.(#'tT^՚pծAAr7ߍ1| B %T?M(yLR N+DVeltw (;Wz 6 t % ~ %q4Zz !"T$%5'Q(7*+--}BFiI["93.+ {vtklb`VZRKHH<>26)0"   #Do z]c_3\_3Z} -:=CJPU^l,T . y ! I]J89>Ol4 +"#$f&'])*,$\C1Z)(:!$twloddY\OUFK;@3<&2* QK9 n{+ِKܻec5yDOociG6\dY9Pfoz} "-H\ = . 2~>"%n( !"f$%G'v(6*c+*xL#!1IB4$!!{m~fl^eT^JQBJ4D+8!.)  ckT%A#vAݜO?8 uIm%tBf+;EHKQT\gu6b 6 3 UvWUEW[Z 5"#$&')o*,zZj#{`6J+&y{rlig`XWQHNC::4-,&! j$L~ޗ# f@fqO$n&%c-Mfu )7Ld P 5 EW, EU !#m$%>'(*,%*>ou% $G!+r~nqeiXaNWFL;C/;'-* p" n^6׍eۈޖBq2d>Sw$w$Il~ #(4BTm 3 e B bx@2 -7 !U#~$,&G'")*+hM*}|&%$~wzjqaeW[MQBD9?(5#) |p[Y?ٛt݂wB|BImZ^<*FS>m3HSVa_hlp{-Qy  T P |=|O"!"#j%&^(P)+u{7?S-{vmij]`RUMF@<65)+  }lKbӴ ١)ݽ:(D|f(XM'Jk$'-8A\n / f K czH/  /B~+ !L#$ &n'(*'i%v   xpqhgZ^LWEG;@/3"/ykXB#kԮUٽڢݰi[`lsF5SWDt6D\Z_eglu~1Nx  V N >y[#!"#%&y(K)6+8*.9azqojaaZSOKE?:11(& vgYxHw6d4#ӧNڤzބm"Qi#$&'(*")9 DqV|vwmk`^WTLKA?53-)"  |m~`pWiDj+tԶ6ۯ6<CqdCZ f Jw(BRYeggqpw0N|  ^ O Ai /!"#%&h()( Xf ~yrmgc\XRJF@=41,(}sf~WvLp4o#n3WFׂz ߽T}!0}Wj'n-Vr$+046<>IRk 3 h  [  f2h7/18rj "?#$&'(*/B}F syjh_`QYFHA;34$, pcvZnKe@Y3VR EԼ }ܤߜs<\8l)X"DHP`r? v  l  xA}KE)5+OT 6"h#%(&' )(: ORw|kvbeSaLKAH19++({oc{VpLe:]-UO PRc*-sپ*RkuX@'f .K\m{x| /Ej . q  q #n1c !"`$z%S' (r**_5m-sthi_]UPHD@81-*  wugo^`QXEL6C+8 0&1Pڮ rWZyfe=$t:>(Wy'28==@HKTbu$O " r  E cR@=FWrB 6"#$w&')c#Xe!_<Y4{7suih\`PRHE;:.0## o}hn[gNZDQ7D*?7 ,)&9x\ fybz k"Q>s8Tgs} '8Tz 7 y ( 0D" 1: !"$%`'x(j( _eC;z}kle^TXNFA=30+#  nwdmYaI[GWLZN>n "+:CAEFNQYh9_ . z 7 S%`fQkgt!C"#$&')cK_D(Yrplj\XSRAG=5..# ~~tpii[WUOBF941+#  5ٶH; h$(.EbTF^s '.D\ E 1 C\6 3Xd ! #$%9'/)E#P3;'JOh"}vvlfb\UKJC;71)&qyij\dLXCJ6B#:*"  I`5H!ݏW6mr{zgqbPz2;DLOOSU]cs!Bl 8 C `8t~j/;!e"$%&'5(D'06`n,w~lsbeTWHR9?56"' |pzdeZaGU?G2;'1) ] .ذ5w.kjO lugh[\LTBD47+( zpsdkV^HS;I/=!3#f:.׳تx޺߆OnWVoZV)B=bv $%***028E]t / e  N  l]H"&('Yd%M !#$c&v''. GGYc|lq_gSWII?=/2#' {wnhc[UPJD?51*&N*j(f߸RF l&S5i.EYbkrpqxu}.R # e  ] S.'B: ]!"$%&(3`lr*|5y{v|hg`^QQBD<1.+wxfo^XTU?H5:+.$ vYhF&^۲!0I?"I^*Vx .49<9?BCO\lD v  h  A_I@AFZu@ ?"#%:&W(!J@@XJ6pxpog]]SMFB;2.'"rwfjV]OL?D28%, }k,JA!i~@0Z4D > oG}$BZou|&?a 8 {  m 7lLOfd !#<$%'& {ikZtX{lonbjSWLK:A1/(#}uokdZTPKB<6/+#r~lj۰ދa_ksfTy\XNW>E1:$, |rqdeXWIM:?00!' q]Pw97"(gRdT:z;2u>Zu#2H^ L > OmR$ %,cw] "!#$%'B6%+e}U U|SfaWER=?00%$ ||nkccTRGG<:-- tavVk?v`|j,^ 7?O?2=]Aq .FW_jjnlnrs/R{  `  ` ]1*^4 !"Z$%' %W2 6"LmVZgHHM=33*# |unjb\WNHE880'!w~gqZgHd|w:<zHt+uEk.>?CHKHKRag}!T 8 ) djsX|!"#|%&.&( k<?Xu;YK5[ShEeGK=C03%% }qphcWWNJ?=41'||km_dL]`0pzg߈׀ZQ+Yh:Pp% Z  Q f)nC=!4)QU# M"_#4%%2( YfGBpwB[OH;@00"& ~pqjcZWNKD;51(# xrpbdWZL\F<3# H~(Q[cVD#N g P:Pbisvwx|z,Cf 4 y  ~ 8U*>j/{ !)#$%' M# 'rBYyQDXD;=3)%  zwqgg[URK@>6/*# x}io_aUTC{>}e S_:Py+:HOUVTXZalz9f M F @#(>9 b!"$%&G& Q'Vd1O=)RIr`9YE<59$* {vtkc_YUKCC84+)!yny[nT\lw bDYuQ+P X%Rm$+12566>HUk= t $ s  T ptXpdMk!"#%N&}(J cKB~9en:OL94:$) xtnh[[ULEB<3/+  wmYyKkH0ֆ;ܧߝf_axZLo{*n&E_oz !/B[ N @ \^@/!$-@W/ 6"}# %%&S(:  n5VnG?Q;51.!  vxkh]^TPDJ8;,/! {k^Lw;T8|5m3A4Bp>I?s7MU[ddeklt~ 0X ( o  q 1tN  0u !N#$$&f'O& G&pR7A5#JGhZ2S9<,4' u~incaQ[EJ>>-6"& paR6:հUPo; {iJs'4=G@GHMT\t1d K D D7KK p!#$%&(({Bo6af0R=717) zzqt_hVZKN=E17', vcT:u@jݯrH~r~eLN=~"Mm"$)19Cb|> x  n  H|ohjt L-!"#z%&(9E&HS{/Rn:AG31/#!zspghY[ONAE6:(-$ yeS7[: ?)j[[^"S|Q%G^qw 6Qz R : bVM.2>?pQ -"#$&'%Ynr4N8*<=lL-M:--,! vsfk\[UQDF8<,-$# yjU8CuQمݟ>^ 4rJ"X!;H][bhghpv&S - q n 4sX!28 * !x#$_&-'(X1Cxh.a`.J>3)0  uvpi]eVQJG>A-3") jY7 jj]:m$Qv_:\ l/]+3 x  m Puwu(YY!"$l%&}(i%>wO!g*06EeK.M44+." zrwap][RUDJ8?+6!)  s`A1Iև:ۆbޝY(R02cNa2/V^T7Q`lxz}';Z V C j!h\;A3OQp!A"#$&')t?j_4[g'N95*5%w{lq^iXYFT9F4:$1$xgG<ղ81s R,22c,:OSY^fedq|8^ . t  9_7 >ZQ !#$s&X')Om/-Sl1EB5-6!# ~~qxal[\RW@J;>,9)  oP PqVմaڹۘޔq"=n$n X?j )3::9CIQ[k?p  H [ ]& #H^ !#$%V')$D)}*C7HiH9N733+"#yymoaeWZLLAH18,+' [0rSL0t/sHMXM;s@/qHi~!!&08Ma!N t 7 ]5Sp !"^$r%K':( )rlp<]HY\7c].RB10; & }~rrhe]`NSGD=>,7#+!  a#HNaըڽiF;\=C> nG| B[kx )=`% _ K  t*wjMTFcg!4!c"#!%&'>*8H(4*]k6FN72;(#" yviqadR]JQAB6?'1&c %X^G܌Nߔ:y2[ x;Qy3@R[\ccgnv9_ 1 y ! ;dE$  -Csy ("}#$U&'})i%7;|/ ?8KmR5V<;.8$'  }mvjm^bNXFO:E-;#0& j$iՋr&1Q}CFY)Pv)28@=@HNXh8k  E T \% '?#T !#$%'()[Ftc;ii1XB?2?&1$u~lqcjU^KU@K5@-90 y-${QjA۞VޱR&h=GoamJ7fq'h'Kdv&*6G]z : z  p ! V 7j q!">$y%-'$(*=-o16Uw?LR?6A.1)&vyinbfU]HQCF6?-5, =CJc3J> p!'e5F?x&=T^fpuv| '@] O K b/}TO:LFm0`!"#R%&,()6' 26VD5FKz[>^F>B?+5*% }vrjm^_XWLM>D:6,1(  WL8zy֍Mku\Fm1pkLy1>GNQVZbhq7a & l $ 1V@ +3v  7"`#%!&((*4}V`Oy>or>]QH=H17/+ % xptheb[UVLJ>C77.-!" sM`(\!WoqI2YzU1<= Np'+378AKRg6g D R T&E` !#$%'(* D{ Jp<`MOaFEJ>480(%% zwrqdf]\QUGH?A73)*$HWղOzގ F 0DMI9P kZ(Ebu~  .6Ca~ = v $ x  ^!y /% c!"#$%&()2( aO@R8.WSzkEfQMFL9A02)+ ~zurmcg^YQTGFB>65)+" :=afsMܝߥ?~W!A4k"42.'& |{rrgj[aTTJPAB8;-1#( |`Ҷԍנ6@9gtohD#v28~Ij !'16:=GOZm9k R Q Y7 !b !M#$)&d' )f*( ;be>^G6c_xQuZ[RWFN:D45.3&x{oshiYeRVIP>G5>*6 ,&! oӳBz<٬crk5v$1D70JnV)Lf}  -/@QjH 0  , m, $HD v!#5$%&()+FR9^WWRRsjcRfISDJ;>46&.$   wnvfnYfQXHV:J4C(;6-(Ӥ:eu `t^F/i-EXktv.Ec' a  U };pb^_mO;!"#~%&q()+R"A0$Wwejtg[eXSNOCB>;13*(  x~pvdlZfR\EW8Q0E(D= 8,1<Ӝձqّܬ &KR,Yq?o(>KW^gdop !<g B ) WOA*49nT 7"#%&')*})B Yfs@mW=whd{mk`cW\OLGF=<63**# ~vlybqYiQ_B`6T-N N KI`ӥSS#~?ޞA_?K}jxVL~'CGk-7@DMMRcm@w  c b (hL&91 !x#$V&o'\)$*S,[Ey``evkgj_^TTMKEC>721*)  xm~buWnMhAd5\']^eӲԿ ֞ز.-p-";|Oa`#Fdw $*+5?C\p$V 9 ; wA/_M !#h$%<'()<,#"gy6=b|sornj_dWYMSHG<?84+/!$ }si^|WqHr9l.kmvyhxBtEڦiv^HI7:p*DYmr~ &<Rs9 m  d  Insp,\k!"7$}%'V( *S+K*y >CB{iBtku{nw`pXbTXHR@G;?-:'.%  }sf_~O~Dv6s$| 2X]@HajUd b It 8HW\eimu -Nr H 9 \^N56,EL~ m!S"#%&')*,kG2 dihyq~dqceWaQTHO8I69,9"+"}ohXJA~.*7gզ֢gڐݣaRUr]a5 n=9})V}&5ABJQSfn0] & h  { 1X68ce "#$f&'b){*,#hU7CH pxstljeaY]QQJL>C:8,3&*! ~riUN5VՁJ^(܌Bߠ? E6"(Bu[9[}*-/;BQc|;n E X _% ,F-e !&#$%'(*+*+ :^PjV{|}~qtnoef^[TSOIDD;971,&(! pfWD%[Q)f֜&:1W|^I3m:Xs $5D^|L  t 3 ^4V{ !"o$%Y'p(^*(+I-9z1R/w!r~}{uulldc\\UMNKC??852+'$~maQ,5^ֵ-؃H۳ipM)s|H)Z q Fw5K[hlw|&?[# b M  s0}hRRRfu:6!"$_%&6()*H-\$RH| 3JT3zzvtmpde_\VXKODH:>64,0$(  |qY>N(E0k֍Mjg86``kOF3M&U{&8GPU\cir &@j 7 ~ 0 E mR.%  DT7 X"#*%s&(S)+Q,E+% x\BP^{t{gvai]cT^JSGH=C6<*3%+%  {pM <^\֊ւz׾mے ߥ O. Qni4\)5:AGOVey&Nz  [ l !x>& PpZ "P#$#&'(*+-cI;~4ywvqtcl^aW\JUGK<G4<04(*!(   {aXo{֥։)*,B. &[  "6e |Py}rsplhbb]UYQNIFG;:>7/.-&$ /qӓՏHM\܂ seOBDB`t&+5:HVe 1b  M L P)X} !C#$&&f')I*,D-,)SBIm+~|txloih^a\WQRNHFD=;:312')$  Vӣ՘.(=kړް(}EuiKmq^ :Xjr ,7M]? } ( % d"95 s!"<$%'()+,/( A)Mwxoqljcb`ZUVQKIFEA79703)'&# QOԶեR)T'F׷ ~*ܮMO'q.F\RS5|@K:l!6I[emvy -C`! a  W  s7iWUXd{C:!"$w%&c()`+,.M'tt hv j,}|sxmokh_eZ[SUMNFG>A7>22*0 (#  GմxErC^׍׺F]SwM|&sFu/=HSXals !@k < . T ~O9#39gR D"#%&')*,-y-8*^S{@zs{oufq^f^cO[QQEO>J5C39,5#/+%  Mwռ֙[ז\ׂzhاR~߉oT~ZOF'Kn (07CEVfv Ex  `  e kC$AB !y#$X&'O)z*a,0-/KID)AS }w~mviobj\dU]LXFO@M9F0B':%3 .*$տֶo׵pסv'?\ ހ \D_{rD!e%~`)Ngv$4>So&X 5 B wD+lO !#$%c'(M*+-./(}<~y}vznsen_f[_TZLUER>I8F0A*7"700&'.)1''אב׌}ۦ߽lDCX?:2W3g -F]hu} 1Hk8 v ^  Agre,Sn!"?$%&'e(*E+"-*.z._p x-;E~~txougmde[fR\RVBW>L:I1A+=";5542;G"սץרפ׉z6ݤPHGyPo,y Di #9DV^bpt&Go Q 9 a\M17*EK~ n!\"#2%&()*,-+0b-m`f!|t}numnbm[gSbM\HVBS7O4G,FA> C@HZVֵؼ ؿFت6E8NpFDPJk*2?CMRco*S ( m  x 2Y/5`i $"#$k&'Z)*W,-/)APup{kwar]mXeSbIaBY=T1T+R!IO QVkxְ2(U٥^݁[$encNpy(l)Oi}##06AMe7i  I W Y&&F-n !.#$ &'(*+-.8/H.HIAU|uvo|gw_s[lTiLeEd=`4[0X$[[d}MAנ6O>,;c߅|E)J@H)x@LGw+G`jx&3G^F % x / [+K) !"m$%V'(Q*+a-8.0  -}n(5tt}j}dv]rWqLlIeDd4a5\"cmYז E!k([$L%~ܧN D#rS$8HW_ioz *>` V V k7`TJVVyF4!"#{%&f()U+,6.0 +~.a}wm|f|br_oQqKhGi8h1hp9xPA}@o=`7؞؀ۇ6ެJ8(sqOOG0W}$6AEOXhs"@i - w , <aN#$;G. X"#1%y&"(`) +G,/./ 0rr[v/] {q~nxex`qXqNlHn=p.uj^]ؓ_؉_}V؊)ٜ;I&?lokc5_"b4Xr!,08EUkFr Q  g j5=eG "Q#$-&')*+-.B1#$C}tqyk~_y^sTtHu={!\U*\؀ئ؄؛ؓ|،3ڨPmi5~+<+$t1U;p 0Nbt ,9LiK 1 5 n4 &ZL !#q$%U'(E*+>-.v0a,F >sKGJ%l! ~yxii{a}VzMy: X@6cئظاخآئ؛ؠ9dwe ouBv$vL{ '>QZhrv-Hm' _  ^  wBpmVfic G!"$%&()+,./0 #6c#|xli}`JNSa(7!"$c%&N()B+,7./Q1. @1y9* (   zL`u3w;k9`9[:مSXyzI#8^X[@0ar&k/Tp)3>HRao*S 0 w  x >d3'Nf:s 0"#%&')*,-/0y2 llI/A($!   wlES׀؍HٕOنQUvPـpܒ O_+DBz1Jfz%2:Oa|3b J R V-![+ !X#$=&'2)*3,->/H02( {Ie"}J 4   xRU@ׄثcٴl٦nٟu٘pّ r!ޚ?2.}k/pmR(DXbsx *=Zx ?   w + [(U. !"{$%f'(_*+_-.Z01i0Y X6%=?4(&0&!   wJ%1גلهّپِٺٰٔٻٷܱ.A**J}zS3@B,X(4IRZhs  3X Z K  q.zhPQNfw =T!"&$~%'f(*U+->./00?3B(2po[ 1S5,0!2/%#"    DA_הٙ٥٧٪٬ٹqڜDfg>|/:SA?Oz_9]|%/9FS`s<c 3 | ( F kN1#<\J `"#=%&'()+,./03*cP@HR"V+%:1#3((&&$  EחٲA:Pma!{ dK2o;Xt #)@Mb~Av N  f o7Ln] "j#$M&'<)*2,-"/02~1gVK9-h$.>MH C6/16).*-'+##$    "O#֨$.kݐ~)XX3e v I~:Obr{.E^!Q - @ kB,{W !#$%'(*+-.0w13 , ot:_&9D30=/3-0).**)$$%%   )XV֫9/-*.ڧqߘ4lE[}fQ#3J#Xy*@OZin{$>e) f  ]  @ zkhh{$f s!"E$%/'(**+.-.30c13F, M8 -^=-I=46>-904+2*/&+"*"% $&         0dx5ڳָ JF!A&?&;(9vڙݧ,5q 8:A)Rl d3Xw+6ELWk{!?o ; 7 O~a;5(23Zo'c!"#p%&g()j+,k./r1{222,p"OJ!RV'N>?5H.A2<-='9)2$5$.!-!''% !      .ےֿ7[AWAYBTDTFQf?ۘ6TMUV?9u6Ti #-:HWpF  _  t $|I1 -ey >"#%x&(j)+_,.G/311o4,# fj|#;j-DIB7J5A8>1>27.9*3+1%-$0"(!($""  ,QXm[m^l_lamcqr6VmRKx}[ cmO.Lai}+=Om#X ? D J P* !S#$9&'/)*-,-!/013->*\A&(0/iG5SI=ED>?=?:9<9476142+00)/%))'$( #!#!   (pwڅ|ڂ|چ~ڈڀڈڊڃ[ހX%Qfsn_@"y4A*[ )!"$%&()+,./1y24$'. Hk(Bs;JOP@NFICI@E@E:B==9?7=7858/713,3,-.-(-(*")$$!"# `;^ڷڤڽڬںڭڸڰھڵںMۅ ޡ4-DR=8t 4Xo$7ANbz%J & p  z 8f="   ,UzD W"#8%&*()'+,$./!1~2M4/ Fmc-81oQ:ZPHJNGIHGBGDDAB>>A>;=;;<68676423/2.0./*-**#/ (&&'$!$"Ez`ڲڸ&ܠ(?,1]iL] bJ} *F^l{.?Zu'V  H L S5,u> !#$o&'k)*o,-|/02R3N4/7V*rd*^i8ZRQIUHOFREIGI@JED@I=B=A>><;<8999655507/2/3+.,1$2#- .",--2.w!qھ2ݲV`6@HD}ֵ  ۀ7\U!z v4aR-Sq'8DP_m*Kw O C k*wdQPRf}S`!"8$%)'((*+.-.&01341 R):G<mb?gSVRZI^LQOXEVJQDWGOGQ?QCLAO>I<M:L7J9B:H/L0E/E,F*G&H%HMPUd֜'9.,. /62ZflnUfBv2)c.Nk}#0:Naw&R * u  } @lB3/;hb!m"#M%&<()9+,/./133I57K98v0^<e[_KfO_Q\JcJ[L]HYJYHUH[BSFV?WCP@U?OAR<R<P7R6P5N1R,S*X"[ ]j{HQ׉ HWQP$Q-R2S;WW_߃ cG`tc/H ]>p .K]m)?Uq .a  I Y b8Nb ""#%&')*,-/0235*pZV<HOVcbSeV]W^V]V]RZT]M\O]KXMYHYMYHUHVETGV?ZASBX;S=U8Y3[1\.`&guiq Xr$h0i?mElMpUv^ܗ(p<@N0%f}5Lp '@Q_mz,OpB  r 4 c8 -d !4#$&')*,- /01342 %rcG;[;toIhbX_aWbZ[Y]WX]VWZZUZUXSXP[OWPZMXMVKYIWFXEWFZA\@Z>`3e1e-m{6mSM g+ۃ;ۂIۀTۀYۄdۉlۍqەޚAC N]3K PIk-:IZcw (Jy _ K  {1 {]la:i !"o$%d'(d*+n-.~01345X ZK 7_KafbYg`a\`]a[]_`^ZbZX]\Z\X\U_RZU]N_SYQ[M_L^IaFaJaBa>g8m1s& M ,rJۚV۔bۖkۘv۝}۟ۅۨۏ۸Lܹ0H:Kpf*~#{)h%J_z&3DTf~'W 4 y # GwUA+((=Qz({5!" $y%&s()q+-q.0`1235,2_XRZt&D?Q|bUo^`dd]g]d\b_b\bYeXeYcWeXaYbWdT`UbSaSeOeNeOdIgIgHjCo=s6z,w`ۦlۤ|ۨۄ۫ۍ۲ۙ۵ۡۼ۪LݾaoGJ]ugcB(BM9l#CXhy )?Yp /k  M b k>".e M"#/%&)()1+,<./>1c2$44388sX?U^DozEs_d[pWmZiYlYj[jYh[mZi[fZjWhViXfXlRkWfUkTjUlMmRlNrFsGvB}7  |ہ۹ی۹ۛۿۤۿ۩۰ۼKmm5)""Lt"k Hm3EUbp1Ps? # { 3 j9>0 !N#$9&'-)*.,-%/013X4I6#\=9s@\Kiih\s_kbkYr]kaj_p]k`j_i^n`j^m^m`n[m^k^mZp\nZl\rUtTuQzLB/ܢۭۡ۶ۡx}3tVK?Fi 2=L[j,U T V  y?ysmy>7 ! #w$%e'(h*+o-.j01Z345/xx+aQH86PJfUvkajlanjdkihighiklhjkkfmgjljfnhlijeqeodmfqdsbrbtcs`yXTF w}~  l}ߌ tStrJ[sP"Bby%6FYt /Z ( v ) Cva;<(=:i{B{4!"$%&()+,./12445qn|7pEtPwjldvcrgoereqgqinjrfsmnipksjnorjqoolrnqoqnntksnsnslwh}dZ$ Qx  &!P#ݏ+p#EKVF0 u.C*`8Tfu(9Qr6l  O e xC, $:y6 n"#T%&N()U+,^./d1|2b44c6&AY;B_WorpcwkqgxgopnlsltmtlqntoqpworrwputuqvrxuxrwutuzvwxvyyzrmD!= o ('11<;BMު9< _ w9ea6e+vM\܅k܎zܗ܆ܡܘܬܠܵ`~ o)vY$MO%Rs2GPds,In6 y ' , s;#i@ "#$&')*,-/023l54C6T`bhj1KiM}oycfhlojrpqutvvw{wz~{y}{u{ne]6ׄ3v5܌F܈Xܓlܚ{ܢ܋ܫܖܷܤܴܞބqEyjMira#Mf/?PauFt S O  y>yyZV !,#$&')*,--/0.2x3456 -O3Puy,URQhfxyj|sws~uyvt{yzy{~~|vo[)>Bv^0ۋOܩ`ܨsܪ܁ܷܕܠܴdy& ^'6THK&k6C:l:Vkx .=RrA~ * z  NWN3C4Ye@r!"T$%J'(M*+]-.n01f3T454w4LtXIZiJWtron|xzy~z~}p`!"'(ەbܽuܿ܇ܙܫܻAޞ"Y 5m] Bp/GVdw-JgQ M R gMToZ!j"#I%&@()F+-N.0@133546 $VId AjZszvm~tyvw}}}ze$"ۖv܈ܞܬܾ  1*ߥB:3zcC;5vEi "6DW`| Ag/ s  v , k:3jW #"#%{&() +,./1235355/I*\ZK:3LVxXstuptxzy|k*5۱ۘܖܦܹ!1)>ݍݹ,F+?cisbM(JbF|+,U./e1|2V4454"6^@ P'HnRv~lpyv&~ #-0=CLU]flv{݅ݏݙݙݒ߁[9LMD/v:J7p,Jiy'8Lg5e F B t;|'uk !D#$9&'>)*I,-R/0K23454P6V* ]qH`aovov~~{!q *6-A>TQ`bts݄݀ݒݔݧݥݳOމ#N |Dn p En (E[m~%;XzD~  g A zhGI:SZu# t!"`$%Y'(d*,q- /t0'2T345q5%5$3zX-<2 VR{Zmyurz~~_9AM5[Hk]|pݍ݀ݛݕݮݧݽݹߝ5cm9 7=~Aj4GWg|,OyW 6 Y q>/  ?R#W!"#%&()+-.0124454s6{[>gY/EjT~xzqpzRT^2jFu[݃oݔ݂ݦݖݲݩݺ.E1E_wnjI3VcVCc "/EVi .U+ o  s + k< My J"#:%&?()O+,_./i12L45n546,sE UC[igqy|zרMj+zB~[ݎrݝ݈ݭݙݽݲއBS'/))^"5)bAWq 1@Yx 0e C J n?Cn !p#$k&'|)*,-/023;5554^4h !>R=NXRyOmnnwx _4؉J?ݍRݓkݡ݃ݯݛݯ([dia_a$ZU4e0K]p5Os <w  g  = {lKNBX`7 !#u$&r')}*.,-E/0P2j354546#O J`Q~rkmv|{ %q9RB-܈Hݡ^ݧyݱݐݦݼ/$=J TgQAasF%f*"h =]!0CUj|/PyK > O iJ# $:eyC!".$%('(5*+N-.X01H34@5<5!55/C?8N08KRneuq~} *d- $ܕYݳoݼ݉ݢݺ4'F;YRwU ==P;5~-T5m7Xt -?Sn ,U [  o  l.$9/n B"#2%&5()B+-O.0P134q54545Dl|-vlItUs{tw 6_"ܞr݃ݣݵ$2%H:[Pneެނy8pDj#sBt1Kcu0Ie*^ 4 ? g7@u# !#${&')*,./ 123C5454~6U'b=a[s{vrx5d\ڑܜ݅ݘݵ 5'G?\Trmޅރޥ:ߕ .bn9 7BJq 9M^q&Gg,j  ^ v <\NAIKi2u2 !#$ &')*$,-7/04234S55G5D51 gP.FRvSnwso|7eO ܒݜݭ-'C 7 I cM +4t$b!"L$%Q'(f*+-.013{4~545r4-6wzPWkDjJj~jnuz/z ۅݶ+(>;TTllހޑޗޫޯ)8l X6(^@[r 7Og@x V  d  c0 I1 ^"#U%&Z()k+ -.013T4J55n54;6*nGsb8PYfuuj{u}{}޸r33FL\_syދސޠޥ޸޼t߱>AJVRL2`2F^n)BdH 1 + l"|1; "q# %n&(x)(+,>./R12<44_54l543>(:.'GGvwKhtlo{z bLc'.;GV]owޅތޛޢް޻9@G5'Ru~ub;`w!_4Z 3DZl9]U X h 6|PP6D>fv=q0 !#$ &')*,,-=/13234x545`46 9Q;<Gy8]FymzdmwzA8ZضU 12CI\`r{ލޒޢެ޻$Qa56?7 p.I9t2Wo):Ne 6d6 | ' D eB#?k8_!"M$%O'(f*+-/0234?55N545[-0%~v G8O`^tpmwy|}*TtDثE# 4$C~mllfw~ `>ؕ8-9 H.]Hteފ~ޢޗ޺޲34߅vzfX{\9:5~Ru5K_r 8W|<w * ! fr>P +"#"%&1()J+,i./z12g44h545`46#E0TIlkqbo{y{WMa6IX1mQނjޙޅާޡ޹ %&A@nf$KQ]O@EbN#Kj$:Mf| 'Q~T J o 0pXA:?Me?V !:#$<&'G)*f,-|/0}235%5"5&555/JF"-FvdMyank~hw|/dd4D["d@z^ސ|ާޘ޳" <;WVp J  Q/\@_s+DYw&P/ x   > g3 OhJ ]!"L$%T')j*#,z-=/0M2o354d545k45![wt`K=Z9{]w]bjpy .G5Tp2}Sޏrޣސ޻ު75URkl߇߶߳;q{LIQ*^2Rex2Ln*] H L  U*"aB!"#%&(*++-.:01+345K54s5{4k6'WlUq1H@gjn_equ 4TRٻ`">ވ_ޡނ޷ޞ޿6,NKif߅߀ߟߩa<1PhyxV@ fq$j1Zx*>Yl@e:z  j ) R%z~ZL ""#%&,()C+,[.0e1384254=54855-2 ;?>k19u`Gsdjjusu}}2S*-~h2ގMޜp޳ގޯ1"I?dZ߂wߜߔ߶߱,:C"9-5g/Ajdl_}h{t| 5Xn?:eFޛcުޡ޾ #B5]Ptpߒߋ߮߫ X^ \n0kbJ|.Fcv 6LjF|% q  x : Z-&UyW !#q$&|')*4,-S/0^2345654S54&6*3`/SOIuKXkcfnos{w 2U`^]ޞsްޑ޲ 1+OLif߅߆ߢߡ߽bQIlzV0{47zNv$;Ym}  ?_$X > Q  W<he;!",$%5'(R*+v-.0134?54E54U543eF/8^k8wVn]aor~/R[ܜٷQuޤވ޵ެ!$54j5L4r68&Aubcg6r1XW]Qr[rh{n{ 2 z,ޡ *'EFdl߇߉ߢߧ&>Ibz6M  W9!_+Nm%9Rj$L}Q Y  r AzwlNg J"#L%&c()+,. 01 3445454551?1 l8'^O7eTY`gauluz  ' ,ޣ޾ @-YNysߙߑ߸߶56TVvy=nIIV1a#Edz&A[$T n , : na3>$@:s]a !N#$T& (h)-+,S./m12W44;54O5454?62(U;Ah'`QXOrYsiwqz 2<P ۲ި5P7p`ߏ߂߬ߡ *$KHij*'{Nb~uwU> hu'm2`6Na{6[%\ D Z l:"!;{K !#$&')*?,-X/0\2345454>5u46w*ed)};z 2c5A`OV_ebnmwx} ';X^ُ۟޴'>#^I}mߚߍ߻߳9;Z^|~[.u,*-h-F;r 6]y "7Lf9_,o  s  h+ gM#!"$%&'(>*+a-/x0*2l34454+54C543>/jj&IWhB]KqNz]zhlw/Ck5ۆ޿/ M/eV߆yߦߜ߾(,KJim D? Pf(dgGs 0Ug $:[v6iA I d 4sra}Jm X"#[%&w()+,.01 344'54;54u546^ Jzzx@*i\A\@pGuYz^iw| *Kn<6#p!4O9p^ߏ߃߮ߦ21UZxz=66[tL&p+,tKv%?Ym0Qs6q d v 8 lJ6%(-D^Ny !i#$v&')$+,D./\1274444444453.19 | Z66NNG]V\cphwt~|+@lڗV+?[C}kߠߏߴ#DBih]A69N:24_F#Mp/C^w 2TD @ B  T>  Rhh0 !##$0&'M)*t,-/023 54&54754b574(5n <SWBLHcKj[pkvu}&3c>A/F)gRߋy߫ߠ 30TRvvb^V#zpFo${OGb/Li$Q[  e  `kP.!"!$%6'(P*,o-+/0C234454(54Z54r6$yabvPQ#WCDJBZMb]icutx 1Z$,J7h\ߋ߆߬ߪ9>]d EkbM~f8;D&W:Tl)Ai"R6 1 _ qcjrZ l T"#X%&q( *+3-.Q01Q3444444445~0hazC5P6JF[Jd[lfvmv,Lwgޚݽ &&ADfl߇ߒ߭ߵ&=K]p(=rX EX`UBLl W,Z(>WpAd"^ X f / l;:.$KVH !#$&()"+,E.0U13)454 5435r4j545bD*.!z$NN/K6\?cMkY{box'<Wݪ%6AWf}ߎߤߴ#9J]m#:KJ V6)e.Wu2Hh=f7u + 8 R3 Irc1 !$#$6&'T)*y,-/ 1234454 54656446&(n} vo2KN36C7NETVaZnksu}*|܌2DCcm߇ߍ߮߷.ETj{ "2FZ{1~1lxKPU7k'Fbx &=^~ 5n Q P  K!.]qM!"N$%f'(*,-#/0/234444454 542 oI8~.6H,?9U=]Od[rb}q} PFiخs:$SFqrߖߜ߹*7O`u !/CWj}u Bctzj[7`}#g >k7Nk6X}?y$ |  [ urUkf jk V"#_% 'v(2*+Z-.013o45454)5d4e53[6QJ}?[iN>-C(X:ZDnKt`|gv$"'R؂`P!bGyߥߡ\0 ! #$2&'P) +w,6./Y12@4444545x4,5H44E .0ls"09+8/N<PN^Wifrp}1Gwd&'q#߅Kߡ}߬8*]Q~ "CGot3B:HjqZufVn=CM/c!Fby #A`Bz i o . sL  *M'sH !@#$U&(v))+,X./x12S4444444e4553W6*$KKQKvX;38'.D)J5\?gOr\ir$BmrgHߛl߷ߝ,#VR|{%)OUv>s`3NffcH2] p!g5a@Xt3]W7 E x I;- p!"u$&'5)*`,-/12344444444440UHApO & 005BEJXS_cspy~6e\aۺڳaQߣr߾ߠ7-cY 36\`4>_""\'<=u 5[|5Pl /V4r _ ! D eydIv-!"$%,'(S*,{-B/0\2344444l45?4G535v  WS#)$>#C8PD\Ufcss~+Y]ښO]ߢ߁߯ ?8lgCBipCE;^ _` Jz 2Vr#@\| ,_A 0 Z  WD*- =Iz%T H"#U%&t()+ -.E01B34444444m4546(YB,uLMa:%" ,-3:EEPT^diqv~ $Eu1tߚߒ߼߼ACjr%@Qq|,H[=Hl{xa;j!*vIt +Im)Lm4p P  h  u?# !^#k !j#$&()'+,W.0q13844444444s44v42f 'rBQ% 4B1J>ZNfZvhuARߡe߇ߑߟߴ(?Ul3F_r&@Rk~1w252q6SKHq &D_~%FmJ' C n G=G y!#$0&'X)*,-/123444z44`4514C5396h~A%4>"1>&I8ZAiUoep1\Hߕߎ߬ߴ1Abp#@Uq "4M`y8_p9rsWIk2Rq Hz\ V ? yfhl?B*!"0$%Q'(y*,-E/0[234444444w44&45*Q{)!i7$ !#(0<=ENWXfirxc`B+$ޥߎ߼߶o 1Mo-HtFi " 9 hW310.asM` V"#j%'(M*+}-.023o44{44k44T44*453E6H#j*HJ++:;ARV[asn~ $F\FNLzߨ 6aKML{ z@f ;Yy)I{Q= R a7 5aF "#%&E()v+-./0163m444444444}444/RNl`?|#$3F3U?fPq^k| *Tٜ/޸߁߭2^Q!"OWAOq5 }5{[$Y b G}=b)Le'Tb q  f % \C !#$<&'d)%+,Y./12R4}44m44[44A444535_c* %6J&U5hBvTbv .Y|Ij@ޮߋ߷3(b]'0Xa(L_~!=!OwyhCl)2~S8]v&:g+]= = c / gi]m{ HgU!"f$%')*@,-n/1~2444~44p44]44;4435&%  );%H7\FkTbw!Sz2ݠߐ߻9-k_+0^g#/Ve,LpGu!/=."x/XH&X +Lh=l/ig r 8 qD:)"ASE "#%'(P*,-6/0M234{44q44f44Y44J44`41DJKqd>\%24<INZ]ll{|Hۢݕߔ߼ <1ld58io 4ڻ݁ߣ =6mo :Bqy 9Fn}9Hly>@q|e37I.c.Mr6XJ{[ i  _ %g `C !I#$n&()G+,x./13R444u44j44Z44@4435)HGBffZ!| $-/@BMVbavr-GD٥i߲ 7Cm{>Ns!CXz$B[st@@TYV<Npc>l"Fd~6]J6 1 l # y`nh cpc!#t$&'Q)*,./%1234g44]44N44=44443t3 Kf|2OR-x1"?3SEdTtiyB~A-Me&<\u-E`x4Jfz/Z6 V8/nAk9Pu 1Y \ \ k 3 o@</#MYN!"$%:'(h*,,-a/0x234\44P44A44'443 5j366_d* U4+7/J@YRmb}w`CY ߿ )T`-?bx:Nn #>Ssa)bwIP[Ay`r/w:}[&cfSDn A_AmO? e  UA%!*4cd/ !"2$%`'(*,-R/0k23j4{4b4y4Y4w4Q4u4J4s4E4^44 0wW%j,G^} !#63IG]Wsey9R܆ߠ 9lY FE}|#-[a 7@kv#"Hr{vjA#i,.}'_=bx8bEy+t o : n R 2W. 1"#K% '}(G*+-.023G44E44644%44 4434_35Vk>vZ-rxm#&2=CRTeg|o!?@@`ߝ <oT LD*/dl?Ir%j-B-%}4^J0a8Uw5]SF E  > 0c ~l !x#$&'()^+-.H01R3;44S4}4I4}4=44+4444359'Pq[qU.#<:RHkX}ky.q٤Eߥ;s_NP3?it IX'4p3_j>o%x_2X0Pt)].lb  E  uX_Wn`! #$/&'b)+,Q./{1274\4u4P4t4G4t4;4w4,4}4444#27 [-IB'Kyz 2E%Y:lLZj| 5`0{?-߲ 2"lbNZ 2Dk|+Qd)@e):ky`4;G0i-Vo+Qr+`@1 \  M> $/8k wB8!"S$%'(*6,-j/,124N4~4@44044444434G35#hJkaxe!+?T1iB~Vcw0Wh9޶߳.%feLZ 6Ip3Wh5Ml%2INL4Jeb8l&Lm Fn9q\ k ! o C@znK P"#p% '(K*+-/0523\4`4Y4_4P4^4F4]494b4"443P5*-eBiDix.!A2ZEkYg~ _iK( > h =  u"ud "r#%%&X()+-.?01D3d4?4v444v4(4z444443433ph<Qn G]o-/;CNZ`mttxٮ݂߾)*cg$R` DP|-<NWdfw|9vC;W1 8Hv 0Hm$@a3Ql@V{}8 W"<<Hl /Zy&T(dC ] j ,Hn b l"#%'(I* ,-L/0o23q4,4o4"4o44s44}43434Q35y2?DpS !94LM^]tu/ A?|6Br+?hy5]o$J^?W#j{U] _MEm)Op%X3vm * Z 0 u${n "#,%&d()++-.`02^3Y454`4,4^4!4a44g44x434^35$6^wdyt*YV*59LQ^fwxߴ@7{|6?t1Ai$:cy,RlY@^p|o_>j#4YBl!Fn2hFL m / z_VKT`s5$ !7#$e&')5+,o.01-3#4T4:4O434K4*4I4!4G44G44<4C4|0Jg!KsyT~':*T>gRexXظ߲=7y~6Ft 3Go)Bg9\tZ'.*q3VR+\GhCp@h 5  _J&EY+rB?!"`$&'R)*,./<123e4#4a44a4 4f43o43434.35/)[I;/6U=q&>T.nCXkw_sܧ߬;3y{8Ev 5Ku 2Jl&A`~mPj9o#{"a0a@aHtP? Q ` - N#w "$%@'(**,-h/023R414L4*4H4!4H44L44X434z35'W9+zYi=Exw|2K*_AzPbpti&xߞB*zq8Az;| DJCM=P 7FjH26z ?j 2Xz 0\1q_ y / aD# !Ec4^b!"$)&'i)+,?./m13 4A4)4:4"4744644544;43V43*5*M`yv5`HRyk1I-e=LZZ-J޶ߔ/pe8;u >OAUBX9RANxjA NUAwCn(Js9c<5 B  N *!F7v !".$%g'(*4,-o/!123%4D44C4 4C44E43M43[43433| J[3to%=g#Vl~/ Fe,DNO!<4ۤݑߚ`d*9k 5N{@ZB]<\|)AX`VD&Xv)nD~@iEr <vP_  V  C{4 '"#S% '(N*+-/01234A44B44C43F43P43e43435)hC7JTl# #mnQ{_x &AW-s@NO!MGڽwߜ `h(f L{K/0 Z ! q^OOXl9VO !i#%&E()++-.d01g3.4%4-4 4%44!4444444434)- s(B1!nfV4Bfcf*!F5eI}[Y5E6ٖeߢXh.@oBT "Nh.Wl0Woo)iX*^tQ-b9^%UX Z e 4  f2,2;|2!#$9&'z)?+,./1 3144B44A43A43E43N43`434@3[4*HXz~2UgTlg|(5:QPlbeE0sQޠmKߠWf-@nC[%Uj5]v!:cz2PHf{{cJq)>!a3\5_([0x, 7 G ,0PO+,!"T$%')*d, ./T1244544543543643=43P434!35"[@6Ps{RE=+VMSdZs +5DPZanWb 4;߫߼Gf!@j?]/Qq=`~&FeK)0-u6\S3i)R~9c+d QU J  JSD V"#%'(a*,-W/0x23/44'4 4#44!434343434.4/'\lxe;4$ZKej|~&-@FW`rqi޹ߦ-8sHc"9h9R~!Jh)PlIn=r."e >r'Nv?o3x&} Z  ggN]Q}Q b] "{#4%&u()+@- /x0/2n3<43943743843=43G43_4342D5$PgMVCbVp  !(5CR[gvzA޾ߘ2,u{N]$6j?W #Pm1[sbq1j~x_3>U7vEr'OyGxNL c * _8+:KM !.#$d&()e+,./0183"44(43%43#43"43'43443c483}5;&t7=US:.E3ONOrq|)'J=aU~hJ[أܠ޻ߎ.(uuN[$= !a#$&()k+3-.u01w334343434343 43-43J4k32c /w1Z}jG6/@J`fr6U$" @9jݜcߪfSEF$+nzIY$7i|

E  C  0r!"/$%x'!)*o, ./B123 43433333333333 434+40 P$+4>A`Txs /Qyiڧڵl`ߤTS7E3iK^%@pDc2ZybRokM#|6D6v Bl2[G"i ` B  {^aXr|'f( 0"#h%'(p*+-A/0e23343 43 43434343)4x3V4)33 :~,%i4B8 @$d;~[x ,Ks`4ڒJb߬ߧCN(D{2`Df#EkFg<]K296# Aa`CAp0ZS90 X  P=,7e}OS !w#%&M( *+Y-.023343434343 4343$4p3_425!>h]v82 2U7oVo=d  ܶY`ߙߤ1K"Aq1^?f&Gr'Nn$AhAwB {)2zNGp)X.i V h " q D Pl!#$K&')M+,.,016333333333333333333.4.b&Q!$5DOalx"Ib1aߔߠ/F~%>s.`~Kg1Lz +Tr-Jq5i^@DTPRKt0aF&D n G  -<1!"_$%'.)*~,J./1233 43 4343 43 4343/4S3k42413t:YY #)M6aX}u2$a W _߃ߜ%At9n )[{Hi-Ly.Wv 1MzNg;LXNAQ{'v]#XJt 7oZT C w^c`u7{=8 Q"#%C'(*(,-u/"12333333333333333b3%42H5%|{{ =.TUom !ܳbkߠߺ?e9b,T|Bh-Sx6Y@c6q  f'MN2o 8f!O[8> \ $ nJD5AEkU|  ("#c%&(:*+-3/0R2343333333,32R33,32>32;32&0 qcF*X'=:[[p{yت܀lUߦߧKWs *Yx 9W/R%G$xA18U(S :iD!s+ B  o [2.*#Od7~UY "#9%&v()+6-.e02N343433333212Z22 2213m13z"><0SPqo-<e~zuZpDߨߔEJ>N2H$;t+_yA^?aEij ch s1beR#V~#GyD&ot0 j = MJ0>!"m$&'#)*8,-M/0@2333333333'2 //g0//0///0?(6n/"FCiWt2LaxQ+ߝ{;66A2E*@|8k!WsjX.e1p|N GE6s9g7b*c_V O ' "z, w!"C$%z'(*+-.01b3333333332X/"./4////././ u .G*0FU\xwB3>۪Aߙo7,5=3B.>|4n "Wqj gIt $|Q$a('uWP}N~NEB } 4 funTWI e"$%I'(N*+W-.Q013333333333S0 -..o.8.#/. /-80];0y 15PUrkK /|ڌ.߈j.(,8/>*?{;n(^vh0x$g8ltY-IgY:r8m1e9(~2 _ # w_VOXh%w9( D"#x%'(*+ -./p123333333331,F-.--3.---b.(=WF[f 8!Z@v\vvXhۙt "xp,t&>(H}&F}@m4_#d=A~1SYWH/m(D>V$TL'ld B x `E>->EkU| "#O%&x()f+,W./71{2333333333 3-+ .y-,!--,-,-8$- du<X3uNkFeo+U\"jp߶-m=t"Iv#Gw@n 2[#aAV)'Kv+{&g>r ;k5qXRp / d E+ *Mm1\Z !}# %&J()3+,./0E2|3333333333/*,^-a,7,?-.,,,.> Z^\*G7gPjnV6B!`q߱ -e?s%Hz&Kx!Ds,#,+,*,( }\_QHl!(?RWqylzKݼUm߫"b7l@x$Ex"Et;i ,]E3tJCog64H0mDt 6j G"q&6 R 1 0T=x !*#$a&'m)*?,-/]0123333333333, )B,+*++*+*\,~UvXb|#<AWay,t9IE4߽ܟDeߝ߿Xw1i@s&Fx%FxVQl ]} )_ +_&Vy4]l SW!YjX1k9g8s_] F  q[QL]j/K8 N"#%'(*c+,.H/01333333333331'%)B(t'()  Tql$?72a3X>{Xy2`HWK*|r,=C`Yw ,d9l=k1b,e"~%sbh6>P@TU(fJOt 2 u XE6:?Urc" $"#S%&():+,-!/c01233333333333*$((&w',& " <=dd3V;YwXrf(߁o2=I`^y0m >x$Bv@p+i+=NKszaHo$:%k F{ ?tW5=Y $  e >5& ?Q=zz !##%&]()+s,-/&012333333333\3=4.I$%(&&P N "Ag*j @s (F~ 0&ODv^yWa) ߈m<=Tc !k9{+I2M0N,k8UU ?hdX@&V q&tU1e0gC'y+K  p O *  <g#TS !r#%&>()+I,-. 0M1r2333333333332r&,#' '"9 z ho$ 5 UDzZtdVں ߅r9A Wm,p%D6S:\7[4|kAij>@7 x:__G W&[3umA b 6 *L`0- !K#$&/()*-,-./1Y2P3333333333e34_*!p%' v 7  d}i>!_A[vg6qy-wې$ߊ߁BQaz8{6T DgJmLpD}lM9 _(LT9rIJ$i ]w/ Q + =kM !3#$l&()*,V-./0!2<33333333333&4/?"u#$# \ @ c[E] :*\Lc)"n۵-ߓߋIY $n.IDcWu)` 0b (XhW,TD6D'c ?s>v^Lk s 9 (M9k u!#$W&')*,1-./01)3333333333332@%C!\q 5 9Ro;:3:XPqKf@ۤ7ߒߔQb,w6TQm (e8olAjRhW3_q~^5 Nd]?xGT5+= { @  LH(/!"X$%'1)*+-1.Z/u012333333333334a0" , c G $\W+<Iei %04ڐmߓ-a+]$VEy1bFr%T}*S~La\A{`WyweF{;QN/k ?tE,x|3 j 7 =|)  !"6$%r')*+,+.;/k0q12z33333333343T4) E >Y N  GQFKMu::Uaz#.MD$چ|ߜJzޑߚMk;{ Do 4k)TBk!Qz)W~([Wm`Au ,C1[82wW&\7u^ l T  |nahkWdQ i"$%K'(*+,../,0W1G2_33 43 4343)434)T' % tU @ ~ JqJM"5P[nv8{ioޢߜ_p*DXyA~=bW{ 3fzTBDo ( m V:5/@Jrf( -"#^%&(4*+,..012234 43!43432  0Xh J: p  8"179,^Bh%MwFa=3ݳ߸"#Rn@ Ms8t2XIn&X}*\+foIvADYF+c2hM1=] %  f =2("CSC !#.%&t(0*+-- //1133>43D43]434+2t. Z } D h W I 29 %=_Oy,]!ݤ߽3)ev1I`|(F Hh$a9p>t0[db+4K7yZ'`E%z4L  o W *% 1;x&ln !#%&V(*+ -- //1123C43G43L43e3&"%n Qc y0 o N $ X*4'0Dg[5T3OݠC4 uAW (r9VZz8w+L3U8K ynKo':,qL\7|#t#G  j B ' 3X qFB !g# %&U()+,../0123 4G43\434.-"uq z | F ? Z x )(Y$I?65y]J,Fk'5ܢFF'~Li=Jn 2m+R AhIoL5do^: `0'i D~V0qpD c 6 (Ia62 !R#$&E()+,../0123 4S44\433#$ gD   F 3 > AsS%BnCW.n#Y]tobܨS["=_.R]"L Cm$X4f7f**(JTJ)V v&{^@y J-pd4 Q 1 @hW+) !K#$&()c+-.//012g3C44l434.` $ B v Y? d ] , F cmYFR3<q9+`OPl=޺ܫ bq3Q+tFk8w=d%]Au*P2U~483E91HgpW:vA$k \z- H ) 3ZG !>#$z&()P+- .//012X3G44x43E4#&F^ &   0 | ) F ZUm 'T{2hKwެܱ!mDfCX(OV@x3\DnNtr:MNG v;bg W0i@cY j) n E  R,|!#$V&()Q+,2.//012~34{444#0 j 5 * nU#~Cp ?nz_+<ߤܻ=wO,[2j{ZUf# h ?   G|o!#$D&')H+,?. /001s2z334 44( drne '  Y   I ( u IpyWfzwA&q/>|OT$_+- gx < t w*ge,CVC@lP9dg9rP']1g6e-a$R $`1mVIa c ,  &l bFR!"$8&')+,6.N//012(3C4&44*T Y  j M  }?xL/IUuf)y߂U4dA{ONK{?p-Y@hCm(J{ MGL?Y6sRM\ Y 0 &UcIX!"$&'h)++,\.J/0001t2j334;2"  q m  H fdL   N luC`5<Wg{ߤ !x Wy.U.p@h 5p5_Qy 0d9gP,6|I EJ>W5t ONV T - KYBQ!"$ &'Z)%+,d.X/K001g2334,>!] ` :3! E  V Qg"&Q">U[XMl:5%2uMp"J_,RT{=q(Q4ZK!CNq>:D8}V.k REV V G?".!"_$ &'_)*,A./8011273)4!3% ) s(  u 2<'J H% <>  n tk|n0q$@5zX]Fq-;K8a;e=z Gp9s/[It$T|-F+Ugg75D7yW*k RDZ V  G4%!"U$ &'_)*,9./B021123j4.-!" $ <:k F ) C  # ;UM ).#[:c~l33k T`2L3}Y,V(c-ZR}5hDw$Gi<1`|w[0u2>6zR0pNHR O 23(!"Y$%'D)*,I./u0112Y3h3(w@ 2A Z ! c F98.\3 E v Z ' c(0+e7 1-9iLwd& uuQg0K ,yOrEQv9v0V AhHgT23lhN.q096}Q2oJIN H ! &~0"!"Y$%'2)*,S./012q230"!A"\ H ! M f3Xf) E   G`Q(-6B~_ `,} l|Kb*F nAb 1q6ZSv ,f6iB8y1bB&l,95yS0k LEQ L  %m!"B$%'5)*,9./0C122]3+    + N 5WYJ vu  ? / j8=XC&BOEl'7[_g3-3!eDeC]+QW| ,~\9`6x Hs=v9^Nt(X~=8)Sm%a 61wS0l KDR G  zz}Y ph "*$%w' )*~,+./0t122. O. 20 v ^h%o @ x W3 ^  j2yW;'IVNqv|TGk<[!H 0xU-W)e1\ W~=q%L|"O72e ]11rN.nLGO D  pvuSb] y"%$%p')*u,,./0172_2)D" S a g_BW1#^ 5> b( Q 4 #qCBy ZWOEiYUx@e&M/r Nx#KU~Dz6aIpGpt6:o&X..sQ.i OEN  D  pksF`W x"$%`')*x,./01W20$ U ]`  ) Hv*:1 w]AV  4 Q:VpH+ei}ik[?n#Q-j@m=s~4X/*uV.l PFS ~ D zqhr};YO q"$%T' )*p,./11_2, " $ MR  M*"  k ;! 7 +!D|w[ 3nU=lHߗ|C0u_?r"Q)c4b.`"M~6aAffI%BDR/1rT2nPGO ?  }hif|<E? ]" $%Y'(*T,!./?111' b! J s r % }_bcpzN   |] M:3w3I:)߭%bQ:x#^>tJTPCq/]:ga,C.VT +/uS7qRKP @  }dc`y4w<2 N"$%X'(*N, ./D12/#" p ]d : 9 W yGBS ;4B   j)!+DMV{d8?;/t aFz)]7nEvAv9g$T2_ 4m@i!N+f;h 5h-XCp"Kv"{m-S:v:v+/z^>aTX E  rZVReuV  *"#n%5'(*/,./&0($!6<$ f   B D  v ef K> ( q+Up=Ga4sR&%41({gHn%N#d2[W|:r&Hu"FY['[F}:w0/}&h>~$kS ` O mcM]X}_# <"#%'(o*h,-0n-& x3V /A M V  3  `<  M07s/-;EWj>JT9Q)H8kGj"FY} G~>bOpOp>C^T@x32|/oB.s Vl V lhLbVd%} G"#%'(f*y,-/*%. % TfL \  _ . !9 i|hN-#wNH%9/FqObsXtJj3YB&kDl>{Aj)aAtBs0U[@|39*rL-p\ h R  taRU]xQ )"#t%'(*;,.5.v(" )15 : i 4 nh"hg @Qn+i~;bc:~oeR~?j J'f7e3i)S@jEn8P e J2>/oR.sj n$ P  }]^PhpH "#Z%?'(*,g.+.':<(< X  y 6  Sc5 4] {@ O^<aaex\=; 8-s^Bq!Q%^*WQ| 9j?mLM oY:B4wW5z!mr' X ! }d^Pfq E "#[%0'(*#,-)t$sdgC) 9 46b:M a3I-+B?\c6v&[/W*WK <}"dCqHN{@w3\ :cEkJp i>D<YA!m z( c  ynS]]~Pu ."#~%'(f*,},(a\. w   K C]C ~X)m;*"G4w I# '-(B|M}Lx>o1_G'k>m;w@g']2g=o}Fv)|GGB_ H(r), m " zwSg\^nu ?"#%&)N*,*&I y X M $ m D ca PZ*5 &Q9 ,[=7!/a([nkeT>l R-g9j/g(O <_?iv@y/$JOG#i K0}.9 n , q_a`Ry *"#x%'(*,)!?$Pj }  E3    7O%  > ucF%R)r' /?uT^.{VRgoL ID9v&` E~"W*^([!O} 6` ?gx`g613FXI2q L@,B i 9 hm\stA "#S%L'(**\(J 3 " SAWNsN oSm/e`X 13AQp.e)A$ t#t'ob O7hDW"PKs /`6j:9M*}0@I^J9xQD0K m > loXtq ; "#I%F'(*)+% xs&f * iI,!#Qfk`EB tX4 nm/2c7![Rk$QY,)Q*>EF@3v]>mE~Kw>q/[:d=j&u4FJ[R<|\G;D w :  yhbk}Ht !"#m% '(9*b)1pFT*$- | 9  |N@"-DH=0. (K}B<5|e1jO<^;i7k2h"V @%aC   7 |]k\P Ze 0"#%&")p)'+< H  aI15,OP$33 \+jfo^t ,pu1N_UoYzYXSDw2dH$]1`)^$M~+X%G'`((+*1{p k : Oa5`K} >$C1aExx6w"^| n$+<+I(K D4iJm@StE><[<;E7L;7;D;>K > CKAJCA?T?>I?I>? L>?G ?KA:T>@:R_@M_RJdMOqJ@ O3[ @7N3 :_7 @?m:?C[@CFiJTFJHMHEK ED?DEK EHMHEK ED?DEK EKDKHF HC=CEI E KJKHLHCLE]C E J_H[JHBYE_B@E QsH_@QBJHEfB E@Nm @ HbN H >REd>E@H]EO@H BiE B6?269F9 >J><> <:J:9B9:D : 7F:K7>G:CG>FJCE[FEC]EbC CREBfC @bB @>_:_<:9V:R9 : 7L:T7:>J>CD C FJFEE ECECBE>JBBJ>EGB EJVHNJ HFCFEJEFN FCKFYCJ] FO_JRbOQiRQOkQkOO] QNoOL[N LJbHdJFkHFEdE7_F_FC[F_C @FJ]7OoJ@JMOF[JFCJ C 5f!OkJdO@ Gf 5J CbGGkC@JkGObJ OHJ?B?H CRC OEO CD CH>?; ?HCLC OO OC= C GB>C >GCDCMB M C9 CGJ>J G> CMCMA CNMCKT0b HLGCG LCHGHRNRHCHPN P/drumstick-2.5.1/library/rt-backends/eassynth/sonivox/PaxHeaders.27918/host_src0000644000000000000000000000013214200302440024233 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.357324521 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/0000755000175000001440000000000014200302440025071 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_host.h0000644000000000000000000000013214200302440026266 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_host.h0000644000175000001440000000724314200302440027055 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_host.h * * Contents and purpose: * This header defines the host wrapper functions for stdio, stdlib, etc. * The host application must provide an abstraction layer for these functions * to support certain features, such as SMAF and SMF-1 conversion. * * DO NOT MODIFY THIS FILE! * * Copyright 2005 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ // sentinel #ifndef _EAS_HOST_H #define _EAS_HOST_H #include "eas_types.h" /* for C++ linkage */ #ifdef __cplusplus extern "C" { #endif /* initialization and shutdown routines */ extern EAS_RESULT EAS_HWInit(EAS_HW_DATA_HANDLE *hwInstData); extern EAS_RESULT EAS_HWShutdown(EAS_HW_DATA_HANDLE hwInstData); /* threading */ extern void* EAS_HWRegisterSignalHandler(); extern EAS_RESULT EAS_HWUnRegisterSignalHandler(void *cookie); /* memory functions */ extern void *EAS_HWMemSet(void *s, int c, EAS_I32 n); extern void *EAS_HWMemCpy(void *s1, const void *s2, EAS_I32 n); extern EAS_I32 EAS_HWMemCmp(const void *s1, const void *s2, EAS_I32 n); /* memory allocation */ extern void *EAS_HWMalloc(EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size); extern void EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData, void *p); /* file I/O */ extern EAS_RESULT EAS_HWOpenFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode); extern EAS_RESULT EAS_HWReadFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead); extern EAS_RESULT EAS_HWGetByte(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p); extern EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst); extern EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst); extern EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition); extern EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position); extern EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position); extern EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength); extern EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pFile); extern EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file); /* vibrate, LED, and backlight functions */ extern EAS_RESULT EAS_HWVibrate(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state); extern EAS_RESULT EAS_HWLED(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state); extern EAS_RESULT EAS_HWBackLight(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state); #ifdef __cplusplus } /* end extern "C" */ #endif /* host yield function */ extern EAS_BOOL EAS_HWYield(EAS_HW_DATA_HANDLE hwInstData); #endif /* end _EAS_HOST_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_report.c0000644000000000000000000000013214200302440026617 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_report.c0000644000175000001440000001472414200302440027410 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_report.c * * Contents and purpose: * This file contains the debug message handling routines for the EAS library. * These routines should be modified as needed for your system. * * Copyright 2005 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 659 $ * $Date: 2007-04-24 13:36:35 -0700 (Tue, 24 Apr 2007) $ *---------------------------------------------------------------------------- */ #ifdef _lint #include "lint_stdlib.h" #else #include #include #include #endif #include "eas_report.h" static int severityLevel = 9999; /* debug file */ static FILE *debugFile = NULL; int flush = 0; #ifndef _NO_DEBUG_PREPROCESSOR /* structure should have an #include for each error message header file */ S_DEBUG_MESSAGES debugMessages[] = { #ifndef UNIFIED_DEBUG_MESSAGES #include "eas_config_msgs.h" #include "eas_host_msgs.h" #include "eas_hostmm_msgs.h" #include "eas_math_msgs.h" #include "eas_midi_msgs.h" #include "eas_mixer_msgs.h" #include "eas_pcm_msgs.h" #include "eas_public_msgs.h" #include "eas_smf_msgs.h" #include "eas_wave_msgs.h" #include "eas_voicemgt_msgs.h" #ifdef _FM_SYNTH #include "eas_fmsynth_msgs.h" #include "eas_fmengine_msgs.h" #endif #ifdef _WT_SYNTH #include "eas_wtsynth_msgs.h" #include "eas_wtengine_msgs.h" #endif #ifdef _ARM_TEST_MAIN #include "arm_main_msgs.h" #endif #ifdef _EAS_MAIN #include "eas_main_msgs.h" #endif #ifdef _EAS_MAIN_IPC #include "eas_main_ipc_msgs.h" #endif #ifdef _METRICS_ENABLED #include "eas_perf_msgs.h" #endif #ifdef _COMPRESSOR_ENABLED #include "eas_compressor_msgs.h" #endif #ifdef _ENHANCER_ENABLED #include "eas_enhancer_msgs.h" #endif #ifdef _WOW_ENABLED #include "eas_wow_msgs.h" #endif #ifdef _SMAF_PARSER #include "eas_smaf_msgs.h" #endif #ifdef _OTA_PARSER #include "eas_ota_msgs.h" #endif #ifdef _IMELODY_PARSER #include "eas_imelody_msgs.h" #endif #ifdef _WAVE_PARSER #include "eas_wavefile_msgs.h" #endif #if defined(_CMX_PARSER) || defined(_MFI_PARSER) #include "eas_cmf_msgs.h" #endif #if defined(_CMX_PARSER) || defined(_MFI_PARSER) || defined(_WAVE_PARSER) #include "eas_imaadpcm_msgs.h" #endif #else #include "eas_debugmsgs.h" #endif /* denotes end of error messages */ { 0,0,0 } }; /*---------------------------------------------------------------------------- * EAS_ReportEx() * * This is the error message handler. The default handler outputs error * messages to stdout. Modify this as needed for your system. *---------------------------------------------------------------------------- */ void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...) { va_list vargs; int i; /* check severity level */ if (severity > severityLevel) return; /* find the error message and output to stdout */ /*lint -e{661} we check for NULL pointer - no fence post error here */ for (i = 0; debugMessages[i].m_pDebugMsg; i++) { if ((debugMessages[i].m_nHashCode == hashCode) && (debugMessages[i].m_nSerialNum == serialNum)) { /*lint -e{826} */ va_start(vargs, serialNum); if (debugFile) { vfprintf(debugFile, debugMessages[i].m_pDebugMsg, vargs); if (flush) fflush(debugFile); } else { vprintf(debugMessages[i].m_pDebugMsg, vargs); } va_end(vargs); return; } } printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum); } /* end EAS_ReportEx */ #else /*---------------------------------------------------------------------------- * EAS_Report() * * This is the error message handler. The default handler outputs error * messages to stdout. Modify this as needed for your system. *---------------------------------------------------------------------------- */ void EAS_Report (int severity, const char *fmt, ...) { va_list vargs; /* check severity level */ if (severity > severityLevel) return; /*lint -e{826} */ va_start(vargs, fmt); if (debugFile) { vfprintf(debugFile, fmt, vargs); if (flush) fflush(debugFile); } else { vprintf(fmt, vargs); } va_end(vargs); } /* end EAS_Report */ /*---------------------------------------------------------------------------- * EAS_ReportX() * * This is the error message handler. The default handler outputs error * messages to stdout. Modify this as needed for your system. *---------------------------------------------------------------------------- */ void EAS_ReportX (int severity, const char *fmt, ...) { va_list vargs; /* check severity level */ if (severity > severityLevel) return; /*lint -e{826} */ va_start(vargs, fmt); if (debugFile) { vfprintf(debugFile, fmt, vargs); if (flush) fflush(debugFile); } else { vprintf(fmt, vargs); } va_end(vargs); } /* end EAS_ReportX */ #endif /*---------------------------------------------------------------------------- * EAS_SetDebugLevel() * * Sets the level for debug message output *---------------------------------------------------------------------------- */ void EAS_SetDebugLevel (int severity) { severityLevel = severity; } /* end EAS_SetDebugLevel */ /*---------------------------------------------------------------------------- * EAS_SetDebugFile() * * Redirect debugger output to the specified file. *---------------------------------------------------------------------------- */ void EAS_SetDebugFile (void *file, int flushAfterWrite) { debugFile = (FILE*) file; flush = flushAfterWrite; } /* end EAS_SetDebugFile */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_chorus.h0000644000000000000000000000013214200302440026614 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_chorus.h0000644000175000001440000000272614200302440027404 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_chorus.h * * Contents and purpose: * Contains parameter enumerations for the Chorus effect * * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 309 $ * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $ *---------------------------------------------------------------------------- */ #ifndef EAS_CHORUS_H #define EAS_CHORUS_H /* enumerated parameter settings for Chorus effect */ typedef enum { EAS_PARAM_CHORUS_BYPASS, EAS_PARAM_CHORUS_PRESET, EAS_PARAM_CHORUS_RATE, EAS_PARAM_CHORUS_DEPTH, EAS_PARAM_CHORUS_LEVEL } E_CHORUS_PARAMS; typedef enum { EAS_PARAM_CHORUS_PRESET1, EAS_PARAM_CHORUS_PRESET2, EAS_PARAM_CHORUS_PRESET3, EAS_PARAM_CHORUS_PRESET4 } E_CHORUS_PRESETS; #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_hostmm.c0000644000000000000000000000013214200302440026613 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_hostmm.c0000644000175000001440000004213714200302440027403 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_hostmm.c * * Contents and purpose: * This file contains the host wrapper functions for stdio, stdlib, etc. * This is a sample version that reads from a filedescriptor. * The file locator (EAS_FILE_LOCATOR) handle passed to * HWOpenFile is the same one that is passed to EAS_OpenFile. * * Modify this file to suit the needs of your particular system. * * EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within * a MIDI type 1 file that can be played. * * EAS_HW_FILE is a structure to support the file I/O functions. It * comprises the file descriptor, the file read pointer, and * the dup flag, which when set, indicates that the file handle has * been duplicated, and offset and length within the file. * * Copyright 2005 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 795 $ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $ *---------------------------------------------------------------------------- */ #ifdef _lint #include "lint_stdlib.h" #else #include #include #include #include #include #include #include #include #include #include #include #include //#include #endif #include "eas_host.h" /* Only for debugging LED, vibrate, and backlight functions */ #include "eas_report.h" /* this module requires dynamic memory support */ #ifdef _STATIC_MEMORY #error "eas_hostmm.c requires the dynamic memory model!\n" #endif #ifndef EAS_MAX_FILE_HANDLES // 100 max file handles == 3 * (nb tracks(32) + 1 for the segment) + 1 for jet file // 3 == 1(playing segment) + 1(prepared segment) // + 1(after end of playing segment, before files closed) #define EAS_MAX_FILE_HANDLES 100 #endif /* * this structure and the related function are here * to support the ability to create duplicate handles * and buffering it in memory. If your system uses * in-memory resources, you can eliminate the calls * to malloc and free, the dup flag, and simply track * the file size and read position. */ typedef struct eas_hw_file_tag { int (*readAt)(void *handle, void *buf, int offset, int size); int (*size)(void *handle); int filePos; void *handle; } EAS_HW_FILE; typedef struct eas_hw_inst_data_tag { EAS_HW_FILE files[EAS_MAX_FILE_HANDLES]; } EAS_HW_INST_DATA; pthread_key_t EAS_sigbuskey; /*---------------------------------------------------------------------------- * EAS_HWInit * * Initialize host wrapper interface * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData) { EAS_HW_FILE *file; int i; /* need to track file opens for duplicate handles */ *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA)); if (!(*pHWInstData)) return EAS_ERROR_MALLOC_FAILED; EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA)); file = (*pHWInstData)->files; for (i = 0; i < EAS_MAX_FILE_HANDLES; i++) { file->handle = NULL; file++; } return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * EAS_HWShutdown * * Shut down host wrapper interface * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData) { free(hwInstData); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * * EAS_HWMalloc * * Allocates dynamic memory * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size) { /* Since this whole library loves signed sizes, let's not let * negative or 0 values through */ if (size <= 0) return NULL; return malloc((size_t) size); } /*---------------------------------------------------------------------------- * * EAS_HWFree * * Frees dynamic memory * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p) { free(p); } /*---------------------------------------------------------------------------- * * EAS_HWMemCpy * * Copy memory wrapper * *---------------------------------------------------------------------------- */ void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount) { if (amount < 0) { EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000004 , amount); exit(255); } return memcpy(dest, src, (size_t) amount); } /*---------------------------------------------------------------------------- * * EAS_HWMemSet * * Set memory wrapper * *---------------------------------------------------------------------------- */ void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount) { if (amount < 0) { EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000005 , amount); exit(255); } return memset(dest, val, (size_t) amount); } /*---------------------------------------------------------------------------- * * EAS_HWMemCmp * * Compare memory wrapper * *---------------------------------------------------------------------------- */ EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount) { if (amount < 0) { EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000006 , amount); exit(255); } return (EAS_I32) memcmp(s1, s2, (size_t) amount); } /*---------------------------------------------------------------------------- * * EAS_HWOpenFile * * Open a file for read or write * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode) { EAS_HW_FILE *file; int fd; int i, temp; /* set return value to NULL */ *pFile = NULL; /* only support read mode at this time */ if (mode != EAS_FILE_READ) return EAS_ERROR_INVALID_FILE_MODE; /* find an empty entry in the file table */ file = hwInstData->files; for (i = 0; i < EAS_MAX_FILE_HANDLES; i++) { /* is this slot being used? */ if (file->handle == NULL) { file->handle = locator->handle; file->readAt = locator->readAt; file->size = locator->size; file->filePos = 0; *pFile = file; return EAS_SUCCESS; } file++; } /* too many open files */ return EAS_ERROR_MAX_FILES_OPEN; } /*---------------------------------------------------------------------------- * * EAS_HWReadFile * * Read data from a file * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead) { EAS_I32 count; /* make sure we have a valid handle */ if (file->handle == NULL) return EAS_ERROR_INVALID_HANDLE; if (n < 0) return EAS_EOF; /* calculate the bytes to read */ count = file->size(file->handle) - file->filePos; if (n < count) count = n; if (count < 0) return EAS_EOF; /* copy the data to the requested location, and advance the pointer */ if (count) { count = file->readAt(file->handle, pBuffer, file->filePos, count); } file->filePos += count; *pBytesRead = count; /* were n bytes read? */ if (count!= n) return EAS_EOF; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * * EAS_HWGetByte * * Read a byte from a file * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p) { EAS_I32 numread; return EAS_HWReadFile(hwInstData, file, p, 1, &numread); } /*---------------------------------------------------------------------------- * * EAS_HWGetWord * * Read a 16 bit word from a file * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst) { EAS_RESULT result; EAS_U8 c1, c2; /* read 2 bytes from the file */ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS) return result; /* order them as requested */ if (msbFirst) *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2; else *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * * EAS_HWGetDWord * * Returns the current location in the file * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst) { EAS_RESULT result; EAS_U8 c1, c2,c3,c4; /* read 4 bytes from the file */ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS) return result; if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS) return result; /* order them as requested */ if (msbFirst) *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4; else *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * * EAS_HWFilePos * * Returns the current location in the file * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition) { /* make sure we have a valid handle */ if (file->handle == NULL) return EAS_ERROR_INVALID_HANDLE; *pPosition = file->filePos; return EAS_SUCCESS; } /* end EAS_HWFilePos */ /*---------------------------------------------------------------------------- * * EAS_HWFileSeek * * Seek to a specific location in the file * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position) { /* make sure we have a valid handle */ if (file->handle == NULL) return EAS_ERROR_INVALID_HANDLE; /* validate new position */ if ((position < 0) || (position > file->size(file->handle))) return EAS_ERROR_FILE_SEEK; /* save new position */ file->filePos = position; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * * EAS_HWFileSeekOfs * * Seek forward or back relative to the current position * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position) { /* make sure we have a valid handle */ if (file->handle == NULL) return EAS_ERROR_INVALID_HANDLE; /* determine the file position */ position += file->filePos; if ((position < 0) || (position > file->size(file->handle))) return EAS_ERROR_FILE_SEEK; /* save new position */ file->filePos = position; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * * EAS_HWDupHandle * * Duplicate a file handle * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile) { EAS_HW_FILE *dupFile; int i; /* make sure we have a valid handle */ if (file->handle == NULL) return EAS_ERROR_INVALID_HANDLE; /* find an empty entry in the file table */ dupFile = hwInstData->files; for (i = 0; i < EAS_MAX_FILE_HANDLES; i++) { /* is this slot being used? */ if (dupFile->handle == NULL) { /* copy info from the handle to be duplicated */ dupFile->handle = file->handle; dupFile->filePos = file->filePos; dupFile->readAt = file->readAt; dupFile->size = file->size; *pDupFile = dupFile; return EAS_SUCCESS; } dupFile++; } /* too many open files */ return EAS_ERROR_MAX_FILES_OPEN; } /*---------------------------------------------------------------------------- * * EAS_HWClose * * Wrapper for fclose function * *---------------------------------------------------------------------------- */ EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1) { EAS_HW_FILE *file2,*dupFile; int i; /* make sure we have a valid handle */ if (file1->handle == NULL) return EAS_ERROR_INVALID_HANDLE; file1->handle = NULL; return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * * EAS_HWVibrate * * Turn on/off vibrate function * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state) { EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000001 , state); return EAS_SUCCESS; } /* end EAS_HWVibrate */ /*---------------------------------------------------------------------------- * * EAS_HWLED * * Turn on/off LED * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state) { EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000002 , state); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * * EAS_HWBackLight * * Turn on/off backlight * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state) { EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000003 , state); return EAS_SUCCESS; } /*---------------------------------------------------------------------------- * * EAS_HWYield * * This function is called periodically by the EAS library to give the * host an opportunity to allow other tasks to run. There are two ways to * use this call: * * If you have a multi-tasking OS, you can call the yield function in the * OS to allow other tasks to run. In this case, return EAS_FALSE to tell * the EAS library to continue processing when control returns from this * function. * * If tasks run in a single thread by sequential function calls (sometimes * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to * return to the caller. Be sure to check the number of bytes rendered * before passing the audio buffer to the codec - it may not be filled. * The next call to EAS_Render will continue processing until the buffer * has been filled. * *---------------------------------------------------------------------------- */ /*lint -esym(715, hwInstData) hwInstData available for customer use */ EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData) { /* put your code here */ return EAS_FALSE; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/jet.h0000644000000000000000000000013214200302440025243 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/jet.h0000644000175000001440000001751414200302440026034 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * jet.h * * Contents and purpose: * Public interface for JET sound engine * * Copyright (c) 2006 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *---------------------------------------------------------------------------- * Revision Control: * $Revision: 554 $ * $Date: 2007-02-02 11:06:10 -0800 (Fri, 02 Feb 2007) $ *---------------------------------------------------------------------------- */ #ifndef _JET_H #define _JET_H #include "eas_types.h" #include "eas.h" /* for C++ linkage */ #ifdef __cplusplus extern "C" { #endif /* opaque handle types for JET interface */ typedef struct s_jet_data_tag *JET_DATA_HANDLE; typedef struct s_jet_config_tag { EAS_U8 appEventRangeLow; EAS_U8 appEventRangeHigh; } S_JET_CONFIG; typedef struct s_jet_status_tag { EAS_INT currentUserID; EAS_INT segmentRepeatCount; EAS_INT numQueuedSegments; EAS_BOOL paused; EAS_I32 location; EAS_U8 currentPlayingSegment; EAS_U8 currentQueuedSegment; } S_JET_STATUS; typedef struct s_jet_event_tag { EAS_U8 segment; EAS_U8 channel; EAS_U8 track; EAS_U8 controller; EAS_U8 value; } S_JET_EVENT; /*---------------------------------------------------------------------------- * JET_Init() *---------------------------------------------------------------------------- * Initializes the JET library, allocates memory, etc. Call * JET_Shutdown to de-allocate memory. Pass NULL for pConfig * to use defaults. If passing config data, configSize should be * sizeof(S_JET_CONFIG). This allows for future expansion of the * config structure while maintaining compatibility. *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Init (EAS_DATA_HANDLE easHandle, const S_JET_CONFIG *pConfig, EAS_INT configSize); /*---------------------------------------------------------------------------- * JET_Shutdown() *---------------------------------------------------------------------------- * Frees any memory used by the JET library *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Shutdown (EAS_DATA_HANDLE easHandle); /*---------------------------------------------------------------------------- * JET_OpenFile() *---------------------------------------------------------------------------- * Opens a JET content file for playback *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_OpenFile (EAS_DATA_HANDLE easHandle, EAS_FILE_LOCATOR locator); /*---------------------------------------------------------------------------- * JET_GetAppData() *---------------------------------------------------------------------------- * Returns location and size of application data in the JET file *---------------------------------------------------------------------------- */ EAS_RESULT JET_GetAppData (EAS_DATA_HANDLE easHandle, EAS_I32 *pAppDataOffset, EAS_I32 *pAppDataSize); /*---------------------------------------------------------------------------- * JET_CloseFile() *---------------------------------------------------------------------------- * Closes a JET content file and releases associated resources *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_CloseFile (EAS_DATA_HANDLE easHandle); /*---------------------------------------------------------------------------- * JET_Status() *---------------------------------------------------------------------------- * Returns current status *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Status (EAS_DATA_HANDLE easHandle, S_JET_STATUS *pStatus); /*---------------------------------------------------------------------------- * JET_GetEvent() *---------------------------------------------------------------------------- * Checks for application events *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_BOOL JET_GetEvent (EAS_DATA_HANDLE easHandle, EAS_U32 *pEventRaw, S_JET_EVENT *pEvent); /*---------------------------------------------------------------------------- * JET_ParseEvent() *---------------------------------------------------------------------------- * Returns current status *---------------------------------------------------------------------------- */ EAS_PUBLIC void JET_ParseEvent (EAS_U32 event, S_JET_EVENT *pEvent); /*---------------------------------------------------------------------------- * JET_QueueSegment() *---------------------------------------------------------------------------- * Queue a segment for playback *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_QueueSegment (EAS_DATA_HANDLE easHandle, EAS_INT segmentNum, EAS_INT libNum, EAS_INT repeatCount, EAS_INT transpose, EAS_U32 muteFlags, EAS_U8 userID); /*---------------------------------------------------------------------------- * JET_Play() *---------------------------------------------------------------------------- * Starts playback of the file *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Play (EAS_DATA_HANDLE easHandle); /*---------------------------------------------------------------------------- * JET_Pause() *---------------------------------------------------------------------------- * Pauses playback of the file *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Pause (EAS_DATA_HANDLE easHandle); /*---------------------------------------------------------------------------- * JET_SetMuteFlags() *---------------------------------------------------------------------------- * Change the state of the mute flags *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_SetMuteFlags (EAS_DATA_HANDLE easHandle, EAS_U32 muteFlags, EAS_BOOL sync); /*---------------------------------------------------------------------------- * JET_SetMuteFlag() *---------------------------------------------------------------------------- * Change the state of a single mute flag *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_SetMuteFlag (EAS_DATA_HANDLE easHandle, EAS_INT trackNum, EAS_BOOL muteFlag, EAS_BOOL sync); /*---------------------------------------------------------------------------- * JET_TriggerClip() *---------------------------------------------------------------------------- * Unmute a track and then mute it when it is complete *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_TriggerClip (EAS_DATA_HANDLE easHandle, EAS_INT clipID); /*---------------------------------------------------------------------------- * JET_Clear_Queue() *---------------------------------------------------------------------------- * Clears all segments in the queue *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT JET_Clear_Queue (EAS_DATA_HANDLE easHandle); #ifdef __cplusplus } /* end extern "C" */ #endif #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_types.h0000644000000000000000000000013214200302440026455 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_types.h0000644000175000001440000001671514200302440027250 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_types.h * * Contents and purpose: * The public interface header for the EAS synthesizer. * * This header only contains declarations that are specific * to this implementation. * * DO NOT MODIFY THIS FILE! * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 726 $ * $Date: 2007-06-14 23:10:46 -0700 (Thu, 14 Jun 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_TYPES_H #define _EAS_TYPES_H /* EAS_RESULT return codes */ typedef long EAS_RESULT; #define EAS_SUCCESS 0 #define EAS_FAILURE -1 #define EAS_ERROR_INVALID_MODULE -2 #define EAS_ERROR_MALLOC_FAILED -3 #define EAS_ERROR_FILE_POS -4 #define EAS_ERROR_INVALID_FILE_MODE -5 #define EAS_ERROR_FILE_SEEK -6 #define EAS_ERROR_FILE_LENGTH -7 #define EAS_ERROR_NOT_IMPLEMENTED -8 #define EAS_ERROR_CLOSE_FAILED -9 #define EAS_ERROR_FILE_OPEN_FAILED -10 #define EAS_ERROR_INVALID_HANDLE -11 #define EAS_ERROR_NO_MIX_BUFFER -12 #define EAS_ERROR_PARAMETER_RANGE -13 #define EAS_ERROR_MAX_FILES_OPEN -14 #define EAS_ERROR_UNRECOGNIZED_FORMAT -15 #define EAS_BUFFER_SIZE_MISMATCH -16 #define EAS_ERROR_FILE_FORMAT -17 #define EAS_ERROR_SMF_NOT_INITIALIZED -18 #define EAS_ERROR_LOCATE_BEYOND_END -19 #define EAS_ERROR_INVALID_PCM_TYPE -20 #define EAS_ERROR_MAX_PCM_STREAMS -21 #define EAS_ERROR_NO_VOICE_ALLOCATED -22 #define EAS_ERROR_INVALID_CHANNEL -23 #define EAS_ERROR_ALREADY_STOPPED -24 #define EAS_ERROR_FILE_READ_FAILED -25 #define EAS_ERROR_HANDLE_INTEGRITY -26 #define EAS_ERROR_MAX_STREAMS_OPEN -27 #define EAS_ERROR_INVALID_PARAMETER -28 #define EAS_ERROR_FEATURE_NOT_AVAILABLE -29 #define EAS_ERROR_SOUND_LIBRARY -30 #define EAS_ERROR_NOT_VALID_IN_THIS_STATE -31 #define EAS_ERROR_NO_VIRTUAL_SYNTHESIZER -32 #define EAS_ERROR_FILE_ALREADY_OPEN -33 #define EAS_ERROR_FILE_ALREADY_CLOSED -34 #define EAS_ERROR_INCOMPATIBLE_VERSION -35 #define EAS_ERROR_QUEUE_IS_FULL -36 #define EAS_ERROR_QUEUE_IS_EMPTY -37 #define EAS_ERROR_FEATURE_ALREADY_ACTIVE -38 /* special return codes */ #define EAS_EOF 3 #define EAS_STREAM_BUFFERING 4 #define EAS_BUFFER_FULL 5 /* EAS_STATE return codes */ typedef long EAS_STATE; typedef enum { EAS_STATE_READY = 0, EAS_STATE_PLAY, EAS_STATE_STOPPING, EAS_STATE_PAUSING, EAS_STATE_STOPPED, EAS_STATE_PAUSED, EAS_STATE_OPEN, EAS_STATE_ERROR, EAS_STATE_EMPTY } E_EAS_STATE; /* constants */ #ifndef EAS_CONST #define EAS_CONST const #endif /* definition for public interface functions */ #ifndef EAS_PUBLIC #define EAS_PUBLIC #endif /* boolean values */ typedef unsigned EAS_BOOL; typedef unsigned char EAS_BOOL8; #define EAS_FALSE 0 #define EAS_TRUE 1 /* scalar variable definitions */ typedef unsigned char EAS_U8; typedef signed char EAS_I8; typedef char EAS_CHAR; typedef unsigned short EAS_U16; typedef short EAS_I16; typedef unsigned long EAS_U32; typedef long EAS_I32; typedef unsigned EAS_UINT; typedef int EAS_INT; typedef long EAS_LONG; /* audio output type */ typedef short EAS_PCM; /* file open modes */ typedef EAS_I32 EAS_FILE_MODE; #define EAS_FILE_READ 1 #define EAS_FILE_WRITE 2 /* file locator e.g. filename or memory pointer */ typedef struct s_eas_file_tag { void *handle; int(*readAt)(void *handle, void *buf, int offset, int size); int(*size)(void *handle); } EAS_FILE, *EAS_FILE_LOCATOR; /* handle to stream */ typedef struct s_eas_stream_tag *EAS_HANDLE; /* handle to file */ typedef struct eas_hw_file_tag *EAS_FILE_HANDLE; /* handle for synthesizer data */ typedef struct s_eas_data_tag *EAS_DATA_HANDLE; /* handle to persistent data for host wrapper interface */ typedef struct eas_hw_inst_data_tag *EAS_HW_DATA_HANDLE; /* handle to sound library */ typedef struct s_eas_sndlib_tag *EAS_SNDLIB_HANDLE; typedef struct s_eas_dls_tag *EAS_DLSLIB_HANDLE; /* pointer to frame buffer - used in split architecture only */ typedef struct s_eas_frame_buffer_tag *EAS_FRAME_BUFFER_HANDLE; /* untyped pointer for instance data */ typedef void *EAS_VOID_PTR; /* inline functions */ #ifndef EAS_INLINE #if defined (__XCC__) #define EAS_INLINE __inline__ #elif defined (__GNUC__) #define EAS_INLINE inline static #else #define EAS_INLINE __inline #endif #endif /* define NULL value */ #ifndef NULL #define NULL 0 #endif /* metadata types for metadata return codes */ typedef enum { EAS_METADATA_UNKNOWN = 0, EAS_METADATA_TITLE, EAS_METADATA_AUTHOR, EAS_METADATA_COPYRIGHT, EAS_METADATA_LYRIC, EAS_METADATA_TEXT } E_EAS_METADATA_TYPE; /* metadata callback function */ typedef void (*EAS_METADATA_CBFUNC) (E_EAS_METADATA_TYPE metaDataType, char *metaDataBuf, EAS_VOID_PTR pUserData); /* file types for metadata return codes */ typedef enum { EAS_FILE_UNKNOWN = 0, EAS_FILE_SMF0, EAS_FILE_SMF1, EAS_FILE_SMAF_UNKNOWN, EAS_FILE_SMAF_MA2, EAS_FILE_SMAF_MA3, EAS_FILE_SMAF_MA5, EAS_FILE_CMX, EAS_FILE_MFI, EAS_FILE_OTA, EAS_FILE_IMELODY, EAS_FILE_RTTTL, EAS_FILE_XMF0, EAS_FILE_XMF1, EAS_FILE_WAVE_PCM, EAS_FILE_WAVE_IMA_ADPCM, EAS_FILE_MMAPI_TONE_CONTROL } E_EAS_FILE_TYPE; /* enumeration for synthesizers */ typedef enum { EAS_MCU_SYNTH = 0, EAS_DSP_SYNTH } E_SYNTHESIZER; /* external audio callback program change */ typedef struct s_ext_audio_prg_chg_tag { EAS_U16 bank; EAS_U8 program; EAS_U8 channel; } S_EXT_AUDIO_PRG_CHG; /* external audio callback event */ typedef struct s_ext_audio_event_tag { EAS_U8 channel; EAS_U8 note; EAS_U8 velocity; EAS_BOOL8 noteOn; } S_EXT_AUDIO_EVENT; typedef struct s_midi_controllers_tag { EAS_U8 modWheel; /* CC1 */ EAS_U8 volume; /* CC7 */ EAS_U8 pan; /* CC10 */ EAS_U8 expression; /* CC11 */ EAS_U8 channelPressure; /* MIDI channel pressure */ #ifdef _REVERB EAS_U8 reverbSend; /* CC91 */ #endif #ifdef _CHORUS EAS_U8 chorusSend; /* CC93 */ #endif } S_MIDI_CONTROLLERS; /* iMode play modes enumeration for EAS_SetPlayMode */ typedef enum { IMODE_PLAY_ALL = 0, IMODE_PLAY_PARTIAL } E_I_MODE_PLAY_MODE; typedef EAS_BOOL (*EAS_EXT_PRG_CHG_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_PRG_CHG *pPrgChg); typedef EAS_BOOL (*EAS_EXT_EVENT_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_EVENT *pEvent); #endif /* #ifndef _EAS_TYPES_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_wave.c0000644000000000000000000000013214200302440026246 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_wave.c0000644000175000001440000002565114200302440027040 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_wave.c * * Contents and purpose: * This module contains .WAV file functions for the EAS synthesizer * test harness. * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *---------------------------------------------------------------------------- * Revision Control: * $Revision: 658 $ * $Date: 2007-04-24 13:35:49 -0700 (Tue, 24 Apr 2007) $ *---------------------------------------------------------------------------- */ /* lint complaints about most C library headers, so we use our own during lint step */ #ifdef _lint #include "lint_stdlib.h" #else #include #include #endif #include "eas_wave.h" /* .WAV file format tags */ const EAS_U32 riffTag = 0x46464952; const EAS_U32 waveTag = 0x45564157; const EAS_U32 fmtTag = 0x20746d66; const EAS_U32 dataTag = 0x61746164; #ifdef _BIG_ENDIAN /*---------------------------------------------------------------------------- * FlipDWord() *---------------------------------------------------------------------------- * Purpose: Endian flip a DWORD for big-endian processors * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static void FlipDWord (EAS_U32 *pValue) { EAS_U8 *p; EAS_U32 temp; p = (EAS_U8*) pValue; temp = (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0]; *pValue = temp; } /*---------------------------------------------------------------------------- * FlipWord() *---------------------------------------------------------------------------- * Purpose: Endian flip a WORD for big-endian processors * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static void FlipWord (EAS_U16 *pValue) { EAS_U8 *p; EAS_U16 temp; p = (EAS_U8*) pValue; temp = (p[1] << 8) | p[0]; *pValue = temp; } /*---------------------------------------------------------------------------- * FlipWaveHeader() *---------------------------------------------------------------------------- * Purpose: Endian flip the wave header for big-endian processors * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static void FlipWaveHeader (WAVE_HEADER *p) { FlipDWord(&p->nRiffTag); FlipDWord(&p->nRiffSize); FlipDWord(&p->nWaveTag); FlipDWord(&p->nFmtTag); FlipDWord(&p->nFmtSize); FlipDWord(&p->nDataTag); FlipDWord(&p->nDataSize); FlipWord(&p->fc.wFormatTag); FlipWord(&p->fc.nChannels); FlipDWord(&p->fc.nSamplesPerSec); FlipDWord(&p->fc.nAvgBytesPerSec); FlipWord(&p->fc.nBlockAlign); FlipWord(&p->fc.wBitsPerSample); } #endif /*---------------------------------------------------------------------------- * WaveFileCreate() *---------------------------------------------------------------------------- * Purpose: Opens a wave file for writing and writes the header * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample) { WAVE_FILE *wFile; /* allocate memory */ wFile = malloc(sizeof(WAVE_FILE)); if (!wFile) return NULL; wFile->write = EAS_TRUE; /* create the file */ wFile->file = fopen(filename,"wb"); if (!wFile->file) { free(wFile); return NULL; } /* initialize PCM format .WAV file header */ wFile->wh.nRiffTag = riffTag; wFile->wh.nRiffSize = sizeof(WAVE_HEADER) - 8; wFile->wh.nWaveTag = waveTag; wFile->wh.nFmtTag = fmtTag; wFile->wh.nFmtSize = sizeof(FMT_CHUNK); /* initalize 'fmt' chunk */ wFile->wh.fc.wFormatTag = 1; wFile->wh.fc.nChannels = (EAS_U16) nChannels; wFile->wh.fc.nSamplesPerSec = (EAS_U32) nSamplesPerSec; wFile->wh.fc.wBitsPerSample = (EAS_U16) wBitsPerSample; wFile->wh.fc.nBlockAlign = (EAS_U16) (nChannels * (EAS_U16) (wBitsPerSample / 8)); wFile->wh.fc.nAvgBytesPerSec = wFile->wh.fc.nBlockAlign * (EAS_U32) nSamplesPerSec; /* initialize 'data' chunk */ wFile->wh.nDataTag = dataTag; wFile->wh.nDataSize = 0; #ifdef _BIG_ENDIAN FlipWaveHeader(&wFile->wh); #endif /* write the header */ if (fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file) != 1) { fclose(wFile->file); free(wFile); return NULL; } #ifdef _BIG_ENDIAN FlipWaveHeader(&wFile->wh); #endif /* return the file handle */ return wFile; } /* end WaveFileCreate */ /*---------------------------------------------------------------------------- * WaveFileWrite() *---------------------------------------------------------------------------- * Purpose: Writes data to the wave file * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n) { EAS_I32 count; /* make sure we have an open file */ if (wFile == NULL) { return 0; } #ifdef _BIG_ENDIAN { EAS_I32 i; EAS_U16 *p; p = buffer; i = n >> 1; while (i--) FlipWord(p++); } #endif /* write the data */ count = (EAS_I32) fwrite(buffer, 1, (size_t) n, wFile->file); /* add the number of bytes written */ wFile->wh.nRiffSize += (EAS_U32) count; wFile->wh.nDataSize += (EAS_U32) count; /* return the count of bytes written */ return count; } /* end WriteWaveHeader */ /*---------------------------------------------------------------------------- * WaveFileClose() *---------------------------------------------------------------------------- * Purpose: Opens a wave file for writing and writes the header * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ EAS_BOOL WaveFileClose (WAVE_FILE *wFile) { EAS_I32 count = 1; /* return to beginning of file and write the header */ if (wFile->write) { if (fseek(wFile->file, 0L, SEEK_SET) == 0) { #ifdef _BIG_ENDIAN FlipWaveHeader(&wFile->wh); #endif count = (EAS_I32) fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file); #ifdef _BIG_ENDIAN FlipWaveHeader(&wFile->wh); #endif } } /* close the file */ if (fclose(wFile->file) != 0) count = 0; /* free the memory */ free(wFile); /* return the file handle */ return (count == 1 ? EAS_TRUE : EAS_FALSE); } /* end WaveFileClose */ #ifdef _WAVE_FILE_READ #ifdef _BIG_ENDIAN #error "WaveFileOpen not currently supported on big-endian processors" #endif /*---------------------------------------------------------------------------- * WaveFileOpen() *---------------------------------------------------------------------------- * Purpose: Opens a wave file for reading and reads the header * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ WAVE_FILE *WaveFileOpen (const char *filename) { WAVE_FILE *wFile; struct { EAS_U32 tag; EAS_U32 size; } chunk; EAS_U32 tag; EAS_I32 startChunkPos; EAS_INT state; EAS_BOOL done; /* allocate memory */ wFile = malloc(sizeof(WAVE_FILE)); if (!wFile) return NULL; /* open the file */ wFile->write = EAS_FALSE; wFile->file = fopen(filename,"rb"); if (!wFile->file) { free(wFile); return NULL; } /* make lint happy */ chunk.tag = chunk.size = 0; startChunkPos = 0; /* read the RIFF tag and file size */ state = 0; done = EAS_FALSE; while (!done) { switch(state) { /* read the RIFF tag */ case 0: if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1) done = EAS_TRUE; else { if (chunk.tag != riffTag) done = EAS_TRUE; else state++; } break; /* read the WAVE tag */ case 1: if (fread(&tag, sizeof(tag), 1, wFile->file) != 1) done = EAS_TRUE; else { if (tag != waveTag) done = EAS_TRUE; else state++; } break; /* looking for fmt chunk */ case 2: if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1) done = EAS_TRUE; else { startChunkPos = ftell(wFile->file); /* not fmt tag, skip it */ if (chunk.tag != fmtTag) fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET); else state++; } break; /* read fmt chunk */ case 3: if (fread(&wFile->wh.fc, sizeof(FMT_CHUNK), 1, wFile->file) != 1) done = EAS_TRUE; else { fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET); state++; } break; /* looking for data chunk */ case 4: if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1) done = EAS_TRUE; else { startChunkPos = ftell(wFile->file); /* not data tag, skip it */ if (chunk.tag != dataTag) fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET); else { wFile->dataSize = chunk.size; state++; done = EAS_TRUE; } } break; default: done = EAS_TRUE; break; } } /* if not final state, an error occurred */ if (state != 5) { fclose(wFile->file); free(wFile); return NULL; } /* return the file handle */ return wFile; } /* end WaveFileOpen */ #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_main.c0000644000000000000000000000013214200302440026230 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.357324521 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_main.c0000644000175000001440000003620514200302440027017 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_main.c * * Contents and purpose: * The entry point and high-level functions for the EAS Synthesizer test * harness. * * Copyright Sonic Network Inc. 2004 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 775 $ * $Date: 2007-07-20 10:11:11 -0700 (Fri, 20 Jul 2007) $ *---------------------------------------------------------------------------- */ #ifdef _lint #include "lint_stdlib.h" #else #include #include #include #include #endif #include "eas.h" #include "eas_wave.h" #include "eas_report.h" /* determines how many EAS buffers to fill a host buffer */ #define NUM_BUFFERS 8 /* default file to play if no filename is specified on the command line */ static const char defaultTestFile[] = "test.mid"; EAS_I32 polyphony; /* prototypes for helper functions */ static void StrCopy(char *dest, const char *src, EAS_I32 size); static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size); static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize); static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig); /* main is defined after playfile to avoid the need for two passes through lint */ /*---------------------------------------------------------------------------- * PlayFile() *---------------------------------------------------------------------------- * Purpose: * This function plays the file requested by filename * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize) { EAS_HANDLE handle; EAS_RESULT result, reportResult; EAS_I32 count; EAS_STATE state; EAS_I32 playTime; char waveFilename[256]; WAVE_FILE *wFile; EAS_INT i; EAS_PCM *p; EAS_FILE file; /* determine the name of the output file */ wFile = NULL; if (outputFile == NULL) { StrCopy(waveFilename, filename, sizeof(waveFilename)); if (!ChangeFileExt(waveFilename, "wav", sizeof(waveFilename))) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error in output filename %s\n", waveFilename); */ } return EAS_FAILURE; } outputFile = waveFilename; } /* call EAS library to open file */ file.path = filename; file.fd = 0; if ((reportResult = EAS_OpenFile(easData, &file, &handle)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_OpenFile returned %ld\n", reportResult); */ } return reportResult; } /* prepare to play the file */ if ((result = EAS_Prepare(easData, handle)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Prepare returned %ld\n", result); */ } reportResult = result; } /* get play length */ if ((result = EAS_ParseMetaData(easData, handle, &playTime)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_ParseMetaData returned %ld\n", result); */ } return result; } EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0xe624f4d9, 0x00000005 , playTime / 1000, playTime % 1000); if (reportResult == EAS_SUCCESS) { /* create the output file */ wFile = WaveFileCreate(outputFile, pLibConfig->numChannels, pLibConfig->sampleRate, sizeof(EAS_PCM) * 8); if (!wFile) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to create output file %s\n", waveFilename); */ } reportResult = EAS_FAILURE; } } /* rendering loop */ while (reportResult == EAS_SUCCESS) { /* we may render several buffers here to fill one host buffer */ for (i = 0, p = buffer; i < NUM_BUFFERS; i++, p+= pLibConfig->mixBufferSize * pLibConfig->numChannels) { /* get the current time */ if ((result = EAS_GetLocation(easData, handle, &playTime)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_GetLocation returned %d\n",result); */ } if (reportResult == EAS_SUCCESS) reportResult = result; break; } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Parser time: %d.%03d\n", playTime / 1000, playTime % 1000); */ } /* render a buffer of audio */ if ((result = EAS_Render(easData, p, pLibConfig->mixBufferSize, &count)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Render returned %d\n",result); */ } if (reportResult == EAS_SUCCESS) reportResult = result; } } if (result == EAS_SUCCESS) { /* write it to the wave file */ if (WaveFileWrite(wFile, buffer, bufferSize) != bufferSize) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "WaveFileWrite failed\n"); */ } reportResult = EAS_FAILURE; } } if (reportResult == EAS_SUCCESS) { /* check stream state */ if ((result = EAS_State(easData, handle, &state)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_State returned %d\n", result); */ } reportResult = result; } /* is playback complete */ if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR)) break; } } /* close the output file */ if (wFile) { if (!WaveFileClose(wFile)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error closing wave file %s\n", waveFilename); */ } if (reportResult == EAS_SUCCESS) result = EAS_FAILURE; } } /* close the input file */ if ((result = EAS_CloseFile(easData,handle)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Close returned %ld\n", result); */ } if (reportResult == EAS_SUCCESS) result = EAS_FAILURE; } return reportResult; } /* end PlayFile */ /*---------------------------------------------------------------------------- * main() *---------------------------------------------------------------------------- * Purpose: The entry point for the EAS sample application * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ int main( int argc, char **argv ) { EAS_DATA_HANDLE easData; const S_EAS_LIB_CONFIG *pLibConfig; void *buffer; EAS_RESULT result, playResult; EAS_I32 bufferSize; int i; int temp; FILE *debugFile; char *outputFile = NULL; /* set the error reporting level */ EAS_SetDebugLevel(_EAS_SEVERITY_INFO); debugFile = NULL; /* process command-line arguments */ for (i = 1; i < argc; i++) { /* check for switch */ if (argv[i][0] == '-') { switch (argv[i][1]) { case 'd': temp = argv[i][2]; if ((temp >= '0') || (temp <= '9')) EAS_SetDebugLevel(temp); else { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid debug level %d\n", temp); */ } break; case 'f': if ((debugFile = fopen(&argv[i][2],"w")) == NULL) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unable to create debug file %s\n", &argv[i][2]); */ } else EAS_SetDebugFile(debugFile, EAS_TRUE); break; case 'o': outputFile = &argv[i][2]; break; case 'p': polyphony = atoi(&argv[i][2]); if (polyphony < 1) polyphony = 1; { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Polyphony set to %d\n", polyphony); */ } break; default: break; } continue; } } /* assume success */ playResult = EAS_SUCCESS; /* get the library configuration */ pLibConfig = EAS_Config(); if (!EASLibraryCheck(pLibConfig)) return -1; if (polyphony > pLibConfig->maxVoices) polyphony = pLibConfig->maxVoices; /* calculate buffer size */ bufferSize = pLibConfig->mixBufferSize * pLibConfig->numChannels * (EAS_I32)sizeof(EAS_PCM) * NUM_BUFFERS; /* allocate output buffer memory */ buffer = malloc((EAS_U32)bufferSize); if (!buffer) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Error allocating memory for audio buffer\n"); */ } return EAS_FAILURE; } /* initialize the EAS library */ polyphony = pLibConfig->maxVoices; if ((result = EAS_Init(&easData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Init returned %ld - aborting!\n", result); */ } free(buffer); return result; } /* * Some debugging environments don't allow for passed parameters. * In this case, just play the default MIDI file "test.mid" */ if (argc < 2) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", defaultTestFile); */ } if ((playResult = PlayFile(easData, defaultTestFile, NULL, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, defaultTestFile); */ } } } /* iterate through the list of files to be played */ else { for (i = 1; i < argc; i++) { /* check for switch */ if (argv[i][0] != '-') { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", argv[i]); */ } if ((playResult = PlayFile(easData, argv[i], outputFile, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, argv[i]); */ } break; } } } } /* shutdown the EAS library */ if ((result = EAS_Shutdown(easData)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Shutdown returned %ld\n", result); */ } } /* free the output buffer */ free(buffer); /* close the debug file */ if (debugFile) fclose(debugFile); /* play errors take precedence over shutdown errors */ if (playResult != EAS_SUCCESS) return playResult; return result; } /* end main */ /*---------------------------------------------------------------------------- * StrCopy() *---------------------------------------------------------------------------- * Purpose: * Safe string copy * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static void StrCopy(char *dest, const char *src, EAS_I32 size) { int len; strncpy(dest, src, (size_t) size-1); len = (int) strlen(src); if (len < size) dest[len] = 0; } /* end StrCopy */ /*---------------------------------------------------------------------------- * ChangeFileExt() *---------------------------------------------------------------------------- * Purpose: * Changes the file extension of a filename * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size) { char *p; /* find the extension, if any */ p = strrchr(str,'.'); if (!p) { if ((EAS_I32)(strlen(str) + 5) > size) return EAS_FALSE; strcat(str,"."); strcat(str,ext); return EAS_TRUE; } /* make sure there's room for the extension */ p++; *p = 0; if ((EAS_I32)(strlen(str) + 4) > size) return EAS_FALSE; strcat(str,ext); return EAS_TRUE; } /* end ChangeFileExt */ /*---------------------------------------------------------------------------- * EASLibraryCheck() *---------------------------------------------------------------------------- * Purpose: * Displays the library version and checks it against the header * file used to build this code. * * Inputs: * pLibConfig - library configuration retrieved from the library * * Outputs: * returns EAS_TRUE if matched * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig) { /* display the library version */ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "EAS Library Version %d.%d.%d.%d\n", pLibConfig->libVersion >> 24, (pLibConfig->libVersion >> 16) & 0x0f, (pLibConfig->libVersion >> 8) & 0x0f, pLibConfig->libVersion & 0x0f); */ } /* display some info about the library build */ if (pLibConfig->checkedVersion) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tChecked library\n"); */ } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMaximum polyphony: %d\n", pLibConfig->maxVoices); */ } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tNumber of channels: %d\n", pLibConfig->numChannels); */ } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tSample rate: %d\n", pLibConfig->sampleRate); */ } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMix buffer size: %d\n", pLibConfig->mixBufferSize); */ } if (pLibConfig->filterEnabled) { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tFilter enabled\n"); */ } #ifndef _WIN32_WCE { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build Timestamp: %s", ctime((time_t*)&pLibConfig->buildTimeStamp)); */ } #endif { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build ID: %s\n", pLibConfig->buildGUID); */ } /* check it against the header file used to build this code */ /*lint -e{778} constant expression used for display purposes may evaluate to zero */ if (LIB_VERSION != pLibConfig->libVersion) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Library version does not match header files. EAS Header Version %d.%d.%d.%d\n", LIB_VERSION >> 24, (LIB_VERSION >> 16) & 0x0f, (LIB_VERSION >> 8) & 0x0f, LIB_VERSION & 0x0f); */ } return EAS_FALSE; } return EAS_TRUE; } /* end EASLibraryCheck */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_wave.h0000644000000000000000000000013214200302440026253 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.357324521 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_wave.h0000644000175000001440000000372714200302440027045 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_wave.h * * Contents and purpose: * Writes output to a .WAV file * * DO NOT MODIFY THIS FILE! * * Copyright Sonic Network Inc. 2005 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ #include "eas_types.h" /* sentinel */ #ifndef _EAS_WAVE_H #define _EAS_WAVE_H /* .WAV file format chunk */ typedef struct { EAS_U16 wFormatTag; EAS_U16 nChannels; EAS_U32 nSamplesPerSec; EAS_U32 nAvgBytesPerSec; EAS_U16 nBlockAlign; EAS_U16 wBitsPerSample; } FMT_CHUNK; /* .WAV file header */ typedef struct { EAS_U32 nRiffTag; EAS_U32 nRiffSize; EAS_U32 nWaveTag; EAS_U32 nFmtTag; EAS_U32 nFmtSize; FMT_CHUNK fc; EAS_U32 nDataTag; EAS_U32 nDataSize; } WAVE_HEADER; typedef struct { WAVE_HEADER wh; FILE *file; EAS_BOOL write; EAS_U32 dataSize; } WAVE_FILE; WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample); EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n); EAS_BOOL WaveFileClose (WAVE_FILE *wFile); WAVE_FILE *WaveFileOpen (const char *filename); #endif /* end #ifndef _EAS_WAVE_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_debugmsgs.h0000644000000000000000000000013214200302440027271 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_debugmsgs.h0000644000175000001440000001272314200302440030057 0ustar00pedrousers00000000000000/* Auto-generated from source file: eas_chorusdata.c */ /* Auto-generated from source file: eas_xmfdata.c */ /* Auto-generated from source file: eas_mdls.c */ { 0x19299ed4, 0x00000022, "eas_mdls.c[2561]: #Instruments: %u\n" }, { 0x19299ed4, 0x00000023, "eas_mdls.c[2562]: #Regions: %u\n" }, { 0x19299ed4, 0x00000024, "eas_mdls.c[2563]: #Articulations: %u\n" }, { 0x19299ed4, 0x00000025, "eas_mdls.c[2564]: #Waves: %u\n" }, { 0x19299ed4, 0x00000026, "eas_mdls.c[2569]: Locale: %lu:%lu:%lu\n" }, { 0x19299ed4, 0x00000027, "eas_mdls.c[2576]: \tRegion: %u\n" }, { 0x19299ed4, 0x00000028, "eas_mdls.c[2578]: \t\tm_nGain: %d\n" }, { 0x19299ed4, 0x00000029, "eas_mdls.c[2579]: \t\trangeLow:rangeHigh %u:%u\n" }, { 0x19299ed4, 0x0000002a, "eas_mdls.c[2580]: \t\tm_nKeyGroupAndFlags: %04x\n" }, { 0x19299ed4, 0x0000002b, "eas_mdls.c[2581]: \t\tm_nLoopStart: %u\n" }, { 0x19299ed4, 0x0000002c, "eas_mdls.c[2582]: \t\tm_nLoopEnd: %u\n" }, { 0x19299ed4, 0x0000002d, "eas_mdls.c[2583]: \t\tm_nNetTuningInCents: %d\n" }, { 0x19299ed4, 0x0000002e, "eas_mdls.c[2584]: \t\tArt Index: %u\n" }, { 0x19299ed4, 0x0000002f, "eas_mdls.c[2585]: \t\tWave Index: %u\n" }, { 0x19299ed4, 0x00000030, "eas_mdls.c[2597]: Articulation: %u\n" }, { 0x19299ed4, 0x00000031, "eas_mdls.c[2599]: \t\tm_nEG2toFilterDepth: %d\n" }, { 0x19299ed4, 0x00000032, "eas_mdls.c[2600]: \t\tm_nEG2toPitchDepth: %d\n" }, { 0x19299ed4, 0x00000033, "eas_mdls.c[2601]: \t\tm_nFilterCutoffFrequency: %d\n" }, { 0x19299ed4, 0x00000034, "eas_mdls.c[2602]: \t\tm_nFilterResonance: %u\n" }, { 0x19299ed4, 0x00000035, "eas_mdls.c[2603]: \t\tm_nLFOAmplitudeDepth: %d\n" }, { 0x19299ed4, 0x00000036, "eas_mdls.c[2604]: \t\tm_nLFODelayTime: %d\n" }, { 0x19299ed4, 0x00000037, "eas_mdls.c[2605]: \t\tm_nLFOFrequency: %d\n" }, { 0x19299ed4, 0x00000038, "eas_mdls.c[2606]: \t\tm_nLFOPitchDepth: %d\n" }, { 0x19299ed4, 0x00000039, "eas_mdls.c[2607]: \t\tm_nPan: %d\n" }, { 0x19299ed4, 0x0000003a, "eas_mdls.c[2610]: \t\tm_nAttack: %d\n" }, { 0x19299ed4, 0x0000003b, "eas_mdls.c[2611]: \t\tm_nDecay: %d\n" }, { 0x19299ed4, 0x0000003c, "eas_mdls.c[2612]: \t\tm_nSustain: %d\n" }, { 0x19299ed4, 0x0000003d, "eas_mdls.c[2613]: \t\tm_nRelease: %d\n" }, { 0x19299ed4, 0x0000003e, "eas_mdls.c[2616]: \t\tm_nAttack: %d\n" }, { 0x19299ed4, 0x0000003f, "eas_mdls.c[2617]: \t\tm_nDecay: %d\n" }, { 0x19299ed4, 0x00000040, "eas_mdls.c[2618]: \t\tm_nSustain: %d\n" }, { 0x19299ed4, 0x00000041, "eas_mdls.c[2619]: \t\tm_nRelease: %d\n" }, { 0x19299ed4, 0x00000042, "eas_mdls.c[2626]: Wave Index: %d\n" }, { 0x19299ed4, 0x00000043, "eas_mdls.c[2627]: \tSize %u\n" }, { 0x19299ed4, 0x00000044, "eas_mdls.c[2628]: \tPointer %08lx\n" }, /* Auto-generated from source file: eas_mididata.c */ /* Auto-generated from source file: eas_pan.c */ /* Auto-generated from source file: eas_wavefiledata.c */ /* Auto-generated from source file: eas_reverbdata.c */ /* Auto-generated from source file: eas_imelodydata.c */ /* Auto-generated from source file: eas_ota.c */ /* Auto-generated from source file: eas_mixbuf.c */ /* Auto-generated from source file: eas_tcdata.c */ /* Auto-generated from source file: jet.c */ /* Auto-generated from source file: eas_rtttl.c */ /* Auto-generated from source file: eas_reverb.c */ /* Auto-generated from source file: eas_pcmdata.c */ /* Auto-generated from source file: eas_chorus.c */ /* Auto-generated from source file: eas_math.c */ /* Auto-generated from source file: eas_xmf.c */ /* Auto-generated from source file: eas_smfdata.c */ /* Auto-generated from source file: eas_imelody.c */ /* Auto-generated from source file: eas_dlssynth.c */ /* Auto-generated from source file: eas_public.c */ /* Auto-generated from source file: eas_rtttldata.c */ /* Auto-generated from source file: eas_voicemgt.c */ /* Auto-generated from source file: eas_tonecontrol.c */ /* Auto-generated from source file: eas_wtengine.c */ /* Auto-generated from source file: eas_imaadpcm.c */ { 0x2380b977, 0x00000006, "eas_imaadpcm.c[305]: IMADecoderLocate: Time=%d, samples=%d\n" }, { 0x2380b977, 0x00000007, "eas_imaadpcm.c[328]: IMADecoderLocate: Looped sample, numBlocks=%d, samplesPerLoop=%d, samplesInLastBlock=%d, samples=%d\n" }, { 0x2380b977, 0x00000008, "eas_imaadpcm.c[335]: IMADecoderLocate: Byte location in audio = %d\n" }, { 0x2380b977, 0x00000009, "eas_imaadpcm.c[345]: IMADecoderLocate: bytesLeft = %d\n" }, /* Auto-generated from source file: eas_flog.c */ /* Auto-generated from source file: eas_midi.c */ /* Auto-generated from source file: eas_otadata.c */ /* Auto-generated from source file: eas_ima_tables.c */ /* Auto-generated from source file: eas_data.c */ /* Auto-generated from source file: eas_pcm.c */ /* Auto-generated from source file: eas_mixer.c */ /* Auto-generated from source file: eas_wavefile.c */ /* Auto-generated from source file: eas_wtsynth.c */ /* Auto-generated from source file: eas_smf.c */ /* Auto-generated from source file: eas_wave.c */ /* Auto-generated from source file: eas_hostmm.c */ { 0x1a54b6e8, 0x00000001, "eas_hostmm.c[586]: Vibrate state: %d\n" }, { 0x1a54b6e8, 0x00000002, "eas_hostmm.c[601]: LED state: %d\n" }, { 0x1a54b6e8, 0x00000003, "eas_hostmm.c[616]: Backlight state: %d\n" }, { 0x1a54b6e8, 0x00000004, "eas_hostmm.c[162]: HWMemCpy: bad amount: %d\n" }, { 0x1a54b6e8, 0x00000005, "eas_hostmm.c[179]: HWMemSet: bad amount: %d\n" }, { 0x1a54b6e8, 0x00000006, "eas_hostmm.c[196]: HWMemCmp: bad amount: %d\n" }, /* Auto-generated from source file: eas_config.c */ /* Auto-generated from source file: eas_main.c */ { 0xe624f4d9, 0x00000005, "eas_main.c[106]: Play length: %d.%03d (secs)\n" }, drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_config.c0000644000000000000000000000013214200302440026551 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_config.c0000644000175000001440000004031314200302440027333 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_config.c * * Contents and purpose: * This file contains the Configuration Module interface (CM). The CM * is a module compiled external to the library that sets the configuration * for this build. It allows the library to find optional components and * links to static memory allocations (when used in a static configuration). * * DO NOT MODIFY THIS FILE! * * NOTE: This module is not intended to be modified by the customer. It * needs to be included in the build process with the correct configuration * defines (see the library documentation for information on how to configure * the library). * * Copyright Sonic Network Inc. 2004-2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 796 $ * $Date: 2007-08-01 00:15:25 -0700 (Wed, 01 Aug 2007) $ *---------------------------------------------------------------------------- */ #include "eas.h" #include "eas_config.h" #ifdef _MFI_PARSER /*---------------------------------------------------------------------------- * Vendor/Device ID for MFi Extensions * * Define the preprocessor symbols to establish the vendor ID and * device ID for the MFi PCM/ADPCM extensions. *---------------------------------------------------------------------------- */ const EAS_U8 eas_MFIVendorIDMSB = (MFI_VENDOR_ID >> 8) & 0xff; const EAS_U8 eas_MFIVendorIDLSB = MFI_VENDOR_ID & 0xff; const EAS_U8 eas_MFIDeviceID = MFI_DEVICE_ID; #endif /*---------------------------------------------------------------------------- * * parserModules * * This structure is used by the EAS library to locate file parsing * modules. *---------------------------------------------------------------------------- */ /* define the external file parsers */ extern EAS_VOID_PTR EAS_SMF_Parser; #ifdef _XMF_PARSER extern EAS_VOID_PTR EAS_XMF_Parser; #endif #ifdef _SMAF_PARSER extern EAS_VOID_PTR EAS_SMAF_Parser; #endif #ifdef _WAVE_PARSER extern EAS_VOID_PTR EAS_Wave_Parser; #endif #ifdef _OTA_PARSER extern EAS_VOID_PTR EAS_OTA_Parser; #endif #ifdef _IMELODY_PARSER extern EAS_VOID_PTR EAS_iMelody_Parser; #endif #ifdef _RTTTL_PARSER extern EAS_VOID_PTR EAS_RTTTL_Parser; #endif #if defined (_CMX_PARSER) || defined(_MFI_PARSER) extern EAS_VOID_PTR EAS_CMF_Parser; #endif /* initalize pointers to parser interfaces */ /*lint -e{605} not pretty, but it works */ EAS_VOID_PTR const parserModules[] = { &EAS_SMF_Parser, #ifdef _XMF_PARSER &EAS_XMF_Parser, #endif #ifdef _WAVE_PARSER &EAS_Wave_Parser, #endif #ifdef _SMAF_PARSER &EAS_SMAF_Parser, #endif #ifdef _OTA_PARSER &EAS_OTA_Parser, #endif #ifdef _IMELODY_PARSER &EAS_iMelody_Parser, #endif #ifdef _RTTTL_PARSER &EAS_RTTTL_Parser, #endif #if defined (_CMX_PARSER) || defined(_MFI_PARSER) &EAS_CMF_Parser #endif }; #define NUM_PARSER_MODULES (sizeof(parserModules) / sizeof(EAS_VOID_PTR)) /*---------------------------------------------------------------------------- * Data Modules *---------------------------------------------------------------------------- */ #ifdef _STATIC_MEMORY extern EAS_VOID_PTR eas_SMFData; extern EAS_VOID_PTR eas_Data; extern EAS_VOID_PTR eas_MixBuffer; extern EAS_VOID_PTR eas_Synth; extern EAS_VOID_PTR eas_MIDI; extern EAS_VOID_PTR eas_PCMData; extern EAS_VOID_PTR eas_MIDIData; #ifdef _XMF_PARSER extern EAS_VOID_PTR eas_XMFData; #endif #ifdef _SMAF_PARSER extern EAS_VOID_PTR eas_SMAFData; #endif #ifdef _OTA_PARSER extern EAS_VOID_PTR eas_OTAData; #endif #ifdef _IMELODY_PARSER extern EAS_VOID_PTR eas_iMelodyData; #endif #ifdef _RTTTL_PARSER extern EAS_VOID_PTR eas_RTTTLData; #endif #ifdef _WAVE_PARSER extern EAS_VOID_PTR eas_WaveData; #endif #if defined (_CMX_PARSER) || defined(_MFI_PARSER) extern EAS_VOID_PTR eas_CMFData; #endif #endif /*---------------------------------------------------------------------------- * * Effects Modules * * These declarations are used by the EAS library to locate * effects modules. *---------------------------------------------------------------------------- */ #ifdef _ENHANCER_ENABLED extern EAS_VOID_PTR EAS_Enhancer; #define EAS_ENHANCER_INTERFACE &EAS_Enhancer #ifdef _STATIC_MEMORY extern EAS_VOID_PTR eas_EnhancerData; #define EAS_ENHANCER_DATA &eas_EnhancerData #else #define EAS_ENHANCER_DATA NULL #endif #else #define EAS_ENHANCER_INTERFACE NULL #define EAS_ENHANCER_DATA NULL #endif #ifdef _COMPRESSOR_ENABLED extern EAS_VOID_PTR EAS_Compressor; #define EAS_COMPRESSOR_INTERFACE &EAS_Compressor #ifdef _STATIC_MEMORY extern EAS_VOID_PTR eas_CompressorData; #define EAS_COMPRESSOR_DATA &eas_CompressorData #else #define EAS_COMPRESSOR_DATA NULL #endif #else #define EAS_COMPRESSOR_INTERFACE NULL #define EAS_COMPRESSOR_DATA NULL #endif #ifdef _MAXIMIZER_ENABLED extern EAS_VOID_PTR EAS_Maximizer; #define EAS_MAXIMIZER_INTERFACE &EAS_Maximizer #ifdef _STATIC_MEMORY extern EAS_VOID_PTR eas_MaximizerData; #define EAS_MAXIMIZER_DATA &eas_MaximizerData #else #define EAS_MAXIMIZER_DATA NULL #endif #else #define EAS_MAXIMIZER_INTERFACE NULL #define EAS_MAXIMIZER_DATA NULL #endif #ifdef _REVERB_ENABLED extern EAS_VOID_PTR EAS_Reverb; #define EAS_REVERB_INTERFACE &EAS_Reverb #ifdef _STATIC_MEMORY extern EAS_VOID_PTR eas_ReverbData; #define EAS_REVERB_DATA &eas_ReverbData #else #define EAS_REVERB_DATA NULL #endif #else #define EAS_REVERB_INTERFACE NULL #define EAS_REVERB_DATA NULL #endif #ifdef _CHORUS_ENABLED extern EAS_VOID_PTR EAS_Chorus; #define EAS_CHORUS_INTERFACE &EAS_Chorus #ifdef _STATIC_MEMORY extern EAS_VOID_PTR eas_ChorusData; #define EAS_CHORUS_DATA &eas_ChorusData #else #define EAS_CHORUS_DATA NULL #endif #else #define EAS_CHORUS_INTERFACE NULL #define EAS_CHORUS_DATA NULL #endif #ifdef _WIDENER_ENABLED extern EAS_VOID_PTR EAS_Widener; #define EAS_WIDENER_INTERFACE &EAS_Widener #ifdef _STATIC_MEMORY extern EAS_VOID_PTR eas_WidenerData; #define EAS_WIDENER_DATA &eas_WidenerData #else #define EAS_WIDENER_DATA NULL #endif #else #define EAS_WIDENER_INTERFACE NULL #define EAS_WIDENER_DATA NULL #endif #ifdef _GRAPHIC_EQ_ENABLED extern EAS_VOID_PTR EAS_GraphicEQ; #define EAS_GRAPHIC_EQ_INTERFACE &EAS_GraphicEQ #ifdef _STATIC_MEMORY extern EAS_VOID_PTR eas_GraphicEQData; #define EAS_GRAPHIC_EQ_DATA &eas_GraphicEQData #else #define EAS_GRAPHIC_EQ_DATA NULL #endif #else #define EAS_GRAPHIC_EQ_INTERFACE NULL #define EAS_GRAPHIC_EQ_DATA NULL #endif #ifdef _WOW_ENABLED extern EAS_VOID_PTR EAS_Wow; #define EAS_WOW_INTERFACE &EAS_Wow #ifdef _STATIC_MEMORY #error "WOW module requires dynamic memory model" #else #define EAS_WOW_DATA NULL #endif #else #define EAS_WOW_INTERFACE NULL #define EAS_WOW_DATA NULL #endif #ifdef _TONECONTROLEQ_ENABLED extern EAS_VOID_PTR EAS_ToneControlEQ; #define EAS_TONECONTROLEQ_INTERFACE &EAS_ToneControlEQ #ifdef _STATIC_MEMORY extern EAS_VOID_PTR eas_ToneControlEQData; #define EAS_TONECONTROLEQ_DATA &eas_ToneControlEQData #else #define EAS_TONECONTROLEQ_DATA NULL #endif #else #define EAS_TONECONTROLEQ_INTERFACE NULL #define EAS_TONECONTROLEQ_DATA NULL #endif /*lint -e{605} not pretty, but it works */ EAS_VOID_PTR const effectsModules[] = { EAS_ENHANCER_INTERFACE, EAS_COMPRESSOR_INTERFACE, EAS_REVERB_INTERFACE, EAS_CHORUS_INTERFACE, EAS_WIDENER_INTERFACE, EAS_GRAPHIC_EQ_INTERFACE, EAS_WOW_INTERFACE, EAS_MAXIMIZER_INTERFACE, EAS_TONECONTROLEQ_INTERFACE }; EAS_VOID_PTR const effectsData[] = { EAS_ENHANCER_DATA, EAS_COMPRESSOR_DATA, EAS_REVERB_DATA, EAS_CHORUS_DATA, EAS_WIDENER_DATA, EAS_GRAPHIC_EQ_DATA, EAS_WOW_DATA, EAS_MAXIMIZER_DATA, EAS_TONECONTROLEQ_DATA }; /*---------------------------------------------------------------------------- * * Optional Modules * * These declarations are used by the EAS library to locate * effects modules. *---------------------------------------------------------------------------- */ #ifdef _METRICS_ENABLED extern EAS_VOID_PTR EAS_Metrics; #define EAS_METRICS_INTERFACE &EAS_Metrics #ifdef _STATIC_MEMORY extern EAS_VOID_PTR eas_MetricsData; #define EAS_METRICS_DATA &eas_MetricsData #else #define EAS_METRICS_DATA NULL #endif #else #define EAS_METRICS_INTERFACE NULL #define EAS_METRICS_DATA NULL #endif #ifdef MMAPI_SUPPORT extern EAS_VOID_PTR EAS_TC_Parser; #define EAS_TONE_CONTROL_PARSER &EAS_TC_Parser #ifdef _STATIC_MEMORY extern EAS_VOID_PTR eas_TCData; #define EAS_TONE_CONTROL_DATA &eas_TCData #else #define EAS_TONE_CONTROL_DATA NULL #endif #else #define EAS_TONE_CONTROL_PARSER NULL #define EAS_TONE_CONTROL_DATA NULL #endif /*lint -e{605} not pretty, but it works */ EAS_VOID_PTR const optionalModules[] = { EAS_TONE_CONTROL_PARSER, EAS_METRICS_INTERFACE }; EAS_VOID_PTR const optionalData[] = { EAS_TONE_CONTROL_DATA, EAS_METRICS_DATA }; /*---------------------------------------------------------------------------- * EAS_CMStaticMemoryModel() *---------------------------------------------------------------------------- * Purpose: * This function returns true if EAS has been configured for * a static memory model. There are some limitations in the * static memory model, see the documentation for more * information. * * Outputs: * returns EAS_TRUE if a module is found *---------------------------------------------------------------------------- */ EAS_BOOL EAS_CMStaticMemoryModel (void) { #ifdef _STATIC_MEMORY return EAS_TRUE; #else return EAS_FALSE; #endif } /*---------------------------------------------------------------------------- * EAS_CMEnumModules() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to optional modules. * * Inputs: * module - module number * * Outputs: * returns a pointer to the module function table or NULL if no module *---------------------------------------------------------------------------- */ EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module) { if (module >= (EAS_INT) NUM_PARSER_MODULES) return NULL; return parserModules[module]; } /*---------------------------------------------------------------------------- * EAS_CMEnumData() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to static memory allocations. * * Inputs: * dataModule - enumerated module number * * Outputs: * Returns handle to data or NULL if not found *---------------------------------------------------------------------------- */ /*lint -esym(715, dataModule) used only when _STATIC_MEMORY is defined */ EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule) { #ifdef _STATIC_MEMORY switch (dataModule) { /* main instance data for synthesizer */ case EAS_CM_EAS_DATA: return &eas_Data; /* mix buffer for mix engine */ case EAS_CM_MIX_BUFFER: /*lint -e{545} lint doesn't like this because it sees the underlying type */ return &eas_MixBuffer; /* instance data for synth */ case EAS_CM_SYNTH_DATA: return &eas_Synth; /* instance data for MIDI parser */ case EAS_CM_MIDI_DATA: return &eas_MIDI; /* instance data for SMF parser */ case EAS_CM_SMF_DATA: return &eas_SMFData; #ifdef _XMF_PARSER /* instance data for XMF parser */ case EAS_CM_XMF_DATA: return &eas_XMFData; #endif #ifdef _SMAF_PARSER /* instance data for SMAF parser */ case EAS_CM_SMAF_DATA: return &eas_SMAFData; #endif /* instance data for the PCM engine */ case EAS_CM_PCM_DATA: /*lint -e{545} lint doesn't like this because it sees the underlying type */ return &eas_PCMData; case EAS_CM_MIDI_STREAM_DATA: return &eas_MIDIData; #ifdef _OTA_PARSER /* instance data for OTA parser */ case EAS_CM_OTA_DATA: return &eas_OTAData; #endif #ifdef _IMELODY_PARSER /* instance data for iMelody parser */ case EAS_CM_IMELODY_DATA: return &eas_iMelodyData; #endif #ifdef _RTTTL_PARSER /* instance data for RTTTL parser */ case EAS_CM_RTTTL_DATA: return &eas_RTTTLData; #endif #ifdef _WAVE_PARSER /* instance data for WAVE parser */ case EAS_CM_WAVE_DATA: return &eas_WaveData; #endif #if defined (_CMX_PARSER) || defined(_MFI_PARSER) /* instance data for CMF parser */ case EAS_CM_CMF_DATA: return &eas_CMFData; #endif default: return NULL; } #else return NULL; #endif } /*---------------------------------------------------------------------------- * EAS_CMEnumFXModules() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to optional effects modules. * * Inputs: * module - enumerated module number * pModule - pointer to module interface * * Outputs: * Returns pointer to function table or NULL if not found *---------------------------------------------------------------------------- */ EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module) { if (module >= NUM_EFFECTS_MODULES) return NULL; return effectsModules[module]; } /*---------------------------------------------------------------------------- * EAS_CMEnumFXData() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to static memory allocations. * * Inputs: * dataModule - enumerated module number * pData - pointer to handle variable * * Outputs: * Returns handle to data or NULL if not found *---------------------------------------------------------------------------- */ EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule) { if (dataModule >= NUM_EFFECTS_MODULES) return NULL; return effectsData[dataModule]; } /*---------------------------------------------------------------------------- * EAS_CMEnumOptModules() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to optional modules. * * Inputs: * module - enumerated module number * * Outputs: * returns pointer to function table or NULL if no module *---------------------------------------------------------------------------- */ EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module) { /* sanity check */ if (module >= NUM_OPTIONAL_MODULES) return EAS_FALSE; return optionalModules[module]; } /*---------------------------------------------------------------------------- * EAS_CMEnumOptData() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to static memory allocations. * * Inputs: * dataModule - enumerated module number * * Outputs: * Returns handle to data or NULL if not found *---------------------------------------------------------------------------- */ EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule) { if (dataModule >= NUM_OPTIONAL_MODULES) return NULL; return optionalData[dataModule]; } drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas.h0000644000000000000000000000013214200302440025231 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas.h0000644000175000001440000011002014200302440026004 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas.h * * Contents and purpose: * The public interface header for the EAS synthesizer. * * This header only contains declarations that are specific * to this implementation. * * DO NOT MODIFY THIS FILE! * * Copyright Sonic Network Inc. 2005, 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 852 $ * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_H #define _EAS_H #include "eas_types.h" /* for C++ linkage */ #ifdef __cplusplus extern "C" { #endif /* library version macro */ #define MAKE_LIB_VERSION(a,b,c,d) (((((((EAS_U32) a <<8) | (EAS_U32) b) << 8) | (EAS_U32) c) << 8) | (EAS_U32) d) #define LIB_VERSION MAKE_LIB_VERSION(3, 6, 10, 14) typedef struct { EAS_U32 libVersion; EAS_BOOL checkedVersion; EAS_I32 maxVoices; EAS_I32 numChannels; EAS_I32 sampleRate; EAS_I32 mixBufferSize; EAS_BOOL filterEnabled; EAS_U32 buildTimeStamp; EAS_CHAR *buildGUID; } S_EAS_LIB_CONFIG; /* enumerated effects module numbers for configuration */ typedef enum { EAS_MODULE_ENHANCER = 0, EAS_MODULE_COMPRESSOR, EAS_MODULE_REVERB, EAS_MODULE_CHORUS, EAS_MODULE_WIDENER, EAS_MODULE_GRAPHIC_EQ, EAS_MODULE_WOW, EAS_MODULE_MAXIMIZER, EAS_MODULE_TONECONTROLEQ, NUM_EFFECTS_MODULES } E_FX_MODULES; /* enumerated optional module numbers for configuration */ typedef enum { EAS_MODULE_MMAPI_TONE_CONTROL = 0, EAS_MODULE_METRICS } E_OPT_MODULES; #define NUM_OPTIONAL_MODULES 2 /* enumerated audio decoders for configuration */ typedef enum { EAS_DECODER_PCM = 0, EAS_DECODER_SMAF_ADPCM, EAS_DECODER_IMA_ADPCM, EAS_DECODER_7BIT_SMAF_ADPCM, EAS_DECODER_NOT_SUPPORTED } E_DECODER_MODULES; #define NUM_DECODER_MODULES 4 /* defines for EAS_PEOpenStream flags parameter */ #define PCM_FLAGS_STEREO 0x00000100 /* stream is stereo */ #define PCM_FLAGS_8_BIT 0x00000001 /* 8-bit format */ #define PCM_FLAGS_UNSIGNED 0x00000010 /* unsigned format */ #define PCM_FLAGS_STREAMING 0x80000000 /* streaming mode */ /* maximum volume setting */ #define EAS_MAX_VOLUME 100 /*---------------------------------------------------------------------------- * EAS_Init() *---------------------------------------------------------------------------- * Purpose: * Initialize the synthesizer library * * Inputs: * polyphony - number of voices to play (dynamic memory model only) * ppLibData - pointer to data handle variable for this instance * * Outputs: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData); /*---------------------------------------------------------------------------- * EAS_Config() *---------------------------------------------------------------------------- * Purpose: * Returns a pointer to a structure containing the configuration options * in this library build. * * Inputs: * * Outputs: * *---------------------------------------------------------------------------- */ EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void); /*---------------------------------------------------------------------------- * EAS_Shutdown() *---------------------------------------------------------------------------- * Purpose: * Shuts down the library. Deallocates any memory associated with the * synthesizer (dynamic memory model only) * * Inputs: * pEASData - handle to data for this instance * * Outputs: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData); /*---------------------------------------------------------------------------- * EAS_Render() *---------------------------------------------------------------------------- * Purpose: * Parse the Midi data and render PCM audio data. * * Inputs: * pEASData - buffer for internal EAS data * pOut - output buffer pointer * nNumRequested - requested num samples to generate * pnNumGenerated - actual number of samples generated * * Outputs: * EAS_SUCCESS if PCM data was successfully rendered * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated); /*---------------------------------------------------------------------------- * EAS_SetRepeat() *---------------------------------------------------------------------------- * Purpose: * Set the selected stream to repeat. * * Inputs: * pEASData - handle to data for this instance * streamHandle - handle to stream * repeatCount - repeat count (0 = no repeat, -1 = repeat forever) * * Outputs: * * Side Effects: * * Notes: * 0 = no repeat * 1 = repeat once, i.e. play through twice * -1 = repeat forever *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 repeatCount); /*---------------------------------------------------------------------------- * EAS_GetRepeat() *---------------------------------------------------------------------------- * Purpose: * Gets the current repeat count for the selected stream. * * Inputs: * pEASData - handle to data for this instance * streamHandle - handle to stream * pRrepeatCount - pointer to variable to hold repeat count * * Outputs: * * Side Effects: * * Notes: * 0 = no repeat * 1 = repeat once, i.e. play through twice * -1 = repeat forever *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pRepeatCount); /*---------------------------------------------------------------------------- * EAS_SetPlaybackRate() *---------------------------------------------------------------------------- * Purpose: * Set the playback rate. * * Inputs: * pEASData - handle to data for this instance * streamHandle - handle to stream * rate - rate (28-bit fractional amount) * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U32 rate); #define MAX_PLAYBACK_RATE (EAS_U32)(1L << 29) #define MIN_PLAYBACK_RATE (EAS_U32)(1L << 27) /*---------------------------------------------------------------------------- * EAS_SetTransposition) *---------------------------------------------------------------------------- * Purpose: * Sets the key tranposition for the synthesizer. Transposes all * melodic instruments by the specified amount. Range is limited * to +/-12 semitones. * * Inputs: * pEASData - handle to data for this instance * streamHandle - handle to stream * transposition - +/-12 semitones * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 transposition); #define MAX_TRANSPOSE 12 /*---------------------------------------------------------------------------- * EAS_SetSynthPolyphony() *---------------------------------------------------------------------------- * Purpose: * Set the polyphony of the synthesizer. Value must be >= 1 and <= the * maximum number of voices. This function will pin the polyphony * at those limits * * Inputs: * pEASData - pointer to overall EAS data structure * synthNum - synthesizer number (0 = onboard, 1 = DSP) * polyphonyCount - the desired polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount); /*---------------------------------------------------------------------------- * EAS_GetSynthPolyphony() *---------------------------------------------------------------------------- * Purpose: * Returns the current polyphony setting of the synthesizer * * Inputs: * pEASData - pointer to overall EAS data structure * synthNum - synthesizer number (0 = onboard, 1 = DSP) * pPolyphonyCount - pointer to variable to receive polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount); /*---------------------------------------------------------------------------- * EAS_SetPolyphony() *---------------------------------------------------------------------------- * Purpose: * Set the polyphony of the stream. Value must be >= 1 and <= the * maximum number of voices. This function will pin the polyphony * at those limits * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - handle returned by EAS_OpenFile * polyphonyCount - the desired polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 polyphonyCount); /*---------------------------------------------------------------------------- * EAS_GetPolyphony() *---------------------------------------------------------------------------- * Purpose: * Returns the current polyphony setting of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - handle returned by EAS_OpenFile * pPolyphonyCount - pointer to variable to receive polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPolyphonyCount); /*---------------------------------------------------------------------------- * EAS_SetPriority() *---------------------------------------------------------------------------- * Purpose: * Set the priority of the stream. Determines which stream's voices * are stolen when there are insufficient voices for all notes. * Value must be in the range of 1-255, lower values are higher * priority. The default priority is 50. * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - handle returned by EAS_OpenFile * polyphonyCount - the desired polyphony count * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 priority); /*---------------------------------------------------------------------------- * EAS_GetPriority() *---------------------------------------------------------------------------- * Purpose: * Returns the current priority setting of the stream * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - handle returned by EAS_OpenFile * pPriority - pointer to variable to receive priority * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPriority); /*---------------------------------------------------------------------------- * EAS_SetVolume() *---------------------------------------------------------------------------- * Purpose: * Set the master volume for the mixer. The default volume setting is * 90 (-10 dB). The volume range is 0 to 100 in 1dB increments. * * Inputs: * pEASData - pointer to overall EAS data structure * volume - the desired master volume * * Outputs: * * * Side Effects: * overrides any previously set master volume from sysex * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 volume); /*---------------------------------------------------------------------------- * EAS_GetVolume() *---------------------------------------------------------------------------- * Purpose: * Returns the master volume for the mixer in 1dB increments. * * Inputs: * pEASData - pointer to overall EAS data structure * volume - the desired master volume * * Outputs: * * * Side Effects: * overrides any previously set master volume from sysex * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle); /*---------------------------------------------------------------------------- * EAS_SetMaxLoad() *---------------------------------------------------------------------------- * Purpose: * Sets the maximum workload the parsers will do in a single call to * EAS_Render. The units are currently arbitrary, but should correlate * well to the actual CPU cycles consumed. The primary effect is to * reduce the occasional peaks in CPU cycles consumed when parsing * dense parts of a MIDI score. Setting maxWorkLoad to zero disables * the workload limiting function. * * Inputs: * pEASData - handle to data for this instance * maxLoad - the desired maximum workload * * Outputs: * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad); /*---------------------------------------------------------------------------- * EAS_SetMaxPCMStreams() *---------------------------------------------------------------------------- * Sets the maximum number of PCM streams allowed in parsers that * use PCM streaming. * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - handle returned by EAS_OpenFile * maxNumStreams - maximum number of PCM streams *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams); /*---------------------------------------------------------------------------- * EAS_OpenFile() *---------------------------------------------------------------------------- * Purpose: * Opens a file for audio playback. * * Inputs: * pEASData - pointer to overall EAS data structure * locator - pointer to filename or other locating information * pStreamHandle - pointer to stream handle variable * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle); #ifdef MMAPI_SUPPORT /*---------------------------------------------------------------------------- * EAS_MMAPIToneControl() *---------------------------------------------------------------------------- * Purpose: * Opens a ToneControl file for audio playback. * * Inputs: * pEASData - pointer to overall EAS data structure * locator - pointer to filename or other locating information * pStreamHandle - pointer to stream handle variable * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle); /*---------------------------------------------------------------------------- * EAS_GetWaveFmtChunk *---------------------------------------------------------------------------- * Helper function to retrieve WAVE file fmt chunk for MMAPI *---------------------------------------------------------------------------- * pEASData - pointer to EAS persistent data object * streamHandle - stream handle * pFmtChunk - pointer to pointer to FMT chunk data *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_VOID_PTR *ppFmtChunk); #endif /*---------------------------------------------------------------------------- * EAS_GetFileType *---------------------------------------------------------------------------- * Returns the file type (see eas_types.h for enumerations) *---------------------------------------------------------------------------- * pEASData - pointer to EAS persistent data object * streamHandle - stream handle * pFileType - pointer to variable to receive file type *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetFileType (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pFileType); /*---------------------------------------------------------------------------- * EAS_ParseMetaData() *---------------------------------------------------------------------------- * Purpose: * * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - file or stream handle * playLength - pointer to variable to store the play length (in msecs) * * Outputs: * * * Side Effects: * - resets the parser to the start of the file *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPlayLength); /*---------------------------------------------------------------------------- * EAS_Prepare() *---------------------------------------------------------------------------- * Purpose: * Prepares the synthesizer to play the file or stream. Parses the first * frame of data from the file and arms the synthesizer. * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - file or stream handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle); /*---------------------------------------------------------------------------- * EAS_State() *---------------------------------------------------------------------------- * Purpose: * Returns the state of an audio file or stream. * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - file or stream handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_STATE *pState); /*---------------------------------------------------------------------------- * EAS_RegisterMetaDataCallback() *---------------------------------------------------------------------------- * Purpose: * Registers a metadata callback function for parsed metadata. To * de-register the callback, call this function again with parameter * cbFunc set to NULL. * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - file or stream handle * cbFunc - pointer to host callback function * metaDataBuffer - pointer to metadata buffer * metaDataBufSize - maximum size of the metadata buffer * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback ( EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_METADATA_CBFUNC cbFunc, char *metaDataBuffer, EAS_I32 metaDataBufSize, EAS_VOID_PTR pUserData); /*---------------------------------------------------------------------------- * EAS_GetNoteCount () *---------------------------------------------------------------------------- * Returns the total number of notes played in this stream * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - file or stream handle * pNoteCount - pointer to variable to receive note count *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount); /*---------------------------------------------------------------------------- * EAS_CloseFile() *---------------------------------------------------------------------------- * Purpose: * Closes an audio file or stream. Playback should have either paused or * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED). * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - file or stream handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle); /*---------------------------------------------------------------------------- * EAS_OpenMIDIStream() *---------------------------------------------------------------------------- * Purpose: * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer * * Inputs: * pEASData - pointer to overall EAS data structure * pStreamHandle - pointer to variable to hold file or stream handle * streamHandle - open stream or NULL for new synthesizer instance * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *pStreamHandle, EAS_HANDLE streamHandle); /*---------------------------------------------------------------------------- * EAS_WriteMIDIStream() *---------------------------------------------------------------------------- * Purpose: * Send data to the MIDI stream device * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - stream handle * pBuffer - pointer to buffer * count - number of bytes to write * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream(EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 *pBuffer, EAS_I32 count); /*---------------------------------------------------------------------------- * EAS_CloseMIDIStream() *---------------------------------------------------------------------------- * Purpose: * Closes a raw MIDI stream * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - stream handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle); /*---------------------------------------------------------------------------- * EAS_Locate() *---------------------------------------------------------------------------- * Purpose: * Locate into the file associated with the handle. * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - file handle * milliseconds - playback offset from start of file in milliseconds * * Outputs: * * * Side Effects: * the actual offset will be quantized to the closest update period, typically * a resolution of 5.9ms. Notes that are started prior to this time will not * sound. Any notes currently playing will be shut off. * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 milliseconds, EAS_BOOL offset); /*---------------------------------------------------------------------------- * EAS_GetRenderTime() *---------------------------------------------------------------------------- * Purpose: * Returns the current playback offset * * Inputs: * pEASData - pointer to overall EAS data structure * * Outputs: * Gets the render time clock in msecs. * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime); /*---------------------------------------------------------------------------- * EAS_GetLocation() *---------------------------------------------------------------------------- * Purpose: * Returns the current playback offset * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - file handle * * Outputs: * The offset in milliseconds from the start of the current sequence, quantized * to the nearest update period. Actual resolution is typically 5.9 ms. * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pTime); /*---------------------------------------------------------------------------- * EAS_Pause() *---------------------------------------------------------------------------- * Purpose: * Pauses the playback of the data associated with this handle. The audio * is gracefully ramped down to prevent clicks and pops. It may take several * buffers of audio before the audio is muted. * * Inputs: * psEASData - pointer to overall EAS data structure * streamHandle - file or stream handle * * Outputs: * * * Side Effects: * * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle); /*---------------------------------------------------------------------------- * EAS_Resume() *---------------------------------------------------------------------------- * Purpose: * Resumes the playback of the data associated with this handle. The audio * is gracefully ramped up to prevent clicks and pops. * * Inputs: * psEASData - pointer to overall EAS data structure * streamHandle - file or stream handle * * Outputs: * * * Side Effects: * * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle); /*---------------------------------------------------------------------------- * EAS_GetParameter() *---------------------------------------------------------------------------- * Purpose: * Set the parameter of a module. See E_MODULES for a list of modules * and the header files of the modules for a list of parameters. * * Inputs: * psEASData - pointer to overall EAS data structure * module - enumerated module number * param - enumerated parameter number * pValue - pointer to variable to receive parameter value * * Outputs: * * * Side Effects: * * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue); /*---------------------------------------------------------------------------- * EAS_SetParameter() *---------------------------------------------------------------------------- * Purpose: * Set the parameter of a module. See E_MODULES for a list of modules * and the header files of the modules for a list of parameters. * * Inputs: * psEASData - pointer to overall EAS data structure * handle - file or stream handle * module - enumerated module number * param - enumerated parameter number * value - new parameter value * * Outputs: * * * Side Effects: * * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value); #ifdef _METRICS_ENABLED /*---------------------------------------------------------------------------- * EAS_MetricsReport() *---------------------------------------------------------------------------- * Purpose: * Displays the current metrics through the EAS_Report interface. * * Inputs: * pEASData - instance data handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData); /*---------------------------------------------------------------------------- * EAS_MetricsReset() *---------------------------------------------------------------------------- * Purpose: * Displays the current metrics through the EAS_Report interface. * * Inputs: * pEASData - instance data handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData); #endif /*---------------------------------------------------------------------------- * EAS_SetSoundLibrary() *---------------------------------------------------------------------------- * Purpose: * Sets the location of the sound library. * * Inputs: * pEASData - instance data handle * streamHandle - file or stream handle * pSoundLib - pointer to sound library * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_SNDLIB_HANDLE pSndLib); /*---------------------------------------------------------------------------- * EAS_SetHeaderSearchFlag() *---------------------------------------------------------------------------- * By default, when EAS_OpenFile is called, the parsers check the * first few bytes of the file looking for a specific header. Some * mobile devices may add a header to the start of a file, which * will prevent the parser from recognizing the file. If the * searchFlag is set to EAS_TRUE, the parser will search the entire * file looking for the header. This may enable EAS to recognize * some files that it would ordinarily reject. The negative is that * it make take slightly longer to process the EAS_OpenFile request. * * Inputs: * pEASData - instance data handle * searchFlag - search flag (EAS_TRUE or EAS_FALSE) *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag); /*---------------------------------------------------------------------------- * EAS_SetPlayMode() *---------------------------------------------------------------------------- * Some file formats support special play modes, such as iMode partial * play mode. This call can be used to change the play mode. The * default play mode (usually straight playback) is always zero. * * Inputs: * pEASData - instance data handle * handle - file or stream handle * playMode - play mode (see eas_types.h for enumerations) *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode); #ifdef DLS_SYNTHESIZER /*---------------------------------------------------------------------------- * EAS_LoadDLSCollection() *---------------------------------------------------------------------------- * Purpose: * Downloads a DLS collection * * Inputs: * pEASData - instance data handle * streamHandle - file or stream handle * locator - file locator * * Outputs: * * * Side Effects: * May overlay instruments in the GM sound set * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_FILE_LOCATOR locator); #endif /*---------------------------------------------------------------------------- * EAS_SetFrameBuffer() *---------------------------------------------------------------------------- * Purpose: * Sets the frame buffer pointer passed to the IPC communications functions * * Inputs: * pEASData - instance data handle * locator - file locator * * Outputs: * * * Side Effects: * May overlay instruments in the GM sound set * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer); #ifdef EXTERNAL_AUDIO /*---------------------------------------------------------------------------- * EAS_RegExtAudioCallback() *---------------------------------------------------------------------------- * Purpose: * Registers callback functions for audio events. * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - file or stream handle * cbProgChgFunc - pointer to host callback function for program change * cbEventFunc - pointer to host callback functio for note events * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc); /*---------------------------------------------------------------------------- * EAS_GetMIDIControllers() *---------------------------------------------------------------------------- * Purpose: * Returns the current state of MIDI controllers on the requested channel. * * Inputs: * pEASData - pointer to overall EAS data structure * streamHandle - file or stream handle * pControl - pointer to structure to receive data * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl); #endif /*---------------------------------------------------------------------------- * EAS_SearchFile *---------------------------------------------------------------------------- * Search file for specific sequence starting at current file * position. Returns offset to start of sequence. * * Inputs: * pEASData - pointer to EAS persistent data object * fileHandle - file handle * searchString - pointer to search sequence * len - length of search sequence * pOffset - pointer to variable to store offset to sequence * * Returns EAS_EOF if end-of-file is reached *---------------------------------------------------------------------------- */ EAS_RESULT EAS_SearchFile (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset); #ifdef __cplusplus } /* end extern "C" */ #endif #endif /* #ifndef _EAS_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_report.h0000644000000000000000000000013214200302440026624 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_report.h0000644000175000001440000000421114200302440027403 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_report.h * * Contents and purpose: * This file contains the debug message handling routines for the EAS library. * These routines should be modified as needed for your system. * * DO NOT MODIFY THIS FILE! * * Copyright 2005 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ /* sentinel */ #ifndef _EAS_REPORT_H #define _EAS_REPORT_H #define _EAS_SEVERITY_NOFILTER 0 #define _EAS_SEVERITY_FATAL 1 #define _EAS_SEVERITY_ERROR 2 #define _EAS_SEVERITY_WARNING 3 #define _EAS_SEVERITY_INFO 4 #define _EAS_SEVERITY_DETAIL 5 /* for C++ linkage */ #ifdef __cplusplus extern "C" { #endif #ifndef _NO_DEBUG_PREPROCESSOR /* structure for included debug message header files */ typedef struct { unsigned long m_nHashCode; int m_nSerialNum; char *m_pDebugMsg; } S_DEBUG_MESSAGES; /* debug message handling prototypes */ extern void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...); #else /* these prototypes are used if the debug preprocessor is not used */ extern void EAS_Report (int severity, const char* fmt, ...); extern void EAS_ReportX (int severity, const char* fmt, ...); #endif extern void EAS_SetDebugLevel (int severity); extern void EAS_SetDebugFile (void *file, int flushAfterWrite); #ifdef __cplusplus } /* end extern "C" */ #endif #endif drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_reverb.h0000644000000000000000000000013214200302440026576 xustar0030 mtime=1644266784.801324165 30 atime=1644266785.357324521 30 ctime=1644266784.801324165 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_reverb.h0000644000175000001440000000271114200302440027360 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_reverb.h * * Contents and purpose: * Contains parameter enumerations for the Reverb effect * * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 300 $ * $Date: 2006-09-11 17:37:20 -0700 (Mon, 11 Sep 2006) $ *---------------------------------------------------------------------------- */ #ifndef _EAS_REVERB_H #define _EAS_REVERB_H /* enumerated parameter settings for Reverb effect */ typedef enum { EAS_PARAM_REVERB_BYPASS, EAS_PARAM_REVERB_PRESET, EAS_PARAM_REVERB_WET, EAS_PARAM_REVERB_DRY } E_REVERB_PARAMS; typedef enum { EAS_PARAM_REVERB_LARGE_HALL, EAS_PARAM_REVERB_HALL, EAS_PARAM_REVERB_CHAMBER, EAS_PARAM_REVERB_ROOM, } E_REVERB_PRESETS; #endif /* _REVERB_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_build.h0000644000000000000000000000013214200302440026410 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_build.h0000644000175000001440000000242014200302440027167 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * host_src\eas_build.h * * Contents and purpose: * This file contains the build configuration for this * build. The buildGUIDStr is a GUID created during * the build process and is guaranteed to be unique * for each build. * * Copyright Sonic Network Inc. 2006 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This file was autogenerated by buildid.exe *---------------------------------------------------------------------------- */ #ifndef _GUID_1feda229b9a845e996f473c0a80e7220_ #define _GUID_1feda229b9a845e996f473c0a80e7220_ #define _BUILD_VERSION_ "1feda229-b9a8-45e9-96f4-73c0a80e7220" #define _BUILD_TIME_ 0x4743badd #endif /* _GUID_1feda229b9a845e996f473c0a80e7220_ */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/PaxHeaders.27918/eas_config.h0000644000000000000000000000013214200302440026556 xustar0030 mtime=1644266784.797324163 30 atime=1644266785.357324521 30 ctime=1644266784.797324163 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/host_src/eas_config.h0000644000175000001440000001421014200302440027335 0ustar00pedrousers00000000000000/*---------------------------------------------------------------------------- * * File: * eas_config.h * * Contents and purpose: * This header declares the Configuration Module interface (CM). The CM * is a module compiled external to the library that sets the configuration * for this build. It allows the library to find optional components and * links to static memory allocations (when used in a static configuration). * * NOTE: This module is not intended to be modified by the customer. It * needs to be included in the build process with the correct configuration * defines (see the library documentation for information on how to configure * the library). * * DO NOT MODIFY THIS FILE! * * Copyright 2005 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision: 82 $ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $ *---------------------------------------------------------------------------- */ // sentinel #ifndef _EAS_CONFIG_H #define _EAS_CONFIG_H #include "eas_types.h" /* list of enumerators for optional modules */ typedef enum { EAS_CM_FILE_PARSERS = 1 } E_CM_ENUM_MODULES; /* list of enumerators for module and memory pointers */ typedef enum { EAS_CM_EAS_DATA = 1, EAS_CM_MIX_BUFFER, EAS_CM_SYNTH_DATA, EAS_CM_MIDI_DATA, EAS_CM_SMF_DATA, EAS_CM_XMF_DATA, EAS_CM_SMAF_DATA, EAS_CM_PCM_DATA, EAS_CM_MIDI_STREAM_DATA, EAS_CM_METRICS_DATA, EAS_CM_OTA_DATA, EAS_CM_IMELODY_DATA, EAS_CM_RTTTL_DATA, EAS_CM_WAVE_DATA, EAS_CM_CMF_DATA } E_CM_DATA_MODULES; typedef struct { int maxSMFStreams; void *pSMFData; void *pSMFStream; } S_EAS_SMF_PTRS; typedef struct { int maxSMAFStreams; void *pSMAFData; void *pSMAFStream; } S_EAS_SMAF_PTRS; /*---------------------------------------------------------------------------- * EAS_CMStaticMemoryModel() *---------------------------------------------------------------------------- * Purpose: * This function returns true if EAS has been configured for * a static memory model. There are some limitations in the * static memory model, see the documentation for more * information. * * Outputs: * returns EAS_TRUE if a module is found *---------------------------------------------------------------------------- */ EAS_BOOL EAS_CMStaticMemoryModel (void); /*---------------------------------------------------------------------------- * EAS_CMEnumModules() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to optional modules. * * Inputs: * module - module number * * Outputs: * returns a pointer to the module function table or NULL if no module *---------------------------------------------------------------------------- */ EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module); /*---------------------------------------------------------------------------- * EAS_CMEnumData() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to static memory allocations. * * Inputs: * dataModule - enumerated module number * * Outputs: * Returns handle to data or NULL if not found *---------------------------------------------------------------------------- */ EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule); /*---------------------------------------------------------------------------- * EAS_CMEnumFXModules() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to optional effects modules. * * Inputs: * module - enumerated module number * pModule - pointer to module interface * * Outputs: * Returns pointer to function table or NULL if not found *---------------------------------------------------------------------------- */ EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module); /*---------------------------------------------------------------------------- * EAS_CMEnumFXData() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to static memory allocations. * * Inputs: * dataModule - enumerated module number * pData - pointer to handle variable * * Outputs: * Returns handle to data or NULL if not found *---------------------------------------------------------------------------- */ EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule); /*---------------------------------------------------------------------------- * EAS_CMEnumOptModules() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to optional modules. * * Inputs: * module - enumerated module number * * Outputs: * returns pointer to function table or NULL if no module *---------------------------------------------------------------------------- */ EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module); /*---------------------------------------------------------------------------- * EAS_CMEnumOptData() *---------------------------------------------------------------------------- * Purpose: * This function is used to find pointers to static memory allocations. * * Inputs: * dataModule - enumerated module number * * Outputs: * Returns handle to data or NULL if not found *---------------------------------------------------------------------------- */ EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule); #endif /* end _EAS_CONFIG_H */ drumstick-2.5.1/library/rt-backends/eassynth/sonivox/PaxHeaders.27918/NOTICE0000644000000000000000000000013214200302440023370 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/eassynth/sonivox/NOTICE0000644000175000001440000000106514200302440024153 0ustar00pedrousers00000000000000Copyright (c) 2004-2022 Sonic Network Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. drumstick-2.5.1/library/rt-backends/eassynth/PaxHeaders.27918/src0000644000000000000000000000013214200302440021471 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/eassynth/src/0000755000175000001440000000000014200302440022327 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/eassynth/src/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440024306 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/eassynth/src/CMakeLists.txt0000644000175000001440000000270214200302440025070 0ustar00pedrousers00000000000000set( HEADERS synthcontroller.h synthrenderer.h ) set( SOURCES synthcontroller.cpp synthrenderer.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp( MOC_SRCS ${HEADERS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp( MOC_SRCS ${HEADERS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library( drumstick-rt-eassynth STATIC ${MOC_SRCS} ${SOURCES} ) target_compile_definitions(drumstick-rt-eassynth PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-eassynth PROPERTIES STATIC_LIB "libdrumstick-rt-eassynth") else() add_library( drumstick-rt-eassynth MODULE ${MOC_SRCS} ${SOURCES} ) target_compile_definitions(drumstick-rt-eassynth PRIVATE QT_PLUGIN) endif() target_link_libraries( drumstick-rt-eassynth PRIVATE Qt${QT_VERSION_MAJOR}::Core PkgConfig::PULSE sonivox ) target_include_directories(drumstick-rt-eassynth PRIVATE ../sonivox/host_src/ ${Drumstick_SOURCE_DIR}/library/include ) set_target_properties(drumstick-rt-eassynth PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install( TARGETS drumstick-rt-eassynth EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} ) drumstick-2.5.1/library/rt-backends/eassynth/src/PaxHeaders.27918/synthcontroller.cpp0000644000000000000000000000013214200302440025523 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/eassynth/src/synthcontroller.cpp0000644000175000001440000001001314200302440026277 0ustar00pedrousers00000000000000/* Sonivox EAS Synthesizer for Qt applications Copyright (C) 2016-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "synthcontroller.h" #include "synthrenderer.h" namespace drumstick { namespace rt { SynthController::SynthController(QObject *parent) : MIDIOutput(parent) { m_renderer = new SynthRenderer(); m_renderer->moveToThread(&m_renderingThread); connect(&m_renderingThread, &QThread::started, m_renderer, &SynthRenderer::run); } SynthController::~SynthController() { //qDebug() << Q_FUNC_INFO; if (m_renderingThread.isRunning()) { stop(); } delete m_renderer; m_renderer = nullptr; } void SynthController::start() { QMutex mutex; mutex.lock(); m_renderer->setCondition(&m_rendering); m_renderingThread.start(QThread::HighPriority); m_rendering.wait(&mutex); mutex.unlock(); } void SynthController::stop() { //qDebug() << Q_FUNC_INFO; m_renderer->stop(); m_renderingThread.quit(); m_renderingThread.wait(); } void SynthController::initialize(QSettings* settings) { m_renderer->initialize(settings); //qDebug() << Q_FUNC_INFO; } QString SynthController::backendName() { return SynthRenderer::QSTR_SONIVOXEAS; } QString SynthController::publicName() { return SynthRenderer::QSTR_SONIVOXEAS; } void SynthController::setPublicName(QString name) { Q_UNUSED(name) } QList SynthController::connections(bool advanced) { Q_UNUSED(advanced) return QList{MIDIConnection(SynthRenderer::QSTR_SONIVOXEAS, SynthRenderer::QSTR_SONIVOXEAS)}; } void SynthController::setExcludedConnections(QStringList conns) { Q_UNUSED(conns) } void SynthController::open(const MIDIConnection& name) { Q_UNUSED(name) //qDebug() << Q_FUNC_INFO << name; start(); } void SynthController::close() { //qDebug() << Q_FUNC_INFO; stop(); } MIDIConnection SynthController::currentConnection() { return m_renderer->connection(); } void SynthController::sendNoteOff(int chan, int note, int vel) { m_renderer->sendMessage(MIDI_STATUS_NOTEOFF + chan, note, vel); } void SynthController::sendNoteOn(int chan, int note, int vel) { m_renderer->sendMessage(MIDI_STATUS_NOTEON + chan, note, vel); } void SynthController::sendKeyPressure(int chan, int note, int value) { m_renderer->sendMessage(MIDI_STATUS_KEYPRESURE + chan, note, value); } void SynthController::sendController(int chan, int control, int value) { m_renderer->sendMessage(MIDI_STATUS_CONTROLCHANGE + chan, control, value); } void SynthController::sendProgram(int chan, int program) { m_renderer->sendMessage(MIDI_STATUS_PROGRAMCHANGE + chan, program); } void SynthController::sendChannelPressure(int chan, int value) { m_renderer->sendMessage(MIDI_STATUS_CHANNELPRESSURE + chan, value); } void SynthController::sendPitchBend(int chan, int v) { // -8192 <= v <= 8191; 0 <= value <= 16384 int value = 8192 + v; m_renderer->sendMessage(MIDI_STATUS_PITCHBEND + chan, MIDI_LSB(value), MIDI_MSB(value)); } void SynthController::sendSysex(const QByteArray &data) { Q_UNUSED(data) } void SynthController::sendSystemMsg(const int status) { Q_UNUSED(status) } QStringList SynthController::getDiagnostics() { return m_renderer->getDiagnostics(); } bool SynthController::getStatus() { return m_renderer->getStatus(); } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/eassynth/src/PaxHeaders.27918/src.pro0000644000000000000000000000013214200302440023057 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/eassynth/src/src.pro0000644000175000001440000000114514200302440023641 0ustar00pedrousers00000000000000TEMPLATE = lib TARGET = drumstick-rt-eassynth DESTDIR = ../../../../build/lib/drumstick2 include (../../../../global.pri) CONFIG += c++11 plugin link_prl static { CONFIG += staticlib create_prl } DEPENDPATH += ../sonivox DEPENDPATH += ../../../include INCLUDEPATH += ../sonivox/host_src INCLUDEPATH += ../../../include QT -= gui LIBS += -L../../../../build/lib \ -ldrumstick-rt \ -lsonivox HEADERS += synthcontroller.h \ synthrenderer.h SOURCES += synthcontroller.cpp synthrenderer.cpp CONFIG += link_pkgconfig packagesExist(libpulse-simple) { PKGCONFIG += libpulse-simple } drumstick-2.5.1/library/rt-backends/eassynth/src/PaxHeaders.27918/synthrenderer.cpp0000644000000000000000000000013214200302440025146 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/eassynth/src/synthrenderer.cpp0000644000175000001440000002434514200302440025737 0ustar00pedrousers00000000000000/* Sonivox EAS Synthesizer for Qt applications Copyright (C) 2016-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include "synthrenderer.h" namespace drumstick { namespace rt { const QString SynthRenderer::QSTR_PREFERENCES = QStringLiteral("SonivoxEAS"); const QString SynthRenderer::QSTR_BUFFERTIME = QStringLiteral("BufferTime"); const QString SynthRenderer::QSTR_REVERBTYPE = QStringLiteral("ReverbType"); const QString SynthRenderer::QSTR_REVERBAMT = QStringLiteral("ReverbAmt"); const QString SynthRenderer::QSTR_CHORUSTYPE = QStringLiteral("ChorusType"); const QString SynthRenderer::QSTR_CHORUSAMT = QStringLiteral("ChorusAmt"); const QString SynthRenderer::QSTR_SONIVOXEAS = QStringLiteral("SonivoxEAS"); SynthRenderer::SynthRenderer(QObject *parent) : QObject(parent), m_Stopped(true), m_rendering(nullptr), m_bufferTime(60) { initEAS(); } void SynthRenderer::initEAS() { /* SONiVOX EAS initialization */ EAS_RESULT eas_res; EAS_DATA_HANDLE dataHandle; EAS_HANDLE handle; m_status = false; m_diagnostics.clear(); const S_EAS_LIB_CONFIG *easConfig = EAS_Config(); if (easConfig == nullptr) { m_diagnostics << "EAS_Config returned null"; return; } eas_res = EAS_Init(&dataHandle); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_Init error: %1").arg( eas_res ); return; } eas_res = EAS_OpenMIDIStream(dataHandle, &handle, nullptr); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_OpenMIDIStream error: %1").arg( eas_res ); EAS_Shutdown(dataHandle); return; } m_easData = dataHandle; m_streamHandle = handle; Q_ASSERT(m_streamHandle != nullptr); m_sampleRate = easConfig->sampleRate; m_bufferSize = easConfig->mixBufferSize; m_channels = easConfig->numChannels; m_status = true; //qDebug() << Q_FUNC_INFO << "EAS bufferSize=" << m_bufferSize << " sampleRate=" << m_sampleRate << " channels=" << m_channels; } void SynthRenderer::initPulse() { pa_sample_spec samplespec; pa_buffer_attr bufattr; int period_bytes; char *server = nullptr; char *device = nullptr; int err; samplespec.format = PA_SAMPLE_S16LE; samplespec.channels = m_channels; samplespec.rate = m_sampleRate; //period_bytes = m_bufferSize * sizeof (EAS_PCM) * m_channels; period_bytes = pa_usec_to_bytes(m_bufferTime * 1000, &samplespec); bufattr.maxlength = (int32_t)-1; bufattr.tlength = period_bytes; bufattr.minreq = (int32_t)-1; bufattr.prebuf = (int32_t)-1; bufattr.fragsize = (int32_t)-1; m_pulseHandle = pa_simple_new (server, "SonivoxEAS", PA_STREAM_PLAYBACK, device, "Synthesizer output", &samplespec, nullptr, /* pa_channel_map */ &bufattr, &err); if (!m_pulseHandle) { m_diagnostics << "Failed to create PulseAudio connection"; m_status = false; } //qDebug() << Q_FUNC_INFO << "period_bytes=" << period_bytes; } void SynthRenderer::uninitEAS() { EAS_RESULT eas_res; if (m_easData != nullptr && m_streamHandle != nullptr) { eas_res = EAS_CloseMIDIStream(m_easData, m_streamHandle); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_CloseMIDIStream error: %1").arg( eas_res ); } eas_res = EAS_Shutdown(m_easData); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_Shutdown error: %1").arg( eas_res ); } m_streamHandle = nullptr; m_easData = nullptr; } //qDebug() << Q_FUNC_INFO; } void SynthRenderer::uninitPulse() { if (m_pulseHandle != nullptr) { pa_simple_free(m_pulseHandle); m_pulseHandle = nullptr; } //qDebug() << Q_FUNC_INFO; } SynthRenderer::~SynthRenderer() { uninitEAS(); } void SynthRenderer::initialize(QSettings *settings) { settings->beginGroup(QSTR_PREFERENCES); m_bufferTime = settings->value(QSTR_BUFFERTIME, 60).toInt(); int reverbType = settings->value(QSTR_REVERBTYPE, EAS_PARAM_REVERB_HALL).toInt(); int reverbAmt = settings->value(QSTR_REVERBAMT, 25800).toInt(); int chorusType = settings->value(QSTR_CHORUSTYPE, -1).toInt(); int chorusAmt = settings->value(QSTR_CHORUSAMT, 0).toInt(); settings->endGroup(); initReverb(reverbType); setReverbWet(reverbAmt); initChorus(chorusType); setChorusLevel(chorusAmt); } bool SynthRenderer::stopped() { QReadLocker locker(&m_mutex); return m_Stopped; } void SynthRenderer::stop() { QWriteLocker locker(&m_mutex); //qDebug() << Q_FUNC_INFO; m_Stopped = true; } void SynthRenderer::run() { int pa_err; unsigned char data[1024]; //qDebug() << Q_FUNC_INFO << "started"; try { initPulse(); //qDebug() << Q_FUNC_INFO << "m_status:" << m_status; m_Stopped = false; if (m_rendering != nullptr) { m_rendering->wakeAll(); } while (!stopped() && m_status) { EAS_RESULT eas_res; EAS_I32 numGen = 0; size_t bytes = 0; QCoreApplication::sendPostedEvents(); if (m_easData != nullptr) { EAS_PCM *buffer = (EAS_PCM *) data; eas_res = EAS_Render(m_easData, buffer, m_bufferSize, &numGen); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_Render error: %1").arg(eas_res); } bytes += (size_t) numGen * sizeof(EAS_PCM) * m_channels; // hand over to pulseaudio the rendered buffer if (pa_simple_write (m_pulseHandle, data, bytes, &pa_err) < 0) { m_diagnostics << QString("Error writing to PulseAudio connection: %1").arg(pa_err); } } } uninitPulse(); } catch (...) { m_diagnostics << "Exception in rendering loop - exiting"; m_status = false; } //qDebug() << Q_FUNC_INFO << "ended"; emit finished(); } void SynthRenderer::writeMIDIData(const QByteArray& message) { EAS_RESULT eas_res = EAS_ERROR_ALREADY_STOPPED; if (m_easData != nullptr && m_streamHandle != nullptr) { if (message.length() > 0) { //qDebug() << Q_FUNC_INFO << message.toHex(); eas_res = EAS_WriteMIDIStream(m_easData, m_streamHandle, (EAS_U8 *)message.data(), message.length()); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_WriteMIDIStream error: %1").arg(eas_res); } } } } bool SynthRenderer::getStatus() const { return m_status; } QStringList SynthRenderer::getDiagnostics() const { return m_diagnostics; } void SynthRenderer::setCondition(QWaitCondition *cond) { m_rendering = cond; } void SynthRenderer::initReverb(int reverb_type) { EAS_RESULT eas_res; EAS_BOOL sw = EAS_TRUE; if ( reverb_type >= EAS_PARAM_REVERB_LARGE_HALL && reverb_type <= EAS_PARAM_REVERB_ROOM ) { sw = EAS_FALSE; eas_res = EAS_SetParameter(m_easData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_PRESET, (EAS_I32) reverb_type); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_SetParameter error: %1").arg(eas_res); } } eas_res = EAS_SetParameter(m_easData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_BYPASS, sw); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_SetParameter error: %1").arg(eas_res); } } void SynthRenderer::initChorus(int chorus_type) { EAS_RESULT eas_res; EAS_BOOL sw = EAS_TRUE; if (chorus_type >= EAS_PARAM_CHORUS_PRESET1 && chorus_type <= EAS_PARAM_CHORUS_PRESET4 ) { sw = EAS_FALSE; eas_res = EAS_SetParameter(m_easData, EAS_MODULE_CHORUS, EAS_PARAM_CHORUS_PRESET, (EAS_I32) chorus_type); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_SetParameter error: %1").arg(eas_res); } } eas_res = EAS_SetParameter(m_easData, EAS_MODULE_CHORUS, EAS_PARAM_CHORUS_BYPASS, sw); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_SetParameter error: %1").arg(eas_res); } } void SynthRenderer::setReverbWet(int amount) { EAS_RESULT eas_res = EAS_SetParameter(m_easData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_WET, (EAS_I32) amount); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_SetParameter error: %1").arg(eas_res); } } void SynthRenderer::setChorusLevel(int amount) { EAS_RESULT eas_res = EAS_SetParameter(m_easData, EAS_MODULE_CHORUS, EAS_PARAM_CHORUS_LEVEL, (EAS_I32) amount); if (eas_res != EAS_SUCCESS) { m_diagnostics << QString("EAS_SetParameter error: %1").arg(eas_res); } } void SynthRenderer::sendMessage(int m0) { QByteArray m; m.resize(1); m[0] = m0; writeMIDIData(m); } void SynthRenderer::sendMessage(int m0, int m1) { QByteArray m; m.resize(2); m[0] = m0; m[1] = m1; writeMIDIData(m); } void SynthRenderer::sendMessage(int m0, int m1, int m2) { QByteArray m; m.resize(3); m[0] = m0; m[1] = m1; m[2] = m2; writeMIDIData(m); } MIDIConnection SynthRenderer::connection() { if (stopped()) { return MIDIConnection(); } else { return MIDIConnection(QSTR_SONIVOXEAS, QSTR_SONIVOXEAS); } } void SynthRenderer::setBufferTime(int milliseconds) { //qDebug() << Q_FUNC_INFO << milliseconds; m_bufferTime = milliseconds; } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/eassynth/src/PaxHeaders.27918/synthrenderer.h0000644000000000000000000000013214200302440024613 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/eassynth/src/synthrenderer.h0000644000175000001440000000551714200302440025404 0ustar00pedrousers00000000000000/* Sonivox EAS Synthesizer for Qt applications Copyright (C) 2016-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SYNTHRENDERER_H_ #define SYNTHRENDERER_H_ #include #include #include #include #include #include #include "eas.h" namespace drumstick { namespace rt { class SynthRenderer : public QObject { Q_OBJECT public: explicit SynthRenderer(QObject *parent = nullptr); virtual ~SynthRenderer(); void stop(); bool stopped(); void initReverb(int reverb_type); void initChorus(int chorus_type); void setReverbWet(int amount); void setChorusLevel(int amount); void sendMessage(int m0); void sendMessage(int m0, int m1); void sendMessage(int m0, int m1, int m2); MIDIConnection connection(); void setBufferTime(int milliseconds); void initialize(QSettings* settings); bool getStatus() const; QStringList getDiagnostics() const; void setCondition(QWaitCondition *cond); static const QString QSTR_PREFERENCES; static const QString QSTR_BUFFERTIME; static const QString QSTR_REVERBTYPE; static const QString QSTR_REVERBAMT; static const QString QSTR_CHORUSTYPE; static const QString QSTR_CHORUSAMT; static const QString QSTR_SONIVOXEAS; private: void initEAS(); void initPulse(); void uninitEAS(); void uninitPulse(); void writeMIDIData(const QByteArray& message); public slots: void run(); signals: void finished(); private: bool m_Stopped; QReadWriteLock m_mutex; QWaitCondition *m_rendering; /* SONiVOX EAS */ int m_sampleRate, m_bufferSize, m_channels; EAS_DATA_HANDLE m_easData; EAS_HANDLE m_streamHandle; EAS_HANDLE m_fileHandle; /* pulseaudio */ int m_bufferTime; pa_simple *m_pulseHandle; /* object properties */ bool m_status; QStringList m_diagnostics; }; }} /* drumstick::rt */ #endif /*SYNTHRENDERER_H_*/ drumstick-2.5.1/library/rt-backends/eassynth/src/PaxHeaders.27918/synthcontroller.h0000644000000000000000000000013214200302440025170 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/eassynth/src/synthcontroller.h0000644000175000001440000000555014200302440025756 0ustar00pedrousers00000000000000/* Sonivox EAS Synthesizer for Qt applications Copyright (C) 2016-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SYNTHCONTROLLER_H #define SYNTHCONTROLLER_H #include #include #include #include #include "synthrenderer.h" namespace drumstick { namespace rt { class SynthController : public MIDIOutput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput/2.0") Q_INTERFACES(drumstick::rt::MIDIOutput) Q_PROPERTY(QStringList diagnostics READ getDiagnostics) Q_PROPERTY(bool status READ getStatus) public: explicit SynthController(QObject *parent = nullptr); virtual ~SynthController(); void start(); void stop(); // MIDIOutput interface public: virtual void initialize(QSettings* settings) override; virtual QString backendName() override; virtual QString publicName() override; virtual void setPublicName(QString name) override; virtual QList connections(bool advanced) override; virtual void setExcludedConnections(QStringList conns) override; virtual void open(const MIDIConnection& name) override; virtual void close() override; virtual MIDIConnection currentConnection() override; public slots: virtual void sendNoteOff(int chan, int note, int vel) override; virtual void sendNoteOn(int chan, int note, int vel) override; virtual void sendKeyPressure(int chan, int note, int value) override; virtual void sendController(int chan, int control, int value) override; virtual void sendProgram(int chan, int program) override; virtual void sendChannelPressure(int chan, int value) override; virtual void sendPitchBend(int chan, int value) override; virtual void sendSysex(const QByteArray &data) override; virtual void sendSystemMsg(const int status) override; private: QThread m_renderingThread; SynthRenderer *m_renderer; QWaitCondition m_rendering; private: QStringList getDiagnostics(); bool getStatus(); }; }} #endif // SYNTHCONTROLLER_H drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/net-in0000644000000000000000000000013214200302440020236 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/net-in/0000755000175000001440000000000014200302440021074 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/net-in/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023053 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/net-in/CMakeLists.txt0000644000175000001440000000474614200302440023647 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . find_package(Qt${QT_VERSION_MAJOR}Network REQUIRED) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-net-in_QTOBJ_SRCS ../common/midiparser.h netmidiinput_p.h netmidiinput.h ) set(drumstick-rt-net-in_SRCS ../common/midiparser.cpp netmidiinput_p.cpp netmidiinput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-net-in_MOC_SRCS ${drumstick-rt-net-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-net-in_MOC_SRCS ${drumstick-rt-net-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-net-in STATIC ${drumstick-rt-net-in_MOC_SRCS} ${drumstick-rt-net-in_SRCS}) target_compile_definitions(drumstick-rt-net-in PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-net-in PROPERTIES STATIC_LIB "libdrumstick-rt-net-in") else() add_library(drumstick-rt-net-in MODULE ${drumstick-rt-net-in_MOC_SRCS} ${drumstick-rt-net-in_SRCS}) target_compile_definitions(drumstick-rt-net-in PRIVATE QT_PLUGIN) endif() target_include_directories(drumstick-rt-net-in PRIVATE ${Drumstick_SOURCE_DIR}/library/include ../common ) target_link_libraries(drumstick-rt-net-in PRIVATE Qt${QT_VERSION_MAJOR}::Network Drumstick::RT ) set_target_properties(drumstick-rt-net-in PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-net-in EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/net-in/PaxHeaders.27918/net-in.pro0000644000000000000000000000013214200302440022227 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/net-in/net-in.pro0000644000175000001440000000117014200302440023007 0ustar00pedrousers00000000000000TEMPLATE = lib CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } TARGET = drumstick-rt-net-in DESTDIR = ../../../build/lib/drumstick2 DEPENDPATH += . ../../include ../common INCLUDEPATH += . ../../include ../common include (../../../global.pri) QT -= gui HEADERS += ../common/midiparser.h \ netmidiinput.h \ netmidiinput_p.h SOURCES += netmidiinput.cpp \ netmidiinput_p.cpp \ ../common/midiparser.cpp QT += network macx:!static:LIBS += -F$$OUT_PWD/../../../build/lib -framework drumstick-rt else:LIBS += -L$$OUT_PWD/../../../build/lib -l$$drumstickLib(drumstick-rt) drumstick-2.5.1/library/rt-backends/net-in/PaxHeaders.27918/netmidiinput_p.h0000644000000000000000000000013214200302440023514 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/net-in/netmidiinput_p.h0000644000175000001440000000335014200302440024276 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef NETMIDIINPUT_P_H #define NETMIDIINPUT_P_H #include #include #include #include "midiparser.h" namespace drumstick { namespace rt { class MIDIOutput; class NetMIDIInput; class NetMIDIInputPrivate : public QObject { Q_OBJECT public: NetMIDIInput *m_inp; MIDIOutput *m_out; QUdpSocket *m_socket; MIDIParser *m_parser; int m_thruEnabled; quint16 m_port; QString m_publicName; QHostAddress m_groupAddress; MIDIConnection m_currentInput; QList m_inputDevices; QStringList m_excludedNames; QNetworkInterface m_iface; bool m_ipv6; bool m_status; QStringList m_diagnostics; explicit NetMIDIInputPrivate(QObject *parent = nullptr); void open(const MIDIConnection& conn); void close(); void initialize(QSettings* settings); void setMIDIThruDevice(MIDIOutput* device); public slots: void processIncomingMessages(); }; }} #endif // NETMIDIINPUT_P_H drumstick-2.5.1/library/rt-backends/net-in/PaxHeaders.27918/netmidiinput_p.cpp0000644000000000000000000000013214200302440024047 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/net-in/netmidiinput_p.cpp0000644000175000001440000001065414200302440024636 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "netmidiinput.h" #include "netmidiinput_p.h" namespace drumstick { namespace rt { NetMIDIInputPrivate::NetMIDIInputPrivate(QObject *parent) : QObject(parent), m_inp(qobject_cast(parent)), m_out(nullptr), m_socket(nullptr), m_parser(nullptr), m_thruEnabled(false), m_port(0), m_publicName(NetMIDIInput::DEFAULT_PUBLIC_NAME), m_groupAddress(QHostAddress(NetMIDIInput::STR_ADDRESS_IPV4)), m_ipv6(false), m_status(false) { for(int i=NetMIDIInput::MULTICAST_PORT; i= NetMIDIInput::MULTICAST_PORT && p < NetMIDIInput::LAST_PORT && m_status) { //qDebug() << Q_FUNC_INFO << portName; m_socket = new QUdpSocket(); m_parser = new MIDIParser(m_inp); m_port = static_cast(p); m_currentInput = portName; bool res = m_socket->bind(m_ipv6 ? QHostAddress::AnyIPv6 : QHostAddress::AnyIPv4, m_port, QUdpSocket::ShareAddress); if (res) { #ifdef Q_OS_WIN // https://docs.microsoft.com/es-es/windows/desktop/WinSock/ip-multicast-2 m_socket->setSocketOption(QAbstractSocket::MulticastLoopbackOption, 0); #endif if (m_iface.isValid()) { res = m_socket->joinMulticastGroup(m_groupAddress, m_iface); } else { res = m_socket->joinMulticastGroup(m_groupAddress); } connect(m_socket, &QUdpSocket::readyRead, this, &NetMIDIInputPrivate::processIncomingMessages); m_status = m_socket->isValid(); } else { m_status = false; m_diagnostics << QString("Socket error. err: %1 = %2").arg(m_socket->error()).arg(m_socket->errorString()); } } } void NetMIDIInputPrivate::close() { delete m_socket; delete m_parser; m_socket = nullptr; m_parser = nullptr; m_currentInput = MIDIConnection(); m_status = false; m_diagnostics.clear(); } void NetMIDIInputPrivate::initialize(QSettings *settings) { if (settings != nullptr) { m_status = false; m_diagnostics.clear(); settings->beginGroup("Network"); QString ifaceName = settings->value("interface", QString()).toString(); m_ipv6 = settings->value("ipv6", false).toBool(); QString address = settings->value("address", m_ipv6 ? NetMIDIInput::STR_ADDRESS_IPV6 : NetMIDIInput::STR_ADDRESS_IPV4).toString(); settings->endGroup(); if (!ifaceName.isEmpty()) { m_iface = QNetworkInterface::interfaceFromName(ifaceName); } if (address.isEmpty()) { m_groupAddress.setAddress(m_ipv6 ? NetMIDIInput::STR_ADDRESS_IPV6 : NetMIDIInput::STR_ADDRESS_IPV4); } else { m_groupAddress.setAddress(address); } m_status = m_groupAddress.isMulticast(); if (!m_status) { m_diagnostics << QString("Invalid multicast address: %1").arg(address); } } } void NetMIDIInputPrivate::setMIDIThruDevice(MIDIOutput* device) { m_out = device; if (m_parser != nullptr) { m_parser->setMIDIThruDevice(device); } } void NetMIDIInputPrivate::processIncomingMessages() { while (m_socket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(static_cast(m_socket->pendingDatagramSize())); m_socket->readDatagram(datagram.data(), datagram.size()); if (m_parser != nullptr) { m_parser->parse(datagram); } } } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/net-in/PaxHeaders.27918/netmidiinput.cpp0000644000000000000000000000013214200302440023530 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/net-in/netmidiinput.cpp0000644000175000001440000000472114200302440024315 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "netmidiinput.h" #include "netmidiinput_p.h" #include namespace drumstick { namespace rt { const QString NetMIDIInput::DEFAULT_PUBLIC_NAME = QStringLiteral("MIDI In"); const QString NetMIDIInput::STR_ADDRESS_IPV4 = QStringLiteral("225.0.0.37"); const QString NetMIDIInput::STR_ADDRESS_IPV6 = QStringLiteral("ff12::37"); const int NetMIDIInput::MULTICAST_PORT = 21928; const int NetMIDIInput::LAST_PORT = 21948; NetMIDIInput::NetMIDIInput(QObject *parent): MIDIInput(parent), d(new NetMIDIInputPrivate(this)) { } void NetMIDIInput::initialize(QSettings *settings) { d->initialize(settings); } QString NetMIDIInput::backendName() { return QStringLiteral("Network"); } QString NetMIDIInput::publicName() { return d->m_publicName; } void NetMIDIInput::setPublicName(QString name) { d->m_publicName = name; } QList NetMIDIInput::connections(bool advanced) { Q_UNUSED(advanced) return d->m_inputDevices; } void NetMIDIInput::setExcludedConnections(QStringList conns) { d->m_excludedNames = conns; } void NetMIDIInput::open(const MIDIConnection& name) { d->open(name); } void NetMIDIInput::close() { d->close(); } MIDIConnection NetMIDIInput::currentConnection() { return d->m_currentInput; } void NetMIDIInput::setMIDIThruDevice(MIDIOutput *device) { d->setMIDIThruDevice(device); } void NetMIDIInput::enableMIDIThru(bool enable) { d->m_thruEnabled = enable; } bool NetMIDIInput::isEnabledMIDIThru() { return d->m_thruEnabled && (d->m_out != nullptr); } QStringList NetMIDIInput::getDiagnostics() { return d->m_diagnostics; } bool NetMIDIInput::getStatus() { return d->m_status; } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/net-in/PaxHeaders.27918/netmidiinput.h0000644000000000000000000000013214200302440023175 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/net-in/netmidiinput.h0000644000175000001440000000470214200302440023761 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef NETMIDIINPUT_H #define NETMIDIINPUT_H #include #include #include #include namespace drumstick { namespace rt { class NetMIDIInputPrivate; class NetMIDIInput : public MIDIInput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput/2.0") Q_INTERFACES(drumstick::rt::MIDIInput) Q_PROPERTY(QStringList diagnostics READ getDiagnostics) Q_PROPERTY(bool status READ getStatus) public: explicit NetMIDIInput(QObject *parent = nullptr); // MIDIInput interface public: virtual void initialize(QSettings* settings) override; virtual QString backendName() override; virtual QString publicName() override; virtual void setPublicName(QString name) override; virtual QList connections(bool advanced) override; virtual void setExcludedConnections(QStringList conns) override; virtual void open(const MIDIConnection& name) override; virtual void close() override; virtual MIDIConnection currentConnection() override; virtual void setMIDIThruDevice(MIDIOutput *device) override; virtual void enableMIDIThru(bool enable) override; virtual bool isEnabledMIDIThru() override; static const QString DEFAULT_PUBLIC_NAME; static const QString STR_ADDRESS_IPV4; static const QString STR_ADDRESS_IPV6; static const int MULTICAST_PORT; static const int LAST_PORT; private: NetMIDIInputPrivate * const d; private: QStringList getDiagnostics(); bool getStatus(); }; }} #endif // NETMIDIINPUT_H drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/fluidsynth0000644000000000000000000000013214200302440021235 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/fluidsynth/0000755000175000001440000000000014200302440022073 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/fluidsynth/PaxHeaders.27918/synthengine.h0000644000000000000000000000013214200302440024016 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/fluidsynth/synthengine.h0000644000175000001440000001021314200302440024574 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #ifndef SynthEngine_H #define SynthEngine_H #include #include #include #include #include #include #include #include namespace drumstick { namespace rt { class SynthEngine : public QObject { Q_OBJECT Q_PROPERTY(QString soundFont READ soundFont WRITE setSoundFont) public: explicit SynthEngine(QObject *parent = nullptr); virtual ~SynthEngine(); QString soundFont() const { return m_soundFont; } void setSoundFont(const QString &value); void appendDiagnostics(int level, const char* message); void stop(); Q_INVOKABLE void initialize(); Q_INVOKABLE void readSettings(QSettings *settings); Q_INVOKABLE void scanSoundFonts(); Q_INVOKABLE void panic(); Q_INVOKABLE void setInstrument(const int channel, int i); Q_INVOKABLE void noteOn(const int channel, const int midiNote, const int velocity); Q_INVOKABLE void noteOff(const int channel, const int midiNote, const int velocity); Q_INVOKABLE void controlChange(const int channel, const int ctl, const int value); Q_INVOKABLE void bender(const int channel, const int value); Q_INVOKABLE QString version() const { return QT_STRINGIFY(VERSION); } MIDIConnection currentConnection() const { return m_currentConnection; } void close(); void open(); void uninitialize(); QStringList getAudioDrivers(); QStringList getDiagnostics(); QString getLibVersion(); bool getStatus(); static const QString QSTR_FLUIDSYNTH_VERSION; static const QString QSTR_FLUIDSYNTH; static const QString QSTR_PREFERENCES; static const QString QSTR_INSTRUMENTSDEFINITION; static const QString QSTR_DATADIR; static const QString QSTR_DATADIR2; static const QString QSTR_SOUNDFONT; static const QString QSTR_AUDIODRIVER; static const QString QSTR_PERIODSIZE; static const QString QSTR_PERIODS; static const QString QSTR_SAMPLERATE; static const QString QSTR_CHORUS; static const QString QSTR_REVERB; static const QString QSTR_GAIN; static const QString QSTR_POLYPHONY; static const QString QSTR_DEFAULT_AUDIODRIVER; static const QString QSTR_BUFFERTIME; static const int DEFAULT_PERIODS; static const int DEFAULT_PERIODSIZE; static const double DEFAULT_SAMPLERATE; static const int DEFAULT_CHORUS; static const int DEFAULT_REVERB; static const double DEFAULT_GAIN; static const int DEFAULT_POLYPHONY; private: void scanSoundFonts(const QDir &dir); void retrieveAudioDrivers(); void initializeSynth(); void loadSoundFont(); void internalInitialize(); int m_sfid; MIDIConnection m_currentConnection; QString m_runtimeLibraryVersion; QString m_soundFont; QString m_defSoundFont; fluid_settings_t* m_settings; fluid_synth_t* m_synth; fluid_audio_driver_t* m_driver; QStringList m_soundFontsList; QStringList m_audioDriversList; QString fs_audiodriver{ QSTR_DEFAULT_AUDIODRIVER }; int fs_periodSize { DEFAULT_PERIODSIZE }; int fs_periods { DEFAULT_PERIODS }; double fs_sampleRate { DEFAULT_SAMPLERATE }; int fs_chorus { DEFAULT_CHORUS }; int fs_reverb { DEFAULT_REVERB }; double fs_gain { DEFAULT_GAIN }; int fs_polyphony { DEFAULT_POLYPHONY }; bool m_status; QStringList m_diagnostics; }; }} // namespace drumstick::rt #endif // SynthEngine_H drumstick-2.5.1/library/rt-backends/fluidsynth/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440024052 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/fluidsynth/CMakeLists.txt0000644000175000001440000000471214200302440024637 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-fluidsynth_QTOBJ_SRCS synthengine.h synthoutput.h ) set(drumstick-rt-fluidsynth_SRCS synthengine.cpp synthoutput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-fluidsynth_MOC_SRCS ${drumstick-rt-fluidsynth_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-fluidsynth_MOC_SRCS ${drumstick-rt-fluidsynth_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-fluidsynth STATIC ${drumstick-rt-fluidsynth_MOC_SRCS} ${drumstick-rt-fluidsynth_SRCS}) target_compile_definitions(drumstick-rt-fluidsynth PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-fluidsynth PROPERTIES STATIC_LIB "libdrumstick-rt-fluidsynth") else() add_library(drumstick-rt-fluidsynth MODULE ${drumstick-rt-fluidsynth_MOC_SRCS} ${drumstick-rt-fluidsynth_SRCS}) target_compile_definitions(drumstick-rt-fluidsynth PRIVATE QT_PLUGIN) endif() target_include_directories(drumstick-rt-fluidsynth PRIVATE ${Drumstick_SOURCE_DIR}/library/include ) target_link_libraries(drumstick-rt-fluidsynth PRIVATE Qt${QT_VERSION_MAJOR}::Core Drumstick::RT PkgConfig::FLUIDSYNTH ) set_target_properties(drumstick-rt-fluidsynth PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-fluidsynth EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/fluidsynth/PaxHeaders.27918/synthoutput.cpp0000644000000000000000000000013214200302440024444 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/fluidsynth/synthoutput.cpp0000644000175000001440000000643014200302440025230 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "synthoutput.h" namespace drumstick { namespace rt { SynthOutput::SynthOutput(QObject *parent) : MIDIOutput(parent) { //qDebug() << Q_FUNC_INFO; m_synth = new SynthEngine; } SynthOutput::~SynthOutput() { //qDebug() << Q_FUNC_INFO; stop(); delete m_synth; } void SynthOutput::start() { m_synth->initialize(); } void SynthOutput::stop() { m_synth->stop(); } QStringList SynthOutput::getAudioDrivers() { return m_synth->getAudioDrivers(); } QStringList SynthOutput::getDiagnostics() { return m_synth->getDiagnostics(); } QString SynthOutput::getLibVersion() { return m_synth->getLibVersion(); } bool SynthOutput::getStatus() { return m_synth->getStatus(); } void SynthOutput::initialize(QSettings *settings) { //qDebug() << Q_FUNC_INFO; m_synth->readSettings(settings); stop(); start(); } QString SynthOutput::backendName() { return SynthEngine::QSTR_FLUIDSYNTH; } QString SynthOutput::publicName() { return SynthEngine::QSTR_FLUIDSYNTH; } void SynthOutput::setPublicName(QString name) { Q_UNUSED(name) } QList SynthOutput::connections(bool advanced) { Q_UNUSED(advanced) return QList{MIDIConnection(SynthEngine::QSTR_FLUIDSYNTH, SynthEngine::QSTR_FLUIDSYNTH)}; } void SynthOutput::setExcludedConnections(QStringList conns) { Q_UNUSED(conns) } void SynthOutput::open(const MIDIConnection& name) { Q_UNUSED(name) m_synth->open(); } void SynthOutput::close() { m_synth->close(); stop(); } MIDIConnection SynthOutput::currentConnection() { return m_synth->currentConnection(); } void SynthOutput::sendNoteOff(int chan, int note, int vel) { m_synth->noteOff(chan, note, vel); } void SynthOutput::sendNoteOn(int chan, int note, int vel) { m_synth->noteOn(chan, note, vel); } void SynthOutput::sendKeyPressure(int chan, int note, int value) { Q_UNUSED(chan) Q_UNUSED(note) Q_UNUSED(value) } void SynthOutput::sendController(int chan, int control, int value) { m_synth->controlChange(chan, control, value); } void SynthOutput::sendProgram(int chan, int program) { m_synth->setInstrument(chan, program); } void SynthOutput::sendChannelPressure(int chan, int value) { Q_UNUSED(chan) Q_UNUSED(value) } void SynthOutput::sendPitchBend(int chan, int value) { m_synth->bender(chan, value); } void SynthOutput::sendSysex(const QByteArray &data) { Q_UNUSED(data) } void SynthOutput::sendSystemMsg(const int status) { Q_UNUSED(status) } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/fluidsynth/PaxHeaders.27918/synthengine.cpp0000644000000000000000000000013214200302440024351 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/fluidsynth/synthengine.cpp0000644000175000001440000002547614200302440025150 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include #include #include #include #include "synthengine.h" namespace drumstick { namespace rt { const QString SynthEngine::QSTR_FLUIDSYNTH_VERSION = QStringLiteral(FLUIDSYNTH_VERSION); const QString SynthEngine::QSTR_FLUIDSYNTH = QStringLiteral("FluidSynth"); const QString SynthEngine::QSTR_PREFERENCES = QStringLiteral("FluidSynth"); const QString SynthEngine::QSTR_INSTRUMENTSDEFINITION = QStringLiteral("InstrumentsDefinition"); const QString SynthEngine::QSTR_DATADIR = QStringLiteral("soundfonts"); const QString SynthEngine::QSTR_DATADIR2 = QStringLiteral("sounds/sf2"); const QString SynthEngine::QSTR_SOUNDFONT = QStringLiteral("default.sf2"); const QString SynthEngine::QSTR_AUDIODRIVER = QStringLiteral("AudioDriver"); const QString SynthEngine::QSTR_BUFFERTIME = QStringLiteral("BufferTime"); const QString SynthEngine::QSTR_PERIODSIZE = QStringLiteral("PeriodSize"); const QString SynthEngine::QSTR_PERIODS = QStringLiteral("Periods"); const QString SynthEngine::QSTR_SAMPLERATE = QStringLiteral("SampleRate"); const QString SynthEngine::QSTR_CHORUS = QStringLiteral("Chorus"); const QString SynthEngine::QSTR_REVERB = QStringLiteral("Reverb"); const QString SynthEngine::QSTR_GAIN = QStringLiteral("Gain"); const QString SynthEngine::QSTR_POLYPHONY = QStringLiteral("Polyphony"); const QString SynthEngine::QSTR_DEFAULT_AUDIODRIVER = #if defined(Q_OS_LINUX) QStringLiteral("pulseaudio"); #elif defined(Q_OS_WIN) QStringLiteral("dsound"); #elif defined(Q_OS_OSX) QStringLiteral("coreaudio"); #else QStringLiteral("oss"); #endif #if defined(Q_OS_WIN) const int SynthEngine::DEFAULT_PERIODS = 8; const int SynthEngine::DEFAULT_PERIODSIZE = 512; #else const int SynthEngine::DEFAULT_PERIODS = 16; const int SynthEngine::DEFAULT_PERIODSIZE = 64; #endif const double SynthEngine::DEFAULT_SAMPLERATE = 44100.0; const int SynthEngine::DEFAULT_CHORUS = 0; const int SynthEngine::DEFAULT_REVERB = 1; const double SynthEngine::DEFAULT_GAIN = .5; const int SynthEngine::DEFAULT_POLYPHONY = 256; static void SynthEngine_log_function(int level, const char* message, void* data) { SynthEngine *classInstance = static_cast(data); classInstance->appendDiagnostics(level, message); } SynthEngine::SynthEngine(QObject *parent) : QObject(parent), m_sfid(0), m_settings(nullptr), m_synth(nullptr), m_driver(nullptr) { //qDebug() << Q_FUNC_INFO; m_runtimeLibraryVersion = ::fluid_version_str(); //qDebug() << "Compiled FluidSynth Version:" << QSTR_FLUIDSYNTH_VERSION; //qDebug() << "Runtime FluidSynth Version:" << m_runtimeLibraryVersion; //::fluid_set_log_function(fluid_log_level::FLUID_DBG, &SynthEngine_log_function, this); ::fluid_set_log_function(fluid_log_level::FLUID_ERR, &SynthEngine_log_function, this); ::fluid_set_log_function(fluid_log_level::FLUID_WARN, &SynthEngine_log_function, this); ::fluid_set_log_function(fluid_log_level::FLUID_INFO, &SynthEngine_log_function, this); } SynthEngine::~SynthEngine() { //qDebug() << Q_FUNC_INFO; uninitialize(); } void SynthEngine::uninitialize() { //qDebug() << Q_FUNC_INFO; if (m_driver != nullptr) { ::delete_fluid_audio_driver(m_driver); m_driver = nullptr; } if (m_synth != nullptr) { ::delete_fluid_synth(m_synth); m_synth = nullptr; } if (m_settings != nullptr) { ::delete_fluid_settings(m_settings); m_settings = nullptr; } m_status = false; m_diagnostics.clear(); } void SynthEngine::initializeSynth() { //qDebug() << Q_FUNC_INFO; uninitialize(); m_settings = ::new_fluid_settings(); ::fluid_settings_setstr(m_settings, "audio.driver", qPrintable(fs_audiodriver)); ::fluid_settings_setint(m_settings, "audio.period-size", fs_periodSize); ::fluid_settings_setint(m_settings, "audio.periods", fs_periods); if (fs_audiodriver == "pulseaudio") { ::fluid_settings_setint(m_settings, "audio.pulseaudio.adjust-latency", 1); } ::fluid_settings_setnum(m_settings, "synth.sample-rate", fs_sampleRate); ::fluid_settings_setint(m_settings, "synth.chorus.active", fs_chorus); ::fluid_settings_setint(m_settings, "synth.reverb.active", fs_reverb); ::fluid_settings_setnum(m_settings, "synth.gain", fs_gain); ::fluid_settings_setint(m_settings, "synth.polyphony", fs_polyphony); m_synth = ::new_fluid_synth(m_settings); m_driver = ::new_fluid_audio_driver(m_settings, m_synth); } void SynthEngine::setInstrument(int channel, int pgm) { ::fluid_synth_program_change(m_synth, channel, pgm); } void SynthEngine::noteOn(int channel, int midiNote, int velocity) { ::fluid_synth_noteon(m_synth, channel, midiNote, velocity); } void SynthEngine::noteOff(int channel, int midiNote, int /*velocity*/) { ::fluid_synth_noteoff(m_synth, channel, midiNote); } void SynthEngine::loadSoundFont() { if (m_sfid != -1) { ::fluid_synth_sfunload(m_synth, unsigned(m_sfid), 1); } m_sfid = ::fluid_synth_sfload(m_synth, qPrintable(m_soundFont), 1); } void SynthEngine::initialize() { initializeSynth(); retrieveAudioDrivers(); scanSoundFonts(); loadSoundFont(); m_status = (m_synth != nullptr) && (m_driver != nullptr) && (m_sfid >= 0); } void SynthEngine::panic() { ::fluid_synth_system_reset(m_synth); } void SynthEngine::controlChange(const int channel, const int midiCtl, const int value) { ::fluid_synth_cc(m_synth, channel, midiCtl, value); } void SynthEngine::bender(const int channel, const int value) { ::fluid_synth_pitch_bend(m_synth, channel, value + 8192); } void SynthEngine::setSoundFont(const QString &value) { if (value != m_soundFont) { m_soundFont = value; loadSoundFont(); } } void SynthEngine::appendDiagnostics(int level, const char *message) { static const QMap prefix { {fluid_log_level::FLUID_DBG, tr("Debug")}, {fluid_log_level::FLUID_ERR, tr("Error")}, {fluid_log_level::FLUID_WARN, tr("Warning")}, {fluid_log_level::FLUID_INFO, tr("Information")} }; m_diagnostics.append(prefix[level]+": "+message); } void SynthEngine::stop() { //qDebug() << Q_FUNC_INFO; uninitialize(); } QStringList SynthEngine::getAudioDrivers() { return m_audioDriversList; } QStringList SynthEngine::getDiagnostics() { return m_diagnostics; } QString SynthEngine::getLibVersion() { return m_runtimeLibraryVersion; } bool SynthEngine::getStatus() { return m_status; } void SynthEngine::scanSoundFonts(const QDir &initialDir) { QDir dir(initialDir); dir.setFilter(QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot); dir.setSorting(QDir::Name); QStringList filters; filters << "*.sf2" << "*.SF2" << "*.sf3" << "*.SF3" << "*.dls" << "*.DLS"; QFileInfoList entries= dir.entryInfoList(filters); foreach(const QFileInfo &info, entries) { QString name = info.absoluteFilePath(); if (info.isFile() && info.fileName().toLower() == QSTR_SOUNDFONT) { m_soundFontsList << name; } else if (info.isDir()){ scanSoundFonts(name); } } } void SynthEngine::retrieveAudioDrivers() { if (m_settings != nullptr) { m_audioDriversList.clear(); ::fluid_settings_foreach_option(m_settings, "audio.driver", &m_audioDriversList, [](void *context2, const char *, const char *option2){ QStringList *options_list = static_cast(context2); options_list->append(option2); }); //qDebug() << "Drivers: " << m_audioDriversList; } } void SynthEngine::scanSoundFonts() { m_soundFontsList.clear(); QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); #if defined(Q_OS_OSX) paths << (QCoreApplication::applicationDirPath() + QLatin1String("../Resources")); #endif foreach(const QString& p, paths) { QDir d(p + QDir::separator() + QSTR_DATADIR); if (!d.exists()) { d = QDir(p + QDir::separator() + QSTR_DATADIR2); } if (d.exists()) { scanSoundFonts(d); } } if (m_defSoundFont.isEmpty() && m_soundFontsList.length() > 0) { m_defSoundFont = m_soundFontsList.first(); } } void SynthEngine::readSettings(QSettings *settings) { QDir dir; #if defined(Q_OS_OSX) dir = QDir(QCoreApplication::applicationDirPath() + QLatin1String("/../Resources")); #elif defined(Q_OS_UNIX) dir = QDir(QCoreApplication::applicationDirPath() + QLatin1String("/../share/soundfonts/")); if (!dir.exists()) { dir = QDir(QCoreApplication::applicationDirPath() + QLatin1String("/../share/sounds/sf2/")); } #else dir = QDir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR, QStandardPaths::LocateDirectory)); #endif QFileInfo sf2(dir, QSTR_SOUNDFONT); if (sf2.exists()) { m_defSoundFont = sf2.absoluteFilePath(); } m_sfid = -1; //qDebug() << "defSoundFont:" << m_defSoundFont; settings->beginGroup(QSTR_PREFERENCES); m_soundFont = settings->value(QSTR_INSTRUMENTSDEFINITION, m_defSoundFont).toString(); fs_audiodriver = settings->value(QSTR_AUDIODRIVER, QSTR_DEFAULT_AUDIODRIVER).toString(); fs_periodSize = settings->value(QSTR_PERIODSIZE, DEFAULT_PERIODSIZE).toInt(); fs_periods = settings->value(QSTR_PERIODS, DEFAULT_PERIODS).toInt(); fs_sampleRate = settings->value(QSTR_SAMPLERATE, DEFAULT_SAMPLERATE).toDouble(); fs_chorus = settings->value(QSTR_CHORUS, DEFAULT_CHORUS).toInt(); fs_reverb = settings->value(QSTR_REVERB, DEFAULT_REVERB).toInt(); fs_gain = settings->value(QSTR_GAIN, DEFAULT_GAIN).toDouble(); fs_polyphony = settings->value(QSTR_POLYPHONY, DEFAULT_POLYPHONY).toInt(); settings->endGroup(); //qDebug() << Q_FUNC_INFO << "audioDriver:" << fs_audiodriver << "buffer" << fs_periodSize << '*' << fs_periods; } void SynthEngine::close() { m_currentConnection = MIDIConnection(); } void SynthEngine::open() { m_currentConnection = MIDIConnection(QSTR_FLUIDSYNTH, QSTR_FLUIDSYNTH); } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/fluidsynth/PaxHeaders.27918/fluidsynth.pro0000644000000000000000000000013214200302440024225 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/fluidsynth/fluidsynth.pro0000644000175000001440000000125614200302440025012 0ustar00pedrousers00000000000000TEMPLATE = lib TARGET = $$qtLibraryTarget(drumstick-rt-fluidsynth) DESTDIR = ../../../build/lib/drumstick2 include (../../../global.pri) CONFIG += c++11 plugin #create_prl DEPENDPATH += ../../include INCLUDEPATH += ../../include QT -= gui HEADERS += synthengine.h \ synthoutput.h SOURCES += synthoutput.cpp synthengine.cpp LIBS += -L$$OUT_PWD/../../../build/lib -ldrumstick-rt macx { INCLUDEPATH += /Library/Frameworks/FluidSynth.framework/Headers QMAKE_LFLAGS += -F/Library/Frameworks LIBS += -framework FluidSynth } else { CONFIG += link_pkgconfig packagesExist(fluidsynth) { PKGCONFIG += fluidsynth } } win32 { TARGET_EXT = .dll } drumstick-2.5.1/library/rt-backends/fluidsynth/PaxHeaders.27918/synthoutput.h0000644000000000000000000000013214200302440024111 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/fluidsynth/synthoutput.h0000644000175000001440000000573514200302440024704 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SynthOUTPUT_H #define SynthOUTPUT_H #include #include #include #include #include "synthengine.h" namespace drumstick { namespace rt { class SynthOutput : public MIDIOutput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput/2.0") Q_INTERFACES(drumstick::rt::MIDIOutput) Q_PROPERTY(QStringList audiodrivers READ getAudioDrivers) Q_PROPERTY(QStringList diagnostics READ getDiagnostics) Q_PROPERTY(QString libversion READ getLibVersion) Q_PROPERTY(bool status READ getStatus) public: explicit SynthOutput(QObject *parent = nullptr); virtual ~SynthOutput(); void start(); void stop(); // MIDIOutput interface public: virtual void initialize(QSettings* settings) override; virtual QString backendName() override; virtual QString publicName() override; virtual void setPublicName(QString name) override; virtual QList connections(bool advanced) override; virtual void setExcludedConnections(QStringList conns) override; virtual void open(const MIDIConnection& name) override; virtual void close() override; virtual MIDIConnection currentConnection() override; public slots: virtual void sendNoteOff(int chan, int note, int vel) override; virtual void sendNoteOn(int chan, int note, int vel) override; virtual void sendKeyPressure(int chan, int note, int value) override; virtual void sendController(int chan, int control, int value) override; virtual void sendProgram(int chan, int program) override; virtual void sendChannelPressure(int chan, int value) override; virtual void sendPitchBend(int chan, int value) override; virtual void sendSysex(const QByteArray &data) override; virtual void sendSystemMsg(const int status) override; private: QPointer m_synth; private: QStringList getAudioDrivers(); QStringList getDiagnostics(); QString getLibVersion(); bool getStatus(); }; }} // namespace drumstick::rt #endif // SynthOUTPUT_H drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/dummy-in0000644000000000000000000000013214200302440020603 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/dummy-in/0000755000175000001440000000000014200302440021441 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/dummy-in/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023420 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/dummy-in/CMakeLists.txt0000644000175000001440000000455014200302440024205 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-dummy-in_QTOBJ_SRCS dummyinput.h ) set(drumstick-rt-dummy-in_SRCS dummyinput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-dummy-in_MOC_SRCS ${drumstick-rt-dummy-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-dummy-in_MOC_SRCS ${drumstick-rt-dummy-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-dummy-in STATIC ${drumstick-rt-dummy-in_MOC_SRCS} ${drumstick-rt-dummy-in_SRCS} ) target_compile_definitions(drumstick-rt-dummy-in PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-dummy-in PROPERTIES STATIC_LIB "libdrumstick-rt-dummy-in") else() add_library(drumstick-rt-dummy-in MODULE ${drumstick-rt-dummy-in_MOC_SRCS} ${drumstick-rt-dummy-in_SRCS} ) target_compile_definitions(drumstick-rt-dummy-in PRIVATE QT_PLUGIN) endif() target_link_libraries(drumstick-rt-dummy-in PUBLIC Qt${QT_VERSION_MAJOR}::Core Drumstick::RT ) target_include_directories(drumstick-rt-dummy-in PRIVATE ${Drumstick_SOURCE_DIR}/library/include ) set_target_properties(drumstick-rt-dummy-in PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-dummy-in EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/dummy-in/PaxHeaders.27918/dummy-in.pro0000644000000000000000000000013214200302440023141 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/dummy-in/dummy-in.pro0000644000175000001440000000056514200302440023730 0ustar00pedrousers00000000000000TEMPLATE = lib TARGET = drumstick-rt-dummy-in DESTDIR = ../../../build/lib/drumstick2 include (../../../global.pri) CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } DEPENDPATH += ../../include INCLUDEPATH += ../../include QT -= gui HEADERS += dummyinput.h SOURCES += dummyinput.cpp LIBS += -L$$OUT_PWD/../../../build/lib -l$$drumstickLib(drumstick-rt) drumstick-2.5.1/library/rt-backends/dummy-in/PaxHeaders.27918/dummyinput.cpp0000644000000000000000000000013214200302440023577 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/dummy-in/dummyinput.cpp0000644000175000001440000000331514200302440024362 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "dummyinput.h" namespace drumstick { namespace rt { void DummyInput::initialize(QSettings* settings) { Q_UNUSED(settings) } QString DummyInput::backendName() { return QStringLiteral("DUMMY"); } QString DummyInput::publicName() { return QStringLiteral("DUMMY In"); } void DummyInput::setPublicName(QString name) { Q_UNUSED(name) } QList DummyInput::connections(bool advanced) { Q_UNUSED(advanced) return QList(); } void DummyInput::setExcludedConnections(QStringList conns) { Q_UNUSED(conns) } MIDIConnection DummyInput::currentConnection() { return MIDIConnection(); } void DummyInput::open(const MIDIConnection& conn) { Q_UNUSED(conn) } void DummyInput::close() { } void DummyInput::setMIDIThruDevice(MIDIOutput *device) { Q_UNUSED(device) } void DummyInput::enableMIDIThru(bool enable) { Q_UNUSED(enable) } bool DummyInput::isEnabledMIDIThru() { return false; } }} drumstick-2.5.1/library/rt-backends/dummy-in/PaxHeaders.27918/dummyinput.h0000644000000000000000000000013214200302440023244 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/dummy-in/dummyinput.h0000644000175000001440000000360314200302440024027 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DUMMYINPUT_H #define DUMMYINPUT_H #include #include #include namespace drumstick { namespace rt { class DummyInput : public MIDIInput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput/2.0") Q_INTERFACES(drumstick::rt::MIDIInput) public: explicit DummyInput(QObject *parent = nullptr) : MIDIInput(parent) {} virtual ~DummyInput() = default; // MIDIInput interface public: virtual void initialize(QSettings* settings); virtual QString backendName(); virtual QString publicName(); virtual void setPublicName(QString name); virtual QList connections(bool advanced); virtual void setExcludedConnections(QStringList conns); virtual void open(const MIDIConnection& name); virtual void close(); virtual MIDIConnection currentConnection(); virtual void setMIDIThruDevice(MIDIOutput *device); virtual void enableMIDIThru(bool enable); virtual bool isEnabledMIDIThru(); }; }} #endif // DUMMYINPUT_H drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/rt-backends.pro0000644000000000000000000000013214200302440022040 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/rt-backends.pro0000644000175000001440000000101214200302440022613 0ustar00pedrousers00000000000000TEMPLATE = subdirs #dummy { # SUBDIRS += dummy-in dummy-out #} linux { SUBDIRS += alsa-in alsa-out } unix:!macx { SUBDIRS += oss-in oss-out } macx { SUBDIRS += mac-in mac-out macsynth exists(/Library/Frameworks/FluidSynth.framework/Headers/*) { SUBDIRS += fluidsynth } } else { packagesExist(fluidsynth) { SUBDIRS += fluidsynth } packagesExist(libpulse-simple) { SUBDIRS += eassynth } } win32 { SUBDIRS += win-in win-out } SUBDIRS += net-in net-out drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/win-in0000644000000000000000000000013214200302440020245 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/win-in/0000755000175000001440000000000014200302440021103 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/win-in/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023062 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/win-in/CMakeLists.txt0000644000175000001440000000454314200302440023651 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-win-in_QTOBJ_SRCS winmidiinput.h ) set(drumstick-rt-win-in_SRCS winmidiinput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-win-in_MOC_SRCS ${drumstick-rt-win-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-win-in_MOC_SRCS ${drumstick-rt-win-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-win-in STATIC ${drumstick-rt-win-in_MOC_SRCS} ${drumstick-rt-win-in_SRCS}) target_compile_definitions(drumstick-rt-win-in PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-win-in PROPERTIES STATIC_LIB "libdrumstick-rt-win-in") else() add_library(drumstick-rt-win-in MODULE ${drumstick-rt-win-in_MOC_SRCS} ${drumstick-rt-win-in_SRCS}) target_compile_definitions(drumstick-rt-win-in PRIVATE QT_PLUGIN) endif() target_link_libraries(drumstick-rt-win-in PUBLIC Qt${QT_VERSION_MAJOR}::Core Drumstick::RT PRIVATE winmm ) target_include_directories(drumstick-rt-win-in PRIVATE ${Drumstick_SOURCE_DIR}/library/include) set_target_properties(drumstick-rt-win-in PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-win-in EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/win-in/PaxHeaders.27918/winmidiinput.h0000644000000000000000000000013214200302440023213 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/win-in/winmidiinput.h0000644000175000001440000000417614200302440024004 0ustar00pedrousers00000000000000/* Drumstick RT Windows Backend Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef WINMIDIINPUT_H #define WINMIDIINPUT_H #include #include #include namespace drumstick { namespace rt { class WinMIDIInput : public MIDIInput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput/2.0") Q_INTERFACES(drumstick::rt::MIDIInput) Q_PROPERTY(QStringList diagnostics READ getDiagnostics) Q_PROPERTY(bool status READ getStatus); public: class WinMIDIInputPrivate; explicit WinMIDIInput(QObject *parent = nullptr); virtual ~WinMIDIInput(); // MIDIInput interface public: virtual void initialize(QSettings* settings); virtual QString backendName(); virtual QString publicName(); virtual void setPublicName(QString name); virtual QList connections(bool advanced); virtual void setExcludedConnections(QStringList conns); virtual void open(const MIDIConnection& name); virtual void close(); virtual MIDIConnection currentConnection(); virtual void setMIDIThruDevice(MIDIOutput *device); virtual void enableMIDIThru(bool enable); virtual bool isEnabledMIDIThru(); private: WinMIDIInputPrivate * const d; private: QStringList getDiagnostics(); bool getStatus(); }; }} #endif // WINMIDIINPUT_H drumstick-2.5.1/library/rt-backends/win-in/PaxHeaders.27918/winmidiinput.cpp0000644000000000000000000000013214200302440023546 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/win-in/winmidiinput.cpp0000644000175000001440000002512214200302440024331 0ustar00pedrousers00000000000000/* Drumstick RT Windows Backend Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "winmidiinput.h" #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #define right Qt::right #define left Qt::left #define hex Qt::hex #define dec Qt::dec #define endl Qt::endl #endif namespace drumstick { namespace rt { static QLatin1String DEFAULT_PUBLIC_NAME = QLatin1String("MIDI In"); void CALLBACK midiCallback( HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 ); class WinMIDIInput::WinMIDIInputPrivate { public: WinMIDIInput *m_inp; MIDIOutput *m_out; bool m_thruEnabled; bool m_clientFilter; HMIDIIN m_handle; QString m_publicName; MIDIConnection m_currentInput; QStringList m_excludedNames; QList m_inputDevices; bool m_status; QStringList m_diagnostics; explicit WinMIDIInputPrivate(WinMIDIInput *inp): m_inp(inp), m_out(nullptr), m_thruEnabled(false), m_clientFilter(true), m_handle(nullptr), m_publicName(DEFAULT_PUBLIC_NAME) { reloadDeviceList(true); } void open(const MIDIConnection &conn) { MMRESULT res; m_status = false; m_diagnostics.clear(); if (conn != m_currentInput) { if (m_handle != nullptr) close(); reloadDeviceList(!m_clientFilter); if (!conn.first.isEmpty()) { res = midiInOpen(&m_handle, conn.second.toInt(), (DWORD_PTR) midiCallback, (DWORD_PTR) this, CALLBACK_FUNCTION | MIDI_IO_STATUS ); if (res != MMSYSERR_NOERROR) { logError("midiInOpen()",res); } else { res = midiInStart(m_handle); if (res != MMSYSERR_NOERROR) { logError("midiInStart()",res); } } m_currentInput = conn; m_status = (res == MMSYSERR_NOERROR); } } } void close() { MMRESULT res; m_status = false; m_diagnostics.clear(); if (m_handle != nullptr) { res = midiInStop(m_handle); if (res != MMSYSERR_NOERROR) logError("midiInStop()", res); res = midiInReset( m_handle ); if (res != MMSYSERR_NOERROR) logError("midiInReset()", res); res = midiInClose( m_handle ); if (res != MMSYSERR_NOERROR) logError("midiInClose()", res); m_handle = nullptr; } m_currentInput = MIDIConnection(); } void reloadDeviceList(bool advanced) { MMRESULT res; MIDIINCAPS deviceCaps; QString devName; unsigned int dev, max = midiInGetNumDevs(); m_inputDevices.clear(); m_clientFilter = !advanced; for ( dev = 0; dev < max; ++dev) { bool excluded = false; res = midiInGetDevCaps( dev, &deviceCaps, sizeof(MIDIINCAPS)); if (res != MMSYSERR_NOERROR) break; #if defined(UNICODE) devName = QString::fromWCharArray(deviceCaps.szPname); #else devName = QString::fromLocal8Bit(deviceCaps.szPname); #endif foreach (const QString& n , m_excludedNames) { if (devName.startsWith(n)) { excluded = true; break; } } if (!excluded) { m_inputDevices << MIDIConnection(devName, dev); } } } void setPublicName(QString name) { if (m_publicName != name) { m_publicName = name; } } void emitSignals(int status, int channel, int data1, int data2) { switch (status) { case MIDI_STATUS_NOTEOFF: if(m_out != nullptr && m_thruEnabled) m_out->sendNoteOff(channel, data1, data2); emit m_inp->midiNoteOff(channel, data1, data2); break; case MIDI_STATUS_NOTEON: if(m_out != nullptr && m_thruEnabled) m_out->sendNoteOn(channel, data1, data2); emit m_inp->midiNoteOn(channel, data1, data2); break; case MIDI_STATUS_KEYPRESURE: if(m_out != nullptr && m_thruEnabled) m_out->sendKeyPressure(channel, data1, data2); emit m_inp->midiKeyPressure(channel, data1, data2); break; case MIDI_STATUS_CONTROLCHANGE: if(m_out != nullptr && m_thruEnabled) m_out->sendController(channel, data1, data2); emit m_inp->midiController(channel, data1, data2); break; case MIDI_STATUS_PROGRAMCHANGE: if(m_out != nullptr && m_thruEnabled) m_out->sendProgram(channel, data1); emit m_inp->midiProgram(channel, data1); break; case MIDI_STATUS_CHANNELPRESSURE: if(m_out != nullptr && m_thruEnabled) m_out->sendChannelPressure(channel, data1); emit m_inp->midiChannelPressure(channel, data1); break; case MIDI_STATUS_PITCHBEND: { int value = (data1 + data2 * 0x80) - 8192; if(m_out != nullptr && m_thruEnabled) m_out->sendPitchBend(channel, value); emit m_inp->midiPitchBend(channel, value); } break; default: m_diagnostics << QString("MIDI in status? %1").arg(status); } } void emitSysex(QByteArray data) { if(m_out != nullptr && m_thruEnabled) m_out->sendSysex(data); emit m_inp->midiSysex(data); } QString mmErrorString(MMRESULT err) { QString errstr; #ifdef UNICODE WCHAR buffer[1024]; midiInGetErrorText(err, &buffer[0], sizeof(buffer)); errstr = QString::fromWCharArray(buffer); #else char buffer[1024]; midiOutGetErrorText(err, &buffer[0], sizeof(buffer)); errstr = QString::fromLocal8Bit(buffer); #endif return errstr; } void logError(const QString context, const MMRESULT code) { m_diagnostics << QString("%1 error: %2 (%3)").arg(context).arg(code).arg(mmErrorString(code)); } }; void CALLBACK midiCallback( HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 ) { Q_UNUSED(hMidiIn) Q_UNUSED(dwParam2) WinMIDIInput::WinMIDIInputPrivate* object = (WinMIDIInput::WinMIDIInputPrivate*) dwInstance; switch( wMsg ) { case MIM_OPEN: object->m_diagnostics << "Open input"; break; case MIM_CLOSE: object->m_diagnostics << "Close input"; break; case MIM_ERROR: case MIM_LONGERROR: object->m_diagnostics << "Errors input"; break; case MIM_LONGDATA: object->m_diagnostics << "Sysex data input"; break; case MIM_DATA: case MIM_MOREDATA: { int status = dwParam1 & 0xf0; int channel = dwParam1 & 0x0f; int data1 = (dwParam1 & 0x7f00) >> 8; int data2 = (dwParam1 & 0x7f0000) >> 16; object->emitSignals(status, channel, data1, data2); } break; default: object->m_diagnostics << QString("unknown input message: %1").arg(wMsg); break; } } WinMIDIInput::WinMIDIInput(QObject *parent) : MIDIInput(parent), d(new WinMIDIInputPrivate(this)) { } WinMIDIInput::~WinMIDIInput() { delete d; } void WinMIDIInput::initialize(QSettings *settings) { Q_UNUSED(settings) } QString WinMIDIInput::backendName() { return QLatin1String("Windows MM"); } QString WinMIDIInput::publicName() { return d->m_publicName; } void WinMIDIInput::setPublicName(QString name) { d->setPublicName(name); } QList WinMIDIInput::connections(bool advanced) { d->reloadDeviceList(advanced); return d->m_inputDevices; } void WinMIDIInput::setExcludedConnections(QStringList conns) { d->m_excludedNames = conns; } void WinMIDIInput::open(const MIDIConnection& name) { d->open(name); } void WinMIDIInput::close() { d->close(); } MIDIConnection WinMIDIInput::currentConnection() { return d->m_currentInput; } void WinMIDIInput::setMIDIThruDevice(MIDIOutput *device) { d->m_out = device; } void WinMIDIInput::enableMIDIThru(bool enable) { d->m_thruEnabled = enable; } bool WinMIDIInput::isEnabledMIDIThru() { return d->m_thruEnabled && d->m_out != nullptr; } QStringList WinMIDIInput::getDiagnostics() { return d->m_diagnostics; } bool WinMIDIInput::getStatus() { return d->m_status; } }} // namespace drumstick::rt drumstick-2.5.1/library/rt-backends/win-in/PaxHeaders.27918/win-in.pro0000644000000000000000000000013214200302440022245 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/win-in/win-in.pro0000644000175000001440000000070414200302440023027 0ustar00pedrousers00000000000000TEMPLATE = lib CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } TARGET = drumstick-rt-win-in DESTDIR = ../../../build/lib/drumstick2 DEPENDPATH += . ../../include INCLUDEPATH += . ../../include include (../../../global.pri) DEPENDPATH += ../../include INCLUDEPATH += ../../include QT -= gui HEADERS += winmidiinput.h SOURCES += winmidiinput.cpp LIBS += -lwinmm LIBS += -L$$OUT_PWD/../../../build/lib -l$$drumstickLib(drumstick-rt) drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/dummy-out0000644000000000000000000000013214200302440021004 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/dummy-out/0000755000175000001440000000000014200302440021642 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/dummy-out/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023621 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/dummy-out/CMakeLists.txt0000644000175000001440000000456414200302440024413 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-dummy-out_QTOBJ_SRCS dummyoutput.h ) set(drumstick-rt-dummy-out_SRCS dummyoutput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-dummy-out_MOC_SRCS ${drumstick-rt-dummy-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-dummy-out_MOC_SRCS ${drumstick-rt-dummy-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-dummy-out STATIC ${drumstick-rt-dummy-out_MOC_SRCS} ${drumstick-rt-dummy-out_SRCS}) target_compile_definitions(drumstick-rt-dummy-out PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-dummy-out PROPERTIES STATIC_LIB "libdrumstick-rt-dummy-out") else() add_library(drumstick-rt-dummy-out MODULE ${drumstick-rt-dummy-out_MOC_SRCS} ${drumstick-rt-dummy-out_SRCS}) target_compile_definitions(drumstick-rt-dummy-out PRIVATE QT_PLUGIN) endif() target_link_libraries(drumstick-rt-dummy-out PUBLIC Qt${QT_VERSION_MAJOR}::Core Drumstick::RT ) target_include_directories(drumstick-rt-dummy-out PRIVATE ${Drumstick_SOURCE_DIR}/library/include ) set_target_properties(drumstick-rt-dummy-out PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-dummy-out EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/dummy-out/PaxHeaders.27918/dummyoutput.h0000644000000000000000000000013214200302440023646 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/dummy-out/dummyoutput.h0000644000175000001440000000443514200302440024435 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DUMMYOUTPUT_H #define DUMMYOUTPUT_H #include #include namespace drumstick { namespace rt { class DummyOutput : public MIDIOutput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput/2.0") Q_INTERFACES(drumstick::rt::MIDIOutput) public: explicit DummyOutput(QObject *parent = nullptr) : MIDIOutput(parent) {} virtual ~DummyOutput() = default; // MIDIOutput interface public: virtual void initialize(QSettings* settings); virtual QString backendName(); virtual QString publicName(); virtual void setPublicName(QString name); virtual QList connections(bool advanced); virtual void setExcludedConnections(QStringList conns); virtual void open(const MIDIConnection& name); virtual void close(); virtual MIDIConnection currentConnection(); public slots: virtual void sendNoteOff(int chan, int note, int vel); virtual void sendNoteOn(int chan, int note, int vel); virtual void sendKeyPressure(int chan, int note, int value); virtual void sendController(int chan, int control, int value); virtual void sendProgram(int chan, int program); virtual void sendChannelPressure(int chan, int value); virtual void sendPitchBend(int chan, int value); virtual void sendSysex(const QByteArray &data); virtual void sendSystemMsg(const int status); }; }} #endif // DUMMYOUTPUT_H drumstick-2.5.1/library/rt-backends/dummy-out/PaxHeaders.27918/dummyoutput.cpp0000644000000000000000000000013214200302440024201 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/dummy-out/dummyoutput.cpp0000644000175000001440000000467314200302440024774 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "dummyoutput.h" namespace drumstick { namespace rt { void DummyOutput::initialize(QSettings* settings) { Q_UNUSED(settings) } QString DummyOutput::backendName() { return QStringLiteral("DUMMY"); } QString DummyOutput::publicName() { return QStringLiteral("DUMMY Out"); } void DummyOutput::setPublicName(QString name) { Q_UNUSED(name) } QList DummyOutput::connections(bool advanced) { Q_UNUSED(advanced) return QList(); } void DummyOutput::setExcludedConnections(QStringList conns) { Q_UNUSED(conns) } void DummyOutput::open(const MIDIConnection& conn) { Q_UNUSED(conn) } void DummyOutput::close() { } MIDIConnection DummyOutput::currentConnection() { return MIDIConnection(); } void DummyOutput::sendNoteOff(int chan, int note, int vel) { Q_UNUSED(chan) Q_UNUSED(note) Q_UNUSED(vel) } void DummyOutput::sendNoteOn(int chan, int note, int vel) { Q_UNUSED(chan) Q_UNUSED(note) Q_UNUSED(vel) } void DummyOutput::sendKeyPressure(int chan, int note, int value) { Q_UNUSED(chan) Q_UNUSED(note) Q_UNUSED(value) } void DummyOutput::sendController(int chan, int control, int value) { Q_UNUSED(chan) Q_UNUSED(control) Q_UNUSED(value) } void DummyOutput::sendProgram(int chan, int program) { Q_UNUSED(chan) Q_UNUSED(program) } void DummyOutput::sendChannelPressure(int chan, int value) { Q_UNUSED(chan) Q_UNUSED(value) } void DummyOutput::sendPitchBend(int chan, int value) { Q_UNUSED(chan) Q_UNUSED(value) } void DummyOutput::sendSysex(const QByteArray &data) { Q_UNUSED(data) } void DummyOutput::sendSystemMsg(const int status) { Q_UNUSED(status) } }} drumstick-2.5.1/library/rt-backends/dummy-out/PaxHeaders.27918/dummy-out.pro0000644000000000000000000000013214200302440023543 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/dummy-out/dummy-out.pro0000644000175000001440000000057014200302440024326 0ustar00pedrousers00000000000000TEMPLATE = lib TARGET = drumstick-rt-dummy-out DESTDIR = ../../../build/lib/drumstick2 include (../../../global.pri) CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } DEPENDPATH += ../../include INCLUDEPATH += ../../include QT -= gui HEADERS += dummyoutput.h SOURCES += dummyoutput.cpp LIBS += -L$$OUT_PWD/../../../build/lib -l$$drumstickLib(drumstick-rt) drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/win-out0000644000000000000000000000013214200302440020446 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/win-out/0000755000175000001440000000000014200302440021304 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/win-out/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023263 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/win-out/CMakeLists.txt0000644000175000001440000000457114200302440024053 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-win-out_QTOBJ_SRCS winmidioutput.h ) set(drumstick-rt-win-out_SRCS winmidioutput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-win-out_MOC_SRCS ${drumstick-rt-win-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-win-out_MOC_SRCS ${drumstick-rt-win-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-win-out STATIC ${drumstick-rt-win-out_MOC_SRCS} ${drumstick-rt-win-out_SRCS}) target_compile_definitions(drumstick-rt-win-out PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-win-out PROPERTIES STATIC_LIB "libdrumstick-rt-win-out") else() add_library(drumstick-rt-win-out MODULE ${drumstick-rt-win-out_MOC_SRCS} ${drumstick-rt-win-out_SRCS}) target_compile_definitions(drumstick-rt-win-out PRIVATE QT_PLUGIN) endif() target_include_directories(drumstick-rt-win-out PRIVATE ${Drumstick_SOURCE_DIR}/library/include) target_link_libraries(drumstick-rt-win-out PUBLIC Qt${QT_VERSION_MAJOR}::Core Drumstick::RT PRIVATE winmm ) set_target_properties(drumstick-rt-win-out PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-win-out EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/win-out/PaxHeaders.27918/winmidioutput.h0000644000000000000000000000013214200302440023615 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/win-out/winmidioutput.h0000644000175000001440000000501714200302440024401 0ustar00pedrousers00000000000000/* Drumstick RT Windows Backend Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef WINMIDIOUTPUT_H #define WINMIDIOUTPUT_H #include #include namespace drumstick { namespace rt { class WinMIDIOutput : public MIDIOutput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput/2.0") Q_INTERFACES(drumstick::rt::MIDIOutput) Q_PROPERTY(QStringList diagnostics READ getDiagnostics) Q_PROPERTY(bool status READ getStatus); public: class WinMIDIOutputPrivate; explicit WinMIDIOutput(QObject *parent = nullptr); virtual ~WinMIDIOutput(); // MIDIOutput interface virtual void initialize(QSettings* settings); virtual QString backendName(); virtual QString publicName(); virtual void setPublicName(QString name); virtual QList connections(bool advanced); virtual void setExcludedConnections(QStringList conns); virtual void open(const MIDIConnection& name); virtual void close(); virtual MIDIConnection currentConnection(); public slots: virtual void sendNoteOff(int chan, int note, int vel); virtual void sendNoteOn(int chan, int note, int vel); virtual void sendKeyPressure(int chan, int note, int value); virtual void sendController(int chan, int control, int value); virtual void sendProgram(int chan, int program); virtual void sendChannelPressure(int chan, int value); virtual void sendPitchBend(int chan, int value); virtual void sendSysex(const QByteArray &data); virtual void sendSystemMsg(const int status); private: WinMIDIOutputPrivate * const d; private: QStringList getDiagnostics(); bool getStatus(); }; }} #endif // WINMIDIOUTPUT_H drumstick-2.5.1/library/rt-backends/win-out/PaxHeaders.27918/win-out.pro0000644000000000000000000000013214200302440022647 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/win-out/win-out.pro0000644000175000001440000000070714200302440023434 0ustar00pedrousers00000000000000TEMPLATE = lib CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } TARGET = drumstick-rt-win-out DESTDIR = ../../../build/lib/drumstick2 DEPENDPATH += . ../../include INCLUDEPATH += . ../../include include (../../../global.pri) DEPENDPATH += ../../include INCLUDEPATH += ../../include QT -= gui HEADERS += winmidioutput.h SOURCES += winmidioutput.cpp LIBS += -lwinmm LIBS += -L$$OUT_PWD/../../../build/lib -l$$drumstickLib(drumstick-rt) drumstick-2.5.1/library/rt-backends/win-out/PaxHeaders.27918/winmidioutput.cpp0000644000000000000000000000013214200302440024150 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/win-out/winmidioutput.cpp0000644000175000001440000002672714200302440024747 0ustar00pedrousers00000000000000/* Drumstick RT Windows Backend Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "winmidioutput.h" #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #define hex Qt::hex #endif namespace drumstick { namespace rt { union WinMIDIPacket { WinMIDIPacket() : dwPacket(0) {} DWORD dwPacket; quint8 data[sizeof(DWORD)]; }; static QLatin1String DEFAULT_PUBLIC_NAME = QLatin1String("MIDI Out"); void CALLBACK midiCallback( HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2); class WinMIDIOutput::WinMIDIOutputPrivate { public: HMIDIOUT m_handle; bool m_clientFilter; QString m_publicName; MIDIConnection m_currentOutput; QList m_outputDevices; MIDIHDR m_midiSysexHdr; QByteArray m_sysexBuffer; QStringList m_excludedNames; bool m_status; QStringList m_diagnostics; WinMIDIOutputPrivate(): m_handle(nullptr), m_clientFilter(true), m_publicName(DEFAULT_PUBLIC_NAME) { reloadDeviceList(true); } void reloadDeviceList(bool advanced) { MMRESULT res; MIDIOUTCAPS deviceCaps; QString devName; unsigned int dev, max = midiOutGetNumDevs(); m_outputDevices.clear(); m_clientFilter = !advanced; for ( dev = 0; dev < max; ++dev) { bool excluded = false; res = midiOutGetDevCaps( dev, &deviceCaps, sizeof(MIDIOUTCAPS)); if (res != MMSYSERR_NOERROR) break; if (m_clientFilter && (deviceCaps.wTechnology == MOD_MAPPER || dev == MIDI_MAPPER)) continue; #if defined(UNICODE) devName = QString::fromWCharArray(deviceCaps.szPname); #else devName = QString::fromLocal8Bit(deviceCaps.szPname); #endif foreach (const QString& n, m_excludedNames) { if (devName.startsWith(n)) { excluded = true; break; } } if (!excluded) { m_outputDevices << MIDIConnection(devName, dev); } } if (!m_clientFilter) { dev = MIDI_MAPPER; res = midiOutGetDevCaps( dev, &deviceCaps, sizeof(MIDIOUTCAPS)); if (res == MMSYSERR_NOERROR) { #if defined(UNICODE) devName = QString::fromWCharArray(deviceCaps.szPname); #else devName = QString::fromLocal8Bit(deviceCaps.szPname); #endif m_outputDevices << MIDIConnection(devName, dev); } } } void setPublicName(QString name) { if (m_publicName != name) { m_publicName = name; } } void open(const MIDIConnection& conn) { MMRESULT res; m_status = false; m_diagnostics.clear(); if (m_handle != nullptr) close(); reloadDeviceList(!m_clientFilter); if (!conn.first.isEmpty()) { res = midiOutOpen( &m_handle, conn.second.toInt(), (DWORD_PTR) midiCallback, (DWORD_PTR) this, CALLBACK_FUNCTION); if (res == MMSYSERR_NOERROR) { m_currentOutput = conn; m_status = true; } else { logError("midiStreamOpen()", res); } } } void close() { MMRESULT res; m_status = false; m_diagnostics.clear(); if (m_handle != nullptr) { res = midiOutReset( m_handle ); if (res != MMSYSERR_NOERROR) logError("midiOutReset()", res); res = midiOutClose( m_handle ); if (res == MMSYSERR_NOERROR) m_currentOutput = MIDIConnection(); else logError("midiStreamClose()", res); m_handle = nullptr; } } void doneHeader( LPMIDIHDR lpMidiHdr ) { MMRESULT res; res = midiOutUnprepareHeader( m_handle, lpMidiHdr, sizeof(MIDIHDR) ); if (res != MMSYSERR_NOERROR) logError("midiOutUnprepareHeader()", res); if ((lpMidiHdr->dwFlags & MHDR_ISSTRM) == 0) return; // sysex header? } void sendShortMessage(WinMIDIPacket &packet) { MMRESULT res; res = midiOutShortMsg( m_handle, packet.dwPacket ); if ( res != MMSYSERR_NOERROR ) logError("midiOutShortMsg()", res); } void sendSysexEvent(const QByteArray& data) { MMRESULT res; m_sysexBuffer = data; m_midiSysexHdr.lpData = (LPSTR) m_sysexBuffer.data(); m_midiSysexHdr.dwBufferLength = m_sysexBuffer.size(); m_midiSysexHdr.dwBytesRecorded = m_sysexBuffer.size(); m_midiSysexHdr.dwFlags = 0; m_midiSysexHdr.dwUser = 0; res = midiOutPrepareHeader( m_handle, &m_midiSysexHdr, sizeof(MIDIHDR) ); if (res != MMSYSERR_NOERROR) logError("midiOutPrepareHeader()", res); else { res = midiOutLongMsg( m_handle, &m_midiSysexHdr, sizeof(MIDIHDR) ); if (res != MMSYSERR_NOERROR) logError("midiOutLongMsg()", res); } } QString mmErrorString(MMRESULT err) { QString errstr; #ifdef UNICODE WCHAR buffer[1024]; midiOutGetErrorText(err, &buffer[0], sizeof(buffer)); errstr = QString::fromWCharArray(buffer); #else char buffer[1024]; midiOutGetErrorText(err, &buffer[0], sizeof(buffer)); errstr = QString::fromLocal8Bit(buffer); #endif return errstr; } void logError(const QString context, const MMRESULT code) { m_diagnostics << QString("%1 error: %2 (%3)").arg(context).arg(code).arg(mmErrorString(code)); } }; void CALLBACK midiCallback( HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { Q_UNUSED(hmo) Q_UNUSED(dwParam2) WinMIDIOutput::WinMIDIOutputPrivate* obj = (WinMIDIOutput::WinMIDIOutputPrivate*) dwInstance; switch( wMsg ) { case MOM_DONE: obj->doneHeader( (LPMIDIHDR) dwParam1 ); break; case MOM_OPEN: obj->m_diagnostics << "Open output"; break; case MOM_CLOSE: obj->m_diagnostics << "Close output"; break; default: obj->m_diagnostics << QString("unknown output message: %1").arg(wMsg); break; } } WinMIDIOutput::WinMIDIOutput(QObject *parent) : MIDIOutput(parent), d(new WinMIDIOutputPrivate) { } WinMIDIOutput::~WinMIDIOutput() { delete d; } void WinMIDIOutput::initialize(QSettings *settings) { Q_UNUSED(settings) } QString WinMIDIOutput::backendName() { return "Windows MM"; } QString WinMIDIOutput::publicName() { return d->m_publicName; } void WinMIDIOutput::setPublicName(QString name) { d->setPublicName(name); } QList WinMIDIOutput::connections(bool advanced) { d->reloadDeviceList(advanced); return d->m_outputDevices; } void WinMIDIOutput::setExcludedConnections(QStringList conns) { d->m_excludedNames = conns; } void WinMIDIOutput::open(const MIDIConnection& name) { d->open(name); } void WinMIDIOutput::close() { d->close(); } MIDIConnection WinMIDIOutput::currentConnection() { return d->m_currentOutput; } void WinMIDIOutput::sendNoteOn(int chan, int note, int vel) { WinMIDIPacket packet; packet.data[0] = MIDI_STATUS_NOTEON | (chan & MIDI_CHANNEL_MASK); packet.data[1] = note; packet.data[2] = vel; d->sendShortMessage(packet); } void WinMIDIOutput::sendNoteOff(int chan, int note, int vel) { WinMIDIPacket packet; packet.data[0] = MIDI_STATUS_NOTEOFF | (chan & MIDI_CHANNEL_MASK); packet.data[1] = note; packet.data[2] = vel; d->sendShortMessage(packet); } void WinMIDIOutput::sendController(int chan, int control, int value) { WinMIDIPacket packet; packet.data[0] = MIDI_STATUS_CONTROLCHANGE | (chan & MIDI_CHANNEL_MASK); packet.data[1] = control; packet.data[2] = value; d->sendShortMessage(packet); } void WinMIDIOutput::sendKeyPressure(int chan, int note, int value) { WinMIDIPacket packet; packet.data[0] = MIDI_STATUS_KEYPRESURE | (chan & MIDI_CHANNEL_MASK); packet.data[1] = note; packet.data[2] = value; d->sendShortMessage(packet); } void WinMIDIOutput::sendProgram(int chan, int program) { WinMIDIPacket packet; packet.data[0] = MIDI_STATUS_PROGRAMCHANGE | (chan & MIDI_CHANNEL_MASK); packet.data[1] = program; d->sendShortMessage(packet); } void WinMIDIOutput::sendChannelPressure(int chan, int value) { WinMIDIPacket packet; packet.data[0] = MIDI_STATUS_CHANNELPRESSURE | (chan & MIDI_CHANNEL_MASK); packet.data[1] = value; d->sendShortMessage(packet); } void WinMIDIOutput::sendPitchBend(int chan, int v) { WinMIDIPacket packet; // -8192 <= v <= 8191; 0 <= value <= 16384 int value = 8192 + v; packet.data[0] = MIDI_STATUS_PITCHBEND | (chan & MIDI_CHANNEL_MASK); packet.data[1] = MIDI_LSB(value); packet.data[2] = MIDI_MSB(value); d->sendShortMessage(packet); } void WinMIDIOutput::sendSystemMsg(const int status) { WinMIDIPacket packet; packet.data[0] = status; d->sendShortMessage(packet); } void WinMIDIOutput::sendSysex(const QByteArray &data) { d->sendSysexEvent(data); } QStringList WinMIDIOutput::getDiagnostics() { return d->m_diagnostics; } bool WinMIDIOutput::getStatus() { return d->m_status; } }} drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/macsynth0000644000000000000000000000013214200302440020672 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.357324521 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/macsynth/0000755000175000001440000000000014200302440021530 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/macsynth/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023507 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.357324521 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/macsynth/CMakeLists.txt0000644000175000001440000000510214200302440024266 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-macsynth_QTOBJ_SRCS macsynth.h ) set(drumstick-rt-macsynth_SRCS ../common/maccommon.h ../common/maccommon.mm macsynth.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-macsynth_MOC_SRCS ${drumstick-rt-macsynth_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-macsynth_MOC_SRCS ${drumstick-rt-macsynth_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-macsynth STATIC ${drumstick-rt-macsynth_MOC_SRCS} ${drumstick-rt-macsynth_SRCS}) target_compile_definitions(drumstick-rt-macsynth PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-macsynth PROPERTIES STATIC_LIB "libdrumstick-rt-macsynth") else() add_library(drumstick-rt-macsynth MODULE ${drumstick-rt-macsynth_MOC_SRCS} ${drumstick-rt-macsynth_SRCS}) target_compile_definitions(drumstick-rt-macsynth PRIVATE QT_PLUGIN) endif() target_link_libraries(drumstick-rt-macsynth PUBLIC Drumstick::RT Qt${QT_VERSION_MAJOR}::Core "-framework CoreMIDI -framework CoreFoundation -framework CoreServices -framework Foundation -framework CoreAudio -framework AudioToolbox -framework AudioUnit" ) target_include_directories(drumstick-rt-macsynth PRIVATE ${Drumstick_SOURCE_DIR}/library/include ../common ) set_target_properties(drumstick-rt-macsynth PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-macsynth EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/macsynth/PaxHeaders.27918/macsynth.h0000644000000000000000000000013214200302440022746 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.357324521 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/macsynth/macsynth.h0000644000175000001440000000504114200302440023527 0ustar00pedrousers00000000000000/* Drumstick RT Mac OSX Backend Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DLSSOFTSYNTH_H #define DLSSOFTSYNTH_H #include #include #include namespace drumstick { namespace rt { class MacSynthOutput : public MIDIOutput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput/2.0") Q_INTERFACES(drumstick::rt::MIDIOutput) Q_PROPERTY(QStringList diagnostics READ getDiagnostics) Q_PROPERTY(bool status READ getStatus); public: explicit MacSynthOutput(QObject *parent = nullptr); virtual ~MacSynthOutput(); // MIDIOutput interface public: virtual void initialize(QSettings* settings); virtual QString backendName(); virtual QString publicName(); virtual void setPublicName(QString name); virtual QList connections(bool advanced); virtual void setExcludedConnections(QStringList conns); virtual void open(const MIDIConnection& name); virtual void close(); virtual MIDIConnection currentConnection(); public slots: virtual void sendNoteOff(int chan, int note, int vel); virtual void sendNoteOn(int chan, int note, int vel); virtual void sendKeyPressure(int chan, int note, int value); virtual void sendController(int chan, int control, int value); virtual void sendProgram(int chan, int program); virtual void sendChannelPressure(int chan, int value); virtual void sendPitchBend(int chan, int value); virtual void sendSysex(const QByteArray &data); virtual void sendSystemMsg(const int status); private: class MacSynthOutputPrivate; MacSynthOutputPrivate* const d; QStringList getDiagnostics(); bool getStatus(); }; }} #endif // MACSYNTH_H drumstick-2.5.1/library/rt-backends/macsynth/PaxHeaders.27918/macsynth.pro0000644000000000000000000000013214200302440023317 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.357324521 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/macsynth/macsynth.pro0000644000175000001440000000101714200302440024077 0ustar00pedrousers00000000000000TEMPLATE = lib CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } TARGET = drumstick-rt-macsynth DESTDIR = ../../../build/lib/drumstick2 DEPENDPATH += . ../../include INCLUDEPATH += . ../../include include (../../../global.pri) QT -= gui HEADERS += macsynth.h SOURCES += macsynth.cpp !static:LIBS += -F$$OUT_PWD/../../../build/lib -framework drumstick-rt LIBS += -framework CoreMIDI -framework CoreFoundation -framework CoreServices LIBS += -framework CoreAudio -framework AudioToolbox -framework AudioUnit drumstick-2.5.1/library/rt-backends/macsynth/PaxHeaders.27918/macsynth.cpp0000644000000000000000000000013214200302440023301 xustar0030 mtime=1644266784.813324173 30 atime=1644266785.357324521 30 ctime=1644266784.813324173 drumstick-2.5.1/library/rt-backends/macsynth/macsynth.cpp0000644000175000001440000003263114200302440024067 0ustar00pedrousers00000000000000/* Drumstick RT Mac OSX Backend Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "macsynth.h" #include "maccommon.h" #include #include #include #define PRETTY_NAME "DLS Synth" namespace drumstick { namespace rt { class MacSynthOutput::MacSynthOutputPrivate { private: AUGraph m_graph; AudioUnit m_synthUnit; MIDIConnection m_connection; QString m_soundfont_dls; bool m_default_dls; bool m_reverb_dls; public: bool m_status; QStringList m_diagnostics; public: explicit MacSynthOutputPrivate(): m_graph(nullptr), m_synthUnit(nullptr), m_default_dls(true), m_reverb_dls(false) { //qDebug() << Q_FUNC_INFO; m_connection = MIDIConnection(); } ~MacSynthOutputPrivate() { //qDebug() << Q_FUNC_INFO; stop(); } void registerStatus(const QString& context, const OSStatus status) { if (status != noErr) { m_diagnostics << QString("%1 error: %2").arg(context).arg(status); m_diagnostics << getErrorTextFromOSStatus(status); } } bool useDefaultDls() const { return m_default_dls; } void setDefaultDlsFlag(const bool f) { if (f != m_default_dls) { m_default_dls = f; } } bool useReverb() const { return m_reverb_dls; } void setReverbFlag(const bool f) { if (f != m_reverb_dls) { m_reverb_dls = f; } } QString soundFontDls() const { return m_soundfont_dls; } void setSoundFontDls(const QString& sf) { if (sf != m_soundfont_dls) { m_soundfont_dls = sf; } } MIDIConnection currentConnection() { return m_connection; } void start () { OSStatus result; AudioComponentDescription cd; UInt32 usesReverb; AUNode synthNode = 0; AUNode outputNode = 0; AUNode limiterNode = 0; m_status = false; m_diagnostics.clear(); //qDebug() << Q_FUNC_INFO; if (m_graph == nullptr) { cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; result = NewAUGraph (&m_graph); registerStatus("NewAUGraph", result); if (result != noErr) return; cd.componentType = kAudioUnitType_MusicDevice; cd.componentSubType = kAudioUnitSubType_DLSSynth; result = AUGraphAddNode (m_graph, &cd, &synthNode); registerStatus( "AUGraphAddNode", result); cd.componentType = kAudioUnitType_Effect; cd.componentSubType = kAudioUnitSubType_PeakLimiter; result = AUGraphAddNode(m_graph, &cd, &limiterNode); registerStatus( "AUGraphAddNode", result); cd.componentType = kAudioUnitType_Output; cd.componentSubType = kAudioUnitSubType_DefaultOutput; result = AUGraphAddNode (m_graph, &cd, &outputNode); registerStatus( "AUGraphAddNode", result); result = AUGraphOpen (m_graph); registerStatus( "AUGraphOpen", result); if (result != noErr) return; result = AUGraphConnectNodeInput (m_graph, synthNode, 0, limiterNode, 0); registerStatus( "AUGraphConnectNodeInput", result); result = AUGraphConnectNodeInput (m_graph, limiterNode, 0, outputNode, 0); registerStatus( "AUGraphConnectNodeInput", result); result = AUGraphNodeInfo (m_graph, synthNode, nullptr, &m_synthUnit); registerStatus( "AUGraphNodeInfo", result); if (!m_default_dls && !m_soundfont_dls.isEmpty()) { QByteArray utf8file = m_soundfont_dls.toUtf8(); CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, reinterpret_cast(utf8file.data()), utf8file.length(), false); if (url) { // kMusicDeviceProperty_SoundBankURL since 10.5 result = AudioUnitSetProperty(m_synthUnit, kMusicDeviceProperty_SoundBankURL, kAudioUnitScope_Global, 0, &url, sizeof(url)); registerStatus( "AudioUnitSetProperty(SoundBankURL)", result); CFRelease(url); if (result != noErr) { return; } } } usesReverb = (m_reverb_dls ? 1 : 0); //qDebug() << "usesReverb =" << usesReverb; result = AudioUnitSetProperty ( m_synthUnit, kMusicDeviceProperty_UsesInternalReverb, kAudioUnitScope_Global, 0, &usesReverb, sizeof (usesReverb) ); registerStatus( "AudioUnitSetProperty(UsesInternalReverb)", result); result = AUGraphInitialize (m_graph); registerStatus( "AUGraphInitialize", result); if (result != noErr) { return; } for (uint i = 0; i < 16; ++i) { result = MusicDeviceMIDIEvent(m_synthUnit, MIDI_STATUS_CONTROLCHANGE+i, MIDI_CONTROL_MSB_MAIN_VOLUME,100,0); registerStatus( "MusicDeviceMIDIEvent", result ); result = MusicDeviceMIDIEvent(m_synthUnit, MIDI_STATUS_CONTROLCHANGE+i, MIDI_CONTROL_REVERB_SEND,100,0); registerStatus( "MusicDeviceMIDIEvent", result ); result = MusicDeviceMIDIEvent(m_synthUnit, MIDI_STATUS_CONTROLCHANGE+i, MIDI_CONTROL_MSB_BANK_SELECT,0,0); registerStatus( "MusicDeviceMIDIEvent", result ); result = MusicDeviceMIDIEvent(m_synthUnit, MIDI_STATUS_CONTROLCHANGE+i, MIDI_CONTROL_LSB_BANK_SELECT,0,0); registerStatus( "MusicDeviceMIDIEvent", result ); result = MusicDeviceMIDIEvent(m_synthUnit, MIDI_STATUS_PROGRAMCHANGE+i, 0,0,0); registerStatus( "MusicDeviceMIDIEvent", result ); } result = AUGraphStart (m_graph); registerStatus( "AUGraphStart", result); if (result != noErr) { return; } } m_status = (result == noErr); m_connection = MIDIConnection(QStringLiteral(PRETTY_NAME), QStringLiteral(PRETTY_NAME)); } void stop () { OSStatus result; m_status = false; m_diagnostics.clear(); //qDebug() << Q_FUNC_INFO; if (m_graph != nullptr) { result = AUGraphStop(m_graph); if (result != noErr) { registerStatus("AUGraphStop()", result); } result = AUGraphClose(m_graph); if (result != noErr) { registerStatus("AUGraphClose()", result); } result = DisposeAUGraph(m_graph); if (result != noErr) { registerStatus("DisposeAUGraph()", result); } m_graph = nullptr; } m_connection = MIDIConnection(); m_status = true; } void initialize ( QSettings *settings ) { //qDebug() << Q_FUNC_INFO; settings->beginGroup(PRETTY_NAME); m_default_dls = settings->value("default_dls", true).toBool(); m_reverb_dls = settings->value("reverb_dls", false).toBool(); m_soundfont_dls = settings->value("soundfont_dls").toString(); //qDebug() << "default_dls:" << m_default_dls; //qDebug() << "reverb_dls:" << m_reverb_dls; //qDebug() << "soundfont_dls" << m_soundfont_dls; settings->endGroup(); } void sendStatusEvent(uint status, uint data1, uint data2) { MusicDeviceMIDIEvent ( m_synthUnit, status, data1, data2, 0 ); } void sendSysexEvent(Byte *msg, uint msglen) { MusicDeviceSysEx ( m_synthUnit, msg, msglen ); } }; MacSynthOutput::MacSynthOutput(QObject *parent): MIDIOutput(parent), d(new MacSynthOutputPrivate) { } MacSynthOutput::~MacSynthOutput() { delete d; } void MacSynthOutput::initialize(QSettings* settings) { d->initialize(settings); } QString MacSynthOutput::backendName() { return QStringLiteral(PRETTY_NAME); } QString MacSynthOutput::publicName() { return QStringLiteral(PRETTY_NAME); } void MacSynthOutput::setPublicName(QString name) { Q_UNUSED(name) } QList MacSynthOutput::connections(bool advanced) { Q_UNUSED(advanced) return QList{MIDIConnection(QStringLiteral(PRETTY_NAME),QStringLiteral(PRETTY_NAME))}; } void MacSynthOutput::setExcludedConnections(QStringList conns) { Q_UNUSED(conns) } void MacSynthOutput::open(const MIDIConnection& name) { Q_UNUSED(name) //qDebug() << Q_FUNC_INFO; d->start(); } void MacSynthOutput::close() { //qDebug() << Q_FUNC_INFO; d->stop(); } MIDIConnection MacSynthOutput::currentConnection() { return d->currentConnection(); } void MacSynthOutput::sendNoteOn(int chan, int note, int vel) { uint status, data1, data2; status = MIDI_STATUS_NOTEON | (chan & 0x0f); data1 = static_cast(note); data2 = static_cast(vel); d->sendStatusEvent(status, data1, data2); } void MacSynthOutput::sendNoteOff(int chan, int note, int vel) { uint status, data1, data2; status = MIDI_STATUS_NOTEOFF | (chan & 0x0f); data1 = static_cast(note); data2 = static_cast(vel); d->sendStatusEvent(status, data1, data2); } void MacSynthOutput::sendController(int chan, int control, int value) { uint status, data1, data2; status = MIDI_STATUS_CONTROLCHANGE | (chan & 0x0f); data1 = static_cast(control); data2 = static_cast(value); d->sendStatusEvent(status, data1, data2); } void MacSynthOutput::sendKeyPressure(int chan, int note, int value) { uint status, data1, data2; status = MIDI_STATUS_KEYPRESURE | (chan & 0x0f); data1 = static_cast(note); data2 = static_cast(value); d->sendStatusEvent(status, data1, data2); } void MacSynthOutput::sendProgram(int chan, int program) { uint status, data1, data2; status = MIDI_STATUS_PROGRAMCHANGE | (chan & 0x0f); data1 = static_cast(program); data2 = 0; d->sendStatusEvent(status, data1, data2); } void MacSynthOutput::sendChannelPressure(int chan, int value) { uint status, data1, data2; status = MIDI_STATUS_CHANNELPRESSURE | (chan & 0x0f); data1 = static_cast(value); data2 = 0; d->sendStatusEvent(status, data1, data2); } void MacSynthOutput::sendPitchBend(int chan, int value) { uint status, data1, data2; quint16 val = static_cast(value + 8192); // value between -8192 and +8191 status = MIDI_STATUS_PITCHBEND | (chan & 0x0f); data1 = MIDI_LSB(val); // LSB data2 = MIDI_MSB(val); // MSB d->sendStatusEvent(status, data1, data2); } void MacSynthOutput::sendSysex(const QByteArray& data) { d->sendSysexEvent(reinterpret_cast(const_cast(data.data())), static_cast(data.length())); } void MacSynthOutput::sendSystemMsg(const int status) { d->sendStatusEvent(static_cast(status), 0, 0); } QStringList MacSynthOutput::getDiagnostics() { return d->m_diagnostics; } bool MacSynthOutput::getStatus() { return d->m_status; } }} drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/alsa-in0000644000000000000000000000013214200302440020370 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/alsa-in/0000755000175000001440000000000014200302440021226 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/alsa-in/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023205 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/alsa-in/CMakeLists.txt0000644000175000001440000000435414200302440023774 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-alsa-in_QTOBJ_SRCS alsamidiinput.h ) set(drumstick-rt-alsa-in_SRCS alsamidiinput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-alsa-in_MOC_SRCS ${drumstick-rt-alsa-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-alsa-in_MOC_SRCS ${drumstick-rt-alsa-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-alsa-in STATIC ${drumstick-rt-alsa-in_MOC_SRCS} ${drumstick-rt-alsa-in_SRCS}) target_compile_definitions(drumstick-rt-alsa-in PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-alsa-in PROPERTIES STATIC_LIB "libdrumstick-rt-alsa-in") else() add_library(drumstick-rt-alsa-in MODULE ${drumstick-rt-alsa-in_MOC_SRCS} ${drumstick-rt-alsa-in_SRCS}) target_compile_definitions(drumstick-rt-alsa-in PRIVATE QT_PLUGIN) endif() target_link_libraries(drumstick-rt-alsa-in PRIVATE Qt${QT_VERSION_MAJOR}::Core Drumstick::ALSA ) set_target_properties(drumstick-rt-alsa-in PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-alsa-in EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/alsa-in/PaxHeaders.27918/alsa-in.pro0000644000000000000000000000013214200302440022513 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/alsa-in/alsa-in.pro0000644000175000001440000000063514200302440023300 0ustar00pedrousers00000000000000TEMPLATE = lib CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } TARGET = drumstick-rt-alsa-in DESTDIR = ../../../build/lib/drumstick2 DEPENDPATH += . ../../include INCLUDEPATH += . ../../include include (../../../global.pri) QT -= gui HEADERS += alsamidiinput.h SOURCES += alsamidiinput.cpp LIBS += -L../../../build/lib \ -ldrumstick-rt \ -ldrumstick-alsa \ -lasound drumstick-2.5.1/library/rt-backends/alsa-in/PaxHeaders.27918/alsamidiinput.h0000644000000000000000000000013214200302440023461 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/alsa-in/alsamidiinput.h0000644000175000001440000000445414200302440024251 0ustar00pedrousers00000000000000/* Drumstick RT Backend using the ALSA Sequencer Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ALSAMIDIInput_H #define ALSAMIDIInput_H #include #include #include namespace drumstick { namespace rt { class ALSAMIDIInput: public MIDIInput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput/2.0") Q_INTERFACES(drumstick::rt::MIDIInput) Q_PROPERTY(QStringList diagnostics READ getDiagnostics) Q_PROPERTY(bool status READ getStatus) public: explicit ALSAMIDIInput(QObject *parent = nullptr); virtual ~ALSAMIDIInput(); // MIDIInput interface virtual void initialize(QSettings* settings) override; virtual QString backendName() override; virtual QString publicName() override; virtual void setPublicName(QString name) override; virtual QList connections(bool advanced) override; virtual void setExcludedConnections(QStringList conns) override; virtual void open(const MIDIConnection& conn) override; virtual void close() override; virtual MIDIConnection currentConnection() override; virtual void setMIDIThruDevice(MIDIOutput *device) override; virtual void enableMIDIThru(bool enable) override; virtual bool isEnabledMIDIThru() override; static const QString DEFAULT_PUBLIC_NAME; private: class ALSAMIDIInputPrivate; ALSAMIDIInputPrivate * const d; private: QStringList getDiagnostics(); bool getStatus(); }; }} #endif /* ALSAMIDIInput_H */ drumstick-2.5.1/library/rt-backends/alsa-in/PaxHeaders.27918/alsamidiinput.cpp0000644000000000000000000000013214200302440024014 xustar0030 mtime=1644266784.793324161 30 atime=1644266785.357324521 30 ctime=1644266784.793324161 drumstick-2.5.1/library/rt-backends/alsa-in/alsamidiinput.cpp0000644000175000001440000003272414200302440024605 0ustar00pedrousers00000000000000/* Drumstick RT Backend using the ALSA Sequencer Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "alsamidiinput.h" #include #include #include #include #include #include namespace drumstick { namespace rt { using namespace ALSA; const QString ALSAMIDIInput::DEFAULT_PUBLIC_NAME = QStringLiteral("MIDI In"); class ALSAMIDIInput::ALSAMIDIInputPrivate : public SequencerEventHandler { public: ALSAMIDIInput *m_inp; MIDIOutput *m_out; MidiClient *m_client; MidiPort *m_port; int m_portId; int m_clientId; bool m_thruEnabled; bool m_clientFilter; int m_runtimeAlsaNum; QString m_publicName; MIDIConnection m_currentInput; QList m_inputDevices; QStringList m_excludedNames; bool m_initialized; bool m_status; QStringList m_diagnostics; explicit ALSAMIDIInputPrivate(ALSAMIDIInput *inp) : m_inp(inp), m_out(nullptr), m_client(nullptr), m_port(nullptr), m_portId(-1), m_clientId(-1), m_thruEnabled(false), m_clientFilter(false), m_publicName(ALSAMIDIInput::DEFAULT_PUBLIC_NAME), m_initialized(false), m_status(false) { m_runtimeAlsaNum = getRuntimeALSALibraryNumber(); } virtual ~ALSAMIDIInputPrivate() { if (m_initialized) { clearSubscription(); uninitialize(); } } void initialize() { //qDebug() << Q_FUNC_INFO << m_initialized; if (!m_initialized) { m_client = new MidiClient(m_inp); m_client->open(); m_client->setClientName(m_publicName); m_port = m_client->createPort(); m_port->setPortName("in"); m_port->setCapability( SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE ); m_port->setPortType( SND_SEQ_PORT_TYPE_APPLICATION | SND_SEQ_PORT_TYPE_MIDI_GENERIC ); m_clientId = m_client->getClientId(); m_portId = m_port->getPortId(); m_port->setTimestamping(false); m_port->setTimestampReal(false); m_client->setHandler(this); m_initialized = true; m_status = true; m_diagnostics.clear(); m_client->startSequencerInput(); } } void uninitialize() { //qDebug() << Q_FUNC_INFO << m_initialized; if (m_initialized) { if (m_port != nullptr) { m_port->detach(); delete m_port; m_port = nullptr; } if (m_client != nullptr) { m_client->close(); delete m_client; m_client = nullptr; } m_initialized = false; m_status = false; m_diagnostics.clear(); } } bool clientIsAdvanced(int clientId) { // asking for runtime version instead of SND_LIB_VERSION if (m_runtimeAlsaNum < 0x01000B) // ALSA <= 1.0.10 return (clientId < 64); else // ALSA >= 1.0.11 return (clientId < 16); } void reloadDeviceList(bool advanced) { QStringList clientNames; QMap namesMap; if (!m_initialized) { initialize(); } auto inputs = m_client->getAvailableInputs(); m_clientFilter = !advanced; m_inputDevices.clear(); m_inputDevices << MIDIConnection(); for (const PortInfo& p : qAsConst(inputs)) { QString name = p.getClientName(); clientNames << name; if (namesMap.contains(name)) { namesMap[name]++; } else { namesMap.insert(name, 1); } } for (PortInfo& p : inputs) { bool excluded = false; QString name = p.getClientName(); if (m_clientFilter && clientIsAdvanced(p.getClient())) continue; if ( m_clientFilter && name.startsWith(QStringLiteral("Virtual Raw MIDI")) ) continue; if ( name.startsWith(m_publicName) ) continue; for (const QString& n : qAsConst(m_excludedNames)) { if (name.startsWith(n)) { excluded = true; break; } } if (!excluded) { int k = clientNames.count(name) + 1; QString addr = QString("%1:%2").arg(p.getClient()).arg(p.getPort()); if (k > 2) { m_inputDevices << MIDIConnection(QString("%1 (%2)").arg(name).arg(k - namesMap[name]--), addr); } else { m_inputDevices << MIDIConnection(name, addr); } } } if (!m_currentInput.first.isEmpty() && !m_inputDevices.contains(m_currentInput)) { m_currentInput = MIDIConnection(); } } bool setSubscription(const MIDIConnection &newDevice) { if (!m_initialized) { initialize(); } if (m_inputDevices.contains(newDevice)) { m_currentInput = newDevice; m_port->unsubscribeAll(); m_port->subscribeFrom(newDevice.second.toString()); return true; } return false; } void clearSubscription() { if (!m_currentInput.first.isEmpty() && m_initialized) { m_client->stopSequencerInput(); m_port->unsubscribeAll(); m_currentInput = MIDIConnection(); } } void setPublicName(QString newName) { if (newName != m_publicName) { m_publicName = newName; if(m_initialized) { m_client->setClientName(newName); } } } void handleSequencerEvent(SequencerEvent* ev) override { if ( !SequencerEvent::isConnectionChange(ev) && m_initialized) switch(ev->getSequencerType()) { case SND_SEQ_EVENT_NOTEOFF: { const NoteOffEvent* n = static_cast(ev); if(m_out != nullptr && m_thruEnabled) { m_out->sendNoteOff(n->getChannel(), n->getKey(), n->getVelocity()); } emit m_inp->midiNoteOff(n->getChannel(), n->getKey(), n->getVelocity()); } break; case SND_SEQ_EVENT_NOTEON: { const NoteOnEvent* n = static_cast(ev); if(m_out != nullptr && m_thruEnabled) { m_out->sendNoteOn(n->getChannel(), n->getKey(), n->getVelocity()); } emit m_inp->midiNoteOn(n->getChannel(), n->getKey(), n->getVelocity()); } break; case SND_SEQ_EVENT_KEYPRESS: { const KeyPressEvent* n = static_cast(ev); if(m_out != nullptr && m_thruEnabled) { m_out->sendKeyPressure(n->getChannel(), n->getKey(), n->getVelocity()); } emit m_inp->midiKeyPressure(n->getChannel(), n->getKey(), n->getVelocity()); } break; case SND_SEQ_EVENT_CONTROLLER: case SND_SEQ_EVENT_CONTROL14: { const ControllerEvent* n = static_cast(ev); if(m_out != nullptr && m_thruEnabled) { m_out->sendController(n->getChannel(), n->getParam(), n->getValue()); } emit m_inp->midiController(n->getChannel(), n->getParam(), n->getValue()); } break; case SND_SEQ_EVENT_PGMCHANGE: { const ProgramChangeEvent* p = static_cast(ev); if(m_out != nullptr && m_thruEnabled) { m_out->sendProgram(p->getChannel(), p->getValue()); } emit m_inp->midiProgram(p->getChannel(), p->getValue()); } break; case SND_SEQ_EVENT_CHANPRESS: { const ChanPressEvent* n = static_cast(ev); if(m_out != nullptr && m_thruEnabled) { m_out->sendChannelPressure(n->getChannel(), n->getValue()); } emit m_inp->midiChannelPressure(n->getChannel(), n->getValue()); } break; case SND_SEQ_EVENT_PITCHBEND: { const PitchBendEvent* n = static_cast(ev); if(m_out != nullptr && m_thruEnabled) { m_out->sendPitchBend(n->getChannel(), n->getValue()); } emit m_inp->midiPitchBend(n->getChannel(), n->getValue()); } break; case SND_SEQ_EVENT_SYSEX: { const SysExEvent* n = static_cast(ev); QByteArray data(n->getData(), n->getLength()); if(m_out != nullptr && m_thruEnabled) { m_out->sendSysex(data); } emit m_inp->midiSysex(data); } break; case SND_SEQ_EVENT_SYSTEM: { const SystemEvent* n = static_cast(ev); int status = (int) n->getRaw8(0); if(m_out != nullptr && m_thruEnabled) { m_out->sendSystemMsg(status); } if (status < 0xF7) emit m_inp->midiSystemCommon(status); else if (status > 0xF7) emit m_inp->midiSystemRealtime(status); } break; default: break; } delete ev; } }; ALSAMIDIInput::ALSAMIDIInput(QObject *parent) : MIDIInput(parent), d(new ALSAMIDIInputPrivate(this)) { } ALSAMIDIInput::~ALSAMIDIInput() { delete d; } void ALSAMIDIInput::initialize(QSettings* settings) { Q_UNUSED(settings) d->initialize(); } QString ALSAMIDIInput::backendName() { return QStringLiteral("ALSA"); } QString ALSAMIDIInput::publicName() { return d->m_publicName; } void ALSAMIDIInput::setPublicName(QString name) { d->setPublicName(name); } QList ALSAMIDIInput::connections(bool advanced) { d->reloadDeviceList(advanced); return d->m_inputDevices; } void ALSAMIDIInput::setExcludedConnections(QStringList conns) { d->m_excludedNames = conns; } void ALSAMIDIInput::open(const MIDIConnection& name) { auto b = d->setSubscription(name); if (!b) { d->m_diagnostics << "failed subscription to " + name.first; } } void ALSAMIDIInput::close() { d->clearSubscription(); d->uninitialize(); } MIDIConnection ALSAMIDIInput::currentConnection() { return d->m_currentInput; } void ALSAMIDIInput::setMIDIThruDevice(MIDIOutput *device) { d->m_out = device; } void ALSAMIDIInput::enableMIDIThru(bool enable) { d->m_thruEnabled = enable; } bool ALSAMIDIInput::isEnabledMIDIThru() { return d->m_thruEnabled && (d->m_out != nullptr); } QStringList ALSAMIDIInput::getDiagnostics() { return d->m_diagnostics; } bool ALSAMIDIInput::getStatus() { return d->m_status; } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/oss-in0000644000000000000000000000013214200302440020254 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-in/0000755000175000001440000000000014200302440021112 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/oss-in/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023071 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-in/CMakeLists.txt0000644000175000001440000000461414200302440023657 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-oss-in_QTOBJ_SRCS ../common/midiparser.h ossinput_p.h ossinput.h ) set(drumstick-rt-oss-in_SRCS ../common/midiparser.cpp ossinput_p.cpp ossinput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-oss-in_MOC_SRCS ${drumstick-rt-oss-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-oss-in_MOC_SRCS ${drumstick-rt-oss-in_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-oss-in STATIC ${drumstick-rt-oss-in_MOC_SRCS} ${drumstick-rt-oss-in_SRCS}) target_compile_definitions(drumstick-rt-oss-in PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-oss-in PROPERTIES STATIC_LIB "libdrumstick-rt-oss-in") else() add_library(drumstick-rt-oss-in MODULE ${drumstick-rt-oss-in_MOC_SRCS} ${drumstick-rt-oss-in_SRCS}) target_compile_definitions(drumstick-rt-oss-in PRIVATE QT_PLUGIN) endif() target_include_directories(drumstick-rt-oss-in PRIVATE ${Drumstick_SOURCE_DIR}/library/include ../common ) target_link_libraries(drumstick-rt-oss-in PRIVATE Qt${QT_VERSION_MAJOR}::Core ) set_target_properties(drumstick-rt-oss-in PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-oss-in EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/oss-in/PaxHeaders.27918/ossinput.cpp0000644000000000000000000000013214200302440022721 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-in/ossinput.cpp0000644000175000001440000000400314200302440023477 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "ossinput.h" namespace drumstick { namespace rt { const QString OSSInput::DEFAULT_PUBLIC_NAME = QStringLiteral("MIDI In"); OSSInput::OSSInput(QObject *parent) : MIDIInput(parent), d(new OSSInputPrivate(this)) { } OSSInput::~OSSInput() { delete d; } void OSSInput::initialize(QSettings *settings) { Q_UNUSED(settings) } QString OSSInput::backendName() { return "OSS"; } QString OSSInput::publicName() { return d->m_publicName; } void OSSInput::setPublicName(QString name) { d->m_publicName = name; } QList OSSInput::connections(bool advanced) { d->reloadDeviceList(advanced); return d->m_inputDevices; } void OSSInput::setExcludedConnections(QStringList conns) { Q_UNUSED(conns) } MIDIConnection OSSInput::currentConnection() { return d->m_currentInput; } void OSSInput::open(const MIDIConnection& conn) { d->open(conn); } void OSSInput::close() { d->close(); } void OSSInput::setMIDIThruDevice(MIDIOutput *device) { d->setMIDIThruDevice(device); //d->m_out = device; } void OSSInput::enableMIDIThru(bool enable) { d->m_thruEnabled = enable; } bool OSSInput::isEnabledMIDIThru() { return d->m_thruEnabled && (d->m_out != nullptr); } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/oss-in/PaxHeaders.27918/ossinput_p.cpp0000644000000000000000000000013214200302440023240 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-in/ossinput_p.cpp0000644000175000001440000000566514200302440024035 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "ossinput.h" #include "ossinput_p.h" namespace drumstick { namespace rt { OSSInputPrivate::OSSInputPrivate(QObject *parent) : QObject(parent), m_inp(qobject_cast(parent)), m_out(nullptr), m_device(nullptr), m_notifier(nullptr), m_parser(nullptr), m_thruEnabled(false), m_advanced(false), m_publicName(OSSInput::DEFAULT_PUBLIC_NAME) { reloadDeviceList(); } void OSSInputPrivate::reloadDeviceList(bool advanced) { QDir dir("/dev"); QStringList filters; m_advanced = advanced; filters << "dmmidi*" << "admmidi*"; if (advanced) { filters << "midi*" << "amidi*"; } dir.setNameFilters(filters); dir.setFilter(QDir::System); dir.setSorting(QDir::Name); m_inputDevices.clear(); QFileInfoList listInfo = dir.entryInfoList(); foreach(const QFileInfo &info, listInfo) { m_inputDevices << MIDIConnection(info.baseName(), info.absoluteFilePath()); } } void OSSInputPrivate::open(const MIDIConnection& portName) { QFile *f = new QFile(portName.second.toString()); m_currentInput = portName; m_device = f; m_device->open( QIODevice::ReadOnly | QIODevice::Unbuffered ); m_notifier = new QSocketNotifier(f->handle(), QSocketNotifier::Read); m_parser = new MIDIParser(m_inp); m_buffer.clear(); connect(m_notifier, &QSocketNotifier::activated, this, &OSSInputPrivate::processIncomingMessages); //qDebug() << Q_FUNC_INFO << portName; } void OSSInputPrivate::close() { if (m_device != nullptr) { m_device->close(); delete m_notifier; delete m_device; delete m_parser; m_device = nullptr; m_parser = nullptr; } m_currentInput = MIDIConnection(); } void OSSInputPrivate::setMIDIThruDevice(MIDIOutput* device) { m_out = device; if (m_parser != nullptr) { m_parser->setMIDIThruDevice(device); } } void OSSInputPrivate::processIncomingMessages(int) { char ch; m_device->getChar(&ch); if (m_parser != nullptr) { uchar uch = static_cast(ch); m_parser->parse(uch); } } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt-backends/oss-in/PaxHeaders.27918/oss-in.pro0000644000000000000000000000013214200302440022263 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-in/oss-in.pro0000644000175000001440000000076514200302440023054 0ustar00pedrousers00000000000000TEMPLATE = lib TARGET = drumstick-rt-oss-in DESTDIR = ../../../build/lib/drumstick2 include (../../../global.pri) CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } DEPENDPATH += ../../include ../common INCLUDEPATH += ../../include ../common QT -= gui HEADERS += ../common/midiparser.h \ ossinput_p.h \ ossinput.h SOURCES += ossinput.cpp \ ossinput_p.cpp \ ../common/midiparser.cpp LIBS += -L$$OUT_PWD/../../../build/lib -ldrumstick-rt drumstick-2.5.1/library/rt-backends/oss-in/PaxHeaders.27918/ossinput_p.h0000644000000000000000000000013214200302440022705 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-in/ossinput_p.h0000644000175000001440000000332014200302440023464 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef OSSINPUT_P_H #define OSSINPUT_P_H #include #include #include #include #include #include "midiparser.h" namespace drumstick { namespace rt { class MIDIOutput; class OSSInput; class OSSInputPrivate : public QObject { Q_OBJECT public: OSSInput *m_inp; MIDIOutput *m_out; QIODevice *m_device; QSocketNotifier *m_notifier; MIDIParser *m_parser; bool m_thruEnabled; bool m_advanced; QString m_publicName; MIDIConnection m_currentInput; QList m_inputDevices; QStringList m_excludedNames; QByteArray m_buffer; explicit OSSInputPrivate(QObject *parent = nullptr); void reloadDeviceList(bool advanced = false); void open(const MIDIConnection& portName); void close(); //void parse(); void setMIDIThruDevice(MIDIOutput* device); public slots: void processIncomingMessages(int); }; }} #endif // OSSINPUT_P_H drumstick-2.5.1/library/rt-backends/oss-in/PaxHeaders.27918/ossinput.h0000644000000000000000000000013214200302440022366 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt-backends/oss-in/ossinput.h0000644000175000001440000000406714200302440023156 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ossINPUT_H #define ossINPUT_H #include #include #include #include "ossinput_p.h" namespace drumstick { namespace rt { class OSSInput : public MIDIInput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput/2.0") Q_INTERFACES(drumstick::rt::MIDIInput) public: explicit OSSInput(QObject *parent = nullptr); virtual ~OSSInput(); static const QString DEFAULT_PUBLIC_NAME; // MIDIInput interface public: virtual void initialize(QSettings* settings) override; virtual QString backendName() override; virtual QString publicName() override; virtual void setPublicName(QString name) override; virtual QList connections(bool advanced) override; virtual void setExcludedConnections(QStringList conns) override; virtual void open(const MIDIConnection& name) override; virtual void close() override; virtual MIDIConnection currentConnection() override; virtual void setMIDIThruDevice(MIDIOutput *device) override; virtual void enableMIDIThru(bool enable) override; virtual bool isEnabledMIDIThru() override; private: OSSInputPrivate *d; }; }} #endif // ossINPUT_H drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/mac-out0000644000000000000000000000013214200302440020411 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/mac-out/0000755000175000001440000000000014200302440021247 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/mac-out/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440023226 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/mac-out/CMakeLists.txt0000644000175000001440000000502214200302440024006 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt-mac-out_QTOBJ_SRCS macmidioutput.h ) set(drumstick-rt-mac-out_SRCS ../common/maccommon.h ../common/maccommon.cpp ../common/maccommon.mm macmidioutput.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt-mac-out_MOC_SRCS ${drumstick-rt-mac-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) else() qt_wrap_cpp(drumstick-rt-mac-out_MOC_SRCS ${drumstick-rt-mac-out_QTOBJ_SRCS} OPTIONS -I ${Drumstick_SOURCE_DIR}/library/include) endif() if(STATIC_DRUMSTICK) add_library(drumstick-rt-mac-out STATIC ${drumstick-rt-mac-out_MOC_SRCS} ${drumstick-rt-mac-out_SRCS}) target_compile_definitions(drumstick-rt-mac-out PRIVATE QT_STATICPLUGIN) set_target_properties(drumstick-rt-mac-out PROPERTIES STATIC_LIB "libdrumstick-rt-mac-out") else() add_library(drumstick-rt-mac-out MODULE ${drumstick-rt-mac-out_MOC_SRCS} ${drumstick-rt-mac-out_SRCS}) target_compile_definitions(drumstick-rt-mac-out PRIVATE QT_PLUGIN) endif() target_link_libraries(drumstick-rt-mac-out PUBLIC Drumstick::RT Qt${QT_VERSION_MAJOR}::Core "-framework CoreMIDI -framework CoreFoundation -framework CoreServices -framework Foundation" ) target_include_directories(drumstick-rt-mac-out PRIVATE ${Drumstick_SOURCE_DIR}/library/include ../common ) set_target_properties(drumstick-rt-mac-out PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${DRUMSTICK_PLUGINS_DIR}) install(TARGETS drumstick-rt-mac-out EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${DRUMSTICK_PLUGINS_DIR}) drumstick-2.5.1/library/rt-backends/mac-out/PaxHeaders.27918/macmidioutput.h0000644000000000000000000000013214200302440023523 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/mac-out/macmidioutput.h0000644000175000001440000000474314200302440024314 0ustar00pedrousers00000000000000/* Drumstick RT Backend Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef MACMIDIOUTPUT_H #define MACMIDIOUTPUT_H #include namespace drumstick { namespace rt { class MacMIDIOutput : public MIDIOutput { Q_OBJECT Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput/2.0") Q_INTERFACES(drumstick::rt::MIDIOutput) Q_PROPERTY(QStringList diagnostics READ getDiagnostics) Q_PROPERTY(bool status READ getStatus); public: explicit MacMIDIOutput(QObject *parent = nullptr); virtual ~MacMIDIOutput(); // MIDIOutput interface virtual void initialize(QSettings* settings); virtual QString backendName(); virtual QString publicName(); virtual void setPublicName(QString name); virtual QList connections(bool advanced); virtual void setExcludedConnections(QStringList conns); virtual void open(const MIDIConnection& name); virtual void close(); virtual MIDIConnection currentConnection(); public slots: virtual void sendNoteOff(int chan, int note, int vel); virtual void sendNoteOn(int chan, int note, int vel); virtual void sendKeyPressure(int chan, int note, int value); virtual void sendController(int chan, int control, int value); virtual void sendProgram(int chan, int program); virtual void sendChannelPressure(int chan, int value); virtual void sendPitchBend(int chan, int value); virtual void sendSysex(const QByteArray &data); virtual void sendSystemMsg(const int status); private: class MacMIDIOutputPrivate; MacMIDIOutputPrivate* const d; QStringList getDiagnostics(); bool getStatus(); }; }} #endif // MACMIDIOUTPUT_H drumstick-2.5.1/library/rt-backends/mac-out/PaxHeaders.27918/mac-out.pro0000644000000000000000000000013214200302440022555 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/mac-out/mac-out.pro0000644000175000001440000000102314200302440023332 0ustar00pedrousers00000000000000TEMPLATE = lib CONFIG += c++11 plugin static { CONFIG += staticlib create_prl } TARGET = drumstick-rt-mac-out DESTDIR = ../../../build/lib/drumstick2 DEPENDPATH += . ../../include ../common INCLUDEPATH += . ../../include ../common include (../../../global.pri) QT -= gui HEADERS += macmidioutput.h \ ../common/maccommon.h SOURCES += macmidioutput.cpp \ ../common/maccommon.cpp !static:LIBS += -F$$OUT_PWD/../../../build/lib -framework drumstick-rt LIBS += -framework CoreMIDI -framework CoreFoundation drumstick-2.5.1/library/rt-backends/mac-out/PaxHeaders.27918/macmidioutput.cpp0000644000000000000000000000013214200302440024056 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/mac-out/macmidioutput.cpp0000644000175000001440000002664014200302440024647 0ustar00pedrousers00000000000000/* Drumstick RT Backend Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "macmidioutput.h" #include "maccommon.h" #include #include #include #include #include #include #include namespace drumstick { namespace rt { static CFStringRef DEFAULT_PUBLIC_NAME CFSTR("MIDI Out"); class MacMIDIOutput::MacMIDIOutputPrivate { public: MIDIClientRef m_client; MIDIPortRef m_port; MIDIEndpointRef m_endpoint; MIDIEndpointRef m_destination; bool m_clientFilter; MIDIConnection m_currentOutput; QString m_publicName; QStringList m_excludedNames; QList m_outputDevices; bool m_status; QStringList m_diagnostics; MacMIDIOutputPrivate(): m_client(0), m_port(0), m_endpoint(0), m_destination(0), m_clientFilter(true), m_publicName(QString::fromCFString(DEFAULT_PUBLIC_NAME)) { internalCreate(DEFAULT_PUBLIC_NAME); } void registerStatus(const QString& context, const OSStatus status) { if (status != noErr) { m_diagnostics << QString("%1 error: %2").arg(context, status); m_diagnostics << getErrorTextFromOSStatus(status); } } void internalCreate(CFStringRef name) { OSStatus result = noErr; m_status = false; m_diagnostics.clear(); result = MIDIClientCreate( name, NULL, NULL, &m_client ); if ( result != noErr ) { registerStatus("MIDIClientCreate()", result); return; } result = MIDISourceCreate( m_client, name, &m_endpoint ); if ( result != noErr ) { registerStatus("MIDISourceCreate()", result); return; } result = MIDIOutputPortCreate( m_client, name, &m_port ); if (result != noErr) { registerStatus("MIDIOutputPortCreate()", result); return; } reloadDeviceList(true); m_status = (result == noErr); } virtual ~MacMIDIOutputPrivate() { internalDispose(); } void internalDispose() { OSStatus result = noErr; m_status = false; m_diagnostics.clear(); if (m_port != 0) { result = MIDIPortDispose( m_port ); if (result != noErr) { registerStatus("MIDIPortDispose()", result); m_port = 0; } } if (m_endpoint != 0) { result = MIDIEndpointDispose( m_endpoint ); if (result != noErr) { registerStatus("MIDIEndpointDispose()", result); m_endpoint = 0; } } if (m_client != 0) { result = MIDIClientDispose( m_client ); if (result != noErr) { registerStatus("MIDIClientDispose()", result); m_client = 0; } } m_status = (result == noErr); } void setPublicName(QString name) { if (m_publicName != name) { internalDispose(); internalCreate(name.toCFString()); m_publicName = name; } } void reloadDeviceList(bool advanced) { int num = MIDIGetNumberOfDestinations(); m_clientFilter = !advanced; m_outputDevices.clear(); for (int i = 0; i < num; ++i) { bool excluded = false; MIDIEndpointRef dest = MIDIGetDestination( i ); if (dest != 0) { QString name = getEndpointName(dest); if ( m_clientFilter && name.contains(QStringLiteral("IAC"), Qt::CaseSensitive) ) continue; if ( name.contains (m_publicName) ) continue; foreach ( const QString& n, m_excludedNames ) { if ( name.contains(n) ) { excluded = true; break; } } if (!excluded) { m_outputDevices << MIDIConnection(name, i); } } } if (!m_currentOutput.first.isEmpty() && m_destination != 0 && !m_outputDevices.contains(m_currentOutput)) { m_currentOutput = MIDIConnection(); m_destination = 0; } } void sendEvents( const MIDIPacketList* events ) { MIDIReceived(m_endpoint, events); if (m_destination != 0) MIDISend(m_port, m_destination, events); } bool open(const MIDIConnection& conn) { m_destination = MIDIGetDestination( conn.second.toInt() ); m_currentOutput = conn; return true; } void close() { m_destination = 0; m_currentOutput = MIDIConnection(); } }; MacMIDIOutput::MacMIDIOutput(QObject *parent) : MIDIOutput(parent), d(new MacMIDIOutputPrivate) { } MacMIDIOutput::~MacMIDIOutput() { delete d; } void MacMIDIOutput::initialize(QSettings *settings) { Q_UNUSED(settings) } QString MacMIDIOutput::backendName() { return QLatin1String("CoreMIDI"); } QString MacMIDIOutput::publicName() { return d->m_publicName; } void MacMIDIOutput::setPublicName(QString name) { d->setPublicName(name); } QList MacMIDIOutput::connections(bool advanced) { d->reloadDeviceList(advanced); return d->m_outputDevices; } void MacMIDIOutput::setExcludedConnections(QStringList conns) { d->m_excludedNames = conns; } void MacMIDIOutput::open(const MIDIConnection& name) { d->open(name); } void MacMIDIOutput::close() { d->close(); } MIDIConnection MacMIDIOutput::currentConnection() { return d->m_currentOutput; } /* Realtime MIDI slots */ void MacMIDIOutput::sendNoteOn(int chan, int note, int vel) { quint8 data[3]; MIDIPacketList pktlist ; MIDIPacket* packet = MIDIPacketListInit(&pktlist); data[0] = MIDI_STATUS_NOTEON | (chan & 0x0f); data[1] = note; data[2] = vel; packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0, sizeof(data), data); if (packet != NULL) d->sendEvents(&pktlist); } void MacMIDIOutput::sendNoteOff(int chan, int note, int vel) { quint8 data[3]; MIDIPacketList pktlist ; MIDIPacket* packet = MIDIPacketListInit(&pktlist); data[0] = MIDI_STATUS_NOTEOFF | (chan & 0x0f); data[1] = note; data[2] = vel; packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0, sizeof(data), data); if (packet != NULL) d->sendEvents(&pktlist); } void MacMIDIOutput::sendController(int chan, int control, int value) { quint8 data[3]; MIDIPacketList pktlist ; MIDIPacket* packet = MIDIPacketListInit(&pktlist); data[0] = MIDI_STATUS_CONTROLCHANGE | (chan & 0x0f); data[1] = control; data[2] = value; packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0, sizeof(data), data); if (packet != NULL) d->sendEvents(&pktlist); } void MacMIDIOutput::sendKeyPressure(int chan, int note, int value) { quint8 data[3]; MIDIPacketList pktlist ; MIDIPacket* packet = MIDIPacketListInit(&pktlist); data[0] = MIDI_STATUS_KEYPRESURE | (chan & 0x0f); data[1] = note; data[2] = value; packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0, sizeof(data), data); if (packet != NULL) d->sendEvents(&pktlist); } void MacMIDIOutput::sendProgram(int chan, int program) { quint8 data[2]; MIDIPacketList pktlist ; MIDIPacket* packet = MIDIPacketListInit(&pktlist); data[0] = MIDI_STATUS_PROGRAMCHANGE | (chan & 0x0f); data[1] = program; packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0, sizeof(data), data); if (packet != NULL) d->sendEvents(&pktlist); } void MacMIDIOutput::sendChannelPressure(int chan, int value) { quint8 data[2]; MIDIPacketList pktlist ; MIDIPacket* packet = MIDIPacketListInit(&pktlist); data[0] = MIDI_STATUS_CHANNELPRESSURE | (chan & 0x0f); data[1] = value; packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0, sizeof(data), data); if (packet != NULL) d->sendEvents(&pktlist); } void MacMIDIOutput::sendPitchBend(int chan, int value) { quint16 val = value + 8192; // value between -8192 and +8191 quint8 data[3]; MIDIPacketList pktlist ; MIDIPacket* packet = MIDIPacketListInit(&pktlist); data[0] = MIDI_STATUS_PITCHBEND | (chan & 0x0f); data[1] = MIDI_LSB(val); // LSB data[2] = MIDI_MSB(val); // MSB packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0, sizeof(data), data); if (packet != NULL) d->sendEvents(&pktlist); } void MacMIDIOutput::sendSysex(const QByteArray& data) { quint8 buf[4096]; if (data.size() > 4096) return; MIDIPacketList* pktlist = (MIDIPacketList*) &buf; MIDIPacket* packet = MIDIPacketListInit(pktlist); packet = MIDIPacketListAdd(pktlist, sizeof(buf), packet, 0, data.size(), (const Byte*)data.data()); if (packet != NULL) d->sendEvents(pktlist); } void MacMIDIOutput::sendSystemMsg(const int status) { quint8 data; MIDIPacketList pktlist; MIDIPacket* packet = MIDIPacketListInit(&pktlist); data = status; packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0, sizeof(data), &data); if (packet != NULL) d->sendEvents(&pktlist); } QStringList MacMIDIOutput::getDiagnostics() { return d->m_diagnostics; } bool MacMIDIOutput::getStatus() { return d->m_status; } }} drumstick-2.5.1/library/rt-backends/PaxHeaders.27918/common0000644000000000000000000000013214200302440020334 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/common/0000755000175000001440000000000014200302440021172 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt-backends/common/PaxHeaders.27918/maccommon.cpp0000644000000000000000000000013214200302440023066 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/common/maccommon.cpp0000644000175000001440000000457514200302440023662 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "maccommon.h" #if QT_VERSION < QT_VERSION_CHECK(5,2,0) QString CFStringToQString(CFStringRef str) { if (!str) return QString(); CFIndex length = CFStringGetLength(str); const UniChar *chars = CFStringGetCharactersPtr(str); if (chars) return QString(reinterpret_cast(chars), length); QVarLengthArray buffer(length); CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data()); return QString(reinterpret_cast(buffer.constData()), length); } #endif QString getEndpointName(MIDIEndpointRef endpoint) { QString result; CFStringRef str = 0; MIDIObjectGetStringProperty (endpoint, kMIDIPropertyName, &str); if (str != 0) { result = QString::fromCFString(str); CFRelease(str); str = 0; } MIDIEntityRef entity = 0; MIDIEndpointGetEntity(endpoint, &entity); if (entity == 0) return result; if (result.isEmpty()) { MIDIObjectGetStringProperty (entity, kMIDIPropertyName, &str); if (str != 0) { result = QString::fromCFString(str); CFRelease(str); str = 0; } } MIDIDeviceRef device = 0; MIDIEntityGetDevice (entity, &device); if (device == 0) return result; MIDIObjectGetStringProperty (device, kMIDIPropertyName, &str); if (str != 0) { QString s = QString::fromCFString(str); CFRelease (str); str = 0; if (!result.startsWith(s, Qt::CaseInsensitive) ) result = (s + ' ' + result).trimmed(); } return result; } drumstick-2.5.1/library/rt-backends/common/PaxHeaders.27918/maccommon.h0000644000000000000000000000013214200302440022533 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/common/maccommon.h0000644000175000001440000000207214200302440023315 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef MACCOMMON_H #define MACCOMMON_H #include #include #if QT_VERSION < QT_VERSION_CHECK(5,2,0) QString CFStringToQString(CFStringRef str); #endif QString getEndpointName(MIDIEndpointRef endpoint); QString getErrorTextFromOSStatus(OSStatus err); #endif // MACCOMMON_H drumstick-2.5.1/library/rt-backends/common/PaxHeaders.27918/maccommon.mm0000644000000000000000000000013214200302440022715 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/common/maccommon.mm0000644000175000001440000000176714200302440023511 0ustar00pedrousers00000000000000/* Drumstick RT Mac OSX Backend Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "maccommon.h" #import QString getErrorTextFromOSStatus(OSStatus err) { NSError* error = [NSError errorWithDomain:NSOSStatusErrorDomain code:err userInfo:nil]; return QString::fromNSString( error.description ); } drumstick-2.5.1/library/rt-backends/common/PaxHeaders.27918/midiparser.h0000644000000000000000000000013214200302440022721 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/common/midiparser.h0000644000175000001440000000242114200302440023501 0ustar00pedrousers00000000000000/* Drumstick MIDI realtime input-output Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef MIDIPARSER_H #define MIDIPARSER_H #include #include namespace drumstick { namespace rt { class MIDIParser : public QObject { Q_OBJECT public: explicit MIDIParser(MIDIInput *in = nullptr, QObject *parent = nullptr); virtual ~MIDIParser(); void setMIDIThruDevice(MIDIOutput* device); public slots: void parse(unsigned char byte); void parse(QByteArray bytes); private: class MIDIParserPrivate; MIDIParserPrivate *d; }; }} #endif // MIDIPARSER_H drumstick-2.5.1/library/rt-backends/common/PaxHeaders.27918/midiparser.cpp0000644000000000000000000000013214200302440023254 xustar0030 mtime=1644266784.817324175 30 atime=1644266785.357324521 30 ctime=1644266784.817324175 drumstick-2.5.1/library/rt-backends/common/midiparser.cpp0000644000175000001440000002100314200302440024031 0ustar00pedrousers00000000000000/* Drumstick MIDI realtime input-output Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "midiparser.h" #include namespace drumstick { namespace rt { class MIDIParser::MIDIParserPrivate { public: MIDIParserPrivate(): m_in(nullptr), m_out(nullptr), m_running_status(0) { } MIDIInput *m_in; MIDIOutput *m_out; unsigned char m_running_status; QByteArray m_buffer; void processNoteOff(const int chan, const int note, const int vel) { //qDebug() << "NoteOff(" << hex << chan << "," << note << "," << vel << ")"; if (m_in != nullptr && m_in->isEnabledMIDIThru() && m_out != nullptr) { m_out->sendNoteOff(chan, note, vel); } if (m_in != nullptr) { emit m_in->midiNoteOff(chan, note, vel); } } void processNoteOn(const int chan, const int note, const int vel) { //qDebug() << "NoteOn(" << hex << chan << "," << note << "," << vel << ")"; if (m_in != nullptr && m_in->isEnabledMIDIThru() && m_out != nullptr) { m_out->sendNoteOn(chan, note, vel); } if (m_in != nullptr) { emit m_in->midiNoteOn(chan, note, vel); } } void processKeyPressure(const int chan, const int note, const int value) { //qDebug() << "KeyPressure(" << hex << chan << "," << note << "," << value << ")"; if (m_in != nullptr && m_in->isEnabledMIDIThru() && m_out != nullptr) { m_out->sendKeyPressure(chan, note, value); } if (m_in != nullptr) { emit m_in->midiKeyPressure(chan, note, value); } } void processController(const int chan, const int control, const int value) { //qDebug() << "Controller(" << chan << "," << control << "," << value << ")"; if (m_in != nullptr && m_in->isEnabledMIDIThru() && m_out != nullptr) { m_out->sendController(chan, control, value); } if (m_in != nullptr) { emit m_in->midiController(chan, control, value); } } void processProgram(const int chan, const int program) { //qDebug() << "Program(" << hex << chan << "," << program << ")"; if (m_in != nullptr && m_in->isEnabledMIDIThru() && m_out != nullptr) { m_out->sendProgram(chan, program); } if (m_in != nullptr) { emit m_in->midiProgram(chan, program); } } void processChannelPressure(const int chan, const int value) { //qDebug() << "ChannelPressure(" << chan << "," << value << ")"; if (m_in != nullptr && m_in->isEnabledMIDIThru() && m_out != nullptr) { m_out->sendChannelPressure(chan, value); } if (m_in != nullptr) { emit m_in->midiChannelPressure(chan, value); } } void processPitchBend(const int chan, const int value) { //qDebug() << "PitchBend(" << chan << "," << value << ")"; if (m_in != nullptr && m_in->isEnabledMIDIThru() && m_out != nullptr) { m_out->sendPitchBend(chan, value); } if (m_in != nullptr) { emit m_in->midiPitchBend(chan, value); } } void processSysex(const QByteArray &data) { //qDebug() << "Sysex(" << data.toHex() << ")"; if (m_in != nullptr && m_in->isEnabledMIDIThru() && m_out != nullptr) { m_out->sendSysex(data); } if (m_in != nullptr) { emit m_in->midiSysex(data); } } void processSystemCommon(const int status) { //qDebug() << "common SystemMsg(" << hex << status << ")"; if (m_in != nullptr && m_in->isEnabledMIDIThru() && m_out != nullptr) { m_out->sendSystemMsg(status); } if (m_in != nullptr) { emit m_in->midiSystemCommon(status); } } void processSystemRealtime(unsigned char byte) { //qDebug() << "realtime SystemMsg(" << hex << byte << ")"; if (m_in != nullptr && m_in->isEnabledMIDIThru() && m_out != nullptr) { m_out->sendSystemMsg(byte); } if (m_in != nullptr) { emit m_in->midiSystemRealtime(byte); } } }; MIDIParser::MIDIParser(MIDIInput *in, QObject *parent) : QObject(parent), d(new MIDIParser::MIDIParserPrivate) { d->m_buffer.clear(); d->m_in = in; } MIDIParser::~MIDIParser() { delete d; } void MIDIParser::setMIDIThruDevice(MIDIOutput *device) { d->m_out = device; } void MIDIParser::parse(unsigned char byte) { if (byte >= MIDI_STATUS_REALTIME) { // system realtime d->processSystemRealtime(byte); return; } else d->m_buffer.append(byte); while(d->m_buffer.length() > 0) { int chan, m1, m2, v; unsigned char status = static_cast(d->m_buffer.at(0)); if (status == MIDI_STATUS_SYSEX) { // system exclusive if (byte == MIDI_STATUS_ENDSYSEX) { d->processSysex(d->m_buffer); d->m_buffer.clear(); } else return; } else if (status > MIDI_STATUS_SYSEX && status < MIDI_STATUS_ENDSYSEX) { // system common d->processSystemCommon(status); d->m_buffer.clear(); } else if (status < MIDI_STATUS_SYSEX && status >= MIDI_STATUS_NOTEOFF) { // channel message d->m_running_status = status; chan = status & MIDI_CHANNEL_MASK; status = status & MIDI_STATUS_MASK; switch(status) { case MIDI_STATUS_NOTEOFF: if (d->m_buffer.length() < 3) return; m1 = static_cast(d->m_buffer.at(1)); m2 = static_cast(d->m_buffer.at(2)); d->processNoteOff(chan, m1, m2); break; case MIDI_STATUS_NOTEON: if (d->m_buffer.length() < 3) return; m1 = static_cast(d->m_buffer.at(1)); m2 = static_cast(d->m_buffer.at(2)); d->processNoteOn(chan, m1, m2); break; case MIDI_STATUS_KEYPRESURE: if (d->m_buffer.length() < 3) return; m1 = static_cast(d->m_buffer.at(1)); m2 = static_cast(d->m_buffer.at(2)); d->processKeyPressure(chan, m1, m2); break; case MIDI_STATUS_CONTROLCHANGE: if (d->m_buffer.length() < 3) return; m1 = static_cast(d->m_buffer.at(1)); m2 = static_cast(d->m_buffer.at(2)); d->processController(chan, m1, m2); break; case MIDI_STATUS_PROGRAMCHANGE: if (d->m_buffer.length() < 2) return; m1 = static_cast(d->m_buffer.at(1)); d->processProgram(chan, m1); break; case MIDI_STATUS_CHANNELPRESSURE: if (d->m_buffer.length() < 2) return; m1 = static_cast(d->m_buffer.at(1)); d->processChannelPressure(chan, m1); break; case MIDI_STATUS_PITCHBEND: if (d->m_buffer.length() < 3) return; m1 = static_cast(d->m_buffer.at(1)); m2 = static_cast(d->m_buffer.at(2)); v = m1 + m2 * 0x80 - 0x2000; d->processPitchBend(chan, v); break; } d->m_buffer.clear(); } else { // running status d->m_buffer.insert(0, d->m_running_status); } } } void MIDIParser::parse(QByteArray bytes) { foreach(unsigned char byte, bytes) { parse(byte); } } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/PaxHeaders.27918/alsa0000644000000000000000000000013214200302440015567 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.357324521 30 ctime=1644266784.825324181 drumstick-2.5.1/library/alsa/0000755000175000001440000000000014200302440016425 5ustar00pedrousers00000000000000drumstick-2.5.1/library/alsa/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020404 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.357324521 30 ctime=1644266784.825324181 drumstick-2.5.1/library/alsa/CMakeLists.txt0000644000175000001440000000717714200302440021201 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-alsa_QTOBJ_SRCS ../include/drumstick/alsaclient.h ../include/drumstick/alsaevent.h ../include/drumstick/alsaport.h ../include/drumstick/alsaqueue.h ../include/drumstick/alsatimer.h ../include/drumstick/playthread.h ) set(drumstick-alsa_HEADERS ../include/drumstick/alsaclient.h ../include/drumstick/alsaevent.h ../include/drumstick/alsaport.h ../include/drumstick/alsaqueue.h ../include/drumstick/alsatimer.h ../include/drumstick/playthread.h ../include/drumstick/sequencererror.h ../include/drumstick/subscription.h ../include/drumstick/macros.h ) set(drumstick-alsa_SRCS alsaclient.cpp alsaevent.cpp alsaport.cpp alsaqueue.cpp alsatimer.cpp playthread.cpp sequencererror.cpp subscription.cpp ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-alsa_MOC_SRCS ${drumstick-alsa_QTOBJ_SRCS}) else() qt_wrap_cpp(drumstick-alsa_MOC_SRCS ${drumstick-alsa_QTOBJ_SRCS}) endif() add_library(drumstick-alsa ${drumstick-alsa_MOC_SRCS} ${drumstick-alsa_SRCS} ${drumstick-alsa_HEADERS} ) add_library(Drumstick::ALSA ALIAS drumstick-alsa) target_include_directories(drumstick-alsa PUBLIC $ $ ) target_link_libraries(drumstick-alsa PRIVATE Qt${QT_VERSION_MAJOR}::Core PkgConfig::ALSA ) if(USE_DBUS) target_link_libraries(drumstick-alsa PRIVATE Qt${QT_VERSION_MAJOR}::DBus ) endif() if(STATIC_DRUMSTICK) set_target_properties(drumstick-alsa PROPERTIES STATIC_LIB "libdrumstick-alsa") else() set_target_properties(drumstick-alsa PROPERTIES VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} SOVERSION ${PROJECT_VERSION_MAJOR} EXPORT_NAME ALSA ) endif() install(TARGETS drumstick-alsa EXPORT drumstick-alsa-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install(FILES ${drumstick-alsa_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/drumstick) install(EXPORT drumstick-alsa-targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/drumstick NAMESPACE Drumstick:: ) export(EXPORT drumstick-alsa-targets NAMESPACE Drumstick:: FILE ${CMAKE_BINARY_DIR}/drumstick-alsa-targets.cmake ) include(CMakePackageConfigHelpers) write_basic_package_version_file( ${CMAKE_BINARY_DIR}/drumstick-alsa-config-version.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) configure_file( drumstick-alsa-config.cmake ${CMAKE_BINARY_DIR}/drumstick-alsa-config.cmake @ONLY ) install(FILES ${CMAKE_BINARY_DIR}/drumstick-alsa-config-version.cmake ${CMAKE_BINARY_DIR}/drumstick-alsa-config.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/drumstick ) drumstick-2.5.1/library/alsa/PaxHeaders.27918/alsaqueue.cpp0000644000000000000000000000013214200302440020335 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.357324521 30 ctime=1644266784.825324181 drumstick-2.5.1/library/alsa/alsaqueue.cpp0000644000175000001440000005167614200302440021135 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "errorcheck.h" #include #include #include #include #include /** * @file alsaqueue.cpp * Implementation of classes managing ALSA Sequencer queues */ namespace drumstick { namespace ALSA { /** * This is the value for the base skew used in ALSA. It is not possible * to assign an arbitrary value (ALSA version <= 1.0.20). */ const unsigned int SKEW_BASE = 0x10000; /** * @addtogroup ALSAQueue * @{ * * ALSA events can be delivered to the output ports at scheduled times using the * queues. There is a small amount of available queues in the system, so this is * a limited resource. Queues are also used to time-stamp incoming events. * * Classes: * * QueueInfo holds several properties about the queue object. * * QueueStatus is used to retrieve the status of the queue object. * * QueueTempo holds properties to get and set the tempo in the queue object. * * QueueTimer holds properties about the Timer used in the queue object. * * MidiQueue represents the queue object. * * @see https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_queue.html * @} */ /** * Default constructor */ QueueInfo::QueueInfo() { snd_seq_queue_info_malloc(&m_Info); } /** * Constructor. * @param other ALSA queue info object pointer */ QueueInfo::QueueInfo(snd_seq_queue_info_t* other) { snd_seq_queue_info_malloc(&m_Info); snd_seq_queue_info_copy(m_Info, other); } /** * Copy constructor. * @param other An existing QueueInfo object reference. */ QueueInfo::QueueInfo(const QueueInfo& other) { snd_seq_queue_info_malloc(&m_Info); snd_seq_queue_info_copy(m_Info, other.m_Info); } /** * Destructor */ QueueInfo::~QueueInfo() { snd_seq_queue_info_free(m_Info); } /** * Copy the current object and return the copy. * @return The pointer to the new object. */ QueueInfo* QueueInfo::clone() { return new QueueInfo(m_Info); } /** * Assignment operator. * @param other An existing QueueInfo object reference. * @return This object. */ QueueInfo& QueueInfo::operator=(const QueueInfo& other) { if (this == &other) return *this; snd_seq_queue_info_copy(m_Info, other.m_Info); return *this; } /** * Gets the queue's numeric identifier. * @return The numeric identifier. */ int QueueInfo::getId() { return snd_seq_queue_info_get_queue(m_Info); } /** * Gets the queue name * @return The queue name. */ QString QueueInfo::getName() { return QString(snd_seq_queue_info_get_name(m_Info)); } /** * Gets the owner's client id of the queue. * @return the owner's client id. */ int QueueInfo::getOwner() { return snd_seq_queue_info_get_owner(m_Info); } /** * Returns the locking status of the queue * @return The locking status. */ bool QueueInfo::isLocked() { return (snd_seq_queue_info_get_locked(m_Info) != 0); } /** * Gets the flags of the queue. * @return The flags of the queue. */ unsigned int QueueInfo::getFlags() { return snd_seq_queue_info_get_flags(m_Info); } /** * Sets the queue name * @param value The queue name */ void QueueInfo::setName(QString value) { snd_seq_queue_info_set_name(m_Info, value.toLocal8Bit().data()); } /** * Sets the client ID of the owner * @param value The client ID of the owner */ void QueueInfo::setOwner(int value) { snd_seq_queue_info_set_owner(m_Info, value); } /** * Sets the bit flags of the queue * @param value The bit flags */ void QueueInfo::setFlags(unsigned int value) { snd_seq_queue_info_set_flags(m_Info, value); } /** * Sets the locked status of the queue * @param locked The locked status */ void QueueInfo::setLocked(bool locked) { snd_seq_queue_info_set_locked(m_Info, locked ? 1 : 0); } /** * Gets the size of the ALSA queue info object. * @return The size of the ALSA object. */ int QueueInfo::getInfoSize() const { return snd_seq_queue_info_sizeof(); } /** * Default constructor */ QueueStatus::QueueStatus() { snd_seq_queue_status_malloc(&m_Info); } /** * Constructor * @param other ALSA queue status object pointer */ QueueStatus::QueueStatus(snd_seq_queue_status_t* other) { snd_seq_queue_status_malloc(&m_Info); snd_seq_queue_status_copy(m_Info, other); } /** * Copy constructor * @param other An existing QueueStatus object reference */ QueueStatus::QueueStatus(const QueueStatus& other) { snd_seq_queue_status_malloc(&m_Info); snd_seq_queue_status_copy(m_Info, other.m_Info); } /** * Destructor */ QueueStatus::~QueueStatus() { snd_seq_queue_status_free(m_Info); } /** * Copy the current object and return the copy * @return The pointer to the new object */ QueueStatus* QueueStatus::clone() { return new QueueStatus(m_Info); } /** * Assignment operator * @param other An existing QueueStatus object reference * @return This object */ QueueStatus& QueueStatus::operator=(const QueueStatus& other) { if (this == &other) return *this; snd_seq_queue_status_copy(m_Info, other.m_Info); return *this; } /** * Gets the queue's numeric identifier * @return The queue's numeric identifier. */ int QueueStatus::getId() { return snd_seq_queue_status_get_queue(m_Info); } /** * Gets the number of queued events * @return The number of queued events */ int QueueStatus::getEvents() { return snd_seq_queue_status_get_events(m_Info); } /** * Gets the real time (secods and nanoseconds) of the queue * @return The queue's real time. */ const snd_seq_real_time_t* QueueStatus::getRealtime() { return snd_seq_queue_status_get_real_time(m_Info); } /** * Gets the running status bits * @return The running status bits */ unsigned int QueueStatus::getStatusBits() { return snd_seq_queue_status_get_status(m_Info); } /** * Gets the musical time (ticks) of the queue * @return The musical time */ snd_seq_tick_time_t QueueStatus::getTickTime() { return snd_seq_queue_status_get_tick_time(m_Info); } /** * Gets the size of the ALSA status object * @return The size of the ALSA object */ int QueueStatus::getInfoSize() const { return snd_seq_queue_status_sizeof(); } /** * Gets the queue's running state * @return True if the queue is running */ bool QueueStatus::isRunning() { return (snd_seq_queue_status_get_status(m_Info) != 0); } /** * Gets the clock time in seconds of the queue * @return The queue time in seconds */ double QueueStatus::getClockTime() { const snd_seq_real_time_t* time = snd_seq_queue_status_get_real_time(m_Info); return (time->tv_sec * 1.0) + (time->tv_nsec * 1.0e-9); } /** * Default constructor */ QueueTempo::QueueTempo() { snd_seq_queue_tempo_malloc(&m_Info); } /** * Constructor * @param other An ALSA queue tempo object pointer */ QueueTempo::QueueTempo(snd_seq_queue_tempo_t* other) { snd_seq_queue_tempo_malloc(&m_Info); snd_seq_queue_tempo_copy(m_Info, other); } /** * Copy constructor * @param other An existing QueueTempo object reference */ QueueTempo::QueueTempo(const QueueTempo& other) { snd_seq_queue_tempo_malloc(&m_Info); snd_seq_queue_tempo_copy(m_Info, other.m_Info); } /** * Destructor */ QueueTempo::~QueueTempo() { snd_seq_queue_tempo_free(m_Info); } /** * Copy the current object returning the copied object * @return The pointer to the new object */ QueueTempo* QueueTempo::clone() { return new QueueTempo(m_Info); } /** * Assignment operator * @param other An existing QueueTempo object reference * @return This object */ QueueTempo& QueueTempo::operator=(const QueueTempo& other) { if (this == &other) return *this; snd_seq_queue_tempo_copy(m_Info, other.m_Info); return *this; } /** * Gets the queue's numeric identifier * @return The queue's numeric identifier */ int QueueTempo::getId() { return snd_seq_queue_tempo_get_queue(m_Info); } /** * Gets the PPQ (parts per quarter note) resolution of the queue * @return The PPQ (parts per quarter note) resolution */ int QueueTempo::getPPQ() { return snd_seq_queue_tempo_get_ppq(m_Info); } /** * Gets the tempo skew numerator. The real skew factor is the quotient of this * value divided by the skew base. * @return The tempo skew numerator. * @see getSkewBase(), setSkewValue(), setTempoFactor() */ unsigned int QueueTempo::getSkewValue() { return snd_seq_queue_tempo_get_skew(m_Info); } /** * Gets the tempo skew base. The real skew factor is the quotient of the skew * value divided by the skew base. * @return The tempo skew base. * @see getSkewValue(), setSkewValue(), setTempoFactor() */ unsigned int QueueTempo::getSkewBase() { return snd_seq_queue_tempo_get_skew_base(m_Info); } /** * Gets the queue's tempo in microseconds per beat. * @return The queue's tempo in microseconds per beat. */ unsigned int QueueTempo::getTempo() { return snd_seq_queue_tempo_get_tempo(m_Info); } /** * Sets the queue resolution in parts per quarter note. * @param value The queue resolution in PPQ. */ void QueueTempo::setPPQ(int value) { snd_seq_queue_tempo_set_ppq(m_Info, value); } /** * Sets the tempo skew numerator. The real skew factor is the quotient of this * value divided by the skew base. * @param value The tempo skew numerator. * @see getSkewBase(), getSkewValue(), setTempoFactor() */ void QueueTempo::setSkewValue(unsigned int value) { snd_seq_queue_tempo_set_skew(m_Info, value); } /** * Sets the tempo skew base. The real skew factor is the quotient of the skew * value divided by the skew base. * @bug Protected because ALSA only accepts as argument a constant SKEW_BASE * @param value The tempo skew base. * @see getSkewBase(), getSkewValue(), setTempoFactor() */ void QueueTempo::setSkewBase(unsigned int value) { snd_seq_queue_tempo_set_skew_base(m_Info, value); } /** * Sets the queue tempo in microseconds per beat * @param value The tempo in microseconds per beat */ void QueueTempo::setTempo(unsigned int value) { snd_seq_queue_tempo_set_tempo(m_Info, value); } /** * Gets the queue's nominal BPM tempo (in beats per minute) * @return The queue's nominal BPM tempo (in beats per minute) */ float QueueTempo::getNominalBPM() { int itempo = getTempo(); if (itempo != 0) return 6.0e7f / itempo; return 0.0f; } /** * Gets the queue's real BPM tempo in beats per minute. The result is equal to * the nominal BPM tempo multiplied by the skew factor. * @return */ float QueueTempo::getRealBPM() { float tempo = getNominalBPM(); return tempo * getSkewValue() / SKEW_BASE; } /** * Sets the queue's tempo skew factor * @param value The tempo skew factor. */ void QueueTempo::setTempoFactor(float value) { setSkewValue(floor(SKEW_BASE * value)); setSkewBase(SKEW_BASE); } /** * Sets the queue's nominal tempo in BPM (beats per minute). * @param value The nominal tempo in BPM (beats per minute). */ void QueueTempo::setNominalBPM(float value) { setTempo(floor(6.0e7f / value)); } /** * Gets the size of the ALSA queue tempo object * @return The size of the ALSA object */ int QueueTempo::getInfoSize() const { return snd_seq_queue_tempo_sizeof(); } /** * Default constructor */ QueueTimer::QueueTimer() { snd_seq_queue_timer_malloc(&m_Info); } /** * Constructor * @param other An ALSA queue timer object pointer */ QueueTimer::QueueTimer(snd_seq_queue_timer_t* other) { snd_seq_queue_timer_malloc(&m_Info); snd_seq_queue_timer_copy(m_Info, other); } /** * Copy constructor * @param other An existing QueueTimer object reference */ QueueTimer::QueueTimer(const QueueTimer& other) { snd_seq_queue_timer_malloc(&m_Info); snd_seq_queue_timer_copy(m_Info, other.m_Info); } /** * Destructor */ QueueTimer::~QueueTimer() { snd_seq_queue_timer_free(m_Info); } /** * Copy the current object and return the copy * @return The pointer to the new object */ QueueTimer* QueueTimer::clone() { return new QueueTimer(m_Info); } /** * Assignment operator * @param other An existing QueueTimer object reference * @return This object */ QueueTimer& QueueTimer::operator=(const QueueTimer& other) { if (this == &other) return *this; snd_seq_queue_timer_copy(m_Info, other.m_Info); return *this; } /** * The queue's numeric identifier * @return The queue's numeric identifier */ int QueueTimer::getQueueId() { return snd_seq_queue_timer_get_queue(m_Info); } /** * Gets the timer type. * * The timer type can be one of the following constants: *

    *
  • SND_SEQ_TIMER_ALSA: ALSA timer
  • *
  • SND_SEQ_TIMER_MIDI_CLOCK: MIDI Clock (CLOCK event)
  • *
  • SND_SEQ_TIMER_MIDI_TICK: MIDI Timer Tick (TICK event)
  • *
* @return the timer type. * @see setType() */ snd_seq_queue_timer_type_t QueueTimer::getType() { return snd_seq_queue_timer_get_type(m_Info); } /** * Gets the timer identifier record * @return The timer identifier record pointer */ const snd_timer_id_t* QueueTimer::getId() { return snd_seq_queue_timer_get_id(m_Info); } /** * Gets the timer resolution * @return The timer resolution */ unsigned int QueueTimer::getResolution() { return snd_seq_queue_timer_get_resolution(m_Info); } /** * Sets the timer type. * The timer type can be one of the following constants: *
    *
  • SND_SEQ_TIMER_ALSA: ALSA timer
  • *
  • SND_SEQ_TIMER_MIDI_CLOCK: MIDI Clock (CLOCK event)
  • *
  • SND_SEQ_TIMER_MIDI_TICK: MIDI Timer Tick (TICK event)
  • *
* @param value The timer type * @see getType() */ void QueueTimer::setType(snd_seq_queue_timer_type_t value) { snd_seq_queue_timer_set_type(m_Info, value); } /** * Sets the timer identifier record * @param value The timer identifier record pointer */ void QueueTimer::setId(snd_timer_id_t* value) { snd_seq_queue_timer_set_id(m_Info, value); } /** * Sets the timer identifier * @param id Timer identifier object * @since 0.3.0 */ void QueueTimer::setId(const TimerId& id) { setId(id.m_Info); } /** * Sets the timer resolution * @param value The timer resolution */ void QueueTimer::setResolution(unsigned int value) { snd_seq_queue_timer_set_resolution(m_Info, value); } /** * Gets the size of the ALSA queue timer object * @return The size of the ALSA object */ int QueueTimer::getInfoSize() const { return snd_seq_queue_timer_sizeof(); } /** * Constructor * @param seq An existing MidiClient instance * @param parent An optional parent object */ MidiQueue::MidiQueue(MidiClient* seq, QObject* parent) : QObject(parent) { m_MidiClient = seq; m_Id = DRUMSTICK_ALSA_CHECK_ERROR(snd_seq_alloc_queue(m_MidiClient->getHandle())); m_allocated = !(m_Id < 0); } /** * Constructor * @param seq An existing MidiClient instance * @param info A QueueInfo object reference * @param parent An optional parent object */ MidiQueue::MidiQueue(MidiClient* seq, const QueueInfo& info, QObject* parent) : QObject(parent) { m_MidiClient = seq; m_Info = info; m_Id = DRUMSTICK_ALSA_CHECK_ERROR(snd_seq_create_queue(m_MidiClient->getHandle(), m_Info.m_Info)); m_allocated = !(m_Id < 0); } /** * Constructor * @param seq An existing MidiClient instance * @param name The name for the new queue * @param parent An optional parent object */ MidiQueue::MidiQueue(MidiClient* seq, const QString name, QObject* parent) : QObject(parent) { m_MidiClient = seq; m_Id = DRUMSTICK_ALSA_CHECK_ERROR(snd_seq_alloc_named_queue(m_MidiClient->getHandle(), name.toLocal8Bit().data())); m_allocated = !(m_Id < 0); } /** * Constructor. * * Note: this constructor doesn't allocate a new queue, it uses an existing one. * @param seq An existing MidiClient instance * @param queue_id An existing queue numeric identifier * @param parent An optional parent object */ MidiQueue::MidiQueue(MidiClient* seq, const int queue_id, QObject* parent) : QObject(parent) { m_MidiClient = seq; m_Id = queue_id; m_allocated = false; } /** * Destructor */ MidiQueue::~MidiQueue() { if ( m_allocated && (m_MidiClient->getHandle() != nullptr) ) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_free_queue(m_MidiClient->getHandle(), m_Id)); } } /** * Gets a QueueInfo object reference * @return A QueueInfo object reference */ QueueInfo& MidiQueue::getInfo() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_queue_info(m_MidiClient->getHandle(), m_Id, m_Info.m_Info)); return m_Info; } /** * Gets a QueueStatus object reference * @return A QueueStatus object reference */ QueueStatus& MidiQueue::getStatus() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_queue_status(m_MidiClient->getHandle(), m_Id, m_Status.m_Info)); return m_Status; } /** * Gets a QueueTempo object reference * @return A QueueTempo object reference */ QueueTempo& MidiQueue::getTempo() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_queue_tempo(m_MidiClient->getHandle(), m_Id, m_Tempo.m_Info)); return m_Tempo; } /** * Gets a QueueTimer object reference * @return A QueueTimer object reference */ QueueTimer& MidiQueue::getTimer() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_queue_timer(m_MidiClient->getHandle(), m_Id, m_Timer.m_Info)); return m_Timer; } /** * Applies a QueueInfo object to the queue * @param value A QueueInfo object reference */ void MidiQueue::setInfo(const QueueInfo& value) { m_Info = value; DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_queue_info(m_MidiClient->getHandle(), m_Id, m_Info.m_Info)); } /** * Applies a QueueTempo object to the queue * @param value A QueueTempo object reference */ void MidiQueue::setTempo(const QueueTempo& value) { m_Tempo = value; DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_queue_tempo(m_MidiClient->getHandle(), m_Id, m_Tempo.m_Info)); } /** * Applies q QueueTimer object to the queue * @param value A QueueTimer object reference */ void MidiQueue::setTimer(const QueueTimer& value) { m_Timer = value; DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_queue_timer(m_MidiClient->getHandle(), m_Id, m_Timer.m_Info)); } /** * Gets the queue usage flag. * * @return 1 = client is allowed to access the queue, 0 = not allowed. */ int MidiQueue::getUsage() { return DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_queue_usage(m_MidiClient->getHandle(), m_Id)); } /** * Sets the queue usage flag. * * @param used 1 = client is allowed to access the queue, 0 = not allowed. */ void MidiQueue::setUsage(int used) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_queue_usage(m_MidiClient->getHandle(), m_Id, used)); } /** * Start the queue. * * This method should start running the queue from the initial position. */ void MidiQueue::start() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_start_queue(m_MidiClient->getHandle(), m_Id, nullptr)); DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_drain_output(m_MidiClient->getHandle())); } /** * Stop the queue. * * This method should stop running the queue. */ void MidiQueue::stop() { if (m_MidiClient != nullptr && m_MidiClient->getHandle() != nullptr) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_stop_queue(m_MidiClient->getHandle(), m_Id, nullptr)); DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_drain_output(m_MidiClient->getHandle())); } } /** * Start the queue without resetting the last position. * * This method should start running the queue from the last position set. */ void MidiQueue::continueRunning() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_continue_queue(m_MidiClient->getHandle(), m_Id, nullptr)); DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_drain_output(m_MidiClient->getHandle())); } /** * Clear the queue, dropping any scheduled events. */ void MidiQueue::clear() { if (m_MidiClient != nullptr && m_MidiClient->getHandle() != nullptr) snd_seq_drop_output(m_MidiClient->getHandle()); } /** * Sets the queue position in musical time (ticks). * @param pos Musical time in ticks. */ void MidiQueue::setTickPosition(snd_seq_tick_time_t pos) { SystemEvent event(SND_SEQ_EVENT_SETPOS_TICK); snd_seq_ev_set_queue_pos_tick(event.getHandle(), m_Id, pos); event.setDirect(); m_MidiClient->outputDirect(&event); } /** * Sets the queue position in real time (clock) units: seconds and nanoseconds. * @param pos Real time (clock) position in seconds/nanoseconds. */ void MidiQueue::setRealTimePosition(snd_seq_real_time_t* pos) { SystemEvent event(SND_SEQ_EVENT_SETPOS_TIME); snd_seq_ev_set_queue_pos_real(event.getHandle(), m_Id, pos); event.setDirect(); m_MidiClient->outputDirect(&event); } } // namespace ALSA } // namespace drumstick drumstick-2.5.1/library/alsa/PaxHeaders.27918/alsa.pro0000644000000000000000000000013214200302440017306 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/alsa/alsa.pro0000644000175000001440000000202314200302440020064 0ustar00pedrousers00000000000000TEMPLATE = lib TARGET = drumstick-alsa DESTDIR = ../../build/lib DEPENDPATH += . ../include INCLUDEPATH += . ../include include (../../global.pri) QT -= gui #QT += dbus CONFIG += c++11 qt thread link_pkgconfig create_pc create_prl no_install_prl static { CONFIG += staticlib } DEFINES += drumstick_alsa_EXPORTS #RTKIT_SUPPORT QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_HIDESYMS QMAKE_PKGCONFIG_PREFIX = $$INSTALLBASE # Input HEADERS += \ ../include/drumstick.h \ ../include/drumstick/alsaclient.h \ ../include/drumstick/alsaevent.h \ ../include/drumstick/alsaport.h \ ../include/drumstick/alsaqueue.h \ ../include/drumstick/alsatimer.h \ ../include/drumstick/macros.h \ ../include/drumstick/playthread.h \ ../include/drumstick/subscription.h \ ../include/drumstick/sequencererror.h \ errorcheck.h SOURCES += \ alsaclient.cpp \ alsaevent.cpp \ alsaport.cpp \ alsaqueue.cpp \ alsatimer.cpp \ playthread.cpp \ sequencererror.cpp \ subscription.cpp linux:PKGCONFIG += alsa drumstick-2.5.1/library/alsa/PaxHeaders.27918/playthread.cpp0000644000000000000000000000013214200302440020505 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.357324521 30 ctime=1644266784.825324181 drumstick-2.5.1/library/alsa/playthread.cpp0000644000175000001440000001405214200302440021270 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ extern "C" { #include } #include #include #include #include #include /** * @file playthread.cpp * Implementation of a sequencer output thread */ /** * @addtogroup PlayThread * @{ * ALSA Sequencer easy playback functionality. * SequencerOutputThread provides MIDI sequence playback. * * This is an abstract class that must be extended providing * an implementation for the pure virtual methods: * SequencerOutputThread::hasNext() and SequencerOutputThread::nextEvent() * before using it for MIDI sequence playback. You can use any structure or * class you prefer to store the SequencerEvent objects, but they must be * provided ordered by time. A simplistic Song definition may be: * * @code * typedef QList Song; * @endcode * * Using this class is optional. You may prefer another mechanism to * manage playback actions. This class uses a thread to manage the * sequence playback as a background task. * @} */ namespace drumstick { namespace ALSA { const int TIMEOUT = 100; /** * Constructor * @param seq Existing MidiClient object pointer * @param portId Numeric input/output port identifier */ SequencerOutputThread::SequencerOutputThread(MidiClient *seq, int portId) : QThread(), m_MidiClient(seq), m_Queue(nullptr), m_PortId(portId), m_Stopped(false), m_QueueId(0), m_npfds(0), m_pfds(nullptr) { if (m_MidiClient != nullptr) { m_Queue = m_MidiClient->getQueue(); m_QueueId = m_Queue->getId(); } } /** * Checks if stop has been requested * @return True if stop has been requested * @since 0.2.0 */ bool SequencerOutputThread::stopRequested() { QReadLocker locker(&m_mutex); return m_Stopped; } /** * Stops the playback task */ void SequencerOutputThread::stop() { QWriteLocker locker(&m_mutex); m_Stopped = true; locker.unlock(); while (isRunning()) { wait(TIMEOUT); } } /** * Sends an echo event, with the same PortId as sender and destination. * @param tick Event schedule time in ticks. */ void SequencerOutputThread::sendEchoEvent(int tick) { if (!stopRequested() && m_MidiClient != nullptr) { SystemEvent ev(SND_SEQ_EVENT_ECHO); ev.setSource(m_PortId); ev.setDestination(m_MidiClient->getClientId(), m_PortId); ev.scheduleTick(m_QueueId, tick, false); sendSongEvent(&ev); } } /** * Sends a SequencerEvent * @param ev SequencerEvent object pointer */ void SequencerOutputThread::sendSongEvent(SequencerEvent* ev) { if (m_MidiClient != nullptr) { while (!stopRequested() && (snd_seq_event_output_direct(m_MidiClient->getHandle(), ev->getHandle()) < 0)) { poll(m_pfds, m_npfds, TIMEOUT); } } } /** * Flush the ALSA output buffer. */ void SequencerOutputThread::drainOutput() { if (!stopRequested() && m_MidiClient != nullptr) { while (!stopRequested() && (snd_seq_drain_output(m_MidiClient->getHandle()) < 0)) { poll(m_pfds, m_npfds, TIMEOUT); } } } /** * Waits until the ALSA output queue is empty (all the events have been played.) */ void SequencerOutputThread::syncOutput() { if (!stopRequested() && m_MidiClient != nullptr) { m_MidiClient->synchronizeOutput(); } } /** * Thread process loop */ void SequencerOutputThread::run() { if (m_MidiClient != nullptr) { try { unsigned int last_tick; m_npfds = snd_seq_poll_descriptors_count(m_MidiClient->getHandle(), POLLOUT); m_pfds = (pollfd*) calloc(m_npfds, sizeof(pollfd)); snd_seq_poll_descriptors(m_MidiClient->getHandle(), m_pfds, m_npfds, POLLOUT); last_tick = getInitialPosition(); if (last_tick == 0) { m_Queue->start(); } else { m_Queue->setTickPosition(last_tick); m_Queue->continueRunning(); } while (!stopRequested() && hasNext()) { SequencerEvent* ev = nextEvent(); if (!stopRequested() && !SequencerEvent::isConnectionChange(ev)) { sendSongEvent(ev); } if (getEchoResolution() > 0) { while (!stopRequested() && (last_tick < ev->getTick())) { last_tick += getEchoResolution(); sendEchoEvent(last_tick); } } } if (stopRequested()) { m_Queue->clear(); emit playbackStopped(); } else { drainOutput(); syncOutput(); if (stopRequested()) emit playbackStopped(); else emit playbackFinished(); } m_Queue->stop(); } catch (...) { qWarning("exception in output thread"); } m_npfds = 0; free(m_pfds); m_pfds = nullptr; } } /** * Starts the playback thread * @param priority Thread priority, default is InheritPriority */ void SequencerOutputThread::start( Priority priority ) { QWriteLocker locker(&m_mutex); m_Stopped = false; QThread::start( priority ); } } // namespace ALSA } // namespace drumstick drumstick-2.5.1/library/alsa/PaxHeaders.27918/subscription.cpp0000644000000000000000000000013214200302440021074 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/alsa/subscription.cpp0000644000175000001440000002654514200302440021671 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "errorcheck.h" #include /** * @file subscription.cpp * Implementation of classes managing ALSA sequencer subscriptions */ /** @ingroup ALSAGroup */ namespace drumstick { namespace ALSA { /** * @addtogroup ALSASubs * @{ * * Subscriptions are virtual MIDI cables between readable and writable ports. * * The ALSA sequencer readable ports are equivalent to the MIDI OUT ports in the * real world. Similarly, the writable ports are equivalent to the MIDI IN ones. * Subscriptions, like real MIDI cables, always involve a readable port (source) * and a writable port (destination). * * Classes: * * Subscriber: This class is used to enumerate the subscribers of a given (root) port. * * Subscription: This class represents a connection between two ports. * * @see https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_subscribe.html * @} */ /** * Default constructor */ Subscriber::Subscriber() { snd_seq_query_subscribe_malloc(&m_Info); } /** * Copy constructor * @param other Existing Subscriber object reference */ Subscriber::Subscriber(const Subscriber& other) { snd_seq_query_subscribe_malloc(&m_Info); snd_seq_query_subscribe_copy(m_Info, other.m_Info); } /** * Constructor * @param other Pointer to an ALSA query subscribe object */ Subscriber::Subscriber(snd_seq_query_subscribe_t* other) { snd_seq_query_subscribe_malloc(&m_Info); snd_seq_query_subscribe_copy(m_Info, other); } /** * Destructor */ Subscriber::~Subscriber() { snd_seq_query_subscribe_free(m_Info); } /** * Copy the current object * @return Pointer to the new object */ Subscriber* Subscriber::clone() { return new Subscriber(m_Info); } /** * Assignment operator * @param other Existing Subscriber object reference * @return This object */ Subscriber& Subscriber::operator=(const Subscriber& other) { if (this == &other) return *this; snd_seq_query_subscribe_copy(m_Info, other.m_Info); return *this; } /** * Gets the subscriber's client number * @return Client number */ int Subscriber::getClient() { return snd_seq_query_subscribe_get_client(m_Info); } /** * Gets the subscriober's port number * @return Port number */ int Subscriber::getPort() { return snd_seq_query_subscribe_get_port(m_Info); } /** * Gets the subscriber's root address * @return Pointer to the ALSA client/port address */ const snd_seq_addr_t* Subscriber::getRoot() { return snd_seq_query_subscribe_get_root(m_Info); } /** * Gets the subscription type (read or write). *
    *
  • SND_SEQ_QUERY_SUBS_READ: read subscriptions
  • *
  • SND_SEQ_QUERY_SUBS_WRITE: write subscriptions
  • *
* @return Subscription type */ snd_seq_query_subs_type_t Subscriber::getType() { return snd_seq_query_subscribe_get_type(m_Info); } /** * Gets the index of the subscriber container * @return Index of the subscriber */ int Subscriber::getIndex() { return snd_seq_query_subscribe_get_index(m_Info); } /** * Gets the number of subscribers returned by a query operation * @return Number of subscribers */ int Subscriber::getNumSubs() { return snd_seq_query_subscribe_get_num_subs(m_Info); } /** * Gets the subscriber's address * @return Pointer to the ALSA address record */ const snd_seq_addr_t* Subscriber::getAddr() { return snd_seq_query_subscribe_get_addr(m_Info); } /** * Gets the subscriber's queue number * @return Queue number */ int Subscriber::getQueue() { return snd_seq_query_subscribe_get_queue(m_Info); } /** * Gets the subscriber's exclusive flag * @return Exclusive flag */ bool Subscriber::getExclusive() { return (snd_seq_query_subscribe_get_exclusive(m_Info) != 0); } /** * Gets the susbcriber's time-update flag * @return Time update flag */ bool Subscriber::getTimeUpdate() { return (snd_seq_query_subscribe_get_time_update(m_Info) != 0); } /** * Gets the subscriber's time real time-stamp flag * @return Time real flag */ bool Subscriber::getTimeReal() { return (snd_seq_query_subscribe_get_time_real(m_Info) != 0); } /** * Sets the subscriber's client number * @param client Client number */ void Subscriber::setClient(int client) { snd_seq_query_subscribe_set_client(m_Info, client); } /** * Sets the subscriber's port number * @param port Port number */ void Subscriber::setPort(int port) { snd_seq_query_subscribe_set_port(m_Info, port); } /** * Sets the subscriber's root address * @param addr Pointer to the root ALSA address record */ void Subscriber::setRoot(snd_seq_addr_t* addr) { snd_seq_query_subscribe_set_root(m_Info, addr); } /** * Sets the subscription type *
    *
  • SND_SEQ_QUERY_SUBS_READ: read subscriptions
  • *
  • SND_SEQ_QUERY_SUBS_WRITE: write subscriptions
  • *
* @param type Subscription type */ void Subscriber::setType(snd_seq_query_subs_type_t type) { snd_seq_query_subscribe_set_type(m_Info, type); } /** * Sets the index of the subscriber * @param index Subscriber index */ void Subscriber::setIndex(int index) { snd_seq_query_subscribe_set_index(m_Info, index); } /** * Gets the size of the ALSA query subscriber object * @return Size of the ALSA object */ int Subscriber::getSizeOfInfo() const { return snd_seq_query_subscribe_sizeof(); } /** * Default constructor */ Subscription::Subscription() { snd_seq_port_subscribe_malloc(&m_Info); } /** * Copy constructor * @param other Existing Subscription object reference */ Subscription::Subscription(const Subscription& other) { snd_seq_port_subscribe_malloc(&m_Info); snd_seq_port_subscribe_copy(m_Info, other.m_Info); } /** * Constructor * @param other Pointer to an ALSA subscription object */ Subscription::Subscription(snd_seq_port_subscribe_t* other) { snd_seq_port_subscribe_malloc(&m_Info); snd_seq_port_subscribe_copy(m_Info, other); } /** * Constructor * @param seq Pointer to a MIDI Client object */ Subscription::Subscription(MidiClient* seq) { snd_seq_port_subscribe_malloc(&m_Info); DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_port_subscription(seq->getHandle(), m_Info)); } /** * Destructor * @return */ Subscription::~Subscription() { snd_seq_port_subscribe_free(m_Info); } /** * Copy the current object * @return Pointer to the new object */ Subscription* Subscription::clone() { return new Subscription(m_Info); } /** * Assignment operator * @param other Existing subscription object reference * @return This object */ Subscription& Subscription::operator=(const Subscription& other) { if (this == &other) return *this; snd_seq_port_subscribe_copy(m_Info, other.m_Info); return *this; } /** * Gets the sender address of the subscription (MIDI OUT port) * @return Pointer to the sender ALSA address record */ const snd_seq_addr_t* Subscription::getSender() { return snd_seq_port_subscribe_get_sender(m_Info); } /** * Gets the destination address of the subscription (MIDI IN port) * @return Pointer to the destination ALSA address record */ const snd_seq_addr_t* Subscription::getDest() { return snd_seq_port_subscribe_get_dest(m_Info); } /** * Gets the susbcription's queue number * @return Queue number */ int Subscription::getQueue() { return snd_seq_port_subscribe_get_queue(m_Info); } /** * Gets the subscription's exclusive flag * @return Exclusive flag */ bool Subscription::getExclusive() { return (snd_seq_port_subscribe_get_exclusive(m_Info) != 0); } /** * Gets the susbcription's time-update flag * @return Time-update flag */ bool Subscription::getTimeUpdate() { return (snd_seq_port_subscribe_get_time_update(m_Info) != 0); } /** * Gets the susbcription's time-real (time-stamping) flag * @return Time real flag */ bool Subscription::getTimeReal() { return (snd_seq_port_subscribe_get_time_real(m_Info) != 0); } /** * Sets the Subscription's sender (MIDI OUT) port * @param addr Pointer to the sender ALSA address record */ void Subscription::setSender(const snd_seq_addr_t* addr) { snd_seq_port_subscribe_set_sender(m_Info, addr); } /** * Sets the Subscription's destination (MIDI IN) port * @param addr Pointer to the destination ALSA address record */ void Subscription::setDest(const snd_seq_addr_t* addr) { snd_seq_port_subscribe_set_dest(m_Info, addr); } /** * Sets the Subscription's Queue number * @param q Queue number */ void Subscription::setQueue(int q) { snd_seq_port_subscribe_set_queue(m_Info, q); } /** * Sets the subscription's exclusive flag * @param val Exclusive flag */ void Subscription::setExclusive(bool val) { snd_seq_port_subscribe_set_exclusive(m_Info, val?1:0); } /** * Sets the susbcription's time-update flag * @param val Time update flag */ void Subscription::setTimeUpdate(bool val) { snd_seq_port_subscribe_set_time_update(m_Info, val?1:0); } /** * Sets the subscription's time real (time-stamping) flag * @param val Time real flag */ void Subscription::setTimeReal(bool val) { snd_seq_port_subscribe_set_time_real(m_Info, val?1:0); } /** * Sets the Subscription's sender (MIDI OUT) port * @param client Client number * @param port Port number */ void Subscription::setSender(unsigned char client, unsigned char port) { snd_seq_addr_t addr; addr.client = client; addr.port = port; setSender(&addr); } /** * Sets the Subscription's destination (MIDI IN) port * @param client Client number * @param port Port number */ void Subscription::setDest(unsigned char client, unsigned char port) { snd_seq_addr_t addr; addr.client = client; addr.port = port; setDest(&addr); } /** * Performs the subscription in the ALSA sequencer subsystem. * Neither the sender nor the destination ports need to belong to the * same MidiClient instance performing the subscription. * @param seq MidiClient instance pointer */ void Subscription::subscribe(MidiClient* seq) { if ((m_Info == nullptr) || (seq == nullptr) || !(seq->isOpened())) { return; } DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_subscribe_port(seq->getHandle(), m_Info)); } /** * Breaks the subscription in the ALSA sequencer subsystem. * Neither the sender nor the destination ports need to belong to the * same MidiClient instance breaking the subscription. * @param seq MidiClient instance pointer */ void Subscription::unsubscribe(MidiClient* seq) { if ((m_Info == nullptr) || (seq == nullptr) || !(seq->isOpened())) { return; } DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_unsubscribe_port(seq->getHandle(), m_Info)); } /** * Gets the size of the ALSA subscription object * @return Size of the ALSA object */ int Subscription::getSizeOfInfo() const { return snd_seq_port_subscribe_sizeof(); } } // namespace ALSA } // namespace drumstick drumstick-2.5.1/library/alsa/PaxHeaders.27918/alsaport.cpp0000644000000000000000000000013214200302440020175 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.357324521 30 ctime=1644266784.821324179 drumstick-2.5.1/library/alsa/alsaport.cpp0000644000175000001440000006432414200302440020767 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "errorcheck.h" #include #include /** * @file alsaport.cpp * Implementation of classes managing ALSA Sequencer ports. */ namespace drumstick { namespace ALSA { /** * @addtogroup ALSAPort * @{ * * Ports are the endpoints of the MIDI connections. * * Ports can be readable, writable, or both. They can be private for the owner * application, or can be subscribed by a third application. * * The ALSA sequencer readable ports are equivalent to the MIDI OUT ports in the * real world. Similarly, the writable ports are equivalent to the MIDI IN ones. * * Classes: * * PortInfo is a container to retrieve and change some properties about the ALSA * MIDI ports. * * MidiPort represents an ALSA MIDI port. * * @see https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_port.html * @} */ /** * Default constructor. */ PortInfo::PortInfo() { snd_seq_port_info_malloc(&m_Info); } /** * Copy constructor * @param other Another PortInfo object reference */ PortInfo::PortInfo(const PortInfo& other) { snd_seq_port_info_malloc(&m_Info); snd_seq_port_info_copy(m_Info, other.m_Info); m_ReadSubscribers = other.m_ReadSubscribers; m_WriteSubscribers = other.m_WriteSubscribers; m_ClientName = other.m_ClientName; } /** * Constructor * @param other An ALSA port info object pointer */ PortInfo::PortInfo(snd_seq_port_info_t* other) { snd_seq_port_info_malloc(&m_Info); snd_seq_port_info_copy(m_Info, other); } /** * Constructor * @param seq A MidiClient instance * @param client An existing client number * @param port An existing port number */ PortInfo::PortInfo(MidiClient* seq, const int client, const int port) { snd_seq_port_info_malloc(&m_Info); DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_any_port_info(seq->getHandle(), client, port, m_Info)); } /** * Constructor * @param seq A MidiClient instance * @param port An existing port number */ PortInfo::PortInfo(MidiClient* seq, const int port) { snd_seq_port_info_malloc(&m_Info); DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_get_port_info(seq->getHandle(), port, m_Info)); } /** * Destructor */ PortInfo::~PortInfo() { snd_seq_port_info_free(m_Info); freeSubscribers(); } /** * Copy the current object * @return A pointer to the new object */ PortInfo* PortInfo::clone() { return new PortInfo(m_Info); } /** * Assignment operator * @param other Another PortInfo object reference * @return This object */ PortInfo& PortInfo::operator=(const PortInfo& other) { if (this == &other) return *this; snd_seq_port_info_copy(m_Info, other.m_Info); m_ReadSubscribers = other.m_ReadSubscribers; m_WriteSubscribers = other.m_WriteSubscribers; m_ClientName = other.m_ClientName; return *this; } /** * Gets the client number * @return The client number * @see setClient() */ int PortInfo::getClient() { return snd_seq_port_info_get_client(m_Info); } /** * Gets the port number * @return The port number * @see setPort() */ int PortInfo::getPort() { return snd_seq_port_info_get_port(m_Info); } /** * Gets the client name. * @return the client name * @see setClientName() */ QString PortInfo::getClientName() const { return m_ClientName; } /** * Gets the address record for this port * @return A pointer to the address record * @see setAddr() */ const snd_seq_addr_t* PortInfo::getAddr() { return snd_seq_port_info_get_addr(m_Info); } /** * Gets the port name * @return The port name * @see setName() */ QString PortInfo::getName() { return QString(snd_seq_port_info_get_name(m_Info)); } /** * Gets the capabilities bitmap * @return The capabilities bitmap * @see setCapability() */ unsigned int PortInfo::getCapability() { return snd_seq_port_info_get_capability(m_Info); } /** * Gets the port type * @return The port type * @see setType() */ unsigned int PortInfo::getType() { return snd_seq_port_info_get_type(m_Info); } /** * Gets the MIDI channels * @return The MIDI channels * @see setMidiChannels() */ int PortInfo::getMidiChannels() { return snd_seq_port_info_get_midi_channels(m_Info); } /** * Gets the MIDI voices * @return The MIDI voices * @see setMidiVoices() */ int PortInfo::getMidiVoices() { return snd_seq_port_info_get_midi_voices(m_Info); } /** * Gets the synth voices * @return The synth voices * @see setSynthVoices() */ int PortInfo::getSynthVoices() { return snd_seq_port_info_get_synth_voices(m_Info); } /** * Get the number of read subscriptions. * @return The number of read subscriptions. */ int PortInfo::getReadUse() { return snd_seq_port_info_get_read_use(m_Info); } /** * Gets the number of write subscriptions. * @return The number of write subscriptions. */ int PortInfo::getWriteUse() { return snd_seq_port_info_get_write_use(m_Info); } /** * Gets the port-specified mode. * @return The port-specified mode. * @see setPortSpecified() */ int PortInfo::getPortSpecified() { return snd_seq_port_info_get_port_specified(m_Info); } /** * Sets the client number * @param client The client number * @see getClient() */ void PortInfo::setClient(int client) { snd_seq_port_info_set_client(m_Info, client); } /** * Set the port number * @param port The port number * @see getPort() */ void PortInfo::setPort(int port) { snd_seq_port_info_set_port(m_Info, port); } /** * Sets the address record * @param addr An address record pointer * @see getAddr() */ void PortInfo::setAddr(const snd_seq_addr_t* addr) { snd_seq_port_info_set_addr(m_Info, addr); } /** * Sets the port name * @param name The port name * @see getName() */ void PortInfo::setName(QString const& name) { snd_seq_port_info_set_name(m_Info, name.toLocal8Bit().data()); } /** * Sets the capability bitmap. * * Each port has the capability bitmaps to specify the access of * the port from other clients. The capability bit flags are: *
    *
  • SND_SEQ_PORT_CAP_READ Readable from this port
  • *
  • SND_SEQ_PORT_CAP_WRITE Writable to this port
  • *
  • SND_SEQ_PORT_CAP_DUPLEX Read/write duplex access is supported
  • *
  • SND_SEQ_PORT_CAP_SUBS_READ Read subscription is allowed
  • *
  • SND_SEQ_PORT_CAP_SUBS_WRITE Write subscription is allowed
  • *
  • SND_SEQ_PORT_CAP_NO_EXPORT Subscription management from 3rd clients is disallowed
  • *
* @param capability The capability bitmap. * @see getCapability() */ void PortInfo::setCapability(unsigned int capability) { snd_seq_port_info_set_capability(m_Info, capability); } /** * Sets the port type. * * The port type is defined combining some of the type bit flags: *
    *
  • SND_SEQ_PORT_TYPE_SPECIFIC Hardware specific port
  • *
  • SND_SEQ_PORT_TYPE_MIDI_GENERIC Generic MIDI device
  • *
  • SND_SEQ_PORT_TYPE_MIDI_GM General MIDI compatible device
  • *
  • SND_SEQ_PORT_TYPE_MIDI_GM2 General MIDI 2 compatible device
  • *
  • SND_SEQ_PORT_TYPE_MIDI_GS GS compatible device
  • *
  • SND_SEQ_PORT_TYPE_MIDI_XG XG compatible device
  • *
  • SND_SEQ_PORT_TYPE_MIDI_MT32 MT-32 compatible device
  • *
  • SND_SEQ_PORT_TYPE_HARDWARE Implemented in hardware
  • *
  • SND_SEQ_PORT_TYPE_SOFTWARE Implemented in software
  • *
  • SND_SEQ_PORT_TYPE_SYNTHESIZER Generates sound
  • *
  • SND_SEQ_PORT_TYPE_PORT Connects to other device(s)
  • *
  • SND_SEQ_PORT_TYPE_APPLICATION Application (sequencer/editor)
  • *
* @param type The port type bitmap * @see getType() */ void PortInfo::setType(unsigned int type) { snd_seq_port_info_set_type(m_Info, type); } /** * Set the MIDI channels * @param channels The MIDI channels * @see getMidiChannels() */ void PortInfo::setMidiChannels(int channels) { snd_seq_port_info_set_midi_channels(m_Info, channels); } /** * Sets the MIDI voices * @param voices The MIDI voices * @see getMidiVoices() */ void PortInfo::setMidiVoices(int voices) { snd_seq_port_info_set_midi_voices(m_Info, voices); } /** * Sets the synth voices * @param voices The synth voices * @see getSynthVoices() */ void PortInfo::setSynthVoices(int voices) { snd_seq_port_info_set_synth_voices(m_Info, voices); } /** * Sets the port-specified mode * @param val The port-specified mode. * @see getPortSpecified() */ void PortInfo::setPortSpecified(int val) { snd_seq_port_info_set_port_specified(m_Info, val); } /** * Gets the list of read subscribers * @return The list of read subscribers */ SubscribersList PortInfo::getReadSubscribers() const { return m_ReadSubscribers; // copy } /** * Gets the list of write subscribers * @return The list of write subscribers */ SubscribersList PortInfo::getWriteSubscribers() const { return m_WriteSubscribers; // copy } /** * Obtains the port subscribers lists * @param seq An opened MidiClient instance */ void PortInfo::readSubscribers(MidiClient* seq) { Subscriber subs; snd_seq_addr_t tmp; freeSubscribers(); tmp.client = getClient(); tmp.port = getPort(); // Read subs subs.setType(SND_SEQ_QUERY_SUBS_READ); subs.setIndex(0); subs.setRoot(&tmp); while (snd_seq_query_port_subscribers(seq->getHandle(), subs.m_Info) >= 0) { m_ReadSubscribers.append(subs); subs.setIndex(subs.getIndex() + 1); } // Write subs subs.setType(SND_SEQ_QUERY_SUBS_WRITE); subs.setIndex(0); subs.setRoot(&tmp); while (snd_seq_query_port_subscribers(seq->getHandle(), subs.m_Info) >= 0) { m_WriteSubscribers.append(subs); subs.setIndex(subs.getIndex() + 1); } } /** * Releases the subscribers lists */ void PortInfo::freeSubscribers() { m_ReadSubscribers.clear(); m_WriteSubscribers.clear(); } /** * Sets the client name. * @see getClientName() * @param name Client name */ void PortInfo::setClientName(QString name) { m_ClientName = name; } /** * Gets the size of the ALSA info object * @return The size of the object */ int PortInfo::getSizeOfInfo() const { return snd_seq_port_info_sizeof(); } /** * Gets the timestamping mode * @return The timestamping mode * @see setTimestamping() */ bool PortInfo::getTimestamping() { return (snd_seq_port_info_get_timestamping(m_Info) == 1); } /** * Gets the timestamping real mode * @return The timestamping real mode * @see setTimestampReal() */ bool PortInfo::getTimestampReal() { return (snd_seq_port_info_get_timestamp_real(m_Info) == 1); } /** * Gets the timestamping queue number * @return The timestamping queue number * @see setTimestampQueue() */ int PortInfo::getTimestampQueue() { return snd_seq_port_info_get_timestamp_queue(m_Info); } /** * Sets the timestamping mode * @param value The timestamping mode * @see getTimestamping() */ void PortInfo::setTimestamping(bool value) { snd_seq_port_info_set_timestamping(m_Info, value?1:0); } /** * Sets the timestamping real mode * @param value The timestamping real mode * @see getTimestampReal() */ void PortInfo::setTimestampReal(bool value) { snd_seq_port_info_set_timestamp_real(m_Info, value?1:0); } /** * Sets the timestamp queue number * @param queueId The timestamp queue number * @see getTimestampQueue() */ void PortInfo::setTimestampQueue(int queueId) { snd_seq_port_info_set_timestamp_queue(m_Info, queueId); } /** * Constructor * @param parent An optional parent object */ MidiPort::MidiPort( QObject* parent ) : QObject( parent ), m_MidiClient( nullptr ), m_Attached( false ) {} /** * Destructor. * * All subscriptions are released. */ MidiPort::~MidiPort() { unsubscribeAll(); detach(); freeSubscriptions(); } /** * Gets the PortInfo object pointer * @return the PortInfo object pointer */ PortInfo* MidiPort::getPortInfo() { return &m_Info; } /** * Gets the list of susbcriptions * @return The list of susbcriptions */ SubscriptionsList MidiPort::getSubscriptions() const { return m_Subscriptions; } /** * Releases the lists of subscriptions. */ void MidiPort::freeSubscriptions() { m_Subscriptions.clear(); } /** * Sets the MidiClient * @param seq A MidiClient object pointer */ void MidiPort::setMidiClient( MidiClient* seq ) { if (m_MidiClient != seq) { m_MidiClient = seq; emit midiClientChanged( this, m_MidiClient ); applyPortInfo(); } } /** * Subscribe a Subscription object * @param subs A Subscription object pointer */ void MidiPort::subscribe(Subscription* subs) { subs->subscribe(m_MidiClient); m_Subscriptions.append(*subs); emit subscribed(this, subs); } /** * Unsubscribe a Subscription object * @param subs A Subscription object pointer */ void MidiPort::unsubscribe( Subscription* subs ) { Subscription subs2; if (m_MidiClient == nullptr) { return; } subs->unsubscribe(m_MidiClient); SubscriptionsList::iterator it; for(it = m_Subscriptions.begin(); it != m_Subscriptions.end(); ++it) { subs2 = (*it); if ((subs2.getSender()->client == subs->getSender()->client) && (subs2.getSender()->port == subs->getSender()->port) && (subs2.getDest()->client == subs->getDest()->client) && (subs2.getDest()->port == subs->getDest()->port)) { m_Subscriptions.erase(it); break; } } } /** * Subscribe to another port destination * @param info A PortInfo object pointer */ void MidiPort::subscribeTo( PortInfo* info ) { Subscription subs; subs.setSender(m_Info.getAddr()); subs.setDest(info->getAddr()); subscribe(&subs); } /** * Susbcribe to another port destination * @param client ALSA client number * @param port ALSA port number */ void MidiPort::subscribeTo( int client, int port ) { Subscription subs; snd_seq_addr addr; addr.client = client; addr.port = port; subs.setSender(m_Info.getAddr()); subs.setDest(&addr); subscribe(&subs); } /** * Subscribe to another port destination * @param name A string representing a client:port pair */ void MidiPort::subscribeTo( QString const& name ) { Subscription subs; snd_seq_addr addr; if ((m_MidiClient != nullptr) && (m_MidiClient->getHandle() != nullptr)) { subs.setSender(m_Info.getAddr()); if (m_MidiClient->parseAddress(name, addr)) { subs.setDest(&addr); subscribe(&subs); } } } /** * Unsubscribe a destination port * @param name A string representing a client:port pair */ void MidiPort::unsubscribeTo( QString const& name ) { Subscription subs; snd_seq_addr addr; if ((m_MidiClient != nullptr) && (m_MidiClient->getHandle() != nullptr)) { subs.setSender(m_Info.getAddr()); if (m_MidiClient->parseAddress(name, addr)) { subs.setDest(&addr); unsubscribe(&subs); } } } /** * Unsubscribe a destination port * @param port A PortInfo object pointer */ void MidiPort::unsubscribeTo( PortInfo* port ) { Subscription subs; if ((m_MidiClient != nullptr) && (m_MidiClient->getHandle() != nullptr)) { subs.setSender(m_Info.getAddr()); subs.setDest(port->getAddr()); unsubscribe(&subs); } } /** * Unsubscribe a destination port * @param addr An ALSA address record pointer */ void MidiPort::unsubscribeTo( const snd_seq_addr_t* addr ) { Subscription subs; if ((m_MidiClient != nullptr) && (m_MidiClient->getHandle() != nullptr)) { subs.setSender(m_Info.getAddr()); subs.setDest(addr); unsubscribe(&subs); } } /** * Subscribe a source port * @param port A PortInfo object pointer */ void MidiPort::subscribeFrom( PortInfo* port ) { Subscription subs; subs.setSender( port->getAddr() ); subs.setDest( m_Info.getAddr() ); subscribe(&subs); } /** * Subscribe a source port * @param client ALSA client number * @param port ALSA port number */ void MidiPort::subscribeFrom( int client, int port ) { Subscription subs; snd_seq_addr addr; addr.client = client; addr.port = port; subs.setSender(&addr); subs.setDest(m_Info.getAddr()); subscribe(&subs); } /** * Subscribe a source port * @param name A string representing a client:port pair */ void MidiPort::subscribeFrom( QString const& name ) { Subscription subs; snd_seq_addr addr; if ((m_MidiClient != nullptr) && (m_MidiClient->getHandle() != nullptr)) { if (m_MidiClient->parseAddress(name, addr)) { subs.setSender(&addr); subs.setDest(m_Info.getAddr()); subscribe(&subs); } } } /** * Unsubscribe a source port * @param name A string representing a client:port pair */ void MidiPort::unsubscribeFrom( QString const& name ) { Subscription subs; snd_seq_addr addr; if ((m_MidiClient != nullptr) && (m_MidiClient->getHandle() != nullptr)) { if (m_MidiClient->parseAddress(name, addr)) { subs.setSender(&addr); subs.setDest(m_Info.getAddr()); unsubscribe(&subs); } } } /** * Unsubscribe a source port * @param port A PortInfo object pointer */ void MidiPort::unsubscribeFrom( PortInfo* port ) { Subscription subs; if ((m_MidiClient != nullptr) && (m_MidiClient->getHandle() != nullptr)) { subs.setSender(port->getAddr()); subs.setDest(m_Info.getAddr()); unsubscribe(&subs); } } /** * Unsubscribe a source port * @param addr An ALSA address record pointer */ void MidiPort::unsubscribeFrom( const snd_seq_addr_t* addr ) { Subscription subs; if ((m_MidiClient != nullptr) && (m_MidiClient->getHandle() != nullptr)) { subs.setSender(addr); subs.setDest(m_Info.getAddr()); unsubscribe(&subs); } } /** * Subscribe from the System:announce port */ void MidiPort::subscribeFromAnnounce() { subscribeFrom(SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); } /** * Unsubscribe all subscriptions */ void MidiPort::unsubscribeAll() { if (m_MidiClient == nullptr) { return; } SubscriptionsList::Iterator it; for( it = m_Subscriptions.begin(); it != m_Subscriptions.end(); ++it) { Subscription s = (*it); s.unsubscribe(m_MidiClient); } m_Subscriptions.clear(); } /** * Applies all the the delayed PortInfo changes to the MIDI port object */ void MidiPort::applyPortInfo() { if (m_Attached && (m_MidiClient != nullptr) && (m_MidiClient->isOpened())) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_port_info( m_MidiClient->getHandle(), m_Info.getPort(), m_Info.m_Info )); } } /** * Gets the port name * @return The port name */ QString MidiPort::getPortName() { return m_Info.getName(); } /** * Sets the port name * @param newName The new port name */ void MidiPort::setPortName( QString const& newName ) { m_Info.setName(newName); applyPortInfo(); } /** * Gets the port number * @return The port number */ int MidiPort::getPortId() { return m_Info.getPort(); } /** * Gets the port capabilities * @return The capabilities bitmap * @see PortInfo::getCapability() */ unsigned int MidiPort::getCapability() { return m_Info.getCapability(); } /** * Sets the port capabilities * @param newValue The capabilities bitmap * @see PortInfo::setCapability() */ void MidiPort::setCapability(unsigned int newValue) { m_Info.setCapability(newValue); applyPortInfo(); } /** * Gets the port type * @return The port type bitmap * @see PortInfo::getType() */ unsigned int MidiPort::getPortType() { return m_Info.getType(); } /** * Sets the port type bitmap * @param newValue The port type flags bitmap * @see PortInfo::setType() */ void MidiPort::setPortType( unsigned int newValue) { m_Info.setType( newValue ); applyPortInfo(); } /** * Gets the MIDI channels * @return The MIDI channels */ int MidiPort::getMidiChannels() { return m_Info.getMidiChannels(); } /** * Sets the MIDI channels * @param newValue The MIDI channels */ void MidiPort::setMidiChannels(int newValue) { m_Info.setMidiChannels( newValue ); applyPortInfo(); } /** * Gets the MIDI voices * @return The MIDI voices */ int MidiPort::getMidiVoices() { return m_Info.getMidiVoices(); } /** * Sets the MIDI voices * @param newValue The MIDI voices */ void MidiPort::setMidiVoices(int newValue) { m_Info.setMidiVoices( newValue ); applyPortInfo(); } /** * Gets the synth voices * @return The synth voices */ int MidiPort::getSynthVoices() { return m_Info.getSynthVoices(); } /** * Sets the synth voices * @param newValue The synth voices */ void MidiPort::setSynthVoices(int newValue) { m_Info.setSynthVoices( newValue ); applyPortInfo(); } /** * Gets the timestamping mode * @return The timestamping mode */ bool MidiPort::getTimestamping() { return m_Info.getTimestamping(); } /** * Gets the timestamp real mode * @return The timestamp real mode */ bool MidiPort::getTimestampReal() { return m_Info.getTimestampReal(); } /** * Gets the timestamp queue number * @return The timestamp queue number */ int MidiPort::getTimestampQueue() { return m_Info.getTimestampQueue(); } /** * Sets the timestamping mode * @param value The timestamping mode */ void MidiPort::setTimestamping(bool value) { m_Info.setTimestamping(value); applyPortInfo(); } /** * Sets the timestamp real mode * @param value The timestamp real mode */ void MidiPort::setTimestampReal(bool value) { m_Info.setTimestampReal(value); applyPortInfo(); } /** * Sets the timestamp queue number * @param queueId The queue number */ void MidiPort::setTimestampQueue(int queueId) { m_Info.setTimestampQueue(queueId); applyPortInfo(); } /** * Attach the port to a MidiClient instance * @param seq A MidiClient object pointer */ void MidiPort::attach( MidiClient* seq ) { if (!m_Attached && (seq != nullptr)) { m_MidiClient = seq; m_MidiClient->portAttach(this); m_Attached = true; emit attached(this); } } /** * Detach the port from any MidiClient instance previously attached */ void MidiPort::detach() { if (m_Attached && (m_MidiClient != nullptr)) { m_MidiClient->portDetach(this); m_Attached = false; emit detached(this); } } /** * Update the subscribers list in the PortInfo member */ void MidiPort::updateSubscribers() { m_Info.readSubscribers(m_MidiClient); } /** * Gets the list of read subscribers * @return The list of read subscribers */ PortInfoList MidiPort::getReadSubscribers() { const SubscribersList subs(m_Info.getReadSubscribers()); PortInfoList lst; SubscribersList::ConstIterator it; for(it = subs.constBegin(); it != subs.constEnd(); ++it) { Subscriber s = *it; int client = s.getAddr()->client; if ((client != SND_SEQ_CLIENT_SYSTEM) && (client != m_Info.getClient())) { int port = s.getAddr()->port; PortInfo p(m_MidiClient, client, port); if ((p.getCapability() & SND_SEQ_PORT_CAP_NO_EXPORT) == 0) { p.setClientName(m_MidiClient->getClientName(client)); lst << p; } } } return lst; } /** * Gets the list of write subscribers * @return The list of write subscribers */ PortInfoList MidiPort::getWriteSubscribers() { const SubscribersList subs(m_Info.getWriteSubscribers()); PortInfoList lst; SubscribersList::ConstIterator it; for(it = subs.constBegin(); it != subs.constEnd(); ++it) { Subscriber s = *it; int client = s.getAddr()->client; if ((client != SND_SEQ_CLIENT_SYSTEM) && (client != m_Info.getClient())) { int port = s.getAddr()->port; PortInfo p(m_MidiClient, client, port); if ((p.getCapability() & SND_SEQ_PORT_CAP_NO_EXPORT) == 0) { p.setClientName(m_MidiClient->getClientName(client)); lst << p; } } } return lst; } /** * Checks if the provided address is included in the port list * @param addr ALSA address record pointer * @param lst List of port information containers * @return True if the address is found */ bool MidiPort::containsAddress(const snd_seq_addr_t* addr, const PortInfoList& lst) { PortInfoList::ConstIterator i; for( i = lst.begin(); i != lst.end(); ++i) { PortInfo p = *i; if ((p.getAddr()->client == addr->client) && (p.getAddr()->port == addr->port)) { return true; } } return false; } /** * Update the write subscriptions * @param ports List of writable ports to be subscribed */ void MidiPort::updateConnectionsTo(const PortInfoList& ports) { PortInfoList subs(getReadSubscribers()); PortInfoList::ConstIterator i; for (i = subs.constBegin(); i != subs.constEnd(); ++i) { PortInfo s = *i; if (!containsAddress(s.getAddr(), ports)) { unsubscribeTo(s.getAddr()); } } for (i = ports.constBegin(); i != ports.constEnd(); ++i) { PortInfo p = *i; if (!containsAddress(p.getAddr(), subs)) { subscribeTo(&p); } } } /** * Update the read susbcriptions * @param ports List of readable ports to be subscribed */ void MidiPort::updateConnectionsFrom(const PortInfoList& ports) { PortInfoList subs(getWriteSubscribers()); PortInfoList::ConstIterator i; for (i = subs.constBegin(); i != subs.constEnd(); ++i) { PortInfo s = *i; if (!containsAddress(s.getAddr(), ports)) { unsubscribeFrom(s.getAddr()); } } for (i = ports.constBegin(); i != ports.constEnd(); ++i) { PortInfo p = *i; if (!containsAddress(p.getAddr(), subs)) { subscribeFrom(&p); } } } } // namespace ALSA } // namespace drumstick drumstick-2.5.1/library/alsa/PaxHeaders.27918/sequencererror.cpp0000644000000000000000000000013214200302440021414 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/alsa/sequencererror.cpp0000644000175000001440000000267114200302440022203 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ extern "C" { #include } #include /** * @file sequencererror.cpp * SequencerError Exception class implementation */ namespace drumstick { namespace ALSA { /** * @addtogroup ALSAError * @{ */ SequencerError::SequencerError(QString const& s, int rc): m_location(s), m_errCode(rc) { } const char *SequencerError::what() const noexcept { return snd_strerror(m_errCode); } QString SequencerError::qstrError() const { return QString(what()); } int SequencerError::code() const { return m_errCode; } const QString &SequencerError::location() const { return m_location; } /** @} */ } // namespace ALSA } // namespace drumstick drumstick-2.5.1/library/alsa/PaxHeaders.27918/alsaevent.cpp0000644000000000000000000000013214200302440020332 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/alsa/alsaevent.cpp0000644000175000001440000007120614200302440021121 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "errorcheck.h" #include /** * @file alsaevent.cpp * Implementation of classes managing ALSA Sequencer events. */ /** * @class QEvent * The QEvent class is the base class of all event classes. * @see https://doc.qt.io/qt-5/qevent.html */ namespace drumstick { namespace ALSA { /** * @addtogroup ALSAEvent * @{ * * MIDI Events are messages transmitted between MIDI devices or applications. * * Classes: * * SequencerEvent: Base class for the event's hierarchy. * * ChannelEvent: Base class for the events having a Channel property. * * KeyEvent: Base class for the events having Key and Velocity properties. * * NoteEvent: Class representing a note event with duration. * * NoteOnEvent: Event representing a note-on MIDI event. * * NoteOffEvent: Event representing a note-off MIDI event. * * KeyPressEvent: Event representing a MIDI key pressure, or polyphonic after-touch event. * * ControllerEvent: Event representing a MIDI control change event. * * ProgramChangeEvent: Event representing a MIDI program change event. * * PitchBendEvent: Event representing a MIDI bender, or pitch wheel event. * * ChanPressEvent: Event representing a MIDI channel pressure or after-touch event. * * VariableEvent: Base class for variable length events. * * SysExEvent: Event representing a MIDI system exclusive event. * * TextEvent: Event representing a SMF text event. * * SystemEvent: Generic event. * * QueueControlEvent: ALSA Event representing a queue control command. * * ValueEvent: Generic event having a value property. * * TempoEvent: ALSA Event representing a tempo change for an ALSA queue. * * SubscriptionEvent: ALSA Event representing a subscription between two ALSA clients and ports. * * ClientEvent: ALSA Event representing a change on some ALSA sequencer client. * * PortEvent: ALSA Event representing a change on some ALSA sequencer port. * * RemoveEvents: Auxiliary class to remove events from an ALSA queue. * * MidiCodec: Auxiliary class to translate between raw MIDI streams and ALSA events. * * @see https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_event.html * @see https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_events.html * @see https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_ev_type.html * @see https://www.alsa-project.org/alsa-doc/alsa-lib/group___m_i_d_i___event.html * @} */ /** * Default constructor. */ SequencerEvent::SequencerEvent() : QEvent(SequencerEventType) { snd_seq_ev_clear( &m_event ); } /** * Constructor from an ALSA event record * @param event ALSA event record */ SequencerEvent::SequencerEvent(const snd_seq_event_t* event) : QEvent(SequencerEventType) { snd_seq_ev_clear( &m_event ); m_event = *event; } /** * Copy constructor * @param other A SequencerEvent object reference */ SequencerEvent::SequencerEvent(const SequencerEvent& other) : QEvent(SequencerEventType) { snd_seq_ev_clear( &m_event ); m_event = other.m_event; } /** * Assignment operator * @param other A SequencerEvent object reference * @return This object */ SequencerEvent& SequencerEvent::operator=(const SequencerEvent& other) { m_event = other.m_event; return *this; } /** * Checks if the event's type is a subscription. * @param event A SequencerEvent object pointer * @return True if the event has a subscribe/unsubscribe type. */ bool SequencerEvent::isSubscription(const SequencerEvent* event) { snd_seq_event_type_t te = event->getSequencerType(); return ( te == SND_SEQ_EVENT_PORT_SUBSCRIBED || te == SND_SEQ_EVENT_PORT_UNSUBSCRIBED ); } /** * Checks if the event's type is of type port. * @param event A SequencerEvent object pointer * @return True if the event has a port start/exit/change type. */ bool SequencerEvent::isPort(const SequencerEvent* event) { snd_seq_event_type_t te = event->getSequencerType(); return ( te == SND_SEQ_EVENT_PORT_START || te == SND_SEQ_EVENT_PORT_EXIT || te == SND_SEQ_EVENT_PORT_CHANGE ); } /** * Checks if the event's type is of type client. * @param event A SequencerEvent object pointer * @return True if the event has a client start/exit/change type. */ bool SequencerEvent::isClient(const SequencerEvent* event) { snd_seq_event_type_t te = event->getSequencerType(); return ( te == SND_SEQ_EVENT_CLIENT_START || te == SND_SEQ_EVENT_CLIENT_EXIT || te == SND_SEQ_EVENT_CLIENT_CHANGE ); } /** * Checks if the event's type is of type connection change. * @param event A SequencerEvent object pointer * @return True if the event has a client/port/subscription type. */ bool SequencerEvent::isConnectionChange(const SequencerEvent* event) { snd_seq_event_type_t te = event->getSequencerType(); return ( te == SND_SEQ_EVENT_PORT_START || te == SND_SEQ_EVENT_PORT_EXIT || te == SND_SEQ_EVENT_PORT_CHANGE || te == SND_SEQ_EVENT_CLIENT_START || te == SND_SEQ_EVENT_CLIENT_EXIT || te == SND_SEQ_EVENT_CLIENT_CHANGE || te == SND_SEQ_EVENT_PORT_SUBSCRIBED || te == SND_SEQ_EVENT_PORT_UNSUBSCRIBED ); } /** * Checks if the event's type is a Channel Voice message. * @param event A SequencerEvent object pointer * @return True if the event is a channel voice message. * @since 0.2.0 */ bool SequencerEvent::isChannel(const SequencerEvent* event) { snd_seq_event_type_t te = event->getSequencerType(); return ( te == SND_SEQ_EVENT_NOTEOFF || te == SND_SEQ_EVENT_NOTEON || te == SND_SEQ_EVENT_NOTE || te == SND_SEQ_EVENT_KEYPRESS || te == SND_SEQ_EVENT_CONTROLLER || te == SND_SEQ_EVENT_CONTROL14 || te == SND_SEQ_EVENT_PGMCHANGE || te == SND_SEQ_EVENT_CHANPRESS || te == SND_SEQ_EVENT_PITCHBEND ); } /** * Sets the event's ALSA sequencer type * @param eventType The ALSA sequencer type */ void SequencerEvent::setSequencerType(const snd_seq_event_type_t eventType) { m_event.type = eventType; } /** * Sets the client:port destination of the event. * @param client The destination's client ID * @param port The destination port ID * @see setSubscribers() */ void SequencerEvent::setDestination(const unsigned char client, const unsigned char port) { snd_seq_ev_set_dest(&m_event, client, port); } /** * Sets the event's source port ID * @param port The source port ID * @see getSourceClient(), getSourcePort() */ void SequencerEvent::setSource(const unsigned char port) { snd_seq_ev_set_source(&m_event, port); } /** * Sets the event's destination to be all the subscribers of the source port. */ void SequencerEvent::setSubscribers() { snd_seq_ev_set_subs(&m_event); } /** * Sets the event's destination to be all queues/clients/ports/channels. */ void SequencerEvent::setBroadcast() { snd_seq_ev_set_broadcast(&m_event); } /** * Sets the event to be immediately delivered, not queued/scheduled. * @see scheduleTick(), scheduleReal() */ void SequencerEvent::setDirect() { snd_seq_ev_set_direct(&m_event); } /** * Sets the event to be scheduled in musical time (ticks) units. * @param queue The queue number to be used. * @param tick The time in ticks. * @param relative Use relative (to the current) time instead of absolute time. */ void SequencerEvent::scheduleTick(int queue, int tick, bool relative) { snd_seq_ev_schedule_tick(&m_event, queue, relative, tick); } /** * Sets the event to be scheduled in real (clock) time units. * @param queue The queue number to be used. * @param secs The time in whole seconds. * @param nanos The nanoseconds to be added. * @param relative Use relative (to the current) time instead of absolute time. */ void SequencerEvent::scheduleReal(int queue, ulong secs, ulong nanos, bool relative) { snd_seq_real_time_t rtime; rtime.tv_sec = secs; rtime.tv_nsec = nanos; snd_seq_ev_schedule_real(&m_event, queue, relative, &rtime); } /** * Sets the priority of the event. This is used in case of several events share * the same scheduling time. * * @param high Mark the event as a high priority one. */ void SequencerEvent::setPriority(const bool high) { snd_seq_ev_set_priority(&m_event, high); } /** * Sets the event's tag. This attribute is any arbitrary number, not used by * the ALSA library. Range limited to 0 thru 255. * @param aTag A tag number. */ void SequencerEvent::setTag(const unsigned char aTag) { #if SND_LIB_VERSION > 0x010008 snd_seq_ev_set_tag(&m_event, aTag); #else m_event.tag = aTag; #endif } /** * Gets an event's raw 32 bits parameter. * @param n The parameter index, between 0 and 2. * @return The parameter's value. * @see setRaw32() */ unsigned int SequencerEvent::getRaw32(const unsigned int n) const { if (n < 3) return m_event.data.raw32.d[n]; return 0; } /** * Sets an event's raw 32 bits parameter. * @param n The parameter index, between 0 and 2. * @param value The parameter's value. */ void SequencerEvent::setRaw32(const unsigned int n, const unsigned int value) { if (n < 3) m_event.data.raw32.d[n] = value; } /** * Gets an event's raw 8 bits parameter. * @param n The parameter index, between 0 and 11. * @return The parameter's value. * @see setRaw8() */ unsigned char SequencerEvent::getRaw8(const unsigned int n) const { if (n < 12) return m_event.data.raw8.d[n]; return 0; } /** * Sets an event's raw 8 bits parameter. * @param n The parameter index, between 0 and 11. * @param value The parameter's value. */ void SequencerEvent::setRaw8(const unsigned int n, const unsigned char value) { if (n < 12) m_event.data.raw8.d[n] = value; } /** * Releases the event record. * @deprecated the event record is not allocated, so you don't have to call this function */ void SequencerEvent::free() { snd_seq_free_event(&m_event); } /** * Gets the encoded length of the event record. * @return The encoded length. */ int SequencerEvent::getEncodedLength() { return snd_seq_event_length(&m_event); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ SequencerEvent* SequencerEvent::clone() const { return new SequencerEvent(&m_event); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ ChannelEvent* ChannelEvent::clone() const { return new ChannelEvent(&m_event); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ KeyEvent* KeyEvent::clone() const { return new KeyEvent(&m_event); } /** * Constructor using proper attribute values. * @param ch MIDI Channel. * @param key MIDI note. * @param vel Note velocity. * @param dur Note duration. */ NoteEvent::NoteEvent(int ch, int key, int vel, int dur) : KeyEvent() { snd_seq_ev_set_note(&m_event, ch, key, vel, dur); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ NoteEvent* NoteEvent::clone() const { return new NoteEvent(&m_event); } /** * Constructor using proper attribute values. * @param ch MIDI Channel. * @param key MIDI note. * @param vel Note velocity. */ NoteOnEvent::NoteOnEvent(int ch, int key, int vel) : KeyEvent() { snd_seq_ev_set_noteon(&m_event, ch, key, vel); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ NoteOnEvent* NoteOnEvent::clone() const { return new NoteOnEvent(&m_event); } /** * Constructor using proper attribute values. * @param ch MIDI Channel. * @param key MIDI note. * @param vel Note velocity. */ NoteOffEvent::NoteOffEvent(int ch, int key, int vel) : KeyEvent() { snd_seq_ev_set_noteoff(&m_event, ch, key, vel); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ NoteOffEvent* NoteOffEvent::clone() const { return new NoteOffEvent(&m_event); } /** * Constructor using proper attribute values. * @param ch MIDI Channel. * @param key MIDI note. * @param vel Note velocity. */ KeyPressEvent::KeyPressEvent(int ch, int key, int vel) : KeyEvent() { snd_seq_ev_set_keypress(&m_event, ch, key, vel); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ KeyPressEvent* KeyPressEvent::clone() const { return new KeyPressEvent(&m_event); } /** * Constructor using proper attribute values. * @param ch MIDI Channel. * @param cc MIDI Controller number. * @param val Controller value. */ ControllerEvent::ControllerEvent(int ch, int cc, int val) : ChannelEvent() { snd_seq_ev_set_controller(&m_event, ch, cc, val); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ ControllerEvent* ControllerEvent::clone() const { return new ControllerEvent(&m_event); } /** * Constructor using proper attribute values. * @param ch MIDI Channel. * @param val MIDI Program number. */ ProgramChangeEvent::ProgramChangeEvent(int ch, int val) : ChannelEvent() { snd_seq_ev_set_pgmchange(&m_event, ch, val); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ ProgramChangeEvent* ProgramChangeEvent::clone() const { return new ProgramChangeEvent(&m_event); } /** * Constructor using proper attribute values. * @param ch MIDI Channel. * @param val Pitch Bend value. Zero centered from -8192 to 8191. */ PitchBendEvent::PitchBendEvent(int ch, int val) : ChannelEvent() { snd_seq_ev_set_pitchbend(&m_event, ch, val); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ PitchBendEvent* PitchBendEvent::clone() const { return new PitchBendEvent(&m_event); } /** * Constructor using proper attribute values. * @param ch MIDI Channel. * @param val Aftertouch value. */ ChanPressEvent::ChanPressEvent(int ch, int val) : ChannelEvent() { snd_seq_ev_set_chanpress(&m_event, ch, val); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ ChanPressEvent* ChanPressEvent::clone() const { return new ChanPressEvent(&m_event); } /** * Default constructor. */ VariableEvent::VariableEvent() : SequencerEvent() { m_data.clear(); snd_seq_ev_set_variable ( &m_event, m_data.size(), m_data.data() ); } /** * Constructor from an ALSA event record. * @param event ALSA event record. */ VariableEvent::VariableEvent(const snd_seq_event_t* event) : SequencerEvent(event) { m_data = QByteArray((char *) event->data.ext.ptr, event->data.ext.len); snd_seq_ev_set_variable ( &m_event, m_data.size(), m_data.data() ); } /** * Constructor from an arbitrary data array. * @param data A data byte array. */ VariableEvent::VariableEvent(const QByteArray& data) : SequencerEvent() { m_data = data; snd_seq_ev_set_variable ( &m_event, m_data.size(), m_data.data() ); } /** * Copy constructor. * @param other Another VariableEvent instance. s */ VariableEvent::VariableEvent(const VariableEvent& other) : SequencerEvent(other) { m_data = other.m_data; snd_seq_ev_set_variable ( &m_event, m_data.size(), m_data.data() ); } /** * Constructor from a data pointer. * @param datalen Length of the data. * @param dataptr Pointer the data. */ VariableEvent::VariableEvent(const unsigned int datalen, char* dataptr) : SequencerEvent() { m_data = QByteArray(dataptr, datalen); snd_seq_ev_set_variable( &m_event, m_data.size(), m_data.data() ); } /** * Assignment operator. * @param other Another VariableEvent object reference * @return Pointer to this object */ VariableEvent& VariableEvent::operator=(const VariableEvent& other) { m_event = other.m_event; m_data = other.m_data; snd_seq_ev_set_variable ( &m_event, m_data.size(), m_data.data() ); return *this; } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ VariableEvent* VariableEvent::clone() const { return new VariableEvent(&m_event); } /** * Default constructor. */ SysExEvent::SysExEvent() : VariableEvent() { snd_seq_ev_set_sysex( &m_event, m_data.size(), m_data.data() ); } /** * Constructor from an ALSA event record. * @param event ALSA event record. */ SysExEvent::SysExEvent(const snd_seq_event_t* event) : VariableEvent(event) { snd_seq_ev_set_sysex( &m_event, m_data.size(), m_data.data() ); } /** * Constructor from a data array. * @param data A data byte array. */ SysExEvent::SysExEvent(const QByteArray& data) : VariableEvent(data) { snd_seq_ev_set_sysex( &m_event, m_data.size(), m_data.data() ); } /** * Copy constructor. * @param other Another SysExEvent object reference. */ SysExEvent::SysExEvent(const SysExEvent& other) : VariableEvent(other) { snd_seq_ev_set_sysex( &m_event, m_data.size(), m_data.data() ); } /** * Constructor taking a data pointer and length * @param datalen Data length * @param dataptr Data pointer */ SysExEvent::SysExEvent(const unsigned int datalen, char* dataptr) : VariableEvent( datalen, dataptr ) { snd_seq_ev_set_sysex( &m_event, m_data.size(), m_data.data() ); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ SysExEvent* SysExEvent::clone() const { return new SysExEvent(&m_event); } /** * Default constructor */ TextEvent::TextEvent() : VariableEvent(), m_textType(1) { setSequencerType(SND_SEQ_EVENT_USR_VAR0); } /** * Constructor from an ALSA sequencer record. * @param event ALSA sequencer record. */ TextEvent::TextEvent(const snd_seq_event_t* event) : VariableEvent(event), m_textType(1) { setSequencerType(SND_SEQ_EVENT_USR_VAR0); } /** * Constructor from a given string * @param text The event's text * @param textType The SMF text type */ TextEvent::TextEvent(const QString& text, const int textType) : VariableEvent(text.toUtf8()), m_textType(textType) { setSequencerType(SND_SEQ_EVENT_USR_VAR0); } /** * Copy constructor * @param other An existing TextEvent object reference */ TextEvent::TextEvent(const TextEvent& other) : VariableEvent(other) { setSequencerType(SND_SEQ_EVENT_USR_VAR0); m_textType = other.getTextType(); } /** * Constructor from a data pointer and length * @param datalen Data length * @param dataptr Data pointer */ TextEvent::TextEvent(const unsigned int datalen, char* dataptr) : VariableEvent(datalen, dataptr), m_textType(1) { setSequencerType(SND_SEQ_EVENT_USR_VAR0); } /** * Gets the event's text content. * @return The text content. */ QString TextEvent::getText() const { return QString::fromUtf8(m_data.data(), m_data.size()); } /** * Gets the event's SMF text type. * @return The SMF text type. */ int TextEvent::getTextType() const { return m_textType; } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ TextEvent* TextEvent::clone() const { return new TextEvent(&m_event); } /** * Constructor * @param type The event's type */ SystemEvent::SystemEvent(const snd_seq_event_type_t type) : SequencerEvent() { snd_seq_ev_set_fixed(&m_event); setSequencerType(type); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ SystemEvent* SystemEvent::clone() const { return new SystemEvent(&m_event); } /** * Constructor * @param type Event type * @param queue Queue number * @param value Value */ QueueControlEvent::QueueControlEvent(snd_seq_event_type_t type, int queue, int value) : SequencerEvent() { snd_seq_ev_set_queue_control(&m_event, type, queue, value); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ QueueControlEvent* QueueControlEvent::clone() const { return new QueueControlEvent(&m_event); } /** * Constructor * @param type The event's type * @param val Value */ ValueEvent::ValueEvent(const snd_seq_event_type_t type, int val) : SequencerEvent() { snd_seq_ev_set_fixed(&m_event); setSequencerType(type); setValue(val); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ ValueEvent* ValueEvent::clone() const { return new ValueEvent(&m_event); } /** * Constructor * @param queue Queue number. * @param tempo Tempo value in microseconds per quarter note. */ TempoEvent::TempoEvent(int queue, int tempo) : QueueControlEvent() { snd_seq_ev_set_queue_tempo(&m_event, queue, tempo); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ TempoEvent* TempoEvent::clone() const { return new TempoEvent(&m_event); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ ClientEvent* ClientEvent::clone() const { return new ClientEvent(&m_event); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ PortEvent* PortEvent::clone() const { return new PortEvent(&m_event); } /** * Clone this object returning a pointer to the new object * @return pointer to the new object */ SubscriptionEvent* SubscriptionEvent::clone() const { return new SubscriptionEvent(&m_event); } /** * Default constructor. */ RemoveEvents::RemoveEvents() { snd_seq_remove_events_malloc(&m_Info); } /** * Copy constructor. * @param other An existing RemoveEvents object reference. */ RemoveEvents::RemoveEvents(const RemoveEvents& other) { snd_seq_remove_events_malloc(&m_Info); snd_seq_remove_events_copy(m_Info, other.m_Info); } /** * Constructor from an ALSA remove events object pointer. * @param other An ALSA remove events object pointer. */ RemoveEvents::RemoveEvents(snd_seq_remove_events_t* other) { snd_seq_remove_events_malloc(&m_Info); snd_seq_remove_events_copy(m_Info, other); } /** * Destructor. */ RemoveEvents::~RemoveEvents() { snd_seq_remove_events_free(m_Info); } /** * Create a new object copied from this object and return a pointer to the copy. * @return A pointer to the new object. */ RemoveEvents* RemoveEvents::clone() { return new RemoveEvents(m_Info); } /** * Assignment operator. * @param other An existing RemoveEvents object reference. * @return This object. */ RemoveEvents& RemoveEvents::operator=(const RemoveEvents& other) { if (this == &other) return *this; snd_seq_remove_events_copy(m_Info, other.m_Info); return *this; } /** * Gets the allocated size of the ALSA remove events object. * @return The size of the ALSA remove events object. */ int RemoveEvents::getSizeOfInfo() const { return snd_seq_remove_events_sizeof(); } /** * Gets the MIDI channel. * @return The MIDI channel. * @see setChannel() */ int RemoveEvents::getChannel() { return snd_seq_remove_events_get_channel(m_Info); } /** * Gets the condition. * @return The condition. * @see setCondition() */ unsigned int RemoveEvents::getCondition() { return snd_seq_remove_events_get_condition(m_Info); } /** * Gets the destination. * @return The destination record pointer. * @see setDest() */ const snd_seq_addr_t* RemoveEvents::getDest() { return snd_seq_remove_events_get_dest(m_Info); } /** * Gets the event type. * @return The event type. * @see setEventType() */ int RemoveEvents::getEventType() { return snd_seq_remove_events_get_event_type(m_Info); } /** * Gets the queue number. * @return The queue number. * @see setQueue() */ int RemoveEvents::getQueue() { return snd_seq_remove_events_get_queue(m_Info); } /** * Gets the numeric tag. * @return The numeric tag. * @see setTag() */ int RemoveEvents::getTag() { return snd_seq_remove_events_get_tag(m_Info); } /** * Gets the timestamp. * @return The timestamp. * @see setTime() */ const snd_seq_timestamp_t* RemoveEvents::getTime() { return snd_seq_remove_events_get_time(m_Info); } /** * Gets the MIDI channel. * @param chan The MIDI channel. * @see getChannel() */ void RemoveEvents::setChannel(int chan) { snd_seq_remove_events_set_channel(m_Info, chan); } /** * Sets the flags of the conditional event's removal. This condition is a * bitmap of the combination (OR) the following auto-described flags: *
    *
  • SND_SEQ_REMOVE_INPUT
  • *
  • SND_SEQ_REMOVE_OUTPUT
  • *
  • SND_SEQ_REMOVE_DEST
  • *
  • SND_SEQ_REMOVE_DEST_CHANNEL
  • *
  • SND_SEQ_REMOVE_TIME_BEFORE
  • *
  • SND_SEQ_REMOVE_TIME_AFTER
  • *
  • SND_SEQ_REMOVE_TIME_TICK
  • *
  • SND_SEQ_REMOVE_EVENT_TYPE
  • *
  • SND_SEQ_REMOVE_IGNORE_OFF
  • *
  • SND_SEQ_REMOVE_TAG_MATCH
  • *
* @param cond The condition bitmap. * @see getCondition() */ void RemoveEvents::setCondition(unsigned int cond) { snd_seq_remove_events_set_condition(m_Info, cond); } /** * Set the destination address. * @param dest A pointer to the destination address record. * @see getDest() */ void RemoveEvents::setDest(const snd_seq_addr_t* dest) { snd_seq_remove_events_set_dest(m_Info, dest); } /** * Sets the event type. * @param type The event type. * @see getEventType() */ void RemoveEvents::setEventType(int type) { snd_seq_remove_events_set_event_type(m_Info, type); } /** * Sets the queue number. * @param queue The queue number. * @see getQueue() */ void RemoveEvents::setQueue(int queue) { snd_seq_remove_events_set_queue(m_Info, queue); } /** * Sets the numeric tag. * @param tag The numeric tag. * @see getTag() */ void RemoveEvents::setTag(int tag) { snd_seq_remove_events_set_tag(m_Info, tag); } /** * Sets the timestamp. * @param time A pointer to the timestamp record. * @see getTime() */ void RemoveEvents::setTime(const snd_seq_timestamp_t* time) { snd_seq_remove_events_set_time(m_Info, time); } /** * MidiCodec constructor * @param bufsize The buffer size of the CODEC * @param parent The optional parent object */ MidiCodec::MidiCodec( int bufsize, QObject* parent ) : QObject(parent) { DRUMSTICK_ALSA_CHECK_ERROR(snd_midi_event_new(bufsize, &m_Info)); } /** * Destructor */ MidiCodec::~MidiCodec() { snd_midi_event_free(m_Info); } /** * CODEC initialization. */ void MidiCodec::init() { snd_midi_event_init(m_Info); } /** * Decode from event to bytes. * @param buf A buffer to get the results * @param count Available bytes in MIDI byte stream * @param ev The input event * @return The number of written bytes if success. */ long MidiCodec::decode(unsigned char *buf, long count, const snd_seq_event_t *ev) { return DRUMSTICK_ALSA_CHECK_WARNING(snd_midi_event_decode(m_Info, buf, count, ev)); } /** * Encode from byte stream. * @param buf MIDI byte stream * @param count Bytes of MIDI byte stream to encode * @param ev Result - sequencer event * @return Number of written bytes if success. */ long MidiCodec::encode(const unsigned char *buf, long count, snd_seq_event_t *ev) { return DRUMSTICK_ALSA_CHECK_WARNING(snd_midi_event_encode(m_Info, buf, count, ev)); } /** * Read one byte and encode to sequencer event if finished. * @param c A byte of MIDI stream * @param ev Result - sequencer event * @return 1 - sequencer event is completed, 0 - next byte is required for completion, otherwise a negative error code */ long MidiCodec::encode(int c, snd_seq_event_t *ev) { return DRUMSTICK_ALSA_CHECK_WARNING(snd_midi_event_encode_byte(m_Info, c, ev)); } /** * Enable MIDI running status (command merge) * @param enable True to enable, false to disable. */ void MidiCodec::enableRunningStatus(bool enable) { snd_midi_event_no_status(m_Info, enable ? 0 : 1); } /** * Reset MIDI decode parser. */ void MidiCodec::resetDecoder() { snd_midi_event_reset_decode(m_Info); } /** * Reset MIDI encode parser. */ void MidiCodec::resetEncoder() { snd_midi_event_reset_encode(m_Info); } /** * Resize the CODEC buffer * @param bufsize New buffer size. */ void MidiCodec::resizeBuffer(int bufsize) { DRUMSTICK_ALSA_CHECK_WARNING(snd_midi_event_resize_buffer(m_Info, bufsize)); } } // namespace ALSA } // namespace drumstick drumstick-2.5.1/library/alsa/PaxHeaders.27918/alsatimer.cpp0000644000000000000000000000013214200302440020331 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/alsa/alsatimer.cpp0000644000175000001440000007351514200302440021125 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "errorcheck.h" #include #include #include #include #include /** * @file alsatimer.cpp * Implementation of classes managing ALSA Timers */ namespace drumstick { namespace ALSA { /** * @addtogroup ALSATimer * @{ * * Timers provide periodic time events to applications, and also to the ALSA * sequencer. * * There are two mechanisms to deliver the timer events. To use the callback * mechanism, a class must be derived from TimerEventHandler, and a instance * of the derived class must be assigned to the Timer instance using * Timer::setHandler(). If the handler is not assigned, then the Timer instance * will generate the signal Timer::timerExpired(). * * Classes: * * TimerInfo: ALSA Timer information container. * * This class is used to hold properties about ALSA Timers. * * TimerId: ALSA Timer identifier container. * * This class provides an unique identifier for a Timer. * * TimerGlobalInfo: Global timer information container. * * This class provides global timer parameters. * * TimerQuery: ALSA Timer inquiry helper. * * This class provides a mechanism to enumerate the available system timers. * * TimerParams: ALSA Timer parameters container. * * This class provides several parameters about a Timer. * * TimerStatus: ALSA Timer status container. * * This class provides some status information about a Timer. * * TimerEventHandler: ALSA Timer events handler. * * This abstract class is used to define an interface that other class can * implement to receive timer events. * * Timer: ALSA Timer management. * * This class represents an ALSA timer object. * * @see https://www.alsa-project.org/alsa-doc/alsa-lib/group___timer.html * @} */ /** * Constructor */ TimerInfo::TimerInfo() { snd_timer_info_malloc(&m_Info); } /** * Cosntructor * @param other ALSA timer info object pointer */ TimerInfo::TimerInfo(const snd_timer_info_t *other) { snd_timer_info_malloc(&m_Info); snd_timer_info_copy(m_Info, other); } /** * Copy constructor * @param other Existing TimerInfo object reference */ TimerInfo::TimerInfo(const TimerInfo& other) { snd_timer_info_malloc(&m_Info); snd_timer_info_copy(m_Info, other.m_Info); } /** * Destructor */ TimerInfo::~TimerInfo() { snd_timer_info_free(m_Info); } /** * Copy the current object * @return Pointer to the new object */ TimerInfo* TimerInfo::clone() { return new TimerInfo(m_Info); } /** * Assignment operator * @param other Existing TimerInfo object reference * @return a reference of this object */ TimerInfo& TimerInfo::operator=(const TimerInfo& other) { if (this == &other) return *this; snd_timer_info_copy(m_Info, other.m_Info); return *this; } /** * Check if the timer is slave (depends on another device) * @return True if the timer is slave */ bool TimerInfo::isSlave() { return (snd_timer_info_is_slave(m_Info) != 0); } /** * Gets the card number * @return Card number */ int TimerInfo::getCard() { return snd_timer_info_get_card(m_Info); } /** * Gets the string identifier * @return String identifier */ QString TimerInfo::getId() { return QString(snd_timer_info_get_id(m_Info)); } /** * Gets the timer name * @return Timer name */ QString TimerInfo::getName() { return QString(snd_timer_info_get_name(m_Info)); } /** * Gets the timer resolution (timer period in nanoseconds) * @return Timer resolution in nanos */ long TimerInfo::getResolution() { return snd_timer_info_get_resolution(m_Info); } /** * Gets the timer frequency in Hz * @return Timer frequency in Hz */ long TimerInfo::getFrequency() { long res = getResolution(); if (res > 0) { return 1000000000L / res; } return 0; } /** * Gets the size of the ALSA timer info object * @return Size of the ALSA object */ int TimerInfo::getSizeOfInfo() const { return snd_timer_info_sizeof(); } /** * Gets the maximum timer ticks * @return Maximum timer ticks * @deprecated */ long TimerInfo::getTicks() { return snd_timer_info_get_ticks(m_Info); } /** * Constructor */ TimerId::TimerId() { snd_timer_id_malloc(&m_Info); } /** * Constructor * @param other ALSA timer ID object pointer */ TimerId::TimerId(const snd_timer_id_t *other) { snd_timer_id_malloc(&m_Info); snd_timer_id_copy(m_Info, other); if (getCard() < 0) setCard(0); if (getDevice() < 0) setDevice(0); if (getSubdevice() < 0) setSubdevice(0); } /** * Copy constructor * @param other Existing TimerId object reference */ TimerId::TimerId(const TimerId& other) { snd_timer_id_malloc(&m_Info); snd_timer_id_copy(m_Info, other.m_Info); if (getCard() < 0) setCard(0); if (getDevice() < 0) setDevice(0); if (getSubdevice() < 0) setSubdevice(0); } /** * Constructor * @param cls Class * @param scls Subclass * @param card Card * @param dev Device * @param sdev Subdevice */ TimerId::TimerId(int cls, int scls, int card, int dev, int sdev) { snd_timer_id_malloc(&m_Info); setClass(cls); setSlaveClass(scls); setCard(card); setDevice(dev); setSubdevice(sdev); } /** * Destructor */ TimerId::~TimerId() { snd_timer_id_free(m_Info); } /** * Copy the object * @return Pointer to the new object */ TimerId* TimerId::clone() { return new TimerId(m_Info); } /** * Assignment operator * @param other Existing TimerId object reference * @return This object */ TimerId& TimerId::operator=(const TimerId& other) { if (this == &other) return *this; snd_timer_id_copy(m_Info, other.m_Info); if (getCard() < 0) setCard(0); if (getDevice() < 0) setDevice(0); if (getSubdevice() < 0) setSubdevice(0); return *this; } /** * Set the class identifier. Existing classes: *
    *
  • SND_TIMER_CLASS_SLAVE: slave timer
  • *
  • SND_TIMER_CLASS_GLOBAL: global timer
  • *
  • SND_TIMER_CLASS_CARD: card timer
  • *
  • SND_TIMER_CLASS_PCM: PCM timer
  • *
* @param devclass Class identifier. */ void TimerId::setClass(int devclass) { snd_timer_id_set_class(m_Info, devclass); } /** * Gets the class identifier. * @return Class identifier * @see setClass() */ int TimerId::getClass() { return snd_timer_id_get_class(m_Info); } /** * Sets the Slave class * @param devsclass Slave class */ void TimerId::setSlaveClass(int devsclass) { snd_timer_id_set_sclass(m_Info, devsclass); } /** * Gets the slave class * @return Slave class */ int TimerId::getSlaveClass() { return snd_timer_id_get_sclass(m_Info); } /** * Sets the card number * @param card Card number */ void TimerId::setCard(int card) { snd_timer_id_set_card(m_Info, card); } /** * Gets the card number * @return Card number */ int TimerId::getCard() { return snd_timer_id_get_card(m_Info); } /** * Sets the device number * @param device Device number */ void TimerId::setDevice(int device) { snd_timer_id_set_device(m_Info, device); } /** * Gets the device number * @return Device number */ int TimerId::getDevice() { return snd_timer_id_get_device(m_Info); } /** * Sets the subdevice number * @param subdevice Subdevice number */ void TimerId::setSubdevice(int subdevice) { snd_timer_id_set_subdevice (m_Info, subdevice); } /** * Gets the subdevice number * @return Subdevice number */ int TimerId::getSubdevice() { return snd_timer_id_get_subdevice(m_Info); } /** * Gets the size of the ALSA timer ID object * @return Size of the ALSA object */ int TimerId::getSizeOfInfo() const { return snd_timer_id_sizeof(); } /** * Constructor * @param deviceName Device name, usually "hw" * @param openMode Open mode (unknown values) */ TimerQuery::TimerQuery(const QString& deviceName, int openMode) { DRUMSTICK_ALSA_CHECK_WARNING( snd_timer_query_open( &m_Info, deviceName.toLocal8Bit().data(), openMode )); readTimers(); } /** * Constructor * @param deviceName Device name, usually "hw" * @param openMode Open mode (unknown values) * @param conf ALSA configuration object pointer */ TimerQuery::TimerQuery( const QString& deviceName, int openMode, snd_config_t* conf ) { DRUMSTICK_ALSA_CHECK_WARNING( snd_timer_query_open_lconf( &m_Info, deviceName.toLocal8Bit().data(), openMode, conf )); readTimers(); } /** * Destructor */ TimerQuery::~TimerQuery() { freeTimers(); snd_timer_query_close(m_Info); } /** * Enumerate the available timers storing the results into an internal list */ void TimerQuery::readTimers() { TimerId tid; snd_timer_id_set_class(tid.m_Info, SND_TIMER_CLASS_NONE); for(;;) { int rc = snd_timer_query_next_device(m_Info, tid.m_Info); if ((rc < 0) || (tid.getClass() < 0)) { break; } m_timers.append(tid); } } /** * Release the internal list of timers */ void TimerQuery::freeTimers() { m_timers.clear(); } /** * Get a TimerGlobalInfo object * @return TimerGlobalInfo object reference */ TimerGlobalInfo& TimerQuery::getGlobalInfo() { snd_timer_query_info(m_Info, m_GlobalInfo.m_Info); return m_GlobalInfo; } /** * Sets the global parameters * @param params Pointer to an ALSA timer global parameters object */ void TimerQuery::setGlobalParams(snd_timer_gparams_t* params) { snd_timer_query_params(m_Info, params); } /** * Gets the global timer parameters * @param params Pointer to an ALSA timer global parameters object */ void TimerQuery::getGlobalParams(snd_timer_gparams_t* params) { snd_timer_query_params(m_Info, params); } /** * Gets the global timer status * @param status Pointer to an ALSA timer global status object */ void TimerQuery::getGlobalStatus(snd_timer_gstatus_t *status) { snd_timer_query_status(m_Info, status); } /** * Default constructor */ TimerGlobalInfo::TimerGlobalInfo() { snd_timer_ginfo_malloc(&m_Info); } /** * Constructor * @param other ALSA global info object pointer */ TimerGlobalInfo::TimerGlobalInfo(const snd_timer_ginfo_t* other) { snd_timer_ginfo_malloc(&m_Info); snd_timer_ginfo_copy(m_Info, other); } /** * Copy constructor * @param other Existing TimerGlobalInfo object reference */ TimerGlobalInfo::TimerGlobalInfo(const TimerGlobalInfo& other) { snd_timer_ginfo_malloc(&m_Info); snd_timer_ginfo_copy(m_Info, other.m_Info); } /** * Destructor */ TimerGlobalInfo::~TimerGlobalInfo() { snd_timer_ginfo_free(m_Info); } /** * Copy the current object * @return Pointer to the new object */ TimerGlobalInfo* TimerGlobalInfo::clone() { return new TimerGlobalInfo(m_Info); } /** * Assignment operator * @param other Existing TimerGlobalInfo object reference * @return This object */ TimerGlobalInfo& TimerGlobalInfo::operator=(const TimerGlobalInfo& other) { if (this == &other) return *this; snd_timer_ginfo_copy(m_Info, other.m_Info); return *this; } /** * Sets the timer identifier * @param tid TimerId object reference */ void TimerGlobalInfo::setTimerId(const TimerId& tid) { m_Id = tid; snd_timer_ginfo_set_tid (m_Info, m_Id.m_Info); } /** * Gets the timer identifier * @return TimerId object reference */ TimerId& TimerGlobalInfo::getTimerId() { m_Id = TimerId(snd_timer_ginfo_get_tid (m_Info)); return m_Id; } /** * Gets the flags * @return Undocumented flags */ unsigned int TimerGlobalInfo::getFlags() { return snd_timer_ginfo_get_flags (m_Info); } /** * Gets the card number * @return Card number */ int TimerGlobalInfo::getCard() { return snd_timer_ginfo_get_card (m_Info); } /** * Gets the timer ID string * @return Timer ID string */ QString TimerGlobalInfo::getId() { return QString(snd_timer_ginfo_get_id (m_Info)); } /** * Gets the timer name * @return Timer name */ QString TimerGlobalInfo::getName() { return QString(snd_timer_ginfo_get_name (m_Info)); } /** * Gets the timer resolution in ns * @return Timer resolution in ns */ unsigned long TimerGlobalInfo::getResolution() { return snd_timer_ginfo_get_resolution (m_Info); } /** * Gets timer minimal resolution in ns * @return Minimal resolution in ns */ unsigned long TimerGlobalInfo::getMinResolution() { return snd_timer_ginfo_get_resolution_min (m_Info); } /** * Gets timer maximal resolution in ns * @return Maximal resolution in ns */ unsigned long TimerGlobalInfo::getMaxResolution() { return snd_timer_ginfo_get_resolution_max(m_Info); } /** * Gets current timer clients * @return Current clients */ unsigned int TimerGlobalInfo::getClients() { return snd_timer_ginfo_get_clients(m_Info); } /** * Gets the size of the ALSA timer global info object * @return Size of the ALSA object */ int TimerGlobalInfo::getSizeOfInfo() const { return snd_timer_ginfo_sizeof(); } /** * Default constructor */ TimerParams::TimerParams() { snd_timer_params_malloc (&m_Info); } /** * Constructor * @param other Pointer to an ALSA timer parameters object */ TimerParams::TimerParams(const snd_timer_params_t *other) { snd_timer_params_malloc (&m_Info); snd_timer_params_copy (m_Info, other); } /** * Copy constructor * @param other Existing TimerParams object reference */ TimerParams::TimerParams(const TimerParams& other) { snd_timer_params_malloc (&m_Info); snd_timer_params_copy (m_Info, other.m_Info); } /** * Destructor * @return */ TimerParams::~TimerParams() { snd_timer_params_free (m_Info); } /** * Copy the current object * @return Pointer to the new object */ TimerParams* TimerParams::clone() { return new TimerParams(m_Info); } /** * Assignment operator * @param other Existing TimerParams object reference * @return This object */ TimerParams& TimerParams::operator=(const TimerParams& other) { if (this == &other) return *this; snd_timer_params_copy (m_Info, other.m_Info); return *this; } /** * Sets the automatic start flag * @param auto_start Value for the automatic start flag */ void TimerParams::setAutoStart(bool auto_start) { snd_timer_params_set_auto_start (m_Info, auto_start ? 1 : 0); } /** * Gets the automatic start flag * @return True if the timer starts automatically */ bool TimerParams::getAutoStart() { return (snd_timer_params_get_auto_start (m_Info) != 0); } /** * Sets the exclusive flag * @param exclusive True if the timer has the exclusive flag */ void TimerParams::setExclusive(bool exclusive) { snd_timer_params_set_exclusive (m_Info, exclusive ? 1 : 0); } /** * Gets the timer's exclusive flag * @return True if the timer has the exclusive flag */ bool TimerParams::getExclusive() { return (snd_timer_params_get_exclusive (m_Info) != 0); } /** * Sets the timer early event * @param early_event Timer early event */ void TimerParams::setEarlyEvent(bool early_event) { snd_timer_params_set_early_event (m_Info, early_event ? 1 : 0); } /** * Gets the timer early event * @return Timer early event */ bool TimerParams::getEarlyEvent() { return (snd_timer_params_get_early_event (m_Info) != 0); } /** * Sets the timer ticks * @param ticks Timer ticks */ void TimerParams::setTicks(long ticks) { snd_timer_params_set_ticks (m_Info, ticks); } /** * Gets the timer ticks * @return Timer ticks */ long TimerParams::getTicks() { return snd_timer_params_get_ticks (m_Info); } /** * Sets the queue size (32-1024) * @param queue_size Queue size */ void TimerParams::setQueueSize(long queue_size) { snd_timer_params_set_queue_size (m_Info, queue_size); } /** * Gets the queue size * @return Queue size */ long TimerParams::getQueueSize() { return snd_timer_params_get_queue_size (m_Info); } /** * Sets the event filter * @param filter Event filter */ void TimerParams::setFilter(unsigned int filter) { snd_timer_params_set_filter (m_Info, filter); } /** * Gets the event filter * @return Event filter */ unsigned int TimerParams::getFilter() { return snd_timer_params_get_filter (m_Info); } /** * Gets the size of the ALSA timer parameters object * @return Size of the ALSA object */ int TimerParams::getSizeOfInfo() const { return snd_timer_params_sizeof(); } /** * Default constructor */ TimerStatus::TimerStatus() { snd_timer_status_malloc (&m_Info); } /** * Constructor * @param other Pointer to an existing ALSA timer status object */ TimerStatus::TimerStatus(const snd_timer_status_t *other) { snd_timer_status_malloc (&m_Info); snd_timer_status_copy (m_Info, other); } /** * Copy constructor * @param other Existing TimerStatus object reference */ TimerStatus::TimerStatus(const TimerStatus& other) { snd_timer_status_malloc (&m_Info); snd_timer_status_copy (m_Info, other.m_Info); } /** * Destructor */ TimerStatus::~TimerStatus() { snd_timer_status_free (m_Info); } /** * Copy the current object * @return Pointer to the new object */ TimerStatus* TimerStatus::clone() { return new TimerStatus(m_Info); } /** * Assignment operator * @param other Existing TimerStatus object reference * @return This object */ TimerStatus& TimerStatus::operator=(const TimerStatus& other) { if (this == &other) return *this; snd_timer_status_copy (m_Info, other.m_Info); return *this; } /** * Gets the high resolution time-stamp * @return High resolution time-stamp */ snd_htimestamp_t TimerStatus::getTimestamp() { return snd_timer_status_get_timestamp (m_Info); } /** * Gets the resolution in us * @return Resolution in us */ long TimerStatus::getResolution() { return snd_timer_status_get_resolution (m_Info); } /** * Gets the master tick lost count * @return Master tick lost count */ long TimerStatus::getLost() { return snd_timer_status_get_lost (m_Info); } /** * Gets the overrun count * @return Overrun count */ long TimerStatus::getOverrun() { return snd_timer_status_get_overrun (m_Info); } /** * Gets the count of used queue elements * @return Count of used queue elements */ long TimerStatus::getQueue() { return snd_timer_status_get_queue (m_Info); } /** * Gets the size of the ALSA timer status object * @return Size of the ALSA object */ int TimerStatus::getSizeOfInfo() const { return snd_timer_status_sizeof(); } /** * Constructor. * Open flags can be a combination of the following constants: *
    *
  • SND_TIMER_OPEN_NONBLOCK: non-blocking behavior
  • *
  • SND_TIMER_OPEN_TREAD: enhanced read, use time-stamps and event notification
  • *
* @param deviceName Name of the device * @param openMode Open mode flags bitmap * @param parent Optional parent object */ Timer::Timer( const QString& deviceName, int openMode, QObject* parent ) : QObject(parent), m_asyncHandler(nullptr), m_handler(nullptr), m_thread(nullptr), m_deviceName(deviceName) { DRUMSTICK_ALSA_CHECK_ERROR( snd_timer_open( &m_Info, m_deviceName.toLocal8Bit().data(), openMode )); } /** * Constructor. * Open flags can be a combination of the following constants: *
    *
  • SND_TIMER_OPEN_NONBLOCK: non-blocking behavior
  • *
  • SND_TIMER_OPEN_TREAD: enhanced read, use time-stamps and event notification
  • *
* @param deviceName Name of the device * @param openMode Open mode flags bitmap * @param conf ALSA configuration object pointer * @param parent Optional parent object */ Timer::Timer( const QString& deviceName, int openMode, snd_config_t* conf, QObject* parent ) : QObject(parent), m_asyncHandler(nullptr), m_handler(nullptr), m_thread(nullptr), m_deviceName(deviceName) { DRUMSTICK_ALSA_CHECK_ERROR( snd_timer_open_lconf( &m_Info, m_deviceName.toLocal8Bit().data(), openMode, conf )); } /** * Constructor * Open flags can be a combination of the following constants: *
    *
  • SND_TIMER_OPEN_NONBLOCK: non-blocking behavior
  • *
  • SND_TIMER_OPEN_TREAD: enhanced read, use time-stamps and event notification
  • *
* @param id TimerId object reference * @param openMode Open mode flags bitmap * @param parent Optional parent object */ Timer::Timer( TimerId& id, int openMode, QObject* parent ) : QObject(parent), m_asyncHandler(nullptr), m_handler(nullptr), m_thread(nullptr) { m_deviceName = QString("hw:CLASS=%1,SCLASS=%2,CARD=%3,DEV=%4,SUBDEV=%5") .arg(id.getClass()) .arg(id.getSlaveClass()) .arg(id.getCard()) .arg(id.getDevice()) .arg(id.getSubdevice()); DRUMSTICK_ALSA_CHECK_ERROR( snd_timer_open( &m_Info, m_deviceName.toLocal8Bit().data(), openMode )); } /** * Constructor. * Open flags can be a combination of the following constants: *
    *
  • SND_TIMER_OPEN_NONBLOCK: non-blocking behavior
  • *
  • SND_TIMER_OPEN_TREAD: enhanced read, use time-stamps and event notification
  • *
* @param cls Class * @param scls Subclass * @param card Card * @param dev Device * @param sdev Subdevice * @param openMode Open mode flags bitmap * @param parent Optional parent object */ Timer::Timer( int cls, int scls, int card, int dev, int sdev, int openMode, QObject* parent ) : QObject(parent), m_asyncHandler(nullptr), m_handler(nullptr), m_thread(nullptr) { m_deviceName = QString("hw:CLASS=%1,SCLASS=%2,CARD=%3,DEV=%4,SUBDEV=%5") .arg(cls) .arg(scls) .arg(card) .arg(dev) .arg(sdev); DRUMSTICK_ALSA_CHECK_ERROR( snd_timer_open( &m_Info, m_deviceName.toLocal8Bit().data(), openMode )); } /** * Destructor. */ Timer::~Timer() { stopEvents(); if (m_thread != nullptr) delete m_thread; DRUMSTICK_ALSA_CHECK_WARNING(snd_timer_close(m_Info)); } /** * Adds an asynchronous timer handler function. * @param callback Function handler * @param private_data Any data that will be passed to the callback */ void Timer::addAsyncTimerHandler(snd_async_callback_t callback, void *private_data) { DRUMSTICK_ALSA_CHECK_WARNING(snd_async_add_timer_handler(&m_asyncHandler, m_Info, callback, private_data)); } /** * Gets the ALSA timer handle * @return ALSA timer handle */ snd_timer_t* Timer::getTimerHandle() { return snd_async_handler_get_timer(m_asyncHandler); } /** * Gets the count of poll descriptors * @return Count of poll descriptors */ int Timer::getPollDescriptorsCount() { return snd_timer_poll_descriptors_count(m_Info); } /** * Gets poll descriptors * @param pfds Pointer to a pollfd array * @param space Number of pollfd elements available */ void Timer::pollDescriptors(struct pollfd *pfds, unsigned int space) { DRUMSTICK_ALSA_CHECK_WARNING(snd_timer_poll_descriptors(m_Info, pfds, space)); } /** * Gets returned events from poll descriptors * @param pfds Pointer to a pollfd array * @param nfds Number of pollfd elements available * @param revents Returned events */ void Timer::pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds, unsigned short *revents) { DRUMSTICK_ALSA_CHECK_WARNING(snd_timer_poll_descriptors_revents(m_Info, pfds, nfds, revents)); } /** * Gets the timer info object * @return TimerInfo object reference */ TimerInfo& Timer::getTimerInfo() { snd_timer_info (m_Info, m_TimerInfo.m_Info); return m_TimerInfo; } /** * Sets the timer parameters * @param params TimerParams object reference */ void Timer::setTimerParams(const TimerParams& params) { DRUMSTICK_ALSA_CHECK_WARNING( snd_timer_params(m_Info, params.m_Info) ); } /** * Gets the timer status * @return TimerStatus object reference */ TimerStatus& Timer::getTimerStatus() { DRUMSTICK_ALSA_CHECK_WARNING( snd_timer_status(m_Info, m_TimerStatus.m_Info) ); return m_TimerStatus; } /** * Start rolling the timer */ void Timer::start() { DRUMSTICK_ALSA_CHECK_WARNING(snd_timer_start(m_Info)); } /** * Stop rolling the timer */ void Timer::stop() { DRUMSTICK_ALSA_CHECK_WARNING(snd_timer_stop(m_Info)); } /** * Continue rolling the timer */ void Timer::continueRunning() { DRUMSTICK_ALSA_CHECK_WARNING(snd_timer_continue(m_Info)); } /** * Read bytes from the timer handle * @param buffer Buffer to store the input bytes * @param size Input buffer size in bytes * @return Bytes read from the timer */ ssize_t Timer::read(void *buffer, size_t size) { return snd_timer_read(m_Info, buffer, size); } /** * Internal function to deliver the timer events using one of the two available * methods: *
    *
  • TimerEventHandler instance pointer provided in Timer::setHandler()
  • *
  • A signal Timer::timerExpired() is emitted, otherwise
  • *
*/ void Timer::doEvents() { snd_timer_tread_t tr; while ( read(&tr, sizeof(tr)) == sizeof(tr) ) { int msecs = ((tr.tstamp.tv_sec - m_last_time.tv_sec) * 1000) + round((tr.tstamp.tv_nsec - m_last_time.tv_nsec) / 1000000.0); m_last_time = tr.tstamp; if ( m_handler != nullptr ) m_handler->handleTimerEvent(tr.val, msecs); else emit timerExpired(tr.val, msecs); } } /** * Starts the events dispatching thread */ void Timer::startEvents() { m_last_time = getTimerStatus().getTimestamp(); if (m_thread == nullptr) { m_thread = new TimerInputThread(this, 500); m_thread->start(); } } /** * Stops the events dispatching thread */ void Timer::stopEvents() { int counter = 0; if (m_thread != nullptr) { m_thread->stop(); while (!m_thread->wait(500) && (counter < 10)) { counter++; } if (!m_thread->isFinished()) { m_thread->terminate(); } delete m_thread; } } /** * Check and return the best available global TimerId in the system, meaning * the timer with higher frequency (or lesser period, resolution). * @return A TimerId object * @since 0.3.0 */ TimerId Timer::bestGlobalTimerId() { TimerId id; snd_timer_t* timer; snd_timer_info_t* info; long res, best_res = LONG_MAX; char timername[64]; int test_devs[] = { SND_TIMER_GLOBAL_SYSTEM , SND_TIMER_GLOBAL_RTC #ifdef SND_TIMER_GLOBAL_HPET , SND_TIMER_GLOBAL_HPET #endif #ifdef SND_TIMER_GLOBAL_HRTIMER , SND_TIMER_GLOBAL_HRTIMER #endif }; int max_global_timers = sizeof(test_devs)/sizeof(int); int clas = SND_TIMER_CLASS_GLOBAL; int scls = SND_TIMER_SCLASS_NONE; int card = 0; int dev = SND_TIMER_GLOBAL_SYSTEM; int sdev = 0; int err = 0; int is_slave = 0; int i; snd_timer_info_alloca(&info); // default system timer id.setClass(clas); id.setSlaveClass(scls); id.setCard(card); id.setDevice(dev); id.setSubdevice(sdev); // select a non slave timer with the lowest resolution value for( i = 0; i < max_global_timers; ++i ) { dev = test_devs[i]; sprintf( timername, "hw:CLASS=%i,SCLASS=%i,CARD=%i,DEV=%i,SUBDEV=%i", clas, scls, card, dev, sdev ); err = snd_timer_open(&timer, timername, SND_TIMER_OPEN_NONBLOCK); if (err < 0) continue; err = snd_timer_info(timer, info); if (err == 0) { is_slave = snd_timer_info_is_slave(info); res = snd_timer_info_get_resolution(info); if ((is_slave == 0) && (best_res > res)) { best_res = res; id.setDevice(dev); } } snd_timer_close(timer); } return id; } /** * Check and return the best available global Timer in the system, meaning * the timer with higher frequency (or lesser period, resolution). * @param openMode Open mode flags * @param parent Optional parent object * @return A new Timer instance pointer */ Timer* Timer::bestGlobalTimer(int openMode, QObject* parent) { TimerId id = bestGlobalTimerId(); return new Timer(id, openMode, parent); } /** * Loop reading and dispatching timer events. */ void Timer::TimerInputThread::run() { int err, count; struct pollfd *fds; if (m_timer == nullptr) return; count = m_timer->getPollDescriptorsCount(); fds = (pollfd *) calloc(count, sizeof(struct pollfd)); if (fds == nullptr) { qWarning() << "allocation error!"; return; } fds->events = POLLIN; fds->revents = 0; try { while (!stopped() && (m_timer != nullptr)) { m_timer->pollDescriptors(fds, count); if ((err = poll(fds, count, m_Wait)) < 0) { qWarning() << "poll error " << err << "(" << strerror(err) << ")"; free(fds); return; } if (err == 0) { qWarning() << "timer time out"; free(fds); return; } m_timer->doEvents(); } } catch (...) { qWarning() << "exception in input thread"; } free(fds); } /** * Returns the rolling state of the timer thread * @return The stopped state */ bool Timer::TimerInputThread::stopped() { QReadLocker locker(&m_mutex); return m_Stopped; } /** * Stop the thread */ void Timer::TimerInputThread::stop() { QWriteLocker locker(&m_mutex); m_Stopped = true; } } // namespace ALSA } // namespace drumstick drumstick-2.5.1/library/alsa/PaxHeaders.27918/errorcheck.h0000644000000000000000000000013214200302440020144 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/alsa/errorcheck.h0000644000175000001440000000450114200302440020725 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ERRORCHECK_H #define ERRORCHECK_H extern "C" { #include } #include #include #include /** * @file errorcheck.h * Error checking functions and macros */ namespace drumstick { namespace ALSA { /** * @addtogroup ALSAError * @{ */ /** * Checks the error code for severe errors. * If the provided error code is less than zero an exception is thrown, * containing both the error code and the location. * @param rc Error code * @param where Location * @return Error code */ inline int checkErrorAndThrow(int rc, const char *where) { if (rc < 0) { qDebug() << "Error code:" << rc << "(" << snd_strerror(rc) << ")"; qDebug() << "Location:" << where; throw SequencerError(QString(where), rc); } return rc; } /** * Check the error code for warning errors. * This method doesn't throw an exception. * @param rc Error code * @param where Location * @return Error code */ inline int checkWarning(int rc, const char *where) { if (rc < 0) { qWarning() << "Exception code:" << rc << "(" << snd_strerror(rc) << ")"; qWarning() << "Location:" << where; } return rc; } /** * This macro calls the check error function. * @param x Error code */ #define DRUMSTICK_ALSA_CHECK_ERROR(x) (checkErrorAndThrow((x),__PRETTY_FUNCTION__)) /** * This macro calls the check warning function. * @param x Error code */ #define DRUMSTICK_ALSA_CHECK_WARNING(x) (checkWarning((x),__PRETTY_FUNCTION__)) /** @} */ }} // namespace drumstick::ALSA #endif // ERRORCHECK_H drumstick-2.5.1/library/alsa/PaxHeaders.27918/alsaclient.cpp0000644000000000000000000000013214200302440020467 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/alsa/alsaclient.cpp0000644000175000001440000020172614200302440021260 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "errorcheck.h" #include #include #include #include #include #include #include #include #include #if defined(RTKIT_SUPPORT) #include #include #include #include #include #endif #include #ifndef RLIMIT_RTTIME #define RLIMIT_RTTIME 15 #endif #ifndef SCHED_RESET_ON_FORK #define SCHED_RESET_ON_FORK 0x40000000 #endif #ifndef DEFAULT_INPUT_TIMEOUT #define DEFAULT_INPUT_TIMEOUT 500 #endif /** * @file alsaclient.cpp * Implementation of classes managing ALSA Sequencer clients */ /** * @class QObject * The QObject class is the base class of all Qt objects. * @see https://doc.qt.io/qt-5/qobject.html */ /** * @class QThread * The QThread class provides platform-independent threads. * @see https://doc.qt.io/qt-5/qthread.html */ namespace drumstick { namespace ALSA { /** * @addtogroup ALSAClient * @{ * * ALSA clients are any entities using ALSA sequencer services. A client * may be an application or a device driver for an external MIDI port, like * USB MIDI devices or the MIDI/game ports of some sound cards. This library * allows to easily create applications managing ALSA clients. * * ALSA clients are also file descriptors representing a sequencer device, * that must be opened before reading or writing MIDI events. When the client * is opened, it is given some handle and a number identifying it to other * clients in the system. You can also provide a name for it. * * Each ALSA sequencer client can have several ports attached. The ports can be * readable or writable, and can be subscribed in pairs: one readable port to * one writable port. The subscriptions can be made and queried by external * applications, like "aconnect" or "qjackctl". * * SystemInfo is an auxiliary class to query several system capabilities. * * The PoolInfo class represents a container to query and change some values * for the kernel memory pool assigned to an ALSA client. * * The ClientInfo class is another container to query and change properties of * the MidiClient itself. * * The SequencerEventHandler abstract class is used to define an interface * that other class can implement to receive sequencer events. It is one of the * three methods of delivering input events offered by the library. * * @section EventInput Input * MidiClient uses a separate thread to receive events from the ALSA sequencer. * The input thread can be started and stopped using the methods * MidiClient::startSequencerInput() and MidiClient::stopSequencerInput(). * It is necessary to have this thread in mind when using this library to read * events. There are three delivering methods of input events: *
    *
  • A Callback method. To use this method, you must derive a class from * SequencerEventHandler, overriding the method * SequencerEventHandler::handleSequencerEvent() to provide your own event * processing code. You must give a handler instance pointer to * the client using MidiClient::setHandler().
  • *
  • Using QEvent listeners. To use this method, you must have one or more * classes derived from QObject overriding the method QObject::customEvent(). * You must also use the method MidiClient::addListener() to add such objects * to the client's listeners list, and MidiClient::setEventsEnabled().
  • *
  • The third method involves signals and slots. Whenever a sequencer event * is received, a signal MidiClient::eventReceived() is emitted, that can be * connected to your own supplied slot(s) to process it. *
* The selected method depends only on your requirements and your preferences. *
    *
  • The Callback method is preferred for real-time usage because the handler * receives the events without any delay, but at the same time you must * avoid calling methods of any GUI widgets within the handler. Instead, * you can create QEvents and call QObject::postEvent() to notify the GUI.
  • *
  • Inside QObject::eventReceiver() you can collect QEvents and call * any method you want, but the events are not delivered in real-time. Instead, * they are enqueued and dispatched by the main application's event loop.
  • *
  • The signals/slots method can be real-time or queued, depending on the * last parameter of QObject::connect(). If it is Qt::DirectConnection, the signal * is delivered in real-time, and the same rule about avoiding calls to any * GUI widgets methods apply. If it is Qt::QueuedConnection, then the signal is * enqueued using the application's event loop, and it is safe to call any GUI * methods in this case.
  • *
* Whichever method you select, it excludes the other methods for the same * program. A callback takes precedence over the others. If it is not set, then * the events are sent if MidiClient::setEventsEnabled() is called. * If neither a callback handler is set nor events are enabled, then the signal * is emitted. In any case, the event pointer must be deleted by the receiver * method. * * @see https://doc.qt.io/qt-5/threads-reentrancy.html * * @section EventOutput Output * * The methods to send a single event to the ALSA sequencer are: *
    *
  • MidiClient::output() using the library buffer, automatically flushed.
  • *
  • MidiClient::outputBuffer() using the library buffer. Not flushed automatically.
  • *
  • MidiClient::outputDirect() not using the library buffer.
  • *
* The two first methods usually require a call to MidiClient::drainOutput() to * flush the ALSA library output buffer. The third one bypasses the buffer, and * doesn't require the call to MidiClient::drainOutput(). Note that the buffer * can be automatically drained by the first method when it becomes full. * * After being dispatched to the ALSA Sequencer, the events can be scheduled at * some time in the future, or immediately. This depends on the following * methods of the SequencerEvent class: *
    *
  • SequencerEvent::setDirect() not scheduled
  • *
  • SequencerEvent::scheduleTick() scheduled in musical time (ticks)
  • *
  • SequencerEvent::scheduleReal() scheduled in clock time (seconds)
  • *
* * When you need to schedule a lot of events, for instance reproducing * a Standard MIDI File (SMF) or a MIDI sequence, you may want to use the * abstract class SequencerOutputThread. * * @section Memory * * There are two memory issues: the memory pool belongs to the kernel sequencer, * and can be managed by the class PoolInfo and the methods * MidiClient::getPoolInfo() and MidiClient::setPoolInfo(). The library buffer * can be controlled using the methods MidiClient::getOutputBufferSize() and * MidiClient::setOutputBufferSize() as well as MidiClient::getInputBufferSize() * and MidiClient::setInputBufferSize(). * * @see https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_client.html */ /** * This class manages event input from the ALSA sequencer. */ class MidiClient::SequencerInputThread: public QThread { public: SequencerInputThread(MidiClient *seq, int timeout) : QThread(), m_MidiClient(seq), m_Wait(timeout), m_Stopped(false), m_RealTime(true) {} virtual ~SequencerInputThread() = default; void run() override; bool stopped(); void stop(); void setRealtimePriority(); MidiClient *m_MidiClient; int m_Wait; bool m_Stopped; bool m_RealTime; QReadWriteLock m_mutex; }; class MidiClient::MidiClientPrivate { public: MidiClientPrivate() : m_eventsEnabled(false), m_BlockMode(false), m_NeedRefreshClientList(true), m_OpenMode(SND_SEQ_OPEN_DUPLEX), m_DeviceName("default"), m_SeqHandle(nullptr), m_Thread(nullptr), m_Queue(nullptr), m_handler(nullptr) { } bool m_eventsEnabled; bool m_BlockMode; bool m_NeedRefreshClientList; int m_OpenMode; QString m_DeviceName; snd_seq_t* m_SeqHandle; QPointer m_Thread; QPointer m_Queue; SequencerEventHandler* m_handler; ClientInfo m_Info; ClientInfoList m_ClientList; MidiPortList m_Ports; PortInfoList m_OutputsAvail; PortInfoList m_InputsAvail; QObjectList m_listeners; SystemInfo m_sysInfo; PoolInfo m_poolInfo; }; /** * Constructor. * * This constructor optionally gets a QObject parent. When you create a * MidiClient with another object as parent, the MidiClient object will * automatically add itself to the parent's children() list. The parent takes * ownership of the object i.e. it will automatically delete its children in * its destructor. * * It is necessary to invoke open() later to get the sequencer client handler * from the ALSA sequencer subsystem. * * @param parent The optional parent object * @return a MidiClient instance */ MidiClient::MidiClient( QObject* parent ) : QObject(parent), d(new MidiClientPrivate) { } /** * Destructor. * * The ports and queue associated to this client are automatically released. */ MidiClient::~MidiClient() { stopSequencerInput(); detachAllPorts(); delete d->m_Queue; close(); freeClients(); delete d->m_Thread; } /** * Returns the sequencer handler managed by ALSA * @return the sequencer handler */ snd_seq_t* MidiClient::getHandle() { return d->m_SeqHandle; } /** * Returns true if the sequencer is opened * @return wheter the sequencer is opened */ bool MidiClient::isOpened() { return !d.isNull() && (d->m_SeqHandle != nullptr); } /** * Returns the name of the sequencer device * @return the device name */ QString MidiClient::getDeviceName() { return d->m_DeviceName; } /** * Returns the last open mode used in open() * @return the last open mode */ int MidiClient::getOpenMode() { return d->m_OpenMode; } /** * Returns the last block mode used in open() * @return the last block mode */ bool MidiClient::getBlockMode() { return d->m_BlockMode; } /** * Returns true if the events mode of delivery has been enabled * @return whether the events mode of delivery is enabled */ bool MidiClient::getEventsEnabled() const { return d->m_eventsEnabled; } /** * Sets a sequencer event handler enabling the callback delivery mode * @param handler the sequencer event handler */ void MidiClient::setHandler(SequencerEventHandler* handler) { d->m_handler = handler; } /** * Enables real-time priority for the MIDI input thread. The system needs either * RLIMIT_RTPRIO or RealtimeKit. First RLIMIT_RTPRIO is tried, and if this * method fails, RealtimeKit is used. * * @param enable real-time priority enabled * @since 0.5.0 */ void MidiClient::setRealTimeInput(bool enable) { if (d->m_Thread == nullptr) { d->m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT); d->m_Thread->m_RealTime = enable; } } /** * Return the real-time priority setting for the MIDI input thread. * @return true if the real-time priority is enabled * @since 0.5.0 */ bool MidiClient::realTimeInputEnabled() { if (d->m_Thread == nullptr) return true; return d->m_Thread->m_RealTime; } /** * Open the sequencer device. * * When opening the MidiClient instance, several properties may optionally * be set as the device name, the open mode and block mode. Default values * are provided for them. After a successful open, an event with * SND_SEQ_EVENT_CLIENT_START is broadcast to the announce port. * * @param deviceName the sequencer device name, default value = "default". * This is not a name you make up for your own purposes; it has special * significance to the ALSA library. Usually you need to pass "default" here. * @param openMode the open mode, default value = SND_SEQ_OPEN_DUPLEX. * The read/write mode of the sequencer. Can be one of these three values: *
    *
  • SND_SEQ_OPEN_OUTPUT - open the sequencer for output only
  • *
  • SND_SEQ_OPEN_INPUT - open the sequencer for input only
  • *
  • SND_SEQ_OPEN_DUPLEX - open the sequencer for output and input
  • *
* @param blockMode open in blocking mode, default value = false. */ void MidiClient::open( const QString deviceName, const int openMode, const bool blockMode) { DRUMSTICK_ALSA_CHECK_ERROR( snd_seq_open( &d->m_SeqHandle, deviceName.toLocal8Bit().data(), openMode, blockMode ? 0 : SND_SEQ_NONBLOCK ) ); DRUMSTICK_ALSA_CHECK_WARNING( snd_seq_get_client_info( d->m_SeqHandle, d->m_Info.m_Info ) ); d->m_DeviceName = deviceName; d->m_OpenMode = openMode; d->m_BlockMode = blockMode; } /** * Open the sequencer device, providing a configuration object pointer. * * This method is like open() except that a configuration is explicitly * provided. After a successful open, an event with SND_SEQ_EVENT_CLIENT_START * type is broadcasted from the announce port. * * @param conf a configuration object pointer. * @param deviceName the sequencer device name, default value = "default". * This is not a name you make up for your own purposes; it has special * significance to the ALSA library. Usually you need to pass "default" here. * @param openMode the open mode, default value = SND_SEQ_OPEN_DUPLEX. * The read/write mode of the sequencer. Can be one of these three values: *
    *
  • SND_SEQ_OPEN_OUTPUT - open the sequencer for output only
  • *
  • SND_SEQ_OPEN_INPUT - open the sequencer for input only
  • *
  • SND_SEQ_OPEN_DUPLEX - open the sequencer for output and input
  • *
* @param blockMode open in blocking mode, default value = false. */ void MidiClient::open( snd_config_t* conf, const QString deviceName, const int openMode, const bool blockMode ) { DRUMSTICK_ALSA_CHECK_ERROR( snd_seq_open_lconf( &d->m_SeqHandle, deviceName.toLocal8Bit().data(), openMode, blockMode ? 0 : SND_SEQ_NONBLOCK, conf )); DRUMSTICK_ALSA_CHECK_WARNING( snd_seq_get_client_info(d->m_SeqHandle, d->m_Info.m_Info)); d->m_DeviceName = deviceName; d->m_OpenMode = openMode; d->m_BlockMode = blockMode; } /** * Close the sequencer device. * * After a client is closed, an event with SND_SEQ_EVENT_CLIENT_EXIT is * broadcast to the announce port. The connection between other clients are * disconnected. Call this just before exiting your program. */ void MidiClient::close() { if (d->m_SeqHandle != nullptr) { stopSequencerInput(); DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_close(d->m_SeqHandle)); d->m_SeqHandle = nullptr; } } /** * Gets the size of the library output buffer for the ALSA client. * * This buffer is used to store the decoded byte-stream of output events before * transferring to the sequencer. * * @return the size of the library output buffer */ size_t MidiClient::getOutputBufferSize() { return snd_seq_get_output_buffer_size(d->m_SeqHandle); } /** * Sets the size of the library output buffer for the ALSA client. * * This buffer is used to store the decoded byte-stream of output events before * transferring to the sequencer. * * @param newSize the size of the library output buffer */ void MidiClient::setOutputBufferSize(size_t newSize) { if (getOutputBufferSize() != newSize) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_output_buffer_size(d->m_SeqHandle, newSize)); } } /** * Gets the size of the library input buffer for the ALSA client. * * This buffer is used to read a byte-stream of input events before * transferring from the sequencer. * * @return the size of the library input buffer */ size_t MidiClient::getInputBufferSize() { return snd_seq_get_input_buffer_size(d->m_SeqHandle); } /** * Sets the size of the library input buffer for the ALSA client. * * This buffer is used to read a byte-stream of input events before * transferring from the sequencer. * * @param newSize the size of the library input buffer */ void MidiClient::setInputBufferSize(size_t newSize) { if (getInputBufferSize() != newSize) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_input_buffer_size(d->m_SeqHandle, newSize)); } } /** * Change the blocking mode of the client. * * In block mode, the client falls into sleep when it fills the output memory * pool with full events. The client will be woken up after a certain amount * of free space becomes available. * * @param newValue the blocking mode */ void MidiClient::setBlockMode(bool newValue) { if (d->m_BlockMode != newValue) { d->m_BlockMode = newValue; if (d->m_SeqHandle != nullptr) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_nonblock(d->m_SeqHandle, d->m_BlockMode ? 0 : 1)); } } } /** * Gets the client ID. * * Returns the ID of the client. A client ID is necessary to inquiry or to set * the client information. A user client ID is assigned from 128 to 191. * * @return the client ID. */ int MidiClient::getClientId() { return DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_client_id(d->m_SeqHandle)); } /** * Returns the type snd_seq_type_t of the given sequencer handle. * @return the type snd_seq_type_t of the given sequencer handle. */ snd_seq_type_t MidiClient::getSequencerType() { return snd_seq_type(d->m_SeqHandle); } /** * Dispatch the events received from the Sequencer. * * There are three methods of events delivering: *
    *
  • A Callback method. To use this method, you must derive a class from * SequencerEventHandler, overriding the method * SequencerEventHandler::handleSequencerEvent() to * provide your own event processing. You must provide the handler instance to * the client using setHandler().
  • *
  • Using QEvent listeners. To use this method, you must use one or more * classes derived from QObject overriding the method QObject::customEvent(). * You must also use the method addListener() to add such objects to the * client's listeners list.
  • *
  • The third method involves signals and slots. Whenever a sequencer event * is received, a signal eventReceived() is emitted, that can be connected to * your own supplied slot(s) to process it. *
* @see ALSAClient */ void MidiClient::doEvents() { do { int err = 0; snd_seq_event_t* evp = nullptr; SequencerEvent* event = nullptr; err = snd_seq_event_input(d->m_SeqHandle, &evp); if ((err >= 0) && (evp != nullptr)) { switch (evp->type) { case SND_SEQ_EVENT_NOTE: event = new NoteEvent(evp); break; case SND_SEQ_EVENT_NOTEON: event = new NoteOnEvent(evp); break; case SND_SEQ_EVENT_NOTEOFF: event = new NoteOffEvent(evp); break; case SND_SEQ_EVENT_KEYPRESS: event = new KeyPressEvent(evp); break; case SND_SEQ_EVENT_CONTROLLER: case SND_SEQ_EVENT_CONTROL14: case SND_SEQ_EVENT_REGPARAM: case SND_SEQ_EVENT_NONREGPARAM: event = new ControllerEvent(evp); break; case SND_SEQ_EVENT_PGMCHANGE: event = new ProgramChangeEvent(evp); break; case SND_SEQ_EVENT_CHANPRESS: event = new ChanPressEvent(evp); break; case SND_SEQ_EVENT_PITCHBEND: event = new PitchBendEvent(evp); break; case SND_SEQ_EVENT_SYSEX: event = new SysExEvent(evp); break; case SND_SEQ_EVENT_PORT_SUBSCRIBED: case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: event = new SubscriptionEvent(evp); break; case SND_SEQ_EVENT_PORT_CHANGE: case SND_SEQ_EVENT_PORT_EXIT: case SND_SEQ_EVENT_PORT_START: event = new PortEvent(evp); d->m_NeedRefreshClientList = true; break; case SND_SEQ_EVENT_CLIENT_CHANGE: case SND_SEQ_EVENT_CLIENT_EXIT: case SND_SEQ_EVENT_CLIENT_START: event = new ClientEvent(evp); d->m_NeedRefreshClientList = true; break; case SND_SEQ_EVENT_SONGPOS: case SND_SEQ_EVENT_SONGSEL: case SND_SEQ_EVENT_QFRAME: case SND_SEQ_EVENT_TIMESIGN: case SND_SEQ_EVENT_KEYSIGN: event = new ValueEvent(evp); break; case SND_SEQ_EVENT_SETPOS_TICK: case SND_SEQ_EVENT_SETPOS_TIME: case SND_SEQ_EVENT_QUEUE_SKEW: event = new QueueControlEvent(evp); break; case SND_SEQ_EVENT_TEMPO: event = new TempoEvent(evp); break; default: event = new SequencerEvent(evp); break; } // first, process the callback (if any) if (d->m_handler != nullptr) { d->m_handler->handleSequencerEvent(event->clone()); } else { // second, process the event listeners if (d->m_eventsEnabled) { QObjectList::Iterator it; for(it=d->m_listeners.begin(); it!=d->m_listeners.end(); ++it) { QObject* sub = (*it); QCoreApplication::postEvent(sub, event->clone()); } } else { // finally, process signals emit eventReceived(event->clone()); } } delete event; } } while (snd_seq_event_input_pending(d->m_SeqHandle, 0) > 0); } /** * Starts reading events from the ALSA sequencer. */ void MidiClient::startSequencerInput() { if (d->m_Thread == nullptr) { d->m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT); } d->m_Thread->start( d->m_Thread->m_RealTime ? QThread::TimeCriticalPriority : QThread::InheritPriority ); } /** * Stops reading events from the ALSA sequencer. */ void MidiClient::stopSequencerInput() { int counter = 0; if (d->m_Thread != nullptr) { if (d->m_Thread->isRunning()) { d->m_Thread->stop(); while (!d->m_Thread->wait(500) && (counter < 10)) { counter++; } if (!d->m_Thread->isFinished()) { d->m_Thread->terminate(); } } delete d->m_Thread; } } /** * Reads the ALSA sequencer's clients list. */ void MidiClient::readClients() { ClientInfo cInfo; freeClients(); cInfo.setClient(-1); while (snd_seq_query_next_client(d->m_SeqHandle, cInfo.m_Info) >= 0) { cInfo.readPorts(this); d->m_ClientList.append(cInfo); } d->m_NeedRefreshClientList = false; } /** * Releases the list of ALSA sequencer's clients. */ void MidiClient::freeClients() { d->m_ClientList.clear(); } /** * Gets the list of clients from the ALSA sequencer. * @return the list of clients. */ ClientInfoList MidiClient::getAvailableClients() { if (d->m_NeedRefreshClientList) readClients(); ClientInfoList lst = d->m_ClientList; // copy return lst; } /** * Gets the ClientInfo object holding data about this client. * @return the ClientInfo object representing this client. */ ClientInfo& MidiClient::getThisClientInfo() { snd_seq_get_client_info(d->m_SeqHandle, d->m_Info.m_Info); return d->m_Info; } /** * Sets the data supplied by the ClientInfo object into the ALSA sequencer * client. This allows to change the name, capabilities, type and other data * in a single step. * * @param val a ClientInfo object reference */ void MidiClient::setThisClientInfo(const ClientInfo& val) { d->m_Info = val; snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info); } /** * This internal method applies the ClientInfo data to the ALSA sequencer client */ void MidiClient::applyClientInfo() { if (d->m_SeqHandle != nullptr) { snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info); } } /** * Gets the client's public name * @return The client's name */ QString MidiClient::getClientName() { return d->m_Info.getName(); } /** * Gets the public name corresponding to the given Client ID. * @param clientId The ID of any existing sequencer client * @return The client's name */ QString MidiClient::getClientName(const int clientId) { ClientInfoList::Iterator it; if (d->m_NeedRefreshClientList) readClients(); for (it = d->m_ClientList.begin(); it != d->m_ClientList.end(); ++it) { if ((*it).getClientId() == clientId) { return (*it).getName(); } } return QString(); } /** * Changes the public name of the ALSA sequencer client. * @param newName A new public name */ void MidiClient::setClientName(QString const& newName) { if (newName != d->m_Info.getName()) { d->m_Info.setName(newName); applyClientInfo(); } } /** * Gets the list of MidiPort instances belonging to this client. * @return The list of MidiPort instances. */ MidiPortList MidiClient::getMidiPorts() const { return d->m_Ports; } /** * Create and attach a new MidiPort instance to this client. * @return The pointer to the new MidiPort instance. */ MidiPort* MidiClient::createPort() { MidiPort* port = new MidiPort(this); port->attach(this); return port; } /** * Attach a MidiPort instance to this client * @param port The MidiPort to be attached */ void MidiClient::portAttach(MidiPort* port) { if (d->m_SeqHandle != nullptr) { DRUMSTICK_ALSA_CHECK_ERROR(snd_seq_create_port(d->m_SeqHandle, port->m_Info.m_Info)); d->m_Ports.push_back(port); } } /** * Detach a MidiPort instance from this client * @param port The MidiPort to be detached */ void MidiClient::portDetach(MidiPort* port) { if (d->m_SeqHandle != nullptr) { if(port->getPortInfo()->getClient() == getClientId()) { return; } DRUMSTICK_ALSA_CHECK_ERROR(snd_seq_delete_port(d->m_SeqHandle, port->getPortInfo()->getPort())); port->setMidiClient(nullptr); MidiPortList::iterator it; for(it = d->m_Ports.begin(); it != d->m_Ports.end(); ++it) { if ((*it)->getPortInfo()->getPort() == port->getPortInfo()->getPort()) { d->m_Ports.erase(it); break; } } } } /** * Detach all the ports belonging to this client. */ void MidiClient::detachAllPorts() { if (d->m_SeqHandle != nullptr) { QMutableListIterator it(d->m_Ports); while (it.hasNext()) { MidiPort* p = it.next(); DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_delete_port(d->m_SeqHandle, p->getPortInfo()->getPort())); p->setMidiClient(nullptr); it.remove(); } } } /** * Add an event filter to the client. * @param evtype An event filter to be added. */ void MidiClient::addEventFilter(int evtype) { snd_seq_set_client_event_filter(d->m_SeqHandle, evtype); } /** * Gets the broadcast filter usage of the client. * * @return The broadcast filter. */ bool MidiClient::getBroadcastFilter() { return d->m_Info.getBroadcastFilter(); } /** * Sets the broadcast filter usage of the client. * * @param newValue The broadcast filter. */ void MidiClient::setBroadcastFilter(bool newValue) { d->m_Info.setBroadcastFilter(newValue); applyClientInfo(); } /** * Get the error-bounce usage of the client. * * @return The error-bounce usage. */ bool MidiClient::getErrorBounce() { return d->m_Info.getErrorBounce(); } /** * Sets the error-bounce usage of the client. * * @param newValue The error-bounce usage. */ void MidiClient::setErrorBounce(bool newValue) { d->m_Info.setErrorBounce(newValue); applyClientInfo(); } /** * Output an event using the library output buffer. * * An event is once expanded on the output buffer. The output buffer will be * drained automatically if it becomes full. * * @param ev The event to be sent. * @param async Use asynchronous mode. If false, this call will block until the * event can be delivered. * @param timeout The maximum time to wait in synchronous mode. */ void MidiClient::output(SequencerEvent* ev, bool async, int timeout) { pollfd* pfds = nullptr; if (async) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_event_output(d->m_SeqHandle, ev->getHandle())); } else { int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT); pfds = (pollfd*) calloc(npfds, sizeof(pollfd)); snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT); while (snd_seq_event_output(d->m_SeqHandle, ev->getHandle()) < 0) { poll(pfds, npfds, timeout); } free(pfds); } } /** * Output an event directly to the sequencer * * This function sends an event to the sequencer directly not using the library * output buffer. * * @param ev The event to be sent. * @param async Use asynchronous mode. If false, this call will block until the * event is delivered to the sequencer. * @param timeout The maximum time to wait in synchronous mode. */ void MidiClient::outputDirect(SequencerEvent* ev, bool async, int timeout) { if (async) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_event_output_direct(d->m_SeqHandle, ev->getHandle())); } else { int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT); pollfd* pfds = (pollfd*) calloc(npfds, sizeof(pollfd)); snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT); while (snd_seq_event_output_direct(d->m_SeqHandle, ev->getHandle()) < 0) { poll(pfds, npfds, timeout); } free(pfds); } } /** * Output an event using the library output buffer, without draining the buffer. * * An event is once expanded on the output buffer. The output buffer will NOT be * drained automatically if it becomes full. * * @param ev The event to be sent. */ void MidiClient::outputBuffer(SequencerEvent* ev) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_event_output_buffer(d->m_SeqHandle, ev->getHandle())); } /** * Drain the library output buffer. * * This function drains all pending events on the output buffer. The function * returns immediately after the events are sent to the queues regardless * whether the events are processed or not. * * @param async Use asynchronous mode. If false, this call will block until the * buffer can be flushed. * @param timeout The maximum time to wait in synchronous mode. */ void MidiClient::drainOutput(bool async, int timeout) { if (async) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_drain_output(d->m_SeqHandle)); } else { int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT); pollfd* pfds = (pollfd*) calloc(npfds, sizeof(pollfd)); snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT); while (snd_seq_drain_output(d->m_SeqHandle) < 0) { poll(pfds, npfds, timeout); } free(pfds); } } /** * Wait until all sent events are processed. * * This function waits until all events of this client are processed. */ void MidiClient::synchronizeOutput() { snd_seq_sync_output_queue(d->m_SeqHandle); } /** * Get the MidiQueue instance associated to this client. * If the client is not associated to a MidiQueue, one is created. * @return A MidiQueue instance pointer */ MidiQueue* MidiClient::getQueue() { if (d->m_Queue == nullptr) { createQueue(); } return d->m_Queue; } /** * Create and return a new MidiQueue associated to this client. * @return A new MidiQueue instance. */ MidiQueue* MidiClient::createQueue() { if (d->m_Queue != nullptr) { delete d->m_Queue; } d->m_Queue = new MidiQueue(this, this); return d->m_Queue; } /** * Create and return a new MidiQueue with the given name, associated to this * client. * @param queueName The name for the new queue. * @return A new MidiQueue instance. */ MidiQueue* MidiClient::createQueue(QString const& queueName ) { if (d->m_Queue != nullptr) { delete d->m_Queue; } d->m_Queue = new MidiQueue(this, queueName, this); return d->m_Queue; } /** * Create a new MidiQueue instance using a queue already existing in the * system, associating it to the client. * * @param queue_id An existing queue identifier. * @return A new MidiQueue instance. */ MidiQueue* MidiClient::useQueue(int queue_id) { if (d->m_Queue != nullptr) { delete d->m_Queue; } d->m_Queue = new MidiQueue(this, queue_id, this); return d->m_Queue; } /** * Create a new MidiQueue instance using a queue already existing in the * system, associating it to the client. * * @param name An existing queue name. * @return A new MidiQueue instance. */ MidiQueue* MidiClient::useQueue(const QString& name) { if (d->m_Queue != nullptr) { delete d->m_Queue; } int queue_id = getQueueId(name); if ( queue_id >= 0) { d->m_Queue = new MidiQueue(this, queue_id, this); } return d->m_Queue; } /** * Associate an existing MidiQueue instance to the client. * * @param queue An existing MidiQueue. * @return The provided MidiQueue instance. */ MidiQueue* MidiClient::useQueue(MidiQueue* queue) { if (d->m_Queue != nullptr) { delete d->m_Queue; } queue->setParent(this); d->m_Queue = queue; return d->m_Queue; } /** * Get a list of the existing queues * @return a list of existing queues */ QList MidiClient::getAvailableQueues() { int q, err, max; QList queues; snd_seq_queue_info_t* qinfo; snd_seq_queue_info_alloca(&qinfo); max = getSystemInfo().getMaxQueues(); for ( q = 0; q < max; ++q ) { err = snd_seq_get_queue_info(d->m_SeqHandle, q, qinfo); if (err == 0) { queues.append(q); } } return queues; } /** * Gets a list of the available user ports in the system, filtered by the given * bitmap of desired capabilities. * * @param filter A bitmap of capabilities. * @return A filtered list of the available ports in the system. */ PortInfoList MidiClient::filterPorts(unsigned int filter) { PortInfoList result; ClientInfoList::ConstIterator itc; PortInfoList::ConstIterator itp; if (d->m_NeedRefreshClientList) readClients(); for (itc = d->m_ClientList.constBegin(); itc != d->m_ClientList.constEnd(); ++itc) { ClientInfo ci = (*itc); if ((ci.getClientId() == SND_SEQ_CLIENT_SYSTEM) || (ci.getClientId() == d->m_Info.getClientId())) continue; PortInfoList lstPorts = ci.getPorts(); for(itp = lstPorts.constBegin(); itp != lstPorts.constEnd(); ++itp) { PortInfo pi = (*itp); unsigned int cap = pi.getCapability(); if ( ((filter & cap) != 0) && ((SND_SEQ_PORT_CAP_NO_EXPORT & cap) == 0) ) { result.append(pi); } } } return result; } /** * Update the internal lists of user ports. */ void MidiClient::updateAvailablePorts() { d->m_InputsAvail.clear(); d->m_OutputsAvail.clear(); d->m_InputsAvail = filterPorts( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ ); d->m_OutputsAvail = filterPorts( SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE ); } /** * Gets the available user input ports in the system. * @return The list of available input ports. */ PortInfoList MidiClient::getAvailableInputs() { d->m_NeedRefreshClientList = true; updateAvailablePorts(); return d->m_InputsAvail; } /** * Gets the available user output ports in the system. * @return The list of available output ports. */ PortInfoList MidiClient::getAvailableOutputs() { d->m_NeedRefreshClientList = true; updateAvailablePorts(); return d->m_OutputsAvail; } /** * Adds a QObject to the listeners list. This object should override the method * QObject::customEvent() to receive SequencerEvent instances. * @param listener A QObject listener to be notified of received events. * @see removeListener(), setEventsEnabled() */ void MidiClient::addListener(QObject* listener) { d->m_listeners.append(listener); } /** * Removes a QObject listener from the listeners list. * @param listener listener A QObject listener to be removed of received events. * @see addListener(), setEventsEnabled() */ void MidiClient::removeListener(QObject* listener) { d->m_listeners.removeAll(listener); } /** * Enables the notification of received SequencerEvent instances to the listeners * registered with addListener() * @param bEnabled The new state of the events delivering mode. * @see addListener(), removeListener(), setEventsEnabled() */ void MidiClient::setEventsEnabled(bool bEnabled) { if (bEnabled != d->m_eventsEnabled) { d->m_eventsEnabled = bEnabled; } } /** * Gets a SystemInfo instance with the updated state of the system. * @return The updated system info. */ SystemInfo& MidiClient::getSystemInfo() { snd_seq_system_info(d->m_SeqHandle, d->m_sysInfo.m_Info); return d->m_sysInfo; } /** * Gets a PoolInfo instance with an updated state of the client memory pool * @return The updated memory pool state. */ PoolInfo& MidiClient::getPoolInfo() { snd_seq_get_client_pool(d->m_SeqHandle, d->m_poolInfo.m_Info); return d->m_poolInfo; } /** * Applies (updates) the client's PoolInfo data into the system. * @param info The PoolInfo reference to be applied to the client. */ void MidiClient::setPoolInfo(const PoolInfo& info) { d->m_poolInfo = info; DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_client_pool(d->m_SeqHandle, d->m_poolInfo.m_Info)); } /** * Resets the client input pool. * @see dropInput() */ void MidiClient::resetPoolInput() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_reset_pool_input(d->m_SeqHandle)); } /** * Resets the client output pool. * @see dropOutput() */ void MidiClient::resetPoolOutput() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_reset_pool_output(d->m_SeqHandle)); } /** * Sets the size of the client's input pool. * @param size The new size */ void MidiClient::setPoolInput(int size) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_client_pool_input(d->m_SeqHandle, size)); } /** * Sets the size of the client's output pool. * @param size The new size */ void MidiClient::setPoolOutput(int size) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_client_pool_output(d->m_SeqHandle, size)); } /** * Sets the room size of the client's output pool. * @param size The new size */ void MidiClient::setPoolOutputRoom(int size) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_client_pool_output_room(d->m_SeqHandle, size)); } /** * Clears the client's input buffer and and remove events in sequencer queue. * @see resetPoolInput() */ void MidiClient::dropInput() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_drop_input(d->m_SeqHandle)); } /** * Remove all events on user-space input buffer. * @see dropInput() */ void MidiClient::dropInputBuffer() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_drop_input_buffer(d->m_SeqHandle)); } /** * Clears the client's output buffer and and remove events in sequencer queue. * * This method removes all events on both user-space output buffer and output * memory pool on kernel. * @see resetPoolOutput() */ void MidiClient::dropOutput() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_drop_output(d->m_SeqHandle)); } /** * Removes all events on the library output buffer. * * Removes all events on the user-space output buffer. Unlike dropOutput(), this * method doesn't remove events on the client's output memory pool. * @see dropOutput() */ void MidiClient::dropOutputBuffer() { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_drop_output_buffer(d->m_SeqHandle)); } /** * Removes events on input/output buffers and pools. * Removes matching events with the given condition from input/output buffers * and pools. The removal condition is specified in the spec argument. * @param spec A RemoveEvents instance specifying the removal condition. */ void MidiClient::removeEvents(const RemoveEvents* spec) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_remove_events(d->m_SeqHandle, spec->m_Info)); } /** * Extracts (and removes) the first event in the output buffer. * @return The extracted event. */ SequencerEvent* MidiClient::extractOutput() { snd_seq_event_t* ev; if (DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_extract_output(d->m_SeqHandle, &ev) == 0)) { return new SequencerEvent(ev); } return nullptr; } /** * Returns the size of pending events on the output buffer. * * @return The size of pending events. */ int MidiClient::outputPending() { return snd_seq_event_output_pending(d->m_SeqHandle); } /** * Gets the size of the events on the input buffer. * * If there are events remaining on the user-space input buffer, this method * returns the total size of events on it. If the argument is true, this method * checks the presence of events on the sequencer FIFO, and when events exist * they are transferred to the input buffer, and the number of received events * are returned. If the argument is false and no events remain on the input * buffer, this method simply returns zero. * * @param fetch Check and fetch the sequencer input pool. * @return The size in bytes of the remaining input events on the buffer. */ int MidiClient::inputPending(bool fetch) { return snd_seq_event_input_pending(d->m_SeqHandle, fetch ? 1 : 0); } /** * Gets the queue's numeric identifier corresponding to the provided name. * * @param name The name string to query. * @return The number of the matching queue. */ int MidiClient::getQueueId(const QString& name) { return snd_seq_query_named_queue(d->m_SeqHandle, name.toLocal8Bit().data()); } /** * Returns the number of poll descriptors. * @param events Poll events to be checked (POLLIN and POLLOUT). * @return The number of poll descriptors. */ int MidiClient::getPollDescriptorsCount(short events) { return snd_seq_poll_descriptors_count(d->m_SeqHandle, events); } /** * Get poll descriptors. * * Get poll descriptors assigned to the sequencer handle. Since a sequencer * handle can duplex streams, you need to set which direction(s) is/are polled * in events argument. When POLLIN bit is specified, the incoming events to the * ports are checked. * * @param pfds Array of poll descriptors * @param space Space in the poll descriptor array * @param events Polling events to be checked (POLLIN and POLLOUT) * @return Count of filled descriptors */ int MidiClient::pollDescriptors( struct pollfd *pfds, unsigned int space, short events ) { return snd_seq_poll_descriptors(d->m_SeqHandle, pfds, space, events); } /** * Gets the number of returned events from poll descriptors * @param pfds Array of poll descriptors. * @param nfds Count of poll descriptors. * @return Number of returned events. */ unsigned short MidiClient::pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds) { unsigned short revents; DRUMSTICK_ALSA_CHECK_WARNING( snd_seq_poll_descriptors_revents( d->m_SeqHandle, pfds, nfds, &revents )); return revents; } /** * Gets the internal sequencer device name * @return The device name. */ const char * MidiClient::_getDeviceName() { return snd_seq_name(d->m_SeqHandle); } /** * Sets the client name * @param name The new client name. */ void MidiClient::_setClientName(const char *name) { DRUMSTICK_ALSA_CHECK_WARNING(snd_seq_set_client_name(d->m_SeqHandle, name)); } /** * Create an ALSA sequencer port, without using MidiPort. * @param name The name of the new port. * @param caps The new port capabilities. * @param type The type of the new port. * @return The port numeric identifier. */ int MidiClient::createSimplePort( const char *name, unsigned int caps, unsigned int type ) { return DRUMSTICK_ALSA_CHECK_WARNING( snd_seq_create_simple_port( d->m_SeqHandle, name, caps, type )); } /** * Remove an ALSA sequencer port. * @param port The numeric identifier of the port. */ void MidiClient::deleteSimplePort(int port) { DRUMSTICK_ALSA_CHECK_WARNING( snd_seq_delete_simple_port( d->m_SeqHandle, port )); } /** * Subscribe one port from another arbitrary sequencer client:port. * @param myport The number of the internal port. * @param client The external client's identifier. * @param port The external port's identifier. */ void MidiClient::connectFrom(int myport, int client, int port) { DRUMSTICK_ALSA_CHECK_WARNING( snd_seq_connect_from(d->m_SeqHandle, myport, client, port )); } /** * Subscribe one port to another arbitrary sequencer client:port. * @param myport The number of the internal port. * @param client The external client's identifier. * @param port The external port's identifier. */ void MidiClient::connectTo(int myport, int client, int port) { DRUMSTICK_ALSA_CHECK_WARNING( snd_seq_connect_to(d->m_SeqHandle, myport, client, port )); } /** * Unsubscribe one port from another arbitrary sequencer client:port. * @param myport The number of the internal port. * @param client The external client's identifier. * @param port The external port's identifier. */ void MidiClient::disconnectFrom(int myport, int client, int port) { DRUMSTICK_ALSA_CHECK_WARNING( snd_seq_disconnect_from(d->m_SeqHandle, myport, client, port )); } /** * Unsubscribe one port to another arbitrary sequencer client:port. * @param myport The number of the internal port. * @param client The external client's identifier. * @param port The external port's identifier. */ void MidiClient::disconnectTo(int myport, int client, int port) { DRUMSTICK_ALSA_CHECK_WARNING( snd_seq_disconnect_to(d->m_SeqHandle, myport, client, port )); } /** * Parse a text address representation, returning an ALSA address record. * * This function can be used as a replacement of the standard ALSA function * snd_seq_parse_address(). * * @param straddr source text address representation * @param addr returned ALSA address record * @return true if the text address was successfully parsed * @since 0.3.1 */ bool MidiClient::parseAddress( const QString& straddr, snd_seq_addr& addr ) { bool ok(false); QString testClient, testPort; ClientInfoList::ConstIterator cit; int pos = straddr.indexOf(':'); if (pos > -1) { testClient = straddr.left(pos); testPort = straddr.mid(pos+1); } else { testClient = straddr; testPort = '0'; } addr.client = testClient.toInt(&ok); if (ok) addr.port = testPort.toInt(&ok); if (!ok) { if (d->m_NeedRefreshClientList) readClients(); for ( cit = d->m_ClientList.constBegin(); cit != d->m_ClientList.constEnd(); ++cit ) { ClientInfo ci = *cit; if (testClient.compare(ci.getName(), Qt::CaseInsensitive) == 0) { addr.client = ci.getClientId(); addr.port = testPort.toInt(&ok); return ok; } } } return ok; } /** * Returns true or false depending on the input thread state. * @return true if the input thread is stopped. */ bool MidiClient::SequencerInputThread::stopped() { QReadLocker locker(&m_mutex); return m_Stopped; } /** * Stops the input thread. */ void MidiClient::SequencerInputThread::stop() { QWriteLocker locker(&m_mutex); m_Stopped = true; } #if defined(RTKIT_SUPPORT) static pid_t _gettid() { return (pid_t) ::syscall(SYS_gettid); } #endif void MidiClient::SequencerInputThread::setRealtimePriority() { struct sched_param p; int rt, policy = SCHED_RR | SCHED_RESET_ON_FORK; quint32 priority = 6; #if defined(RTKIT_SUPPORT) bool ok; quint32 max_prio; quint64 thread; struct rlimit old_limit, new_limit; long long max_rttime; #endif ::memset(&p, 0, sizeof(p)); p.sched_priority = priority; rt = ::pthread_setschedparam(::pthread_self(), policy, &p); if (rt != 0) { #if defined(RTKIT_SUPPORT) const QString rtkit_service = QStringLiteral("org.freedesktop.RealtimeKit1"); const QString rtkit_path = QStringLiteral("/org/freedesktop/RealtimeKit1"); const QString rtkit_iface = rtkit_service; thread = _gettid(); QDBusConnection bus = QDBusConnection::systemBus(); QDBusInterface realtimeKit(rtkit_service, rtkit_path, rtkit_iface, bus); QVariant maxRTPrio = realtimeKit.property("MaxRealtimePriority"); max_prio = maxRTPrio.toUInt(&ok); if (!ok) { qWarning() << "invalid property RealtimeKit.MaxRealtimePriority"; return; } if (priority > max_prio) priority = max_prio; QVariant maxRTNSec = realtimeKit.property("RTTimeNSecMax"); max_rttime = maxRTNSec.toLongLong(&ok); if (!ok || max_rttime < 0) { qWarning() << "invalid property RealtimeKit.RTTimeNSecMax"; return; } new_limit.rlim_cur = new_limit.rlim_max = max_rttime; rt = ::getrlimit(RLIMIT_RTTIME, &old_limit); if (rt < 0) { qWarning() << "getrlimit() failed. err=" << rt << ::strerror(rt); return; } rt = ::setrlimit(RLIMIT_RTTIME, &new_limit); if ( rt < 0) { qWarning() << "setrlimit() failed, err=" << rt << ::strerror(rt); return; } QDBusMessage reply = realtimeKit.call("MakeThreadRealtime", thread, priority); if (reply.type() == QDBusMessage::ErrorMessage ) qWarning() << "error returned by RealtimeKit.MakeThreadRealtime:" << reply.errorMessage(); #endif } else { qWarning() << "pthread_setschedparam() failed, err=" << rt << ::strerror(rt); } } /** * Main input thread process loop. */ void MidiClient::SequencerInputThread::run() { if ( priority() == TimeCriticalPriority ) { setRealtimePriority(); } if (m_MidiClient != nullptr) { int npfd = snd_seq_poll_descriptors_count(m_MidiClient->getHandle(), POLLIN); pollfd* pfd = (pollfd *) calloc(npfd, sizeof(pollfd)); try { snd_seq_poll_descriptors(m_MidiClient->getHandle(), pfd, npfd, POLLIN); while (!stopped() && (m_MidiClient != nullptr)) { int rt = poll(pfd, npfd, m_Wait); if (rt > 0) { m_MidiClient->doEvents(); } } } catch (...) { qWarning() << "exception in input thread"; } free(pfd); } } /** * Default constructor */ ClientInfo::ClientInfo() { snd_seq_client_info_malloc(&m_Info); } /** * Copy constructor * @param other Another ClientInfo reference to be copied */ ClientInfo::ClientInfo(const ClientInfo& other) { snd_seq_client_info_malloc(&m_Info); snd_seq_client_info_copy(m_Info, other.m_Info); m_Ports = other.m_Ports; } /** * Copy constructor * @param other An existing ALSA client info object */ ClientInfo::ClientInfo(snd_seq_client_info_t* other) { snd_seq_client_info_malloc(&m_Info); snd_seq_client_info_copy(m_Info, other); } /** * Constructor * @param seq A MidiClient object * @param id A numeric client id */ ClientInfo::ClientInfo(MidiClient* seq, int id) { snd_seq_client_info_malloc(&m_Info); snd_seq_get_any_client_info(seq->getHandle(), id, m_Info); } /** * Destructor */ ClientInfo::~ClientInfo() { freePorts(); snd_seq_client_info_free(m_Info); } /** * Clone the client info object. * @return A pointer to the new object. */ ClientInfo* ClientInfo::clone() { return new ClientInfo(m_Info); } /** * Assignment operator * @param other Another ClientInfo object * @return This object */ ClientInfo& ClientInfo::operator=(const ClientInfo& other) { if (this == &other) return *this; snd_seq_client_info_copy(m_Info, other.m_Info); m_Ports = other.m_Ports; return *this; } /** * Gets the client's numeric identifier. * @return The client's numeric identifier. */ int ClientInfo::getClientId() { return snd_seq_client_info_get_client(m_Info); } /** * Gets the client's type * @return The client's type. */ snd_seq_client_type_t ClientInfo::getClientType() { return snd_seq_client_info_get_type(m_Info); } /** * Gets the client's name * @return The client's name. */ QString ClientInfo::getName() { return QString(snd_seq_client_info_get_name(m_Info)); } /** * Gets the client's broadcast filter * @return The client's broadcast filter. */ bool ClientInfo::getBroadcastFilter() { return (snd_seq_client_info_get_broadcast_filter(m_Info) != 0); } /** * Gets the client's error bounce * @return The client's error bounce. */ bool ClientInfo::getErrorBounce() { return (snd_seq_client_info_get_error_bounce(m_Info) != 0); } /** * Gets the client's event filter. * @return The client's event filter. * @deprecated Use isFiltered() instead. */ const unsigned char* ClientInfo::getEventFilter() { return snd_seq_client_info_get_event_filter(m_Info); } /** * Gets the client's port count. * @return The client's port count. */ int ClientInfo::getNumPorts() { return snd_seq_client_info_get_num_ports(m_Info); } /** * Gets the number of lost events. * @return The number of lost events. */ int ClientInfo::getEventLost() { return snd_seq_client_info_get_event_lost(m_Info); } /** * Sets the client identifier number. * @param client The client identifier number. */ void ClientInfo::setClient(int client) { snd_seq_client_info_set_client(m_Info, client); } /** * Sets the client name. * @param name The client name. */ void ClientInfo::setName(QString name) { snd_seq_client_info_set_name(m_Info, name.toLocal8Bit().data()); } /** * Sets the broadcast filter. * @param val The broadcast filter. */ void ClientInfo::setBroadcastFilter(bool val) { snd_seq_client_info_set_broadcast_filter(m_Info, val ? 1 : 0); } /** * Sets the error bounce. * @param val The error bounce. */ void ClientInfo::setErrorBounce(bool val) { snd_seq_client_info_set_error_bounce(m_Info, val ? 1 : 0); } /** * Sets the event filter. * @param filter The event filter. * @deprecated Use addFilter() instead. */ void ClientInfo::setEventFilter(unsigned char *filter) { snd_seq_client_info_set_event_filter(m_Info, filter); } /** * Read the client ports. * @param seq The client instance. */ void ClientInfo::readPorts(MidiClient* seq) { PortInfo info; freePorts(); info.setClient(getClientId()); info.setClientName(getName()); info.setPort(-1); while (snd_seq_query_next_port(seq->getHandle(), info.m_Info) >= 0) { info.readSubscribers(seq); m_Ports.append(info); } } /** * Release the ports list. */ void ClientInfo::freePorts() { m_Ports.clear(); } /** * Gets the ports list. * @return The ports list. */ PortInfoList ClientInfo::getPorts() const { PortInfoList lst = m_Ports; // copy return lst; } /** * Gets the size of the internal object. * @return The size of the internal object. */ int ClientInfo::getSizeOfInfo() const { return snd_seq_client_info_sizeof(); } #if SND_LIB_VERSION > 0x010010 /** * Adds an event type to the client's filter. * * @param eventType The new event's type. */ void ClientInfo::addFilter(int eventType) { snd_seq_client_info_event_filter_add(m_Info, eventType); } /** * Checks id the given event's type is filtered. * @param eventType The event's type. * @return true if the event type is filtered */ bool ClientInfo::isFiltered(int eventType) { return (snd_seq_client_info_event_filter_check(m_Info, eventType) != 0); } /** * Clear the client's event filter */ void ClientInfo::clearFilter() { snd_seq_client_info_event_filter_clear(m_Info); } /** * Removes the event type from the client's filter. * @param eventType The event's type. */ void ClientInfo::removeFilter(int eventType) { snd_seq_client_info_event_filter_del(m_Info, eventType); } #endif /** * Default constructor */ SystemInfo::SystemInfo() { snd_seq_system_info_malloc(&m_Info); } /** * Copy constructor * @param other Another SystemInfo object reference to be copied */ SystemInfo::SystemInfo(const SystemInfo& other) { snd_seq_system_info_malloc(&m_Info); snd_seq_system_info_copy(m_Info, other.m_Info); } /** * Copy constructor * @param other Another ALSA system info object to be copied */ SystemInfo::SystemInfo(snd_seq_system_info_t* other) { snd_seq_system_info_malloc(&m_Info); snd_seq_system_info_copy(m_Info, other); } /** * Constructor * @param seq A MidiClient object */ SystemInfo::SystemInfo(MidiClient* seq) { snd_seq_system_info_malloc(&m_Info); snd_seq_system_info(seq->getHandle(), m_Info); } /** * Destructor */ SystemInfo::~SystemInfo() { snd_seq_system_info_free(m_Info); } /** * Clone the system info object * @return A pointer to the new object */ SystemInfo* SystemInfo::clone() { return new SystemInfo(m_Info); } /** * Assignment operator * @param other Another SystemInfo object * @return This object */ SystemInfo& SystemInfo::operator=(const SystemInfo& other) { if (this == &other) return *this; snd_seq_system_info_copy(m_Info, other.m_Info); return *this; } /** * Get the system's maximum number of clients. * @return The maximum number of clients. */ int SystemInfo::getMaxClients() { return snd_seq_system_info_get_clients(m_Info); } /** * Get the system's maximum number of ports. * @return The maximum number of ports. */ int SystemInfo::getMaxPorts() { return snd_seq_system_info_get_ports(m_Info); } /** * Get the system's maximum number of queues. * @return The system's maximum number of queues. */ int SystemInfo::getMaxQueues() { return snd_seq_system_info_get_queues(m_Info); } /** * Get the system's maximum number of channels. * @return The system's maximum number of channels. */ int SystemInfo::getMaxChannels() { return snd_seq_system_info_get_channels(m_Info); } /** * Get the system's current number of queues. * @return The system's current number of queues. */ int SystemInfo::getCurrentQueues() { return snd_seq_system_info_get_cur_queues(m_Info); } /** * Get the system's current number of clients. * @return The system's current number of clients. */ int SystemInfo::getCurrentClients() { return snd_seq_system_info_get_cur_clients(m_Info); } /** * Get the system's info object size. * @return The system's info object size. */ int SystemInfo::getSizeOfInfo() const { return snd_seq_system_info_sizeof(); } /** * Default constructor */ PoolInfo::PoolInfo() { snd_seq_client_pool_malloc(&m_Info); } /** * Copy constructor * @param other Another PoolInfo object reference to be copied */ PoolInfo::PoolInfo(const PoolInfo& other) { snd_seq_client_pool_malloc(&m_Info); snd_seq_client_pool_copy(m_Info, other.m_Info); } /** * Copy constructor * @param other An ALSA pool info object to be copied */ PoolInfo::PoolInfo(snd_seq_client_pool_t* other) { snd_seq_client_pool_malloc(&m_Info); snd_seq_client_pool_copy(m_Info, other); } /** * Constructor * @param seq A MidiClient object */ PoolInfo::PoolInfo(MidiClient* seq) { snd_seq_client_pool_malloc(&m_Info); snd_seq_get_client_pool(seq->getHandle(), m_Info); } /** * Destructor */ PoolInfo::~PoolInfo() { snd_seq_client_pool_free(m_Info); } /** * Clone the pool info obeject * @return A pointer to the new object */ PoolInfo* PoolInfo::clone() { return new PoolInfo(m_Info); } /** * Assignment operator * @param other Another PoolInfo object reference to be copied * @return This object */ PoolInfo& PoolInfo::operator=(const PoolInfo& other) { if (this == &other) return *this; snd_seq_client_pool_copy(m_Info, other.m_Info); return *this; } /** * Gets the client ID for this object. * @return The client ID. */ int PoolInfo::getClientId() { return snd_seq_client_pool_get_client(m_Info); } /** * Gets the available size on input pool. * @return The available size on input pool. */ int PoolInfo::getInputFree() { return snd_seq_client_pool_get_input_free(m_Info); } /** * Gets the input pool size. * @return The input pool size. */ int PoolInfo::getInputPool() { return snd_seq_client_pool_get_input_pool(m_Info); } /** * Gets the available size on output pool. * @return The available size on output pool. */ int PoolInfo::getOutputFree() { return snd_seq_client_pool_get_output_free(m_Info); } /** * Gets the output pool size. * @return The output pool size. */ int PoolInfo::getOutputPool() { return snd_seq_client_pool_get_output_pool(m_Info); } /** * Gets the output room size. * The output room is the minimum pool size for select/blocking mode. * @return The output room size. */ int PoolInfo::getOutputRoom() { return snd_seq_client_pool_get_output_room(m_Info); } /** * Set the input pool size. * @param size The input pool size. */ void PoolInfo::setInputPool(int size) { snd_seq_client_pool_set_input_pool(m_Info, size); } /** * Sets the output pool size. * @param size The output pool size. */ void PoolInfo::setOutputPool(int size) { snd_seq_client_pool_set_output_pool(m_Info, size); } /** * Sets the output room size. * The output room is the minimum pool size for select/blocking mode. * * @param size Output room size */ void PoolInfo::setOutputRoom(int size) { snd_seq_client_pool_set_output_room(m_Info, size); } /** * Gets the size of the client pool object. * @return The size of the client pool object. */ int PoolInfo::getSizeOfInfo() const { return snd_seq_client_pool_sizeof(); } #if SND_LIB_VERSION > 0x010004 /** * Gets the runtime ALSA library version string * @return string representing the runtime ALSA library version * @since 0.3.0 */ QString getRuntimeALSALibraryVersion() { return QString(snd_asoundlib_version()); } /** * Gets the runtime ALSA library version number * @return integer representing the runtime ALSA library version * @since 0.3.0 */ int getRuntimeALSALibraryNumber() { QRegularExpression rx("(\\d+)"); QString str = getRuntimeALSALibraryVersion(); bool ok; int result = 0, j = 0; QRegularExpressionMatchIterator i = rx.globalMatch(str); while (i.hasNext() && (j < 3)) { QRegularExpressionMatch m = i.next(); int v = m.captured(1).toInt(&ok); if (ok) { result <<= 8; result += v; } j++; } return result; } #endif // SND_LIB_VERSION > 0x010004 /** * Gets the runtime ALSA drivers version string * @return string representing the runtime ALSA drivers version * @since 0.3.0 */ QString getRuntimeALSADriverVersion() { QRegularExpression rx("([\\d\\.]+)"); QString s; QFile f("/proc/asound/version"); if (f.open(QFile::ReadOnly)) { QTextStream str(&f); QString sub = str.readLine().trimmed(); QRegularExpressionMatch m = rx.match(sub); if (m.hasMatch()) { s = m.captured(1); } } return s; } /** * Gets the runtime ALSA drivers version number * @return integer representing the runtime ALSA drivers version * @since 0.3.0 */ int getRuntimeALSADriverNumber() { QRegularExpression rx("(\\d+)"); QString str = getRuntimeALSADriverVersion(); bool ok; int result = 0, j = 0; QRegularExpressionMatchIterator i = rx.globalMatch(str); while (i.hasNext() && (j < 3)) { QRegularExpressionMatch m = i.next(); int v = m.captured(1).toInt(&ok); if (ok) { result <<= 8; result += v; } j++; } return result; } /** * ALSA library version at build time. * * This string corresponds to the compilation library, which may be * different to the runtime library. * @return ALSA runtime library formatted as a QString * @see getRuntimeALSALibraryVersion */ QString getCompiledALSALibraryVersion() { return QStringLiteral(SND_LIB_VERSION_STR); } /** * @brief getDrumstickLibraryVersion provides the Drumstick version as an edited QString * @return Drumstick library version */ QString getDrumstickLibraryVersion() { return QStringLiteral(QT_STRINGIFY(VERSION)); } /** @} */ } // namespace ALSA } // namespace drumstick drumstick-2.5.1/library/alsa/PaxHeaders.27918/drumstick-alsa-config.cmake0000644000000000000000000000013214200302440023034 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/alsa/drumstick-alsa-config.cmake0000644000175000001440000000020114200302440023606 0ustar00pedrousers00000000000000include(CMakeFindDependencyMacro) find_dependency(ALSA REQUIRED) include(${CMAKE_CURRENT_LIST_DIR}/drumstick-alsa-targets.cmake) drumstick-2.5.1/library/PaxHeaders.27918/vpiano-plugin0000644000000000000000000000013214200302440017437 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/vpiano-plugin/0000755000175000001440000000000014200302440020275 5ustar00pedrousers00000000000000drumstick-2.5.1/library/vpiano-plugin/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440022254 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/vpiano-plugin/CMakeLists.txt0000644000175000001440000000423614200302440023042 0ustar00pedrousers00000000000000# Drumstick PianoKeybd Qt Designer Plugin # Copyright (C) 2008-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) find_package(Qt${QT_VERSION_MAJOR}Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR}UiPlugin REQUIRED) set(SOURCES vpiano-plugin.h vpiano-plugin.cpp vpiano-plugin.qrc) add_library(drumstick-vpiano-plugin MODULE ${SOURCES}) target_compile_definitions(drumstick-vpiano-plugin PRIVATE QT_PLUGIN) target_include_directories(drumstick-vpiano-plugin PRIVATE ${Drumstick_SOURCE_DIR}/library/include ) target_link_libraries(drumstick-vpiano-plugin PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::UiPlugin Drumstick::Widgets ) set_target_properties(drumstick-vpiano-plugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/designer) get_target_property(QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake LOCATION) execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_PLUGINS OUTPUT_VARIABLE QT_INSTALL_PLUGINS OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_HOST_PREFIX OUTPUT_VARIABLE QT_HOST_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE ) string(REPLACE "${QT_HOST_PREFIX}/" "" _INSTALL_PLUGINS "${QT_INSTALL_PLUGINS}") install(TARGETS drumstick-vpiano-plugin EXPORT drumstick-vpiano-targets RUNTIME DESTINATION ${_INSTALL_PLUGINS}/designer ARCHIVE DESTINATION ${_INSTALL_PLUGINS}/designer LIBRARY DESTINATION ${_INSTALL_PLUGINS}/designer) drumstick-2.5.1/library/vpiano-plugin/PaxHeaders.27918/vpiano-plugin.pro0000644000000000000000000000013214200302440023026 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/vpiano-plugin/vpiano-plugin.pro0000644000175000001440000000111714200302440023607 0ustar00pedrousers00000000000000TEMPLATE = lib TARGET = drumstick-vpiano-plugin target.path = $$[QT_INSTALL_PLUGINS]/designer INSTALLS += target DESTDIR = ../../build/lib/designer DEPENDPATH += . ../include INCLUDEPATH += . ../include include (../../global.pri) QT += widgets uiplugin CONFIG += plugin HEADERS += vpiano-plugin.h SOURCES += vpiano-plugin.cpp RESOURCES += vpiano-plugin.qrc macx:!static { QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib LIBS += -framework drumstick-widgets } else { LIBS += -L$$OUT_PWD/../../build/lib \ -l$$drumstickLib(drumstick-widgets) } drumstick-2.5.1/library/vpiano-plugin/PaxHeaders.27918/vpiano-plugin.qrc0000644000000000000000000000013214200302440023013 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/vpiano-plugin/vpiano-plugin.qrc0000644000175000001440000000014014200302440023567 0ustar00pedrousers00000000000000 vpiano-plugin.png drumstick-2.5.1/library/vpiano-plugin/PaxHeaders.27918/vpiano-plugin.png0000644000000000000000000000013214200302440023012 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/vpiano-plugin/vpiano-plugin.png0000644000175000001440000000111114200302440023565 0ustar00pedrousers00000000000000PNG  IHDR szzbKGD pHYs  tIME 8+93tEXtCommentCreated with The GIMPd%nIDATX헿@2BRDO#X +;V,|}_<QDD3[|!d90Ŝ{70Ey\.T^v|>Ǚal6h4G)yt:>. RȄ\וRZJJ< F1&'Iʛ繵J !UQ1~S{4AIyZ! 4@hmۙ!m4LnYַj\\.4zNrRl¶mZ-mPJ>APp8`0`! ø/!~?Cl6SEr<2N~@h%RYb~R"5#~=|*k+8c^˼q4MDQʌ`,ʌlޜsMG ULIENDB`drumstick-2.5.1/library/vpiano-plugin/PaxHeaders.27918/vpiano-plugin.cpp0000644000000000000000000000013214200302440023010 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/vpiano-plugin/vpiano-plugin.cpp0000644000175000001440000000475114200302440023600 0ustar00pedrousers00000000000000/* Virtual Piano Widget for Qt Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include "vpiano-plugin.h" #include #include using namespace drumstick::widgets; /** * @file vpiano-plugin.cpp * Implementation of the PianoKeybdPlugin class (Qt Designer plugin) */ PianoKeybdPlugin::PianoKeybdPlugin(QObject *parent) : QObject(parent) { } void PianoKeybdPlugin::initialize(QDesignerFormEditorInterface * /* core */) { if (initialized) return; initialized = true; } bool PianoKeybdPlugin::isInitialized() const { return initialized; } QWidget *PianoKeybdPlugin::createWidget(QWidget *parent) { return new PianoKeybd(parent); } QString PianoKeybdPlugin::name() const { return QStringLiteral("drumstick::widgets::PianoKeybd"); } QString PianoKeybdPlugin::group() const { return QStringLiteral("Drumstick"); } QIcon PianoKeybdPlugin::icon() const { return QIcon(":/vpiano-plugin.png"); } QString PianoKeybdPlugin::toolTip() const { return QStringLiteral("Virtual Piano Keyboard"); } QString PianoKeybdPlugin::whatsThis() const { return QStringLiteral("The Virtual Piano Keyboard is a MIDI controller emulator"); } bool PianoKeybdPlugin::isContainer() const { return false; } QString PianoKeybdPlugin::includeFile() const { return QStringLiteral(""); } QString PianoKeybdPlugin::domXml() const { return "\n" " \n" " \n" " \n" " 0\n" " 0\n" " 640\n" " 80\n" " \n" " \n" " \n" ""; } drumstick-2.5.1/library/vpiano-plugin/PaxHeaders.27918/vpiano-plugin.h0000644000000000000000000000013214200302440022455 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/vpiano-plugin/vpiano-plugin.h0000644000175000001440000000374114200302440023243 0ustar00pedrousers00000000000000/* Virtual Piano Widget for Qt Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #ifndef VPIANOPLUGIN_H #define VPIANOPLUGIN_H #include /** * @file vpiano-plugin.h * PianoKeybdPlugin class definition (Qt Designer plugin) */ /** * @class QDesignerCustomWidgetInterface * @brief The QDesignerCustomWidgetInterface class enables Qt Designer to access and construct custom widgets. * @see https://doc.qt.io/qt-5/qdesignercustomwidgetinterface.html */ class PianoKeybdPlugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface") Q_INTERFACES(QDesignerCustomWidgetInterface) public: explicit PianoKeybdPlugin(QObject *parent = nullptr); bool isContainer() const override; bool isInitialized() const override; QIcon icon() const override; QString domXml() const override; QString group() const override; QString includeFile() const override; QString name() const override; QString toolTip() const override; QString whatsThis() const override; QWidget *createWidget(QWidget *parent) override; void initialize(QDesignerFormEditorInterface *core) override; private: bool initialized = false; }; #endif // VPIANOPLUGIN_H drumstick-2.5.1/library/PaxHeaders.27918/rt0000644000000000000000000000013214200302440015274 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.361324523 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt/0000755000175000001440000000000014200302440016132 5ustar00pedrousers00000000000000drumstick-2.5.1/library/rt/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020111 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.361324523 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt/CMakeLists.txt0000644000175000001440000001006014200302440020667 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-rt_QOBJ_SRCS ../include/drumstick/rtmidiinput.h ../include/drumstick/rtmidioutput.h ) set(drumstick-rt_HEADERS ../include/drumstick/macros.h ../include/drumstick/rtmidiinput.h ../include/drumstick/rtmidioutput.h ../include/drumstick/backendmanager.h ) if(BUILD_FRAMEWORKS) set_source_files_properties(${drumstick-rt_HEADERS} PROPERTIES MACOSX_PACKAGE_LOCATION Headers/drumstick ) endif() set(drumstick-rt_SRCS backendmanager.cpp ) if (WIN32) set(TARGET_DESCRIPTION ${Drumstick_DESCRIPTION}) set(TARGET_NAME drumstick-rt) set(TARGET_ORIGINAL_FILENAME libdrumstick-rt.dll) configure_file(${Drumstick_SOURCE_DIR}/versioninfo.rc.in versioninfo.rc @ONLY) list(APPEND drumstick-rt_SRCS versioninfo.rc) endif() if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-rt_MOC_SRCS ${drumstick-rt_QOBJ_SRCS}) else() qt_wrap_cpp(drumstick-rt_MOC_SRCS ${drumstick-rt_QOBJ_SRCS}) endif() add_library(drumstick-rt ${drumstick-rt_MOC_SRCS} ${drumstick-rt_SRCS} ${drumstick-rt_HEADERS} ) add_library(Drumstick::RT ALIAS drumstick-rt) target_include_directories(drumstick-rt PUBLIC $ $ ) target_compile_definitions(drumstick-rt PRIVATE LIBSUFFIX=${CMAKE_INSTALL_LIBDIR} ) target_link_libraries(drumstick-rt PRIVATE Qt${QT_VERSION_MAJOR}::Core ) if(STATIC_DRUMSTICK) set_target_properties(drumstick-rt PROPERTIES STATIC_LIB "libdrumstick-rt") else() # STATIC_DRUMSTICK set_target_properties(drumstick-rt PROPERTIES VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} SOVERSION ${PROJECT_VERSION_MAJOR} EXPORT_NAME RT # macOS: MACOSX_RPATH TRUE ) if (BUILD_FRAMEWORKS) set_target_properties(drumstick-rt PROPERTIES FRAMEWORK ${BUILD_FRAMEWORKS} FRAMEWORK_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} MACOSX_FRAMEWORK_IDENTIFIER "net.sourceforge.drumstick-rt" MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_SOURCE_DIR}/cmake_admin/CustomFrameworkInfo.plist.in" ) endif() endif() # STATIC_DRUMSTICK install(TARGETS drumstick-rt EXPORT drumstick-rt-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install(FILES ${drumstick-rt_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/drumstick) install(EXPORT drumstick-rt-targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/drumstick NAMESPACE Drumstick:: ) export(EXPORT drumstick-rt-targets NAMESPACE Drumstick:: FILE ${CMAKE_BINARY_DIR}/drumstick-rt-targets.cmake ) include(CMakePackageConfigHelpers) write_basic_package_version_file(${CMAKE_BINARY_DIR}/drumstick-rt-config-version.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) configure_file( drumstick-rt-config.cmake ${CMAKE_BINARY_DIR}/drumstick-rt-config.cmake @ONLY ) install(FILES ${CMAKE_BINARY_DIR}/drumstick-rt-config-version.cmake ${CMAKE_BINARY_DIR}/drumstick-rt-config.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/drumstick ) drumstick-2.5.1/library/rt/PaxHeaders.27918/backendmanager.cpp0000644000000000000000000000013214200302440020777 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.361324523 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt/backendmanager.cpp0000644000175000001440000002676114200302440021574 0ustar00pedrousers00000000000000/* Drumstick RT (realtime MIDI In/Out) Copyright (C) 2009-2022 Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include /** * @file backendmanager.cpp * Implementation of a class managing realtime MIDI input/output backends */ namespace drumstick { namespace rt { /** * @addtogroup RT * @{ * * BackendManager provides a mechanism to find and enumerate backends (plugins) * to manage realtime MIDI input/output * * This class and plugins are multiplatform. The backends implement one of these * interfaces: * * MIDIInput: for plugins that can receive MIDI events * * MIDIOutput: for plugins that can consume MIDI events * * @} */ class BackendManager::BackendManagerPrivate { public: QList m_inputsList; QList m_outputsList; QString m_inputBackend{QLatin1String("Network")}; #if defined(Q_OS_LINUX) QStringList m_outputBackends{QLatin1String("SonivoxEAS"),QLatin1String("FluidSynth"),QLatin1String("ALSA")}; #elif defined(Q_OS_DARWIN) QStringList m_outputBackends{QLatin1String("DLS Synth"),QLatin1String("FluidSynth"),QLatin1String("CoreMIDI")}; #elif defined(Q_OS_WINDOWS) QStringList m_outputBackends{QLatin1String("Windows MM"),QLatin1String("FluidSynth")}; #elif defined(Q_OS_UNIX) QStringList m_outputBackends{QLatin1String("FluidSynth"),QLatin1String("OSS")}; #else QStringList m_outputBackends{m_inputBackend}; #endif ~BackendManagerPrivate() { clearLists(); } void clearLists() { m_inputsList.clear(); m_outputsList.clear(); } void appendDir(const QString& candidate, QStringList& result) { QDir checked(candidate.trimmed()); //qDebug() << Q_FUNC_INFO << candidate << "exists:" << checked.exists(); if (checked.exists() && !result.contains(checked.absolutePath())) { result << checked.absolutePath(); } } }; /** * @brief Constructor */ BackendManager::BackendManager(): d(new BackendManagerPrivate) { QVariantMap defaultSettings { { QSTR_DRUMSTICKRT_PUBLICNAMEIN, QStringLiteral("MIDI In")}, { QSTR_DRUMSTICKRT_PUBLICNAMEOUT, QStringLiteral("MIDI Out")} }; refresh(defaultSettings); } /** * @brief Destructor */ BackendManager::~BackendManager() { } /** * @brief returns the paths where backends are searched * @return list of paths */ QStringList BackendManager::defaultPaths() { QStringList result; QString appPath = QCoreApplication::applicationDirPath() + QDir::separator(); #if defined(Q_OS_WIN) d->appendDir( appPath + QSTR_DRUMSTICK, result ); d->appendDir( appPath + "../lib/" + QSTR_DRUMSTICK, result ); #else #if defined(Q_OS_MAC) d->appendDir( appPath + QStringLiteral("../PlugIns/") + QSTR_DRUMSTICK, result ); #endif // Linux, Unix... QStringList libs; libs << "../lib/"; #if defined(LIBSUFFIX) libs << QString("../%1/").arg(QT_STRINGIFY(LIBSUFFIX)); #endif foreach(const QString& lib, libs) { d->appendDir( appPath + lib + QSTR_DRUMSTICK, result ); } #endif d->appendDir( appPath + ".." + QDir::separator() + QSTR_DRUMSTICK, result ); QByteArray envdir = qgetenv(QSTR_DRUMSTICKRT.toLatin1()); //qDebug() << Q_FUNC_INFO << "envdir:" << envdir; if(!envdir.isEmpty()) { d->appendDir(QString(envdir), result ); } d->appendDir( QDir::homePath() + QDir::separator() + QSTR_DRUMSTICK, result ); #if QT_VERSION < QT_VERSION_CHECK(6,0,0) d->appendDir( QLibraryInfo::location(QLibraryInfo::PluginsPath) + QDir::separator() + QSTR_DRUMSTICK, result ); #else d->appendDir( QLibraryInfo::path(QLibraryInfo::PluginsPath) + QDir::separator() + QSTR_DRUMSTICK, result ); #endif foreach(const QString& path, QCoreApplication::libraryPaths()) { d->appendDir( path + QDir::separator() + QSTR_DRUMSTICK, result ); } return result; } /** * @brief BackendManager::refresh finds the installed backends applying the provided settings. * @param settings */ void BackendManager::refresh(QSettings *settings) { QVariantMap tmpMap; settings->beginGroup(QSTR_DRUMSTICKRT_GROUP); const QStringList allKeys = settings->allKeys(); //qDebug() << Q_FUNC_INFO << allKeys; for(const auto &k : allKeys) { tmpMap.insert(k, settings->value(k)); } settings->endGroup(); refresh(tmpMap); } /** * @brief BackendManager::refresh finds the installed backends searching the list of paths * provided by the function defaultPaths() applying the provided settings map as well. * @param map */ void BackendManager::refresh(const QVariantMap &map) { QString name_in; QString name_out; QStringList names; QStringList paths; d->appendDir(map.value(QSTR_DRUMSTICKRT_PATH).toString(), paths); name_in = map.value(QSTR_DRUMSTICKRT_PUBLICNAMEIN).toString(); name_out = map.value(QSTR_DRUMSTICKRT_PUBLICNAMEOUT).toString(); names << map.value(QSTR_DRUMSTICKRT_EXCLUDED).toStringList(); names << (name_in.isEmpty() ? QStringLiteral("MIDI In") : name_in); names << (name_out.isEmpty() ? QStringLiteral("MIDI Out") : name_out); paths << defaultPaths(); //qDebug() << Q_FUNC_INFO << "names:" << names; //qDebug() << Q_FUNC_INFO << "paths:" << paths; d->clearLists(); // Dynamic backends foreach(const QString& dir, paths) { QDir pluginsDir(dir); foreach (QString fileName, pluginsDir.entryList(QDir::Files)) { if (QLibrary::isLibrary(fileName)) { QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); QObject *obj = loader.instance(); if (obj != nullptr) { MIDIInput *input = qobject_cast(obj); if (input != nullptr && !d->m_inputsList.contains(input)) { if (!name_in.isEmpty()) { input->setPublicName(name_in); } input->setExcludedConnections(names); d->m_inputsList << input; } else { MIDIOutput *output = qobject_cast(obj); if (output != nullptr && !d->m_outputsList.contains(output)) { if (!name_out.isEmpty()) { output->setPublicName(name_out); } output->setExcludedConnections(names); d->m_outputsList << output; } } } } } } // Static backends foreach(QObject* obj, QPluginLoader::staticInstances()) { if (obj != nullptr) { MIDIInput *input = qobject_cast(obj); if (input != nullptr && !d->m_inputsList.contains(input)) { if (!name_in.isEmpty()) { input->setPublicName(name_in); } input->setExcludedConnections(names); d->m_inputsList << input; } else { MIDIOutput *output = qobject_cast(obj); if (output != nullptr && !d->m_outputsList.contains(output)) { if (!name_out.isEmpty()) { output->setPublicName(name_out); } output->setExcludedConnections(names); d->m_outputsList << output; } } } } } QList BackendManager::availableInputs() { return d->m_inputsList; } QList BackendManager::availableOutputs() { return d->m_outputsList; } MIDIInput* BackendManager::inputBackendByName(const QString name) { foreach (MIDIInput* i, d->m_inputsList) { if (i->backendName() == name) { return i; } } return nullptr; } MIDIOutput* BackendManager::outputBackendByName(const QString name) { foreach (MIDIOutput* i, d->m_outputsList) { if (i->backendName() == name) { return i; } } return nullptr; } MIDIInput* BackendManager::findInput(QString name) { QStringList names{name}; names << d->m_inputBackend; names.removeDuplicates(); if (!names.isEmpty()) { foreach(const QString& n, names) { foreach(MIDIInput* input, d->m_inputsList) { if (input->backendName() == n) { return input; } } } } return nullptr; } MIDIOutput* BackendManager::findOutput(QString name) { QStringList names{name}; names << d->m_outputBackends; names.removeDuplicates(); if (!names.isEmpty()) { foreach(const QString& n, names) { foreach(MIDIOutput* output, d->m_outputsList) { if (output->backendName() == n) { return output; } } } } return nullptr; } const QString BackendManager::QSTR_DRUMSTICK = QStringLiteral("drumstick2"); const QString BackendManager::QSTR_DRUMSTICK_VERSION = QStringLiteral(QT_STRINGIFY(VERSION)); const QString BackendManager::QSTR_DRUMSTICKRT = QStringLiteral("DRUMSTICKRT"); const QString BackendManager::QSTR_DRUMSTICKRT_GROUP = QStringLiteral("DrumstickRT"); const QString BackendManager::QSTR_DRUMSTICKRT_PUBLICNAMEIN = QStringLiteral("PublicNameIN"); const QString BackendManager::QSTR_DRUMSTICKRT_PUBLICNAMEOUT = QStringLiteral("PublicNameOUT"); const QString BackendManager::QSTR_DRUMSTICKRT_EXCLUDED = QStringLiteral("ExcludedNames"); const QString BackendManager::QSTR_DRUMSTICKRT_PATH = QStringLiteral("BackendsPath"); /** * @brief drumstickLibraryVersion provides the Drumstick version as an edited QString * @return Drumstick library version */ QString drumstickLibraryVersion() { return BackendManager::QSTR_DRUMSTICK_VERSION; } } // namespace rt } // namespace drumstick drumstick-2.5.1/library/rt/PaxHeaders.27918/drumstick-rt-config.cmake0000644000000000000000000000013214200302440022246 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.361324523 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt/drumstick-rt-config.cmake0000644000175000001440000000014114200302440023023 0ustar00pedrousers00000000000000#include(CMakeFindDependencyMacro) include(${CMAKE_CURRENT_LIST_DIR}/drumstick-rt-targets.cmake) drumstick-2.5.1/library/rt/PaxHeaders.27918/rt.pro0000644000000000000000000000013214200302440016520 xustar0030 mtime=1644266784.821324179 30 atime=1644266785.361324523 30 ctime=1644266784.821324179 drumstick-2.5.1/library/rt/rt.pro0000644000175000001440000000203314200302440017277 0ustar00pedrousers00000000000000TEMPLATE = lib TARGET = drumstick-rt DESTDIR = ../../build/lib DEPENDPATH += . ../include INCLUDEPATH += . ../include include (../../global.pri) CONFIG += c++11 qt create_pc create_prl no_install_prl static { CONFIG += staticlib } DEFINES += drumstick_rt_EXPORTS QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_HIDESYMS QMAKE_PKGCONFIG_PREFIX = $$INSTALLBASE QT -= gui # Input HEADERS += \ ../include/drumstick/rtmidiinput.h \ ../include/drumstick/rtmidioutput.h \ ../include/drumstick/backendmanager.h \ ../include/drumstick/macros.h SOURCES += \ backendmanager.cpp macx:!static { TARGET = drumstick-rt CONFIG += lib_bundle FRAMEWORK_HEADERS.version = Versions FRAMEWORK_HEADERS.files = $$HEADERS FRAMEWORK_HEADERS.path = Headers/drumstick QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS #QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/ QMAKE_SONAME_PREFIX = @rpath QMAKE_TARGET_BUNDLE_PREFIX = net.sourceforge QMAKE_BUNDLE = drumstick-rt QMAKE_INFO_PLIST = ../Info.plist.lib } drumstick-2.5.1/library/PaxHeaders.27918/file0000644000000000000000000000013214200302440015566 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/file/0000755000175000001440000000000014200302440016424 5ustar00pedrousers00000000000000drumstick-2.5.1/library/file/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020403 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/file/CMakeLists.txt0000644000175000001440000001017214200302440021165 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR ON) set(drumstick-file_QTOBJ_SRCS ../include/drumstick/qsmf.h ../include/drumstick/qwrk.h ../include/drumstick/rmid.h ) set(drumstick-file_HEADERS ../include/drumstick/macros.h ../include/drumstick/qsmf.h ../include/drumstick/qwrk.h ../include/drumstick/rmid.h ) if(BUILD_FRAMEWORKS) set_source_files_properties(${drumstick-file_HEADERS} PROPERTIES MACOSX_PACKAGE_LOCATION Headers/drumstick ) endif() set(drumstick-file_SRCS qsmf.cpp qwrk.cpp rmid.cpp ) if (WIN32) set(TARGET_DESCRIPTION ${Drumstick_DESCRIPTION}) set(TARGET_NAME drumstick-file) set(TARGET_ORIGINAL_FILENAME libdrumstick-file.dll) configure_file(${Drumstick_SOURCE_DIR}/versioninfo.rc.in versioninfo.rc @ONLY) list(APPEND drumstick-file_SRCS versioninfo.rc) endif() if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(drumstick-file_MOC_SRCS ${drumstick-file_QTOBJ_SRCS}) else() qt_wrap_cpp(drumstick-file_MOC_SRCS ${drumstick-file_QTOBJ_SRCS}) endif() add_library(drumstick-file ${drumstick-file_MOC_SRCS} ${drumstick-file_SRCS} ${drumstick-file_HEADERS} ) add_library(Drumstick::File ALIAS drumstick-file) target_include_directories(drumstick-file PUBLIC $ $ ) target_link_libraries(drumstick-file PRIVATE Qt${QT_VERSION_MAJOR}::Core ) if (QT_VERSION VERSION_GREATER_EQUAL 6.0) target_link_libraries(drumstick-file PRIVATE Qt6::Core5Compat ) endif() if(STATIC_DRUMSTICK) set_target_properties(drumstick-file PROPERTIES STATIC_LIB "libdrumstick-file") else() set_target_properties(drumstick-file PROPERTIES VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} SOVERSION ${PROJECT_VERSION_MAJOR} MACOSX_RPATH TRUE EXPORT_NAME File ) if(BUILD_FRAMEWORKS) set_target_properties(drumstick-file PROPERTIES FRAMEWORK ${BUILD_FRAMEWORKS} FRAMEWORK_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} MACOSX_FRAMEWORK_IDENTIFIER "net.sourceforge.drumstick-file" MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_SOURCE_DIR}/cmake_admin/CustomFrameworkInfo.plist.in" ) endif() endif() install(TARGETS drumstick-file EXPORT drumstick-file-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install(FILES ${drumstick-file_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/drumstick) install(EXPORT drumstick-file-targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/drumstick NAMESPACE Drumstick:: ) export(EXPORT drumstick-file-targets NAMESPACE Drumstick:: FILE ${CMAKE_BINARY_DIR}/drumstick-file-targets.cmake ) include(CMakePackageConfigHelpers) write_basic_package_version_file(${CMAKE_BINARY_DIR}/drumstick-file-config-version.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) configure_file( drumstick-file-config.cmake ${CMAKE_BINARY_DIR}/drumstick-file-config.cmake @ONLY ) install(FILES ${CMAKE_BINARY_DIR}/drumstick-file-config-version.cmake ${CMAKE_BINARY_DIR}/drumstick-file-config.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/drumstick ) drumstick-2.5.1/library/file/PaxHeaders.27918/file.pro0000644000000000000000000000013214200302440017304 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/file/file.pro0000644000175000001440000000212514200302440020065 0ustar00pedrousers00000000000000TEMPLATE = lib TARGET = drumstick-file DESTDIR = ../../build/lib DEPENDPATH += . ../include INCLUDEPATH += . ../include include (../../global.pri) CONFIG += c++11 qt create_pc create_prl no_install_prl DEFINES += drumstick_file_EXPORTS QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_HIDESYMS QMAKE_PKGCONFIG_PREFIX = $$INSTALLBASE QT -= gui # Input HEADERS += ../include/drumstick/macros.h \ ../include/drumstick/rmid.h \ ../include/drumstick/qsmf.h \ ../include/drumstick/qwrk.h SOURCES += rmid.cpp \ qsmf.cpp \ qwrk.cpp static { CONFIG += staticlib DEFINES += DRUMSTICK_STATIC } macx:!static { TARGET = drumstick-file CONFIG += lib_bundle FRAMEWORK_HEADERS.version = Versions FRAMEWORK_HEADERS.files = $$HEADERS FRAMEWORK_HEADERS.path = Headers/drumstick QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS #QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/ QMAKE_SONAME_PREFIX = @rpath QMAKE_TARGET_BUNDLE_PREFIX = net.sourceforge QMAKE_BUNDLE = drumstick-file QMAKE_INFO_PLIST = ../Info.plist.lib } drumstick-2.5.1/library/file/PaxHeaders.27918/qwrk.cpp0000644000000000000000000000013214200302440017333 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/file/qwrk.cpp0000644000175000001440000010442114200302440020116 0ustar00pedrousers00000000000000/* WRK File component Copyright (C) 2010-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include DISABLE_WARNING_PUSH DISABLE_WARNING_DEPRECATED_DECLARATIONS /** * @file qwrk.cpp * Implementation of a class managing Cakewalk WRK Files input */ namespace drumstick { namespace File { /** * @addtogroup WRK * @{ * * QWrk provides a mechanism to parse Cakewalk WRK Files, without * the burden of a policy forcing to use some internal sequence representation. * * This class is not related or based on the ALSA library. * * @} */ class QWrk::QWrkPrivate { public: QWrkPrivate(): m_Now(0), m_From(0), m_Thru(11930), m_KeySig(0), m_Clock(0), m_AutoSave(0), m_PlayDelay(0), m_ZeroCtrls(false), m_SendSPP(true), m_SendCont(true), m_PatchSearch(false), m_AutoStop(false), m_StopTime(4294967295U), m_AutoRewind(false), m_RewindTime(0), m_MetroPlay(false), m_MetroRecord(true), m_MetroAccent(false), m_CountIn(1), m_ThruOn(true), m_AutoRestart(false), m_CurTempoOfs(1), m_TempoOfs1(32), m_TempoOfs2(64), m_TempoOfs3(128), m_PunchEnabled(false), m_PunchInTime(0), m_PunchOutTime(0), m_EndAllTime(0), m_division(120), m_codec(nullptr), m_IOStream(nullptr) { } quint32 m_Now; ///< Now marker time quint32 m_From; ///< From marker time quint32 m_Thru; ///< Thru marker time quint8 m_KeySig; ///< Key signature (0=C, 1=C#, ... 11=B) quint8 m_Clock; ///< Clock Source (0=Int, 1=MIDI, 2=FSK, 3=SMPTE) quint8 m_AutoSave; ///< Auto save (0=disabled, 1..256=minutes) quint8 m_PlayDelay; ///< Play Delay bool m_ZeroCtrls; ///< Zero continuous controllers? bool m_SendSPP; ///< Send Song Position Pointer? bool m_SendCont; ///< Send MIDI Continue? bool m_PatchSearch; ///< Patch/controller search-back? bool m_AutoStop; ///< Auto-stop? quint32 m_StopTime; ///< Auto-stop time bool m_AutoRewind; ///< Auto-rewind? quint32 m_RewindTime; ///< Auto-rewind time bool m_MetroPlay; ///< Metronome on during playback? bool m_MetroRecord; ///< Metronome on during recording? bool m_MetroAccent; ///< Metronome accents primary beats? quint8 m_CountIn; ///< Measures of count-in (0=no count-in) bool m_ThruOn; ///< MIDI Thru enabled? (only used if no THRU rec) bool m_AutoRestart; ///< Auto-restart? quint8 m_CurTempoOfs; ///< Which of the 3 tempo offsets is used: 0..2 quint8 m_TempoOfs1; ///< Fixed-point ratio value of offset 1 quint8 m_TempoOfs2; ///< Fixed-point ratio value of offset 2 quint8 m_TempoOfs3; ///< Fixed-point ratio value of offset 3 bool m_PunchEnabled; ///< Auto-Punch enabled? quint32 m_PunchInTime; ///< Punch-in time quint32 m_PunchOutTime; ///< Punch-out time quint32 m_EndAllTime; ///< Time of latest event (incl. all tracks) int m_division; QTextCodec *m_codec; QDataStream *m_IOStream; QByteArray m_lastChunkData; QList m_tempos; qint64 m_lastChunkPos; qint64 internalFilePos(); }; /** * Constructor * @param parent Object owner */ QWrk::QWrk(QObject * parent) : QObject(parent), d(new QWrkPrivate) { } /** * Destructor */ QWrk::~QWrk() { } /** * Gets the text codec used for text meta-events I/O. * * @return QTextCodec pointer * @deprecated because the class QTextCodec was removed from QtCore since Qt6. */ QTextCodec* QWrk::getTextCodec() { return d->m_codec; } /** * Sets the text codec for text meta-events. * The engine doesn't take ownership of the codec instance. * * @param codec QTextCodec pointer * @deprecated because the class QTextCodec was removed from QtCore since Qt6. */ void QWrk::setTextCodec(QTextCodec *codec) { d->m_codec = codec; } /** * Gets the last chunk raw data (undecoded) * * @return last chunk raw data */ QByteArray QWrk::getLastChunkRawData() const { return d->m_lastChunkData; } /** * Read the chunk raw data (undecoded) */ void QWrk::readRawData(int size) { if (size > 0) { d->m_lastChunkData = d->m_IOStream->device()->read(size); } else { d->m_lastChunkData.clear(); //qDebug() << Q_FUNC_INFO << "Size error:" << size; } } /** * Now marker time * @return Now marker time */ int QWrk::getNow() const { return d->m_Now; } /** * From marker time * @return From marker time */ int QWrk::getFrom() const { return d->m_From; } /** * Thru marker time * @return Thru marker time */ int QWrk::getThru() const { return d->m_Thru; } /** * Key signature (0=C, 1=C#, ... 11=B) * @return Key signature */ int QWrk::getKeySig() const { return d->m_KeySig; } /** * Clock Source (0=Int, 1=MIDI, 2=FSK, 3=SMPTE) * @return Clock Source */ int QWrk::getClock() const { return d->m_Clock; } /** * Auto save (0=disabled, 1..256=minutes) * @return Auto save */ int QWrk::getAutoSave() const { return d->m_AutoSave; } /** * Play Delay * @return Play Delay */ int QWrk::getPlayDelay() const { return d->m_PlayDelay; } /** * Zero continuous controllers? * @return Zero continuous controllers */ bool QWrk::getZeroCtrls() const { return d->m_ZeroCtrls; } /** * Send Song Position Pointer? * @return Send Song Position Pointer */ bool QWrk::getSendSPP() const { return d->m_SendSPP; } /** * Send MIDI Continue? * @return Send MIDI Continue */ bool QWrk::getSendCont() const { return d->m_SendCont; } /** * Patch/controller search-back? * @return Patch/controller search-back */ bool QWrk::getPatchSearch() const { return d->m_PatchSearch; } /** * Auto-stop? * @return Auto-stop */ bool QWrk::getAutoStop() const { return d->m_AutoStop; } /** * Auto-stop time * @return Auto-stop time */ unsigned int QWrk::getStopTime() const { return d->m_StopTime; } /** * Auto-rewind? * @return Auto-rewind */ bool QWrk::getAutoRewind() const { return d->m_AutoRewind; } /** * Auto-rewind time * @return Auto-rewind time */ int QWrk::getRewindTime() const { return d->m_RewindTime; } /** * Metronome on during playback? * @return Metronome on during playback */ bool QWrk::getMetroPlay() const { return d->m_MetroPlay; } /** * Metronome on during recording? * @return Metronome on during recording */ bool QWrk::getMetroRecord() const { return d->m_MetroRecord; } /** * Metronome accents primary beats? * @return Metronome accents primary beats */ bool QWrk::getMetroAccent() const { return d->m_MetroAccent; } /** * Measures of count-in (0=no count-in) * @return Measures of count-in */ int QWrk::getCountIn() const { return d->m_CountIn; } /** * MIDI Thru enabled? (only used if no THRU rec) * @return MIDI Thru enabled */ bool QWrk::getThruOn() const { return d->m_ThruOn; } /** * Auto-restart? * @return Auto-restart */ bool QWrk::getAutoRestart() const { return d->m_AutoRestart; } /** * Which of the 3 tempo offsets is used: 0..2 * @return tempo offset index */ int QWrk::getCurTempoOfs() const { return d->m_CurTempoOfs; } /** * Fixed-point ratio value of tempo offset 1 * * NOTE: The offset ratios are expressed as a numerator in the expression * n/64. To get a ratio from this number, divide the number by 64. To get * this number from a ratio, multiply the ratio by 64. * Examples: * 32 ==> 32/64 = 0.5 * 63 ==> 63/64 = 0.9 * 64 ==> 64/64 = 1.0 * 128 ==> 128/64 = 2.0 * * @return tempo offset 1 */ int QWrk::getTempoOfs1() const { return d->m_TempoOfs1; } /** * Fixed-point ratio value of tempo offset 2 * * NOTE: The offset ratios are expressed as a numerator in the expression * n/64. To get a ratio from this number, divide the number by 64. To get * this number from a ratio, multiply the ratio by 64. * Examples: * 32 ==> 32/64 = 0.5 * 63 ==> 63/64 = 0.9 * 64 ==> 64/64 = 1.0 * 128 ==> 128/64 = 2.0 * * @return tempo offset 2 */ int QWrk::getTempoOfs2() const { return d->m_TempoOfs2; } /** * Fixed-point ratio value of tempo offset 3 * * NOTE: The offset ratios are expressed as a numerator in the expression * n/64. To get a ratio from this number, divide the number by 64. To get * this number from a ratio, multiply the ratio by 64. * Examples: * 32 ==> 32/64 = 0.5 * 63 ==> 63/64 = 0.9 * 64 ==> 64/64 = 1.0 * 128 ==> 128/64 = 2.0 * * @return tempo offset 3 */ int QWrk::getTempoOfs3() const { return d->m_TempoOfs3; } /** * Auto-Punch enabled? * @return Auto-Punch enabled */ bool QWrk::getPunchEnabled() const { return d->m_PunchEnabled; } /** * Punch-in time * @return punch-in time */ int QWrk::getPunchInTime() const { return d->m_PunchInTime; } /** * Punch-out time * @return Punch-out time */ int QWrk::getPunchOutTime() const { return d->m_PunchOutTime; } /** * Time of latest event (incl. all tracks) * @return Time of latest event */ int QWrk::getEndAllTime() const { return d->m_EndAllTime; } /** * Gets a single byte from the stream * @return A Single byte */ quint8 QWrk::readByte() { quint8 b = 0xff; if (!d->m_IOStream->atEnd()) *d->m_IOStream >> b; return b; } /** * Converts two bytes into a single 16-bit value * @param c1 first byte * @param c2 second byte * @return 16-bit value */ quint16 QWrk::to16bit(quint8 c1, quint8 c2) { quint16 value = (c1 << 8); value += c2; return value; } /** * Converts four bytes into a single 32-bit value * @param c1 1st byte * @param c2 2nd byte * @param c3 3rd byte * @param c4 4th byte * @return 32-bit value */ quint32 QWrk::to32bit(quint8 c1, quint8 c2, quint8 c3, quint8 c4) { quint32 value = (c1 << 24); value += (c2 << 16); value += (c3 << 8); value += c4; return value; } /** * Reads a 16-bit value * @return 16-bit value */ quint16 QWrk::read16bit() { quint8 c1, c2; c1 = readByte(); c2 = readByte(); return to16bit(c2, c1); } /** * Reads a 24-bit value * @return 32-bit value */ quint32 QWrk::read24bit() { quint8 c1, c2, c3; c1 = readByte(); c2 = readByte(); c3 = readByte(); return to32bit(0, c3, c2, c1); } /** * Reads a 32-bit value * @return 32-bit value */ quint32 QWrk::read32bit() { quint8 c1, c2, c3, c4; c1 = readByte(); c2 = readByte(); c3 = readByte(); c4 = readByte(); return to32bit(c4, c3, c2, c1); } /** * Reads a string assuming local encoding if getTextCodec() is null * @return a string */ QString QWrk::readString(int len) { QString s; if ( len > 0 ) { QByteArray data = readByteArray(len); if (d->m_codec == nullptr) { s = QString::fromLatin1(data); } else { s = d->m_codec->toUnicode(data); } } return s; } /** * Reads a string as a QByteArray (without decoding) * @return a string */ QByteArray QWrk::readByteArray(int len) { QByteArray data; if ( len > 0 ) { quint8 c = 0xff; for ( int i = 0; i < len && c != 0 && !atEnd(); ++i ) { c = readByte(); if ( c != 0) data += c; } } return data; } /** * Reads a variable length string (C-style) * (assuming local encoding if getTextCodec() is null) * @return a string */ QString QWrk::readVarString() { QString s; QByteArray data = readVarByteArray(); if (d->m_codec == nullptr) { s = QString::fromLatin1(data); } else { s = d->m_codec->toUnicode(data); } return s; } /** * Reads a variable length string (C-style) as a QByteArray (without decoding) * @return a string */ QByteArray QWrk::readVarByteArray() { QByteArray data; quint8 b; do { b = readByte(); if (b != 0) data += b; } while (b != 0 && !atEnd()); return data; } void QWrk::processMarkers() { int num = read32bit(); for (int i = 0; (i < num) && (d->internalFilePos() < d->m_lastChunkPos) && !atEnd(); ++i) { int smpte = readByte(); readGap(1); long time = read24bit(); readGap(5); int len = readByte(); if (d->m_codec == nullptr) { QByteArray data = readByteArray(len); Q_EMIT signalWRKMarker2(time, smpte, data); } else { QString name = readString(len); Q_EMIT signalWRKMarker(time, smpte, name); } } } /** * Current position in the data stream * @return current position */ long QWrk::getFilePos() { return d->internalFilePos(); } /** * Seeks to a new position in the data stream * @param pos new position */ void QWrk::seek(qint64 pos) { if (!d->m_IOStream->device()->seek(pos)) { //qDebug() << Q_FUNC_INFO << "Error, pos:" << pos; } } /** * Checks if the data stream pointer has reached the end position * @return true if the read pointer is at end */ bool QWrk::atEnd() { return d->m_IOStream->atEnd(); } /** * Jumps the given size in the data stream * @param size the gap size */ void QWrk::readGap(int size) { if ( size > 0) seek( d->internalFilePos() + size ); } /** * Reads a stream. * @param stream Pointer to an existing and opened stream */ void QWrk::readFromStream(QDataStream *stream) { d->m_IOStream = stream; wrkRead(); } /** * Reads a stream from a disk file. * @param fileName Name of an existing file. */ void QWrk::readFromFile(const QString& fileName) { QFile file(fileName); file.open(QIODevice::ReadOnly); QDataStream ds(&file); readFromStream(&ds); file.close(); } void QWrk::processTrackChunk() { int namelen; QString name[2]; QByteArray data[2]; int trackno; int channel; int pitch; int velocity; int port; bool selected; bool muted; bool loop; trackno = read16bit(); for(int i=0; i<2; ++i) { namelen = readByte(); if (d->m_codec == nullptr) { data[i] = readByteArray(namelen); } else { name[i] = readString(namelen); } } channel = readByte() & 0x0f; pitch = readByte(); velocity = readByte(); port = readByte(); quint8 flags = readByte(); selected = ((flags & 1) != 0); muted = ((flags & 2) != 0); loop = ((flags & 4) != 0); if (d->m_codec == nullptr) { Q_EMIT signalWRKTrack2( data[0], data[1], trackno, channel, pitch, velocity, port, selected, muted, loop ); } else { Q_EMIT signalWRKTrack( name[0], name[1], trackno, channel, pitch, velocity, port, selected, muted, loop ); } } void QWrk::processVarsChunk() { d->m_Now = read32bit(); d->m_From = read32bit(); d->m_Thru = read32bit(); d->m_KeySig = readByte(); d->m_Clock = readByte(); d->m_AutoSave = readByte(); d->m_PlayDelay = readByte(); readGap(1); d->m_ZeroCtrls = (readByte() != 0); d->m_SendSPP = (readByte() != 0); d->m_SendCont = (readByte() != 0); d->m_PatchSearch = (readByte() != 0); d->m_AutoStop = (readByte() != 0); d->m_StopTime = read32bit(); d->m_AutoRewind = (readByte() != 0); d->m_RewindTime = read32bit(); d->m_MetroPlay = (readByte() != 0); d->m_MetroRecord = (readByte() != 0); d->m_MetroAccent = (readByte() != 0); d->m_CountIn = readByte(); readGap(2); d->m_ThruOn = (readByte() != 0); readGap(19); d->m_AutoRestart = (readByte() != 0); d->m_CurTempoOfs = readByte(); d->m_TempoOfs1 = readByte(); d->m_TempoOfs2 = readByte(); d->m_TempoOfs3 = readByte(); readGap(2); d->m_PunchEnabled = (readByte() != 0); d->m_PunchInTime = read32bit(); d->m_PunchOutTime = read32bit(); d->m_EndAllTime = read32bit(); Q_EMIT signalWRKGlobalVars(); } void QWrk::processTimebaseChunk() { quint16 timebase = read16bit(); d->m_division = timebase; Q_EMIT signalWRKTimeBase(timebase); } void QWrk::processNoteArray(int track, int events) { quint32 time = 0; quint8 status = 0, data1 = 0, data2 = 0, i = 0; quint16 dur = 0; int value = 0, type = 0, channel = 0, len = 0; QString text; QByteArray data; for ( i = 0; (i < events) && (d->internalFilePos() < d->m_lastChunkPos) && !atEnd(); ++i ) { time = read24bit(); status = readByte(); dur = 0; if (status >= 0x90) { type = status & 0xf0; channel = status & 0x0f; data1 = readByte(); if (type == 0x90 || type == 0xA0 || type == 0xB0 || type == 0xE0) data2 = readByte(); if (type == 0x90) dur = read16bit(); switch (type) { case 0x90: Q_EMIT signalWRKNote(track, time, channel, data1, data2, dur); break; case 0xA0: Q_EMIT signalWRKKeyPress(track, time, channel, data1, data2); break; case 0xB0: Q_EMIT signalWRKCtlChange(track, time, channel, data1, data2); break; case 0xC0: Q_EMIT signalWRKProgram(track, time, channel, data1); break; case 0xD0: Q_EMIT signalWRKChanPress(track, time, channel, data1); break; case 0xE0: value = (data2 << 7) + data1 - 8192; Q_EMIT signalWRKPitchBend(track, time, channel, value); break; case 0xF0: Q_EMIT signalWRKSysexEvent(track, time, data1); break; } } else if (status == 5) { int code = read16bit(); len = read32bit(); if (d->m_codec == nullptr) { data = readByteArray(len); Q_EMIT signalWRKExpression2(track, time, code, data); } else { text = readString(len); Q_EMIT signalWRKExpression(track, time, code, text); } } else if (status == 6) { int code = read16bit(); dur = read16bit(); readGap(4); Q_EMIT signalWRKHairpin(track, time, code, dur); } else if (status == 7) { len = read32bit(); text = readString(len); data.clear(); for(int j=0; j<13; ++j) { int byte = readByte(); data += byte; } Q_EMIT signalWRKChord(track, time, text, data); } else if (status == 8) { len = read16bit(); data.clear(); for(int j=0; jm_codec == nullptr) { data = readByteArray(len); Q_EMIT signalWRKText2(track, time, status, data); } else { text = readString(len); Q_EMIT signalWRKText(track, time, status, text); } } } if ((i < events) && atEnd()) { Q_EMIT signalWRKError("Corrupted file"); } Q_EMIT signalWRKStreamEnd(time + dur); } void QWrk::processStreamChunk() { long time = 0; int dur = 0, value = 0, type = 0, channel = 0, i = 0; quint8 status = 0, data1 = 0, data2 = 0; quint16 track = read16bit(); int events = read16bit(); for ( i = 0; (i < events) && (d->internalFilePos() < d->m_lastChunkPos) && !atEnd(); ++i ) { time = read24bit(); status = readByte(); data1 = readByte(); data2 = readByte(); dur = read16bit(); type = status & 0xf0; channel = status & 0x0f; switch (type) { case 0x90: Q_EMIT signalWRKNote(track, time, channel, data1, data2, dur); break; case 0xA0: Q_EMIT signalWRKKeyPress(track, time, channel, data1, data2); break; case 0xB0: Q_EMIT signalWRKCtlChange(track, time, channel, data1, data2); break; case 0xC0: Q_EMIT signalWRKProgram(track, time, channel, data1); break; case 0xD0: Q_EMIT signalWRKChanPress(track, time, channel, data1); break; case 0xE0: value = (data2 << 7) + data1 - 8192; Q_EMIT signalWRKPitchBend(track, time, channel, value); break; case 0xF0: Q_EMIT signalWRKSysexEvent(track, time, data1); break; } } if ((i < events) && atEnd()) { Q_EMIT signalWRKError("Corrupted file"); } Q_EMIT signalWRKStreamEnd(time + dur); } void QWrk::processMeterChunk() { int count = read16bit(); for (int i = 0; i < count; ++i) { readGap(4); int measure = read16bit(); int num = readByte(); int den = pow(2.0, readByte()); readGap(4); Q_EMIT signalWRKTimeSig(measure, num, den); } } void QWrk::processMeterKeyChunk() { int count = read16bit(); for (int i = 0; i < count; ++i) { int measure = read16bit(); int num = readByte(); int den = pow(2.0, readByte()); qint8 alt = readByte(); Q_EMIT signalWRKTimeSig(measure, num, den); Q_EMIT signalWRKKeySig(measure, alt); } } double QWrk::getRealTime(long ticks) const { double division = 1.0 * d->m_division; RecTempo last; last.time = 0; last.tempo = 100.0; last.seconds = 0.0; if (!d->m_tempos.isEmpty()) { foreach(const RecTempo& rec, d->m_tempos) { if (rec.time >= ticks) break; last = rec; } } return last.seconds + (((ticks - last.time) / division) * (60.0 / last.tempo)); } void QWrk::processTempoChunk(int factor) { double division = 1.0 * d->m_division; int count = read16bit(); RecTempo last, next; for (int i = 0; i < count; ++i) { long time = read32bit(); readGap(4); long tempo = read16bit() * factor; readGap(8); next.time = time; next.tempo = tempo / 100.0; next.seconds = 0.0; last.time = 0; last.tempo = next.tempo; last.seconds = 0.0; if (! d->m_tempos.isEmpty()) { foreach(const RecTempo& rec, d->m_tempos) { if (rec.time >= time) break; last = rec; } next.seconds = last.seconds + (((time - last.time) / division) * (60.0 / last.tempo)); } d->m_tempos.append(next); Q_EMIT signalWRKTempo(time, tempo); } } void QWrk::processSysexChunk() { int j; QString name; QByteArray data; int bank = readByte(); int length = read16bit(); bool autosend = (readByte() != 0); int namelen = readByte(); name = readString(namelen); for(j=0; j> 4; bool autosend = ( (b & 0x0f) != 0); int namelen = readByte(); name = readString(namelen); for(j=0; j127 qint8 channel = readByte(); // -1, 0->15 qint8 keyPlus = readByte(); // 0->127 qint8 velPlus = readByte(); // 0->127 qint8 localPort = readByte(); qint8 mode = readByte(); Q_EMIT signalWRKThru(mode, port, channel, keyPlus, velPlus, localPort); } void QWrk::processTrackOffset() { quint16 track = read16bit(); qint16 offset = read16bit(); Q_EMIT signalWRKTrackOffset(track, offset); } void QWrk::processTrackReps() { quint16 track = read16bit(); quint16 reps = read16bit(); Q_EMIT signalWRKTrackReps(track, reps); } void QWrk::processTrackPatch() { quint16 track = read16bit(); qint8 patch = readByte(); Q_EMIT signalWRKTrackPatch(track, patch); } void QWrk::processTimeFormat() { quint16 fmt = read16bit(); quint16 ofs = read16bit(); Q_EMIT signalWRKTimeFormat(fmt, ofs); } void QWrk::processComments() { int len = read16bit(); if (d->m_codec == nullptr) { QByteArray data = readByteArray(len); Q_EMIT signalWRKComments2(data); } else { QString text = readString(len); Q_EMIT signalWRKComments(text); } } void QWrk::processVariableRecord(int max) { int datalen = max - 32; QByteArray data; QString name = readVarString(); readGap(31 - name.length()); for ( int i = 0; i < datalen; ++i ) { data += readByte(); } while (data.endsWith('\0')) { data.chop(1); } Q_EMIT signalWRKVariableRecord(name, data); } void QWrk::processUnknown(int id) { Q_EMIT signalWRKUnknownChunk(id, d->m_lastChunkData); } void QWrk::processNewTrack() { QByteArray data; QString name; qint16 bank = -1; qint16 patch = -1; //qint16 vol = -1; //qint16 pan = -1; qint8 key = -1; qint8 vel = 0; quint8 port = 0; qint8 channel = 0; bool selected = false; bool muted = false; bool loop = false; quint16 track = read16bit(); quint8 len = readByte(); if (d->m_codec == nullptr) { data = readByteArray(len); } else { name = readString(len); } bank = read16bit(); patch = read16bit(); /*vol =*/ read16bit(); /*pan =*/ read16bit(); key = readByte(); vel = readByte(); readGap(7); port = readByte(); channel = readByte(); muted = (readByte() != 0); if (d->m_codec == nullptr) { Q_EMIT signalWRKNewTrack2(data, track, channel, key, vel, port, selected, muted, loop); } else { Q_EMIT signalWRKNewTrack(name, track, channel, key, vel, port, selected, muted, loop); } if (bank > -1) Q_EMIT signalWRKTrackBank(track, bank); if (patch > -1) { if (channel > -1) Q_EMIT signalWRKProgram(track, 0, channel, patch); else Q_EMIT signalWRKTrackPatch(track, patch); } } void QWrk::processSoftVer() { int len = readByte(); QString vers = readString(len); Q_EMIT signalWRKSoftVer(vers); } void QWrk::processTrackName() { int track = read16bit(); int len = readByte(); if (d->m_codec == nullptr) { QByteArray data = readByteArray(len); Q_EMIT signalWRKTrackName2(track, data); } else { QString name = readString(len); Q_EMIT signalWRKTrackName(track, name); } } void QWrk::processStringTable() { if (d->m_codec == nullptr) { QList table; int rows = read16bit(); for (int i = 0; i < rows; ++i) { int len = readByte(); QByteArray name = readByteArray(len); /*int idx =*/ readByte(); table.insert(i, name); } Q_EMIT signalWRKStringTable2(table); } else { QStringList table; int rows = read16bit(); for (int i = 0; i < rows; ++i) { int len = readByte(); QString name = readString(len); /*int idx =*/ readByte(); table.insert(i, name); } Q_EMIT signalWRKStringTable(table); } } void QWrk::processLyricsStream() { quint16 track = read16bit(); int events = read32bit(); processNoteArray(track, events); } void QWrk::processTrackVol() { quint16 track = read16bit(); int vol = read16bit(); Q_EMIT signalWRKTrackVol(track, vol); } void QWrk::processNewTrackOffset() { quint16 track = read16bit(); int offset = read32bit(); Q_EMIT signalWRKTrackOffset(track, offset); } void QWrk::processTrackBank() { quint16 track = read16bit(); int bank = read16bit(); Q_EMIT signalWRKTrackBank(track, bank); } void QWrk::processSegmentChunk() { QString name; QByteArray data; int track = read16bit(); int offset = read32bit(); readGap(8); int len = readByte(); if (d->m_codec == nullptr) { data = readByteArray(len); } else { name = readString(len); } readGap(20); if (d->m_codec == nullptr) { Q_EMIT signalWRKSegment2(track, offset, data); } else { Q_EMIT signalWRKSegment(track, offset, name); } int events = read32bit(); processNoteArray(track, events); } void QWrk::processNewStream() { QString name; QByteArray data; int track = read16bit(); int len = readByte(); if (d->m_codec == nullptr) { data = readByteArray(len); Q_EMIT signalWRKSegment2(track, 0, data); } else { name = readString(len); Q_EMIT signalWRKSegment(track, 0, name); } int events = read32bit(); processNoteArray(track, events); } void QWrk::processEndChunk() { emit signalWRKEnd(); } int QWrk::readChunk() { qint64 start_pos = d->internalFilePos(); int ck = readByte(); if (ck != END_CHUNK) { quint32 ck_len = read32bit(); if (ck_len > d->m_IOStream->device()->bytesAvailable()) { Q_EMIT signalWRKError("Corrupted file"); seek(start_pos); return END_CHUNK; } start_pos = d->internalFilePos(); d->m_lastChunkPos = start_pos + ck_len; readRawData(ck_len); seek(start_pos); switch (ck) { case TRACK_CHUNK: processTrackChunk(); break; case VARS_CHUNK: processVarsChunk(); break; case TIMEBASE_CHUNK: processTimebaseChunk(); break; case STREAM_CHUNK: processStreamChunk(); break; case METER_CHUNK: processMeterChunk(); break; case TEMPO_CHUNK: processTempoChunk(100); break; case NTEMPO_CHUNK: processTempoChunk(); break; case SYSEX_CHUNK: processSysexChunk(); break; case THRU_CHUNK: processThruChunk(); break; case TRKOFFS_CHUNK: processTrackOffset(); break; case TRKREPS_CHUNK: processTrackReps(); break; case TRKPATCH_CHUNK: processTrackPatch(); break; case TIMEFMT_CHUNK: processTimeFormat(); break; case COMMENTS_CHUNK: processComments(); break; case VARIABLE_CHUNK: processVariableRecord(ck_len); break; case NTRACK_CHUNK: processNewTrack(); break; case SOFTVER_CHUNK: processSoftVer(); break; case TRKNAME_CHUNK: processTrackName(); break; case STRTAB_CHUNK: processStringTable(); break; case LYRICS_CHUNK: processLyricsStream(); break; case TRKVOL_CHUNK: processTrackVol(); break; case NTRKOFS_CHUNK: processNewTrackOffset(); break; case TRKBANK_CHUNK: processTrackBank(); break; case METERKEY_CHUNK: processMeterKeyChunk(); break; case SYSEX2_CHUNK: processSysex2Chunk(); break; case NSYSEX_CHUNK: processNewSysexChunk(); break; case SGMNT_CHUNK: processSegmentChunk(); break; case NSTREAM_CHUNK: processNewStream(); break; case MARKERS_CHUNK: processMarkers(); break; default: processUnknown(ck); } if (d->internalFilePos() != d->m_lastChunkPos) { //qDebug() << Q_FUNC_INFO << "Current pos:" << d->internalFilePos() << "should be:" << d->m_lastChunkPos; seek(d->m_lastChunkPos); } } return ck; } void QWrk::wrkRead() { QByteArray hdr(HEADER.length(), ' '); d->m_tempos.clear(); d->m_IOStream->device()->read(hdr.data(), HEADER.length()); if (hdr == HEADER) { int vma, vme; int ck_id; readGap(1); vme = readByte(); vma = readByte(); Q_EMIT signalWRKHeader(vma, vme); do { ck_id = readChunk(); } while ((ck_id != END_CHUNK) && !atEnd()); if (!atEnd()) { //qDebug() << Q_FUNC_INFO << "extra junk past the end at" << d->internalFilePos(); readRawData(d->m_IOStream->device()->bytesAvailable()); processUnknown(ck_id); } processEndChunk(); } else Q_EMIT signalWRKError("Invalid file format"); } qint64 QWrk::QWrkPrivate::internalFilePos() { return m_IOStream->device()->pos(); } const QByteArray QWrk::HEADER = QByteArrayLiteral("CAKEWALK"); } // namespace File } // namespace drumstick DISABLE_WARNING_POP drumstick-2.5.1/library/file/PaxHeaders.27918/rmid.cpp0000644000000000000000000000013214200302440017302 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/file/rmid.cpp0000644000175000001440000001575714200302440020102 0ustar00pedrousers00000000000000/* Standard RIFF MIDI Component Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #define right Qt::right #define left Qt::left #define endl Qt::endl #define hex Qt::hex #define dec Qt::dec #endif /** * @file rmid.cpp * Implementation of a class managing RIFF MIDI Files input */ namespace drumstick { namespace File { /** * @addtogroup RMID * @{ * * Rmidi provides a mechanism to parse RIFF RMID Files, without the burden of a policy forcing to use some internal sequence representation. * * RIFF RMID is a wrapper format for MIDI data, as first specified by Microsoft, and later extended by MIDI.org (an arm of the MIDI Manufacturers Association) to permit the bundling of both MIDI files and Downloadable Sounds (DLS) files. According to Multimedia Programming Interface and Data Specifications 1.0, August 1991.: The 'RMID' format consists of a standard MIDI file enclosed in a RIFF chunk. Enclosing the MIDI file in a 'RIFF' chunk allows the file to be consistently identified; for example, an 'INFO' list can be included in the file. * * This implementation does not yet support embedded DLS data. This format is deprecated in favor of Extensible Music Files (XMF). * * This class is not related or based on the ALSA library. To parse the SMF portion of the format, the QSmf class should be used. * * @see https://www.loc.gov/preservation/digital/formats/fdd/fdd000120.shtml * @see http://web.archive.org/web/20110610135604/http://www.midi.org/about-midi/rp29spec(rmid).pdf * @} */ const quint32 CKID_RIFF = 0x46464952; const quint32 CKID_LIST = 0x5453494c; const quint32 CKID_INFO = 0x4f464e49; const quint32 CKID_RMID = 0x44494d52; const quint32 CKID_data = 0x61746164; const quint32 CKID_DISP = 0x50534944; /** * Constructor * @param parent Object owner */ Rmidi::Rmidi(QObject * parent): QObject(parent) { } /** * Destructor */ Rmidi::~Rmidi() { } /** * Reads a stream from a disk file. * @param fileName Name of an existing file. */ void Rmidi::readFromFile(QString fileName) { //qDebug() << Q_FUNC_INFO << fileName; QFile file(m_fileName = fileName); file.open(QIODevice::ReadOnly); QDataStream ds(&file); readFromStream(&ds); file.close(); } /** * Reads a stream. * @param ds Pointer to an existing and opened input stream */ void Rmidi::readFromStream(QDataStream* ds) { //qDebug() << Q_FUNC_INFO; if (ds != nullptr) { m_stream = ds; m_stream->setByteOrder(QDataStream::LittleEndian); read(); } } QString Rmidi::toString(quint32 ckid) { QByteArray data(reinterpret_cast(&ckid), sizeof(quint32)); return QString::fromLatin1(data); } QByteArray Rmidi::readByteArray(int size) { //qDebug() << Q_FUNC_INFO << size; char *buffer = new char[size]; m_stream->readRawData(buffer, size); QByteArray ba(buffer); delete[] buffer; return ba; } void Rmidi::skip(quint32 cktype, int size) { Q_UNUSED(cktype) //qDebug() << Q_FUNC_INFO << toString(cktype) << size; m_stream->skipRawData(size); } quint32 Rmidi::readExpectedChunk(quint32 cktype) { quint32 chunkType, len = 0; *m_stream >> chunkType; if (chunkType == cktype) { *m_stream >> len; if (len % 2) len++; // alignment to even size /*qDebug() << Q_FUNC_INFO << "Expected:" << toString(chunkType) << "(" << hex << chunkType << ")" << "length:" << dec << len;*/ } /*else { qDebug() << Q_FUNC_INFO << "Expected:" << toString(cktype) << "(" << hex << cktype << ")" << "got instead:" << toString(chunkType) << "(" << hex << chunkType << ")"; }*/ return len; } quint32 Rmidi::readChunk(quint32& chunkType) { quint32 len = 0; *m_stream >> chunkType; *m_stream >> len; if (len % 2) len++; // alignment to even size /*qDebug() << Q_FUNC_INFO << "chunkType:" << toString(chunkType) << "(" << hex << chunkType << ")" << "length:" << dec << len;*/ return len; } quint32 Rmidi::readChunkID() { quint32 chunkID; *m_stream >> chunkID; /*qDebug() << Q_FUNC_INFO << "chunkID:" << toString(chunkID) << "(" << hex << chunkID << ")";*/ return chunkID; } void Rmidi::processINFO(int size) { //qDebug() << Q_FUNC_INFO << size; quint32 chunkID = 0; quint32 length = 0; while ((size > 0) && !m_stream->atEnd()) { length = readChunk(chunkID); size -= 8; size -= length; QString cktype = toString(chunkID); QByteArray data = readByteArray(length); emit signalRiffInfo(cktype, data); } } void Rmidi::processList(int size) { //qDebug() << Q_FUNC_INFO; quint32 chunkID = 0; if (m_stream->atEnd()) return; chunkID = readChunkID(); size -= 4; switch (chunkID) { case CKID_INFO: processINFO(size); break; default: skip(chunkID, size); } } void Rmidi::processRMID(int size) { //qDebug() << Q_FUNC_INFO << size; quint32 chunkID = 0; int length; while ((size > 0) && !m_stream->atEnd()) { length = readChunk(chunkID); size -= 8; switch (chunkID) { case CKID_data: processData("RMID", length); break; case CKID_LIST: processList(length); break; case CKID_DISP: skip(chunkID, length); break; default: skip(chunkID, length); } size -= length; } } void Rmidi::processData(const QString& dataType, int size) { //qDebug() << Q_FUNC_INFO << size; QByteArray memdata(size, '\0'); m_stream->readRawData(memdata.data(), size); emit signalRiffData(dataType, memdata); } void Rmidi::read() { //qDebug() << Q_FUNC_INFO; quint32 chunkID; quint32 length = readExpectedChunk(CKID_RIFF); if (length > 0) { chunkID = readChunkID(); length -= 4; switch(chunkID) { case CKID_RMID: //qDebug() << "RMI format"; processRMID(length); break; default: qWarning() << "Unsupported format"; skip(chunkID, length); } } } }} // namespace drumstick::File drumstick-2.5.1/library/file/PaxHeaders.27918/qsmf.cpp0000644000000000000000000000013214200302440017315 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/file/qsmf.cpp0000644000175000001440000007126114200302440020105 0ustar00pedrousers00000000000000/* Standard MIDI File component Copyright (C) 2006-2022, Pedro Lopez-Cabanillas Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include DISABLE_WARNING_PUSH DISABLE_WARNING_DEPRECATED_DECLARATIONS /** * @file qsmf.cpp * Implementation of a class managing Standard MIDI Files input/output */ namespace drumstick { namespace File { /** * @addtogroup SMF * @{ * * QSmf provides a mechanism to parse and encode Standard MIDI Files, without * the burden of a policy forcing to use some internal sequence representation. * * This class is not related or based on the ALSA library. * * @} */ class QSmf::QSmfPrivate { public: QSmfPrivate(): m_Interactive(false), m_CurrTime(0), m_RealTime(0), m_DblRealTime(0), m_DblOldRealtime(0), m_Division(96), m_CurrTempo(500000), m_OldCurrTempo(500000), m_OldRealTime(0), m_OldCurrTime(0), m_RevisedTime(0), m_TempoChangeTime(0), m_ToBeRead(0), m_NumBytesWritten(0), m_Tracks(0), m_fileFormat(0), m_LastStatus(0), m_codec(nullptr), m_IOStream(nullptr) { } bool m_Interactive; /**< file and track headers are not required */ quint64 m_CurrTime; /**< current time in delta-time units */ quint64 m_RealTime; /**< current time in 1/16 centisecond-time units */ double m_DblRealTime; /**< as above, floating */ double m_DblOldRealtime; int m_Division; /**< ticks per beat. Default = 96 */ quint64 m_CurrTempo; /**< microseconds per quarter note */ quint64 m_OldCurrTempo; quint64 m_OldRealTime; quint64 m_OldCurrTime; quint64 m_RevisedTime; quint64 m_TempoChangeTime; quint64 m_ToBeRead; quint64 m_NumBytesWritten; int m_Tracks; int m_fileFormat; int m_LastStatus; QTextCodec *m_codec; QDataStream *m_IOStream; QByteArray m_MsgBuff; QList m_TempoList; }; /** * Constructor * @param parent Optional parent object */ QSmf::QSmf(QObject * parent) : QObject(parent), d(new QSmfPrivate) { } /** * Destructor */ QSmf::~QSmf() { d->m_TempoList.clear(); } /** * Check if the SMF stream is positioned at the end. * @return True if the SMF stream is at the end */ bool QSmf::endOfSmf() { return d->m_IOStream->atEnd(); } /** * Gets a single byte from the SMF stream * @return A Single byte */ quint8 QSmf::getByte() { quint8 b = 0; if (!endOfSmf()) { *d->m_IOStream >> b; d->m_ToBeRead--; } return b; } /** * Puts a single byte to the SMF stream * @param value A Single byte */ void QSmf::putByte(quint8 value) { *d->m_IOStream << value; d->m_NumBytesWritten++; } /** * Adds a tempo change to the internal tempo list * @param tempo Tempo in microseconds per quarter * @param time Location in ticks */ void QSmf::addTempo(quint64 tempo, quint64 time) { QSmfRecTempo tempoRec; tempoRec.tempo = tempo; tempoRec.time = time; d->m_TempoList.append(tempoRec); } /** * Reads a SMF header */ void QSmf::readHeader() { d->m_CurrTime = 0; d->m_RealTime = 0; d->m_Division = 96; d->m_CurrTempo = 500000; d->m_OldCurrTempo = 500000; addTempo(d->m_CurrTempo, 0); if (d->m_Interactive) { d->m_fileFormat= 0; d->m_Tracks = 1; d->m_Division = 96; } else { readExpected("MThd"); d->m_ToBeRead = read32bit(); d->m_fileFormat = read16bit(); d->m_Tracks = read16bit(); d->m_Division = read16bit(); } emit signalSMFHeader(d->m_fileFormat, d->m_Tracks, d->m_Division); /* flush any extra stuff, in case the length of header is not */ while ((d->m_ToBeRead > 0) && !endOfSmf()) { getByte(); } if (d->m_ToBeRead > 0) { SMFError("Unexpected end of input"); } } /** * Reads a track chunk */ void QSmf::readTrack() { /* This array is indexed by the high half of a status byte. It's value is either the number of bytes needed (1 or 2) for a channel message, or 0 (meaning it's not a channel message). */ static const quint8 chantype[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 2, 0 }; quint64 lookfor; quint8 c, c1, type; bool sysexcontinue; // 1 if last message was an unfinished SysEx bool running; // 1 when running status used quint8 status; // status value (e.g. 0x90==note-on) int needed; double delta_secs; quint64 delta_ticks, save_time, save_tempo; sysexcontinue = false; status = 0; if (d->m_Interactive) { d->m_ToBeRead = std::numeric_limits::max(); } else { readExpected("MTrk"); d->m_ToBeRead = read32bit(); } d->m_CurrTime = 0; d->m_RealTime = 0; d->m_DblRealTime = 0; d->m_DblOldRealtime = 0; d->m_OldCurrTime = 0; d->m_OldRealTime = 0; d->m_CurrTempo = findTempo(); emit signalSMFTrackStart(); while (!endOfSmf() && (d->m_Interactive || d->m_ToBeRead > 0)) { lookfor = 0; if (d->m_Interactive) { d->m_CurrTime++; } else { delta_ticks = unsigned(readVarLen()); d->m_RevisedTime = d->m_CurrTime; d->m_CurrTime += delta_ticks; while (d->m_RevisedTime < d->m_CurrTime) { save_time = d->m_RevisedTime; save_tempo = d->m_CurrTempo; d->m_CurrTempo = findTempo(); if (d->m_CurrTempo != d->m_OldCurrTempo) { d->m_OldCurrTempo = d->m_CurrTempo; d->m_OldRealTime = d->m_RealTime; if (d->m_RevisedTime != d->m_TempoChangeTime) { d->m_DblOldRealtime = d->m_DblRealTime; d->m_OldCurrTime = save_time; } delta_secs = ticksToSecs(d->m_RevisedTime - d->m_OldCurrTime, quint16(d->m_Division), save_tempo); d->m_DblRealTime = d->m_DblOldRealtime + delta_secs * 1600.0; d->m_RealTime = llround(d->m_DblRealTime); if (d->m_RevisedTime == d->m_TempoChangeTime) { d->m_OldCurrTime = d->m_RevisedTime; d->m_DblOldRealtime = d->m_DblRealTime; } } else { delta_secs = ticksToSecs(d->m_RevisedTime - d->m_OldCurrTime, quint16(d->m_Division), d->m_CurrTempo); d->m_DblRealTime = d->m_DblOldRealtime + delta_secs * 1600.0; d->m_RealTime = llround(d->m_DblRealTime); } } } c = getByte(); if (sysexcontinue && (c != end_of_sysex)) { SMFError("didn't find expected continuation of a SysEx"); } if (c < 0xf8) { if ((c & 0x80) == 0) { if (status == 0) { SMFError("unexpected running status"); } running = true; } else { status = c; running = false; } needed = chantype[status >> 4 & 0x0f]; if (needed != 0) { if (running) { c1 = c; } else { c1 = getByte(); } if (needed > 1) { channelMessage(status, c1, getByte()); } else { channelMessage(status, c1, 0); } continue; } } switch (c) { case meta_event: type = getByte(); lookfor = quint64(readVarLen()); lookfor = d->m_ToBeRead - lookfor; msgInit(); while ((d->m_ToBeRead > lookfor) && !endOfSmf()) { msgAdd(getByte()); } metaEvent(type); break; case system_exclusive: lookfor = quint64(readVarLen()); lookfor = d->m_ToBeRead - lookfor; msgInit(); msgAdd(system_exclusive); while ((d->m_ToBeRead > lookfor) && !endOfSmf()) { c = getByte(); msgAdd(c); } if (c == end_of_sysex) { sysEx(); } else { sysexcontinue = true; } break; case end_of_sysex: lookfor = readVarLen(); lookfor = d->m_ToBeRead - lookfor; if (!sysexcontinue) { msgInit(); } while ((d->m_ToBeRead > lookfor) && !endOfSmf()) { c = getByte(); msgAdd(c); } if (sysexcontinue) { if (c == end_of_sysex) { sysEx(); sysexcontinue = false; } } break; default: badByte(c, d->m_IOStream->device()->pos() - 1); break; } if ((d->m_ToBeRead > lookfor) && endOfSmf()) { SMFError("Unexpected end of input"); } } emit signalSMFTrackEnd(); } /** * Reads a SMF stream. */ void QSmf::SMFRead() { int i; readHeader(); for ( i = d->m_Tracks; (i > 0) && !endOfSmf(); i--) { readTrack(); } } /** * Writes a SMF stream. * * Every MIDI file starts with a header. * In format 1 files, the first track is a tempo map. * The rest of the file is a series of tracks */ void QSmf::SMFWrite() { int i; d->m_LastStatus = 0; writeHeaderChunk(d->m_fileFormat, d->m_Tracks, d->m_Division); d->m_LastStatus = 0; if (d->m_fileFormat == 1) { emit signalSMFWriteTempoTrack(); } for (i = 0; i < d->m_Tracks; ++i) { writeTrackChunk(i); } } /** * Reads a SMF stream. * @param stream Pointer to an existing and opened stream */ void QSmf::readFromStream(QDataStream *stream) { d->m_IOStream = stream; SMFRead(); } /** * Reads a SMF stream from a disk file. * @param fileName Name of an existing file. */ void QSmf::readFromFile(const QString& fileName) { QFile file(fileName); file.open(QIODevice::ReadOnly); QDataStream ds(&file); readFromStream(&ds); file.close(); } /** * Writes a SMF stream * @param stream Pointer to an existing and opened stream */ void QSmf::writeToStream(QDataStream *stream) { d->m_IOStream = stream; SMFWrite(); } /** * Writes a SMF stream to a disk file * @param fileName File name */ void QSmf::writeToFile(const QString& fileName) { QFile file(fileName); file.open(QIODevice::WriteOnly); QDataStream ds(&file); writeToStream(&ds); file.close(); } /** * Writes a SMF header chuck * @param format SMF Format (0/1/2) * @param ntracks Number of tracks * @param division Resolution in ticks per quarter note */ void QSmf::writeHeaderChunk(int format, int ntracks, int division) { write32bit(MThd); write32bit(6); write16bit(quint16(format)); write16bit(quint16(ntracks)); write16bit(quint16(division)); } /** * Writes a track chuck * @param track Number of the track */ void QSmf::writeTrackChunk(int track) { quint32 trkhdr; quint32 trklength; qint64 offset; qint64 place_marker; d->m_LastStatus = 0; trkhdr = MTrk; trklength = 0; offset = d->m_IOStream->device()->pos(); write32bit(trkhdr); write32bit(trklength); d->m_NumBytesWritten = 0; emit signalSMFWriteTrack(track); place_marker = d->m_IOStream->device()->pos(); d->m_IOStream->device()->seek(offset); trklength = d->m_NumBytesWritten; write32bit(trkhdr); write32bit(trklength); d->m_IOStream->device()->seek(place_marker); } /** * Writes a variable length Meta Event * @param deltaTime Time offset in ticks * @param type Meta event type * @param data Message data */ void QSmf::writeMetaEvent(long deltaTime, int type, const QByteArray& data) { writeVarLen(deltaTime); d->m_LastStatus = meta_event; putByte(d->m_LastStatus); putByte(type); writeVarLen(data.size()); foreach(char byte, data) putByte(byte); } /** * Writes a Text Meta Event * @param deltaTime Time offset in ticks * @param type Meta event type * @param data Message text */ void QSmf::writeMetaEvent(long deltaTime, int type, const QString& data) { writeVarLen(deltaTime); putByte(d->m_LastStatus = meta_event); putByte(type); QByteArray lcldata; if (d->m_codec == nullptr) lcldata = data.toLatin1(); else lcldata = d->m_codec->fromUnicode(data); writeVarLen(lcldata.length()); foreach(char byte, lcldata) putByte(byte); } /** * Writes a simple Meta event * @param deltaTime Time offset in ticks * @param type Meta event type * @param data Meta event data * @since 0.2.0 */ void QSmf::writeMetaEvent(long deltaTime, int type, int data) { writeVarLen(deltaTime); putByte(d->m_LastStatus = meta_event); putByte(type); putByte(1); putByte(data); } /** * Writes a simple Meta event * @param deltaTime Time offset in ticks * @param type Meta event type */ void QSmf::writeMetaEvent(long deltaTime, int type) { writeVarLen(deltaTime); putByte(d->m_LastStatus = meta_event); putByte(type); putByte(0); } /** * Writes a variable length MIDI message * @param deltaTime Time offset in ticks * @param type MIDI event type * @param chan MIDI Channel * @param data Message data */ void QSmf::writeMidiEvent(long deltaTime, int type, int chan, const QByteArray& data) { unsigned int i, j, size; quint8 c; writeVarLen(quint64(deltaTime)); if ((type == system_exclusive) || (type == end_of_sysex)) { c = type; d->m_LastStatus = 0; } else { if (chan > 15) { SMFError("error: MIDI channel greater than 16"); } c = type | chan; } if (d->m_LastStatus != c) { d->m_LastStatus = c; putByte(c); } c = quint8(data[0]); if (type == system_exclusive || type == end_of_sysex) { size = data.size(); if (type == c) --size; writeVarLen(size); } j = (c == type ? 1 : 0); for (i = j; i < unsigned(data.size()); ++i) { putByte(quint8(data[i])); } } /** * Writes a MIDI message with a single parameter * @param deltaTime Time offset in ticks * @param type MIDI event type * @param chan MIDI Channel * @param b1 Message parameter */ void QSmf::writeMidiEvent(long deltaTime, int type, int chan, int b1) { quint8 c; writeVarLen(deltaTime); if ((type == system_exclusive) || (type == end_of_sysex)) { SMFError("error: Wrong method for a system exclusive event"); } if (chan > 15) { SMFError("error: MIDI channel greater than 16"); } c = type | chan; if (d->m_LastStatus != c) { d->m_LastStatus = c; putByte(c); } putByte(b1); } /** * Writes a MIDI message with two parameters * @param deltaTime Time offset in ticks * @param type MIDI event type * @param chan MIDI Channel * @param b1 Message parameter 1 * @param b2 Message parameter 2 */ void QSmf::writeMidiEvent(long deltaTime, int type, int chan, int b1, int b2) { quint8 c; writeVarLen(deltaTime); if ((type == system_exclusive) || (type == end_of_sysex)) { SMFError("error: Wrong method for a system exclusive event"); } if (chan > 15) { SMFError("error: MIDI channel greater than 16"); } c = type | chan; if (d->m_LastStatus != c) { d->m_LastStatus = c; putByte(c); } putByte(b1); putByte(b2); } /** * Writes a variable length MIDI message * @param deltaTime Time offset in ticks * @param type MIDI event type * @param len Message length * @param data Message data */ void QSmf::writeMidiEvent(long deltaTime, int type, long len, char* data) { unsigned int i, j, size; quint8 c; writeVarLen(quint64(deltaTime)); if ((type != system_exclusive) && (type != end_of_sysex)) { SMFError("error: type should be system exclusive"); } d->m_LastStatus = 0; c = quint8(type); putByte(c); size = unsigned(len); c = quint8(data[0]); if (c == type) --size; writeVarLen(size); j = (c == type ? 1 : 0); for (i = j; i < unsigned(len); ++i) { putByte(quint8(data[i])); } } /** * Writes a MIDI Sequence number * @param deltaTime Time offset in ticks * @param seqnum Sequence number */ void QSmf::writeSequenceNumber(long deltaTime, int seqnum) { writeVarLen(deltaTime); d->m_LastStatus = meta_event; putByte(d->m_LastStatus); putByte(sequence_number); putByte(2); putByte((seqnum >> 8) & 0xff); putByte(seqnum & 0xff); } /** * Writes a Tempo change message * @param deltaTime Time offset in ticks * @param tempo Tempo in microseconds per quarter note */ void QSmf::writeTempo(long deltaTime, long tempo) { writeVarLen(deltaTime); putByte(d->m_LastStatus = meta_event); putByte(set_tempo); putByte(3); putByte((tempo >> 16) & 0xff); putByte((tempo >> 8) & 0xff); putByte(tempo & 0xff); } /** * Writes a Tempo change message * @param deltaTime Time offset in ticks * @param tempo Tempo expressed in quarter notes per minute */ void QSmf::writeBpmTempo(long deltaTime, int tempo) { long us_tempo = 60000000l / tempo; writeTempo(deltaTime, us_tempo); } /** * Writes a Time Signature message * @param deltaTime Time offset in ticks * @param num Numerator * @param den Denominator (exponent for a power of two) * @param cc Number of MIDI clocks in a metronome click * @param bb Number of notated 32nd notes in 24 MIDI clocks */ void QSmf::writeTimeSignature(long deltaTime, int num, int den, int cc, int bb) { writeVarLen(deltaTime); putByte(d->m_LastStatus = meta_event); putByte(time_signature); putByte(4); putByte(num & 0xff); putByte(den & 0xff); putByte(cc & 0xff); putByte(bb & 0xff); } /** * Writes a key Signature message * @param deltaTime Time offset in ticks * @param tone Number of alterations (positive=sharps, negative=flats) * @param mode Scale mode (0=major, 1=minor) */ void QSmf::writeKeySignature(long deltaTime, int tone, int mode) { writeVarLen(quint64(deltaTime)); putByte(d->m_LastStatus = meta_event); putByte(key_signature); putByte(2); putByte(quint8(tone)); putByte(mode & 0x01); } /** * Writes multi-length bytes * @param value Integer value */ void QSmf::writeVarLen(quint64 value) { quint64 buffer; buffer = value & 0x7f; while ((value >>= 7) > 0) { buffer <<= 8; buffer |= 0x80; buffer += (value & 0x7f); } while (true) { putByte(buffer & 0xff); if (buffer & 0x80) buffer >>= 8; else break; } } /* These routines are used to make sure that the byte order of the various data types remains constant between machines. */ void QSmf::write32bit(quint32 data) { putByte((data >> 24) & 0xff); putByte((data >> 16) & 0xff); putByte((data >> 8) & 0xff); putByte(data & 0xff); } void QSmf::write16bit(quint16 data) { putByte((data >> 8) & 0xff); putByte(data & 0xff); } quint16 QSmf::to16bit(quint8 c1, quint8 c2) { quint16 value; value = quint16(c1 << 8); value += c2; return value; } quint32 QSmf::to32bit(quint8 c1, quint8 c2, quint8 c3, quint8 c4) { quint32 value; value = unsigned(c1 << 24); value += unsigned(c2 << 16); value += unsigned(c3 << 8); value += c4; return value; } quint16 QSmf::read16bit() { quint8 c1, c2; c1 = getByte(); c2 = getByte(); return to16bit(c1, c2); } quint32 QSmf::read32bit() { quint8 c1, c2, c3, c4; c1 = getByte(); c2 = getByte(); c3 = getByte(); c4 = getByte(); return to32bit(c1, c2, c3, c4); } long QSmf::readVarLen() { quint64 value; quint8 c; c = getByte(); value = c; if ((c & 0x80) != 0) { value &= 0x7f; do { c = getByte(); value = (value << 7) + (c & 0x7f); } while ((c & 0x80) != 0); } return long(value); } void QSmf::readExpected(const QString& s) { int j; quint8 b; for (j = 0; j < s.length(); ++j) { b = getByte(); if (QChar(b) != s[j]) { SMFError(QString("Invalid (%1) SMF format at %2").arg(b, 0, 16).arg(d->m_IOStream->device()->pos())); break; } } } quint64 QSmf::findTempo() { quint64 result, old_tempo, new_tempo; QSmfRecTempo rec = d->m_TempoList.last(); old_tempo = d->m_CurrTempo; new_tempo = d->m_CurrTempo; QList::Iterator it; for( it = d->m_TempoList.begin(); it != d->m_TempoList.end(); ++it ) { rec = (*it); if (rec.time <= d->m_CurrTime) { old_tempo = rec.tempo; } new_tempo = rec.tempo; if (rec.time > d->m_RevisedTime) { break; } } if ((rec.time <= d->m_RevisedTime) || (rec.time > d->m_CurrTime)) { d->m_RevisedTime = d->m_CurrTime; result = old_tempo; } else { d->m_RevisedTime = rec.time; d->m_TempoChangeTime = d->m_RevisedTime; result = new_tempo; } return result; } /* This routine converts delta times in ticks into seconds. The else statement is needed because the formula is different for tracks based on notes and tracks based on SMPTE times. */ double QSmf::ticksToSecs(quint64 ticks, quint16 division, quint64 tempo) { double result; double smpte_format; double smpte_resolution; if (division > 0) { result = double(ticks * tempo)/(division * 1000000.0); } else { smpte_format = upperByte(division); smpte_resolution = lowerByte(division); result = double(ticks)/(smpte_format * smpte_resolution * 1000000.0); } return result; } void QSmf::SMFError(const QString& s) { emit signalSMFError(s); } void QSmf::channelMessage(quint8 status, quint8 c1, quint8 c2) { quint8 chan; int k; chan = status & midi_channel_mask; if (c1 > 127) { SMFError(QString("ChannelMessage with bad c1 = %1").arg(c1)); //c1 &= 127; } if (c2 > 127) { SMFError(QString("ChannelMessage with bad c2 = %1").arg(c2)); //c2 &= 127; } switch (status & midi_command_mask) { case note_off: emit signalSMFNoteOff(chan, c1, c2); break; case note_on: emit signalSMFNoteOn(chan, c1, c2); break; case poly_aftertouch: emit signalSMFKeyPress(chan, c1, c2); break; case control_change: emit signalSMFCtlChange(chan, c1, c2); break; case program_chng: emit signalSMFProgram(chan, c1); break; case channel_aftertouch: emit signalSMFChanPress(chan, c1); break; case pitch_wheel: k = c1 + (c2 << 7) - 8192; emit signalSMFPitchBend(chan, k); break; default: SMFError(QString("Invalid MIDI status %1. Unhandled event").arg(status)); break; } } void QSmf::metaEvent(quint8 b) { QSmfRecTempo rec; QByteArray m(d->m_MsgBuff); switch (b) { case sequence_number: emit signalSMFSequenceNum(to16bit(m[0], m[1])); break; case text_event: case copyright_notice: case sequence_name: case instrument_name: case lyric: case marker: case cue_point: { QString s; if (d->m_codec == nullptr) { emit signalSMFText2(b, m); } else { s = d->m_codec->toUnicode(m); emit signalSMFText(b, s); } } break; case forced_channel: emit signalSMFforcedChannel(m[0]); break; case forced_port: emit signalSMFforcedPort(m[0]); break; case end_of_track: emit signalSMFendOfTrack(); break; case set_tempo: d->m_CurrTempo = to32bit(0, m[0], m[1], m[2]); emit signalSMFTempo(d->m_CurrTempo); rec = d->m_TempoList.last(); if (rec.tempo == d->m_CurrTempo) { return; } if (rec.time > d->m_CurrTime) { return; } addTempo(d->m_CurrTempo, d->m_CurrTime); break; case smpte_offset: emit signalSMFSmpte(m[0], m[1], m[2], m[3], m[4]); break; case time_signature: emit signalSMFTimeSig(m[0], m[1], m[2], m[3]); break; case key_signature: emit signalSMFKeySig(m[0], m[1]); break; case sequencer_specific: emit signalSMFSeqSpecific(m); break; default: emit signalSMFMetaUnregistered(b, m); break; } emit signalSMFMetaMisc(b, m); } void QSmf::sysEx() { QByteArray varr(d->m_MsgBuff); emit signalSMFSysex(varr); } void QSmf::badByte(quint8 b, int p) { SMFError(QString("Unexpected byte (%1) at %2").arg(b, 2, 16).arg(p)); } quint8 QSmf::lowerByte(quint16 x) { return (x & 0xff); } quint8 QSmf::upperByte(quint16 x) { return ((x >> 8) & 0xff); } void QSmf::msgInit() { d->m_MsgBuff.truncate(0); } void QSmf::msgAdd(quint8 b) { int s = d->m_MsgBuff.size(); d->m_MsgBuff.resize(s + 1); d->m_MsgBuff[s] = b; } /* public properties (accessors) */ /** * Gets the current time in ticks * @return Time in ticks */ long QSmf::getCurrentTime() { return d->m_CurrTime; } /** * Gets the current tempo * @return Tempo in us per quarter */ long QSmf::getCurrentTempo() { return d->m_CurrTempo; } /** * Gets the real time in seconds * @return Time in seconds */ long QSmf::getRealTime() { return d->m_RealTime; } /** * Gets the resolution * @return Resolution in ticks per quarter note */ int QSmf::getDivision() { return d->m_Division; } /** * Sets the resolution * @param division Resolution in ticks per quarter note */ void QSmf::setDivision(int division) { d->m_Division = division; } /** * Gets the number of tracks * @return Number of tracks */ int QSmf::getTracks() { return d->m_Tracks; } /** * Sets the number of tracks * @param tracks Number of tracks */ void QSmf::setTracks(int tracks) { d->m_Tracks = tracks; } /** * Gets the SMF file format * @return File format (0, 1, or 2) */ int QSmf::getFileFormat() { return d->m_fileFormat; } /** * Sets the SMF file format * @param fileFormat File format (0, 1, or 2) */ void QSmf::setFileFormat(int fileFormat) { d->m_fileFormat = fileFormat; } /** * Gets the position in the SMF stream * @return Position offset in the stream */ long QSmf::getFilePos() { return long(d->m_IOStream->device()->pos()); } /** * Gets the text codec used for text meta-events I/O * @return QTextCodec pointer * @since 0.2.0 * @deprecated because the class QTextCodec was removed from QtCore since Qt6. */ QTextCodec* QSmf::getTextCodec() { return d->m_codec; } /** * Sets the text codec for text meta-events. * The engine doesn't take ownership of the codec instance. * * @param codec QTextCodec pointer * @since 0.2.0 * @deprecated because the class QTextCodec was removed from QtCore since Qt6. */ void QSmf::setTextCodec(QTextCodec *codec) { d->m_codec = codec; } /** * @brief drumstickLibraryVersion provides the Drumstick version as an edited QString * @return Drumstick library version */ QString drumstickLibraryVersion() { return QStringLiteral(QT_STRINGIFY(VERSION)); } } // namespace File } // namespace drumstick DISABLE_WARNING_POP drumstick-2.5.1/library/file/PaxHeaders.27918/drumstick-file-config.cmake0000644000000000000000000000013214200302440023032 xustar0030 mtime=1644266784.825324181 30 atime=1644266785.361324523 30 ctime=1644266784.825324181 drumstick-2.5.1/library/file/drumstick-file-config.cmake0000644000175000001440000000014314200302440023611 0ustar00pedrousers00000000000000#include(CMakeFindDependencyMacro) include(${CMAKE_CURRENT_LIST_DIR}/drumstick-file-targets.cmake) drumstick-2.5.1/library/PaxHeaders.27918/Info.plist.lib0000644000000000000000000000013214200302440017441 xustar0030 mtime=1644266784.789324158 30 atime=1644266785.361324523 30 ctime=1644266784.789324158 drumstick-2.5.1/library/Info.plist.lib0000644000175000001440000000153314200302440020224 0ustar00pedrousers00000000000000 CFBundlePackageType FMWK CFBundleShortVersionString @FULL_VERSION@ CFBundleVersion @FULL_VERSION@ CFBundleGetInfoString Created by Qt/QMake CFBundleSignature @TYPEINFO@ CFBundleExecutable @LIBRARY@ CFBundleIdentifier @BUNDLEIDENTIFIER@ NSHumanReadableCopyright © 2006-2019, Pedro López-Cabanillas and others NOTE Please, do NOT change this file -- It was generated by Qt/QMake. drumstick-2.5.1/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440016020 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.361324523 30 ctime=1644266784.865324206 drumstick-2.5.1/CMakeLists.txt0000644000175000001440000002704614200302440016612 0ustar00pedrousers00000000000000# MIDI C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . cmake_minimum_required(VERSION 3.14) set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment version") project( Drumstick VERSION 2.5.1 LANGUAGES C CXX DESCRIPTION "MIDI C++ Libraries for Qt" HOMEPAGE_URL "https://sourceforge.net/p/drumstick/" ) list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_admin) include(SCMRevision) include(CTest) include(GNUInstallDirs) set(RELEASE_DATE "February 7, 2022") set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # cmake bug https://gitlab.kitware.com/cmake/cmake/issues/18396 closed in cmake 3.14 if(APPLE AND ${CMAKE_VERSION} VERSION_LESS 3.14) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") endif() if (WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") #/source-charset:utf-8 /execution-charset:utf-8 endif() if(UNIX AND NOT APPLE) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic") #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic") #set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--as-needed") #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") #set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--as-needed -Wl,--no-undefined") endif() endif() add_definitions(-DVERSION=${PROJECT_VERSION}) if (DEFINED PROJECT_WC_REVISION) add_definitions(-DREVISION=${PROJECT_WC_REVISION}) endif() if (UNIX) set(_DOCS_INIT ON) else() set(_DOCS_INIT OFF) endif() set(_DBUS_INIT OFF) if (UNIX AND NOT APPLE) set(_PULSE_INIT ON) else () set(_PULSE_INIT OFF) endif () if (APPLE) set(_FRAMEWORKS_INIT ON) else() set(_FRAMEWORKS_INIT OFF) endif() # ALSA Sequencer is only available on Linux if (${CMAKE_SYSTEM} MATCHES "Linux") set(_BUILD_ALSA_INIT ON) else() set(_BUILD_ALSA_INIT OFF) endif() option(BUILD_DOCS "Build Doxygen documentation and man pages" ${_DOCS_INIT}) option(BUILD_UTILS "Build Utilities and Examples" ON) option(BUILD_FRAMEWORKS "Build macOS style frameworks" ${_FRAMEWORKS_INIT}) option(BUILD_ALSA "Build the libdrumstick-alsa library (Linux only)" ${_BUILD_ALSA_INIT}) option(BUILD_FILE "Build the libdrumstick-file library" ON) option(BUILD_RT "Build the libdrumstick-rt library" ON) option(BUILD_WIDGETS "Build the libdrumstick-widgets library" ON) option(STATIC_DRUMSTICK "Build static libraries instead of dynamic" OFF) option(USE_DBUS "Include DBus support (required for RealtimeKit)" ${_DBUS_INIT}) option(USE_PULSEAUDIO "Build Sonivox RT backend (if PulseAudio is available)" ${_PULSE_INIT}) option(USE_FLUIDSYNTH "Build FluidSynth RT backend (if available)" ON) option(USE_NETWORK "Build Network RT backend (if QtNetwork is available)" ON) option(USE_QT "Choose which Qt major version (5 or 6) to prefer. By default uses whatever is found") if (BUILD_WIDGETS AND NOT BUILD_RT) message(FATAL_ERROR "libdrumstick-widgets requires libdrumstick-rt") endif() if(STATIC_DRUMSTICK) set(BUILD_SHARED_LIBS OFF) add_definitions(-DDRUMSTICK_STATIC) message(STATUS "Building static libraries") else() set(BUILD_SHARED_LIBS ON) if (BUILD_FRAMEWORKS) message(STATUS "Building macOS style frameworks") else() message(STATUS "Building unix dynamic libraries") endif() endif() if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.15) set(CMAKE_FRAMEWORK ${BUILD_FRAMEWORKS}) endif() if (USE_QT) if (NOT (USE_QT EQUAL 5 OR USE_QT EQUAL 6)) message(FATAL_ERROR "Wrong Qt major version. Only 5 and 6 are valid options") endif() endif() if (USE_QT EQUAL 5) find_package(QT NAMES Qt5) elseif (USE_QT EQUAL 6) find_package(QT NAMES Qt6) else() find_package(QT NAMES Qt5 Qt6) endif() if (QT_VERSION VERSION_LESS 6.0.0) find_package(Qt5 5.9 COMPONENTS Core REQUIRED) else() if (QT_VERSION VERSION_LESS 6.2.0) message (FATAL_ERROR "Qt6 >= 6.2 is required, or use Qt5 >= 5.9") endif() find_package(Qt6 6.2 COMPONENTS Core REQUIRED) if (BUILD_FILE) find_package(Qt6Core5Compat REQUIRED) endif() endif() message(STATUS "Found Qt version = ${QT_VERSION}") if(BUILD_ALSA AND USE_DBUS) find_package(Qt${QT_VERSION_MAJOR}DBus REQUIRED) add_definitions(-DRTKIT_SUPPORT) message(STATUS "Found QtDBus version = ${Qt${QT_VERSION_MAJOR}DBus_VERSION}") endif() if(BUILD_RT AND USE_NETWORK) find_package(Qt${QT_VERSION_MAJOR}Network REQUIRED) if(Qt${QT_VERSION_MAJOR}Network_FOUND) message(STATUS "Found QtNetwork version = ${Qt${QT_VERSION_MAJOR}Network_VERSION}") else() message(STATUS "Warning: QtNetwork library not available. Network RT backend won't be built.") endif() endif() find_package(PkgConfig REQUIRED) if(PKG_CONFIG_FOUND) message(STATUS "Program pkg-config ${PKG_CONFIG_VERSION_STRING} found (${PKG_CONFIG_EXECUTABLE})") else() message(FATAL_ERROR "Program pkg-config not found") endif() # ALSA Sequencer is only available on Linux if(${CMAKE_SYSTEM} MATCHES "Linux") pkg_check_modules(ALSA REQUIRED IMPORTED_TARGET alsa>=1.0.0) if(ALSA_FOUND) message(STATUS "Found ALSA version = ${ALSA_VERSION}") endif() endif() if (BUILD_ALSA AND NOT ALSA_FOUND) message(FATAL_ERROR "library libdrumstick-alsa requested, but ALSA Sequencer was not found") endif() if(BUILD_RT AND PKG_CONFIG_FOUND AND UNIX AND NOT APPLE) if (USE_PULSEAUDIO) pkg_check_modules(PULSE QUIET IMPORTED_TARGET libpulse-simple) endif() if(PULSE_FOUND) message(STATUS "Found PulseAudio version = ${PULSE_VERSION}") else() message(STATUS "Warning: PulseAudio library not available. Sonivox RT backend won't be built.") endif() endif() if (BUILD_RT AND PKG_CONFIG_FOUND) if (USE_FLUIDSYNTH) pkg_check_modules(FLUIDSYNTH QUIET IMPORTED_TARGET fluidsynth>=1.1.1) endif() if(FLUIDSYNTH_FOUND) message(STATUS "Found FluidSynth version = ${FLUIDSYNTH_VERSION}") else() message(STATUS "Warning: FluidSynth library not available. FluidSynth RT backend won't be built.") endif() endif() if (${CMAKE_SYSTEM} MATCHES "Darwin" AND QT_VERSION VERSION_LESS 6.0.0) find_package(Qt${QT_VERSION_MAJOR}Concurrent REQUIRED) if (Qt${QT_VERSION_MAJOR}Concurrent_FOUND) message(STATUS "Found Qt${QT_VERSION_MAJOR}Concurrent version = ${Qt${QT_VERSION_MAJOR}Concurrent_VERSION_STRING}") endif() endif() # CMAKE_SYSTEM_PROCESSOR is broken on Windows with MSVC # cmake bug https://gitlab.kitware.com/cmake/cmake/-/issues/15170 still open in 2021/03 if (MSVC) string(TOLOWER ${MSVC_CXX_ARCHITECTURE_ID} CMAKE_SYSTEM_PROCESSOR) endif() message (STATUS "${PROJECT_NAME} v${PROJECT_VERSION} Install prefix: ${CMAKE_INSTALL_PREFIX} Build configuration: ${CMAKE_BUILD_TYPE} System: ${CMAKE_SYSTEM_NAME} Processor: ${CMAKE_SYSTEM_PROCESSOR} Qt Version: ${QT_VERSION} D-Bus support: ${USE_DBUS} Network support: ${USE_NETWORK} PulseAudio support: ${USE_PULSEAUDIO} FluidSynth support: ${USE_FLUIDSYNTH} Building libdrumstick-alsa: ${BUILD_ALSA} Building libdrumstick-file: ${BUILD_FILE} Building libdrumstick-rt: ${BUILD_RT} Building libdrumstick-widgets: ${BUILD_WIDGETS} Building tests: ${BUILD_TESTING} Building docs: ${BUILD_DOCS} Building utils: ${BUILD_UTILS} Building frameworks: ${BUILD_FRAMEWORKS}" ) add_subdirectory(library) if (BUILD_UTILS) add_subdirectory(utils) endif() add_subdirectory(icons) if(BUILD_TESTING) add_subdirectory(tests) endif() if(UNIX AND NOT APPLE) if (BUILD_DOCS) find_package(Doxygen REQUIRED dot) if(DOXYGEN_FOUND) string(REPLACE ";" " " DOXYGEN_INCLUDE_DIRS "${Qt${QT_VERSION_MAJOR}Core_INCLUDE_DIRS}") configure_file("${CMAKE_SOURCE_DIR}/Doxyfile.in" "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile" IMMEDIATE @ONLY) add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) endif() add_subdirectory(doc) endif() configure_file(drumstick.spec.in drumstick.spec IMMEDIATE @ONLY) if(ALSA_FOUND AND PKG_CONFIG_FOUND) configure_file(drumstick-alsa.pc.in drumstick-alsa.pc IMMEDIATE @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/drumstick-alsa.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) endif() # XML mime types set( SHARED_MIME_INFO_MINIMUM_VERSION "0.30" ) set( XDG_MIME_INSTALL_DIR "${CMAKE_INSTALL_DATAROOTDIR}/mime/packages" ) find_package( SharedMimeInfo ) if( SHARED_MIME_INFO_FOUND ) install( FILES drumstick.xml DESTINATION ${XDG_MIME_INSTALL_DIR} ) update_xdg_mimetypes( ${XDG_MIME_INSTALL_DIR} ) endif() endif() if(PKG_CONFIG_FOUND) configure_file(drumstick-file.pc.in drumstick-file.pc IMMEDIATE @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/drumstick-file.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) configure_file(drumstick-rt.pc.in drumstick-rt.pc IMMEDIATE @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/drumstick-rt.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) configure_file(drumstick-widgets.pc.in drumstick-widgets.pc IMMEDIATE @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/drumstick-widgets.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) endif() # uninstall custom target configure_file( "${CMAKE_SOURCE_DIR}/cmake_admin/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) add_custom_target( uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") if(UNIX) # tarball target add_custom_target( tarball COMMAND mkdir -p drumstick-${PROJECT_VERSION} COMMAND cp -r cmake_admin drumstick-${PROJECT_VERSION} COMMAND cp -r library drumstick-${PROJECT_VERSION} COMMAND cp -r utils drumstick-${PROJECT_VERSION} COMMAND cp -r doc drumstick-${PROJECT_VERSION} COMMAND cp -r icons drumstick-${PROJECT_VERSION} COMMAND cp -r tests drumstick-${PROJECT_VERSION} COMMAND cp CMakeLists.txt AUTHORS COPYING ChangeLog NEWS TODO *.md drumstick*.in drumstick.pro drumstick.xml configure* Doxyfile.in global.pri versioninfo.rc.in drumstick-${PROJECT_VERSION} COMMAND tar -cj --exclude=.[a-z]* -f drumstick-${PROJECT_VERSION}.tar.bz2 drumstick-${PROJECT_VERSION} COMMAND tar -cz --exclude=.[a-z]* -f drumstick-${PROJECT_VERSION}.tar.gz drumstick-${PROJECT_VERSION} COMMAND zip -qr drumstick-${PROJECT_VERSION}.zip drumstick-${PROJECT_VERSION} -x '.[a-z]*' COMMAND rm -rf drumstick-${PROJECT_VERSION} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) endif() drumstick-2.5.1/PaxHeaders.27918/drumstick-widgets.pc.in0000644000000000000000000000013214200302440017662 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.361324523 30 ctime=1644266784.865324206 drumstick-2.5.1/drumstick-widgets.pc.in0000644000175000001440000000053314200302440020444 0ustar00pedrousers00000000000000prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: drumstick-widgets Version: @PROJECT_VERSION@ Description: MIDI Widgets C++ Library for Qt5 URL: http://sourceforge.net/projects/drumstick Libs: -L${libdir} -ldrumstick-widgets Cflags: -I${includedir} drumstick-2.5.1/PaxHeaders.27918/install.md0000644000000000000000000000013214200302440015250 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.361324523 30 ctime=1644266784.865324206 drumstick-2.5.1/install.md0000644000175000001440000001033314200302440016031 0ustar00pedrousers00000000000000## Basic build commands Using a Linux terminal... ~~~ $ cd drumstick-x.x.x $ mkdir -p build $ cd build $ cmake .. (or ccmake ..) (or cmake-gui ..) (or cmake .. -options, see below...) ~~~ For simple test/development scenarios you can also use Qmake, but the Qmake-based build system provides only minimal functionality. ~~~ $ make (or make VERBOSE=1) $ sudo make install $ sudo ldconfig (not needed if you only want STATIC_DRUMSTICK) ~~~ ## Requirements Minimum supported versions: * CMake 3.14 * Qt5 >= 5.9, Qt6 >= 6.2 When using Qt6, Qt6Core5Compat is required for Drumstick::File * For Linux: ALSA 1.x * RT backends for * Linux: ALSA * macOS: CoreMIDI * Windows: WinMM * Unix: OSS * Synthesizers (output backends): SonivoxEAS, FluidSynth, Apple DLS Synth * All: Network - ipMIDI (IPv4, IPv6) * shared-mime-info 0.30 See http://freedesktop.org/wiki/Software/shared-mime-info The utility "update-mime-database" must be executed after installing the library "drumstick-file" and the "drumstick.xml" file. This is automatically done by the cmake build system unless you defined DESTDIR. In this case, your package manager should perform it as a post-install step. * Doxygen 1.5 See http://www.doxygen.org If you want to generate the HTML documentation for the libraries If you want to generate and install the man pages, the build system can do it if you have installed in your system the following packages: * xsltproc program. * docbook XSLT stylesheets. The package names depend on the Linux distribution. For Debian they are: xsltproc, docbook-xsl and docbook-xml. For openSUSE: libxslt, docbook_4, and docbook-xsl-stylesheets. RealtimeKit actions are called through DBus, so it is not a direct dependency. ## Optional CMake parameters -DSTATIC_DRUMSTICK=YES|ON|1 Build static libraries instead of a shared object -DSTATIC_DRUMSTICK=NO|OFF|0 Build dynamic libraries (default) -DCMAKE_BUILD_TYPE=Debug Compile with debug flags enabled -DCMAKE_BUILD_TYPE=Release Compile without debug flags, and optimization enabled -DCMAKE_CXX_FLAGS="-W -Wall" Specify custom compilation flags -DCMAKE_INSTALL_PREFIX=/usr/local Specify the desired install prefix -DUSE_DBUS=YES|ON|1 Build DBus support, required to use RealtimeKit -DUSE_DBUS=NO|OFF|0 Don't include DBus support (default) -DBUILD_DOCS=YES|ON|1 Build Doxygen documentation and man pages (default in Unix) -DBUILD_DOCS=NO|OFF|0 Don't build Doxygen documentation nor man pages Note: the last option only creates a "doxygen" target. You still need to call the target build if you want to generate the actual documentation. -DBUILD_UTILS=YES|ON|1 Build utilities and example programs (default) -DBUILD_UTILS=NO|OFF|0 Don't build utilities and example programs -DBUILD_TESTING=YES|ON|1 Build unit tests (default) -DBUILD_TESTING=NO|OFF|0 Don't build unit tests -DBUILD_FRAMEWORKS=YES|ON|1 Build macOS style frameworks (default on macOS) -DBUILD_FRAMEWORKS=NO|OFF|0 Don't build macOS style frameworks, build Unix style dynamic libraries (.dylib) -DBUILD_ALSA=YES|ON|1 Build Drumstick::ALSA (default on Linux) -DBUILD_ALSA=NO|OFF|0 Don't build Drumstick::ALSA (default on non Linux Operating Systems) -DBUILD_FILE=YES|ON|1 Build Drumstick::File (default) -DBUILD_FILE=NO|OFF|0 Don't build Drumstick::File -DBUILD_RT=YES|ON|1 Build Drumstick::RT (default) -DBUILD_RT=NO|OFF|0 Don't build Drumstick::RT -DBUILD_WIDGETS=YES|ON|1 Build Drumstick::Widgets (default) -DBUILD_WIDGETS=NO|OFF|0 Don't build Drumstick::Widgets -DUSE_NETWORK=YES|ON|1 Build the ipMIDI Network RT backend (default) -DUSE_NETWORK=NO|OFF|0 Don't build the ipMIDI Network RT backend -DUSE_PULSEAUDIO=YES|ON|1 Build the SonivoxEAS RT output backend (default) -DUSE_PULSEAUDIO=NO|OFF|0 Don't build the SonivoxEAS RT output backend Note: FluidSynth has also a PulseAudio driver, which is independent of the last option -DUSE_FLUIDSYNTH=YES|ON|1 Build the FluidSynth RT output backend (default) -DUSE_FLUIDSYNTH=NO|OFF|0 Don't build the FluidSynth RT output backend -DUSE_QT=5|6 Choose which Qt major version (5 or 6) to prefer. By default (if not set) uses whatever is found. notes: Qt6 support is still experimental. When using Qt6, the Core5Compat additional library is required for Drumstick::File drumstick-2.5.1/PaxHeaders.27918/drumstick-alsa.pc.in0000644000000000000000000000013214200302440017134 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.361324523 30 ctime=1644266784.865324206 drumstick-2.5.1/drumstick-alsa.pc.in0000644000175000001440000000055114200302440017716 0ustar00pedrousers00000000000000prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: drumstick-alsa Version: @PROJECT_VERSION@ Description: MIDI Sequencer C++ Library Bindings for ALSA and Qt5 URL: http://sourceforge.net/projects/drumstick Libs: -L${libdir} -ldrumstick-alsa Cflags: -I${includedir} drumstick-2.5.1/PaxHeaders.27918/versioninfo.rc.in0000644000000000000000000000013214200302440016554 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.361324523 30 ctime=1644266784.865324206 drumstick-2.5.1/versioninfo.rc.in0000644000175000001440000000234514200302440017341 0ustar00pedrousers00000000000000IDI_ICON1 ICON DISCARDABLE "@Drumstick_SOURCE_DIR@/icons/drumstick.ico" 1 VERSIONINFO FILEVERSION @PROJECT_VERSION_MAJOR@, @PROJECT_VERSION_MINOR@, @PROJECT_VERSION_PATCH@ PRODUCTVERSION @PROJECT_VERSION_MAJOR@, @PROJECT_VERSION_MINOR@, @PROJECT_VERSION_PATCH@, 0 FILEOS 4 // VOS__WINDOWS32 FILETYPE 1 // VFT_APP BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "CompanyName", "Drumstick" VALUE "FileDescription", "@TARGET_DESCRIPTION@" VALUE "FileVersion", "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@" VALUE "Full Version", "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@.0" VALUE "InternalName", "@TARGET_NAME@" VALUE "LegalCopyright", "Copyright \251 2005-2021, Pedro Lopez-Cabanillas. Licensed under the terms of the GPL v3 or later." VALUE "OriginalFilename", "@TARGET_ORIGINAL_FILENAME@" VALUE "ProductName", "@TARGET_NAME@" VALUE "ProductVersion", "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x0409, 1200 // U.S. English END END drumstick-2.5.1/PaxHeaders.27918/configure0000644000000000000000000000013214200302440015164 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.361324523 30 ctime=1644266784.865324206 drumstick-2.5.1/configure0000755000175000001440000000035314200302440015751 0ustar00pedrousers00000000000000#!/bin/bash # a typical configuration for production usage... mkdir -p build cd build cmake .. -DCMAKE_CXX_FLAGS="-W -Wall" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr/local \ -DSTATIC_DRUMSTICK=NO \ -DUSE_DBUS=YES drumstick-2.5.1/PaxHeaders.27918/tests0000644000000000000000000000013214200302440014345 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/0000755000175000001440000000000014200302440015203 5ustar00pedrousers00000000000000drumstick-2.5.1/tests/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440017162 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/CMakeLists.txt0000644000175000001440000000223514200302440017745 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . find_package(Qt${QT_VERSION_MAJOR}Test REQUIRED) set (CMAKE_AUTOMOC ON) enable_testing() if (BUILD_ALSA AND ALSA_FOUND) add_subdirectory(alsaTest1) add_subdirectory(alsaTest2) endif() if (BUILD_FILE) add_subdirectory(fileTest1) add_subdirectory(fileTest2) add_subdirectory(fileTest3) endif() if (BUILD_RT) add_subdirectory(rtTest) if(BUILD_WIDGETS) add_subdirectory(widgetsTest) endif() endif() drumstick-2.5.1/tests/PaxHeaders.27918/fileTest20000644000000000000000000000013214200302440016206 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest2/0000755000175000001440000000000014200302440017044 5ustar00pedrousers00000000000000drumstick-2.5.1/tests/fileTest2/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440021023 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest2/CMakeLists.txt0000644000175000001440000000207414200302440021607 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . add_executable (fileTest2 filetest2.cpp) target_link_libraries (fileTest2 PRIVATE Drumstick::File Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Test ) if(QT_VERSION VERSION_GREATER_EQUAL 6.0.0) target_link_libraries(fileTest2 PRIVATE Qt6::Core5Compat) endif() add_test (fileTest2 ${PROJECT_BINARY_DIR}/bin/fileTest2) drumstick-2.5.1/tests/fileTest2/PaxHeaders.27918/fileTest2.pro0000644000000000000000000000013214200302440020646 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest2/fileTest2.pro0000644000175000001440000000103614200302440021427 0ustar00pedrousers00000000000000QT += testlib QT -= gui TARGET = fileTest2 CONFIG += qt warn_on depend_includepath testcase CONFIG += c++11 cmdline TEMPLATE = app include (../../global.pri) SOURCES += filetest2.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" INCLUDEPATH += . ../../library/include DESTDIR = ../../build/bin static:DEFINES+=DRUMSTICK_STATIC macx:!static { QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib LIBS += -framework drumstick-file } else { LIBS += -L$$OUT_PWD/../../build/lib \ -l$$drumstickLib(drumstick-file) } drumstick-2.5.1/tests/fileTest2/PaxHeaders.27918/filetest2.cpp0000644000000000000000000000013214200302440020670 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest2/filetest2.cpp0000644000175000001440000002124014200302440021450 0ustar00pedrousers00000000000000/* Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This file is part of the Drumstick project, see https://sf.net/p/drumstick This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include #include #include #include DISABLE_WARNING_PUSH DISABLE_WARNING_DEPRECATED_DECLARATIONS using namespace drumstick::File; class FileTest2 : public QObject { Q_OBJECT public: explicit FileTest2(QObject* parent = nullptr); static const char test_wrk[]; static const int test_wrk_len; public slots: void fileHeader(int verh, int verl); void trackHeader(const QString& name1, const QString& name2, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop); void timeBase(int timebase); void noteEvent(int track, long time, int chan, int pitch, int vol, int dur); void timeSigEvent(int bar, int num, int den); void keySigEvent(int bar, int alt); void tempoEvent(long time, int tempo); void errorHandler(const QString& errorStr); void newTrackHeader(const QString& name, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop); private slots: void initTestCase(); void cleanupTestCase(); void testCaseReadWrkFile(); private: QWrk *m_engine; int m_timeBase; int m_numNotes; int m_lastNote; int m_tracks; int m_lastKeySig; float m_lastTempo; QByteArray m_testData; QString m_fileVersion; QString m_lastTimeSig; QString m_lastError; }; FileTest2::FileTest2(QObject* parent): QObject(parent), m_engine(nullptr), m_timeBase(0), m_numNotes(0), m_lastNote(0), m_tracks(0), m_lastKeySig(0), m_lastTempo(0) { m_engine = new QWrk(this); m_engine->setTextCodec(QTextCodec::codecForName("UTF-8")); connect(m_engine, &QWrk::signalWRKError, this, &FileTest2::errorHandler); connect(m_engine, &QWrk::signalWRKHeader, this, &FileTest2::fileHeader); connect(m_engine, &QWrk::signalWRKTrack, this, &FileTest2::trackHeader); connect(m_engine, &QWrk::signalWRKTimeBase, this, &FileTest2::timeBase); connect(m_engine, &QWrk::signalWRKNote, this, &FileTest2::noteEvent); connect(m_engine, &QWrk::signalWRKTimeSig, this, &FileTest2::timeSigEvent); connect(m_engine, &QWrk::signalWRKKeySig, this, &FileTest2::keySigEvent); connect(m_engine, &QWrk::signalWRKTempo, this, &FileTest2::tempoEvent); connect(m_engine, &QWrk::signalWRKNewTrack, this, &FileTest2::newTrackHeader); } const char FileTest2::test_wrk[] = { '\x43','\x41','\x4b','\x45','\x57','\x41','\x4c','\x4b','\x1a','\x00','\x02','\x0a','\x02','\x00','\x00','\x00', '\xc0','\x00','\x03','\x59','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00', '\x03','\x00','\x00','\x00','\x00','\x05','\x00','\x00','\x00','\x01','\x01','\x00','\x01','\x00','\x03','\x00', '\x00','\x01','\x00','\x00','\x00','\x00','\x00','\x01','\x01','\x00','\xff','\xff','\x01','\x7b','\x00','\x00', '\x00','\x01','\x02','\x03','\x04','\x05','\x06','\x07','\x08','\x09','\x0a','\x0b','\x0c','\x0d','\x0e','\x0f', '\x01','\x01','\x20','\x40','\x80','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00', '\x40','\x02','\x00','\x00','\xfe','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00', '\x16','\x16','\x00','\x00','\x00','\x03','\x00','\x06','\x4d','\x43','\x49','\x43','\x6d','\x64','\x01','\x04', '\x57','\x61','\x76','\x65','\x02','\x04','\x54','\x65','\x78','\x74','\x03','\x0f','\x14','\x00','\x00','\x00', '\x01','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\xe0','\x2e','\x00','\x00','\x00','\x00', '\x00','\x00','\x00','\x00','\x05','\x0e','\x00','\x00','\x00','\x01','\x00','\x00','\x00','\x00','\x00','\x01', '\x00','\x04','\x02','\x00','\x00','\x00','\x00','\x17','\x07','\x00','\x00','\x00','\x01','\x00','\x01','\x00', '\x04','\x02','\x00','\x0b','\x06','\x00','\x00','\x00','\x1e','\x00','\x00','\x00','\x00','\x00','\x11','\x0e', '\x00','\x00','\x00','\x00','\x00','\x09','\x00','\x25','\x00','\x6e','\x00','\x01','\x00','\x00','\x00','\x00', '\x00','\x10','\x0c','\x00','\x00','\x00','\x02','\x00','\x00','\x09','\x00','\x7f','\xff','\xff','\x00','\x00', '\x00','\x00','\x01','\x09','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x09','\x00','\x7f','\x00','\x00', '\x02','\x2c','\x00','\x00','\x00','\x00','\x00','\x05','\x00','\x00','\x00','\x00','\x90','\x58','\x64','\xc0', '\x00','\x00','\x00','\x00','\x90','\x25','\x64','\xc0','\x00','\xc0','\x00','\x00','\x90','\x25','\x64','\xc0', '\x00','\x80','\x01','\x00','\x90','\x25','\x64','\xc0','\x00','\x40','\x02','\x00','\x90','\x25','\x64','\xc0', '\x00','\x13','\x06','\x00','\x00','\x00','\x00','\x00','\x7f','\x00','\x40','\x00','\x19','\x42','\x00','\x00', '\x00','\x10','\x00','\x00','\x00','\x07','\x3f','\x01','\x00','\x07','\x3f','\x02','\x00','\x07','\x3f','\x03', '\x00','\x07','\x3f','\x04','\x00','\x07','\x3f','\x05','\x00','\x07','\x3f','\x06','\x00','\x07','\x3f','\x07', '\x00','\x07','\x3f','\x08','\x00','\x07','\x3f','\x09','\x00','\x07','\x3f','\x0a','\x00','\x07','\x3f','\x0b', '\x00','\x07','\x3f','\x0c','\x00','\x07','\x3f','\x0d','\x00','\x07','\x3f','\x0e','\x00','\x07','\x3f','\x0f', '\x00','\x07','\x3f','\xff' }; const int FileTest2::test_wrk_len = sizeof(test_wrk); //388 void FileTest2::fileHeader(int verh, int verl) { m_fileVersion = QString("%1.%2").arg(verh).arg(verl); } void FileTest2::errorHandler(const QString& errorStr) { m_lastError = errorStr; qWarning() << errorStr; } void FileTest2::trackHeader( const QString& name1, const QString& name2, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop ) { Q_UNUSED(name1) Q_UNUSED(name2) Q_UNUSED(trackno) Q_UNUSED(channel) Q_UNUSED(pitch) Q_UNUSED(velocity) Q_UNUSED(port) Q_UNUSED(selected) Q_UNUSED(muted) Q_UNUSED(loop) m_tracks++; } void FileTest2::timeBase(int timebase) { m_timeBase = timebase; } void FileTest2::noteEvent(int track, long time, int chan, int pitch, int vol, int dur) { Q_UNUSED(track) Q_UNUSED(time) Q_UNUSED(chan) Q_UNUSED(vol) Q_UNUSED(dur) m_numNotes++; m_lastNote = pitch; } void FileTest2::timeSigEvent(int bar, int num, int den) { Q_UNUSED(bar) m_lastTimeSig = QString("%1/%2").arg(num).arg(den); } void FileTest2::keySigEvent(int bar, int alt) { Q_UNUSED(bar) m_lastKeySig = alt; } void FileTest2::tempoEvent(long time, int tempo) { Q_UNUSED(time) double bpm = tempo / 100.0; m_lastTempo = bpm; } void FileTest2::newTrackHeader( const QString& name, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop ) { Q_UNUSED(name) Q_UNUSED(trackno) Q_UNUSED(channel) Q_UNUSED(pitch) Q_UNUSED(velocity) Q_UNUSED(port) Q_UNUSED(selected) Q_UNUSED(muted) Q_UNUSED(loop) m_tracks++; } void FileTest2::initTestCase() { m_testData = QByteArray::fromRawData(test_wrk, test_wrk_len); } void FileTest2::cleanupTestCase() { m_testData.clear(); } void FileTest2::testCaseReadWrkFile() { QDataStream stream(&m_testData, QIODevice::ReadWrite); m_engine->readFromStream(&stream); if (!m_lastError.isEmpty()) { QFAIL(m_lastError.toLocal8Bit()); } QCOMPARE(m_fileVersion, QString("2.0")); QCOMPARE(m_timeBase, 192); QCOMPARE(m_tracks, 1); QCOMPARE(m_lastTempo, 120.0); QCOMPARE(m_lastTimeSig, QString("4/4")); QCOMPARE(m_lastKeySig, 0); QCOMPARE(m_numNotes, 5); QCOMPARE(m_lastNote, 37); } QTEST_APPLESS_MAIN(FileTest2) #include "filetest2.moc" DISABLE_WARNING_POP drumstick-2.5.1/tests/PaxHeaders.27918/fileTest30000644000000000000000000000013214200302440016207 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest3/0000755000175000001440000000000014200302440017045 5ustar00pedrousers00000000000000drumstick-2.5.1/tests/fileTest3/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440021024 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest3/CMakeLists.txt0000644000175000001440000000207414200302440021610 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . add_executable (fileTest3 filetest3.cpp) target_link_libraries (fileTest3 PRIVATE Drumstick::File Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Test ) if(QT_VERSION VERSION_GREATER_EQUAL 6.0.0) target_link_libraries(fileTest3 PRIVATE Qt6::Core5Compat) endif() add_test (fileTest3 ${PROJECT_BINARY_DIR}/bin/fileTest3) drumstick-2.5.1/tests/fileTest3/PaxHeaders.27918/filetest3.cpp0000644000000000000000000000013214200302440020672 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest3/filetest3.cpp0000644000175000001440000002226514200302440021462 0ustar00pedrousers00000000000000/* Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This file is part of the Drumstick project, see https://sf.net/p/drumstick This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include #include #include #include #include DISABLE_WARNING_PUSH DISABLE_WARNING_DEPRECATED_DECLARATIONS using namespace drumstick::File; class FileTest3 : public QObject { Q_OBJECT public: explicit FileTest3(QObject* parent = nullptr); static const char test_rmi[]; static const int test_rmi_len; static const int FORMAT; static const int TRACKS; static const int DIVISION; static const int TEMPO; static const QList NOTES; public Q_SLOTS: void dataHandler(const QString& dataType, const QByteArray& data); void errorHandler(const QString& errorStr); void headerEvent(int format, int ntrks, int division); void trackStartEvent(); void trackEndEvent(); void endOfTrackEvent(); void noteOnEvent(int chan, int pitch, int vol); void noteOffEvent(int chan, int pitch, int vol); void keyPressEvent(int chan, int pitch, int press); void ctlChangeEvent(int chan, int ctl, int value); void pitchBendEvent(int chan, int value); void programEvent(int chan, int patch); void chanPressEvent(int chan, int press); void sysexEvent(const QByteArray& data); void textEvent(int typ, const QString& data); void timeSigEvent(int b0, int b1, int b2, int b3); void keySigEvent(int b0, int b1); void tempoEvent(int tempo); private Q_SLOTS: void testCaseReadRmidi(); void initTestCase(); void cleanupTestCase(); private: Rmidi *m_rmidi; QSmf *m_engine; int m_numNoteOn; int m_lastNoteOn; int m_numNoteOff; int m_lastNoteOff; int m_lastKeyPress; int m_currentTrack; int m_endOfTrack; int m_lastCtl; int m_lastProgram; int m_lastChanPress; int m_lastPitchBend; int m_lastTempo; int m_format; int m_ntrks; int m_division; QByteArray m_testData; QByteArray m_lastSysex; QString m_lastError; QString m_trackEnd; QString m_lastTextEvent; QString m_lastTimeSig; QString m_lastKeySig; }; FileTest3::FileTest3(QObject* parent): QObject(parent), m_rmidi(nullptr), m_engine(nullptr), m_numNoteOn(0), m_lastNoteOn(0), m_numNoteOff(0), m_lastNoteOff(0), m_lastKeyPress(0), m_currentTrack(0), m_endOfTrack(0), m_lastCtl(0), m_lastProgram(0), m_lastChanPress(0), m_lastPitchBend(0), m_lastTempo(0), m_format(0), m_ntrks(0), m_division(0) { m_rmidi = new Rmidi(this); connect(m_rmidi, &Rmidi::signalRiffData, this, &FileTest3::dataHandler); m_engine = new QSmf(this); m_engine->setTextCodec(QTextCodec::codecForName("UTF-8")); connect(m_engine, &QSmf::signalSMFError, this, &FileTest3::errorHandler); connect(m_engine, &QSmf::signalSMFHeader, this, &FileTest3::headerEvent); connect(m_engine, &QSmf::signalSMFTrackStart, this, &FileTest3::trackStartEvent); connect(m_engine, &QSmf::signalSMFTrackEnd, this, &FileTest3::trackEndEvent); connect(m_engine, &QSmf::signalSMFNoteOn, this, &FileTest3::noteOnEvent); connect(m_engine, &QSmf::signalSMFNoteOff, this, &FileTest3::noteOffEvent); connect(m_engine, &QSmf::signalSMFKeyPress, this, &FileTest3::keyPressEvent); connect(m_engine, &QSmf::signalSMFCtlChange, this, &FileTest3::ctlChangeEvent); connect(m_engine, &QSmf::signalSMFPitchBend, this, &FileTest3::pitchBendEvent); connect(m_engine, &QSmf::signalSMFProgram, this, &FileTest3::programEvent); connect(m_engine, &QSmf::signalSMFChanPress, this, &FileTest3::chanPressEvent); connect(m_engine, &QSmf::signalSMFSysex, this, &FileTest3::sysexEvent); connect(m_engine, &QSmf::signalSMFText, this, &FileTest3::textEvent); connect(m_engine, &QSmf::signalSMFendOfTrack, this, &FileTest3::endOfTrackEvent); connect(m_engine, &QSmf::signalSMFTimeSig, this, &FileTest3::timeSigEvent); connect(m_engine, &QSmf::signalSMFKeySig, this, &FileTest3::keySigEvent); connect(m_engine, &QSmf::signalSMFTempo, this, &FileTest3::tempoEvent); } const char FileTest3::test_rmi[] = { '\x52', '\x49', '\x46', '\x46', '\x7c', '\x00', '\x00', '\x00', '\x52', '\x4d', '\x49', '\x44', '\x64', '\x61', '\x74', '\x61', '\x70', '\x00', '\x00', '\x00', '\x4d', '\x54', '\x68', '\x64', '\x00', '\x00', '\x00', '\x06', '\x00', '\x00', '\x00', '\x01', '\x03', '\xc0', '\x4d', '\x54', '\x72', '\x6b', '\x00', '\x00', '\x00', '\x5a', '\x00', '\xff', '\x58', '\x04', '\x04', '\x02', '\x18', '\x08', '\x00', '\xff', '\x59', '\x02', '\x00', '\x00', '\x00', '\xff', '\x51', '\x03', '\x07', '\xa1', '\x20', '\x00', '\xb0', '\x07', '\x65', '\x00', '\x90', '\x3c', '\x64', '\x83', '\x60', '\x3c', '\x00', '\x00', '\x3e', '\x64', '\x83', '\x60', '\x3e', '\x00', '\x00', '\x40', '\x64', '\x83', '\x60', '\x40', '\x00', '\x00', '\x41', '\x64', '\x83', '\x60', '\x41', '\x00', '\x00', '\x43', '\x64', '\x83', '\x60', '\x43', '\x00', '\x00', '\x45', '\x64', '\x83', '\x60', '\x45', '\x00', '\x00', '\x47', '\x64', '\x83', '\x60', '\x47', '\x00', '\x00', '\x48', '\x64', '\x83', '\x60', '\x48', '\x00', '\x00', '\xb0', '\x07', '\x65', '\x00', '\xff', '\x2f', '\x00' }; const int FileTest3::test_rmi_len = sizeof(test_rmi); //132; const QList FileTest3::NOTES = { 60, 62, 64, 65, 67, 69, 71, 72 }; const int FileTest3::FORMAT = 0; const int FileTest3::TRACKS = 1; const int FileTest3::DIVISION = 960; const int FileTest3::TEMPO = 120; void FileTest3::dataHandler(const QString &dataType, const QByteArray &data) { if (dataType == "RMID") { QDataStream ds(data); m_engine->readFromStream(&ds); } } void FileTest3::errorHandler(const QString& errorStr) { m_lastError = errorStr; qWarning() << Q_FUNC_INFO << errorStr; } void FileTest3::headerEvent(int format, int ntrks, int division) { m_format = format; m_ntrks = ntrks; m_division = division; } void FileTest3::trackStartEvent() { m_currentTrack++; } void FileTest3::trackEndEvent() { m_trackEnd = QString("End: %1").arg(m_currentTrack); //qDebug() << Q_FUNC_INFO << m_trackEnd; } void FileTest3::endOfTrackEvent() { m_endOfTrack++; } void FileTest3::noteOnEvent(int , int pitch, int vel) { Q_UNUSED(vel) m_numNoteOn++; m_lastNoteOn = pitch; //qDebug() << Q_FUNC_INFO << pitch << vel; } void FileTest3::noteOffEvent(int , int pitch, int vel) { Q_UNUSED(vel) m_numNoteOff++; m_lastNoteOff = pitch; //qDebug() << Q_FUNC_INFO << pitch << vel; } void FileTest3::keyPressEvent(int , int pitch, int ) { m_lastKeyPress = pitch; } void FileTest3::ctlChangeEvent(int , int ctl, int ) { m_lastCtl = ctl; } void FileTest3::pitchBendEvent(int , int value) { m_lastPitchBend = value; } void FileTest3::programEvent(int , int patch) { m_lastProgram = patch; } void FileTest3::chanPressEvent(int , int press) { m_lastChanPress = press; } void FileTest3::sysexEvent(const QByteArray& data) { m_lastSysex = data; } void FileTest3::textEvent(int , const QString& data) { m_lastTextEvent = data; } void FileTest3::timeSigEvent(int b0, int b1, int b2, int b3) { m_lastTimeSig = QString("%1, %2, %3, %4").arg(b0).arg(b1).arg(b2).arg(b3); //qDebug() << Q_FUNC_INFO << m_lastTimeSig; } void FileTest3::keySigEvent(int b0, int b1) { m_lastKeySig = QString("%1, %2").arg(b0).arg(b1); //qDebug() << Q_FUNC_INFO << m_lastKeySig; } void FileTest3::tempoEvent(int tempo) { m_lastTempo = static_cast( 6e7 / tempo ); //qDebug() << Q_FUNC_INFO << m_lastTempo; } void FileTest3::initTestCase() { m_testData = QByteArray::fromRawData(test_rmi, test_rmi_len); } void FileTest3::cleanupTestCase() { m_testData.clear(); } void FileTest3::testCaseReadRmidi() { QDataStream stream(&m_testData, QIODevice::ReadOnly); m_rmidi->readFromStream(&stream); if (!m_lastError.isEmpty()) { QFAIL(m_lastError.toLocal8Bit()); } QCOMPARE(m_format, FORMAT); QCOMPARE(m_ntrks, TRACKS); QCOMPARE(m_division, DIVISION); QCOMPARE(m_engine->getFileFormat(), FORMAT); QCOMPARE(m_engine->getTracks(), TRACKS); QCOMPARE(m_engine->getDivision(), DIVISION); QCOMPARE(m_lastTempo, TEMPO); QCOMPARE(m_numNoteOn, NOTES.length() * 2); QCOMPARE(m_numNoteOff, 0); // no notes off QCOMPARE(m_lastNoteOn, NOTES.last()); QCOMPARE(m_lastNoteOff, 0); // no notes off QCOMPARE(m_currentTrack, TRACKS); QCOMPARE(m_endOfTrack, TRACKS); } QTEST_APPLESS_MAIN(FileTest3) #include "filetest3.moc" DISABLE_WARNING_POP drumstick-2.5.1/tests/fileTest3/PaxHeaders.27918/fileTest3.pro0000644000000000000000000000013214200302440020650 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest3/fileTest3.pro0000644000175000001440000000103714200302440021432 0ustar00pedrousers00000000000000QT += testlib QT -= gui TARGET = fileTest3 CONFIG += qt warn_on depend_includepath testcase CONFIG += c++11 cmdline TEMPLATE = app include (../../global.pri) SOURCES += filetest3.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" INCLUDEPATH += . ../../library/include DESTDIR = ../../build/bin static:DEFINES+=DRUMSTICK_STATIC macx:!static { QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib LIBS += -framework drumstick-file } else { LIBS += -L$$OUT_PWD/../../build/lib \ -l$$drumstickLib(drumstick-file) } drumstick-2.5.1/tests/PaxHeaders.27918/widgetsTest0000644000000000000000000000013214200302440016653 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/widgetsTest/0000755000175000001440000000000014200302440017511 5ustar00pedrousers00000000000000drumstick-2.5.1/tests/widgetsTest/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440021470 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/widgetsTest/CMakeLists.txt0000644000175000001440000000221114200302440022245 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . find_package(Qt${QT_VERSION_MAJOR}Widgets REQUIRED) set ( SOURCES widgetstest.cpp ) add_executable ( widgetsTest ${SOURCES} ) target_include_directories ( widgetsTest PUBLIC ${CMAKE_SOURCE_DIR}/library/include ) target_link_libraries (widgetsTest PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Test Drumstick::Widgets ) add_test (widgetsTest ${PROJECT_BINARY_DIR}/bin/widgetsTest) drumstick-2.5.1/tests/widgetsTest/PaxHeaders.27918/widgetsTest.pro0000644000000000000000000000013214200302440021760 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/widgetsTest/widgetsTest.pro0000644000175000001440000000104614200302440022542 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = widgetsTest QT += testlib gui widgets CONFIG += c++11 cmdline include (../../global.pri) SOURCES += \ widgetstest.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" INCLUDEPATH += . ../../library/include/ DESTDIR = ../../build/bin macx:!static { QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib LIBS += -framework drumstick-rt drumstick-widgets } else { LIBS += -L$$OUT_PWD/../../build/lib \ -l$$drumstickLib(drumstick-rt) \ -l$$drumstickLib(drumstick-widgets) } drumstick-2.5.1/tests/widgetsTest/PaxHeaders.27918/widgetstest.cpp0000644000000000000000000000013214200302440022002 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/widgetsTest/widgetstest.cpp0000644000175000001440000001070214200302440022563 0ustar00pedrousers00000000000000/* Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This file is part of the Drumstick project, see https://sf.net/p/drumstick This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include #include #include #include using namespace drumstick::widgets; class WidgetsTest : public QObject { Q_OBJECT public: WidgetsTest(); private Q_SLOTS: void testPaletteSingle(); void testPaletteDouble(); void testPaletteChannels(); void testPaletteScale(); void testPaletteKeys(); void testPaletteFont(); void testPaletteAssign(); void testPaletteUnchanged(); void testPaletteChanged(); private: QList m_paletteList { PianoPalette(PAL_SINGLE), PianoPalette(PAL_DOUBLE), PianoPalette(PAL_CHANNELS), PianoPalette(PAL_SCALE), PianoPalette(PAL_KEYS), PianoPalette(PAL_FONT), }; }; WidgetsTest::WidgetsTest() = default; //{ // for( PianoPalette& pal : m_paletteList) { // ... pal.paletteId(); // } //} void WidgetsTest::testPaletteSingle() { PianoPalette p(PAL_SINGLE); QCOMPARE(p, m_paletteList[PAL_SINGLE]); QCOMPARE(p.paletteId(), static_cast(PAL_SINGLE)); QCOMPARE(p.getNumColors(), 1); QCOMPARE(p.isHighLight(), true); QCOMPARE(p.isBackground(), false); QCOMPARE(p.isForeground(), false); } void WidgetsTest::testPaletteDouble() { PianoPalette p(PAL_DOUBLE); QCOMPARE(p, m_paletteList[PAL_DOUBLE]); QCOMPARE(p.paletteId(), static_cast(PAL_DOUBLE)); QCOMPARE(p.getNumColors(), 2); QCOMPARE(p.isHighLight(), true); QCOMPARE(p.isBackground(), false); QCOMPARE(p.isForeground(), false); } void WidgetsTest::testPaletteChannels() { PianoPalette p(PAL_CHANNELS); QCOMPARE(p, m_paletteList[PAL_CHANNELS]); QCOMPARE(p.paletteId(), static_cast(PAL_CHANNELS)); QCOMPARE(p.getNumColors(), 16); QCOMPARE(p.isHighLight(), true); QCOMPARE(p.isBackground(), false); QCOMPARE(p.isForeground(), false); } void WidgetsTest::testPaletteScale() { PianoPalette p(PAL_SCALE); QCOMPARE(p, m_paletteList[PAL_SCALE]); QCOMPARE(p.paletteId(), static_cast(PAL_SCALE)); QCOMPARE(p.getNumColors(), 12); QCOMPARE(p.isHighLight(), false); QCOMPARE(p.isBackground(), true); QCOMPARE(p.isForeground(), false); } void WidgetsTest::testPaletteKeys() { PianoPalette p(PAL_KEYS); QCOMPARE(p, m_paletteList[PAL_KEYS]); QCOMPARE(p.paletteId(), static_cast(PAL_KEYS)); QCOMPARE(p.getNumColors(), 2); QCOMPARE(p.isHighLight(), false); QCOMPARE(p.isBackground(), true); QCOMPARE(p.isForeground(), false); } void WidgetsTest::testPaletteFont() { PianoPalette p(PAL_FONT); QCOMPARE(p, m_paletteList[PAL_FONT]); QCOMPARE(p.paletteId(), static_cast(PAL_FONT)); QCOMPARE(p.getNumColors(), 4); QCOMPARE(p.isHighLight(), false); QCOMPARE(p.isBackground(), false); QCOMPARE(p.isForeground(), true); } void WidgetsTest::testPaletteAssign() { PianoPalette a(PAL_SINGLE); PianoPalette b(PAL_DOUBLE); a = b; QCOMPARE(a, b); QCOMPARE(a, m_paletteList[PAL_DOUBLE]); QCOMPARE(a.paletteId(), b.paletteId()); QCOMPARE(a.getNumColors(), b.getNumColors()); } void WidgetsTest::testPaletteUnchanged() { PianoPalette p(PAL_KEYS); p.setColor(0, Qt::white); p.setColor(1, Qt::black); QCOMPARE(p, m_paletteList[PAL_KEYS]); QCOMPARE(p.paletteId(), static_cast(PAL_KEYS)); QCOMPARE(p.getNumColors(), 2); } void WidgetsTest::testPaletteChanged() { PianoPalette p(PAL_KEYS); p.setColor(0, Qt::black); p.setColor(1, Qt::white); QVERIFY(p != m_paletteList[PAL_KEYS]); p.resetColors(); QCOMPARE(p, m_paletteList[PAL_KEYS]); } QTEST_MAIN(WidgetsTest) #include "widgetstest.moc" drumstick-2.5.1/tests/PaxHeaders.27918/tests.pro0000644000000000000000000000013214200302440016306 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/tests.pro0000644000175000001440000000025614200302440017072 0ustar00pedrousers00000000000000TEMPLATE = subdirs SUBDIRS += fileTest1 \ fileTest2 \ rtTest \ widgetsTest linux { SUBDIRS += \ alsaTest1 \ alsaTest2 } drumstick-2.5.1/tests/PaxHeaders.27918/fileTest10000644000000000000000000000013214200302440016205 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest1/0000755000175000001440000000000014200302440017043 5ustar00pedrousers00000000000000drumstick-2.5.1/tests/fileTest1/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440021022 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest1/CMakeLists.txt0000644000175000001440000000207414200302440021606 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . add_executable (fileTest1 filetest1.cpp) target_link_libraries (fileTest1 PRIVATE Drumstick::File Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Test ) if(QT_VERSION VERSION_GREATER_EQUAL 6.0.0) target_link_libraries(fileTest1 PRIVATE Qt6::Core5Compat) endif() add_test (fileTest1 ${PROJECT_BINARY_DIR}/bin/fileTest1) drumstick-2.5.1/tests/fileTest1/PaxHeaders.27918/filetest1.cpp0000644000000000000000000000013214200302440020666 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest1/filetest1.cpp0000644000175000001440000002403114200302440021447 0ustar00pedrousers00000000000000/* Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This file is part of the Drumstick project, see https://sf.net/p/drumstick This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include #include #include #include DISABLE_WARNING_PUSH DISABLE_WARNING_DEPRECATED_DECLARATIONS using namespace drumstick::File; class FileTest1 : public QObject { Q_OBJECT public: explicit FileTest1(QObject* parent = nullptr); static const char test_mid[]; static const int test_mid_len; static const int FORMAT; static const int TRACKS; static const int DIVISION; static const int TEMPO; static const QString COPYRIGHT; static const QByteArray GSRESET; static const QList NOTES; public Q_SLOTS: void errorHandler(const QString& errorStr); void trackHandler(int track); void headerEvent(int format, int ntrks, int division); void trackStartEvent(); void trackEndEvent(); void endOfTrackEvent(); void noteOnEvent(int chan, int pitch, int vol); void noteOffEvent(int chan, int pitch, int vol); void keyPressEvent(int chan, int pitch, int press); void ctlChangeEvent(int chan, int ctl, int value); void pitchBendEvent(int chan, int value); void programEvent(int chan, int patch); void chanPressEvent(int chan, int press); void sysexEvent(const QByteArray& data); void textEvent(int typ, const QString& data); void timeSigEvent(int b0, int b1, int b2, int b3); void keySigEvent(int b0, int b1); void tempoEvent(int tempo); private Q_SLOTS: void testCaseWriteSmf(); void testCaseReadSmf(); void initTestCase(); void cleanupTestCase(); private: QSmf *m_engine; int m_numNoteOn; int m_lastNoteOn; int m_numNoteOff; int m_lastNoteOff; int m_lastKeyPress; int m_currentTrack; int m_endOfTrack; int m_lastCtl; int m_lastProgram; int m_lastChanPress; int m_lastPitchBend; int m_lastTempo; QByteArray m_testData; QByteArray m_lastSysex; QString m_lastError; QString m_header; QString m_trackEnd; QString m_lastTextEvent; QString m_lastTimeSig; QString m_lastKeySig; }; FileTest1::FileTest1(QObject* parent): QObject(parent), m_engine(nullptr), m_numNoteOn(0), m_lastNoteOn(0), m_numNoteOff(0), m_lastNoteOff(0), m_lastKeyPress(0), m_currentTrack(0), m_endOfTrack(0), m_lastCtl(0), m_lastProgram(0), m_lastChanPress(0), m_lastPitchBend(0), m_lastTempo(0) { m_engine = new QSmf(this); m_engine->setTextCodec(QTextCodec::codecForName("UTF-8")); connect(m_engine, &QSmf::signalSMFError, this, &FileTest1::errorHandler); connect(m_engine, &QSmf::signalSMFWriteTrack, this, &FileTest1::trackHandler); connect(m_engine, &QSmf::signalSMFHeader, this, &FileTest1::headerEvent); connect(m_engine, &QSmf::signalSMFTrackStart, this, &FileTest1::trackStartEvent); connect(m_engine, &QSmf::signalSMFTrackEnd, this, &FileTest1::trackEndEvent); connect(m_engine, &QSmf::signalSMFNoteOn, this, &FileTest1::noteOnEvent); connect(m_engine, &QSmf::signalSMFNoteOff, this, &FileTest1::noteOffEvent); connect(m_engine, &QSmf::signalSMFKeyPress, this, &FileTest1::keyPressEvent); connect(m_engine, &QSmf::signalSMFCtlChange, this, &FileTest1::ctlChangeEvent); connect(m_engine, &QSmf::signalSMFPitchBend, this, &FileTest1::pitchBendEvent); connect(m_engine, &QSmf::signalSMFProgram, this, &FileTest1::programEvent); connect(m_engine, &QSmf::signalSMFChanPress, this, &FileTest1::chanPressEvent); connect(m_engine, &QSmf::signalSMFSysex, this, &FileTest1::sysexEvent); connect(m_engine, &QSmf::signalSMFText, this, &FileTest1::textEvent); connect(m_engine, &QSmf::signalSMFendOfTrack, this, &FileTest1::endOfTrackEvent); connect(m_engine, &QSmf::signalSMFTimeSig, this, &FileTest1::timeSigEvent); connect(m_engine, &QSmf::signalSMFKeySig, this, &FileTest1::keySigEvent); connect(m_engine, &QSmf::signalSMFTempo, this, &FileTest1::tempoEvent); } const char FileTest1::test_mid[] = { '\x4d','\x54','\x68','\x64','\x00','\x00','\x00','\x06','\x00','\x00','\x00','\x01', '\x00','\x78','\x4d','\x54','\x72','\x6b','\x00','\x00','\x00','\x99','\x00','\xff', '\x02','\x2f','\x43','\x6f','\x70','\x79','\x72','\x69','\x67','\x68','\x74','\x20', '\x28','\x43','\x29','\x20','\x32','\x30','\x30','\x36','\x2d','\x32','\x30','\x32', '\x32','\x20','\x50','\x65','\x64','\x72','\x6f','\x20','\x4c','\xc3','\xb3','\x70', '\x65','\x7a','\x2d','\x43','\x61','\x62','\x61','\x6e','\x69','\x6c','\x6c','\x61', '\x73','\x00','\xff','\x51','\x03','\x09','\x27','\xc0','\x00','\xff','\x58','\x04', '\x03','\x02','\x24','\x08','\x00','\xff','\x59','\x02','\x02','\x00','\x00','\xf0', '\x0a','\x41','\x10','\x42','\x12','\x40','\x00','\x7f','\x00','\x41','\xf7','\x00', '\x90','\x3c','\x78','\x3c','\x80','\x3c','\x00','\x00','\x90','\x3e','\x78','\x3c', '\x80','\x3e','\x00','\x00','\x90','\x40','\x78','\x3c','\x80','\x40','\x00','\x00', '\x90','\x41','\x78','\x3c','\x80','\x41','\x00','\x00','\x90','\x43','\x78','\x3c', '\x80','\x43','\x00','\x00','\x90','\x45','\x78','\x3c','\x80','\x45','\x00','\x00', '\x90','\x47','\x78','\x3c','\x80','\x47','\x00','\x00','\x90','\x48','\x78','\x3c', '\x80','\x48','\x00','\x00','\xff','\x2f','\x00' }; const int FileTest1::test_mid_len = sizeof(test_mid); //175; const QString FileTest1::COPYRIGHT = u8"Copyright (C) 2006-2022 Pedro López-Cabanillas"; const QByteArray FileTest1::GSRESET = QByteArrayLiteral( "f04110421240007f0041f7" ); const QList FileTest1::NOTES = { 60, 62, 64, 65, 67, 69, 71, 72 }; const int FileTest1::FORMAT = 0; const int FileTest1::TRACKS = 1; const int FileTest1::DIVISION = 120; const int FileTest1::TEMPO = 100; void FileTest1::errorHandler(const QString& errorStr) { m_lastError = errorStr; qWarning() << errorStr; } void FileTest1::trackHandler(int ) { int i; // Text event m_engine->writeMetaEvent(0, copyright_notice, COPYRIGHT); m_engine->writeBpmTempo(0, TEMPO); m_engine->writeTimeSignature(0, 3, 2, 36, 8); // ts = 3/4 m_engine->writeKeySignature(0, 2, major_mode); // D major (2 sharps) // system exclusive event QByteArray gsreset = QByteArray::fromHex( GSRESET ); m_engine->writeMidiEvent(0, system_exclusive, long(gsreset.size()), gsreset.data()); // some note events for(i = 0; i < NOTES.length(); ++i) { m_engine->writeMidiEvent(0, note_on, 0, NOTES[i], 120); m_engine->writeMidiEvent(60, note_off, 0, NOTES[i], 0); } // final event m_engine->writeMetaEvent(0, end_of_track); } void FileTest1::headerEvent(int format, int ntrks, int division) { m_header = QString("Format=%1, Tracks=%2, Division=%3").arg(format).arg(ntrks).arg(division); } void FileTest1::trackStartEvent() { m_currentTrack++; } void FileTest1::trackEndEvent() { m_trackEnd = QString("End: %1").arg(m_currentTrack); } void FileTest1::endOfTrackEvent() { m_endOfTrack++; } void FileTest1::noteOnEvent(int , int pitch, int ) { m_numNoteOn++; m_lastNoteOn = pitch; } void FileTest1::noteOffEvent(int , int pitch, int ) { m_numNoteOff++; m_lastNoteOff = pitch; } void FileTest1::keyPressEvent(int , int pitch, int ) { m_lastKeyPress = pitch; } void FileTest1::ctlChangeEvent(int , int ctl, int ) { m_lastCtl = ctl; } void FileTest1::pitchBendEvent(int , int value) { m_lastPitchBend = value; } void FileTest1::programEvent(int , int patch) { m_lastProgram = patch; } void FileTest1::chanPressEvent(int , int press) { m_lastChanPress = press; } void FileTest1::sysexEvent(const QByteArray& data) { m_lastSysex = data; } void FileTest1::textEvent(int , const QString& data) { m_lastTextEvent = data; } void FileTest1::timeSigEvent(int b0, int b1, int b2, int b3) { m_lastTimeSig = QString("%1, %2, %3, %4").arg(b0).arg(b1).arg(b2).arg(b3); } void FileTest1::keySigEvent(int b0, int b1) { m_lastKeySig = QString("%1, %2").arg(b0).arg(b1); } void FileTest1::tempoEvent(int tempo) { m_lastTempo = static_cast( 6e7 / tempo ); } void FileTest1::initTestCase() { m_testData = QByteArray::fromRawData(test_mid, test_mid_len); } void FileTest1::cleanupTestCase() { m_testData.clear(); } void FileTest1::testCaseWriteSmf() { QByteArray data; QDataStream stream(&data, QIODevice::ReadWrite); m_engine->setDivision(DIVISION); m_engine->setFileFormat(FORMAT); m_engine->setTracks(TRACKS); m_engine->writeToStream(&stream); if (!m_lastError.isEmpty()) { QFAIL(m_lastError.toLocal8Bit()); } QCOMPARE(data, m_testData); } void FileTest1::testCaseReadSmf() { QDataStream stream(&m_testData, QIODevice::ReadWrite); m_engine->readFromStream(&stream); if (!m_lastError.isEmpty()) { QFAIL(m_lastError.toLocal8Bit()); } QCOMPARE(m_engine->getFileFormat(), FORMAT); QCOMPARE(m_engine->getDivision(), DIVISION); QCOMPARE(m_engine->getTracks(), TRACKS); QCOMPARE(m_lastTempo, TEMPO); QCOMPARE(m_lastTextEvent, COPYRIGHT); QCOMPARE(m_lastSysex, QByteArray::fromHex(GSRESET)); QCOMPARE(m_numNoteOn, NOTES.length()); QCOMPARE(m_numNoteOff, NOTES.length()); QCOMPARE(m_lastNoteOn, NOTES.last()); QCOMPARE(m_lastNoteOff, NOTES.last()); QCOMPARE(m_currentTrack, TRACKS); QCOMPARE(m_endOfTrack, TRACKS); } QTEST_APPLESS_MAIN(FileTest1) #include "filetest1.moc" DISABLE_WARNING_POP drumstick-2.5.1/tests/fileTest1/PaxHeaders.27918/fileTest1.pro0000644000000000000000000000013214200302440020644 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/fileTest1/fileTest1.pro0000644000175000001440000000103714200302440021426 0ustar00pedrousers00000000000000QT += testlib QT -= gui TARGET = fileTest1 CONFIG += qt warn_on depend_includepath testcase CONFIG += c++11 cmdline TEMPLATE = app include (../../global.pri) SOURCES += filetest1.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" INCLUDEPATH += . ../../library/include DESTDIR = ../../build/bin static:DEFINES+=DRUMSTICK_STATIC macx:!static { QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib LIBS += -framework drumstick-file } else { LIBS += -L$$OUT_PWD/../../build/lib \ -l$$drumstickLib(drumstick-file) } drumstick-2.5.1/tests/PaxHeaders.27918/alsaTest20000644000000000000000000000013214200302440016207 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/alsaTest2/0000755000175000001440000000000014200302440017045 5ustar00pedrousers00000000000000drumstick-2.5.1/tests/alsaTest2/PaxHeaders.27918/alsaTest2.pro0000644000000000000000000000013214200302440020650 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/alsaTest2/alsaTest2.pro0000644000175000001440000000042414200302440021431 0ustar00pedrousers00000000000000QT += testlib QT -= gui TARGET = alsaTest2 CONFIG += c++11 cmdline TEMPLATE = app SOURCES += \ alsatest2.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" INCLUDEPATH += . ../../library/include LIBS = -L../../build/lib -ldrumstick-alsa -lasound DESTDIR = ../../build/bin drumstick-2.5.1/tests/alsaTest2/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440021024 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/alsaTest2/CMakeLists.txt0000644000175000001440000000171214200302440021606 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . add_executable (alsaTest2 alsatest2.cpp) target_link_libraries (alsaTest2 PRIVATE Drumstick::ALSA Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Test ) add_test (alsaTest2 ${PROJECT_BINARY_DIR}/bin/alsaTest2) drumstick-2.5.1/tests/alsaTest2/PaxHeaders.27918/alsatest2.cpp0000644000000000000000000000013214200302440020672 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/alsaTest2/alsatest2.cpp0000644000175000001440000000661714200302440021465 0ustar00pedrousers00000000000000/* Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This file is part of the Drumstick project, see https://sf.net/p/drumstick This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include using namespace drumstick::ALSA; class AlsaTest2 : public QObject, public TimerEventHandler { Q_OBJECT public: AlsaTest2(); // TimerEventHandler implementation void handleTimerEvent(int ticks, int msecs) override; private Q_SLOTS: void testTimer(); void initTestCase(); void cleanupTestCase(); private: QPointer m_test_timer; int m_count; }; AlsaTest2::AlsaTest2(): m_test_timer(nullptr), m_count(0) { } void AlsaTest2::handleTimerEvent(int , int ) { m_count++; } void AlsaTest2::initTestCase() { try { QFileInfo check_devsnd("/dev/snd/"); QVERIFY(check_devsnd.exists() && check_devsnd.isDir()); QFileInfo check_devsndseq("/dev/snd/seq"); QVERIFY(check_devsndseq.exists() && !check_devsndseq.isFile() && !check_devsndseq.isDir()); QFileInfo check_devsndtimer("/dev/snd/timer"); QVERIFY(check_devsndtimer.exists() && !check_devsndseq.isFile() && !check_devsndseq.isDir()); m_test_timer = Timer::bestGlobalTimer( SND_TIMER_OPEN_NONBLOCK | SND_TIMER_OPEN_TREAD ); } catch (...) { QWARN("Timer test initialization failed"); } } void AlsaTest2::cleanupTestCase() { delete m_test_timer; } void AlsaTest2::testTimer() { if (m_test_timer != nullptr) { m_count = 0; try { TimerParams tparams; TimerInfo tinfo = m_test_timer->getTimerInfo(); tparams.setAutoStart(true); if (!tinfo.isSlave()) { /* 50 Hz */ tparams.setTicks( 1000000000L / tinfo.getResolution() / 50); if (tparams.getTicks() < 1) { tparams.setTicks(1); } } else { tparams.setTicks(1); } tparams.setFilter(1 << SND_TIMER_EVENT_TICK); m_test_timer->setTimerParams(tparams); m_test_timer->setHandler(this); // Testing timer callback method m_test_timer->start(); m_test_timer->startEvents(); QTest::qWait(1000); m_test_timer->stopEvents(); m_test_timer->stop(); QVERIFY2(qAbs(50 - m_count) <= 1, "Timer results are wrong"); TimerStatus tstatus = m_test_timer->getTimerStatus(); QCOMPARE(tstatus.getLost(), 0L); QCOMPARE(tstatus.getOverrun(), 0L); } catch (...) { QFAIL("Timer test failed"); } } } QTEST_GUILESS_MAIN(AlsaTest2) #include "alsatest2.moc" drumstick-2.5.1/tests/PaxHeaders.27918/rtTest0000644000000000000000000000013214200302440015632 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/rtTest/0000755000175000001440000000000014200302440016470 5ustar00pedrousers00000000000000drumstick-2.5.1/tests/rtTest/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020447 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/rtTest/CMakeLists.txt0000644000175000001440000000534714200302440021241 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set ( SOURCES rttest.cpp ) add_executable ( rtTest ${SOURCES} ) target_include_directories (rtTest PUBLIC ${CMAKE_SOURCE_DIR}/library/include ) target_link_libraries (rtTest PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Test Drumstick::RT ) add_test (rtTest ${PROJECT_BINARY_DIR}/bin/rtTest) if(STATIC_DRUMSTICK) if (FALSE) target_compile_definitions(rtTest PUBLIC DUMMY_BACKEND) target_link_libraries(rtTest PRIVATE drumstick-rt-dummy-in drumstick-rt-dummy-out) endif() if(ALSA_FOUND) target_compile_definitions(rtTest PUBLIC LINUX_BACKEND) target_link_libraries(rtTest PRIVATE drumstick-rt-alsa-in drumstick-rt-alsa-out drumstick-rt-eassynth) endif() if(UNIX AND NOT APPLE) target_compile_definitions(rtTest PUBLIC OSS_BACKEND) target_link_libraries(rtTest PRIVATE drumstick-rt-oss-in drumstick-rt-oss-out) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") target_compile_definitions(rtTest PUBLIC MAC_BACKEND) target_link_libraries(rtTest PRIVATE drumstick-rt-mac-in drumstick-rt-mac-out drumstick-rt-macsynth "-framework CoreMIDI -framework CoreFoundation") endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") target_compile_definitions(rtTest PUBLIC WIN_BACKEND) target_link_libraries(rtTest PRIVATE drumstick-rt-win-in drumstick-rt-win-out winmm) endif() find_package(Qt${QT_VERSION_MAJOR}Network) if(Qt${QT_VERSION_MAJOR}Network_FOUND) target_compile_definitions(rtTest PUBLIC NET_BACKEND) target_link_libraries(rtTest PRIVATE drumstick-rt-net-in drumstick-rt-net-out) endif() if(FLUIDSYNTH_FOUND) target_compile_definitions(rtTest PUBLIC FLUIDSYNTH_BACKEND) target_link_libraries(rtTest PRIVATE drumstick-rt-fluidsynth) endif() endif() drumstick-2.5.1/tests/rtTest/PaxHeaders.27918/rtTest.pro0000644000000000000000000000013214200302440017716 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/rtTest/rtTest.pro0000644000175000001440000000343314200302440020502 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = rtTest QT += testlib QT -= gui CONFIG += c++11 cmdline include (../../global.pri) SOURCES += rttest.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" INCLUDEPATH += . ../../library/include/ DESTDIR = ../../build/bin static { CONFIG += link_prl DEFINES += DRUMSTICK_STATIC DEFINES += NET_BACKEND LIBS += -L$$OUT_PWD/../../build/lib/drumstick/ LIBS += -ldrumstick-rt-net-in \ -ldrumstick-rt-net-out packagesExist(fluidsynth) { DEFINES += FLUIDSYNTH_BACKEND LIBS += -ldrumstick-rt-fluidsynth macx { QMAKE_LFLAGS += -F/Library/Frameworks LIBS += -framework FluidSynth } else { CONFIG += link_pkgconfig PKGCONFIG += fluidsynth } } linux { DEFINES += LINUX_BACKEND LIBS += -ldrumstick-rt-alsa-in \ -ldrumstick-rt-alsa-out \ -ldrumstick-rt-eassynth \ -lsonivox \ -ldrumstick-alsa \ -lasound } unix:!macx { DEFINES += OSS_BACKEND LIBS += -ldrumstick-rt-oss-in \ -ldrumstick-rt-oss-out } macx { DEFINES += MAC_BACKEND LIBS += -ldrumstick-rt-mac-in \ -ldrumstick-rt-mac-out \ -ldrumstick-rt-macsynth \ -framework CoreMIDI \ -framework CoreFoundation } win32 { DEFINES += WIN_BACKEND LIBS += -ldrumstick-rt-win-in \ -ldrumstick-rt-win-out \ -lwinmm } } macx:!static { QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib LIBS += -framework drumstick-rt } else { LIBS += -L$$OUT_PWD/../../build/lib \ -l$$drumstickLib(drumstick-rt) } drumstick-2.5.1/tests/rtTest/PaxHeaders.27918/rttest.cpp0000644000000000000000000000013214200302440017740 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/rtTest/rttest.cpp0000644000175000001440000000766514200302440020537 0ustar00pedrousers00000000000000/* Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This file is part of the Drumstick project, see https://sf.net/p/drumstick This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include #include #include #include #if defined(LINUX_BACKEND) Q_IMPORT_PLUGIN(ALSAMIDIInput) Q_IMPORT_PLUGIN(ALSAMIDIOutput) Q_IMPORT_PLUGIN(SynthController) #endif #if defined(MAC_BACKEND) Q_IMPORT_PLUGIN(MacMIDIInput) Q_IMPORT_PLUGIN(MacMIDIOutput) Q_IMPORT_PLUGIN(MacSynthOutput) #endif #if defined(WIN_BACKEND) Q_IMPORT_PLUGIN(WinMIDIInput) Q_IMPORT_PLUGIN(WinMIDIOutput) #endif #if defined(NET_BACKEND) Q_IMPORT_PLUGIN(NetMIDIInput) Q_IMPORT_PLUGIN(NetMIDIOutput) #endif #if defined(DUMMY_BACKEND) Q_IMPORT_PLUGIN(DummyInput) Q_IMPORT_PLUGIN(DummyOutput) #endif #if defined(FLUIDSYNTH_BACKEND) Q_IMPORT_PLUGIN(SynthOutput) #endif #if defined(OSS_BACKEND) Q_IMPORT_PLUGIN(OSSInput) Q_IMPORT_PLUGIN(OSSOutput) #endif using namespace drumstick::rt; class RtTest : public QObject { Q_OBJECT public: RtTest(); private: QString joinConns(QList conns); private Q_SLOTS: void testRT(); }; RtTest::RtTest() = default; void RtTest::testRT() { QSettings settings; QList inputsList; QList outputsList; BackendManager man; man.refresh(&settings); QStringList paths = man.defaultPaths(); #if !defined(DRUMSTICK_STATIC) QVERIFY2(paths.length() > 0, "Plugins path is empty"); foreach(const QString& p, paths) { qDebug() << "path:" << p; } #endif inputsList = man.availableInputs(); QVERIFY2(inputsList.length() > 0, "There aren't input backends"); foreach(MIDIInput* input, inputsList) { QList conns = input->connections(); qDebug() << "input:" << input->backendName() << input->publicName(); qDebug() << " connections:" << (conns.isEmpty() ? "none" : joinConns(conns)); QCOMPARE(input->backendName().isEmpty(), false ); QCOMPARE(input->publicName().isEmpty(), false ); /*QVERIFY2(conns.length() > 0, "Backend without any connection"); QStringList avconns = input->connections(true); QVERIFY2(avconns.length() > 0, "Backend without any advanced connection"); QVERIFY2(avconns.length() >= conns.length(), "unexpected connections number");*/ } outputsList = man.availableOutputs(); QVERIFY2(outputsList.length() > 0, "There aren't output backends"); foreach(MIDIOutput* output, outputsList) { QList conns = output->connections(); qDebug() << "output:" << output->backendName() << output->publicName(); qDebug() << " connections:" << (conns.isEmpty() ? "none" : joinConns(conns)); /*QVERIFY2(conns.length() > 0, "Backend without any connection"); QStringList avconns = output->connections(true); QVERIFY2(avconns.length() > 0, "Backend without any advanced connection"); QVERIFY2(avconns.length() >= conns.length(), "unexpected connections number");*/ } } QString RtTest::joinConns(QList conns) { QString res; for(const MIDIConnection& c : conns) { res += c.first + ", "; } return res; } QTEST_GUILESS_MAIN(RtTest) #include "rttest.moc" drumstick-2.5.1/tests/PaxHeaders.27918/alsaTest10000644000000000000000000000013214200302440016206 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/alsaTest1/0000755000175000001440000000000014200302440017044 5ustar00pedrousers00000000000000drumstick-2.5.1/tests/alsaTest1/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440021023 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/alsaTest1/CMakeLists.txt0000644000175000001440000000171214200302440021605 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . add_executable (alsaTest1 alsatest1.cpp) target_link_libraries (alsaTest1 PRIVATE Drumstick::ALSA Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Test ) add_test (alsaTest1 ${PROJECT_BINARY_DIR}/bin/alsaTest1) drumstick-2.5.1/tests/alsaTest1/PaxHeaders.27918/alsatest1.cpp0000644000000000000000000000013214200302440020670 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/alsaTest1/alsatest1.cpp0000644000175000001440000000527314200302440021460 0ustar00pedrousers00000000000000/* Copyright (C) 2008-2022, Pedro Lopez-Cabanillas This file is part of the Drumstick project, see https://sf.net/p/drumstick This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; If not, see . */ #include #include #include using namespace drumstick::ALSA; class AlsaTest1 : public QObject { Q_OBJECT public: AlsaTest1(); private Q_SLOTS: void testEvents(); }; AlsaTest1::AlsaTest1() = default; void AlsaTest1::testEvents() { NoteEvent note(0, 60, 100, 120); QCOMPARE(note.getChannel(), 0); QCOMPARE(note.getKey(), 60); QCOMPARE(note.getVelocity(), 100); QCOMPARE(note.getDuration(), 120uL); NoteOnEvent noteOn(1, 60, 100); QCOMPARE(noteOn.getChannel(), 1); QCOMPARE(noteOn.getKey(), 60); QCOMPARE(noteOn.getVelocity(), 100); NoteOffEvent noteOff(2, 60, 0); QCOMPARE(noteOff.getChannel(), 2); QCOMPARE(noteOff.getKey(), 60); QCOMPARE(noteOff.getVelocity(), 0); ControllerEvent ctl(3, 33, 66); QCOMPARE(ctl.getChannel(), 3); QCOMPARE(ctl.getParam(), 33u); QCOMPARE(ctl.getValue(), 66); ProgramChangeEvent pgm(4, 123); QCOMPARE(pgm.getChannel(), 4); QCOMPARE(pgm.getValue(), 123); KeyPressEvent keyPress(5, 60, 124); QCOMPARE(keyPress.getChannel(), 5); QCOMPARE(keyPress.getKey(), 60); QCOMPARE(keyPress.getVelocity(), 124); ChanPressEvent chanPress(6, 111); QCOMPARE(chanPress.getChannel(), 6); QCOMPARE(chanPress.getValue(), 111); PitchBendEvent bender(7, 1234); QCOMPARE(bender.getChannel(), 7); QCOMPARE(bender.getValue(), 1234); QByteArray sysexData = QByteArray::fromHex("f04110421240007f0041f7"); SysExEvent sysexEvent(sysexData); QCOMPARE(sysexEvent.getData(), sysexData.data()); QCOMPARE(sysexEvent.getLength(), (unsigned) sysexData.length()); QString text = "This can be a copyright, song name, instrument, lyric..."; TextEvent textEvent(text, 3); QCOMPARE(textEvent.getText(), text); QCOMPARE(textEvent.getLength(), (unsigned) text.length()); } QTEST_APPLESS_MAIN(AlsaTest1) #include "alsatest1.moc" drumstick-2.5.1/tests/alsaTest1/PaxHeaders.27918/alsaTest1.pro0000644000000000000000000000013214200302440020646 xustar0030 mtime=1644266784.861324204 30 atime=1644266785.361324523 30 ctime=1644266784.861324204 drumstick-2.5.1/tests/alsaTest1/alsaTest1.pro0000644000175000001440000000042414200302440021427 0ustar00pedrousers00000000000000QT += testlib QT -= gui TARGET = alsatest1 CONFIG += c++11 cmdline TEMPLATE = app SOURCES += \ alsatest1.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" INCLUDEPATH += . ../../library/include LIBS = -L../../build/lib -ldrumstick-alsa -lasound DESTDIR = ../../build/bin drumstick-2.5.1/PaxHeaders.27918/AUTHORS0000644000000000000000000000013214200302440014330 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.361324523 30 ctime=1644266784.865324206 drumstick-2.5.1/AUTHORS0000644000175000001440000000027314200302440015113 0ustar00pedrousers00000000000000Pedro Lopez-Cabanillas Translators: Frank Kober - German and French Pavel Fric - Czech Sergey Basalaev - Russian Pedro Lopez-Cabanillas - Spanish drumstick-2.5.1/PaxHeaders.27918/drumstick.spec.in0000644000000000000000000000013214200302440016546 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.361324523 30 ctime=1644266784.865324206 drumstick-2.5.1/drumstick.spec.in0000644000175000001440000001327214200302440017334 0ustar00pedrousers00000000000000# spec file for package drumstick (Version @PROJECT_VERSION@) # # MIDI Sequencer C++ Library Bindings for Qt5 # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This file and all modifications and additions to the pristine # package are under the same license as the package itself. # # norootforbuild Name: drumstick Version: @PROJECT_VERSION@ Release: 1 License: GPL v3 or later Summary: MIDI Sequencer C++ Library Bindings Group: Productivity/Multimedia/Sound/Midi URL: http://drumstick.sourceforge.net Source: %{name}-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: cmake BuildRequires: alsa-lib-devel BuildRequires: qt5-qtbase-devel BuildRequires: fluidsynth-devel BuildRequires: pulseaudio-libs-devel BuildRequires: doxygen BuildRequires: graphviz BuildRequires: libxslt BuildRequires: docbook-utils BuildRequires: docbook-style-xsl Requires: shared-mime-info %description This package includes test and example programs for drumstick libraries. Authors: -------- Pedro Lopez-Cabanillas %package -n libdrumstick-file2 Summary: MIDI Sequencer C++ Library Group: System/Libraries %description -n libdrumstick-file2 MIDI Sequencer C++ Library Bindings for Qt5 This library includes classes providing file input and output in formats commonly used by MIDI programs. Currently, SMF (standard MIDI file) read/write and WRK (Cakewalk) file read are supported. Authors: -------- Pedro Lopez-Cabanillas %package -n libdrumstick-alsa2 Summary: MIDI Sequencer C++ Library Group: System/Libraries %description -n libdrumstick-alsa2 MIDI Sequencer C++ Library Bindings for Qt5 and ALSA. This library includes the ALSA Sequencer library classes, providing MIDI recording and playback functionality to C++/Qt5 programs. Authors: -------- Pedro Lopez-Cabanillas %package -n libdrumstick-rt2 Summary: MIDI Realtime IO C++ Library Group: System/Libraries %description -n libdrumstick-rt2 MIDI Realtime IO C++ Library for Qt5 This library includes the RT library classes, providing MIDI realtime IO functionality to C++/Qt5 programs. Authors: -------- Pedro Lopez-Cabanillas %package -n libdrumstick-widgets2 Summary: MIDI Widgets C++ Library Group: System/Libraries %description -n libdrumstick-widgets2 MIDI Widgets C++ Library for Qt5 This library includes the Widgets library, providing GUI, MIDI related, components for C++/Qt5 programs. Authors: -------- Pedro Lopez-Cabanillas %package -n libdrumstick-devel Summary: Development package for the drumstick libraries Group: Development/Libraries/C and C++ Requires: libdrumstick-file2 = %{version} Requires: libdrumstick-alsa2 = %{version} Requires: libdrumstick-rt2 = %{version} Requires: libdrumstick-widgets2 = %{version} Requires: glibc-devel libstdc++-devel alsa-lib-devel qt5-qtbase-devel %description -n libdrumstick-devel This package contains the files needed to compile programs that use the libdrumstick libraries. Authors: -------- Pedro Lopez-Cabanillas %package -n libdrumstick-doc Summary: Development documentation package for the drumstick libraries Group: Documentation/Other %description -n libdrumstick-doc This package contains the developer's documentation of the drumstick libraries. Authors: -------- Pedro Lopez-Cabanillas %prep %setup -q %build CXXFLAGS="$RPM_OPT_FLAGS -g -fexceptions" \ cmake . -DSTATIC_DRUMSTICK=0 \ -DCMAKE_INSTALL_PREFIX=%{_prefix} \ -DLIB_SUFFIX=$(echo %_lib | cut -b4-) make %{?jobs:-j %jobs} VERBOSE=1 make doxygen %install make install DESTDIR=$RPM_BUILD_ROOT %post %{_bindir}/update-mime-database %{_datadir}/mime %postun %{_bindir}/update-mime-database %{_datadir}/mime %post -n libdrumstick-file2 -p /sbin/ldconfig %postun -n libdrumstick-file2 -p /sbin/ldconfig %post -n libdrumstick-alsa2 -p /sbin/ldconfig %postun -n libdrumstick-alsa2 -p /sbin/ldconfig %post -n libdrumstick-rt2 -p /sbin/ldconfig %postun -n libdrumstick-rt2 -p /sbin/ldconfig %post -n libdrumstick-widgets2 -p /sbin/ldconfig %postun -n libdrumstick-widgets2 -p /sbin/ldconfig %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-, root, root) %doc AUTHORS COPYING INSTALL NEWS README TODO ChangeLog %doc %{_mandir}/* %{_datadir}/icons/hicolor/*/*/* %{_datadir}/applications/* %{_bindir}/* %files -n libdrumstick-file2 %defattr(-,root,root) %{_libdir}/libdrumstick-file.so.* %{_datadir}/mime/packages/* %files -n libdrumstick-alsa2 %defattr(-,root,root) %{_libdir}/libdrumstick-alsa.so.* %files -n libdrumstick-rt2 %defattr(-,root,root) %{_libdir}/libdrumstick-rt.so.* %{_libdir}/drumstick/*.so %files -n libdrumstick-widgets2 %defattr(-,root,root) %dir %{_datadir}/drumstick %{_libdir}/libdrumstick-widgets.so.* %{_datadir}/drumstick/* %files -n libdrumstick-devel %defattr(-, root, root) %dir %{_includedir}/drumstick %{_libdir}/libdrumstick-file.so %{_libdir}/libdrumstick-alsa.so %{_libdir}/libdrumstick-rt.so %{_libdir}/libdrumstick-widgets.so %{_includedir}/drumstick.h %{_includedir}/drumstick/*.h %{_libdir}/pkgconfig/*.pc %files -n libdrumstick-doc %defattr(-, root, root) %doc doc/html/* %changelog * Pedro Lopez-Cabanillas 2.0.0 - New version * Sat Aug 30 2014 Pedro Lopez-Cabanillas 1.0.0 - New version * Thu Sep 9 2010 Pedro Lopez-Cabanillas 0.5.0 - New version drumstick-2.5.1/PaxHeaders.27918/Doxyfile.in0000644000000000000000000000013214200302440015373 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.361324523 30 ctime=1644266784.865324206 drumstick-2.5.1/Doxyfile.in0000644000175000001440000016750014200302440016165 0ustar00pedrousers00000000000000# Doxyfile 1.6.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = drumstick # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PROJECT_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = YES # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = YES # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = YES # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST = YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = YES # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @CMAKE_BINARY_DIR@/doc/drumstick-devel.doc.txt @CMAKE_SOURCE_DIR@/library # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.cpp *.h # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = @CMAKE_SOURCE_DIR@/library/include/drumstick.h @CMAKE_SOURCE_DIR@/library/rt-backends # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/utils/dumpmid @CMAKE_SOURCE_DIR@/utils/dumpwrk @CMAKE_SOURCE_DIR@/utils/playsmf @CMAKE_SOURCE_DIR@/utils/dumpsmf @CMAKE_SOURCE_DIR@/utils/dumprmi @CMAKE_SOURCE_DIR@/utils/metronome @CMAKE_SOURCE_DIR@/utils/sysinfo @CMAKE_SOURCE_DIR@/utils/vpiano @CMAKE_SOURCE_DIR@/utils/drumgrid @CMAKE_SOURCE_DIR@/utils/guiplayer # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = YES # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! # HTML_STYLESHEET = @CMAKE_SOURCE_DIR@/doc/doxygen.css HTML_STYLESHEET = # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see #
Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to FRAME, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. Other possible values # for this tag are: HIERARCHIES, which will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list; # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which # disables this behavior completely. For backwards compatibility with previous # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE # respectively. GENERATE_TREEVIEW = YES # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = @DOXYGEN_INCLUDE_DIRS@ # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = NO # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = Sans Serif # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = NO # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = NO # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Options related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO drumstick-2.5.1/PaxHeaders.27918/readme.md0000644000000000000000000000013214200302440015037 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.437324572 30 ctime=1644266784.865324206 drumstick-2.5.1/readme.md0000644000175000001440000000735614200302440015633 0ustar00pedrousers00000000000000# Drumstick Libraries Drumstick is a set of MIDI libraries using C++/Qt idioms and style. Includes a C++ wrapper around the ALSA library sequencer interface: ALSA sequencer provides software support for MIDI technology on Linux. A complementary library provides classes for processing SMF (Standard MIDI files: .MID/.KAR), RIFF RMID (*.rmi) and Cakewalk (.WRK) file formats. A multiplatform realtime MIDI I/O library and a GUI Widgets libraries are also provided for Linux, Windows, and Mac OSX. Currently, there are four libraries designed to work together if/when needed: * **Drumstick::ALSA** is a Linux only C++/Qt wrapper around the ALSA Sequencer API. ALSA sequencer provides software support for MIDI technology on Linux. * **Drumstick::File** provides easy multiplatform file I/O for Standard MIDI Files (.mid), RIFF RMID (.rmi) and Cakewalk (.wrk) file formats. * **Drumstick::RT** is a realtime MIDI I/O library with pluggable backends. It uses Drumstick::ALSA on Linux, and other native frameworks on macOS and Windows. * **Drumstick::Widgets** contains MIDI widgets, including a Virtual Piano used by VMPK among other programs. **Drumstick::ALSA** was the first library developed under the Drumstick umbrella, and is available only on Linux, because ALSA Sequencer is an exclusive Linux technology. For realtime IO applications you can use the **Drumstick::RT** library which is multiplatform, and only depends on **Drumstick::ALSA** in Linux for its ALSA Sequencer backend. Other multiplatform backends are: Network/[ipMIDI](https://www.nerds.de/en/ipmidi.html) and [Fluidsynth](https://github.com/FluidSynth/fluidsynth). There are ten examples in the source tree, under the utils/ directory: * drumgrid: GUI program. Simple drum patterns. Depends on Drumstick::ALSA. * dumpmid: CLI program. Prints received MIDI events. Depends on Drumstick::ALSA. See also [kmidimon](https://kmidimon.sourceforge.io) * dumprmi: CLI program. Prints and converts RIFF MIDI files. Depends on Drumstick::File. * dumpsmf: CLI program. Prints standard MIDI files. Depends on Drumstick::File. * dumpwrk: CLI program. Prints Cakewalk/Sonar MIDI files. Depends on Drumstick::File. See also [wrk2mid](https://wrk2mid.sourceforge.io) * guiplayer: GUI program. Plays SMF and Cakewalk files. Depends on Drumstick::ALSA and Drumstick::File. See also [dmidiplayer](https://dmidiplayer.sourceforge.io) * metronome: CLI program. Simple command line MIDI metronome. Depends on Drumstick::ALSA. See also [kmetronome](https://kmetronome.sourceforge.io) * playsmf: CLI program. SMF player. Depends on Drumstick::ALSA and Drumstick::File. * sysinfo: CLI program. Prints information about the ALSA sequencer subsystem. Depends on Drumstick::ALSA. * vpiano: GUI program. A simple Virtual Piano Keyboard GUI application. Depends on Drumstick::RT. See also [VMPK](http://vmpk.sourceforge.io). And you can also see independent applications using this library: * [dmidiplayer](https://sourceforge.net/p/dmidiplayer): Multiplatform MIDI file player with many features. * [kmetronome](https://sourceforge.net/p/kmetronome): MIDI metronome for Linux. * [kmidimon](https://sourceforge.net/p/kmidimon): MIDI monitor for Linux. * [VMPK](https://sourceforge.net/p/vmpk): Multiplatform Virtual MIDI Piano Keyboard. * [wrk2mid](https://sourceforge.net/p/wrk2mid): Command line utility to convert WRK files to SMF. Here is a diagram about the relationship between the libraries and the applications: ![Drumstick ecosystem](doc/drumstick-ecosystem.png) The main web site of this project is [drumstick.sourceforge.io](https://drumstick.sourceforge.io) See also: * [Downloads](https://sourceforge.net/projects/drumstick/files/) * [Online documentation](https://drumstick.sourceforge.io/docs/index.html) * [Build and install documentation](install.md) drumstick-2.5.1/PaxHeaders.27918/COPYING0000644000000000000000000000013214200302440014313 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.437324572 30 ctime=1644266784.865324206 drumstick-2.5.1/COPYING0000644000175000001440000010451514200302440015102 0ustar00pedrousers00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . drumstick-2.5.1/PaxHeaders.27918/drumstick.pro0000644000000000000000000000013214200302440016007 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.437324572 30 ctime=1644266784.865324206 drumstick-2.5.1/drumstick.pro0000644000175000001440000000016414200302440016571 0ustar00pedrousers00000000000000TEMPLATE = subdirs SUBDIRS += \ library \ utils \ tests utils.depends = library tests.depends = library drumstick-2.5.1/PaxHeaders.27918/cmake_admin0000644000000000000000000000013214200302440015433 xustar0030 mtime=1644266784.789324158 30 atime=1644266785.437324572 30 ctime=1644266784.789324158 drumstick-2.5.1/cmake_admin/0000755000175000001440000000000014200302440016271 5ustar00pedrousers00000000000000drumstick-2.5.1/cmake_admin/PaxHeaders.27918/cmake_uninstall.cmake.in0000644000000000000000000000013214200302440022270 xustar0030 mtime=1644266784.789324158 30 atime=1644266785.437324572 30 ctime=1644266784.789324158 drumstick-2.5.1/cmake_admin/cmake_uninstall.cmake.in0000644000175000001440000000155514200302440023057 0ustar00pedrousers00000000000000IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) STRING(REGEX REPLACE "\n" ";" files "${files}") FOREACH(file ${files}) MESSAGE(STATUS "Uninstalling \"${file}\"") IF(EXISTS "${file}") EXEC_PROGRAM( "@CMAKE_COMMAND@" ARGS "-E remove \"${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) IF("${rm_retval}" STREQUAL 0) ELSE("${rm_retval}" STREQUAL 0) MESSAGE(FATAL_ERROR "Problem when removing \"${file}\"") ENDIF("${rm_retval}" STREQUAL 0) ELSE(EXISTS "${file}") MESSAGE(STATUS "File \"${file}\" does not exist.") ENDIF(EXISTS "${file}") ENDFOREACH(file) drumstick-2.5.1/cmake_admin/PaxHeaders.27918/MacroEnsureVersion.cmake0000644000000000000000000000013214200302440022303 xustar0030 mtime=1644266784.789324158 30 atime=1644266785.437324572 30 ctime=1644266784.789324158 drumstick-2.5.1/cmake_admin/MacroEnsureVersion.cmake0000644000175000001440000001173514200302440023073 0ustar00pedrousers00000000000000# This file defines the following macros for developers to use in ensuring # that installed software is of the right version: # # MACRO_ENSURE_VERSION - test that a version number is greater than # or equal to some minimum # MACRO_ENSURE_VERSION_RANGE - test that a version number is greater than # or equal to some minimum and less than some # maximum # MACRO_ENSURE_VERSION2 - deprecated, do not use in new code # # MACRO_ENSURE_VERSION # This macro compares version numbers of the form "x.y.z" or "x.y" # MACRO_ENSURE_VERSION( FOO_MIN_VERSION FOO_VERSION_FOUND FOO_VERSION_OK) # will set FOO_VERSION_OK to true if FOO_VERSION_FOUND >= FOO_MIN_VERSION # Leading and trailing text is ok, e.g. # MACRO_ENSURE_VERSION( "2.5.31" "flex 2.5.4a" VERSION_OK) # which means 2.5.31 is required and "flex 2.5.4a" is what was found on the system # Copyright (c) 2006, David Faure, # Copyright (c) 2007, Will Stephenson # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # MACRO_ENSURE_VERSION_RANGE # This macro ensures that a version number of the form # "x.y.z" or "x.y" falls within a range defined by # min_version <= found_version < max_version. # If this expression holds, FOO_VERSION_OK will be set TRUE # # Example: MACRO_ENSURE_VERSION_RANGE3( "0.1.0" ${FOOCODE_VERSION} "0.7.0" FOO_VERSION_OK ) # # This macro will break silently if any of x,y,z are greater than 100. # # Copyright (c) 2007, Will Stephenson # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # NORMALIZE_VERSION # Helper macro to convert version numbers of the form "x.y.z" # to an integer equal to 10^4 * x + 10^2 * y + z # # This macro will break silently if any of x,y,z are greater than 100. # # Copyright (c) 2006, David Faure, # Copyright (c) 2007, Will Stephenson # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # CHECK_RANGE_INCLUSIVE_LOWER # Helper macro to check whether x <= y < z # # Copyright (c) 2007, Will Stephenson # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. MACRO(NORMALIZE_VERSION _requested_version _normalized_version) STRING(REGEX MATCH "[^0-9]*[0-9]+\\.[0-9]+\\.[0-9]+.*" _threePartMatch "${_requested_version}") if (_threePartMatch) # parse the parts of the version string STRING(REGEX REPLACE "[^0-9]*([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" _major_vers "${_requested_version}") STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" _minor_vers "${_requested_version}") STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" _patch_vers "${_requested_version}") else (_threePartMatch) STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+" "\\1" _major_vers "${_requested_version}") STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)" "\\1" _minor_vers "${_requested_version}") set(_patch_vers "0") endif (_threePartMatch) # compute an overall version number which can be compared at once MATH(EXPR ${_normalized_version} "${_major_vers}*10000 + ${_minor_vers}*100 + ${_patch_vers}") ENDMACRO(NORMALIZE_VERSION) MACRO(MACRO_CHECK_RANGE_INCLUSIVE_LOWER _lower_limit _value _upper_limit _ok) if (${_value} LESS ${_lower_limit}) set( ${_ok} FALSE ) elseif (${_value} EQUAL ${_lower_limit}) set( ${_ok} TRUE ) elseif (${_value} EQUAL ${_upper_limit}) set( ${_ok} FALSE ) elseif (${_value} GREATER ${_upper_limit}) set( ${_ok} FALSE ) else (${_value} LESS ${_lower_limit}) set( ${_ok} TRUE ) endif (${_value} LESS ${_lower_limit}) ENDMACRO(MACRO_CHECK_RANGE_INCLUSIVE_LOWER) MACRO(MACRO_ENSURE_VERSION requested_version found_version var_too_old) NORMALIZE_VERSION( ${requested_version} req_vers_num ) NORMALIZE_VERSION( ${found_version} found_vers_num ) if (found_vers_num LESS req_vers_num) set( ${var_too_old} FALSE ) else (found_vers_num LESS req_vers_num) set( ${var_too_old} TRUE ) endif (found_vers_num LESS req_vers_num) ENDMACRO(MACRO_ENSURE_VERSION) MACRO(MACRO_ENSURE_VERSION2 requested_version2 found_version2 var_too_old2) MACRO_ENSURE_VERSION( ${requested_version2} ${found_version2} ${var_too_old2}) ENDMACRO(MACRO_ENSURE_VERSION2) MACRO(MACRO_ENSURE_VERSION_RANGE min_version found_version max_version var_ok) NORMALIZE_VERSION( ${min_version} req_vers_num ) NORMALIZE_VERSION( ${found_version} found_vers_num ) NORMALIZE_VERSION( ${max_version} max_vers_num ) MACRO_CHECK_RANGE_INCLUSIVE_LOWER( ${req_vers_num} ${found_vers_num} ${max_vers_num} ${var_ok}) ENDMACRO(MACRO_ENSURE_VERSION_RANGE) drumstick-2.5.1/cmake_admin/PaxHeaders.27918/SCMRevision.cmake0000644000000000000000000000013214200302440020653 xustar0030 mtime=1644266784.789324158 30 atime=1644266785.437324572 30 ctime=1644266784.789324158 drumstick-2.5.1/cmake_admin/SCMRevision.cmake0000644000175000001440000000321514200302440021435 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2008-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; If not, see . find_package(Subversion QUIET) if (Subversion_FOUND) Subversion_WC_INFO(${PROJECT_SOURCE_DIR} PROJECT IGNORE_SVN_FAILURE) if (DEFINED PROJECT_WC_REVISION) message(STATUS "Current revision (SVN) is ${PROJECT_WC_REVISION}") endif() endif() if (NOT DEFINED PROJECT_WC_REVISION) find_package(Git QUIET) if (Git_FOUND) execute_process( COMMAND "${GIT_EXECUTABLE}" rev-parse --short HEAD WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" RESULT_VARIABLE res OUTPUT_VARIABLE PROJECT_WC_REVISION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (${res} EQUAL 0) message(STATUS "Current revision (Git) is ${PROJECT_WC_REVISION}") else() unset(PROJECT_WC_REVISION) endif() endif() endif() if (DEFINED PROJECT_WC_REVISION) set(${PROJECT_NAME}_WC_REVISION ${PROJECT_WC_REVISION}) endif() drumstick-2.5.1/cmake_admin/PaxHeaders.27918/FindSharedMimeInfo.cmake0000644000000000000000000000013214200302440022145 xustar0030 mtime=1644266784.789324158 30 atime=1644266785.437324572 30 ctime=1644266784.789324158 drumstick-2.5.1/cmake_admin/FindSharedMimeInfo.cmake0000644000175000001440000000561514200302440022735 0ustar00pedrousers00000000000000# - Try to find the shared-mime-info package # # SHARED_MIME_INFO_MINIMUM_VERSION - Set this to the minimum version you need, default is 0.18 # # Once done this will define # # SHARED_MIME_INFO_FOUND - system has the shared-mime-info package # UPDATE_MIME_DATABASE_EXECUTABLE - the update-mime-database executable # Copyright (c) 2007, Pino Toscano, # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # the minimum version of shared-mime-database we require if (NOT SHARED_MIME_INFO_MINIMUM_VERSION) set(SHARED_MIME_INFO_MINIMUM_VERSION "0.18") endif (NOT SHARED_MIME_INFO_MINIMUM_VERSION) if (UPDATE_MIME_DATABASE_EXECUTABLE) # in cache already set(SHARED_MIME_INFO_FOUND TRUE) else (UPDATE_MIME_DATABASE_EXECUTABLE) include (MacroEnsureVersion) find_program (UPDATE_MIME_DATABASE_EXECUTABLE NAMES update-mime-database) if (UPDATE_MIME_DATABASE_EXECUTABLE) exec_program (${UPDATE_MIME_DATABASE_EXECUTABLE} ARGS -v RETURN_VALUE _null OUTPUT_VARIABLE _smiVersionRaw) string(REGEX REPLACE "update-mime-database \\([a-zA-Z\\-]+\\) ([0-9]\\.[0-9]+).*" "\\1" smiVersion "${_smiVersionRaw}") set (SHARED_MIME_INFO_FOUND TRUE) endif (UPDATE_MIME_DATABASE_EXECUTABLE) if (SHARED_MIME_INFO_FOUND) if (NOT SharedMimeInfo_FIND_QUIETLY) message(STATUS "Found shared-mime-info version: ${smiVersion}") macro_ensure_version(${SHARED_MIME_INFO_MINIMUM_VERSION} ${smiVersion} _smiVersion_OK) if (NOT _smiVersion_OK) message(FATAL_ERROR "The found version of shared-mime-info (${smiVersion}) is below the minimum required (${SHARED_MIME_INFO_MINIMUM_VERSION})") endif (NOT _smiVersion_OK) endif (NOT SharedMimeInfo_FIND_QUIETLY) else (SHARED_MIME_INFO_FOUND) if (SharedMimeInfo_FIND_REQUIRED) message(FATAL_ERROR "Could NOT find shared-mime-info. See http://freedesktop.org/wiki/Software/shared-mime-info.") endif (SharedMimeInfo_FIND_REQUIRED) endif (SHARED_MIME_INFO_FOUND) endif (UPDATE_MIME_DATABASE_EXECUTABLE) mark_as_advanced(UPDATE_MIME_DATABASE_EXECUTABLE) macro(UPDATE_XDG_MIMETYPES _path) get_filename_component(_xdgmimeDir "${_path}" NAME) if("${_xdgmimeDir}" STREQUAL packages ) get_filename_component(_xdgmimeDir "${_path}" PATH) else("${_xdgmimeDir}" STREQUAL packages ) set(_xdgmimeDir "${_path}") endif("${_xdgmimeDir}" STREQUAL packages ) install(CODE " set(DESTDIR_VALUE \"\$ENV{DESTDIR}\") if (NOT DESTDIR_VALUE) # under Windows relative paths are used, that's why it runs from CMAKE_INSTALL_PREFIX execute_process(COMMAND ${UPDATE_MIME_DATABASE_EXECUTABLE} ${_xdgmimeDir} WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\") endif (NOT DESTDIR_VALUE) ") endmacro (UPDATE_XDG_MIMETYPES) drumstick-2.5.1/cmake_admin/PaxHeaders.27918/CustomFrameworkInfo.plist.in0000644000000000000000000000013214200302440023136 xustar0030 mtime=1644266784.789324158 30 atime=1644266785.437324572 30 ctime=1644266784.789324158 drumstick-2.5.1/cmake_admin/CustomFrameworkInfo.plist.in0000644000175000001440000000133614200302440023722 0ustar00pedrousers00000000000000 CFBundlePackageType FMWK CFBundleShortVersionString ${PROJECT_VERSION} CFBundleVersion ${PROJECT_VERSION} CFBundleGetInfoString Created by CMake CFBundleIdentifier ${MACOSX_FRAMEWORK_IDENTIFIER} NSHumanReadableCopyright © 2006-2021, Pedro López-Cabanillas and others NOTE Please, do NOT change this file -- It was generated by CMake. drumstick-2.5.1/cmake_admin/PaxHeaders.27918/CustomBundleInfo.plist.in0000644000000000000000000000013214200302440022412 xustar0030 mtime=1644266784.789324158 30 atime=1644266785.437324572 30 ctime=1644266784.789324158 drumstick-2.5.1/cmake_admin/CustomBundleInfo.plist.in0000644000175000001440000000246614200302440023203 0ustar00pedrousers00000000000000 NSPrincipalClass NSApplication NSHighResolutionCapable True CFBundleDevelopmentRegion English CFBundleExecutable ${MACOSX_BUNDLE_EXECUTABLE_NAME} CFBundleGetInfoString ${MACOSX_BUNDLE_INFO_STRING} CFBundleIconFile ${MACOSX_BUNDLE_ICON_FILE} CFBundleIdentifier ${MACOSX_BUNDLE_GUI_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString ${MACOSX_BUNDLE_LONG_VERSION_STRING} CFBundleName ${MACOSX_BUNDLE_BUNDLE_NAME} CFBundlePackageType APPL CFBundleShortVersionString ${MACOSX_BUNDLE_SHORT_VERSION_STRING} CFBundleSignature ???? CFBundleVersion ${MACOSX_BUNDLE_BUNDLE_VERSION} CSResourcesFileMapped NSHumanReadableCopyright ${MACOSX_BUNDLE_COPYRIGHT} drumstick-2.5.1/cmake_admin/PaxHeaders.27918/COPYING-CMAKE-SCRIPTS0000644000000000000000000000013214200302440020506 xustar0030 mtime=1644266784.789324158 30 atime=1644266785.437324572 30 ctime=1644266784.789324158 drumstick-2.5.1/cmake_admin/COPYING-CMAKE-SCRIPTS0000644000175000001440000000245614200302440021276 0ustar00pedrousers00000000000000Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. drumstick-2.5.1/cmake_admin/PaxHeaders.27918/CreateManpages.cmake0000644000000000000000000000013214200302440021371 xustar0030 mtime=1644266784.789324158 30 atime=1644266785.437324572 30 ctime=1644266784.789324158 drumstick-2.5.1/cmake_admin/CreateManpages.cmake0000644000175000001440000000301014200302440022144 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2008-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; If not, see . MACRO(CREATE_MANPAGES) SET(outfiles) FOREACH (it ${ARGN}) GET_FILENAME_COMPONENT(outfile ${it} NAME_WE) GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE) SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/${outfile}.1) SET(outfiles ${outfiles} ${outfile}) ADD_CUSTOM_COMMAND( OUTPUT ${outfile} COMMAND ${XSLTPROC_EXECUTABLE} --nonet --xinclude --xincludestyle --output ${outfile} http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl ${infile} DEPENDS ${infile}) ENDFOREACH (it) ADD_CUSTOM_TARGET(manpages ALL DEPENDS ${outfiles}) INSTALL ( FILES ${outfiles} DESTINATION "${CMAKE_INSTALL_MANDIR}/man1" ) ENDMACRO(CREATE_MANPAGES) drumstick-2.5.1/PaxHeaders.27918/drumstick-file.pc.in0000644000000000000000000000013214200302440017133 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.437324572 30 ctime=1644266784.865324206 drumstick-2.5.1/drumstick-file.pc.in0000644000175000001440000000052214200302440017713 0ustar00pedrousers00000000000000prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: drumstick-file Version: @PROJECT_VERSION@ Description: MIDI File C++ Library for Qt5 URL: http://sourceforge.net/projects/drumstick Libs: -L${libdir} -ldrumstick-file Cflags: -I${includedir} drumstick-2.5.1/PaxHeaders.27918/drumstick.xml0000644000000000000000000000013214200302440016007 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.437324572 30 ctime=1644266784.865324206 drumstick-2.5.1/drumstick.xml0000644000175000001440000000107014200302440016566 0ustar00pedrousers00000000000000 Cakewalk project file Cakewalk project file Archivo de proyecto Cakewalk drumstick-2.5.1/PaxHeaders.27918/drumstick-rt.pc.in0000644000000000000000000000013214200302440016641 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.437324572 30 ctime=1644266784.865324206 drumstick-2.5.1/drumstick-rt.pc.in0000644000175000001440000000052214200302440017421 0ustar00pedrousers00000000000000prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: drumstick-rt Version: @PROJECT_VERSION@ Description: MIDI Realtime C++ Library for Qt5 URL: http://sourceforge.net/projects/drumstick Libs: -L${libdir} -ldrumstick-rt Cflags: -I${includedir} drumstick-2.5.1/PaxHeaders.27918/doc0000644000000000000000000000013214200302440013750 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.437324572 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/0000755000175000001440000000000014200302440014606 5ustar00pedrousers00000000000000drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-metronome.xml.in0000644000000000000000000000013214200302440021164 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.437324572 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/drumstick-metronome.xml.in0000644000175000001440000001030214200302440021741 0ustar00pedrousers00000000000000 ]> &product; Pedro Lopez-Cabanillas plcl@users.sf.net 2010-2021 Pedro Lopez-Cabanillas @RELEASE_DATE@ &product; 1 @PROJECT_VERSION@ drumstick User Commands &product; A Drumstick command line utility for playing a metronome pattern. Synopsis &product; options Description This program is a Drumstick example and utility program. You can use it to play a MIDI metronome pattern. Arguments The following arguments are required: client:port An ALSA client:port specification that will be subscribed in order to send MIDI events to it. The client portion can be a number or a name, like in "20:0" or "KMidimon:0". The following arguments are optional: BPM Tempo in beats per minute. Default is 120 BPM. Prints a summary of the command-line options and exit. Prints the program version number and exit. License Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation, considering as source code any files used for the production of this manpage. See also drumstick-dumpmid 1 , drumstick-playsmf 1 drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-dumpmid.xml.in0000644000000000000000000000013214200302440020616 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.437324572 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/drumstick-dumpmid.xml.in0000644000175000001440000000763214200302440021407 0ustar00pedrousers00000000000000 ]> &product; Pedro Lopez-Cabanillas plcl@users.sf.net 2010-2021 Pedro Lopez-Cabanillas @RELEASE_DATE@ &product; 1 @PROJECT_VERSION@ drumstick User Commands &product; A Drumstick command line utility for decoding MIDI events. Synopsis &product; options Description This program is a Drumstick example and utility program. You can use it to decode standard MIDI events as text. Arguments The following argument is mandatory: client:port An ALSA client:port specification that will be subscribed in order to read MIDI events from it. The client portion can be a number or a name, like in "20:0" or "Virtual Piano:0". The following arguments are optional: Prints a summary of the command-line options and exit. Prints the program version number and exit. License Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation, considering as source code any files used for the production of this manpage. See also drumstick-playsmf 1 , drumstick-vpiano 1 drumstick-2.5.1/doc/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440016565 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.437324572 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/CMakeLists.txt0000644000175000001440000000612214200302440017347 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2008-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; If not, see . find_program(XSLTPROC_EXECUTABLE xsltproc) if(XSLTPROC_EXECUTABLE) message(STATUS "XSLTPROC Found: ${XSLTPROC_EXECUTABLE}") if (NOT RELEASE_DATE) execute_process ( COMMAND bash -c "LANG=C;date +'%B %d, %Y'" OUTPUT_VARIABLE RELEASE_DATE OUTPUT_STRIP_TRAILING_WHITESPACE ) endif() configure_file(drumstick-devel.doc.txt.in ${CMAKE_CURRENT_BINARY_DIR}/drumstick-devel.doc.txt IMMEDIATE @ONLY) configure_file(drumstick-drumgrid.xml.in ${CMAKE_CURRENT_BINARY_DIR}/drumstick-drumgrid.xml IMMEDIATE @ONLY) configure_file(drumstick-dumpmid.xml.in ${CMAKE_CURRENT_BINARY_DIR}/drumstick-dumpmid.xml IMMEDIATE @ONLY) configure_file(drumstick-dumpsmf.xml.in ${CMAKE_CURRENT_BINARY_DIR}/drumstick-dumpsmf.xml IMMEDIATE @ONLY) configure_file(drumstick-dumprmi.xml.in ${CMAKE_CURRENT_BINARY_DIR}/drumstick-dumprmi.xml IMMEDIATE @ONLY) configure_file(drumstick-dumpwrk.xml.in ${CMAKE_CURRENT_BINARY_DIR}/drumstick-dumpwrk.xml IMMEDIATE @ONLY) configure_file(drumstick-metronome.xml.in ${CMAKE_CURRENT_BINARY_DIR}/drumstick-metronome.xml IMMEDIATE @ONLY) configure_file(drumstick-playsmf.xml.in ${CMAKE_CURRENT_BINARY_DIR}/drumstick-playsmf.xml IMMEDIATE @ONLY) configure_file(drumstick-guiplayer.xml.in ${CMAKE_CURRENT_BINARY_DIR}/drumstick-guiplayer.xml IMMEDIATE @ONLY) configure_file(drumstick-sysinfo.xml.in ${CMAKE_CURRENT_BINARY_DIR}/drumstick-sysinfo.xml IMMEDIATE @ONLY) configure_file(drumstick-vpiano.xml.in ${CMAKE_CURRENT_BINARY_DIR}/drumstick-vpiano.xml IMMEDIATE @ONLY) include(CreateManpages) create_manpages ( ${CMAKE_CURRENT_BINARY_DIR}/drumstick-drumgrid.xml ${CMAKE_CURRENT_BINARY_DIR}/drumstick-dumpmid.xml ${CMAKE_CURRENT_BINARY_DIR}/drumstick-dumpsmf.xml ${CMAKE_CURRENT_BINARY_DIR}/drumstick-dumprmi.xml ${CMAKE_CURRENT_BINARY_DIR}/drumstick-dumpwrk.xml ${CMAKE_CURRENT_BINARY_DIR}/drumstick-metronome.xml ${CMAKE_CURRENT_BINARY_DIR}/drumstick-playsmf.xml ${CMAKE_CURRENT_BINARY_DIR}/drumstick-guiplayer.xml ${CMAKE_CURRENT_BINARY_DIR}/drumstick-sysinfo.xml ${CMAKE_CURRENT_BINARY_DIR}/drumstick-vpiano.xml ) else() message(STATUS "Warning: XSLTPROC NOT Found. Man pages won't be installed") endif() drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-dumpwrk.xml.in0000644000000000000000000000013214200302440020650 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.437324572 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/drumstick-dumpwrk.xml.in0000644000175000001440000000773114200302440021441 0ustar00pedrousers00000000000000 ]> &product; Pedro Lopez-Cabanillas plcl@users.sf.net 2010-2021 Pedro Lopez-Cabanillas @RELEASE_DATE@ &product; 1 @PROJECT_VERSION@ drumstick User Commands &product; A Drumstick command line utility for decoding WRK (Cakewalk) files. Synopsis &product; options FILE Description This program is a Drumstick example and utility program. You can use it to decode as text your WRK files created with Cakewalk or Sonar. Arguments The following argument is required: The name of the input WRK file. The following arguments are optional: Prints a summary of the command-line options and exit. Prints the program version number and exit. Verbose output. License Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation, considering as source code any files used for the production of this manpage. See also drumstick-dumpsmf 1 , drumstick-dumpove 1 drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-vpiano.xml.in0000644000000000000000000000013214200302440020453 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.437324572 30 ctime=1644266784.845324194 drumstick-2.5.1/doc/drumstick-vpiano.xml.in0000644000175000001440000002567714200302440021255 0ustar00pedrousers00000000000000 ]> &product; Pedro Lopez-Cabanillas plcl@users.sf.net 2010-2021 Pedro Lopez-Cabanillas @RELEASE_DATE@ &product; 1 @PROJECT_VERSION@ drumstick User Commands &product; A Drumstick GUI virtual piano utility. Synopsis &product; options... Description This program is a Drumstick example and utility program. You can use it to play and watch a virtual piano. Arguments The following arguments are optional: Prints a summary of the command-line options and exit. Prints the program version number and exit. style sets the application GUI style. Possible values are motif, windows, and platinum. If you compiled Qt with additional styles or have additional styles as plugins these will be available to the -style command line option stylesheet sets the application styleSheet. The value must be a path to a file that contains the Style Sheet. Note: Relative URLs in the Style Sheet file are relative to the Style Sheet file's path. session restores the application from an earlier session. prints debug message at the end about number of widgets left undestroyed and maximum number of widgets existed at the same time sets the application's layout direction to Qt::RightToLeft sets the backend to be used for on-screen widgets and QPixmaps. Available options are raster and opengl. display sets the X display (default is $DISPLAY). geometry sets the client geometry of the first window that is shown. font defines the application font. The font should be specified using an X logical font description. color sets the default background color and an application palette (light and dark shades are calculated). color sets the default foreground color. color sets the default button color. name sets the application name. title sets the application title. forces the application to use a TrueColor visual on an 8-bit display. count limits the number of colors allocated in the color cube on an 8-bit display, if the application is using the QApplication::ManyColor color specification. If count is 216 then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green, and 6 of blue); for other values, a cube approximately proportional to a 2x3x1 cube is used. causes the application to install a private color map on an 8-bit display. sets the input method server (equivalent to setting the XMODIFIERS environment variable) defines how the input is inserted into the given widget, e.g., onTheSpot makes the input appear directly in the widget, while overTheSpot makes the input appear in a box floating over the widget and is not inserted until the editing is done. License Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation, considering as source code any files used for the production of this manpage. See also drumstick-drumgrid 1 , drumstick-guiplayer 1 drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-sysinfo.xml.in0000644000000000000000000000013214200302440020651 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.437324572 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/drumstick-sysinfo.xml.in0000644000175000001440000000570714200302440021443 0ustar00pedrousers00000000000000 ]> &product; Pedro Lopez-Cabanillas plcl@users.sf.net 2010-2021 Pedro Lopez-Cabanillas @RELEASE_DATE@ &product; 1 @PROJECT_VERSION@ drumstick User Commands &product; A Drumstick command line utility to get information about the ALSA sequencer. Synopsis &product; options... Description This program is a Drumstick example and utility program. You can use it to build a report containing useful information about the ALSA sequencer. Arguments The following arguments are optional: Prints a summary of the command-line options and exit. Prints the program version number and exit. License Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation, considering as source code any files used for the production of this manpage. drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-ecosystem.qmodel0000644000000000000000000000013214200302440021246 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.437324572 30 ctime=1644266784.845324194 drumstick-2.5.1/doc/drumstick-ecosystem.qmodel0000644000175000001440000014162714200302440022042 0ustar00pedrousers00000000000000 {47d56938-7b53-47e3-ad51-765969fce542} {68d7107b-1399-432f-9af5-edf91cde4edf} drumstick-ecosystem {b02e24be-4978-4575-9045-4252bb5b8c0c} {b02e24be-4978-4575-9045-4252bb5b8c0c} drumstick-ecosystem {e90a6748-6ab9-4521-97cd-fe505b32e046} {7726ed01-e4a7-4e0d-9322-84e778dc2c3f} library Drumstick::ALSA x:110;y:-310 x:-75;y:-30;w:150;h:60 0 {69e44e37-e180-42f8-883b-0cbbd0f6bbf9} {3dad3b7a-c863-4a2c-bd91-9f6f34dd5d22} library Drumstick::File x:250;y:-200 x:-70;y:-30;w:140;h:60 0 {2994929f-78c5-41d4-9e8a-91fa5efd55a1} {1d4b22db-c088-4d2e-b3de-0114fc13636e} library Drumstick::RT x:375;y:-305 x:-70;y:-30;w:140;h:60 0 {dc419392-dc46-420d-8fb9-6ad679983c44} {738f1658-0bb6-497d-8345-2cd495314a08} library Drumstick::Widgets x:560;y:-205 x:-85;y:-30;w:170;h:60 0 {ace9a9c0-c199-40a1-a24f-cfcb738631f7} {fcac40d5-789b-49ab-ba4a-1fb40c0a48af} application kmetronome x:65;y:-35 x:-45;y:-25;w:90;h:50 0 false {6dcc50b0-99b0-45a5-a0b7-e42fdf2a5a13} {c295a2cc-c327-4f47-a365-3f401a859541} application kmidimon x:160;y:-35 x:-35;y:-25;w:70;h:50 0 false {d284cca2-d46b-438f-9efb-c2b17567b7d9} {84d17b47-83b0-4d47-80a9-e78138286118} application dmidiplayer x:350;y:-35 x:-40;y:-25;w:80;h:50 0 false {487ed391-dd29-46b0-abb7-3bf6ef825a9b} {38603669-f85f-41f0-b4bf-88bc519e5958} application wrk2mid x:255;y:-35 x:-35;y:-25;w:70;h:50 0 false {7fa7c7ea-e29c-4660-90d8-3d427642943c} {a9dbdab5-b13d-4af0-95b2-aae83c8ec44d} application VMPK x:445;y:-35 x:-35;y:-25;w:70;h:50 0 false {a0fef4b3-fb1b-4232-887b-b9bd549abb6b} {8e285950-f0f1-406f-bee2-8f3461aaf648} uses {ace9a9c0-c199-40a1-a24f-cfcb738631f7} {e90a6748-6ab9-4521-97cd-fe505b32e046} {660a76e4-a696-416e-8928-6057633d97d9} {d3dfa591-b798-4184-bc05-d19dbaecdf4c} uses {6dcc50b0-99b0-45a5-a0b7-e42fdf2a5a13} {e90a6748-6ab9-4521-97cd-fe505b32e046} {ce5769d2-d5c4-4b05-ad61-f40f9d31b1da} {d84e35f5-20b9-4cce-ae19-77a2591bc7a1} uses {6dcc50b0-99b0-45a5-a0b7-e42fdf2a5a13} {69e44e37-e180-42f8-883b-0cbbd0f6bbf9} {96e0bc6d-f155-4637-b43e-d0cd847fc78a} {02a572e4-e948-426c-b21a-95c6b4195540} uses {487ed391-dd29-46b0-abb7-3bf6ef825a9b} {69e44e37-e180-42f8-883b-0cbbd0f6bbf9} {c6de2eab-3279-4c72-9b09-4e8aeeb95180} {d09e7a2a-925f-4776-8975-04f8f1111ba4} uses {d284cca2-d46b-438f-9efb-c2b17567b7d9} {69e44e37-e180-42f8-883b-0cbbd0f6bbf9} {9b6aacaf-7688-4d75-8c2c-f85ae0a96593} {4f10981e-fefc-4922-af20-99c1a214b806} uses {d284cca2-d46b-438f-9efb-c2b17567b7d9} {2994929f-78c5-41d4-9e8a-91fa5efd55a1} {59b8c001-2425-4666-96f7-d38bebc76ea4} {75bf8e97-91c6-4d14-903d-89fb41659fce} uses {d284cca2-d46b-438f-9efb-c2b17567b7d9} {dc419392-dc46-420d-8fb9-6ad679983c44} {581a9749-4454-4c6e-b6ed-b71ee2d0af5d} {903bd59b-62eb-4672-96bb-ab529d7db20d} uses {2994929f-78c5-41d4-9e8a-91fa5efd55a1} {e90a6748-6ab9-4521-97cd-fe505b32e046} {5f1fd565-98ff-4e89-9902-57c76b2aba6c} {6fdc35e3-7c68-4f2b-b67c-7b0c4bc1a483} uses {7fa7c7ea-e29c-4660-90d8-3d427642943c} {dc419392-dc46-420d-8fb9-6ad679983c44} {0e9e928c-a2b1-49c9-8f18-5ecb116c624f} {f8ba77da-cef3-49fe-a263-6878b456ba00} uses {7fa7c7ea-e29c-4660-90d8-3d427642943c} {2994929f-78c5-41d4-9e8a-91fa5efd55a1} {ab6b12b1-092f-4c69-af23-353a42267d8e} {30a7d630-9f71-493c-9420-2e6ec46e353f} library FluidSynth x:615;y:-305 x:-60;y:-30;w:120;h:60 5 {5fd2d49a-5320-496c-845a-c2a14b9fc9e3} {129c7e9f-d97e-421f-8419-cc764c9bec15} uses {2994929f-78c5-41d4-9e8a-91fa5efd55a1} {ab6b12b1-092f-4c69-af23-353a42267d8e} 1631617481319 General {2daefbdc-4a3d-4b57-be2c-a1cc3f6f76f1} {2daefbdc-4a3d-4b57-be2c-a1cc3f6f76f1} Drumstick::ALSA {05946d7b-dfe5-4db3-a20a-4aaf4d3521b0} {05946d7b-dfe5-4db3-a20a-4aaf4d3521b0} Drumstick::File {5434f3c9-9e2e-47c2-a5ae-66114f619baf} {5434f3c9-9e2e-47c2-a5ae-66114f619baf} Drumstick::RT {b082fbdf-9a9b-494c-b06f-ac8d71611f9d} {b082fbdf-9a9b-494c-b06f-ac8d71611f9d} Drumstick::Widgets {7726ed01-e4a7-4e0d-9322-84e778dc2c3f} {7726ed01-e4a7-4e0d-9322-84e778dc2c3f} library Drumstick::ALSA {3dad3b7a-c863-4a2c-bd91-9f6f34dd5d22} {3dad3b7a-c863-4a2c-bd91-9f6f34dd5d22} library Drumstick::File {1d4b22db-c088-4d2e-b3de-0114fc13636e} {1d4b22db-c088-4d2e-b3de-0114fc13636e} library Drumstick::RT {903bd59b-62eb-4672-96bb-ab529d7db20d} {903bd59b-62eb-4672-96bb-ab529d7db20d} uses {1d4b22db-c088-4d2e-b3de-0114fc13636e} {7726ed01-e4a7-4e0d-9322-84e778dc2c3f} {129c7e9f-d97e-421f-8419-cc764c9bec15} {129c7e9f-d97e-421f-8419-cc764c9bec15} uses {1d4b22db-c088-4d2e-b3de-0114fc13636e} {30a7d630-9f71-493c-9420-2e6ec46e353f} {738f1658-0bb6-497d-8345-2cd495314a08} {738f1658-0bb6-497d-8345-2cd495314a08} library Drumstick::Widgets {fcac40d5-789b-49ab-ba4a-1fb40c0a48af} {fcac40d5-789b-49ab-ba4a-1fb40c0a48af} application kmetronome {8e285950-f0f1-406f-bee2-8f3461aaf648} {8e285950-f0f1-406f-bee2-8f3461aaf648} uses {fcac40d5-789b-49ab-ba4a-1fb40c0a48af} {7726ed01-e4a7-4e0d-9322-84e778dc2c3f} {c295a2cc-c327-4f47-a365-3f401a859541} {c295a2cc-c327-4f47-a365-3f401a859541} application kmidimon {d3dfa591-b798-4184-bc05-d19dbaecdf4c} {d3dfa591-b798-4184-bc05-d19dbaecdf4c} uses {c295a2cc-c327-4f47-a365-3f401a859541} {7726ed01-e4a7-4e0d-9322-84e778dc2c3f} {d84e35f5-20b9-4cce-ae19-77a2591bc7a1} {d84e35f5-20b9-4cce-ae19-77a2591bc7a1} uses {c295a2cc-c327-4f47-a365-3f401a859541} {3dad3b7a-c863-4a2c-bd91-9f6f34dd5d22} {84d17b47-83b0-4d47-80a9-e78138286118} {84d17b47-83b0-4d47-80a9-e78138286118} application dmidiplayer {d09e7a2a-925f-4776-8975-04f8f1111ba4} {d09e7a2a-925f-4776-8975-04f8f1111ba4} uses {84d17b47-83b0-4d47-80a9-e78138286118} {3dad3b7a-c863-4a2c-bd91-9f6f34dd5d22} {4f10981e-fefc-4922-af20-99c1a214b806} {4f10981e-fefc-4922-af20-99c1a214b806} uses {84d17b47-83b0-4d47-80a9-e78138286118} {1d4b22db-c088-4d2e-b3de-0114fc13636e} {75bf8e97-91c6-4d14-903d-89fb41659fce} {75bf8e97-91c6-4d14-903d-89fb41659fce} uses {84d17b47-83b0-4d47-80a9-e78138286118} {738f1658-0bb6-497d-8345-2cd495314a08} {38603669-f85f-41f0-b4bf-88bc519e5958} {38603669-f85f-41f0-b4bf-88bc519e5958} application wrk2mid {02a572e4-e948-426c-b21a-95c6b4195540} {02a572e4-e948-426c-b21a-95c6b4195540} uses {38603669-f85f-41f0-b4bf-88bc519e5958} {3dad3b7a-c863-4a2c-bd91-9f6f34dd5d22} {a9dbdab5-b13d-4af0-95b2-aae83c8ec44d} {a9dbdab5-b13d-4af0-95b2-aae83c8ec44d} application VMPK {6fdc35e3-7c68-4f2b-b67c-7b0c4bc1a483} {6fdc35e3-7c68-4f2b-b67c-7b0c4bc1a483} uses {a9dbdab5-b13d-4af0-95b2-aae83c8ec44d} {738f1658-0bb6-497d-8345-2cd495314a08} {f8ba77da-cef3-49fe-a263-6878b456ba00} {f8ba77da-cef3-49fe-a263-6878b456ba00} uses {a9dbdab5-b13d-4af0-95b2-aae83c8ec44d} {1d4b22db-c088-4d2e-b3de-0114fc13636e} {30a7d630-9f71-493c-9420-2e6ec46e353f} {30a7d630-9f71-493c-9420-2e6ec46e353f} library FluidSynth drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-dumpsmf.xml.in0000644000000000000000000000013214200302440020632 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.441324575 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/drumstick-dumpsmf.xml.in0000644000175000001440000000751514200302440021423 0ustar00pedrousers00000000000000 ]> &product; Pedro Lopez-Cabanillas plcl@users.sf.net 2010-2021 Pedro Lopez-Cabanillas @RELEASE_DATE@ &product; 1 @PROJECT_VERSION@ drumstick User Commands &product; A Drumstick command line utility for decoding standard MIDI files. Synopsis &product; options FILE Description This program is a Drumstick example and utility program. You can use it to decode a standard MIDI file as text. Arguments The following argument is required: The name of the input SMF. The following arguments are optional: Prints a summary of the command-line options and exit. Prints the program version number and exit. License Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation, considering as source code any files used for the production of this manpage. See also drumstick-playsmf 1 , drumstick-dumpwrk 1 , drumstick-dumpove 1 drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-ecosystem.png0000644000000000000000000000013214200302440020551 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.441324575 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/drumstick-ecosystem.png0000644000175000001440000023632514200302440021345 0ustar00pedrousers00000000000000PNG  IHDRYE pHYsodtEXtSoftwarewww.inkscape.org<tEXtTitleQt SVG DocumentwRtEXtCopyrightCC Attribution-ShareAlike http://creativecommons.org/licenses/by-sa/4.0/Tb IDATxu\.݈(! ؂؊-zzgyޝ?nA5/wgyavw<< I$AAA!(;   B&SAAA!]TAAAHW"0AAAҕLAAAt%SAAA!]TAAAHW"0AAAҕLAAAt%SAAA!]TAAAHW"0AAAҕLAAAt%SAAA!]TAAAHW"0AAAҕLAAAtH $ OCCmmΆ   C;9|l_zgC2<]]=69rwVAAA%W_./ʕOB[(SAA!C))E MlBYAA$e4 L|>AA)K[AA!:$EO $M|<AA *nA2(;fJ ttt;B*2*!ds:hh^8Sq-_">B$gAH3tC^Ί?I&n * F*ZχHċϨP"AH[m"0RWDQ'HٔW\۵D`N$q-!#C| ن! -B!S!}hOmfTH]ǏĭTI߼yccll)g d _N?t2շnySV $mΑC@gtvlߕwNAHbS6AR5?u1"j+:3!c7KA~O8T`*.SSܽgOacSc44,[G})_ 9| 2b\\ѴyCN?g ^ڔ)[ `ז}ٿ+EWWu\}}}*Wχq$A#C&f/7/SkiO<|L~=x 9ի܌аpYDj G+N=#;wŋSFM޵/DCCI0,+ţ~>|ԂW!eRỉS!=/Ӑ^yI0iZ޼~Ź 牊D:$c7<~kM~.Q{-A e7a$..Eiռ#}v ݽϬ9STUk˯9qH<~ gN3?B:9"TR+ӱ]7/͈!;w.JtMb*SAAI8;f3wpwۺŇej7c֜i|uB ȯp}؈#""XƛNkn޸M5jA)/Yz#T{ZkRg[ΟČhtʩzVVV䲲L .LSS>DT!{Te5`$I$UH5Mգn12P>M)/qN? FFד$9A](Zz\zC=)gT^)a˂… $d =}N~=>\ ^jο`B$Z)]!׮^$ƎCG=b$?Cz7ֿn\~ݯ/[7-a鞿3ԯ1%Ԙb?O6F1 V!/M# P>Nwӹoe LseQR9&xK8s<,IXv;]_;aLGWeGw"%e2O/$}/!eb˭k7=<3:~~b\|vhӆvv${1*?S?0UIT#0Ux MJ {J1s%++K@b*\ٻ+ :s%>xU/ Hf쿈_;;+ MM y;EGGeWQQ*Zn"/kס%f9MqrvL̄F.&88P06$JWWL ex-nݡ`,[2eݨQӝS'ryT* գ@g>Nܸ~'NSb9\,)R$_X$CB&/=t %~ݺs^jU˰}ܺsGH wwʕrZ}NJ@!o¥KSR$OcɪԹ!@).s:"'ve_hզZwܵ~UQQ(4l=.{.ɝf\n-M6GRT1_ ,vm;E`[/)R ƍŋxEPP0 D ./JbI*Y}==jN͔vsc\|ϟQf- i֮ OGӹ}{|)R܅ 4 'dSlJjL]q ma](4{ܗ`WKﬤn#ʗ+hqqT ~;}ǻ*%)ZL2=bZ7I?n}l޶F~}q.DAOwh;ZZZDEE1\x%]9z8?c G>l߽Q!;xu6F9sbW< _wu>ъ!к'۷'Ѧ' UB2h[R+\Dh>O'{9Ǽ)i!|_ =QGDT7@Y̊R^KQ( PDabj~я!#`kkgAH-}G6Ԫر}'^C}7',,p$v1 B!I eUbp}AhjhP* @?E߇*INRP*P(}ol6nŸƑٙI5 a| 73z0yFRo~8TLU*$֘@BRK ݕ#vޙK2//{r9͢$n\|MyCCda%,YtC GG;ϟ)\ylA)]:Rv3y/4C :IviZ}V\<9?VF.P &K<]rE~}=kkGplːxy*1޻ENdttiٴ)s.gr?|[صi3 Z`_PY|~TLVϘS!3稐Xv30o"J)#xf95quW\g@aXZhrS-mc.U$I8t(,M\F={a=mZg/o2e+OBRe>my@^( LMMX2{o޽p-oppKѢ\!CppPqsc漹~ Dضvnߞͳsh?~d儇ѷG׭h'3ԘTf : 8G@LE=h,Ws C#@b!;=zwRr޵/^m%J1zyl\OLalc6XZZ*WJI򲞽Pd19dϦi o e{$9hΎNHt vH4iЈ=zr]\̿RjU$ oڿjy9x zuN++}x$A5X]Eۖ-e5wl.{RϘf,RR$ BF%Q! F"ī̤]GyڵeiI ԎY___'ށUVR[?iܤ>&&ƙȎMy3 fƼY]~]yr[Qý<@WGn:?lDmv6DbIt۶{tuML1?a+q]<###444x-~~~ۣ# ɓ'X[[RESSJePˍD ;0bӆm;Mwee4tq5o Y:{n,54HAȨ9%ahh9r`ݺu[]vqvvC}R);d@2%ŋIB"\fȎfwǞMc:`~e.q&oҥ\vkΊ+:vvvӥK FB8<*OS ͛7R 7tM>'OLʕ)^8ݻwm۶ͅ) E|AH%R6kn!Ks n$3o֟ćR2;JŸq1b+V@+W.hjjrqwwCBŋԳgOrI2e8|0W\!_|̟?=== =zʕ+>}:M_Tfzի/f<~֭[SpaTڵkt3gΤdɒ-[իWw؁; QFܽ{7[e;n1e'5?DO BhRJ%Vk׮9rVXAN&44TNԔ?AQF qqq!""ǣhEaժUܸq2eжm[>̨Qشi}m۶TT) ^^=>~H׮]Yn%KÃC&{|_~/_3g3%… Yj6l 00 +:t`Ν8;;sEz*gtЁ'..{՘F׽s SBBhjzEVRnB@iX+Qpttu.""]3xx_ )FK^@@ aaXXwV~9GQu6+T `x{{ӼysZhAѢE9wǎΎɓ'U/_ٳ+W0055Ņ ҳgOJtԉcǎ~~~ꢭ?äIP*xm۶ٱg1$~ # rQQQmۖƍk.m <@WWRJ/^̘1cprrulڴҥKT*y)*T^|i׮͚5ĉNl7%Q~9j!uq D>'4߷Un+44_ e  Ks峧UftlH|͛o4NMwdwjuU(mىgPy0j]9D>' Vp։$׽v&҅PFef#((iۮ9OCM?^*K2j(FAB2={ʯO< @ѢE};wQggLŕ |SC&M(Z(.\@WW7ɴ?kfb8::144ח^z1`9mfb޽ 0c2zh<==Q(,_ sNTG"M6{T T,R~7o_ԌJT*9pt+Q<}1z|aEjQF"I54EѨͪ )S-Mn&,,Yz~mpڵFB>=}=̝;-00g&LN&Y0`/_m۶4o<.zE^\q$盙=WF jԨQ٩TH\P 7k޼9ԩSe˖1~|ZBXrҥKyG^ccc̙C͚5L2:ucǎ鉑͚5c۶m˗+++v l YH'JHH1Ϸf )ܥxQJrI46p9PN޿HTTgHē'xvr:aaHćyJ3ٶeDy|5{v`j:~&W.]G?$I<6>} `ߞC'o#?~:??\NpP0l۲?"Ilݼ>s-ܾٸn QQQeLN>׌?bEprvG -Q5֣ZZ}0ϝ>RtԉUP(8vWg}|t+;LH1!izw!7eNNN̝;-[2gv޽{ŋ@sw{-уǏP~}f͚Exx8ݢߟ0>}@*UU=ƍL8ooo:wСCPB$ҽC4(:NLbJe:.+R훳b: ĥx=͵+7pȗ52q:XvQ"a̅sr+hjjs͘N}ܸv}?zs,]#&Rp~BCByp3M3S @Q(L2zkQ˽ KWͦ~:lC^PwosY ՟ )FuPX!,ұ7aĘ:q0l '~&*W@6M3r'{~q6E] 'ɓg>y7Xz M>2`f͚ĉ122b޼ytY"Uc BvPn]G91cIB IDATz:]vÇʕǏ˭IƍG%O&8rfܔ7nѯ?{I߆гwFB4%<,\^'$$~%3 (\ ]w~:HHu-LhPKODD$ocSףl{xe^&mIV4`4/^s&J~f\@>nLmx=9SW8|H7C իWoL0cc4ΡS`$svv wΝ;Ӽys޿O޼y$** ŋ7o^rccco۷oN~fחO5 {{{ F~o`̭(Zr4K 3e\ f9L2+ߘ?JpP j-Z5g^>o߼ қPpeƏOrI%~fZn*U<ֹ^-ϟ9b\x*UЪU++۷1cJ:AS>###P*hkk'/9!,--ɟ?ZGJ899acc#VL`=ۨ߹}ƌL1 K՘f/)qJ442s)LsIm#::XX^BUn y$KWͦg_\ Vm[;dOc`V2i`9(.C__/ɲHκ՛026䏑 88[wѶC/OMM%E޿z<Ç49s%B=|[w1m4ș dl H ItQ5o/m*TK _n$$B#T[-|>eIs f9rhIyE L7%,UUWw.]D޽1i<:t`ԩXZZ&J{oߥDCke(Sҍ~vW`g#'qN :;d,,:c{IzhQρ\|s3T޸!,.Ѩ)? 'B L%28&~~ ݻ:p[H1"kcJ޹3n{,gO_0%$b|nٻ kVAK[BBB)PIs sΝD(IѠLjɌ<]]n\MG```hT +ѼU#޾yЁc޳3* E>]([WoYFhhhC*c k2hX$):}L-&&<}O_V,x=O,g\Kc}( կ[m왋=n(ZZc$I܌|v޽LJGgyާOV LhժUhܸ1[5=}Z;///ŋ<9 R$mT7Y8~8q奶Er/zzzШQ#9JСC& :$""B9+!η aYYY=תSzwä 32eݰ&**nR;s{;;ab< %b3z9}%,43/A 7[ܻ'015XB5KQ(xQ ț6ܹ}cc\]KGO|JynŽz%޼~˝ZbzTZAXףrIhe. XA%Kr)V\ٱc^^^'Kʊj~;޽tƐ$+7c##T*}/{舍ڲGPəу*.@@<~L֊YʝpvGPpZ[s-^~Mg'm]ܼs~ɝ kgB .\>.E %ue+l?VQQQ[J\ }vGhhS;x`]WhiB45_E=.{*?QhH89ѰmҜ߇³K[mX`9+6PɕՠF˭+avُka*T*ͣn.suϞ(JmaHz2CzQB)zwLppJ2˭V(zX&uыw1EFL7R^AU#QfE8 -Z2n8tRxȑ311͛7XJ%XblذA~LXXtRJurre˖@tMkHHtuJDΣG^=|߿/+wjiHHjJիǮ]gΜQ  |du1uT}@zرTTI~l2N> Dw6 [KK|}}}o)r:Itr _MMMyHF16a Cpp54btҟ0zACPJ#+0g"nߺ nHHss3f=P(O3Sv&w+"""ұ7ǎ/^#IWd?پu7*DN}Pr!=°Acym`ߑY卙)Q*+OţNMY8B3iTVȅkGwca.֩ %Ku^^_O/&M$\COOm`ӸMO<רsjJrz'/caii,,YO|@n?> TY˷q"##qrvmZ{ҥ{tuko˞CZ+f!o~>6xx_z@i2Q]ttO<' \Xks^^eeeʔL2)SyfΝK5Rm KK$ %dnn._SjUV#GL&$󂂂KY:'0˙I!z񄅅)ekJEWy[wBDDD/AJoӱM9j#!ѸZΓ E}ž>aa1$."G̘1N:ѻwo*VH6mZzg-C۾g W,gÒxԬExDzt4kδ9Ӳ^ÆSjU;) eMSZ1;p(CeÒ\0?INuscTWޛV~޾ȧ5n9s生]<^ L3۝#M-Mf\10&<-ym4ە$ M-MXmRm=Bc@d6fiWAb%LP(ʣxbjcǮ\Yv$Ihh1|@Гۏ<~k&9SWW///ڷoO=U:tM`eWI T*ɗ/_ַk׮)J[fMj֬Ǐg)J{ k###ijjrVVVjiZ툈f}nҔ'7WWԞKwjӬ)N IQzu.]W^JxEjm2>Bb _Oʬr[^rgKYr%d߾}t)&I=WT*ۯb)J[nDT*F@EɼFO17⢰nH:J&\yƌs>πDn7޿ aە$,|}6%FPҹ]O45?d%':1J#)dt^CflܸQ~ׯ6իDŽ GeРAI0`s ,`I7oZrX=9rD飇o߾MF/?Rv$YfML):}4}M2m޽嗸ږ-[dYf5}>|8H2}0337i҄ϟ'JgiiϟrL>]~Ez(6NJrJ%:u^z 2ӧQ`aq֖<ɵNO_~ŽbEbmҕwĔUsʅ~>$ b*BCC|yh Ӡ\| 5Mi%w\iX~~\rUʋ6L Yj׮СCdҥ̛72B\H$xx/]óK[J6Ċ:$$Dm= I M$Cy}Av͘?gyv7k(mR#I<ôcIcG)V~=ѵGG'dX$gNK,͏aD)$rpP555M6m\EsN6mgȝ'/a<...%Jgaa^KK+;: &&&ɦM؂*ٴ [8::&V+c9EMTƞFی&s<\:Qj]*sb9r0~N 6aÆ_O+E/122Jq^ .IHNݿ(ĉSNOO/y͟?&燗gϦhѢl2=]]C݋יaRlmڼGO|u_%g^}-k .\̩0ۆ[R(ۨ$ Sܝ ILb$yxxp-ʟIR8sLowosE~3^S@⭯@[} >̙S~QH %$H hްvn*ʟ'q@O_}G"!{~̛֭鳏6DyWl 5ǘO2?AVW\RJtܙ:up]\M=Ӣ/P[btv&wdiP=:yn8-]qʔt#w>SN- 8H!jVƚǫהwjݚs.Ѷioλ%-5s>ΌI?-SHԠ9sMkݻƍk2`/\ίa:ؾ};M6,y IDATΏ<ԥ@9\̛*44i]ĝwT*=}A\I.έhjjR(aaa| "--Mr={J%9:jH,sY>xLdd?s] (\!|hї/_/F-V ?)k Om>#J-)C_J)@pp޾.ZAAܹs=2s) 3vXfϞ3fJk ƣe7_}&:Ϋׯ΃FuC<{'Glr01AOO^zh7qCbmWx* {[;$x~쥋iՒGck) AX[=#Rx9Vr3n$Iypp-R#CCxASS !!I!#{+b_${z4[d{hhhTH}R̕xHEP?'ȐeKד'9af6/&oCCʔ+~cΝܹj$ICCFr9L(UZ^̊t,}}DV~Hʕ+2dAAA=:K`uK4?:iki%N. r+ag;76 :Kh޲Wcs-R( "Q `jbi󳳟F?cH.8G8زc=i_In ܸ~3M P _O(.]#?G/_0s77}SP CS͜dЀ@J%W}+F3AA?{ptDQ ذF5Ƙ{l)51_5iMQh,ذػwEV, eYY.{^ydgg=3s޹s(GN`ƍl ^JaKY$v)TњIbUaBυpR(5j4x5k2x8u"*U*Rh9c7(eI%$%1{:VOw~.>;[r0'Cx uU݉o&ļШ~o@ҕlZL\)"!";+++M0 fܺ+ƽM{wΚ;ǎ_17Mb(YAYww"6MᴘKbVtOQ\H`ZQ}b[T B((Z3:E&Sh1U0S ȅ\H3ABYJf*2=9*(>*r2N$BB`]yV}<ؑSs|Ak%$B<s\B?zHˆ[L;8ҢY ёWGE٠Z[PK t$"tB"_!DA1T˜1h4tj׵{"N:xOQsj1MSMd0S _!&9cJG| !D0{L@*Tm_!M"7b'!x&fٕW2SQ8LbA$BM"'j1E)!D28*T!DA2SE{<S9Pb*'B<|?DviiaL8:W; !Dr+"3w(D""_!E" 9ɆX;ƠUZSvuZQ svf Zoʽ$bcqr-mzxPREBȨ!-BBM"+%h׫jh7ëZ%r:%(lgz=tgΦyh4ȁT=B! &BBE4sE '~#"l!BdUDS.GBPt}IMx4~!BTdѱsX0̊V|e*{U|5/]d)g ):]ZZ!#Bg# 5sLPn#-?̭[vҮck:tj]r'OBr&օȪW ʖ)vBH'!B)iivfel!^^^\ gĺ=dرcqww=p 7ܹB%b*DZL a(EwyHϞ=Y`.](,_Dpp0|M!G,BQ(2ɤTD0vJŊ?pppۛ 7oݻ+WУGO?~<>>>tk 0 ~a6dWABMb*Ԥ( &""+W@޽ -#88///yݻ7gϞ-C+2dI!Ib*mʔ),[?Uߟ۷oqG~>==˗ӻwo%yc JYɒZ[0DZ %+E`[ܡ(t^lْk׮qQJ.rnݢL2O >?C?}vZnMŊٺu+tЁH!$թS>|8o6 g:v숋 .ԛ̺ur zkkk.]%ݺuchBڵkY`3fQFz\/fwEiժիWg͜;w.]\ !0_ҥ ueԩ ݺu#((Ho뉏[n.ݝ+Wr F !y&Æ gϞzM 777O2mۆ͛7ͫ[.ׯСCٓ4aV!DTpZ-˖->ۯ_?.\u,YBͩXհaC~w4 Z>+歷BQ~'666̚5;w<۷f͚j*6mĠA,Ib*rh۶-aaa+W. "5knx֯_OϞ=*}2s'~B l2~7roܹs,Cղk.]7Zn͒%KXddBQl_*/{=4Ouh4Ӈ`RSSYv-)))kuƏ/ !S~: W^uWWWÏ?Hzzz?~7oҺu<ҥ s~cܸqBF͚5|o߾oߞwjݻnnݺŤI +pH:t(L2ˍ=+Wv\߶m...ԯ_ۗiӦ_3y䧎[!JSGx]63g|߿Oř;w.})|̚5aÆaڵk۶mKRR{^6mpvvfٲe{ҤI?S2f̘']!JZL ۻ@ʲjժ9s@Bsq5}||%cƌz󓓓ٷo_fܸq|;6hB!ēT<7nK5 L___BBB y$ÅzR!S!Yf (ԩCRؽ{w/|Ib*%,,BQQQxxxJKb*Ib*e˖̘1v+V(z)grB+_!yT<۷*gfڳg=z 99B&==X aÆqҥB+_!yT___i1B#F!(0E#w^.\ӱT;!ܹ35k֨B"@S!زe 666z]SL/͛rQ!3B!D?2k,۷9}ABQIb*ݻhZBQQQxxxz, !(G9r$;v4x111۷ !)13L---  "" !( ¤tDL/fĉܺuu !)R7nn:W\\B䯉xs|}}}6׮]3xBanݺEJJASIJB"ݻwUILԩ 3B|UHB''SXX*iҥqss̙3[!L bŊ;66u !(Z$1y x+WN}}}%1B|R 7x鯿.Hb*t|}}h4+]y+B<ILEƍUBx 4Ig*hEQB!&<<;;;ʔ)c;t@bX|BQ4HBQ3QFRw@@vLB<5ILB" ** U $66gϪRB'Ղ \2ƑsTA!LALL nnnGZtRB! 7߰d.\jBabbbpwwWn+++i-BLT*,,5j>>>\|DCB@bbjBT*,,;>>>hZBCCiذ!QP+0}17HMMU; ! (FQ;T䐞ŋV;̙3 !D^- QbEUOP. yƥC.7A0 FS˗Qt嵲ۛCBUvm([n8::tRCO[XYY3xCBS$iBM =7nܠM6̝;zV%66WWWC1z gs?j!AeoJ0TC˖-֭[~qrrR;D$5BGS'44SNQD C3rHN8ݤnzԫ[_P0M7wS0TaФI֯_viH^*0$BOXXxzz5k$]*^j!A۫߿ϝ;wpwwW;as<HQ#􄅅Qzu,,k!>>W Q{sd2dbbbPhZLO'1,Խw/IkQ#,! Ƹ0N:iP;MI&CN.&&d՘SV˱cǸqڡ'(28ݎŻ>E!=-es=:( _~ /]V=F 8!+􄅅ѿŅ2ep:uv8&|j͛7jlT6l|2Ǯ$s+(XXZc˸e/#QIb*tr 5jP;\r0KQT)CckkKӦMٽ{$O ==;wo{( ܺm-(X/T"ct۷n菈Oy>tȈ(J82gv_KF Xc'f4nLWn}.h:rҶ}k]ݓRW\-IL-aaaFH v&DRS!z9saksa6giiiA)[V(&ewx[,,qcp,|>q2? ƾ;))e.^/}jܽKL KySO_>Aq_PA]^ )))|T^lȭkLgxu}8wPń9TXXXPZ5_vERa.d_7JL8 .crF45kԢqFjb0?h>q(a>):o3y.d]QQ d=)_6׺u 9)^ko) IDAT˜tG'GG?#[Ӕ_t1\Zfu&yFYywG\WeV,[Cm(Y$%ys(>bwc͆xyU.#̚$BAʃBs'N%ڡiڴ)vvvڵK'DJq(30ӰQ}*UH^Cس3<eʃ05~z}qt*{?""!$%%ulggCd2>˗ o$ݺ㯵nWtڏbooWI%W!U+u=juZZnCG9vZa XjCLPEk6nhSpp‚7x^?'%'^'%%c_^Xbzutԋr˲nr>ww^؋%Vp9 WG[ ~9y2հU}d$1:ÇgʕjXW#)0&6M;.BCװnC0rէOD~dv*Z2V# O*u,+EXfYm޵o{7n_\OMI!,<=zuƚ+^快z|)^܁'ȫV!ӯZ5?1ߙ*ҕWϜ[` 4P;Gz׉cjbpl,?Mo*::wwwՐ!C(- +9ٽ0ﱲByp=ߞבy~X[[s ڼ)<ߌ8Jd5)}׬U*^kTPж}+@OyaIb* 0LJpqtt|Trv?-I*$c߁}Z> EQfT1cGOF/d5IKO_]`Ο 2l/o_LH(?III|;6Bԭ ضu' ښOiWZsavl߃uoڴD:Sҥ$?F1oB7ޞ-3A*n5an޼IzzѶ'`~-fښu}tۢ^3D 4lgۃ\\JRRoZZXutVK8߅P$HLEQ qj[wHJG/QĹs7}TBsF,#|=9{4LJIӆԪ֐I?bo1atVWƷSշw~:N@?(p5h9l<+eȰ\p+"ǎO!lܲEA敮/b `-qqql޼^zP{Yw5?E،gͪ1d] s-Hb*Ĵf͚jXժUޞNL3UV '''0[qqċ-rZ6l^A_Q'93Ӭ?+xU{8D28pʕ)F!4Ķ-;[~Mѽ??|?!|"w2߇lJ3׾}{TvOח0x$ bT-ZƆݻwӿ1:ݺE]%N=AVy'/Np~2O/vlٹ Ft~:N)sل\v2)\>gwԉ g:+$y(BUL)URm 22#{^Ν: W>mBrܻھ5 S K@wlۃ}1{n٩74mkk+ /y2U_ILrvvV;2Qy%G0={F$00`0[O,TJhּ/ 24j\?˝4o:v.ѮCkYV؛q,^^}^TiZ7eC= [nsiz}wѺ;oBQb7*ժ{޿{7uk6q7u[Z֩M@l޸5ѱ#sIJ8qvhx2E>^4#:y+++jԠqS?~zãHb*D!2V+i0+Xlڡ<@k^JŊGq>ujѩs[%_L^n߃p)B:ѻ+~35jVcr ?/~6ƽ{p)BrR2g_~Ĝ )SEQ:m`[i6{wŧd&Q7Xn3i̟)]څGujJe$'L[ +K+fBvX tz;6b/}شq;'Ls A |ciiɮ{)Uڅs/q#&n|_bx?# ܾu7~ɩ}D\NN̚9_{2@rR2Wiظ>\L~X=7]Nd<؂+Wˉ߱vbU_u=VK8{W?cFc<|Srw]+ c' eΝ :kkk)Ea"** k޼9'OXbj"1 Xsez}̚3m۷Xp 3]^IL==zQ{}t'^Kdź Z724[;[4 t>xS7z>{2ߙ7:tj@ZZ:z__}FZ />c((ЊOڠ&ܹsg[в|qpeӕoZzϞϿҒٹIx]OX/z*zV --A}"--]̮{?g1fmoZ-= Yw,直k=-߿^53OIT۶Eؾ};}(dҤIjSs{L2r2O& Lŋ>tj"S\HS$%M7 Ѷ]1Y^;:sMackk;5nǵ ]K? ١AЦ[޷[6!>]ҪM M{ϥ3#G tR]J2r0\\JժyP ;MVhBmJZ42׸;Bޯ\(`ooO>-tܖ+a~zˬ[5f-oPBc˯t`}(Z%߉n9cע@[[[,44H3 FzÀD8v9XYe@/ Co^VF15=-i1`mmCGgX >x,_Bٵ?f#hOUWX[S̡N\Yw>ow@ZT a"Ŕτl?tF,űԽ_ݻjf+ nJB7ښT@҂UΛz_( ^ZZW\W%ݼ-3l(#O 䐛}=!ܳk/_c~]m|8v"UVb8oӶeWV 6+꼗j֮NJyk{lٽ:[h-oʷ~bC֩Ei(ܻw-vk<|\RXX`cc)zgΔvv/v266txE~u8lTR2-cLnm[hԤAP$f,,,^0իܹsSn#U=zʕIuZmۿo?%99Kٺe'}{ ep)l<ݼZi&i`8?_`qÈ0ɮM-[ٙ"~JZ֭[S>\~…,ZH0DjJWSjj 'Oc^2dx?:t~[-wp ٲi',ϱm򳭲n{I̛(… \J(@r$%%cߤn^ާ\rk"Yr}J81Y`kVoDNً֣صc/K^R=ǔog-w`bo1zG\/7oqi(@ eؽs/ '$?s-:ZEҥJJO;#ILԹsPS/// Q;QMr/^ @zW;c7i|uگu'D;(hO _dU4H%|40 yk^Ψ?`˦̘6r;HOr`2@Wojj}ss1L$u޴a^Nb=~>1#OU?q> c|2~sg/56аnK[?аnˌ.Qb֭TPAPZ@@w|ԅPڧ6EGŀWxs>7Dg7rY>{ ԧӋ=*W>7S&f[6m}rf/~M>r_kڼUAazD\sǷNFyVV4m֐WJ*̜>bkgK '/gkWmkκ!c̟-,4HnC+uXթ[:Rgz ^1ضy'Zֽ߽WW~a&g! ?VVV޽޽{P`llq-akgGF2[?^R%,#/n YZZ8uciin[lٸN{X> śmcSb?ILɫT!)S<9.6UUZs]6/3Ųe=yp<RS2pg1s˰7TݭJWMY󆸺X_}hҏ/CS!(SJ)50OC/0 9YXH!---rI~c綴iےūiʯZ-dI\c>ʒ<'n3A,Yޛ͐YfNmr[LY\wwWڇoArr2k֬Q;ghPΝյ4ս mJ(JAu?!rYʖ`ޢ_h.:s14VXA֭)U`#*Cg]\up(Fad^쯳{egccMyԭ{ҵ#4yY9WeN?2%J81flKm{sֽses&yΕleYF܈%ʕ&(`Q)S,͛P; Pm۷vHE#}t1_~dT^NϞ=9>jС̛7 &[nsNaՊ}(JU<ͭ>5Y$%%p286˜wevثKY Pgτ}Դtҵq؝-w4/;w㉈b9W?z(ѥcnݺ,_.rnǭoS'o }saIIIڵHR}xDGGvϬvtQ0(ZL2ɤ7i15C. W3]xt v(FĔj9wW7-Khа.%٤y|7Gаq}>0-wd[6gWbb"o }؛qciiƏ^_@gWX`9jca}9|kgw&{ ps߼1x 6/w8K:qD;MK6,ZcFÿI{ ctȀ-ޫ#jAߊ~Vt=FBbCV'2uT9CqaCQ?AUhּڡ"22 K Kݨ|!--7bIMM kDD\=%],'5%(Q5SSӈ|r11+_V&ns]qp(VeeKWQݓ./P;HIIΎ`uv8)N6m EaҤi׾ սMuBeK_U;S3F͚5@jWS2 r---ZY[QѳgeeIeuk|~-8P nVV~Nm]E,:qъBEE\UV!‰D6~gҺ 8rIϕ{iiiIr5_}T6šly&331 ϟ?NJ+vZ4jԈw-:&jH(ёw Gqq1RRR`i[b?5|;qwkѣ[u˯WOطo77h~R(^TB*LՒP(ȑMC  ::Z! SQs<~;u.85ӧHO@]yG!Dicȍ!N)c PiJȿk S5SVVCK.Uz`ffh 6w{n]X4ڵ̢)IͣsqqŋyP1Hլ0UvjT"((wjqIhтwJL>'ݖB7oVepJZL3/! SB:v;0{6B$z)?'''hhh௿RձŔB*L VRHW}/!xzzB" 00w144D۶mօb6_h0"BѬY34lؐwVEHMR\||<5k;/hD*#j1%+*L̰a0aZwj1k, 8RHr84%СC1N&t Lm>7h)!T -- 666TpԮ][q Suj1ɏ011Tul1Yy /u|IPaF JU0Gtt42j5+/QNJH H$ΦkU:1SBjE(BCC[cǎc0>'SB]NN$ϟÇq!QQS'! S" ѢE RmАw5l1%TL1$C,ȑ#Wc|uJSBj$!!AZL &&=zF1c䂐ҺukҒwj@ Ç_ӡ}nP)!TёwjժU+Ԯ]ъQS)URtuuagg;FiР)+K!&0U##T; ;v x\LZǔpC9U+WHNL(=Fw 2hhjt `0%*#Hh ?'&sN8;;# hذ!85_!}%BړG.M6Y4 B)!I1Yy ~Ř;w.(Y6Օwe޲5[Q48|^&ר0U٨]6xGQ+TsBH AݺuyǨVFFFs P/N S5l2"""wjWQQ+V:uESB]FFxǨvڵA-QoZB:0U*TkZZZ B `9?!ZdffĄw jB(bc{{{TMf]yĆ꒙ SSS1!T "++KmZLW^ MMg/,,j2)L```___Q͌K"Q#j >>Ԫ0!Hj0fн ^`P70CVftbCH5|t8{,&0UB:::hٲ%(5HJJu_SSY`_hiBTIÆ {nXXXR#?#''FFFAIwRѩS'hi#FE5h&MByG...`lBT-̞=gFծ]vByGzuAOudll [[[cȐ! pD9}4:wf͚~q5Ԯ]pttرcχl R5!|(; .`Ȑ!SѵkW"779rssadd~ ňիW!g؇Mhh(.^;FrqqAll, yGQӅ.tC- ($$WƥK0|pY潷>뇅 V-[ЧOl޼Iypayd8Vs}{W+;FYfҥK5k,.3f@q=xyyo߾ MMM<}zj 0#G,--Ǐ O͛7h"UQPPbbbp!011AFF;ofe˖AQQQ`۶mؿ?Ww1n8 8666o1sL4h駟0|p\x}A۶me-!Ԕ 7}}}HRddd˃D"̽eeeɁ ag q(//ER)rsY:ҟ <(//h\`g~{w1fMYroZ43DQZA @__"zz%%%#G`Μ9/m6R+uwww|@NpA 0Fnn.LMM\}yyy000X,X, ?~vuuEϞ=Ѹqc9AAApu}|̙3ѨQ#ٶ7@ /ٳgcݺuppp@TT6mڵkk===WMOZblmm1f@BB,XgϢÅ  УG۷(,,D.]S|W@:u9shذ!<==1eGfGyy9444-ZСW}ܹƍ=z4 777C,c @ @pbÆ ظq#5j 5f̘Çk׮000]ၗ/_sŎ;믿rVy׮] 3VXLXYYW^9r$RÇ>] 66n777ܹs&&&… !JN:wޅ?222kkkXZZbGcLP͛͛w8s{oӤI$$$ 11ݺuCϞ=Q\\b(++_~M41fXXXk>|8Ξ=޽{?ckJqq1\]]i&Y {N:aHKKl`tY6A1w\t3g΄7fff򂛛ؠcǎv̛̤7ӦM-7o+))'>yGaݺu Bƍ?b$T~F3( ~7=z{Я_?ܹsɁ]]]ԭ[ިS={f͚a055ŕ+W D={*]b=zyyypvvttt`gg7n 22;nݺUcURR6mڠo߾`ܹsx!ԩ̌}M[|af;:BH̚Xb 7Q* ֭RRR0rH 8sjc޼ywظq#4iVZ-[CGGׯ_Gqq1VX{bشilĉabbWWW 8iii\ھ};>ϣI&@۶+͛q=|͚5T*Eڵw^|pttD&M*WisAqq1et {E-֯_ҥK5Xq;?-+!RSS? (( 4̙#+H_;s "_0UaO<wUUeΝàA1Tի´Dm\S! S;}X`nܸ:u`h۶Fhh(O.+LWCߏ9s5jpѷ377^^^oD.]ҥKaoo/ [b1+7zzz@xx8tuuaii[n^~ 3fΝ;>}dѿxxxu3f 답kXv-PD=R}ZZ֮] ԯ_χ[ٳgfΜ)Jy;ʫ?~ MMM= &&FZQrro@Zzl)H$/D+K3ԭ[Ga\MMM߿z%̚&o>tpwwǷ~y~: Jek5g`ll a…000Ν;_"66vvv`!-- -Z@JJ ѠAF/R+Wxhkk۷/\#((3g΄-86m ..ǎ×_~ agg]vEjҤIWf IDATB۶maooGAKK _|@WWiii˗1a/T9H?{yﶯ ={~ذaf̘yyy焐wSWZZn%15kgܕ*u:}j&?G­w> {c0}$߿ƭM@Ʀp me!Ѽi Q(++ 4&222ШQ#<{ }Aaa!4551a!55Ɯ9sдiSdggcXz5`ǎX|9QTTɓ'cݺu;v,._ SSScǎݻl T*_լijgFRR1l0$%%! ѱcG޽[x޽غu+233ѪU+]9p=hhhW^-;}i&^}m̘1O… b :u qqqLJ”cسg.\MMM8;;̙3䥬 [Fݺu?C+W_ϯLD^zixׯmmJI$dgg&&&5Y[[cȐ!yؼu[GGGtСRBZ>߈BBJNNF>}0yd6lb1ܶmېgϢo߾X,>Ѽys\|HLLD۶m1}J|%ߴabb"+JdO555ajjZ(^QE)@(Aĉ'йsg{7nݟ'8ͥy @TBTNEElGGG$''#44Ǐ ע6liЪU+:rXy{РAǦMp1X[[cro &aٲe}Օ?y 1k Çnj3޸݁`ffVOPaJȇTEׯ_޽ټp=t ,ɓGvTO?\,Y`kk OOOx{{#==]nga9s 99ƍòeжm[;wNn$A$QFcpc\0aX+Wӳx#G0n85_^w'*J(ѣGfWTSL͛7yG!ըK,AN Hpulٲ?]]ĬY*j*ԩS}\0}[l[ШQ# 4_}bbbo—H$RnTUVVz'Nرc@ x㶡رc7nIIIo>77@T(P---]6lFI pڴi~ k׮۷ѩS7n+Dqq1-ZTuu~tttޙ>CXXc[@D"JJJxG Lj#޹ѵkW,z'/^PW^B>*J(Bv0UA"0`Zjc\Si^^lقs羱5kرٳ'Ν DR Xȑ#?, HˣS/^ xG! Yf{[|˗8{Oz>ژ8qc)! S% i ppp@tt4D_[[[r Zn۽o$tÆ Jz[nEtt4vQ|MzzzXd >|_}k6233S׮](ǏWCƋ?~FX2/_D"SB>*J(ʥpppP(6mo'llݺIMe˖UKGnԨvލ .Ti߄RۣI&p׬Y3XXX <n|,,,A=ԁ j,??Ķm۰qF4ln߾}{xzzV)úu0|s;===̙3-ZQT mmm<~(6mÃP#oO)tl۶ /Fݺu߻}fܹQQQM~D:pvvƭ[hz)qM\xSN B=/_++wnۨQ#SoB>*QFt¬.sssQH Ɂn߾Q^z5kfʔ)ر#<<< J?i:!q(]~:t@QQ"##ѫW J1eXYYa5BT~zddd?U0}1vލKB__o ĝ;wO7SPU͛7?; A/_F6mޖeDFFb4544RW斁UG :u^x;y F뙪,aŊSjaw߽sav==wFFF=kHGG~~~8<-BD"LLLx dddkDsνu!0U1ˣ5LߠuCLL (of ju1bDM߯jo++v0`9s漳@&C$Ԕw #J!x rv}tϟ?y! *LUP(*L@KK 666Tۿ-?~:u+oUw~v[l'OX-9H͑Jɡ75kU1/^puk׎w$<}wB*F(B__͛7E!SW^RCYZZ>>>ԢrrrPQQA-oХKܺu EEE9ѧO\vM!cN:+++<~wB*F(_&Tx<|w X8q"Xr%Zn'OB 33n2ggg#22wREزe /^Ǐ+8\xxx`С6R}ʚDaÇyGQH!!!߿?M&b틼<ܼywB䮸ElTы/P~}1d&Ls!..!ZD"CakGՒիWq%?wB")*gggA>Aii)d+RQze߿D- DQT*.Dٳ3gċ/PV-q رcqymۖwJ ;;;;wwB Bֹs_a͚5dff?˗/]v(,,rvvyG!(((}A6mrKm۶BڡSBRbC055EHH82'Nȑ#!%={̙3Gx~WFii)~QV^իWcԩ 6XoI]x ZLUa1^qq1^ NFEEEL?EӦMwaӦMHLL|[n!--w BXf lق;v(lQ RB8T={c(۷o *ҥ бcGQ*y=M`aż@3Up)\|0U!񰵵C988bbb8'!UղeKCWWbZrׯ__.]| HSSS1iswwGtt4;ݿ}Enn.(5*LUT*Ebb"lllxGQxGӦM; QAb Æ ×_~ӲRJ"++ZL?@׮]i#J+nff)ɻUTT`Aݺuy!D)=zR*L?=*Bab?>|MMMQ{|bi(p8qwwڴi߿(uE-*B(ž+j1UBEEET hkkرc9r$85rHDFFB(B__wM&C!:H$$$`ݺu(..ETTT !!w ƌ/J@KK \̿MxG!rI;ww B*)((СC;G¾}x * ""޲ɇ9s lmmQPP; ʴ𹮮.JKKy ͛7ǂ n:<~w"0% ޽;ÕrV{OOO,YBހ S  aeeMMMQc===i1ŋaÆ8~8(0xeeetREdd$v튢"\~]f><=@uB  CXXXVZƍ;GSSղ$7o… yG!IY}Ǐo߾E8qz9nܸtkcƌo;!-0UT~MMM"&&wŋq=Q>@ƍyG PRRj1HVVVhҤ xGQ߇pd(((?(wTɕ!55 O@Zlr9===j1%'33`ll9qrrBxx8*.]ž={;Gr v4mڔwB;Pa!H0Dx_]]6e˖I^xOOOj׮5k֠uּ(gggܸqCz-(/wOVQQ?~<(P3>R!|||`mm;RТE Baԩ ;'[.x$8pV^;Z322²e˨+'pqqAqq1nݺ;RƤI HxG @ B^ _?Sf}TXp!ݻ{{{q(14iJs .`ԨQhݺ5~w4hЀw$BSBByKE)GܹsyG! xzzʊwc 2={DXXRDcB>BNEExdV6/_;'?_"88XiT+(HRtڕw$ ͛xzzbJ9|||sN$&&* Bԑr9v܉ϟ^x;e.JWK8ݹsw*ݻ7 ///D???|c5۷#(([lQ466=ONE)!JF}ӧO1m4BQZPP5kT; Q*QHD1o<8q"(U&J1m4X[[cżB>J,>>`kk9rFqq1=z;*//DŽ ;\Jajaa~ 6EPaZu)))8y$ e˖prrC.ݻwC[[wBGT Bԭ[7EC  ::wsN>|w Cii)DeffĄw vEL0bw~!w)))Xr%бcGq! S%@rP^=4k֌ SNJJJ?`ɰG.TߨخxV3~0ưtR?/_G=&MۛwB'T B;Zڲe rrrTjA===+L7l؀/b׀,HRj16maaapWZZذa֭[7$wK.ŵkPV-Q! S%& amm;J”/_bƍ@fxǑ1c`ͼcȕ pQT^EE -ZzpQJOOΞ=SN@Ƽ#B S%%J1b8;; !HxGQ+6mX,V%;;;|嗼cUΝŋ˗㨴͛#88漣(=gggDDD8Bt"׮]Ð!CxG"0h"ԭ[˗/|HkkkL>ׯF۶m.]Ů]0p@4jԈw;qw^hjjC"*L !| 6`Ŋ8c K,ԩSaii;١w8t89”B,&&!!!Xp!(rW^^{{{mۖֈ&FzxG!J~~~򂎎8!!!QT*H4kL&Q(#G`̘1H$P066V};233qEQ˗/[n#UGQx!ȉ1I&!00w ֭[_C$RmtuujPE]vD"HORRwhtQZTTYfaTb0UBbIII5mEZ hР(uajk!k#44WiwHxTڮ(((wD$st upDkժUyG!J(99b S9spprNq1x{{C[[wjբڵkCdffRa*g{O?$Ų"277pQ9vVVVHJJT*ŨQХKL6 fffx!ŋ´i`mmG=z;;;aذaм}W^EHHf̘b:u z;wp=V^UV!&&={ /^gϢnݺU>6yYvm/yd_ b_ ¨Q~vnرc1tP;vLTxxx`Xz5}qCT B4n i111(;w*ޜwƭ[xQ 99{ IDAT9Tʙ q޽*Ϟ={iӦaԨQػw/jժ۴hDŽ '֭[`!55'NÇCll,pI_/^~ŋ3gbΜ9l2<{ W^ݻ+&M:`ܹIޫ˗0551(*m۶022<~ |}}xb߿ҥ[hiiƍB^0zh //wܑ]fΜ sGll,,--?xͻw)Sp}ܸq㓏 L8&]*--:wcm۶a9r$zcϞ=^uaFnۣ~ʕ+ѵkW1BֵQ:~C%1sss1TNyy9`(\~ vaQy!CV>]Zn͞?zcѣ/m &P(t"ֵkW~w366ժUؘ{)S0//*OU_ҒWzwЁ~?tc|5+W/_2ӧ366fܜ>bfccYv*mۖM6}B*UVaɒ%cYf!99w ~J{?~ 777T*/:wΝ;c֬Y8޽͓D~~>A*ch}q!=/FQQ òe`ll ###kϞ=Ҿ}{4hڵݻwYYY۷/4h bo7!W^8? ,;pIܹŰGTT#,\P&qi<{ !akk3f ..qqqػw/ <<7n@vv6233AAKK [n&222ay<4Rҥ ]VN_|)nݺ8r/b^ Xr% ܽ{7nDRR^kbժUiiiχ _ݻB ϪҥKYxx8{5kcI&uɶa7f1v1ֽ{wocL$1vic70cnnnlҥ,--EEEH&HبQXzz:۷o۹sg sttd'j*cqqq/`&&&ܜO1$ ffff̬Ro2[[[fbb:tn߾]|}}ن Xrr2ҥ +//glĈɓ'Ȉ]|ժU=}0333YHLL J`cfL*26m4VQQe-N'Of'N`7odcΝ;BmƺtœXPP`O++ժUIRǺw^8ǖ-[&٘1cXAAsttd/^d֭cÇgR&RM0%D8puޝ3kkkv5ػ ϳ֭[JuV6bof&&&WEرcY^^^>|#""8?H$b=z`EEEl…ȑ#1իeۭ^ZV|21X̞>}N:^x~ֽ{w2225;s +))ajbL"{/_86`&СCX=wk׮`… 1&+Lc1d/gEEE|2333cofofnbÇĉ‚N2>},,,؃ԩSe'3@֬YEիWYQQDf1믿u#F]!C S֫W/6i$ {-~1 6|p֥K֢E fccì+swwg͛7g+++caaaWBTɤl1 HIIaFFFٳglСl͚5U2X@@kܸ10`DdP6>޽{,6i$֠A6oIZZ eiiiX͛,$$k<`!!!lҥLCCݸq沰0>BH Txzz6o\\\xǨv믿f7ofOfڵjM<}m+tϏ|&L YXX07777|\]]c=۷o3fȺi&ֿ XRR޲´X5lؐ1 v!ֲeKfmm:t ,Z1Xrr21b322b>>>L"iӦ,<}իZhٜ9s{LXݺuYϞ=YӦMԩS>믬J*uLSS5mڔ1ذaØ oд0X0&Ml֧O Zlc,..ծ][4,,L>.\444؞={؆ XNXzz:cV qqqEGGۜ:u*svvfʊ>}0wwH$Ú_~,ɓ `Vb666LSSY5mڔըQծ]͘1C~Ѣ@ֹsgf``{8jԨjժ7n,oC+ ;FUTTLLLJ\HYܹijj[B!\1FWyyy0447;N ###8q=8"&&jՂ!`ll xiBBjԨjժ\NN֮] WWWBXZZbcc @WWSjժɁ@ 6.^hkkjժ۷/d2~L6 NB!ɐ5k`֬Y?>ahhLwwwtZBaa!ѰaCx{{J*__͚5 ǎCDD[y?===ܹ'O4h444pQR .Ď;0w\@]rЖmmmB SmAAABĉ;A 0vXl߾w˃[WfΜ)pQQahhX3"咽dddI&=z4v;JΆ1Ν;Saظq#RRR999ŋ*?=z4q Q!TΟTTxx8444ШQ#Q*<[[[󎡒c0aVX;¼(MMM/M4)SSS(CVъR055~7<~wիsNRXt |r/J/?~ 1U!nnn8pXqiB***B֭Qzu\zw'J3Ԯ]:::TXRժU͛-Gff&}v4i҄[et'N Cff&tuu+,BʓnܸGGGhhhC`ӧyG!N?077 2QPP@{y!*֭[F6mʭMƘZk׮W^8x x!pD)!L̜9BJ~~>&N#&&5jIi?ɸx"x!pD?R(,,wz t֍w1zhL6w RTTL1ݻqF1HKHH@=pxyyQQƱcǨ(%Pa*._ }}}dddRilݺ?* kצB СC1k,1/߿;)CAAAԩ^x??? w#h;j &M#] ɡ´ijjseVfddu^9]Ч$LiӦ ˖-d0U)))HMM´AAA(-SSS,Y|1}gggbܹw ^:$ҥKv333ŋdQF*UN(g=z@ZZBCC?{~~~ر#444v2LW<}k֬Eжm[q!JH1x 'ɠF{Yll,xGQ*t.!"(**)6n܈ٳg<3f011Q@ʊaD`` tuuy!(!*L !D&uݻ7l;!||WTTd2,_[l̙3J D"tЁwB”I`oo۷o}'JqAL8ڼR*ҥ &MDBH”RjR666'xQj?;R{ vZ,]wn.]HCBJI"Џ)RGJfffںu+xP Bdd$~gQ^||OګW/x{{رcشiG0k, 0GB0UrTrKKKBTȫ=+Ǵ:tPԮ]wrLիRiiiiSN~:{FEEFN,[ طo(Cc!""M6k޼y-L+塕_aÆ8z(455yG(w3g5j;Jfgg___00dCcSSS077b>J.//1:ǔ`JwD4j...:u*80W^E^  ѤIq!ҩ|?M}}}/T9;;CWW".];(JXh>}~㨤ٳg 8 # F{ً/0x`DEE ~-H*۷GvG/B{Lv;yյlt#""'''*J?Saa!~G򎢲mۆ(ٳwڸq#̙;Fr-m999{.__~APPO; !DQa._<1Kɓ'y(7o%xGQYnC1|͚5ìY䄔q&11aZaee۷ouK}[hժ8GDBBTT[ƸۻR޺hhh@SSc֬Y---^wIJJ´?~/_FժUzW\Jd2L2y!TSIJHIIAyQ(###lْw 'h211ݻadd;PaxRZw޽Ҝ% ˏ!/A{LTxx8РAQKiJHi20bۗw `!55 SJJJB׮]qR}=H'S]1:tsEǎy!TT*)PFU+QuĤB/^]PaJ>&-- 033B B R}cǎNuμB**LTxx8ƫd*y/^DqmQ* {{{QC$Qf Ю];R\t ݺu кuR}N cǎT~>x T tS%HƍBpuE):vccc\|wBީ 4i;QbXh #G@__>///!(8q#Gĭ[|!֮]M6!44(`lK,3?l@[[[ Uz쉉'B0%JN:;!kkkk IDAT޼%LїgéS0tPq!Tr”)S w2o `vڼT(G|DB{W_}.]B*(Ċ+x w^={w2o>SQ&MeYF=z`(**̞=}Cݸq{F~~~[&0UѢE;vB0UB>>>s=Μ9S~1;F$ yǨ\]]QHbb"T;:|0z xsY t oPT*04k֌w 666^eCAttt0U͛#(($%%cprr¤I0a066.66l\ܸqLJ0m4&LRQaB!T <<'@ @AAVE OWPPcbشi--2oGWW۷3o}B0U2ʢTڢ|Lxzz}Xǔ|Lrr2h8<Ξ=e˖)-;;;\vMm(^z‚w BH%@yu3'xGl[n̙3;JF{LGBB6l;'F~~>xGQ)W? O*-B0U20009(=tuuѰaC=455X`V;NVV-TVw /448}4($-- jjjT~Uֶ\ܹ3ʥ=eX1! T<AAAK0|ް@xGd ,;ƺu%GaaB.d2v H{U&(M! 5k()KKK,Z7nի;>|8sRm۶޽{}voBr=Thڴ)V\ӧCHͅz wwwqg ASN{#U 111ܹsUbbG?R"QQQXbyG!1JMWW !JUP"+)) 666c(ٳgücB*9cDѬY31H)Ǽc|Խ{:mD"ᜤd#WRRjԨ;W999={6xGnݺA[[ׯ_B*,*LHxx8x dkkT$%%A˗/ݻyǨ^PPP9I4c ce/L?]|ڴiS S:ՀL0URT[[[Py}||p58;;CMMwJSX9IԨQ#رBw ;;fffpqt@vxG=zT455۷+( SXMBJ ~'t {R=|͝;3g(oINNJYѠAܺu ּ#sQĂ `oo; !TiŅ.bжm[1Ӹ}66m;JզMDGGܜwJIKK ;woqJ033͛7ѪU+Q՟#GbvJ]tAz;p<<<{nT^wB1" !L&C-P~};wwB8p B!ӧOΆ ZhABR=T@111yG!m۶t0%`hhHE)g+V@vv6; !@{L $ y D)xxxuR {; +++]SNBJ=J111cpI*JͅyGƍTEv;B]x;wƞ={ Jy)3J166Fpp0L; ! S%#,,w.\'OAL&[X )[ΝÅ xPF.]phhhTfzUV٪VJ#(%*LYfacc1;Wڡ*۷oY,Y& J1o<㏘1cΟ?###ޱT.]*L !DYPaázB>R4;;˗/ǃxG!/ QaD"""ХK=zk$ԨQkE1b݋?PWx_38QJ}kxG!x[ $ Ѵi uSebccǶmې+VpAJ(((ԤIcٲe喣cƌK0ydQ[nT[lUꞱʉ S%+++1gEQQB! iiipqq *]U&hAJڲe rrrqF.KRWBaĈѣ ehhVZDa* n:X666BQaѴiS1gj֬455cn6muuu,\[n:::TԬY˖-ïro?%%2BHNN~~~c|L&Ô)SP~}:0UƍC޽y I `ݻl2r@o֭y pBԩS˖-+uttm6c Vѣ;Nի,,,Gݻw# _B}iBB y}}}qQgΜ:u2 0yd;v ?xG"ƍcʔ)ضm8R*TB*m[%!!C Ahh(<==1dޑ{?~, !* SB!|Ttt4z 믿вeKΉ!T$t)g7nz5WR6d2|}}Uv\rDܾ}[/.ׯܹCE)ϳ BVV(R!Paټyw^1H4hΝ;WnM>'O,ټy3:;7n`ӦM־}\.m%U(J!;;ZŋyG۽{7ʄE)G2 t @]] )޽t$Z\n*J-ZP>}gƍ7xG!B)Gϟ?H$´APPP֭[/T5L6 6665kIJJB5ƗJOOG~0b$$$ziVV̙QFaРABg”p´(+W~z)=ettt^v  mK htpvvv CRR .DAA\]] /A)G011Q/(lmmx|rtSh;lSѥK >-H$RH1L!RԩR)`gg;R޽;չ>CŅOBT&F\ytҿO]Y8_(E:hu2L&õS #Ey/ꐙسq?ZXRH! ?/XM_I޻"]:.:/Uz9^*wVBI!.(7_|H}pY8FsrQXX'8!Ry_ ͱ`R^ G~ƴ1 [Z$ŕ?#;#W|z-p`a UPm%Xn.Z4k\cghf 6!¥0u>լF4lPW.|7(]uCnbj~=`ʘѿ0صiufKKJGН0ԷBT=XZK6vOxoQaJQ8>[~;Yö5 }xGP8PmԪ*)O癫'o 5!}x$?EbO>#{@P\|l N| Ş_=tA^y|:x S|*oʛ2MoʁY5#7MoBH9ZҺ|*NRizSWϪʁ7!+L+pe4ߔ;eKA8&:)/[>yB*$n)}ٷ4TnRLh 㡼t8NC 1i0ʁ&7!ŏJ_˟2MoG{LБBqk(ʍ~V~!2εW#$8ڴCD˖@ZTTfwv^IJ6ϴưo^ٰϟ?K.Vd]֬ƍp{)ax_~\_ SoB] d22ӹr9XY7œh1nGtTT oܸq7B*'n)@"YY` "~s S{BaQ~{GdTyfV&233+T?~ }G~~> `srzc^v_yݟ(,*BvN6@RXD9oPy||< $ʹ (o},v?9%y"g7ɟgdf"++R3!rǔ6-- =BjjBI!d A4i$'' xDy h vZhijCDEFLRR=z,k1Obo^@\bA"6VD,;'1IѯoջD{qqx ɤ2<`)o?~2/eRb $8Dddd ';Yx!232K~ !L*{۵i1Ǽ_Gzzz82"aaI=v7o"I QǼ_ֲ#x=!!EE\TV;wDTT$BBabl ޽bڶ°  u̩3};Q 7w00gl9s 6D|B555DEGc061ƜGukaմ)""#1s ,[0a5lwn!!!8s,:vԴTAKK IIYLfߓPj5hhh`UYXZ6w8p BC1y07Q^""#ѯo_;`iW07p_hѼ<+CRrEVF6Ә5k&4h$ٵ{D  E͚9s칳gUV;wu4n?ƨ1#aV S.a``w#1R*?Ɯ9sr#R|=XVEofiMHH@͚5QTT,TZ 7&OU3DDѯo?p 8pnߺ¢BPV-?q.ĄD!88k~ZgmX }óg0d`0 Spuqq/i5ǁ9c&.YՎu?CO_OOkVAXh D"#**UTE|B<@}{HIMA*Uq*]]zBH`,^"gOe[f)e$,5)M7G=.0H‚vi&IXZr:d^'X$a#`]tey"&I-[YmX$agu֕c9ZjS6 oؼq33z $YZJK-L,=f7ʇe?ƞ͞5ELWWEGx.XΙ" cY>e/1HlmlD0Nڏeby0%fb1]]]& `bYZZ믿aGX$aǍg'Lge祰p/QF79͝V,_" suqeݺvcYyL,0Ǚ-`I ۳7&IX~nk٢%;D9M6l]l>t;T:=_yplӆMW,;#ekjVn]" ;w^:Jf9 ۵s|>j߮=s>5r$O‚%'氵e:" [p1[x>טu3k&IXDX$322bazyή[[" [ZnYM< Oؖ(7_}L˶23xjĬY3ޚ{c}cbݽ}`W._eb%'Zj /0H'kVavv=꣧Ϙߗmkr6e$ ִiRj5" k׶۹c|[ƙH IDATnbͬYb|ܩ3;yD2KOP"m%|iy3$lX>('E+믘X$aQhy0HEQFeg0lϥ+lFf?ƾDŽG y 'CAvp^ǽ8iijj_4p0n߹-,ci׶ԩ_>tuuf͚a%g{c/qݏ a?,F`` oy3@KK 8w8ޘ {1%msԭ[аaCn`k0q(>sW}"//7_?_9 ZZZ| B n(@]]666HLL<ݏbނyѽttt~ ''Æ~?N'@dz (_뀞=z$1DEGrY?5 nLML(8riih߾,,,իo߾|oՋW͛@|B`򕈎yW5f$ >ڦ* p;täжM[>ܽc^7&&ֵǭ۷0@>mnjݻw>pZjѣW@ M@lۢ1vL6@]]Ǝ/]tY W6DFm0e8Lrۡ#Xj>ڦ**((1#~3| 2: +PѮC[\zbqԀԼ7q:@7UTܷIgw@ZTuuWd!-- F%ehh(G`/uuu̜>;cHJNMJnYѷO_g;?~cHIIFm=HKK˸ne\O_ٯ :A/(((q뀗)>0}>QOkٻG>l5xk0UTP(Daah԰W{Ϟɘ aZu7֭[BbHx=\<J|^ j`2Vr/߰ACDӐ gO#,,>tut?W#y454&w#G0aDlwu+0q׷zsE\\\>~[P܏W`@uK+l;\v⛯v;\b8[4lx/,, ߚ,]77Qڂw~ xb{8vWW_6o0@>aÆ6NE !E{WIoz~`CPH0n߹;Ȣe+qp<'|`1O>ΟCphWĄ5w eo3gĽpU<iSAk//v35kDFF^Ó 55̜>.ƃw:79co!H$X G=`bb~PҴr5 ),Ķ_c @WW|! U"o~Í7p}e3&L(/996m@0~uuutI^{Ipy \;w¥022F~A>o 84C[[[>(iS_x`Q05/Jqysg1e4ڏ^`B?qG=Oo05w S%{m>rap,Z={Dmss0Y\a}/._񁻧&#Gƅ~< |d0R۶oCTt~;#L5kנfhݦ{4,_ [o"+3 wA`c8uzyīm@u/DDEBRXXbq:vށ/!q fϛiT ׇǎÒKѮ}gBHo)5^:8{ekҌ1L7̂9#_a024g^Z `8""a+`bd}UTİoubŨbj50q"#"0u4mG=&U6oD3fpuف~}`062Ʋ`bl~ԷDJLACOWuԅaQc Uj񵱶A{9ם.`ao ##0/\=Azz~4S&? t0ctXZZszv:uq&(*~=;`:brG1 u 79apDsЪek9䁝\v=hbZZ6{6^}hkɿS'O+tT:M;? X'M@}~ٯo2qp0Z4oQ<sz*hhhMC>jhP~ ̩ؾc;=a b=X S|'cQسsjԨQaDcڏShb4nX~ _:絘=g6i _03Эkw65Uݺv;^9zzf2Fв!<~ oOu۴nǏ˗aG^f@`C*UYu3yḷ={^’EKTRMG::2;1;{,9 QZ5[?@ll,&O68+W|Vڰ~8A۶my3~;6ۈ;\h"TV wv=4jШC-M-mm۴tUywX7D (*]b7%Fj5bbXc5K5F_{+Er?wKgenwfvfvfwv5+PTuK2'?(,"S)asԟJ+:L]~jv;,;wL`@>s7]:u~r"E1o2l]ę7?kl5,Y-j%ЖDkK&&&WzdxrOs7mvLU3Z5xW;ov* MFFlݴ-|DҥY0wa9*sF7 ZB!@) 6ܶId((o9EHچIq !tEB!B!@ɏT(0!=1vkU,?-yޠH@چIq !t$ǤL4MYd$wMO!"P^!B!Rbd8N>ُ\2S(nAaA!OLB!B(JɏdL[U+FuL~.FdFF -'? 7uMXn+ܖNzm!92+ m-{HBPoeJ}v$ IpSL<|~Y*{(;r04/,(AL{+B,'?R2\~9-[qȢE=].=:Yl J:}.=: @źkT3G2.s.o\gޝt+Bw`o.})&$S:;wxz_~3;Zњu~˜l.5gz3}/]m3w,3z}f<IHOYdd_}˗ zlRa ϧҗa_ Sן_4i,_Lge!hZr"\څQ$qt Nl֊Raժzagk6:zí2.%K5-UTB gEE"}ks)E8tm۱UWTh/]ļs9qduXK/>C@Obrj֫ ?Gi7plB:g !t%/TȕWصg 'KܦsQWЭKwk|rWOOYfT6;,o3ﴐ+%KĻ76nzmؼ T*Ԯ˚uXw߁}QltiTRw%[0OSMfǮ޶k+S!={bSj>w,8xh?T 6EK08qŎ>ATd$ G?pG'+&MH:[Ը.\*GUxx#yaqsfQRqv ;:tn͛7]xu9q8ub]uxB>T;gk7S_huqK*zV`%5 º%<]Y|Fa8#Yllf%&iCPx?nπ!P%&rCo;I1 qY6oHuOl_ۗNmZHgڌTb4nшjy4nH 1|?~ ʗٚN]:񄑣GP| K%Ǐi5k ܫUҾUݙ3oŊUb0u<k[7sG=/jǃΨöl݄S?jxe+0;;^Ur,ʵkWS&yOi٦9ߎT*;\_O.u٤e0;wsP윭)Uc'|t;gkʸ0껑P=vt" ʱ(˱|RML G*QYglL =|0zioP._q*c);zH SJ-Χ3v>j칳᣶8d9'0#CC] ,늧/Ef:[Q&Cyj;vnI`J/KygBvRѹ[:zy@,^P;w űNe3b>Uilٺi3R~|ex%eknB|\:,"  eF5k܌ R#UkV.]+/ͺZ6kIp꿗\F3rwIDAT豣Hr~#i9**;wSy1?NDXxnae=;Ɔ5YhΟe?LF͠C8vCe/u?ÈgÚrwcWCx4׽bkcTmز(تp6́C;?Ȇ՛prrVsPr .\W5/u{wS|kppaĤ)?Шy}80#ӧ>v7o$666-F?u*dXef?7D~ǥeVDFEr(p-۶`ddDGA$&&{nQQlߵm:QIޝw155ܼp:8u{1g\ylg!D򆇇ѺC+:H^4>Q̓5?V8̘=1#AL7mڕ.N'&&re3i܏%9(jQV͕UkWIO0pP+r)<+{riN>ɡ=G^IpIfΞcgBZ`7cX|͚4mH;F~59gs?pvrfמܸy]`aaCWϘ$ .UƟ/cnJHH`WQ }ѩk~<:0tp &2*ˢ^b1͛W ]Sӭ1U<вy+6n~ m:pi63fO'_nTtGyz襞֎^S1r̈*V:~ &>>}Эk ǎܰz+׮uvjL_bb"l]c XZS4kԢ'W*wOϾsYש.]{v#fO#͡{ 'fӖ L8Apӭhfʵ+z FOP_+6\u!]l^L<= [iՆZ`ɊׂZ4mwػ?)6!mfC,Q?~&oIL bV*T/h _7ܰI222eVYZ}-߸e+Z" zwqqqDFEɉSǙxB;|Q 7o$kG,,R'V!`4THws4+9ܺ5*feͽRqDEGq _8н׷7i^ɃE,̨^:gΝ}ϳƶv<^"EP٭:59r-M7--bhh{E7u!E-*Ν9St?|@\|oߤkJ2yoVMҺ-dɲE8t [kT'җuҗJS’EFD`iQ4e?v*m[[9mQQ\ aVŬ(RSӔ6jmMdT$Trjl 5=[n޺~jF%"޳&.ρkVY~3u ''g'LPgmeM4e*a#g)Rp[a-eڭkARZI3ʚ4睤v*KAy 'gS,;x\zq:^"/@c;^\[c#t׊׮dROU<=}y_M[7fo8w,CipSV[IFMc-1T*Ξ;C!BL:O+nܸe1@EP _=灶]!-B3~4'Nӧ>zE.Nw A]H;Zw !22ˢZm:hmVn]>Cؿ g2m|p~<]G{.쬼\Ƴ9s4N7yE4033K:/1iQkĝ6/IYh=xyu )b.>u^޿c'affF^"KmX/ٳO;~C`"UlӶSSta gQ"GK)YcTt4Ei>6O"#ӨCBXx#o^ӹڳHϳiѬ*YYYX[ۼmֶեYpAJB_7(c7[[[6m78{ !-[[Ҡ~Cʕ(M4n֤9}zcXz[vly!(4x~l\-lmz#4EFidrsUj׬<#w(Ιsg[LiwtGx\=3)۸tImx}vBWĝ9{,f@-V~u4ᎎkoWS6qNY[tvQN]o&̏n8u3PPAz 9pp=_M ~\;7fo>b(^|Pz'ӏ1e 7ʼ>ޥ2iCN KGs曥|;&a:ѣG)%IXxQQQ"Çq)ᒾͤڗ7cgk֒_x?s~0zEn`@-ٺm3'N A0E$p'!!o} Agv=ˊ<6ʆZ5kshڨ&Ʀz-k~[MXxuk.y!sJ,Iæt 2"B!&?Iw 9W/'Ox~T3+3Ŀx8Tyғ5&͸r?;;s .^Vo6uԮKV,Q ;55jИYju^Ľ̑:iVmhۺ=-Gn<ɰ d%,UT㷍k喨RqFuCf0cSkmUb" .guӷĭD=Kuwpׯ_~HzzqiN9I:T'zzzXYYY^zѽw7܅stځI&Ӳo,۬R*a8x:DDFXyZVWDIlmXv:iL ̉~\۷8{ㄤw_q lڲ^$ VV$?=EKקcP}hצ4ej#'yma>Gi"$2PmCs1.]QizGʚ>?'Q !(4;<:L8Q;NwTiPenæ06!U͋/_r YL5TR bVtځ5nJ)q۳'zcv4m =}}vFv&1I~RŠd؟0ʆ]{wVɍ]?ys|4nՈM.bgk&qoU4RQhҘM]݇lX9U~3;l7ԪY_fLWP[N=I42cp=`ƔqnXB|BJ-byy=B#CF>zsu9z(U+WU7s[/)O6 ;o|ͩ3')R'Nˇ9)azz4l^jޜ9w;w0w =o&]z|3{쥲{e[َm;1He˔e >M[7R©ùq|֔FNh܌!_ pyUµ+n\y })2F-`(@r8; 667W7q覞&m )W+$M`@051ٳ8;%+~`llLpP0q@bV2'@ch@:xWG23o~s}lm HΕUq. {%6!**W>Q_IO `jj?,SPï&Aux9 ^^ɝ`ce( nTHų;r e1/G`cc[1O)_1*' %]%Mռq >(]HJ8dܨ T(W *PܡxiT WOjk^fh.J}T+yPN/^hˢs@Q߼F Ө~FzIHxEEJ 3H}WT֯=y?^Z`eM+wLE i7LMLqv*A&-X^be4 ;"=E:P|, 'G|"ܽuZ|kfmc֘2{yDbb"v.V,_F ߾Aw_gt7OQc,AB)fgr҃Y>Ko@Cۏ^"!4S:+B|N#t) 9@{^4׽<07K*@%&&ÐQ?OOݗRuF - TNu6՛-%;空9_ [q/[V+VOJچBvL꒏IThԿnI#9s|O~ZqqwL~XzB[d#!YyE%FrMqQPz~=qUN헵u^aB!MM A !I ?1U,um3"[ !ȷ|TJ.zn 2]SURy2w-m薼b*Hh<1?rSyK<1Q0Hy !tD_ !B!(ؔHB%3[Z{`*F&k=)(o9iB7d(m a\ 7(UG6"_B!B!P^inU0.]m-c2\SdB *+ yb*B!BQʽc}ObDVݪhRDyK= Z !ȷH.L\UR:'kQ0Hq !tD !B!P“)6UU-s<0E9/B!rcB\mU}U䅎/cqbna/XUt-n;7*F:(ZXĘh=-3-137I:8wqwQ: B@O^"e:fdbA=iKO !U'ޝ1zzN~JTEy( 14Sx^%$$-}FhS|\S3HutLB!Bd#!B!B!BEIT!B!c*B!BQ1B!B( !B!PtLB!B(J:B!B!%S!B!B!BEIT!B!c*B!BQ1B!B( !B!PtLB!B(J:B!B!%S!B!ew7hIENDB`drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-drumgrid.xml.in0000644000000000000000000000013214200302440020774 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.441324575 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/drumstick-drumgrid.xml.in0000644000175000001440000002636114200302440021565 0ustar00pedrousers00000000000000 ]> &product; Pedro Lopez-Cabanillas plcl@users.sf.net 2010-2021 Pedro Lopez-Cabanillas @RELEASE_DATE@ &product; 1 @PROJECT_VERSION@ drumstick User Commands &product; A Drumstick utility emulating a drum box. Synopsis &product; Standard options... Description This program is a Drumstick example and utility program. You can use it to create and play drum patterns. Arguments The following arguments are optional: client:port MIDI Destination Port. Prints a summary of the command-line options and exit. Prints the program version number and exit. style sets the application GUI style. Possible values are motif, windows, and platinum. If you compiled Qt with additional styles or have additional styles as plugins these will be available to the -style command line option stylesheet sets the application styleSheet. The value must be a path to a file that contains the Style Sheet. Note: Relative URLs in the Style Sheet file are relative to the Style Sheet file's path. session restores the application from an earlier session. prints debug message at the end about number of widgets left undestroyed and maximum number of widgets existed at the same time sets the application's layout direction to Qt::RightToLeft sets the backend to be used for on-screen widgets and QPixmaps. Available options are raster and opengl. display sets the X display (default is $DISPLAY). geometry sets the client geometry of the first window that is shown. font defines the application font. The font should be specified using an X logical font description. color sets the default background color and an application palette (light and dark shades are calculated). color sets the default foreground color. color sets the default button color. name sets the application name. title sets the application title. forces the application to use a TrueColor visual on an 8-bit display. count limits the number of colors allocated in the color cube on an 8-bit display, if the application is using the QApplication::ManyColor color specification. If count is 216 then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green, and 6 of blue); for other values, a cube approximately proportional to a 2x3x1 cube is used. causes the application to install a private color map on an 8-bit display. sets the input method server (equivalent to setting the XMODIFIERS environment variable) defines how the input is inserted into the given widget, e.g., onTheSpot makes the input appear directly in the widget, while overTheSpot makes the input appear in a box floating over the widget and is not inserted until the editing is done. License Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation, considering as source code any files used for the production of this manpage. See also drumstick-guiplayer 1 , drumstick-vpiano 1 drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-playsmf.xml.in0000644000000000000000000000013214200302440020632 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.441324575 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/drumstick-playsmf.xml.in0000644000175000001440000001024214200302440021412 0ustar00pedrousers00000000000000 ]> &product; Pedro Lopez-Cabanillas plcl@users.sf.net 2010-2021 Pedro Lopez-Cabanillas @RELEASE_DATE@ &product; 1 @PROJECT_VERSION@ drumstick User Commands &product; A Drumstick command line utility for playing standard MIDI files. Synopsis &product; options FILE Description This program is a Drumstick example and utility program. You can use it to play standard MIDI files without GUI controls. Arguments The following arguments are required: client:port An ALSA client:port specification that will be subscribed in order to send MIDI events to it. The client portion can be a number or a name, like in "20:0" or "KMidimon:0". The name of the input SMF. The following arguments are optional: Prints a summary of the command-line options and exit. Prints the program version number and exit. License Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation, considering as source code any files used for the production of this manpage. See also drumstick-dumpmid 1 , drumstick-guiplayer 1 drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-dumprmi.xml.in0000644000000000000000000000013214200302440020634 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.441324575 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/drumstick-dumprmi.xml.in0000644000175000001440000001003114200302440021410 0ustar00pedrousers00000000000000 ]> &product; Pedro Lopez-Cabanillas plcl@users.sf.net 2010-2021 Pedro Lopez-Cabanillas @RELEASE_DATE@ &product; 1 @PROJECT_VERSION@ drumstick User Commands &product; A Drumstick command line utility for decoding RIFF MIDI files. Synopsis &product; options FILE Description This program is a Drumstick example and utility program. You can use it to decode a RIFF MIDI file as text, or to extract the MIDI data to a standard MIDI file. Arguments The following argument is required: The name of the input RMI. The following arguments are optional: Prints a summary of the command-line options and exit. Prints the program version number and exit. Extracts the MIDI data to a separate Standard MIDI file. License Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation, considering as source code any files used for the production of this manpage. See also drumstick-dumpsmf 1 , drumstick-dumpwrk 1 drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-guiplayer.xml.in0000644000000000000000000000013214200302440021160 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.441324575 30 ctime=1644266784.845324194 drumstick-2.5.1/doc/drumstick-guiplayer.xml.in0000644000175000001440000002705714200302440021754 0ustar00pedrousers00000000000000 ]> &product; Pedro Lopez-Cabanillas plcl@users.sf.net 2010-2021 Pedro Lopez-Cabanillas @RELEASE_DATE@ &product; 1 @PROJECT_VERSION@ drumstick User Commands &product; A Drumstick GUI utility for playing MIDI files. Synopsis &product; options... FILE Description This program is a Drumstick example and utility program. You can use it to play Standard MIDI Files and Cakewalk WRK files with GUI controls. Arguments The following arguments are optional: The name of the input (mid/kar/wrk/rmi) file. client:port MIDI Destination Port. Prints a summary of the command-line options and exit. Prints the program version number and exit. style sets the application GUI style. Possible values are motif, windows, and platinum. If you compiled Qt with additional styles or have additional styles as plugins these will be available to the -style command line option stylesheet sets the application styleSheet. The value must be a path to a file that contains the Style Sheet. Note: Relative URLs in the Style Sheet file are relative to the Style Sheet file's path. session restores the application from an earlier session. prints debug message at the end about number of widgets left undestroyed and maximum number of widgets existed at the same time sets the application's layout direction to Qt::RightToLeft sets the backend to be used for on-screen widgets and QPixmaps. Available options are raster and opengl. display sets the X display (default is $DISPLAY). geometry sets the client geometry of the first window that is shown. font defines the application font. The font should be specified using an X logical font description. color sets the default background color and an application palette (light and dark shades are calculated). color sets the default foreground color. color sets the default button color. name sets the application name. title sets the application title. forces the application to use a TrueColor visual on an 8-bit display. count limits the number of colors allocated in the color cube on an 8-bit display, if the application is using the QApplication::ManyColor color specification. If count is 216 then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green, and 6 of blue); for other values, a cube approximately proportional to a 2x3x1 cube is used. causes the application to install a private color map on an 8-bit display. sets the input method server (equivalent to setting the XMODIFIERS environment variable) defines how the input is inserted into the given widget, e.g., onTheSpot makes the input appear directly in the widget, while overTheSpot makes the input appear in a box floating over the widget and is not inserted until the editing is done. License Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation, considering as source code any files used for the production of this manpage. See also drumstick-drumgrid 1 , drumstick-vpiano 1 drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-ecosystem.svg0000644000000000000000000000013214200302440020564 xustar0030 mtime=1644266784.853324199 30 atime=1644266785.441324575 30 ctime=1644266784.853324199 drumstick-2.5.1/doc/drumstick-ecosystem.svg0000644000175000001440000050230714200302440021354 0ustar00pedrousers00000000000000 Qt SVG Document Generated with Qt «library» Drumstick::ALSA «library» Drumstick::File «library» Drumstick::RT «library» Drumstick::Widgets «application» kmetronome «application» kmidimon «application» dmidiplayer «application» wrk2mid «application» VMPK «library» FluidSynth «uses» «uses» «uses» «uses» «uses» «uses» «uses» «uses» «uses» «uses» «uses» Qt SVG Document drumstick-2.5.1/doc/PaxHeaders.27918/drumstick-devel.doc.txt.in0000644000000000000000000000013214200302440021041 xustar0030 mtime=1644266784.849324196 30 atime=1644266785.441324575 30 ctime=1644266784.849324196 drumstick-2.5.1/doc/drumstick-devel.doc.txt.in0000644000175000001440000002753414200302440021635 0ustar00pedrousers00000000000000/** @mainpage drumstick Documentation @author Copyright © 2009-2021 Pedro López-Cabanillas <plcl AT users.sf.net> @date @RELEASE_DATE@ @version @PROJECT_VERSION@ This document is licensed under the Creative Commons Attribution-Share Alike 4.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ @section Abstract This is the reference documentation for drumstick. These libraries are a set of C++ MIDI related classes, using Qt5 objects, idioms and style. Currently, there are four libraries designed to work together if/when needed: - \b Drumstick::ALSA is a Linux only C++/Qt wrapper around the ALSA Sequencer API. ALSA sequencer provides software support for MIDI technology on Linux. - \b Drumstick::File provides easy multiplatform file I/O for Standard MIDI Files (.mid), RIFF MIDI (.rmi) and Cakewalk (.wrk) file formats. - \b Drumstick::RT is a realtime MIDI I/O library with pluggable backends. It uses Drumstick::ALSA on Linux, and other native frameworks on macOS and Windows. - \b Drumstick::Widgets contains MIDI widgets, including a Virtual Piano used by VMPK among other programs @see https://doc.qt.io/qt-5/index.html @see https://www.alsa-project.org/alsa-doc/alsa-lib/seq.html @see https://www.ics.com/intro-design-patterns-c-qt-2nd-edition @see https://www.midi.org/articles/tutorials @section Disclaimer This document is a work in progress and it will be always in development. Please visit the drumstick web site to read the latest version. @see https://drumstick.sourceforge.io @section Introduction For an introduction to design and programming with C++ and Qt, see the book "An Introduction to Design Patterns in C++ with Qt" by by Alan Ezust and Paul Ezust. It is available published on dead trees, and also online. Drumstick::ALSA was the first library developed under the Drumstick umbrella, and is available only on Linux, because ALSA Sequencer is an exclusive Linux technology. Here is how a simple program playing notes using Drumstick::ALSA looks like: @code #include #include #include int main(int argc, char **argv) { QCoreApplication app(argc, argv); // create a client object on the heap drumstick::ALSA::MidiClient *client = new drumstick::ALSA::MidiClient; client->open(); client->setClientName( "MyClient" ); // create the port. The pointer is owned by the client instance drumstick::ALSA::MidiPort *port = client->createPort(); port->setPortName( "MyPort" ); port->setCapability( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ ); port->setPortType( SND_SEQ_PORT_TYPE_MIDI_GENERIC ); // subscribe the port to some other client:port port->subscribeTo( "128:0" ); // or "name:port", like in "FluidSynth:0" QList notelist{ 60, 62, 64, 65, 67, 69, 71, 72 }; for(auto note : notelist) { // create event objects on the stack, to send note on/off messages drumstick::ALSA::NoteOnEvent ev1( 0, note, 100 ); // (channel, note number, velocity) ev1.setSource( port->getPortId() ); ev1.setSubscribers(); // deliver to all the connected ports ev1.setDirect(); // not scheduled, deliver immediately client->output( &ev1 ); // or outputDirect() if you prefer not buffered client->drainOutput(); // flush the buffer QThread::msleep(250); // wait a quarter second drumstick::ALSA::NoteOffEvent ev2( 0, note, 0 ); // (channel, note number, velocity) ev2.setSource( port->getPortId() ); ev2.setSubscribers(); // deliver to all the connected ports ev2.setDirect(); // not scheduled, deliver immediately client->output( &ev2 ); // or outputDirect() if you prefer not buffered client->drainOutput(); // flush the buffer } // close and clean client->close(); // it also deletes the port and other owned objects delete client; return 0; } @endcode MIDI is a real time protocol, so it is not a surprise that many applications using MIDI require only real time functionality. In this case, you may use the Drumstick::RT library, which is multiplatform. An example equivalent to the former one, but implemented using the Drumstick::RT library looks like this: @code #include #include #include #include #include int main(int argc, char **argv) { QCoreApplication app(argc, argv); drumstick::rt::BackendManager man; drumstick::rt::MIDIOutput* output = man.outputBackendByName("SonivoxEAS"); if (output != 0) { qDebug() << "testing backend: " << output->backendName(); qDebug() << "public name " << output->publicName(); auto conn = output->connections().first(); qDebug() << "port " << conn.first; output->open(conn); QList note_list{ 60, 62, 64, 65, 67, 69, 71, 72 }; for(auto midi_note : note_list) { output->sendNoteOn(0, midi_note, 100); QThread::msleep(250); // wait a quarter second output->sendNoteOff(0, midi_note, 0); } output->close(); } return 0; } @endcode A common pattern on both implementations is QThread::msleep(250) to do the rhythm. If you are targeting only Linux, you may be interested on another (better) way to do the same, using Drumstick::ALSA again, because ALSA Sequencer is capable of event scheduling (that is why it is called a Sequencer). @code #include #include #include #include #include int main(int argc, char **argv) { QCoreApplication app(argc, argv); drumstick::ALSA::MidiClient *client = new drumstick::ALSA::MidiClient; client->open(); client->setClientName( "MyClient" ); drumstick::ALSA::MidiPort *port = client->createPort(); port->setPortName( "MyPort" ); port->setCapability( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ ); port->setPortType( SND_SEQ_PORT_TYPE_MIDI_GENERIC ); port->subscribeTo( "FLUID Synth (qsynth):0" ); drumstick::ALSA::MidiQueue *queue = client->createQueue( "MyQueue" ); drumstick::ALSA::QueueTempo tempo = queue->getTempo(); tempo.setPPQ( 120 ); tempo.setNominalBPM( 120 ); queue->setTempo(tempo); client->drainOutput(); queue->start(); int tick = 0; QList notelist{ 60, 62, 64, 65, 67, 69, 71, 72 }; for(auto midinote : notelist) { drumstick::ALSA::NoteOnEvent ev1( 0, midinote, 100 ); ev1.setSource( port->getPortId() ); ev1.setSubscribers(); ev1.scheduleTick(queue->getId(), tick, false); client->output( &ev1 ); tick += 60; drumstick::ALSA::NoteOffEvent ev2( 0, midinote, 0 ); ev2.setSource( port->getPortId() ); ev2.setSubscribers(); ev2.scheduleTick(queue->getId(), tick, false); client->output( &ev2 ); } client->drainOutput(); client->synchronizeOutput(); queue->stop(); // close and clean client->close(); delete client; return 0; } @endcode To build a program using Drumstick, you may use CMake or Qmake. Using CMake you need first to build or install Drumstick on your development machine, and create a project file like the following, with the name: "CMakeLists.txt" @code cmake_minimum_required(VERSION 3.9) project(example LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt5 COMPONENTS Core REQUIRED) find_package(Drumstick COMPONENTS ALSA REQUIRED) add_executable(example main.cpp) target_link_libraries( example Qt5::Core Drumstick::ALSA ) @endcode Assuming that you have Qt 5.12.9 installed at your $HOME/Qt directory, and Drumstick is installed at $HOME/Drumstick, then you can configure and build your project with these commands: (your current directory is your project's) @code mkdir build cd build cmake .. -DCMAKE_PREFIX_PATH="$HOME/Qt/5.12.9/gcc_64;$HOME/Drumstick" cmake --build . @endcode If you prefer to download the Drumstick sources and build it, you can also build your project without needing to install Drumstick. In this case: @code mkdir build cd build cmake .. -DCMAKE_PREFIX_PATH=$HOME/Qt/5.12.9/gcc_64 -DDrumstick_DIR=$HOME/Source/Drumstick/build cmake --build . @endcode To run your Drumstick::RT programs without installing Drumstick and your program, you may need to use an environment variable to indicate the location of the plugins, like this: @code export DRUMSTICKRT=$HOME/Source/Drumstick/build/lib/drumstick2/ ./example @endcode There are more examples in the source tree, under the utils/ directory, and you can also see applications using this library, like kmetronome, kmidimon and VMPK. @see https://dmidiplayer.sourceforge.io @see https://kmetronome.sourceforge.io @see https://kmidimon.sourceforge.io @see https://vmpk.sourceforge.io @see https://wrk2mid.sourceforge.io @section Acknowledgments Parts of this documentation are copied from the ALSA library documentation, whose authors are:
  • Jaroslav Kysela <perex AT perex.cz>
  • Abramo Bagnara <abramo AT alsa-project.org>
  • Takashi Iwai <tiwai AT suse.de>
  • Frank van de Pol <fvdpol AT coil.demon.nl>
@defgroup ALSAGroup ALSA Sequencer Library Wrapper @brief Classes wrapping the ALSA Sequencer API @{ @defgroup ALSAClient ALSA Sequencer Clients @brief ALSA clients are any entities using ALSA sequencer services. @defgroup ALSAEvent ALSA Sequencer Events @brief MIDI Events are messages transmitted between MIDI devices or applications. @defgroup ALSAPort ALSA Sequencer Ports @brief Ports are the endpoints of the MIDI connections. @defgroup ALSAQueue ALSA Sequencer Queues @brief ALSA events are delivered to the output ports at scheduled times using queues. @defgroup ALSASubs ALSA Sequencer Subscriptions @brief Subscriptions are virtual MIDI cables between readable and writable ports. @defgroup PlayThread ALSA Sequencer Output @brief ALSA Sequencer easy playback functionality. @defgroup ALSAError ALSA Sequencer Exception @brief Exception class for ALSA Sequencer errors. @defgroup ALSATimer ALSA Timers @brief Timers provide periodic time events to applications, and also to the Sequencer. @} @defgroup File MIDI File Formats @brief Support for some MIDI File Formats @{ @defgroup SMF Standard MIDI Files Management (I/O) @brief Provides a mechanism to parse and encode Standard MIDI Files @defgroup RMID RIFF MIDI File Parser (Input) @brief Provides a mechanism to parse RIFF MIDI Files @defgroup WRK Cakewalk WRK File Parser (Input) @brief Provides a mechanism to parse Cakewalk WRK Files. @} @defgroup RT Realtime MIDI (I/O) @brief Realtime MIDI input/output multiplatform classes. @defgroup Widgets Drumstick Widgets @brief MIDI related widgets and functions. @example drumgrid.cpp Simple drum patterns @include drumgrid.h @example dumpmid.cpp Print received sequencer events @include dumpmid.h @example playsmf.cpp SMF playback, command line interface program @include playsmf.h @example guiplayer.cpp SMF playback, graphic user interface program @include guiplayer.h @example dumprmi.cpp RMI read, print and extract @include main.cpp @include dumprmi.h @example dumpsmf.cpp SMF read and print @include dumpsmf.h @example dumpwrk.cpp Cakewalk WRK file parse and print @include dumpwrk.h @example metronome.cpp Simple command line MIDI metronome @include metronome.h @example sysinfo.cpp Prints information about the ALSA sequencer subsystem @example vpiano.cpp A Virtual Piano Keyboard GUI application. See another one at http://vmpk.sourceforge.io @include vpiano.h */ drumstick-2.5.1/PaxHeaders.27918/utils0000644000000000000000000000013214200302440014343 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.441324575 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/0000755000175000001440000000000014200302440015201 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440017160 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/CMakeLists.txt0000644000175000001440000000224614200302440017745 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . if (BUILD_FILE) add_subdirectory(dumpsmf) add_subdirectory(dumprmi) add_subdirectory(dumpwrk) endif() if(BUILD_ALSA AND ALSA_FOUND) add_subdirectory(dumpmid) add_subdirectory(sysinfo) add_subdirectory(metronome) add_subdirectory(drumgrid) if(BUILD_FILE) add_subdirectory(playsmf) add_subdirectory(guiplayer) endif() endif() if (BUILD_RT AND BUILD_WIDGETS) add_subdirectory(vpiano) endif() drumstick-2.5.1/utils/PaxHeaders.27918/drumgrid0000644000000000000000000000013214200302440016160 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/0000755000175000001440000000000014200302440017016 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumgridabout.ui0000644000000000000000000000013214200302440021444 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumgridabout.ui0000644000175000001440000001347014200302440022232 0ustar00pedrousers00000000000000 AboutClass 0 0 487 334 About false true <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Drum Grid %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> true QDialogButtonBox::Close buttonBox rejected() AboutClass close() 306 315 325 335 drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020775 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/CMakeLists.txt0000644000175000001440000000536014200302440021562 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR TRUE) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Gui Widgets LinguistTools REQUIRED) set(drumgrid_forms_SRCS drumgridabout.ui drumgrid.ui ) set(drumgrid_SRCS drumgridabout.cpp drumgridabout.h drumgrid.cpp drumgrid.h drumgrid.qrc drumgridmodel.cpp drumgridmodel.h drumgridmain.cpp ) set(drumgrid_qtobject_SRCS drumgridabout.h drumgridmodel.h drumgrid.h ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_ui(drumgrid_ui_SRCS ${drumgrid_forms_SRCS}) qt5_wrap_cpp(drumgrid_moc_SRCS ${drumgrid_qtobject_SRCS}) else() qt_wrap_ui(drumgrid_ui_SRCS ${drumgrid_forms_SRCS}) qt_wrap_cpp(drumgrid_moc_SRCS ${drumgrid_qtobject_SRCS}) endif() add_executable(drumstick-drumgrid ${drumgrid_ui_SRCS} ${drumgrid_moc_SRCS} ${drumgrid_SRCS} ) target_link_libraries(drumstick-drumgrid PRIVATE Drumstick::ALSA Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Widgets ) set(TS_FILES drumstick-drumgrid_en.ts drumstick-drumgrid_es.ts ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_add_translation(QM_FILES ${TS_FILES}) else() qt_add_translation(QM_FILES ${TS_FILES}) endif() add_custom_command(TARGET drumstick-drumgrid POST_BUILD COMMAND Qt${QT_VERSION_MAJOR}::lupdate ${CMAKE_CURRENT_SOURCE_DIR} -ts ${TS_FILES} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Updating translations" ) add_custom_target(drumstick-drumgrid-translations ALL DEPENDS ${QM_FILES}) if (UNIX AND NOT APPLE) install( FILES ${QM_FILES} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/drumstick ) endif () install(TARGETS drumstick-drumgrid RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES drumstick-drumgrid.desktop DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" RENAME net.sourceforge.drumstick-drumgrid.desktop) install(FILES drumstick-drumgrid.metainfo.xml DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo" RENAME net.sourceforge.drumstick-drumgrid.metainfo.xml) drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumgrid.cpp0000644000000000000000000000013214200302440020556 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumgrid.cpp0000644000175000001440000003127414200302440021346 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include "drumgrid.h" #include "drumgridabout.h" #include "drumgridmodel.h" #include "ui_drumgrid.h" using namespace drumstick::ALSA; const QString DrumGrid::QSTR_WINDOW = QStringLiteral("Window"); const QString DrumGrid::QSTR_GEOMETRY = QStringLiteral("Geometry"); const QString DrumGrid::QSTR_STATE = QStringLiteral("State"); const QString DrumGrid::QSTR_MIDI = QStringLiteral("MIDI"); const QString DrumGrid::QSTR_CONNECTION = QStringLiteral("Connection"); const QString DrumGrid::QSTR_TEMPO = QStringLiteral("Tempo"); const QString DrumGrid::QSTR_PATTERN = QStringLiteral("Pattern"); const int DrumGrid::TEMPO_MIN = 25; const int DrumGrid::TEMPO_MAX = 250; const int DrumGrid::TEMPO_DEFAULT = 120; const int DrumGrid::NOTE_DURATION = 10; const int DrumGrid::METRONOME_CHANNEL = 9; const int DrumGrid::METRONOME_VELOCITY = 100; const int DrumGrid::METRONOME_PROGRAM = 0; const int DrumGrid::METRONOME_RESOLUTION = 120; const int DrumGrid::METRONOME_VOLUME = 100; const int DrumGrid::METRONOME_PAN = 64; const int DrumGrid::VOLUME_CC = 7; const int DrumGrid::PAN_CC = 10; DrumGrid::DrumGrid(QWidget *parent) : QMainWindow(parent), m_ui(new Ui::DrumGrid), m_clientId(-1), m_portId(-1), m_queueId(-1), m_tick(0), m_weak_velocity(METRONOME_VELOCITY / 2), m_strong_velocity(METRONOME_VELOCITY), m_program(METRONOME_PROGRAM), m_channel(METRONOME_CHANNEL), m_volume(METRONOME_VOLUME), m_pan(METRONOME_PAN), m_resolution(METRONOME_RESOLUTION), m_bpm(TEMPO_DEFAULT), m_noteDuration(NOTE_DURATION), m_autoconnect(false), m_playing(false), m_useNoteOff(true) { m_ui->setupUi(this); m_ui->startButton->setIcon(style()->standardIcon(QStyle::StandardPixmap(QStyle::SP_MediaPlay))); m_ui->startButton->setShortcut(Qt::Key_MediaPlay); m_ui->stopButton->setIcon(style()->standardIcon(QStyle::StandardPixmap(QStyle::SP_MediaStop))); m_ui->stopButton->setShortcut(Qt::Key_MediaStop); m_ui->tempoSlider->setMaximum(TEMPO_MAX); m_ui->tempoSlider->setMinimum(TEMPO_MIN); m_ui->tempoSlider->setValue(m_bpm); connect( m_ui->actionAbout, &QAction::triggered, this, &DrumGrid::slotAbout); connect( m_ui->actionAbout_Qt, &QAction::triggered, qApp, &QApplication::aboutQt); connect( m_ui->actionQuit, &QAction::triggered, this, &DrumGrid::close); connect( m_ui->actionConnect, &QAction::triggered, this, &DrumGrid::connectMidi); connect( m_ui->startButton, &QPushButton::clicked, this, &DrumGrid::play); connect( m_ui->stopButton, &QPushButton::clicked, this, &DrumGrid::stop); connect( m_ui->tempoSlider, &QSlider::valueChanged, this, &DrumGrid::tempoChange); connect( m_ui->gridColumns, QOverload::of(&QSpinBox::valueChanged), this, &DrumGrid::gridColumns); m_model = new DrumGridModel(this); m_model->fillSampleData(); m_ui->tableView->setModel(m_model); connect ( this, &DrumGrid::signalUpdate, this, &DrumGrid::updateDisplay ); addShortcut(QKeySequence(Qt::Key_F), "f"); addShortcut(QKeySequence(Qt::Key_P), "p"); addShortcut(QKeySequence(Qt::Key_1), "1"); addShortcut(QKeySequence(Qt::Key_2), "2"); addShortcut(QKeySequence(Qt::Key_3), "3"); addShortcut(QKeySequence(Qt::Key_4), "4"); addShortcut(QKeySequence(Qt::Key_5), "5"); addShortcut(QKeySequence(Qt::Key_6), "6"); addShortcut(QKeySequence(Qt::Key_7), "7"); addShortcut(QKeySequence(Qt::Key_8), "8"); addShortcut(QKeySequence(Qt::Key_9), "9"); addShortcut(QKeySequence(Qt::Key_0), QString()); addShortcut(QKeySequence::Delete, QString()); connect ( m_ui->tableView, &QTableView::doubleClicked, m_model, QOverload::of(&DrumGridModel::changeCell) ); m_Client = new MidiClient(this); m_Client->open(); m_Client->setClientName("DrumGrid"); connect( m_Client, &MidiClient::eventReceived, this, &DrumGrid::sequencerEvent, Qt::QueuedConnection ); m_Port = new MidiPort(this); m_Port->attach( m_Client ); m_Port->setPortName("DrumGrid Output Port"); m_Port->setCapability( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_READ ); m_Port->setPortType( SND_SEQ_PORT_TYPE_APPLICATION | SND_SEQ_PORT_TYPE_MIDI_GENERIC ); m_Queue = m_Client->createQueue("DrumGrid"); m_queueId = m_Queue->getId(); m_portId = m_Port->getPortId(); m_clientId = m_Client->getClientId(); m_Client->setRealTimeInput(false); m_Client->startSequencerInput(); readSettings(); updateView(); } DrumGrid::~DrumGrid() { foreach(QShortcut* s, m_shortcuts) delete s; m_Port->detach(); m_Client->close(); delete m_ui; } void DrumGrid::updateView() { m_ui->tableView->resizeColumnsToContents(); m_ui->tableView->resizeRowsToContents(); } void DrumGrid::subscribe(const QString& portName) { try { if (!m_subscription.isEmpty()) { m_Port->unsubscribeTo(m_subscription); m_subscription.clear(); } m_Port->subscribeTo(portName); m_subscription = portName; } catch (const SequencerError& err) { qWarning() << "SequencerError exception. Error code: " << err.code() << " (" << err.qstrError() << ")"; qWarning() << "Location: " << err.location(); } } void DrumGrid::connectMidi() { bool ok; int current; QStringList items; QListIterator it(m_Client->getAvailableOutputs()); while(it.hasNext()) { PortInfo p = it.next(); items << QString("%1:%2").arg(p.getClientName()).arg(p.getPort()); } current = items.indexOf(m_subscription); QString item = QInputDialog::getItem(this, "MIDI port subscription", "Output port:", items, current, false, &ok); if (ok && !item.isEmpty()) { subscribe(item); } } void DrumGrid::sequencerEvent(SequencerEvent *ev) { switch (ev->getSequencerType()) { case SND_SEQ_EVENT_USR0: metronome_pattern(ev->getTick()); m_bar++; m_beat = 0; break; case SND_SEQ_EVENT_USR1: m_beat++; emit signalUpdate(m_bar, m_beat-1); break; } delete ev; } void DrumGrid::play() { metronome_set_tempo(); metronome_start(); } void DrumGrid::stop() { metronome_stop(); } void DrumGrid::tempoChange(int newTempo) { QString tip = QString::number(newTempo); m_bpm = newTempo; metronome_set_tempo(); m_ui->tempoSlider->setToolTip(tip); QToolTip::showText(QCursor::pos(), tip, this); } void DrumGrid::gridColumns(int columns) { m_model->updatePatternColumns(columns); updateView(); } void DrumGrid::shortcutPressed(const QString& value) { QModelIndex index = m_ui->tableView->currentIndex(); m_model->changeCell(index, value); } void DrumGrid::addShortcut(const QKeySequence& key, const QString& value) { QShortcut* shortcut = new QShortcut(key, m_ui->tableView); connect(shortcut, &QShortcut::activated, this, [=]{ shortcutPressed(value); }); m_shortcuts.append(shortcut); } void DrumGrid::readSettings() { QSettings settings; settings.beginGroup(QSTR_WINDOW); restoreGeometry(settings.value(QSTR_GEOMETRY).toByteArray()); restoreState(settings.value(QSTR_STATE).toByteArray()); settings.endGroup(); settings.beginGroup(QSTR_MIDI); QString midiConn = settings.value(QSTR_CONNECTION).toString(); m_bpm = settings.value(QSTR_TEMPO, TEMPO_DEFAULT).toInt(); settings.endGroup(); if (midiConn.length() > 0) { subscribe(midiConn); } settings.beginGroup(QSTR_PATTERN); QStringList keys = settings.allKeys(); if (!keys.empty()) { keys.sort(); m_model->clearPattern(); foreach(const QString& key, keys) { QStringList row = settings.value(key).toStringList(); m_model->addPatternData(key.toInt(), row); } m_model->endOfPattern(); } settings.endGroup(); } void DrumGrid::writeSettings() { QSettings settings; settings.clear(); settings.beginGroup(QSTR_WINDOW); settings.setValue(QSTR_GEOMETRY, saveGeometry()); settings.setValue(QSTR_STATE, saveState()); settings.endGroup(); settings.beginGroup(QSTR_MIDI); settings.setValue(QSTR_CONNECTION, m_subscription); settings.setValue(QSTR_TEMPO, m_bpm); settings.endGroup(); settings.beginGroup(QSTR_PATTERN); for(int r = 0; r < m_model->rowCount(); ++r) { settings.setValue( m_model->patternKey(r), m_model->patternData(r) ); } settings.endGroup(); settings.sync(); } void DrumGrid::closeEvent( QCloseEvent *event ) { writeSettings(); event->accept(); } void DrumGrid::metronome_event_output(SequencerEvent* ev) { ev->setSource(m_portId); ev->setSubscribers(); ev->setDirect(); m_Client->outputDirect(ev); } void DrumGrid::sendControlChange(int cc, int value) { ControllerEvent ev(m_channel, cc, value); metronome_event_output(&ev); } void DrumGrid::sendInitialControls() { metronome_set_program(); metronome_set_controls(); metronome_set_tempo(); } void DrumGrid::metronome_set_program() { ProgramChangeEvent ev(m_channel, m_program); metronome_event_output(&ev); } void DrumGrid::metronome_schedule_event(SequencerEvent* ev, int tick) { ev->setSource(m_portId); if (ev->getSequencerType() >= SND_SEQ_EVENT_USR0) ev->setDestination(m_clientId, m_portId); else ev->setSubscribers(); ev->scheduleTick(m_queueId, tick, false); m_Client->outputDirect(ev); } void DrumGrid::metronome_note(int note, int vel, int tick) { if (m_useNoteOff) { NoteEvent ev(m_channel, note, vel, m_noteDuration); metronome_schedule_event(&ev, tick); } else { NoteOnEvent ev(m_channel, note, vel); metronome_schedule_event(&ev, tick); } } void DrumGrid::metronome_echo(int tick, int ev_type) { SystemEvent ev(ev_type); metronome_schedule_event(&ev, tick); } int DrumGrid::decodeVelocity(const QString drumVel) { const qreal f = 127.0 / 9.0; int num = 0; bool isNum = false; if (drumVel.isEmpty()) return 0; if (drumVel == "f") return m_strong_velocity; else if (drumVel == "p") return m_weak_velocity; num = drumVel.toInt(&isNum); if (isNum) return qRound(f * num); return 0; } void DrumGrid::metronome_pattern(int tick) { int i, j, t, duration, key, vel; t = tick; duration = m_resolution / 4; for(i=0; icolumnCount(); ++i) { for(j=0; jrowCount(); ++j) { QString n = m_model->patternHit(j, i); if (!n.isEmpty()) { key = m_model->patternKey(j).toInt(); vel = decodeVelocity(n); metronome_note(key, vel, t); } } metronome_echo(t, SND_SEQ_EVENT_USR1); t += duration; } metronome_echo(t, SND_SEQ_EVENT_USR0); } void DrumGrid::metronome_set_tempo() { QueueTempo t = m_Queue->getTempo(); t.setPPQ(m_resolution); t.setNominalBPM(m_bpm); m_Queue->setTempo(t); m_Client->drainOutput(); } void DrumGrid::metronome_set_controls() { sendControlChange(VOLUME_CC, m_volume); sendControlChange(PAN_CC, m_pan); } void DrumGrid::metronome_start() { m_Queue->start(); m_patternDuration = m_resolution * m_model->columnCount() / 4; metronome_pattern(0); m_bar = 1; m_beat = 0; m_playing = true; } void DrumGrid::metronome_stop() { m_Queue->stop(); m_playing = false; } void DrumGrid::updateDisplay(int /*bar*/, int beat) { m_ui->tableView->selectColumn(beat); } void DrumGrid::slotAbout() { About dlgAbout(this); dlgAbout.exec(); } drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumgrid.ui0000644000000000000000000000013214200302440020411 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumgrid.ui0000644000175000001440000000672114200302440021200 0ustar00pedrousers00000000000000 DrumGrid 0 0 596 396 Drumstick Drum Grid :/drumstick.png:/drumstick.png QFrame::StyledPanel QFrame::Raised 2 64 16 start stop 10 250 100 Qt::Horizontal 0 0 596 25 File Help Connect... Quit About About Qt drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumgrid.pro0000644000000000000000000000013214200302440020574 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumgrid.pro0000644000175000001440000000114114200302440021352 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = drumstick-drumgrid QT += gui widgets #dbus CONFIG += c++11 CONFIG += qt thread exceptions CONFIG += lrelease static { CONFIG += link_prl } DESTDIR = ../../build/bin LRELEASE_DIR=. INCLUDEPATH += . ../../library/include LIBS = -L../../build/lib -ldrumstick-alsa -lasound include (../../global.pri) SOURCES += drumgridabout.cpp \ drumgridmain.cpp \ drumgrid.cpp \ drumgridmodel.cpp HEADERS += drumgridabout.h \ drumgrid.h \ drumgridmodel.h FORMS += drumgridabout.ui \ drumgrid.ui TRANSLATIONS += \ drumstick-drumgrid_en.ts \ drumstick-drumgrid_es.ts drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumstick-drumgrid_es.ts0000644000000000000000000000013214200302440023114 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumstick-drumgrid_es.ts0000644000175000001440000004254714200302440023711 0ustar00pedrousers00000000000000 About Revision Revisión AboutClass About Acerca de <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Drum Grid %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Drum Grid %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Drum Grid %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> DrumGrid Drumstick Drum Grid Drumstick matriz de percusión start iniciar stop parar File Archivo Help Ayuda Connect... Conexión... Quit Terminar About Acerca de About Qt Acerca de Qt main Drumstick Drum Grid Drumstick matriz de percusión Fatal error from the ALSA sequencer. This usually happens when the kernel doesn't have ALSA support, or the device node (/dev/snd/seq) doesn't exists, or the kernel module (snd_seq) is not loaded. Please check your ALSA/MIDI configuration. Error fatal en el secuenciador ALSA. Esto ocurre habitualmente cuando el núcleo no tiene soporte ALSA, o bién el nodo de dispositivo (/dev/snd/seq) no existe, o el módulo del núcleo (snd_seq) no se ha cargado. Por favor compruebe su configuración de MIDI ALSA. MIDI Out Port. Puerto MIDI Out. Error Error Returned error was: El error devuelto fué: drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumgrid.h0000644000000000000000000000013214200302440020223 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumgrid.h0000644000175000001440000000730614200302440021012 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMGRID_H #define DRUMGRID_H #include #include #include namespace Ui { class DrumGrid; } namespace drumstick { namespace ALSA { class MidiClient; class MidiPort; class MidiQueue; class SequencerEvent; }} class DrumGridModel; class DrumGrid : public QMainWindow { Q_OBJECT public: explicit DrumGrid(QWidget *parent = nullptr); ~DrumGrid(); void subscribe(const QString& portName); void addShortcut(const QKeySequence& key, const QString& value); void readSettings(); void writeSettings(); void closeEvent( QCloseEvent *event ) override; void metronome_start(); void metronome_stop(); void metronome_continue(); void sendControlChange(int cc, int value); void sendInitialControls(); void metronome_set_controls(); void metronome_set_program(); void metronome_set_tempo(); void metronome_pattern(int tick); void metronome_echo(int tick, int ev_type); void metronome_note(int note, int vel, int tick); void metronome_schedule_event(drumstick::ALSA::SequencerEvent* ev, int tick); void metronome_event_output(drumstick::ALSA::SequencerEvent* ev); int decodeVelocity(const QString drumVel); static const QString QSTR_WINDOW; static const QString QSTR_GEOMETRY; static const QString QSTR_STATE; static const QString QSTR_MIDI; static const QString QSTR_CONNECTION; static const QString QSTR_TEMPO; static const QString QSTR_PATTERN; static const int TEMPO_MIN; static const int TEMPO_MAX; static const int TEMPO_DEFAULT; static const int NOTE_DURATION; static const int METRONOME_CHANNEL; static const int METRONOME_VELOCITY; static const int METRONOME_PROGRAM; static const int METRONOME_RESOLUTION; static const int METRONOME_VOLUME; static const int METRONOME_PAN; static const int VOLUME_CC; static const int PAN_CC; public slots: void slotAbout(); void updateView(); void sequencerEvent(drumstick::ALSA::SequencerEvent *ev); void connectMidi(); void play(); void stop(); void tempoChange(int newTempo); void gridColumns(int columns); void shortcutPressed(const QString& value); void updateDisplay(int bar, int beat); signals: void signalUpdate(int bar, int beat); private: Ui::DrumGrid *m_ui; int m_clientId; int m_portId; int m_queueId; unsigned long m_tick; drumstick::ALSA::MidiClient* m_Client; drumstick::ALSA::MidiPort* m_Port; drumstick::ALSA::MidiQueue* m_Queue; DrumGridModel* m_model; QString m_subscription; QVector m_shortcuts; int m_bar; int m_beat; int m_weak_velocity; int m_strong_velocity; int m_program; int m_channel; int m_volume; int m_pan; int m_resolution; int m_bpm; int m_noteDuration; int m_patternDuration; bool m_autoconnect; bool m_playing; bool m_useNoteOff; }; #endif // DRUMGRID_H drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumgridmodel.cpp0000644000000000000000000000013214200302440021577 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumgridmodel.cpp0000644000175000001440000001174414200302440022367 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "drumgridmodel.h" #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) #include #else #include #endif const QString DrumGridModel::DEFVAL = QStringLiteral("f"); DrumGridModel::DrumGridModel(QObject *parent) : QAbstractTableModel(parent), m_columns(16), m_lastValue(DEFVAL) { m_modelData.clear(); m_keys.clear(); loadKeyNames(); } void DrumGridModel::loadKeyNames() { m_keyNames.clear(); m_keyNames[46] = QStringLiteral("Open HH"); m_keyNames[42] = QStringLiteral("Closed HH"); m_keyNames[39] = QStringLiteral("Hand Claps"); m_keyNames[38] = QStringLiteral("Snare Drum"); m_keyNames[36] = QStringLiteral("Bass Drum"); } void DrumGridModel::fillSampleData() { beginInsertRows(QModelIndex(), 0, 4); m_modelData.insert(0, QString(",p,,,,p,,,,p,,,,p,,").split(",")); m_modelData.insert(1, QString("f,,,p,f,,,p,f,,,p,f,,,p").split(",")); m_modelData.insert(2, QString(",,,,,,,,,,,,,4,4,").split(",")); m_modelData.insert(3, QString(",,,,f,,,,,,,,f,,,").split(",")); m_modelData.insert(4, QString("f,,,,p,,,,f,,,,p,,,").split(",")); m_keys.insert(0, 46); m_keys.insert(1, 42); m_keys.insert(2, 39); m_keys.insert(3, 38); m_keys.insert(4, 36); endInsertRows(); } int DrumGridModel::rowCount(const QModelIndex & /* parent */) const { return m_modelData.size(); } int DrumGridModel::columnCount(const QModelIndex & /* parent */) const { return m_columns; } QVariant DrumGridModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || role != Qt::DisplayRole) return QVariant(); return m_modelData[index.row()][index.column()].trimmed(); } QVariant DrumGridModel::headerData(int section , Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole) { if ( orientation == Qt::Horizontal ) { int m = section % 10; if (m == 9) m = 0; else m++; return QString::number(m); } else { int k = m_keys.value(section, 0); if (m_keyNames.contains(k)) return m_keyNames[k]; } } return QVariant(); } void DrumGridModel::changeCell(const QModelIndex &index) { QString after, before = m_modelData[index.row()][index.column()]; if (before.isEmpty()) after = m_lastValue; else after = QString(); changeCell(index, after); } void DrumGridModel::changeCell(const QModelIndex &index, const QString& newValue) { m_lastValue = m_modelData[index.row()][index.column()] = newValue; emit dataChanged(index, index); } QStringList DrumGridModel::patternData(int row) { return m_modelData.value(row, QStringList()); } QString DrumGridModel::patternKey(int row) { return QString::number(m_keys.value(row, 0)); } void DrumGridModel::clearPattern() { beginRemoveRows(QModelIndex(), 0, rowCount()); m_modelData.clear(); m_keys.clear(); m_tempData.clear(); m_tempKeys.clear(); endRemoveRows(); } void DrumGridModel::addPatternData(int key, const QStringList& row) { m_tempKeys.prepend(key); m_tempData.prepend(row); } void DrumGridModel::endOfPattern() { beginInsertRows(QModelIndex(), 0, m_tempData.size()); m_keys = m_tempKeys; m_modelData = m_tempData; endInsertRows(); } void DrumGridModel::updatePatternColumns(int columns) { int diff = m_columns - columns; if (diff == 0) return; if (diff > 0) { beginRemoveColumns(QModelIndex(), columns, m_columns-1); for(int i=0; i columns ) m_modelData[i].removeLast(); } else { beginInsertColumns(QModelIndex(), columns, columns-diff-1); for(int i=0; i 0) endRemoveColumns(); else endInsertColumns(); } QString DrumGridModel::patternHit(int row, int col) { if ((col < m_columns) && (row < m_modelData.size())) return m_modelData[row][col].trimmed(); return QString(); } drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumstick-drumgrid_en.ts0000644000000000000000000000013214200302440023107 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumstick-drumgrid_en.ts0000644000175000001440000003115714200302440023677 0ustar00pedrousers00000000000000 About Revision AboutClass About <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Drum Grid %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Drum Grid %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> DrumGrid Drumstick Drum Grid start stop File Help Connect... Quit About About Qt main Drumstick Drum Grid Fatal error from the ALSA sequencer. This usually happens when the kernel doesn't have ALSA support, or the device node (/dev/snd/seq) doesn't exists, or the kernel module (snd_seq) is not loaded. Please check your ALSA/MIDI configuration. MIDI Out Port. Error Returned error was: drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumstick-drumgrid.metainfo.xml0000644000000000000000000000013214200302440024400 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumstick-drumgrid.metainfo.xml0000644000175000001440000000166614200302440025172 0ustar00pedrousers00000000000000 net.sourceforge.drumstick-drumgrid drumstick-drumgrid Simple MIDI rhythm box based on ALSA Sequencer FSFAP GPL-3.0+

Simple MIDI software rhythm box based on percussion patterns and ALSA Sequencer.

This program is an example of the Drumstick libraries. For a fully featured rhythm utility see: kmetronome.sourceforge.io

net.sourceforge.drumstick-drumgrid.desktop https://drumstick.sourceforge.io/images/drumstick-drumgrid.png
drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumstick-drumgrid.desktop0000644000000000000000000000013214200302440023450 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumstick-drumgrid.desktop0000644000175000001440000000040614200302440024231 0ustar00pedrousers00000000000000[Desktop Entry] Name=Drumstick Drum Grid Exec=drumstick-drumgrid Icon=drumstick Terminal=false Type=Application Categories=AudioVideo;Audio;Midi;Education;Music; Keywords=Music;Midi;Drum;Grid; Comment=Drumstick Drum Grid Comment[es]=Caja de Ritmos de Drumstick drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumgrid.qrc0000644000000000000000000000013214200302440020561 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumgrid.qrc0000644000175000001440000000020114200302440021333 0ustar00pedrousers00000000000000 ../../icons/drumstick_32.png drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumgridabout.h0000644000000000000000000000013214200302440021256 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumgridabout.h0000644000175000001440000000200014200302440022027 0ustar00pedrousers00000000000000/* Drumgrid test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ABOUT_H #define ABOUT_H #include #include "ui_drumgridabout.h" class About : public QDialog { Q_OBJECT public: explicit About(QWidget *parent = nullptr); private: Ui::AboutClass ui; }; #endif // ABOUT_H drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumgridmain.cpp0000644000000000000000000000013214200302440021423 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumgridmain.cpp0000644000175000001440000000747414200302440022220 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "drumgrid.h" const char* QSTR_APPNAME = "drumstick-drumgrid"; const char* QSTR_DOMAIN = "drumstick.sourceforge.net"; const char* PGM_DESCRIPTION = QT_TRANSLATE_NOOP("main", "Drumstick Drum Grid"); const char* errorstr = QT_TRANSLATE_NOOP("main", "Fatal error from the ALSA sequencer. " "This usually happens when the kernel doesn't have ALSA support, " "or the device node (/dev/snd/seq) doesn't exists, " "or the kernel module (snd_seq) is not loaded. " "Please check your ALSA/MIDI configuration."); int main(int argc, char *argv[]) { QApplication app(argc, argv); QCoreApplication::setOrganizationName(QSTR_DOMAIN); QCoreApplication::setOrganizationDomain(QSTR_DOMAIN); QCoreApplication::setApplicationName(QSTR_APPNAME); QCoreApplication::setApplicationVersion(QStringLiteral(QT_STRINGIFY(VERSION))); QLocale locale; QTranslator qtTranslator; if ((locale.language() != QLocale::C) && (locale.language() != QLocale::English)) { if (qtTranslator.load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { QCoreApplication::installTranslator(&qtTranslator); } else { qWarning() << "Unable to load Qt translator:" << locale.name(); } } #if defined(Q_OS_WIN32) QString dataDir = QApplication::applicationDirPath() + "/"; #elif defined(Q_OS_MAC) QString dataDir = QApplication::applicationDirPath() + "/../Resources/"; #else QString dataDir = QApplication::applicationDirPath() + "/../share/drumstick/"; #endif QTranslator appTranslator; if ((locale.language() != QLocale::C) && (locale.language() != QLocale::English)) { if (appTranslator.load(locale, "drumstick-drumgrid", "_", dataDir)) { QCoreApplication::installTranslator(&appTranslator); } else { qWarning() << "Unable to load app translator:" << locale.name(); } } QCommandLineParser parser; parser.setApplicationDescription(PGM_DESCRIPTION); auto helpOption = parser.addHelpOption(); auto versionOption = parser.addVersionOption(); QCommandLineOption portOption({"p", "port"}, QCoreApplication::translate("main", "MIDI Out Port."), "client:port"); parser.addOption(portOption); parser.process(app); using drumstick::ALSA::SequencerError; try { DrumGrid w; if (parser.isSet(portOption)) { QString port = parser.value(portOption); w.subscribe(port); } w.show(); return app.exec(); } catch (const SequencerError& ex) { QMessageBox::critical(nullptr, QCoreApplication::translate("main", "Error"), QCoreApplication::translate("main", errorstr) + "\n" + QCoreApplication::translate("main", "Returned error was: ") + ex.qstrError() ); } catch (...) { qWarning() << QCoreApplication::translate("main", errorstr); } return EXIT_FAILURE; } drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumgridabout.cpp0000644000000000000000000000013214200302440021611 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumgridabout.cpp0000644000175000001440000000240314200302440022371 0ustar00pedrousers00000000000000/* Drumgrid test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "drumgridabout.h" About::About(QWidget *parent) : QDialog(parent) { ui.setupUi(this); QString aboutText = ui.AboutTextView->toHtml(); QString strver(QT_STRINGIFY(VERSION)); #ifdef REVISION strver.append("
"); strver.append(tr("Revision")); strver.append(" "); strver.append(QT_STRINGIFY(REVISION)); #endif aboutText.replace("%VERSION%", strver); aboutText.replace("%QT_VERSION%", qVersion()); ui.AboutTextView->setHtml(aboutText); } drumstick-2.5.1/utils/drumgrid/PaxHeaders.27918/drumgridmodel.h0000644000000000000000000000013214200302440021244 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/drumgrid/drumgridmodel.h0000644000175000001440000000403614200302440022030 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DRUMGRIDMODEL_H #define DRUMGRIDMODEL_H #include #include class DrumGridModel : public QAbstractTableModel { Q_OBJECT public: explicit DrumGridModel(QObject *parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; void loadKeyNames(); void fillSampleData(); void clearPattern(); void addPatternData(int key, const QStringList& row); void endOfPattern(); QStringList patternData(int row); QString patternKey(int row); QString patternHit(int row, int col); void updatePatternColumns(int columns); static const QString DEFVAL; public slots: void changeCell(const QModelIndex &index); void changeCell(const QModelIndex &index, const QString& newValue); private: int m_columns; QString m_lastValue; QMap m_keyNames; QList m_modelData; QList m_tempData; QList m_keys; QList m_tempKeys; }; #endif /* DRUMGRIDMODEL_H */ drumstick-2.5.1/utils/PaxHeaders.27918/metronome0000644000000000000000000000013214200302440016350 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/metronome/0000755000175000001440000000000014200302440017206 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/metronome/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440021165 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/metronome/CMakeLists.txt0000644000175000001440000000243114200302440021746 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(metronome_SRCS metronome.cpp metronome.h ) set(metronome_qtobject_SRCS metronome.h ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(metronome_moc_SRCS ${metronome_qtobject_SRCS}) else() qt_wrap_cpp(metronome_moc_SRCS ${metronome_qtobject_SRCS}) endif() add_executable(drumstick-metronome ${metronome_moc_SRCS} ${metronome_SRCS} ) target_link_libraries(drumstick-metronome PRIVATE Drumstick::ALSA Qt${QT_VERSION_MAJOR}::Core ) install(TARGETS drumstick-metronome RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) drumstick-2.5.1/utils/metronome/PaxHeaders.27918/metronome.h0000644000000000000000000000013214200302440020603 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/metronome/metronome.h0000644000175000001440000000556414200302440021376 0ustar00pedrousers00000000000000/* Standard MIDI simple metronome Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef METRONOME_H #define METRONOME_H #include #include #include #include #include #include #include #include const int TEMPO_DEFAULT(120); const int NOTE_DURATION(10); const int RHYTHM_TS_NUM(4); const int RHYTHM_TS_DEN(4); const int METRONOME_CHANNEL(9); const int METRONOME_STRONG_NOTE(34); const int METRONOME_WEAK_NOTE(33); const int METRONOME_VELOCITY(100); const int METRONOME_PROGRAM(0); const int METRONOME_RESOLUTION(240); const int METRONOME_VOLUME(100); const int METRONOME_PAN(64); class Metronome : public QObject, public drumstick::ALSA::SequencerEventHandler { Q_OBJECT public: explicit Metronome(QObject *parent = nullptr); virtual ~Metronome(); void play(QString tempo); bool stopped(); void stop(); void subscribe(const QString& portName); void shutupSound(); void sendControlChange( int cc, int value ); void sendInitialControls(); void metronome_note(int note, int tick); void metronome_echo(int tick); void metronome_pattern(int tick); void metronome_event_output(drumstick::ALSA::SequencerEvent* ev); void metronome_schedule_event(drumstick::ALSA::SequencerEvent* ev, int tick, bool lb); void metronome_set_program(); void metronome_set_tempo(); void metronome_set_controls(); // SequencerEventHandler interface void handleSequencerEvent( drumstick::ALSA::SequencerEvent* ev ) override; private: int m_weak_note; int m_strong_note; int m_weak_velocity; int m_strong_velocity; int m_program; int m_channel; int m_volume; int m_pan; int m_resolution; int m_bpm; int m_ts_num; /* time signature: numerator */ int m_ts_div; /* time signature: denominator */ int m_noteDuration; int m_patternDuration; int m_portId; int m_queueId; int m_clientId; bool m_Stopped; QReadWriteLock m_mutex; drumstick::ALSA::MidiClient* m_Client; drumstick::ALSA::MidiPort* m_Port; drumstick::ALSA::MidiQueue* m_Queue; }; #endif /*METRONOME_H*/ drumstick-2.5.1/utils/metronome/PaxHeaders.27918/metronome.pro0000644000000000000000000000013214200302440021154 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/metronome/metronome.pro0000644000175000001440000000051614200302440021737 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = drumstick-metronome #QT += dbus CONFIG += c++11 cmdline qt thread exceptions static { CONFIG += link_prl } DESTDIR = ../../build/bin INCLUDEPATH += . ../../library/include LIBS = -L../../build/lib -ldrumstick-alsa -lasound include (../../global.pri) # Input HEADERS += metronome.h SOURCES += metronome.cpp drumstick-2.5.1/utils/metronome/PaxHeaders.27918/metronome.cpp0000644000000000000000000000013214200302440021136 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/metronome/metronome.cpp0000644000175000001440000002106614200302440021724 0ustar00pedrousers00000000000000/* Standard MIDI simple metronome Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "metronome.h" #include #include #include #include #include #include #include #include #include #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #define right Qt::right #define left Qt::left #define endl Qt::endl #endif QTextStream cout(stdout, QIODevice::WriteOnly); QTextStream cerr(stderr, QIODevice::WriteOnly); using namespace drumstick::ALSA; /* *************** * * Metronome class * * *************** */ Metronome::Metronome(QObject *parent) : QObject(parent), m_weak_note(METRONOME_WEAK_NOTE), m_strong_note(METRONOME_STRONG_NOTE), m_weak_velocity(METRONOME_VELOCITY), m_strong_velocity(METRONOME_VELOCITY), m_program(METRONOME_PROGRAM), m_channel(METRONOME_CHANNEL), m_volume(METRONOME_VOLUME), m_pan(METRONOME_PAN), m_resolution(METRONOME_RESOLUTION), m_bpm(TEMPO_DEFAULT), m_ts_num(RHYTHM_TS_NUM), m_ts_div(RHYTHM_TS_DEN), m_noteDuration(NOTE_DURATION), m_portId(-1), m_queueId(-1), m_clientId(-1), m_Stopped(true) { QString name{QStringLiteral("Metronome")}; m_Client = new MidiClient(this); m_Client->open(); m_Client->setClientName(name); m_Client->setHandler(this); m_Port = new MidiPort(this); m_Port->attach( m_Client ); m_Port->setPortName(name); m_Port->setCapability( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ | SND_SEQ_PORT_CAP_WRITE ); m_Port->setPortType( SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION ); m_Queue = m_Client->createQueue(name); m_clientId = m_Client->getClientId(); m_queueId = m_Queue->getId(); m_portId = m_Port->getPortId(); m_Port->setTimestamping(true); m_Port->setTimestampQueue(m_queueId); // Get and apply the best available timer TimerId best = Timer::bestGlobalTimerId(); QueueTimer qtimer; qtimer.setId(best); m_Queue->setTimer(qtimer); // Start sequencer input m_Client->setRealTimeInput(false); m_Client->startSequencerInput(); } Metronome::~Metronome() { m_Port->detach(); m_Client->close(); } void Metronome::handleSequencerEvent( SequencerEvent *ev ) { if (ev->getSequencerType() == SND_SEQ_EVENT_USR0) metronome_pattern(static_cast(ev->getTick()) + m_patternDuration); delete ev; } void Metronome::metronome_event_output(SequencerEvent* ev) { ev->setSource(static_cast(m_portId)); ev->setSubscribers(); ev->setDirect(); m_Client->outputDirect(ev); } void Metronome::sendControlChange(int cc, int value) { ControllerEvent ev(m_channel, cc, value); metronome_event_output(&ev); } void Metronome::sendInitialControls() { metronome_set_program(); metronome_set_controls(); metronome_set_tempo(); } void Metronome::metronome_set_program() { ProgramChangeEvent ev(m_channel, m_program); metronome_event_output(&ev); } void Metronome::metronome_schedule_event(SequencerEvent* ev, int tick, bool lb) { ev->setSource(static_cast(m_portId)); if (lb) // loop back ev->setDestination(static_cast(m_clientId), static_cast(m_portId)); else ev->setSubscribers(); ev->scheduleTick(m_queueId, tick, false); m_Client->outputDirect(ev); } void Metronome::metronome_note(int note, int tick) { NoteEvent ev(m_channel, note, METRONOME_VELOCITY, m_noteDuration); metronome_schedule_event(&ev, tick, false); } void Metronome::metronome_echo(int tick) { SystemEvent ev(SND_SEQ_EVENT_USR0); metronome_schedule_event(&ev, tick, true); } void Metronome::metronome_pattern(int tick) { int j, t, duration; t = tick; duration = m_resolution * 4 / m_ts_div; for (j = 0; j < m_ts_num; j++) { metronome_note(j ? m_weak_note : m_strong_note, t); t += duration; } metronome_echo(t); } void Metronome::metronome_set_tempo() { QueueTempo t = m_Queue->getTempo(); t.setPPQ(m_resolution); t.setNominalBPM(m_bpm); m_Queue->setTempo(t); m_Client->drainOutput(); } void Metronome::metronome_set_controls() { sendControlChange(MIDI_CTL_MSB_MAIN_VOLUME, m_volume); sendControlChange(MIDI_CTL_MSB_PAN, m_pan); } void Metronome::subscribe(const QString& portName) { m_Port->subscribeTo(portName); } bool Metronome::stopped() { QReadLocker locker(&m_mutex); return m_Stopped; } void Metronome::stop() { QWriteLocker locker(&m_mutex); m_Stopped = true; m_Client->dropOutput(); } void Metronome::shutupSound() { sendControlChange( MIDI_CTL_ALL_NOTES_OFF, 0 ); sendControlChange( MIDI_CTL_ALL_SOUNDS_OFF, 0 ); } void Metronome::play(QString tempo) { bool ok; m_Stopped = false; m_patternDuration = m_resolution * 4 / m_ts_div * m_ts_num; m_bpm = tempo.toInt(&ok); if (!ok) m_bpm = TEMPO_DEFAULT; cout << "Metronome playing. " << m_bpm << " bpm" << endl; cout << "Press Ctrl+C to exit" << endl; try { sendInitialControls(); m_Queue->start(); metronome_pattern(0); metronome_pattern(m_patternDuration); while (!stopped()) sleep(1); } catch (const SequencerError& err) { cerr << "SequencerError exception. Error code: " << err.code() << " (" << err.qstrError() << ")" << endl; cerr << "Location: " << err.location() << endl; } } static Metronome* metronome = nullptr; void signalHandler(int sig) { if (sig == SIGINT) qDebug() << "Caught a SIGINT. Exiting"; else if (sig == SIGTERM) qDebug() << "Caught a SIGTERM. Exiting"; if (metronome != nullptr) { metronome->stop(); metronome->shutupSound(); } } int main(int argc, char **argv) { const QString PGM_NAME = QStringLiteral("drumstick-metronome"); const QString PGM_DESCRIPTION = QStringLiteral("ALSA based command line metronome"); const QString ERRORSTR = QStringLiteral("Fatal error from the ALSA sequencer. " "This usually happens when the kernel doesn't have ALSA support, " "or the device node (/dev/snd/seq) doesn't exists, " "or the kernel module (snd_seq) is not loaded. " "Please check your ALSA/MIDI configuration."); signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); QCoreApplication app(argc, argv); QCoreApplication::setApplicationName(PGM_NAME); QCoreApplication::setApplicationVersion(QStringLiteral(QT_STRINGIFY(VERSION))); QCommandLineParser parser; parser.setApplicationDescription(PGM_DESCRIPTION); auto helpOption = parser.addHelpOption(); auto versionOption = parser.addVersionOption(); QCommandLineOption portOption({"p","port"}, "Destination, MIDI port identifier.", "client:port"); parser.addOption(portOption); QCommandLineOption bpmOption({"b","bpm"}, "Tempo, in beats per minute (default=120).", "BPM", "120"); parser.addOption(bpmOption); parser.process(app); if (parser.isSet(versionOption) || parser.isSet(helpOption)) { return 0; } try { metronome = new Metronome(); if (parser.isSet(portOption)) { QString port = parser.value(portOption); metronome->subscribe(port); } else { cerr << "Destination Port is mandatory" << endl; parser.showHelp(); } QString bpm("120"); if (parser.isSet(bpmOption)) { bpm = parser.value(bpmOption); } metronome->play(bpm); } catch (const SequencerError& ex) { cerr << ERRORSTR << " Returned error was: " << ex.qstrError() << endl; } catch (...) { cerr << ERRORSTR << endl; } delete metronome; return 0; } drumstick-2.5.1/utils/PaxHeaders.27918/Info.plist.app0000644000000000000000000000013214200302440017147 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/Info.plist.app0000644000175000001440000000216314200302440017732 0ustar00pedrousers00000000000000 NSPrincipalClass NSApplication NSHighResolutionCapable True CFBundleIconFile @ICON@ CFBundlePackageType APPL CFBundleGetInfoString Created by Qt/QMake CFBundleInfoDictionaryVersion 6.0 CFBundleDisplayName Sample Drumstick Application CFBundleSignature @TYPEINFO@ CFBundleExecutable @EXECUTABLE@ CFBundleIdentifier @BUNDLEIDENTIFIER@ CFBundleVersion @FULL_VERSION@ CFBundleShortVersionString @FULL_VERSION@ NSHumanReadableCopyright © 2006-2021, Pedro López-Cabanillas and others NOTE This file was generated by QMake/CMake. drumstick-2.5.1/utils/PaxHeaders.27918/dumprmi0000644000000000000000000000013214200302440016020 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.441324575 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumprmi/0000755000175000001440000000000014200302440016656 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/dumprmi/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020635 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.441324575 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumprmi/CMakeLists.txt0000644000175000001440000000260414200302440021420 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(dumprmi_SRCS dumprmi.cpp dumprmi.h main.cpp ) set(dumprmi_qtobject_SRCS dumprmi.h ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(dumprmi_moc_SRCS ${dumprmi_qtobject_SRCS}) else() qt_wrap_cpp(dumprmi_moc_SRCS ${dumprmi_qtobject_SRCS}) endif() add_executable(drumstick-dumprmi ${dumprmi_moc_SRCS} ${dumprmi_SRCS} ) target_link_libraries(drumstick-dumprmi PRIVATE Drumstick::File Qt${QT_VERSION_MAJOR}::Core ) if(QT_VERSION VERSION_GREATER_EQUAL 6.0.0) target_link_libraries(drumstick-dumprmi PRIVATE Qt6::Core5Compat) endif() install(TARGETS drumstick-dumprmi RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) drumstick-2.5.1/utils/dumprmi/PaxHeaders.27918/dumprmi.cpp0000644000000000000000000000013214200302440020256 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.441324575 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumprmi/dumprmi.cpp0000644000175000001440000002143714200302440021046 0ustar00pedrousers00000000000000/* Standard RIFF MIDI File dump program Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include "dumprmi.h" DISABLE_WARNING_PUSH DISABLE_WARNING_DEPRECATED_DECLARATIONS #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #define right Qt::right #define left Qt::left #define endl Qt::endl #endif QTextStream cout(stdout, QIODevice::WriteOnly); QTextStream cerr(stderr, QIODevice::WriteOnly); using namespace drumstick::File; DumpRmid::DumpRmid(): m_currentTrack(0), m_engine(nullptr), m_rc(0) { QTextCodec *codec = QTextCodec::codecForName("UTF-8"); m_engine = new Rmidi(this); m_smf = new QSmf(this); m_smf->setTextCodec(codec); connect(m_engine, &Rmidi::signalRiffInfo, this, &DumpRmid::infoHandler); connect(m_engine, &Rmidi::signalRiffData, this, &DumpRmid::dataHandler); connect(m_smf, &QSmf::signalSMFHeader, this, &DumpRmid::headerEvent); connect(m_smf, &QSmf::signalSMFTrackStart, this, &DumpRmid::trackStartEvent); connect(m_smf, &QSmf::signalSMFTrackEnd, this, &DumpRmid::trackEndEvent); connect(m_smf, &QSmf::signalSMFNoteOn, this, &DumpRmid::noteOnEvent); connect(m_smf, &QSmf::signalSMFNoteOff, this, &DumpRmid::noteOffEvent); connect(m_smf, &QSmf::signalSMFKeyPress, this, &DumpRmid::keyPressEvent); connect(m_smf, &QSmf::signalSMFCtlChange, this, &DumpRmid::ctlChangeEvent); connect(m_smf, &QSmf::signalSMFPitchBend, this, &DumpRmid::pitchBendEvent); connect(m_smf, &QSmf::signalSMFProgram, this, &DumpRmid::programEvent); connect(m_smf, &QSmf::signalSMFChanPress, this, &DumpRmid::chanPressEvent); connect(m_smf, &QSmf::signalSMFSysex, this, &DumpRmid::sysexEvent); connect(m_smf, &QSmf::signalSMFSeqSpecific, this, &DumpRmid::seqSpecificEvent); connect(m_smf, &QSmf::signalSMFMetaUnregistered, this, &DumpRmid::metaMiscEvent); connect(m_smf, &QSmf::signalSMFSequenceNum, this, &DumpRmid::seqNum); connect(m_smf, &QSmf::signalSMFforcedChannel, this, &DumpRmid::forcedChannel); connect(m_smf, &QSmf::signalSMFforcedPort, this, &DumpRmid::forcedPort); connect(m_smf, &QSmf::signalSMFText, this, &DumpRmid::textEvent); connect(m_smf, &QSmf::signalSMFendOfTrack, this, &DumpRmid::endOfTrackEvent); connect(m_smf, &QSmf::signalSMFTimeSig, this, &DumpRmid::timeSigEvent); connect(m_smf, &QSmf::signalSMFSmpte, this, &DumpRmid::smpteEvent); connect(m_smf, &QSmf::signalSMFKeySig, this, &DumpRmid::keySigEvent); connect(m_smf, &QSmf::signalSMFTempo, this, &DumpRmid::tempoEvent); connect(m_smf, &QSmf::signalSMFError, this, &DumpRmid::errorHandler); cout.setRealNumberNotation(QTextStream::FixedNotation); cout.setRealNumberPrecision(4); #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) cout.setCodec(codec); #else cout.setEncoding(QStringConverter::Utf8); #endif } void DumpRmid::dump(const QString& chan, const QString& event, const QString& data) { cout << right << qSetFieldWidth(7) << m_smf->getCurrentTime(); cout << right << qSetFieldWidth(10) << m_smf->getRealTime() / 1600.0; cout << qSetFieldWidth(3) << chan; cout << qSetFieldWidth(0) << left << " "; cout << qSetFieldWidth(15) << event; cout << qSetFieldWidth(0) << " " << data << endl; } void DumpRmid::dumpStr(const QString& event, const QString& data) { cout << right << qSetFieldWidth(7) << m_smf->getCurrentTime(); cout << right << qSetFieldWidth(10) << m_smf->getRealTime() / 1600.0; cout << qSetFieldWidth(3) << "--"; cout << qSetFieldWidth(0) << left << " "; cout << qSetFieldWidth(15) << event; cout << qSetFieldWidth(0) << " " << data << endl; } void DumpRmid::headerEvent(int format, int ntrks, int division) { dumpStr("SMF Header", QString("Format=%1, Tracks=%2, Division=%3") .arg(format).arg(ntrks).arg(division)); } void DumpRmid::trackStartEvent() { m_currentTrack++; dumpStr("Track", QString("Start: %1").arg(m_currentTrack)); } void DumpRmid::trackEndEvent() { dumpStr("Track", QString("End: %1").arg(m_currentTrack)); } void DumpRmid::endOfTrackEvent() { dumpStr("Meta Event", "End Of Track"); } void DumpRmid::noteOnEvent(int chan, int pitch, int vol) { dump(QString("%1").arg(chan, 2), "Note On", QString("%1, %2").arg(pitch).arg(vol)); } void DumpRmid::noteOffEvent(int chan, int pitch, int vol) { dump(QString("%1").arg(chan, 2), "Note Off", QString("%1, %2").arg(pitch).arg(vol)); } void DumpRmid::keyPressEvent(int chan, int pitch, int press) { dump(QString("%1").arg(chan, 2), "Key Pressure", QString("%1, %2").arg(pitch).arg(press)); } void DumpRmid::ctlChangeEvent(int chan, int ctl, int value) { dump(QString("%1").arg(chan, 2), "Control Change", QString("%1, %2").arg(ctl).arg(value)); } void DumpRmid::pitchBendEvent(int chan, int value) { dump(QString("%1").arg(chan, 2), "Pitch Bend", QString::number(value)); } void DumpRmid::programEvent(int chan, int patch) { dump(QString("%1").arg(chan, 2), "Program Change", QString::number(patch)); } void DumpRmid::chanPressEvent(int chan, int press) { dump(QString("%1").arg(chan, 2), "Chan.Pressure", QString::number(press)); } void DumpRmid::sysexEvent(const QByteArray& data) { int j; QString s; for (j = 0; j < data.count(); ++j) s.append(QString("%1 ").arg(data[j] & 0xff, 2, 16)); dumpStr("SysEx", s); } void DumpRmid::seqSpecificEvent(const QByteArray& data) { int j; QString s; for (j = 0; j < data.count(); ++j) s.append(QString("%1 ").arg(data[j] & 0xff, 2, 16)); dumpStr("Seq. specific", s); } void DumpRmid::metaMiscEvent(int typ, const QByteArray& data) { int j; QString s = QString("type=%1 ").arg(typ); for (j = 0; j < data.count(); ++j) s.append(QString("%1 ").arg(data[j] & 0xff, 2, 16)); dumpStr("Meta (unreg.)", s); } void DumpRmid::seqNum(int seq) { dump("--", "Sequence num.", QString::number(seq)); } void DumpRmid::forcedChannel(int channel) { dump("--", "Forced channel", QString::number(channel)); } void DumpRmid::forcedPort(int port) { dump("--", "Forced port", QString::number(port)); } void DumpRmid::textEvent(int typ, const QString& data) { dumpStr(QString("Text (%1)").arg(typ), data); } void DumpRmid::smpteEvent(int b0, int b1, int b2, int b3, int b4) { dump("--", "SMPTE", QString("%1, %2, %3, %4, %5").arg(b0).arg(b1).arg(b2).arg(b3).arg(b4)); } void DumpRmid::timeSigEvent(int b0, int b1, int b2, int b3) { dump("--", "Time Signature", QString("%1, %2, %3, %4").arg(b0).arg(b1).arg(b2).arg(b3)); } void DumpRmid::keySigEvent(int b0, int b1) { dump("--", "Key Signature", QString("%1, %2").arg(b0).arg(b1)); } void DumpRmid::tempoEvent(int tempo) { dump("--", "Tempo", QString::number(tempo)); } void DumpRmid::errorHandler(const QString& errorStr) { m_rc++; cerr << "*** Warning! " << errorStr << " at file offset " << m_smf->getFilePos() << endl; } void DumpRmid::infoHandler(const QString &infoType, const QByteArray &data) { QString info = QString::fromLatin1(data); if (m_extract) { cout << infoType << ": " << info << endl; } else { dump("--", "Info", QString("%1: %2").arg(infoType, info)); } } void DumpRmid::dataHandler(const QString &dataType, const QByteArray &data) { if (dataType == "RMID") { if (m_extract) { QFileInfo finfo(m_fileName); QString outfile = QDir::current().absoluteFilePath(finfo.baseName() + ".mid"); QFile file(outfile); file.open(QFile::WriteOnly); file.write(data); file.close(); } else { QDataStream ds(data); m_smf->readFromStream(&ds); } } } void DumpRmid::run(QString fileName) { m_fileName = fileName; m_currentTrack = 0; if (!m_extract) { cout << "__ticks __seconds ch event__________ data____" << endl; } m_engine->readFromFile(fileName); } int DumpRmid::numErrors() { return m_rc; } void DumpRmid::setExtract(bool enable) { m_extract = enable; } DISABLE_WARNING_POP drumstick-2.5.1/utils/dumprmi/PaxHeaders.27918/dumprmi.h0000644000000000000000000000013214200302440017723 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.441324575 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumprmi/dumprmi.h0000644000175000001440000000465614200302440020517 0ustar00pedrousers00000000000000/* Standard RIFF MIDI File dump program Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include class DumpRmid : public QObject { Q_OBJECT public: DumpRmid(); void run(QString fileName); void dump(const QString& chan, const QString& event, const QString& data); void dumpStr(const QString& event, const QString& data); int numErrors(); void setExtract(bool enable); public slots: void headerEvent(int format, int ntrks, int division); void trackStartEvent(); void trackEndEvent(); void endOfTrackEvent(); void noteOnEvent(int chan, int pitch, int vol); void noteOffEvent(int chan, int pitch, int vol); void keyPressEvent(int chan, int pitch, int press); void ctlChangeEvent(int chan, int ctl, int value); void pitchBendEvent(int chan, int value); void programEvent(int chan, int patch); void chanPressEvent(int chan, int press); void sysexEvent(const QByteArray& data); void seqSpecificEvent(const QByteArray& data); void metaMiscEvent(int typ, const QByteArray& data); void seqNum(int seq); void forcedChannel(int channel); void forcedPort(int port); void textEvent(int typ, const QString& data); void smpteEvent(int b0, int b1, int b2, int b3, int b4); void timeSigEvent(int b0, int b1, int b2, int b3); void keySigEvent(int b0, int b1); void tempoEvent(int tempo); void errorHandler(const QString& errorStr); void infoHandler(const QString& infoType, const QByteArray& data); void dataHandler(const QString& dataType, const QByteArray& data); private: int m_currentTrack; drumstick::File::Rmidi *m_engine; drumstick::File::QSmf *m_smf; int m_rc; bool m_extract; QString m_fileName; }; drumstick-2.5.1/utils/dumprmi/PaxHeaders.27918/dumprmi.pro0000644000000000000000000000013214200302440020274 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.441324575 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumprmi/dumprmi.pro0000644000175000001440000000077714200302440021070 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = drumstick-dumprmi CONFIG += c++11 cmdline qt static { CONFIG += link_prl DEFINES += DRUMSTICK_STATIC } DESTDIR = ../../build/bin INCLUDEPATH += . ../../library/include include (../../global.pri) # Input HEADERS += dumprmi.h SOURCES += dumprmi.cpp main.cpp macx:!static { QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib LIBS += -framework drumstick-file } else { LIBS = -L$$OUT_PWD/../../build/lib \ -l$$drumstickLib(drumstick-file) } drumstick-2.5.1/utils/dumprmi/PaxHeaders.27918/main.cpp0000644000000000000000000000013214200302440017525 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.441324575 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumprmi/main.cpp0000644000175000001440000000533314200302440020312 0ustar00pedrousers00000000000000/* Standard RIFF MIDI File dump program Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include "dumprmi.h" #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #define right Qt::right #define left Qt::left #define endl Qt::endl #endif using namespace drumstick::File; int main(int argc, char **argv) { const QString PGM_NAME = QStringLiteral("drumstick-dumprmi"); const QString PGM_DESCRIPTION = QStringLiteral("Drumstick command line utility for decoding RMI (RIFF MIDI) files"); QTextStream cerr(stderr, QIODevice::WriteOnly); DumpRmid spy; QCoreApplication app(argc, argv); QCoreApplication::setApplicationName(PGM_NAME); QCoreApplication::setApplicationVersion(QStringLiteral(QT_STRINGIFY(VERSION))); QCommandLineParser parser; parser.setApplicationDescription(PGM_DESCRIPTION); auto helpOption = parser.addHelpOption(); auto versionOption = parser.addVersionOption(); QCommandLineOption extractOption({{"e", "extract"}, "Extracts the embedded standard MIDI file."}); parser.addOption(extractOption); parser.addPositionalArgument("file", "Input RMI file name.", "files..."); parser.process(app); if (parser.isSet(versionOption) || parser.isSet(helpOption)) { return 0; } spy.setExtract(parser.isSet(extractOption)); QStringList fileNames, positionalArgs = parser.positionalArguments(); if (positionalArgs.isEmpty()) { cerr << "Input file name(s) missing" << endl; parser.showHelp(); } foreach(const QString& a, positionalArgs) { QFileInfo f(a); if (f.exists()) fileNames += f.canonicalFilePath(); else cerr << "File not found: " << a << endl; } int totalErrors = 0; foreach(const QString& file, fileNames) { spy.run(file); totalErrors += spy.numErrors(); } return totalErrors; } drumstick-2.5.1/utils/PaxHeaders.27918/sysinfo0000644000000000000000000000013214200302440016035 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/sysinfo/0000755000175000001440000000000014200302440016673 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/sysinfo/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020652 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/sysinfo/CMakeLists.txt0000644000175000001440000000200114200302440021424 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(sysinfo_SRCS sysinfo.cpp ) add_executable(drumstick-sysinfo ${sysinfo_SRCS} ) target_link_libraries(drumstick-sysinfo PRIVATE Drumstick::ALSA Qt${QT_VERSION_MAJOR}::Core ) install(TARGETS drumstick-sysinfo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) drumstick-2.5.1/utils/sysinfo/PaxHeaders.27918/sysinfo.cpp0000644000000000000000000000013214200302440020310 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/sysinfo/sysinfo.cpp0000644000175000001440000002251514200302440021076 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #define right Qt::right #define left Qt::left #define endl Qt::endl #define hex Qt::hex #define dec Qt::dec #endif QString PGM_NAME = QStringLiteral("drumstick-sysinfo"); QString PGM_DESCRIPTION = QStringLiteral("ALSA Sequencer System Info"); QTextStream cout(stdout, QIODevice::WriteOnly); QTextStream cerr(stderr, QIODevice::WriteOnly); using namespace drumstick::ALSA; void queryTimers() { cout << endl << "ALSA Timers" << endl; TimerQuery* query = new TimerQuery("hw", 0); cout << "type___ Name________________ c/s/C/D/S Freq." << endl; TimerIdList lst = query->getTimers(); TimerIdList::ConstIterator it; for( it = lst.constBegin(); it != lst.constEnd(); ++it ) { TimerId id = *it; try { Timer* timer = new Timer(id, SND_TIMER_OPEN_NONBLOCK); TimerInfo info = timer->getTimerInfo(); cout << qSetFieldWidth(8) << left << info.getId() << qSetFieldWidth(20) << left << info.getName().leftJustified(20, ' ', true) << qSetFieldWidth(0) << " " << id.getClass() << "/" << id.getSlaveClass() << "/" << id.getCard() << "/" << id.getDevice() << "/" << id.getSubdevice() << " "; if( info.isSlave() ) { cout << "SLAVE"; } else { long freq = info.getFrequency(); cout << freq << " Hz"; } cout << endl; delete timer; } catch (const SequencerError& err) { cerr << "Error opening timer:" << err.qstrError(); } } delete query; } void queryQueues(MidiClient* c) { cout << endl << "ALSA Queues" << endl; cout << "id Queue_Name__________ Timer_Name__________ owner status " << " state PPQ Tempo BPM Ticks Time" << endl; QList queues = c->getAvailableQueues(); foreach( int q, queues ) { MidiQueue* queue = new MidiQueue(c, q); if (queue != nullptr) { QueueInfo qinfo = queue->getInfo(); QueueStatus qsts = queue->getStatus(); QueueTempo qtmp = queue->getTempo(); QueueTimer qtmr = queue->getTimer(); TimerId tid(qtmr.getId()); QString tname; try { Timer* timer = new Timer(tid, SND_TIMER_OPEN_NONBLOCK); TimerInfo tinfo = timer->getTimerInfo(); tname = tinfo.getName(); delete timer; } catch (...) { tname = "inaccessible"; } cout << qSetFieldWidth(3) << left << qinfo.getId() << qSetFieldWidth(20) << qinfo.getName().leftJustified(20, ' ', true) << qSetFieldWidth(0) << " " << qSetFieldWidth(20) << tname.leftJustified(20, ' ', true) << qSetFieldWidth(6) << right << qinfo.getOwner() << qSetFieldWidth(7) << (qinfo.isLocked() ? "locked" : "free") << qSetFieldWidth(8) << (qsts.isRunning() ? "running" : "stopped") << qSetFieldWidth(4) << qtmp.getPPQ() << qSetFieldWidth(7) << qtmp.getRealBPM() << qSetFieldWidth(4) << qtmp.getNominalBPM() << qSetFieldWidth(8) << qsts.getTickTime() << qSetFieldWidth(0) << " " << qsts.getClockTime() << endl; delete queue; } } } QString clientTypeName(snd_seq_client_type_t ctype) { if (ctype == SND_SEQ_USER_CLIENT) return "User"; if (ctype == SND_SEQ_KERNEL_CLIENT) return "Kernel"; return "Unknown"; } QString portTypeNames(int ptype) { QStringList lst; if ((ptype & SND_SEQ_PORT_TYPE_HARDWARE) != 0) lst << "Hardware"; if ((ptype & SND_SEQ_PORT_TYPE_SOFTWARE) != 0) lst << "Software"; if ((ptype & SND_SEQ_PORT_TYPE_PORT) != 0) lst << "Port"; if ((ptype & SND_SEQ_PORT_TYPE_DIRECT_SAMPLE) != 0) lst << "Direct Sample"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_GENERIC) != 0) lst << "MIDI Generic"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_GM) != 0) lst << "GM"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_GM2) != 0) lst << "GM2"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_GS) != 0) lst << "GS"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_MT32) != 0) lst << "MT32"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_XG) != 0) lst << "XG"; if ((ptype & SND_SEQ_PORT_TYPE_SAMPLE) != 0) lst << "Sample"; if ((ptype & SND_SEQ_PORT_TYPE_SPECIFIC) != 0) lst << "Specific"; if ((ptype & SND_SEQ_PORT_TYPE_SYNTH) != 0) lst << "Synth"; if ((ptype & SND_SEQ_PORT_TYPE_APPLICATION) != 0) lst << "Application"; if ((ptype & SND_SEQ_PORT_TYPE_SYNTHESIZER) != 0) lst << "Synthesizer"; return " (" + lst.join(", ") + ")"; } QString subsNames(SubscribersList& subs) { QStringList lst; foreach( Subscriber s, subs ) { QString sname = QString("%1:%2").arg(static_cast(s.getAddr()->client)) .arg(static_cast(s.getAddr()->port)); lst << sname; } return lst.join(", "); } void queryClients(MidiClient* c) { cout << endl << "ALSA Sequencer clients" << endl; ClientInfoList clients = c->getAvailableClients(); foreach( ClientInfo cinfo, clients ) { PortInfoList plist = cinfo.getPorts(); cout << "Client " << qSetFieldWidth(4) << left << cinfo.getClientId() << qSetFieldWidth(0) << " : \"" << cinfo.getName() << "\" [" << clientTypeName(cinfo.getClientType()) << "]" << endl; foreach( PortInfo pinfo, plist ) { SubscribersList to = pinfo.getReadSubscribers(); SubscribersList from = pinfo.getWriteSubscribers(); cout << " Port " << qSetFieldWidth(4) << right << pinfo.getPort() << qSetFieldWidth(0) << " : \"" << pinfo.getName() << "\"" << (pinfo.getType() != 0 ? portTypeNames(pinfo.getType()) : "") << endl; if ( from.count() > 0 ) cout << " Connected From: " << subsNames(from) << endl; if ( to.count() > 0 ) cout << " Connecting To: " << subsNames(to) << endl; } } } void systemInfo() { MidiClient* client = new MidiClient(); client->open(); client->setClientName(PGM_NAME); SystemInfo info = client->getSystemInfo(); cout << PGM_DESCRIPTION << ", version: "<< QStringLiteral(QT_STRINGIFY(VERSION)) << endl; cout << "Compiled ALSA library: " << getCompiledALSALibraryVersion() << endl; cout << "Runtime ALSA library: " << getRuntimeALSALibraryVersion() << endl; cout << "Runtime ALSA drivers: " << getRuntimeALSADriverVersion() << endl; cout << "Numeric ALSA compiled library: " << hex << SND_LIB_VERSION << endl; cout << "Numeric ALSA runtime library: " << getRuntimeALSALibraryNumber() << endl; cout << "Numeric ALSA runtime driver: " << getRuntimeALSADriverNumber() << endl; cout << "Max Clients: " << dec << info.getMaxClients() << endl; cout << "Max Ports: " << info.getMaxPorts() << endl; cout << "Max Queues: " << info.getMaxQueues() << endl; cout << "Max Channels: " << info.getMaxChannels() << endl; cout << "Current Queues: " << info.getCurrentQueues() << endl; cout << "Current Clients: " << info.getCurrentClients() << endl; queryTimers(); if (info.getCurrentQueues() > 0) queryQueues(client); if (info.getCurrentClients() > 0) queryClients(client); delete client; } int main(int argc, char **argv) { const QString ERRORSTR = QStringLiteral("Fatal error from the ALSA sequencer. " "This usually happens when the kernel doesn't have ALSA support, " "or the device node (/dev/snd/seq) doesn't exists, " "or the kernel module (snd_seq) is not loaded. " "Please check your ALSA/MIDI configuration."); QCoreApplication app(argc, argv); QCoreApplication::setApplicationName(PGM_NAME); QCoreApplication::setApplicationVersion(QStringLiteral(QT_STRINGIFY(VERSION))); QCommandLineParser parser; parser.setApplicationDescription(PGM_DESCRIPTION); auto helpOption = parser.addHelpOption(); auto versionOption = parser.addVersionOption(); parser.process(app); if (parser.isSet(versionOption) || parser.isSet(helpOption)) { return 0; } try { systemInfo(); } catch (const SequencerError& ex) { cerr << ERRORSTR << " Returned error was: " << ex.qstrError() << endl; } catch (...) { cerr << ERRORSTR << endl; } return 0; } drumstick-2.5.1/utils/sysinfo/PaxHeaders.27918/sysinfo.pro0000644000000000000000000000013214200302440020326 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/sysinfo/sysinfo.pro0000644000175000001440000000054714200302440021115 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = drumstick-sysinfo #QT += dbus CONFIG += c++11 cmdline qt thread exceptions static { CONFIG += link_prl } DESTDIR = ../../build/bin INCLUDEPATH += . ../../library/include DEPENDPATH += . ../../library ../../library/include LIBS = -L../../build/lib -ldrumstick-alsa -lasound include (../../global.pri) # Input SOURCES += sysinfo.cpp drumstick-2.5.1/utils/PaxHeaders.27918/dumpsmf0000644000000000000000000000013214200302440016016 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.441324575 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumpsmf/0000755000175000001440000000000014200302440016654 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/dumpsmf/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020633 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/dumpsmf/CMakeLists.txt0000644000175000001440000000256714200302440021426 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(dumpsmf_SRCS dumpsmf.cpp dumpsmf.h ) set(dumpsmf_qtobject_SRCS dumpsmf.h ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(dumpsmf_moc_SRCS ${dumpsmf_qtobject_SRCS}) else() qt_wrap_cpp(dumpsmf_moc_SRCS ${dumpsmf_qtobject_SRCS}) endif() add_executable(drumstick-dumpsmf ${dumpsmf_moc_SRCS} ${dumpsmf_SRCS} ) target_link_libraries(drumstick-dumpsmf PRIVATE Drumstick::File Qt${QT_VERSION_MAJOR}::Core ) if(QT_VERSION VERSION_GREATER_EQUAL 6.0.0) target_link_libraries(drumstick-dumpsmf PRIVATE Qt6::Core5Compat) endif() install(TARGETS drumstick-dumpsmf RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) drumstick-2.5.1/utils/dumpsmf/PaxHeaders.27918/dumpsmf.cpp0000644000000000000000000000013214200302440020252 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.441324575 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumpsmf/dumpsmf.cpp0000644000175000001440000002247514200302440021045 0ustar00pedrousers00000000000000/* Standard MIDI File dump program Copyright (C) 2006-2022, Pedro Lopez-Cabanillas Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "dumpsmf.h" #include #include #include #include #include #include #include #include #include DISABLE_WARNING_PUSH DISABLE_WARNING_DEPRECATED_DECLARATIONS #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #define right Qt::right #define left Qt::left #define endl Qt::endl #endif QTextStream cout(stdout, QIODevice::WriteOnly); QTextStream cerr(stderr, QIODevice::WriteOnly); using drumstick::File::QSmf; QSpySMF::QSpySMF(): m_currentTrack(0), m_engine(nullptr), m_rc(0) { QTextCodec *codec = QTextCodec::codecForName("UTF-8"); m_engine = new QSmf(this); m_engine->setTextCodec(codec); connect(m_engine, &QSmf::signalSMFHeader, this, &QSpySMF::headerEvent); connect(m_engine, &QSmf::signalSMFTrackStart, this, &QSpySMF::trackStartEvent); connect(m_engine, &QSmf::signalSMFTrackEnd, this, &QSpySMF::trackEndEvent); connect(m_engine, &QSmf::signalSMFNoteOn, this, &QSpySMF::noteOnEvent); connect(m_engine, &QSmf::signalSMFNoteOff, this, &QSpySMF::noteOffEvent); connect(m_engine, &QSmf::signalSMFKeyPress, this, &QSpySMF::keyPressEvent); connect(m_engine, &QSmf::signalSMFCtlChange, this, &QSpySMF::ctlChangeEvent); connect(m_engine, &QSmf::signalSMFPitchBend, this, &QSpySMF::pitchBendEvent); connect(m_engine, &QSmf::signalSMFProgram, this, &QSpySMF::programEvent); connect(m_engine, &QSmf::signalSMFChanPress, this, &QSpySMF::chanPressEvent); connect(m_engine, &QSmf::signalSMFSysex, this, &QSpySMF::sysexEvent); connect(m_engine, &QSmf::signalSMFSeqSpecific, this, &QSpySMF::seqSpecificEvent); connect(m_engine, &QSmf::signalSMFMetaUnregistered, this, &QSpySMF::metaMiscEvent); connect(m_engine, &QSmf::signalSMFSequenceNum, this, &QSpySMF::seqNum); connect(m_engine, &QSmf::signalSMFforcedChannel, this, &QSpySMF::forcedChannel); connect(m_engine, &QSmf::signalSMFforcedPort, this, &QSpySMF::forcedPort); connect(m_engine, &QSmf::signalSMFText, this, &QSpySMF::textEvent); connect(m_engine, &QSmf::signalSMFendOfTrack, this, &QSpySMF::endOfTrackEvent); connect(m_engine, &QSmf::signalSMFTimeSig, this, &QSpySMF::timeSigEvent); connect(m_engine, &QSmf::signalSMFSmpte, this, &QSpySMF::smpteEvent); connect(m_engine, &QSmf::signalSMFKeySig, this, &QSpySMF::keySigEvent); connect(m_engine, &QSmf::signalSMFTempo, this, &QSpySMF::tempoEvent); connect(m_engine, &QSmf::signalSMFError, this, &QSpySMF::errorHandler); cout.setRealNumberNotation(QTextStream::FixedNotation); cout.setRealNumberPrecision(4); #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) cout.setCodec(codec); #else cout.setEncoding(QStringConverter::Utf8); #endif } void QSpySMF::dump(const QString& chan, const QString& event, const QString& data) { cout << right << qSetFieldWidth(7) << m_engine->getCurrentTime(); cout << right << qSetFieldWidth(10) << m_engine->getRealTime() / 1600.0; cout << qSetFieldWidth(3) << chan; cout << qSetFieldWidth(0) << left << " "; cout << qSetFieldWidth(15) << event; cout << qSetFieldWidth(0) << " " << data << endl; } void QSpySMF::dumpStr(const QString& event, const QString& data) { cout << right << qSetFieldWidth(7) << m_engine->getCurrentTime(); cout << right << qSetFieldWidth(10) << m_engine->getRealTime() / 1600.0; cout << qSetFieldWidth(3) << "--"; cout << qSetFieldWidth(0) << left << " "; cout << qSetFieldWidth(15) << event; cout << qSetFieldWidth(0) << " " << data << endl; } void QSpySMF::headerEvent(int format, int ntrks, int division) { dumpStr("SMF Header", QString("Format=%1, Tracks=%2, Division=%3") .arg(format).arg(ntrks).arg(division)); } void QSpySMF::trackStartEvent() { m_currentTrack++; dumpStr("Track", QString("Start: %1").arg(m_currentTrack)); } void QSpySMF::trackEndEvent() { dumpStr("Track", QString("End: %1").arg(m_currentTrack)); } void QSpySMF::endOfTrackEvent() { dumpStr("Meta Event", "End Of Track"); } void QSpySMF::noteOnEvent(int chan, int pitch, int vol) { dump(QString("%1").arg(chan, 2), "Note On", QString("%1, %2").arg(pitch).arg(vol)); } void QSpySMF::noteOffEvent(int chan, int pitch, int vol) { dump(QString("%1").arg(chan, 2), "Note Off", QString("%1, %2").arg(pitch).arg(vol)); } void QSpySMF::keyPressEvent(int chan, int pitch, int press) { dump(QString("%1").arg(chan, 2), "Key Pressure", QString("%1, %2").arg(pitch).arg(press)); } void QSpySMF::ctlChangeEvent(int chan, int ctl, int value) { dump(QString("%1").arg(chan, 2), "Control Change", QString("%1, %2").arg(ctl).arg(value)); } void QSpySMF::pitchBendEvent(int chan, int value) { dump(QString("%1").arg(chan, 2), "Pitch Bend", QString::number(value)); } void QSpySMF::programEvent(int chan, int patch) { dump(QString("%1").arg(chan, 2), "Program Change", QString::number(patch)); } void QSpySMF::chanPressEvent(int chan, int press) { dump(QString("%1").arg(chan, 2), "Chan.Pressure", QString::number(press)); } void QSpySMF::sysexEvent(const QByteArray& data) { int j; QString s; for (j = 0; j < data.count(); ++j) s.append(QString("%1 ").arg(data[j] & 0xff, 2, 16)); dumpStr("SysEx", s); } /*void QSpySMF::variableEvent(const QByteArray& data) { int j; QString s; for (j = 0; j < data.count(); ++j) s.append(QString("%1 ").arg(data[j] & 0xff, 2, 16)); dumpStr("Variable event", s); }*/ void QSpySMF::seqSpecificEvent(const QByteArray& data) { int j; QString s; for (j = 0; j < data.count(); ++j) s.append(QString("%1 ").arg(data[j] & 0xff, 2, 16)); dumpStr("Seq. specific", s); } void QSpySMF::metaMiscEvent(int typ, const QByteArray& data) { int j; QString s = QString("type=%1 ").arg(typ); for (j = 0; j < data.count(); ++j) s.append(QString("%1 ").arg(data[j] & 0xff, 2, 16)); dumpStr("Meta (unreg.)", s); } void QSpySMF::seqNum(int seq) { dump("--", "Sequence num.", QString::number(seq)); } void QSpySMF::forcedChannel(int channel) { dump("--", "Forced channel", QString::number(channel)); } void QSpySMF::forcedPort(int port) { dump("--", "Forced port", QString::number(port)); } void QSpySMF::textEvent(int typ, const QString& data) { dumpStr(QString("Text (%1)").arg(typ), data); } void QSpySMF::smpteEvent(int b0, int b1, int b2, int b3, int b4) { dump("--", "SMPTE", QString("%1, %2, %3, %4, %5").arg(b0).arg(b1).arg(b2).arg(b3).arg(b4)); } void QSpySMF::timeSigEvent(int b0, int b1, int b2, int b3) { dump("--", "Time Signature", QString("%1, %2, %3, %4").arg(b0).arg(b1).arg(b2).arg(b3)); } void QSpySMF::keySigEvent(int b0, int b1) { dump("--", "Key Signature", QString("%1, %2").arg(b0).arg(b1)); } void QSpySMF::tempoEvent(int tempo) { dump("--", "Tempo", QString::number(tempo)); } void QSpySMF::errorHandler(const QString& errorStr) { m_rc++; cerr << "*** Warning! " << errorStr << " at file offset " << m_engine->getFilePos() << endl; } void QSpySMF::run(QString fileName) { m_currentTrack = 0; cout << "__ticks __seconds ch event__________ data____" << endl; m_engine->readFromFile(fileName); } int QSpySMF::numErrors() { return m_rc; } int main(int argc, char **argv) { const QString PGM_NAME = QStringLiteral("drumstick-dumpsmf"); const QString PGM_DESCRIPTION = QStringLiteral("Drumstick command line utility for decoding SMF (Standard MIDI) files"); QSpySMF spy; QCoreApplication app(argc, argv); QCoreApplication::setApplicationName(PGM_NAME); QCoreApplication::setApplicationVersion(QStringLiteral(QT_STRINGIFY(VERSION))); QCommandLineParser parser; parser.setApplicationDescription(PGM_DESCRIPTION); auto helpOption = parser.addHelpOption(); auto versionOption = parser.addVersionOption(); parser.addPositionalArgument("file", "Input SMF file name.", "files..."); parser.process(app); if (parser.isSet(versionOption) || parser.isSet(helpOption)) { return 0; } QStringList fileNames, positionalArgs = parser.positionalArguments(); if (positionalArgs.isEmpty()) { cerr << "Input file name(s) missing" << endl; parser.showHelp(); } foreach(const QString& a, positionalArgs) { QFileInfo f(a); if (f.exists()) fileNames += f.canonicalFilePath(); else cerr << "File not found: " << a << endl; } foreach(const QString& file, fileNames) { spy.run(file); } return spy.numErrors(); } DISABLE_WARNING_POP drumstick-2.5.1/utils/dumpsmf/PaxHeaders.27918/dumpsmf.pro0000644000000000000000000000013214200302440020270 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.441324575 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumpsmf/dumpsmf.pro0000644000175000001440000000076614200302440021062 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = drumstick-dumpsmf CONFIG += c++11 cmdline qt static { CONFIG += link_prl DEFINES += DRUMSTICK_STATIC } DESTDIR = ../../build/bin INCLUDEPATH += . ../../library/include include (../../global.pri) # Input HEADERS += dumpsmf.h SOURCES += dumpsmf.cpp macx:!static { QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib LIBS += -framework drumstick-file } else { LIBS = -L$$OUT_PWD/../../build/lib \ -l$$drumstickLib(drumstick-file) } drumstick-2.5.1/utils/dumpsmf/PaxHeaders.27918/dumpsmf.h0000644000000000000000000000013214200302440017717 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/dumpsmf/dumpsmf.h0000644000175000001440000000441714200302440020506 0ustar00pedrousers00000000000000/* Standard MIDI File dump program Copyright (C) 2006-2022, Pedro Lopez-Cabanillas Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include class QSpySMF : public QObject { Q_OBJECT public: QSpySMF(); void run(QString fileName); void dump(const QString& chan, const QString& event, const QString& data); void dumpStr(const QString& event, const QString& data); int numErrors(); public slots: void headerEvent(int format, int ntrks, int division); void trackStartEvent(); void trackEndEvent(); void endOfTrackEvent(); void noteOnEvent(int chan, int pitch, int vol); void noteOffEvent(int chan, int pitch, int vol); void keyPressEvent(int chan, int pitch, int press); void ctlChangeEvent(int chan, int ctl, int value); void pitchBendEvent(int chan, int value); void programEvent(int chan, int patch); void chanPressEvent(int chan, int press); void sysexEvent(const QByteArray& data); //void variableEvent(const QByteArray& data); void seqSpecificEvent(const QByteArray& data); void metaMiscEvent(int typ, const QByteArray& data); void seqNum(int seq); void forcedChannel(int channel); void forcedPort(int port); void textEvent(int typ, const QString& data); void smpteEvent(int b0, int b1, int b2, int b3, int b4); void timeSigEvent(int b0, int b1, int b2, int b3); void keySigEvent(int b0, int b1); void tempoEvent(int tempo); void errorHandler(const QString& errorStr); private: int m_currentTrack; drumstick::File::QSmf *m_engine; int m_rc; }; drumstick-2.5.1/utils/PaxHeaders.27918/guiplayer0000644000000000000000000000013214200302440016344 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/0000755000175000001440000000000014200302440017202 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/guiplayer.pro0000644000000000000000000000013214200302440021144 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/guiplayer.pro0000644000175000001440000000133714200302440021731 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = drumstick-guiplayer QT += gui widgets #dbus CONFIG += qt c++11 thread exceptions CONFIG += lrelease static { CONFIG += link_prl } DESTDIR = ../../build/bin LRELEASE_DIR=. INCLUDEPATH += . ../../library/include LIBS = -L../../build/lib -ldrumstick-file -ldrumstick-alsa -lasound include (../../global.pri) # Input HEADERS += player.h guiplayer.h song.h playerabout.h iconutils.h FORMS += guiplayer.ui playerabout.ui SOURCES += playermain.cpp \ player.cpp \ guiplayer.cpp \ song.cpp \ iconutils.cpp \ playerabout.cpp RESOURCES += guiplayer.qrc TRANSLATIONS += \ drumstick-guiplayer_cs.ts \ drumstick-guiplayer_en.ts \ drumstick-guiplayer_es.ts \ drumstick-guiplayer_ru.ts drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440021161 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/CMakeLists.txt0000644000175000001440000000612314200302440021744 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR TRUE) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Gui Widgets LinguistTools REQUIRED) set(guiplayer_forms_SRCS guiplayer.ui playerabout.ui ) set(guiplayer_SRCS guiplayer.cpp guiplayer.h iconutils.cpp iconutils.h player.cpp player.h playerabout.cpp playerabout.h playermain.cpp song.cpp song.h ) set(guiplayer_qtobject_SRCS player.h playerabout.h guiplayer.h ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_ui(guiplayer_ui_SRCS ${guiplayer_forms_SRCS}) qt5_wrap_cpp(guiplayer_moc_SRCS ${guiplayer_qtobject_SRCS}) qt5_add_resources(guiplayer_resources guiplayer.qrc) else() qt_wrap_ui(guiplayer_ui_SRCS ${guiplayer_forms_SRCS}) qt_wrap_cpp(guiplayer_moc_SRCS ${guiplayer_qtobject_SRCS}) qt_add_resources(guiplayer_resources guiplayer.qrc) endif() add_executable(drumstick-guiplayer ${guiplayer_resources} ${guiplayer_ui_SRCS} ${guiplayer_moc_SRCS} ${guiplayer_SRCS} ) target_link_libraries(drumstick-guiplayer PRIVATE Drumstick::File Drumstick::ALSA Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Widgets ) if(QT_VERSION VERSION_GREATER_EQUAL 6.0.0) target_link_libraries(drumstick-guiplayer PRIVATE Qt6::Core5Compat) endif() set(TS_FILES drumstick-guiplayer_cs.ts drumstick-guiplayer_es.ts drumstick-guiplayer_ru.ts ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_add_translation(QM_FILES ${TS_FILES}) else() qt_add_translation(QM_FILES ${TS_FILES}) endif() add_custom_command(TARGET drumstick-guiplayer POST_BUILD COMMAND Qt${QT_VERSION_MAJOR}::lupdate ${CMAKE_CURRENT_SOURCE_DIR} -ts ${TS_FILES} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Updating translations" ) add_custom_target(drumstick-guiplayer-translations ALL DEPENDS ${QM_FILES}) if (UNIX AND NOT APPLE) install( FILES ${QM_FILES} DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/drumstick" ) endif () install(TARGETS drumstick-guiplayer RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES drumstick-guiplayer.desktop DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" RENAME net.sourceforge.drumstick-guiplayer.desktop) install(FILES drumstick-guiplayer.metainfo.xml DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo" RENAME net.sourceforge.drumstick-guiplayer.metainfo.xml) drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/song.h0000644000000000000000000000013214200302440017540 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/song.h0000644000175000001440000000331014200302440020316 0ustar00pedrousers00000000000000/* SMF GUI Player test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef INCLUDED_SONG_H #define INCLUDED_SONG_H #include namespace drumstick { namespace ALSA { class SequencerEvent; }} class Song : public QList { public: Song() : QList(), m_format(0), m_ntrks(0), m_division(0) { } virtual ~Song(); void clear(); void sort(); void setHeader(int format, int ntrks, int division); void setDivision(int division); void setFileName(const QString& fileName); int getFormat() const { return m_format; } int getTracks() const { return m_ntrks; } int getDivision() const { return m_division; } QString getFileName() const { return m_fileName; } private: int m_format; int m_ntrks; int m_division; QString m_fileName; }; typedef QListIterator SongIterator; #endif /*INCLUDED_SONG_H*/ drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/playermain.cpp0000644000000000000000000000013214200302440021266 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/guiplayer/playermain.cpp0000644000175000001440000001054714200302440022056 0ustar00pedrousers00000000000000/* SMF GUI Player test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "guiplayer.h" const char* PGM_DESCRIPTION = QT_TRANSLATE_NOOP("main", "ALSA Sequencer based MIDI file player"); const char* errorstr = QT_TRANSLATE_NOOP("main", "Fatal error from the ALSA sequencer. " "This usually happens when the kernel doesn't have ALSA support, " "or the device node (/dev/snd/seq) doesn't exists, " "or the kernel module (snd_seq) is not loaded. " "Please check your ALSA/MIDI configuration."); int main(int argc, char *argv[]) { QApplication app(argc, argv); QCoreApplication::setOrganizationName(GUIPlayer::QSTR_DOMAIN); QCoreApplication::setOrganizationDomain(GUIPlayer::QSTR_DOMAIN); QCoreApplication::setApplicationName(GUIPlayer::QSTR_APPNAME); QCoreApplication::setApplicationVersion(QStringLiteral(QT_STRINGIFY(VERSION))); QLocale locale; QTranslator qtTranslator; if ((locale.language() != QLocale::C) && (locale.language() != QLocale::English)) { if (qtTranslator.load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { QCoreApplication::installTranslator(&qtTranslator); } else { qWarning() << "Unable to load Qt translator:" << locale.name(); } } #if defined(Q_OS_WIN32) QString dataDir = QApplication::applicationDirPath() + "/"; #elif defined(Q_OS_MAC) QString dataDir = QApplication::applicationDirPath() + "/../Resources/"; #else QString dataDir = QApplication::applicationDirPath() + "/../share/drumstick/"; #endif QTranslator appTranslator; if ((locale.language() != QLocale::C) && (locale.language() != QLocale::English)) { if (appTranslator.load(locale, "drumstick-guiplayer", "_", dataDir)) { QCoreApplication::installTranslator(&appTranslator); } else { qWarning() << "Unable to load app translator:" << locale.name(); } } QCommandLineParser parser; parser.setApplicationDescription(QCoreApplication::translate("main", PGM_DESCRIPTION)); auto helpOption = parser.addHelpOption(); auto versionOption = parser.addVersionOption(); QCommandLineOption portOption({"p", "port"}, QCoreApplication::translate("main", "MIDI Out Connection."), "client:port"); parser.addOption(portOption); parser.addPositionalArgument("file", QCoreApplication::translate("main", "Input SMF/KAR/RMI/WRK file name."), "file"); parser.process(app); QStringList fileNames, positionalArgs = parser.positionalArguments(); foreach(const QString& a, positionalArgs) { QFileInfo f(a); if (f.exists()) fileNames += f.canonicalFilePath(); else qWarning() << QCoreApplication::translate("main", "File not found: ") << a; } try { GUIPlayer w; if(parser.isSet(portOption)) { QString port = parser.value(portOption); w.subscribe(port); } if (!fileNames.isEmpty()) { w.openFile(fileNames.first()); } w.show(); return app.exec(); } catch (const drumstick::ALSA::SequencerError& ex) { QMessageBox::critical(nullptr, QCoreApplication::translate("main", "Error"), QCoreApplication::translate("main", errorstr) + "\n" + QCoreApplication::translate("main", "Returned error was: ") + ex.qstrError() ); } catch (...) { qWarning() << QCoreApplication::translate("main", errorstr); } return EXIT_FAILURE; } drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/drumstick-guiplayer_ru.ts0000644000000000000000000000013214200302440023503 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/drumstick-guiplayer_ru.ts0000644000175000001440000004761214200302440024276 0ustar00pedrousers00000000000000 About Revision AboutClass About О программе <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick ALSA MIDI Player %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick ALSA MIDI Player %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> About Qt О Qt GUIPlayerClass Drumstick ALSA MIDI Player Drumstick MIDI Player Проигрыватель Drumstick MIDI Playback time and current levels Время воспроизведения и текущие уровни 00:00:00 00:00:00 Tempo: Темп: Volume: Громкость: Pitch: Тон: Pitch Control Управление тоном Pitch transpose between -12 and +12 semitones Изменение тона от –12 до +12 полутонов Reset Volume Сбросить громкость Reset Volume to 100% Сбросить громкость на 100% Volume Slider Бегунок громкости Playback progress Прогресс воспроизведения File Name: Имя файла: Currently loaded MIDI file name Имя загруженного MIDI файла Tempo Slider Бегунок темпа Reset Tempo Сбросить темп Reset Tempo to 100% Сбросить темп на 100% tempo=100% темп=100% File Файл Help Справка Settings Настройки Tool Bar Панель инструментов Open Открыть Open a MIDI file Открыть файл MIDI Quit Выход Quit the application Выйти из приложения Play Играть Start playing the current MIDI file Начать воспроизведение текущего файла MIDI Pause Пауза Pause the playback Приостановить воспроизведение Stop Стоп Stop the playback Остановить воспроизведение About О программе Show the about box Показать информацию о программе About Qt О Qt Show the about Qt dialog box Показать информацию о Qt MIDI Setup Настройка MIDI Select a connection for the MIDI output port Выберите соединение для порта выхода MIDI Show Tool Bar Показать панель инструментов Show or hide the tool bar Показать или скрыть панель инструментов Show Status Bar Показать панель статуса Show or hide the status bar Показать или скрыть панель статуса main ALSA Sequencer based MIDI file player Fatal error from the ALSA sequencer. This usually happens when the kernel doesn't have ALSA support, or the device node (/dev/snd/seq) doesn't exists, or the kernel module (snd_seq) is not loaded. Please check your ALSA/MIDI configuration. MIDI Out Connection. Input SMF/KAR/RMI/WRK file name. File not found: Error Returned error was: drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/song.cpp0000644000000000000000000000013214200302440020073 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/song.cpp0000644000175000001440000000301514200302440020653 0ustar00pedrousers00000000000000/* SMF GUI Player test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "song.h" #include using namespace drumstick::ALSA; static inline bool eventLessThan(const SequencerEvent* s1, const SequencerEvent* s2) { return s1->getTick() < s2->getTick(); } Song::~Song() { clear(); } void Song::sort() { std::sort(begin(), end(), eventLessThan); } void Song::clear() { while (!isEmpty()) delete takeFirst(); m_fileName.clear(); m_format = 0; m_ntrks = 0; m_division = 0; } void Song::setHeader(int format, int ntrks, int division) { m_format = format; m_ntrks = ntrks; m_division = division; } void Song::setDivision(int division) { m_division = division; } void Song::setFileName(const QString& fileName) { m_fileName = fileName; } drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/drumstick-guiplayer_es.ts0000644000000000000000000000013214200302440023464 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/guiplayer/drumstick-guiplayer_es.ts0000644000175000001440000006040714200302440024254 0ustar00pedrousers00000000000000 About Revision Revisión AboutClass About Acerca de <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick ALSA MIDI Player %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick ALSA MIDI Player %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick MIDI Player %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> About Qt Acerca de Qt GUIPlayerClass Drumstick ALSA MIDI Player Reproductor ALSA MIDI Drumstick Drumstick MIDI Player Reproductor MIDI Drumstick Playback time and current levels Tiempo de reproducción y niveles actuales 00:00:00 00:00:00 Tempo: Tempo: Volume: Volumen: Pitch: Transporte: Pitch Control Control de tono Pitch transpose between -12 and +12 semitones Transporte del tono entre -12 y +12 semitonos Reset Volume Restablecer volumen Reset Volume to 100% Restablecer volumen al 100% Volume Slider Deslizador de volumen Playback progress Progreso de reproducción File Name: Nombre de archivo: Currently loaded MIDI file name Nombre de archivo MIDI actual Tempo Slider Deslizador de tempo Reset Tempo Restablecer tempo Reset Tempo to 100% Restablecer el tempo al 100% tempo=100% tempo=100% File Archivo Help Ayuda Settings Preferencias Tool Bar Barra de herramientas Open Abrir Open a MIDI file Abrir un archivo MIDI Quit Terminar Quit the application Terminar la aplicación Play Reproducir Start playing the current MIDI file Iniciar la reproducción del archivo MIDI actual Pause Pausa Pause the playback Pausar la reproducción Stop Parar Stop the playback Parar la reproducción About Acerca de Show the about box Mostrar el cuadro de Acerca de About Qt Acerca de Qt Show the about Qt dialog box Mostrar el cuadro de Acerca de Qt MIDI Setup Ajustes MIDI Select a connection for the MIDI output port Seleccionar una conexión para el puerto de salida MIDI Show Tool Bar Mostrar la barra de herramientas Show or hide the tool bar Mostrar u ocultar la barra de herramientas Show Status Bar Mostrar la barra de estado Show or hide the status bar Mostar u ocultar la barra de estado main ALSA Sequencer based MIDI file player Reproductor de archivos MIDI basado en el secuenciador ALSA Fatal error from the ALSA sequencer. This usually happens when the kernel doesn't have ALSA support, or the device node (/dev/snd/seq) doesn't exists, or the kernel module (snd_seq) is not loaded. Please check your ALSA/MIDI configuration. Error fatal en el secuenciador ALSA. Esto ocurre habitualmente cuando el núcleo no tiene soporte ALSA, o bién el nodo de dispositivo (/dev/snd/seq) no existe, o el módulo del núcleo (snd_seq) no se ha cargado. Por favor compruebe su configuración de MIDI ALSA. MIDI Out Connection. Conexión MIDI Out. Input SMF/KAR/RMI/WRK file name. Archivo de entrada SMF/KAR/RMI/WRK. File not found: Archivo no encontrado: Error Error Returned error was: El error devuelto fué: drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/guiplayer.h0000644000000000000000000000013214200302440020573 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/guiplayer.h0000644000175000001440000001345714200302440021366 0ustar00pedrousers00000000000000/* SMF GUI Player test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef INCLUDED_GUIPLAYER_H #define INCLUDED_GUIPLAYER_H #include #include #include #include #include #include #include namespace drumstick { namespace ALSA { class MidiClient; class MidiPort; class MidiQueue; class SequencerEvent; class SysExEvent; } namespace File { class QSmf; class QWrk; class Rmidi; } } namespace Ui { class GUIPlayerClass; } class Player; class About; class Song; class GUIPlayer : public QMainWindow { Q_OBJECT public: enum PlayerState { InvalidState, EmptyState, PlayingState, PausedState, StoppedState }; Q_ENUM(PlayerState) GUIPlayer(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::Window); ~GUIPlayer(); void appendSMFEvent(drumstick::ALSA::SequencerEvent* ev); void appendWRKEvent(unsigned long ticks, drumstick::ALSA::SequencerEvent* ev); void subscribe(const QString& portName); void updateTimeLabel(int mins, int secs, int cnts); void updateTempoLabel(float ftempo); void dragEnterEvent(QDragEnterEvent* event) override; void dropEvent(QDropEvent* event) override; void closeEvent(QCloseEvent* event) override; void openFile(const QString& fileName); void readSettings(); void writeSettings(); void updateState(PlayerState newState); void progressDialogInit(const QString& type, int max); void progressDialogUpdate(int pos); void progressDialogClose(); static const QString QSTR_DOMAIN; static const QString QSTR_APPNAME; public slots: void about(); void play(); void pause(); void stop(); void open(); void setup(); void tempoReset(); void volumeReset(); void tempoSlider(int value); void volumeSlider(int value); void pitchShift(int value); void songFinished(); void playerStopped(); void sequencerEvent(drumstick::ALSA::SequencerEvent* ev); /* RMI slots */ void dataHandler(const QString &dataType, const QByteArray &data); /* SMF slots */ void smfHeaderEvent(int format, int ntrks, int division); void smfNoteOnEvent(int chan, int pitch, int vol); void smfNoteOffEvent(int chan, int pitch, int vol); void smfKeyPressEvent(int chan, int pitch, int press); void smfCtlChangeEvent(int chan, int ctl, int value); void smfPitchBendEvent(int chan, int value); void smfProgramEvent(int chan, int patch); void smfChanPressEvent(int chan, int press); void smfSysexEvent(const QByteArray& data); void smfTempoEvent(int tempo); void smfErrorHandler(const QString& errorStr); void smfTrackStarted(); void smfTrackEnded(); void smfUpdateLoadProgress(); /* WRK slots */ void wrkUpdateLoadProgress(); void wrkErrorHandler(const QString& errorStr); void wrkFileHeader(int verh, int verl); void wrkEndOfFile(); void wrkStreamEndEvent(long time); void wrkTrackHeader(const QString& name1, const QString& name2, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop); void wrkTimeBase(int timebase); void wrkNoteEvent(int track, long time, int chan, int pitch, int vol, int dur); void wrkKeyPressEvent(int track, long time, int chan, int pitch, int press); void wrkCtlChangeEvent(int track, long time, int chan, int ctl, int value); void wrkPitchBendEvent(int track, long time, int chan, int value); void wrkProgramEvent(int track, long time, int chan, int patch); void wrkChanPressEvent(int track, long time, int chan, int press); void wrkSysexEvent(int track, long time, int bank); void wrkSysexEventBank(int bank, const QString& name, bool autosend, int port, const QByteArray& data); void wrkTempoEvent(long time, int tempo); void wrkTrackPatch(int track, int patch); void wrkNewTrackHeader(const QString& name, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop); void wrkTrackVol(int track, int vol); void wrkTrackBank(int track, int bank); private: int m_portId; int m_queueId; int m_initialTempo; int m_currentTrack; float m_tempoFactor; unsigned long m_tick; PlayerState m_state; drumstick::File::QSmf* m_smf; drumstick::File::QWrk* m_wrk; drumstick::File::Rmidi* m_rmi; drumstick::ALSA::MidiClient* m_Client; drumstick::ALSA::MidiPort* m_Port; drumstick::ALSA::MidiQueue* m_Queue; Player* m_player; Ui::GUIPlayerClass* m_ui; QPointer m_pd; Song* m_song; QString m_subscription; QString m_lastDirectory; QString m_loadingMessages; QHash m_savedSysexEvents; struct TrackMapRec { int channel; int pitch; int velocity; }; QHash m_trackMap; }; #endif // INCLUDED_GUIPLAYER_H drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/guiplayer.cpp0000644000000000000000000000013214200302440021126 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/guiplayer.cpp0000644000175000001440000007245314200302440021722 0ustar00pedrousers00000000000000/* SMF GUI Player test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "guiplayer.h" #include "iconutils.h" #include "player.h" #include "playerabout.h" #include "song.h" #include "ui_guiplayer.h" #include #include #include #include #include #include #include #include DISABLE_WARNING_PUSH DISABLE_WARNING_DEPRECATED_DECLARATIONS using namespace drumstick; using namespace ALSA; using namespace File; const QString GUIPlayer::QSTR_DOMAIN = QStringLiteral("drumstick.sourceforge.net"); const QString GUIPlayer::QSTR_APPNAME = QStringLiteral("drumstick-guiplayer"); GUIPlayer::GUIPlayer(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags), m_portId(-1), m_queueId(-1), m_initialTempo(0), m_currentTrack(0), m_tempoFactor(1.0), m_tick(0), m_state(InvalidState), m_smf(nullptr), m_wrk(nullptr), m_Client(nullptr), m_Port(nullptr), m_Queue(nullptr), m_player(nullptr), m_ui(new Ui::GUIPlayerClass), m_pd(nullptr), m_song(new Song) { m_ui->setupUi(this); setAcceptDrops(true); connect(m_ui->actionAbout, &QAction::triggered, this, &GUIPlayer::about); connect(m_ui->actionAboutQt, &QAction::triggered, qApp, QApplication::aboutQt); connect(m_ui->actionPlay, &QAction::triggered, this, &GUIPlayer::play); connect(m_ui->actionPause, &QAction::triggered, this, &GUIPlayer::pause); connect(m_ui->actionStop, &QAction::triggered, this, &GUIPlayer::stop); connect(m_ui->actionOpen, &QAction::triggered, this, &GUIPlayer::open); connect(m_ui->actionMIDISetup, &QAction::triggered, this, &GUIPlayer::setup); connect(m_ui->actionQuit, &QAction::triggered, this, &GUIPlayer::close); connect(m_ui->btnTempo, &QPushButton::clicked, this, &GUIPlayer::tempoReset); connect(m_ui->btnVolume, &QPushButton::clicked, this, &GUIPlayer::volumeReset); connect(m_ui->sliderTempo, &QSlider::valueChanged, this, &GUIPlayer::tempoSlider); connect(m_ui->volumeSlider, &QSlider::valueChanged, this, &GUIPlayer::volumeSlider); connect(m_ui->spinPitch, QOverload::of(&QSpinBox::valueChanged), this, &GUIPlayer::pitchShift); connect(m_ui->toolBar->toggleViewAction(), &QAction::toggled, m_ui->actionShowToolbar, &QAction::setChecked); m_ui->actionPlay->setIcon(QIcon(IconUtils::GetPixmap(this, ":/resources/play.png"))); m_ui->actionPlay->setShortcut( Qt::Key_MediaPlay ); m_ui->actionStop->setIcon(QIcon(IconUtils::GetPixmap(this, ":/resources/stop.png"))); m_ui->actionStop->setShortcut( Qt::Key_MediaStop ); m_ui->actionPause->setIcon(QIcon(IconUtils::GetPixmap(this, ":/resources/pause.png"))); m_ui->actionMIDISetup->setIcon(QIcon(IconUtils::GetPixmap(this, ":/resources/setup.png"))); m_Client = new MidiClient(this); m_Client->open(); m_Client->setPoolOutput(50); // small size, for near real-time pitchShift m_Client->setClientName("MIDI Player"); connect( m_Client, &MidiClient::eventReceived, this, &GUIPlayer::sequencerEvent, Qt::QueuedConnection ); m_Port = new MidiPort(this); m_Port->attach( m_Client ); m_Port->setPortName("MIDI Player Output Port"); m_Port->setCapability( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ | SND_SEQ_PORT_CAP_WRITE ); m_Port->setPortType( SND_SEQ_PORT_TYPE_APPLICATION | SND_SEQ_PORT_TYPE_MIDI_GENERIC ); m_Queue = m_Client->createQueue(QSTR_APPNAME); m_queueId = m_Queue->getId(); m_portId = m_Port->getPortId(); m_rmi = new Rmidi(this); connect(m_rmi, &Rmidi::signalRiffData, this, &GUIPlayer::dataHandler); m_smf = new QSmf(this); connect(m_smf, &QSmf::signalSMFHeader, this, &GUIPlayer::smfHeaderEvent); connect(m_smf, &QSmf::signalSMFNoteOn, this, &GUIPlayer::smfNoteOnEvent); connect(m_smf, &QSmf::signalSMFNoteOff, this, &GUIPlayer::smfNoteOffEvent); connect(m_smf, &QSmf::signalSMFKeyPress, this, &GUIPlayer::smfKeyPressEvent); connect(m_smf, &QSmf::signalSMFCtlChange, this, &GUIPlayer::smfCtlChangeEvent); connect(m_smf, &QSmf::signalSMFPitchBend, this, &GUIPlayer::smfPitchBendEvent); connect(m_smf, &QSmf::signalSMFProgram, this, &GUIPlayer::smfProgramEvent); connect(m_smf, &QSmf::signalSMFChanPress, this, &GUIPlayer::smfChanPressEvent); connect(m_smf, &QSmf::signalSMFSysex, this, &GUIPlayer::smfSysexEvent); connect(m_smf, &QSmf::signalSMFText, this, &GUIPlayer::smfUpdateLoadProgress); connect(m_smf, &QSmf::signalSMFTempo, this, &GUIPlayer::smfTempoEvent); connect(m_smf, &QSmf::signalSMFTrackStart, this, &GUIPlayer::smfUpdateLoadProgress); connect(m_smf, &QSmf::signalSMFTrackStart, this, &GUIPlayer::smfTrackStarted); connect(m_smf, &QSmf::signalSMFTrackEnd, this, &GUIPlayer::smfTrackEnded); connect(m_smf, &QSmf::signalSMFendOfTrack, this, &GUIPlayer::smfUpdateLoadProgress); connect(m_smf, &QSmf::signalSMFError, this, &GUIPlayer::smfErrorHandler); m_wrk = new QWrk(this); m_wrk->setTextCodec(QTextCodec::codecForLocale()); connect(m_wrk, &QWrk::signalWRKError, this, &GUIPlayer::wrkErrorHandler); connect(m_wrk, &QWrk::signalWRKUnknownChunk, this, &GUIPlayer::wrkUpdateLoadProgress); connect(m_wrk, &QWrk::signalWRKHeader, this, &GUIPlayer::wrkFileHeader); connect(m_wrk, &QWrk::signalWRKEnd, this, &GUIPlayer::wrkEndOfFile); connect(m_wrk, &QWrk::signalWRKStreamEnd, this, &GUIPlayer::wrkStreamEndEvent); connect(m_wrk, &QWrk::signalWRKGlobalVars, this, &GUIPlayer::wrkUpdateLoadProgress); connect(m_wrk, &QWrk::signalWRKTrack, this, &GUIPlayer::wrkTrackHeader); connect(m_wrk, &QWrk::signalWRKTimeBase, this, &GUIPlayer::wrkTimeBase); connect(m_wrk, &QWrk::signalWRKNote, this, &GUIPlayer::wrkNoteEvent); connect(m_wrk, &QWrk::signalWRKKeyPress, this, &GUIPlayer::wrkKeyPressEvent); connect(m_wrk, &QWrk::signalWRKCtlChange, this, &GUIPlayer::wrkCtlChangeEvent); connect(m_wrk, &QWrk::signalWRKPitchBend, this, &GUIPlayer::wrkPitchBendEvent); connect(m_wrk, &QWrk::signalWRKProgram, this, &GUIPlayer::wrkProgramEvent); connect(m_wrk, &QWrk::signalWRKChanPress, this, &GUIPlayer::wrkChanPressEvent); connect(m_wrk, &QWrk::signalWRKSysexEvent, this, &GUIPlayer::wrkSysexEvent); connect(m_wrk, &QWrk::signalWRKSysex, this, &GUIPlayer::wrkSysexEventBank); connect(m_wrk, &QWrk::signalWRKText, this, &GUIPlayer::wrkUpdateLoadProgress); connect(m_wrk, &QWrk::signalWRKTimeSig, this, &GUIPlayer::wrkUpdateLoadProgress); connect(m_wrk, &QWrk::signalWRKKeySig, this, &GUIPlayer::wrkUpdateLoadProgress); connect(m_wrk, &QWrk::signalWRKTempo, this, &GUIPlayer::wrkTempoEvent); connect(m_wrk, &QWrk::signalWRKTrackPatch, this, &GUIPlayer::wrkTrackPatch); connect(m_wrk, &QWrk::signalWRKComments, this, &GUIPlayer::wrkUpdateLoadProgress); connect(m_wrk, &QWrk::signalWRKVariableRecord, this, &GUIPlayer::wrkUpdateLoadProgress); connect(m_wrk, &QWrk::signalWRKNewTrack, this, &GUIPlayer::wrkNewTrackHeader); connect(m_wrk, &QWrk::signalWRKTrackName, this, &GUIPlayer::wrkUpdateLoadProgress); connect(m_wrk, &QWrk::signalWRKTrackVol, this, &GUIPlayer::wrkTrackVol); connect(m_wrk, &QWrk::signalWRKTrackBank, this, &GUIPlayer::wrkTrackBank); connect(m_wrk, &QWrk::signalWRKSegment, this, &GUIPlayer::wrkUpdateLoadProgress); connect(m_wrk, &QWrk::signalWRKChord, this, &GUIPlayer::wrkUpdateLoadProgress); connect(m_wrk, &QWrk::signalWRKExpression, this, &GUIPlayer::wrkUpdateLoadProgress); m_player = new Player(m_Client, m_portId); connect(m_player, &Player::playbackStopped, this, &GUIPlayer::playerStopped, Qt::QueuedConnection); m_Client->setRealTimeInput(false); m_Client->startSequencerInput(); tempoReset(); volumeReset(); updateState(EmptyState); readSettings(); } GUIPlayer::~GUIPlayer() { m_Client->stopSequencerInput(); m_Port->unsubscribeAll(); m_Port->detach(); m_Client->close(); delete m_player; delete m_ui; delete m_song; } void GUIPlayer::subscribe(const QString& portName) { try { if (!m_subscription.isEmpty()) { m_Port->unsubscribeTo(m_subscription); } m_subscription = portName; m_Port->subscribeTo(m_subscription); } catch (const SequencerError& err) { qWarning() << "SequencerError exception. Error code: " << err.code() << " (" << err.qstrError() << ")"; qWarning() << "Location: " << err.location(); } } void GUIPlayer::updateTimeLabel(int mins, int secs, int cnts) { static QChar fill('0'); QString stime = QString("%1:%2.%3").arg(mins,2,10,fill) .arg(secs,2,10,fill) .arg(cnts,2,10,fill); m_ui->lblTime->setText(stime); } void GUIPlayer::updateState(PlayerState newState) { if (m_state == newState) return; switch (newState) { case EmptyState: m_ui->actionPlay->setEnabled(false); m_ui->actionPause->setEnabled(false); m_ui->actionStop->setEnabled(false); statusBar()->showMessage("Please, load a song"); break; case PlayingState: m_ui->actionPlay->setEnabled(false); m_ui->actionPause->setEnabled(true); m_ui->actionStop->setEnabled(true); statusBar()->showMessage("Playing"); break; case PausedState: m_ui->actionPlay->setEnabled(false); m_ui->actionStop->setEnabled(true); statusBar()->showMessage("Paused"); break; case StoppedState: m_ui->actionPause->setChecked(false); m_ui->actionPause->setEnabled(false); m_ui->actionStop->setEnabled(false); m_ui->actionPlay->setEnabled(true); statusBar()->showMessage("Stopped"); break; default: statusBar()->showMessage("Not initialized"); break; } m_state = newState; } void GUIPlayer::play() { if (!m_song->isEmpty()) { if (m_player->getInitialPosition() == 0) { if (m_initialTempo == 0) return; QueueTempo firstTempo = m_Queue->getTempo(); firstTempo.setPPQ(m_song->getDivision()); firstTempo.setTempo(m_initialTempo); firstTempo.setTempoFactor(m_tempoFactor); m_Queue->setTempo(firstTempo); m_Client->drainOutput(); m_player->sendVolumeEvents(); } m_player->start(); updateState(PlayingState); } } void GUIPlayer::pause() { if (m_state == PlayingState || m_player->isRunning()) { m_player->stop(); m_player->setPosition(m_Queue->getStatus().getTickTime()); updateState(PausedState); } else if (!m_song->isEmpty()) { m_player->start(); updateState(PlayingState); } } void GUIPlayer::stop() { if (m_state == PlayingState || m_state == PausedState || m_player->isRunning()) { m_Queue->stop(); m_Queue->clear(); m_player->stop(); } if (m_initialTempo != 0) songFinished(); else updateState(StoppedState); } void GUIPlayer::progressDialogInit(const QString& type, int max) { m_pd = new QProgressDialog("", "", 0, max, this); m_pd->setWindowTitle(QString("Loading %1 file...").arg(type)); m_pd->setMinimumDuration(1000); m_pd->setValue(0); } void GUIPlayer::progressDialogUpdate(int pos) { if (m_pd != nullptr) { m_pd->setValue(pos); qApp->processEvents(); } } void GUIPlayer::progressDialogClose() { delete m_pd; // set to 0 by QPointer<> } void GUIPlayer::openFile(const QString& fileName) { QFileInfo finfo(fileName); if (finfo.exists()) { m_song->clear(); m_loadingMessages.clear(); m_tick = 0; m_initialTempo = 0; m_currentTrack = 0; try { QString ext = finfo.suffix().toLower(); if (ext == "wrk") { progressDialogInit("Cakewalk", finfo.size()); m_wrk->readFromFile(fileName); } else if (ext == "mid" || ext == "midi" || ext == "kar") { progressDialogInit("MIDI", finfo.size()); m_smf->readFromFile(fileName); } else if (ext == "rmi") { progressDialogInit("RIFF MIDI", finfo.size()); m_rmi->readFromFile(fileName); } progressDialogUpdate(finfo.size()); if (m_song->isEmpty()) { m_ui->lblName->clear(); } else { m_song->sort(); m_player->setSong(m_song); m_ui->lblName->setText(finfo.fileName()); m_lastDirectory = finfo.absolutePath(); } } catch (...) { m_song->clear(); m_ui->lblName->clear(); } progressDialogClose(); if (m_initialTempo == 0) { m_initialTempo = 500000; } updateTimeLabel(0,0,0); updateTempoLabel(6.0e7f / m_initialTempo); m_ui->progressBar->setValue(0); if (!m_loadingMessages.isEmpty()) { m_loadingMessages.insert(0, "Warning, this file may be non-standard or damaged.
"); QMessageBox::warning(this, QSTR_APPNAME, m_loadingMessages); } if (m_song->isEmpty()) updateState(EmptyState); else updateState(StoppedState); } } void GUIPlayer::open() { QString fileName = QFileDialog::getOpenFileName(this, "Open MIDI File", m_lastDirectory, "All files (*.kar *.mid *.midi *rmi *.wrk);;" "Karaoke files (*.kar);;" "MIDI Files (*.mid *.midi);;" "RIFF MIDI Files (*.rmi);;" "Cakewalk files (*.wrk)" ); if (! fileName.isEmpty() ) { stop(); openFile(fileName); } } void GUIPlayer::setup() { bool ok; int current; QStringList items; QListIterator it(m_Client->getAvailableOutputs()); while(it.hasNext()) { PortInfo p = it.next(); items << QString("%1:%2").arg(p.getClientName()).arg(p.getPort()); } current = items.indexOf(m_subscription); QString item = QInputDialog::getItem(this, "Player subscription", "Output port:", items, current, false, &ok); if (ok && !item.isEmpty()) subscribe(item); } void GUIPlayer::songFinished() { m_player->resetPosition(); updateState(StoppedState); } void GUIPlayer::playerStopped() { int portId = m_Port->getPortId(); for (int channel = 0; channel < 16; ++channel) { ControllerEvent ev1(channel, MIDI_CTL_ALL_NOTES_OFF, 0); ev1.setSource(portId); ev1.setSubscribers(); ev1.setDirect(); m_Client->outputDirect(&ev1); ControllerEvent ev2(channel, MIDI_CTL_ALL_SOUNDS_OFF, 0); ev2.setSource(portId); ev2.setSubscribers(); ev2.setDirect(); m_Client->outputDirect(&ev2); } m_Client->drainOutput(); } void GUIPlayer::updateTempoLabel(float ftempo) { QString stempo = QString("%1 bpm").arg(ftempo, 0, 'f', 2); m_ui->lblOther->setText(stempo); } void GUIPlayer::sequencerEvent(SequencerEvent *ev) { if ((ev->getSequencerType() == SND_SEQ_EVENT_ECHO) && (m_tick != 0)){ auto t = ev->getTick(); int pos = 100 * t / m_tick; const snd_seq_real_time_t* rt = m_Queue->getStatus().getRealtime(); int mins = rt->tv_sec / 60; int secs = rt->tv_sec % 60; int cnts = qFloor( rt->tv_nsec / 1.0e7 ); updateTempoLabel(m_Queue->getTempo().getRealBPM()); updateTimeLabel(mins, secs, cnts); m_ui->progressBar->setValue(pos); if (t >= m_tick) { songFinished(); } } delete ev; } void GUIPlayer::dataHandler(const QString &dataType, const QByteArray &data) { if (dataType == "RMID") { QDataStream ds(data); m_smf->readFromStream(&ds); } } void GUIPlayer::pitchShift(int value) { m_player->setPitchShift(value); } void GUIPlayer::tempoReset() { m_ui->sliderTempo->setValue(100); tempoSlider(100); } void GUIPlayer::volumeReset() { m_ui->volumeSlider->setValue(100); volumeSlider(100); } void GUIPlayer::tempoSlider(int value) { m_tempoFactor = (value*value + 100.0*value + 20000.0) / 40000.0; QueueTempo qtempo = m_Queue->getTempo(); qtempo.setTempoFactor(m_tempoFactor); m_Queue->setTempo(qtempo); m_Client->drainOutput(); if (!m_player->isRunning()) updateTempoLabel(qtempo.getRealBPM()); // Slider tooltip QString tip = QString("%1 %").arg(m_tempoFactor*100.0, 0, 'f', 0); m_ui->sliderTempo->setToolTip(tip); QToolTip::showText(QCursor::pos(), tip, this); } void GUIPlayer::volumeSlider(int value) { QString tip = QString::number(value)+'%'; m_ui->lblVolume->setText(tip); m_ui->volumeSlider->setToolTip(tip); m_player->setVolumeFactor(value); QToolTip::showText(QCursor::pos(), tip, this); } void GUIPlayer::dragEnterEvent( QDragEnterEvent * event ) { if (event->mimeData()->hasUrls()) { event->acceptProposedAction(); } } void GUIPlayer::dropEvent( QDropEvent * event ) { if ( event->mimeData()->hasUrls() ) { QList urls = event->mimeData()->urls(); if (!urls.empty()) { QString fileName = urls.first().toLocalFile(); if ( fileName.endsWith(".mid", Qt::CaseInsensitive) || fileName.endsWith(".midi", Qt::CaseInsensitive) || fileName.endsWith(".kar", Qt::CaseInsensitive) || fileName.endsWith(".rmi", Qt::CaseInsensitive) || fileName.endsWith(".wrk", Qt::CaseInsensitive) ) { stop(); event->accept(); openFile(fileName); } else { QMessageBox::warning(this, QSTR_APPNAME, QString("Dropped file %1 is not supported").arg(fileName)); } } } } void GUIPlayer::readSettings() { QSettings settings; settings.beginGroup("Window"); restoreGeometry(settings.value("Geometry").toByteArray()); restoreState(settings.value("State").toByteArray()); settings.endGroup(); settings.beginGroup("Preferences"); m_lastDirectory = settings.value("LastDirectory").toString(); QString midiConn = settings.value("MIDIConnection").toString(); settings.endGroup(); if (midiConn.length() > 0) subscribe(midiConn); } void GUIPlayer::writeSettings() { QSettings settings; settings.beginGroup("Window"); settings.setValue("Geometry", saveGeometry()); settings.setValue("State", saveState()); settings.endGroup(); settings.beginGroup("Preferences"); settings.setValue("LastDirectory", m_lastDirectory); settings.setValue("MIDIConnection", m_subscription); settings.endGroup(); } void GUIPlayer::closeEvent( QCloseEvent *event ) { stop(); m_player->wait(); writeSettings(); event->accept(); } void GUIPlayer::about() { About aboutDlg(this); aboutDlg.exec(); } /* **************************************** * * SMF (Standard MIDI file) format handling * **************************************** */ void GUIPlayer::smfUpdateLoadProgress() { progressDialogUpdate(m_smf->getFilePos()); } void GUIPlayer::appendSMFEvent(SequencerEvent* ev) { unsigned long tick = m_smf->getCurrentTime(); ev->setSource(m_portId); if (ev->getSequencerType() != SND_SEQ_EVENT_TEMPO) { ev->setSubscribers(); } ev->scheduleTick(m_queueId, tick, false); m_song->append(ev); if (tick > m_tick) m_tick = tick; smfUpdateLoadProgress(); } void GUIPlayer::smfHeaderEvent(int format, int ntrks, int division) { m_song->setHeader(format, ntrks, division); smfUpdateLoadProgress(); } void GUIPlayer::smfNoteOnEvent(int chan, int pitch, int vol) { SequencerEvent* ev = new NoteOnEvent (chan, pitch, vol); appendSMFEvent(ev); } void GUIPlayer::smfNoteOffEvent(int chan, int pitch, int vol) { SequencerEvent* ev = new NoteOffEvent (chan, pitch, vol); appendSMFEvent(ev); } void GUIPlayer::smfKeyPressEvent(int chan, int pitch, int press) { SequencerEvent* ev = new KeyPressEvent (chan, pitch, press); appendSMFEvent(ev); } void GUIPlayer::smfCtlChangeEvent(int chan, int ctl, int value) { SequencerEvent* ev = new ControllerEvent (chan, ctl, value); appendSMFEvent(ev); } void GUIPlayer::smfPitchBendEvent(int chan, int value) { SequencerEvent* ev = new PitchBendEvent (chan, value); appendSMFEvent(ev); } void GUIPlayer::smfProgramEvent(int chan, int patch) { SequencerEvent* ev = new ProgramChangeEvent (chan, patch); appendSMFEvent(ev); } void GUIPlayer::smfChanPressEvent(int chan, int press) { SequencerEvent* ev = new ChanPressEvent (chan, press); appendSMFEvent(ev); } void GUIPlayer::smfSysexEvent(const QByteArray& data) { SequencerEvent* ev = new SysExEvent (data); appendSMFEvent(ev); } void GUIPlayer::smfTempoEvent(int tempo) { if ( m_initialTempo == 0 ) { m_initialTempo = tempo; } SequencerEvent* ev = new TempoEvent (m_queueId, tempo); appendSMFEvent(ev); } void GUIPlayer::smfErrorHandler(const QString& errorStr) { if (m_loadingMessages.length() < 1024) m_loadingMessages.append(QString("%1 at file offset %2
") .arg(errorStr).arg(m_smf->getFilePos())); } void GUIPlayer::smfTrackStarted() { m_currentTrack++; } void GUIPlayer::smfTrackEnded() { if (m_currentTrack == m_smf->getTracks()) { SequencerEvent* ev = new SystemEvent(SND_SEQ_EVENT_ECHO); appendSMFEvent(ev); } } /* ********************************* * * Cakewalk WRK file format handling * ********************************* */ void GUIPlayer::wrkUpdateLoadProgress() { if (m_pd != nullptr) { progressDialogUpdate(m_wrk->getFilePos()); } } void GUIPlayer::appendWRKEvent(unsigned long ticks, SequencerEvent* ev) { ev->setSource(m_portId); if (ev->getSequencerType() != SND_SEQ_EVENT_TEMPO) { ev->setSubscribers(); } ev->scheduleTick(m_queueId, ticks, false); m_song->append(ev); if (ticks > m_tick) m_tick = ticks; wrkUpdateLoadProgress(); } void GUIPlayer::wrkErrorHandler(const QString& errorStr) { if (m_loadingMessages.length() < 1024) { m_loadingMessages.append(QString("%1 at file offset %2
") .arg(errorStr).arg(m_wrk->getFilePos())); } } void GUIPlayer::wrkFileHeader(int /*verh*/, int /*verl*/) { m_song->setHeader(1, 0, 120); wrkUpdateLoadProgress(); // qDebug() << Q_FUNC_INFO; } void GUIPlayer::wrkTimeBase(int timebase) { m_song->setDivision(timebase); wrkUpdateLoadProgress(); // qDebug() << Q_FUNC_INFO << timebase; } void GUIPlayer::wrkStreamEndEvent(long time) { unsigned long ticks = time; if (ticks > m_tick) m_tick = ticks; wrkUpdateLoadProgress(); // qDebug() << Q_FUNC_INFO << time; } void GUIPlayer::wrkTrackHeader( const QString& /*name1*/, const QString& /*name2*/, int trackno, int channel, int pitch, int velocity, int /*port*/, bool /*selected*/, bool /*muted*/, bool /*loop*/ ) { TrackMapRec rec; rec.channel = channel; rec.pitch = pitch; rec.velocity = velocity; m_trackMap[trackno] = rec; wrkUpdateLoadProgress(); // qDebug() << Q_FUNC_INFO << trackno << channel << pitch << velocity; } void GUIPlayer::wrkNoteEvent(int track, long time, int chan, int pitch, int vol, int dur) { TrackMapRec rec = m_trackMap[track]; int channel = (rec.channel > -1) ? rec.channel : chan; int key = qBound(0, pitch + rec.pitch, 127); int velocity = qBound(0, vol + rec.velocity, 127); SequencerEvent* ev = new NoteEvent(channel, key, velocity, dur); appendWRKEvent(time, ev); // qDebug() << Q_FUNC_INFO << channel << key << velocity << dur; } void GUIPlayer::wrkKeyPressEvent(int track, long time, int chan, int pitch, int press) { TrackMapRec rec = m_trackMap[track]; int key = pitch + rec.pitch; int channel = (rec.channel > -1) ? rec.channel : chan; SequencerEvent* ev = new KeyPressEvent(channel, key, press); appendWRKEvent(time, ev); // qDebug() << Q_FUNC_INFO; } void GUIPlayer::wrkCtlChangeEvent(int track, long time, int chan, int ctl, int value) { TrackMapRec rec = m_trackMap[track]; int channel = (rec.channel > -1) ? rec.channel : chan; SequencerEvent* ev = new ControllerEvent(channel, ctl, value); appendWRKEvent(time, ev); // qDebug() << Q_FUNC_INFO; } void GUIPlayer::wrkPitchBendEvent(int track, long time, int chan, int value) { TrackMapRec rec = m_trackMap[track]; int channel = (rec.channel > -1) ? rec.channel : chan; SequencerEvent* ev = new PitchBendEvent(channel, value); appendWRKEvent(time, ev); // qDebug() << Q_FUNC_INFO; } void GUIPlayer::wrkProgramEvent(int track, long time, int chan, int patch) { TrackMapRec rec = m_trackMap[track]; int channel = (rec.channel > -1) ? rec.channel : chan; SequencerEvent* ev = new ProgramChangeEvent(channel, patch); appendWRKEvent(time, ev); // qDebug() << Q_FUNC_INFO; } void GUIPlayer::wrkChanPressEvent(int track, long time, int chan, int press) { TrackMapRec rec = m_trackMap[track]; int channel = (rec.channel > -1) ? rec.channel : chan; SequencerEvent* ev = new ChanPressEvent(channel, press); appendWRKEvent(time, ev); // qDebug() << Q_FUNC_INFO; } void GUIPlayer::wrkSysexEvent(int track, long time, int bank) { Q_UNUSED(track) qDebug() << Q_FUNC_INFO; if (m_savedSysexEvents.contains(bank)) { SysExEvent* ev = m_savedSysexEvents[bank].clone(); appendWRKEvent(time, ev); wrkUpdateLoadProgress(); } } void GUIPlayer::wrkSysexEventBank(int bank, const QString& /*name*/, bool autosend, int /*port*/, const QByteArray& data) { //qDebug() << Q_FUNC_INFO; SysExEvent* ev = new SysExEvent(data); if (autosend) { appendWRKEvent(0, ev); } else { m_savedSysexEvents[bank] = *ev; delete ev; } wrkUpdateLoadProgress(); } void GUIPlayer::wrkTempoEvent(long time, int tempo) { double bpm = tempo / 100.0; if ( m_initialTempo < 0 ) m_initialTempo = qRound( bpm ); SequencerEvent* ev = new TempoEvent(m_queueId, qRound ( 6e7 / bpm ) ); appendWRKEvent(time, ev); // qDebug() << Q_FUNC_INFO; } void GUIPlayer::wrkTrackPatch(int track, int patch) { TrackMapRec rec = m_trackMap[track]; int channel = (rec.channel > -1) ? rec.channel : 0; wrkProgramEvent(track, 0, channel, patch); // qDebug() << Q_FUNC_INFO; } void GUIPlayer::wrkNewTrackHeader( const QString& /*name*/, int trackno, int channel, int pitch, int velocity, int /*port*/, bool /*selected*/, bool /*muted*/, bool /*loop*/ ) { TrackMapRec rec; rec.channel = channel; rec.pitch = pitch; rec.velocity = velocity; m_trackMap[trackno] = rec; wrkUpdateLoadProgress(); // qDebug() << Q_FUNC_INFO << trackno << channel << pitch << velocity; } void GUIPlayer::wrkTrackVol(int track, int vol) { int lsb, msb; TrackMapRec rec = m_trackMap[track]; int channel = (rec.channel > -1) ? rec.channel : 0; if (vol < 128) wrkCtlChangeEvent(track, 0, channel, MIDI_CTL_MSB_MAIN_VOLUME, vol); else { lsb = vol % 0x80; msb = vol / 0x80; wrkCtlChangeEvent(track, 0, channel, MIDI_CTL_LSB_MAIN_VOLUME, lsb); wrkCtlChangeEvent(track, 0, channel, MIDI_CTL_MSB_MAIN_VOLUME, msb); } // qDebug() << Q_FUNC_INFO; } void GUIPlayer::wrkTrackBank(int track, int bank) { // assume GM/GS bank method int lsb, msb; TrackMapRec rec = m_trackMap[track]; int channel = (rec.channel > -1) ? rec.channel : 0; lsb = bank % 0x80; msb = bank / 0x80; wrkCtlChangeEvent(track, 0, channel, MIDI_CTL_MSB_BANK, msb); wrkCtlChangeEvent(track, 0, channel, MIDI_CTL_LSB_BANK, lsb); // qDebug() << Q_FUNC_INFO; } void GUIPlayer::wrkEndOfFile() { if (m_initialTempo < 0) m_initialTempo = 120; SequencerEvent* ev = new SystemEvent(SND_SEQ_EVENT_ECHO); appendWRKEvent(m_tick, ev); // qDebug() << Q_FUNC_INFO; } DISABLE_WARNING_POP drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/playerabout.ui0000644000000000000000000000013214200302440021307 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/playerabout.ui0000644000175000001440000001506214200302440022074 0ustar00pedrousers00000000000000 AboutClass 0 0 468 337 About :/drumstick.png:/drumstick.png false true <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick ALSA MIDI Player %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> true About Qt :/resources/qtlogo.png:/resources/qtlogo.png QDialogButtonBox::Close buttonBox rejected() AboutClass close() 306 315 325 335 drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/drumstick-guiplayer.desktop0000644000000000000000000000013214200302440024020 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/drumstick-guiplayer.desktop0000644000175000001440000000047714200302440024611 0ustar00pedrousers00000000000000[Desktop Entry] Name=Drumstick MIDI Player Exec=drumstick-guiplayer %f Icon=drumstick Terminal=false Type=Application Categories=AudioVideo;Audio;Midi;Education;Music; Keywords=Music;Midi;Player; MimeType=audio/midi;audio/x-midi;audio/cakewalk; Comment=Drumstick MIDI Player Comment[es]=Reproductor MIDI de Drumstick drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/playerabout.h0000644000000000000000000000013214200302440021121 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/guiplayer/playerabout.h0000644000175000001440000000200214200302440021674 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ABOUT_H #define ABOUT_H #include #include "ui_playerabout.h" class About : public QDialog { Q_OBJECT public: explicit About(QWidget *parent = nullptr); private: Ui::AboutClass ui; }; #endif // ABOUT_H drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/drumstick-guiplayer_en.ts0000644000000000000000000000013214200302440023457 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/guiplayer/drumstick-guiplayer_en.ts0000644000175000001440000004335314200302440024250 0ustar00pedrousers00000000000000 About Revision AboutClass About <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick ALSA MIDI Player %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick ALSA MIDI Player %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> About Qt GUIPlayerClass Drumstick ALSA MIDI Player Drumstick MIDI Player Playback time and current levels 00:00:00 Tempo: Volume: Pitch: Pitch Control Pitch transpose between -12 and +12 semitones Reset Volume Reset Volume to 100% Volume Slider Playback progress File Name: Currently loaded MIDI file name Tempo Slider Reset Tempo Reset Tempo to 100% tempo=100% File Help Settings Tool Bar Open Open a MIDI file Quit Quit the application Play Start playing the current MIDI file Pause Pause the playback Stop Stop the playback About Show the about box About Qt Show the about Qt dialog box MIDI Setup Select a connection for the MIDI output port Show Tool Bar Show or hide the tool bar Show Status Bar Show or hide the status bar drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/drumstick-guiplayer_cs.ts0000644000000000000000000000013214200302440023462 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/drumstick-guiplayer_cs.ts0000644000175000001440000004654514200302440024261 0ustar00pedrousers00000000000000 About Revision Verze AboutClass About O programu <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick ALSA MIDI Player %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick ALSA MIDI Player %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Using Qt version: %QT_VERSION%</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> About Qt O Qt GUIPlayerClass Drumstick ALSA MIDI Player Drumstick MIDI Player Přehrávač MIDI Palička Playback time and current levels Čas přehrávání a nynější úrovně 00:00:00 00:00:00 Tempo: Tempo: Volume: Hlasitost: Pitch: Výška tónu: Pitch Control Ovládání výšky tónu Pitch transpose between -12 and +12 semitones Transpozice výšky tónu mezi -12 a +12 půltóny Reset Volume Obnovit výchozí hlasitost Reset Volume to 100% Obnovit výchozí hlasitost na 100 % Volume Slider Posuvník hlasitosti Playback progress Postup přehrávání File Name: Název souboru: Currently loaded MIDI file name Nyní nahraný název souboru MIDI Tempo Slider Posuvník tempa Reset Tempo Obnovit výchozí tempo Reset Tempo to 100% Obnovit výchozí tempo na 100 % tempo=100% Tempo = 100 % File Soubor Help Nápověda Settings Nastavení Tool Bar Nástrojový pruh Open Otevřít Open a MIDI file Otevřít soubor MIDI Quit Ukončit Quit the application Ukončit program Play Přehrát Start playing the current MIDI file Spustit přehrávání nynějšího souboru MIDI Pause Pozastavit Pause the playback Pozastavit přehrávání Stop Zastavit Stop the playback Zastavit přehrávání About O programu Show the about box Ukázat okno O programu About Qt O Qt Show the about Qt dialog box Ukázat okno O Qt MIDI Setup Nastavení MIDI Select a connection for the MIDI output port Vybrat spojení pro výstupní přípojku MIDI Show Tool Bar Ukázat nástrojový pruh Show or hide the tool bar Ukázat nebo skrýt nástrojový pruh Show Status Bar Ukázat stavový řádek Show or hide the status bar Ukázat nebo skrýt stavový řádek main ALSA Sequencer based MIDI file player Fatal error from the ALSA sequencer. This usually happens when the kernel doesn't have ALSA support, or the device node (/dev/snd/seq) doesn't exists, or the kernel module (snd_seq) is not loaded. Please check your ALSA/MIDI configuration. MIDI Out Connection. Input SMF/KAR/RMI/WRK file name. File not found: Error Returned error was: drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/iconutils.cpp0000644000000000000000000000013214200302440021136 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/guiplayer/iconutils.cpp0000644000175000001440000000255714200302440021730 0ustar00pedrousers00000000000000/* SMF GUI Player test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "iconutils.h" #include #include namespace IconUtils { void PaintPixmap(QPixmap &pixmap, const QColor& color) { QPainter painter(&pixmap); painter.setCompositionMode(QPainter::CompositionMode_SourceIn); painter.fillRect(pixmap.rect(), color); } QPixmap GetPixmap(QWidget* widget, const QString& fileName) { QPixmap pixmap(fileName); QColor color = widget->palette().color(QPalette::Active, QPalette::WindowText); PaintPixmap(pixmap, color); return pixmap; } } // namespace IconUtils drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/iconutils.h0000644000000000000000000000013214200302440020603 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/iconutils.h0000644000175000001440000000207314200302440021366 0ustar00pedrousers00000000000000/* SMF GUI Player test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ICONUTILS_H #define ICONUTILS_H #include #include #include #include namespace IconUtils { void PaintPixmap(QPixmap &pixmap, const QColor& color); QPixmap GetPixmap(QWidget* widget, const QString& fileName); } #endif // ICONUTILS_H drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/player.cpp0000644000000000000000000000013214200302440020421 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.441324575 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/guiplayer/player.cpp0000644000175000001440000001160714200302440021207 0ustar00pedrousers00000000000000/* SMF GUI Player test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "player.h" #include "song.h" #include #include #include using namespace drumstick::ALSA; Player::Player(MidiClient *seq, int portId) : SequencerOutputThread(seq, portId), m_song(nullptr), m_songIterator(nullptr), m_lastEvent(nullptr), m_songPosition(0), m_echoResolution(0), m_pitchShift(0), m_volumeFactor(100) { for (int chan = 0; chan < MIDI_CHANNELS; ++chan) m_volume[chan] = 100; } Player::~Player() { if (isRunning()) { stop(); } delete m_songIterator; delete m_lastEvent; } void Player::setSong(Song* s) { m_song = s; if (m_song != nullptr) { delete m_songIterator; m_songIterator = new SongIterator(*m_song); m_echoResolution = m_song->getDivision() / 12; m_songPosition = 0; } } void Player::resetPosition() { if ((m_song != nullptr) && (m_songIterator != nullptr)) { m_songIterator->toFront(); m_songPosition = 0; } } void Player::setPosition(unsigned int pos) { m_songPosition = pos; m_songIterator->toFront(); while (m_songIterator->hasNext() && (m_songIterator->next()->getTick() < pos)) { }; if (m_songIterator->hasPrevious()) m_songIterator->previous(); } bool Player::hasNext() { auto res = m_songIterator->hasNext(); return res; } SequencerEvent* Player::nextEvent() { delete m_lastEvent; m_lastEvent = m_songIterator->next()->clone(); switch (m_lastEvent->getSequencerType()) { case SND_SEQ_EVENT_NOTE: case SND_SEQ_EVENT_NOTEON: case SND_SEQ_EVENT_NOTEOFF: case SND_SEQ_EVENT_KEYPRESS: { KeyEvent* kev = static_cast(m_lastEvent); if (kev->getChannel() != MIDI_GM_DRUM_CHANNEL) kev->setKey(kev->getKey() + m_pitchShift); } break; case SND_SEQ_EVENT_CONTROLLER: { ControllerEvent *cev = static_cast(m_lastEvent); if (cev->getParam() == MIDI_CTL_MSB_MAIN_VOLUME) { int chan = cev->getChannel(); int value = cev->getValue(); m_volume[chan] = value; value = floor(value * m_volumeFactor / 100.0); if (value < 0) value = 0; if (value > 127) value = 127; cev->setValue(value); } } break; } return m_lastEvent; } unsigned int Player::getInitialPosition() { return m_songPosition; } unsigned int Player::getEchoResolution() { return m_echoResolution; } unsigned int Player::getPitchShift() { return m_pitchShift; } unsigned int Player::getVolumeFactor() { return m_volumeFactor; } void Player::setPitchShift(unsigned int pitch) { bool playing = isRunning(); if (playing) { stop(); unsigned int pos = m_Queue->getStatus().getTickTime(); m_Queue->clear(); allNotesOff(); setPosition(pos); } m_pitchShift = pitch; if (playing) start(); } void Player::setVolumeFactor(unsigned int vol) { m_volumeFactor = vol; for(int chan = 0; chan < MIDI_CHANNELS; ++chan) { int value = m_volume[chan]; value = floor(value * m_volumeFactor / 100.0); if (value < 0) value = 0; if (value > 127) value = 127; sendController(chan, MIDI_CTL_MSB_MAIN_VOLUME, value); } } void Player::sendController(int chan, int control, int value) { ControllerEvent ev(chan, control, value); ev.setSource(m_PortId); ev.setSubscribers(); ev.setDirect(); sendSongEvent(&ev); } void Player::allNotesOff() { for(int chan = 0; chan < MIDI_CHANNELS; ++chan) { sendController(chan, MIDI_CTL_ALL_NOTES_OFF, 0); sendController(chan, MIDI_CTL_ALL_SOUNDS_OFF, 0); } } void Player::sendVolumeEvents() { for(int chan = 0; chan < MIDI_CHANNELS; ++chan) { int value = m_volume[chan] = 100; value = floor(value * m_volumeFactor / 100.0); if (value < 0) value = 0; if (value > 127) value = 127; sendController(chan, MIDI_CTL_MSB_MAIN_VOLUME, value); } } drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/playerabout.cpp0000644000000000000000000000013214200302440021454 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/playerabout.cpp0000644000175000001440000000252314200302440022237 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "playerabout.h" About::About(QWidget *parent) : QDialog(parent) { ui.setupUi(this); QString aboutText = ui.AboutTextView->toHtml(); QString strver(QT_STRINGIFY(VERSION)); #ifdef REVISION strver.append("
"); strver.append(tr("Revision")); strver.append(" "); strver.append(QT_STRINGIFY(REVISION)); #endif aboutText.replace("%VERSION%", strver); aboutText.replace("%QT_VERSION%", qVersion()); ui.AboutTextView->setHtml(aboutText); connect(ui.aboutQt, &QPushButton::clicked, qApp, QApplication::aboutQt); } drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/resources0000644000000000000000000000013214200302440020356 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.441324575 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/resources/0000755000175000001440000000000014200302440021214 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/guiplayer/resources/PaxHeaders.27918/qtlogo.png0000644000000000000000000000013214200302440022446 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.445324578 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/resources/qtlogo.png0000644000175000001440000000126114200302440023227 0ustar00pedrousers00000000000000PNG  IHDRabKGD pHYs@tIME %$#+>IDAT8}MHTaO3wqь! +haVAP-2lѢE?rYZHRJ!J_* ͟bi̽Zӌ/p2]GEN0)G!3#'҆26ȑX7SHJ,KT0" Jگ/ ;Waϑ;@*{IC" FOkd3q>ڛp.[:Mu12qǥϻ qxsG8;.q[6OKq0b1SySGPMRzS- @U[|wlͽeĎ&?``wh[Z[l 4(p> ðbG1*XNF>\į&„ٗ 4B a^T $!0#;^\H8UއyŽBt8Rm ^Z&u!m lAyh44'_j5XVbs -ùT3*!wzR_Nn,7 vvrpf dۏ^|mZp6cqSL`"PDJŹ_w[oߧB㑍|1E= 6޼y\r{Hatddd6slc.e T 4]5~bf=t`xLIENDB`drumstick-2.5.1/utils/guiplayer/resources/PaxHeaders.27918/stop.png0000644000000000000000000000013214200302440022126 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.445324578 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/resources/stop.png0000644000175000001440000000024214200302440022705 0ustar00pedrousers00000000000000PNG  IHDRabKGD pHYs  #utIME mz/IDAT8c?%B0 022 305q4/0 IENDB`drumstick-2.5.1/utils/guiplayer/resources/PaxHeaders.27918/drumstick.png0000644000000000000000000000013214200302440023146 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.445324578 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/resources/drumstick.png0000644000175000001440000000103614200302440023727 0ustar00pedrousers00000000000000PNG  IHDRasBIT|d pHYsNtEXtSoftwarewww.inkscape.org<IDAT8Kﳭ{׻" H/bD!(b)LA֭i%:B)"QT(ba(fcctק"?DU$  "rǝuΝ>bqJ|MQUD|b 4,쨅mY彅 lRgwQZެVZ ˛t9>$#@:뗸8pNPcG#Hm#esG':AY#S]+nyKEWnTӞhR7VJ d2[᚜h G3'pA\>MWȆ ;ܕ?("zIQ-֙a3\&QoASZD$D+ȑ( x+~,TRHIENDB`drumstick-2.5.1/utils/guiplayer/resources/PaxHeaders.27918/play.png0000644000000000000000000000013214200302440022106 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.445324578 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/resources/play.png0000644000175000001440000000023714200302440022671 0ustar00pedrousers00000000000000PNG  IHDRagAMA a pHYs  ~AIDATxc`? (5DBc^C5!@ )1fb jNųIENDB`drumstick-2.5.1/utils/guiplayer/resources/PaxHeaders.27918/quit.png0000644000000000000000000000013214200302440022123 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.445324578 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/resources/quit.png0000644000175000001440000000032414200302440022703 0ustar00pedrousers00000000000000PNG  IHDRaIDATxڭ !FM7NTgq`\IH?boVڳ(tW ^re c4S,!jv* y;] d'yk-@7 &;h$X$l5P/%(Z&t>F¡IENDB`drumstick-2.5.1/utils/guiplayer/resources/PaxHeaders.27918/open.png0000644000000000000000000000013214200302440022102 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.445324578 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/resources/open.png0000644000175000001440000000040514200302440022662 0ustar00pedrousers00000000000000PNG  IHDRaIDATxڥS 0 sNlB l#AM:H!GR|e *}TՙfZavc4H)yK̢59#"rUO{ђv3;avM"O,0B"ԃeCm.1맃;|]хGl/C6`yEuEqpx# PL1GO*"ve+z_5:ǍIENDB`drumstick-2.5.1/utils/guiplayer/resources/PaxHeaders.27918/vol.png0000644000000000000000000000013214200302440021741 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.445324578 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/resources/vol.png0000644000175000001440000000142214200302440022521 0ustar00pedrousers00000000000000PNG  IHDRagAMA abKGD pHYs )ItIME 7Q}KIDATx}MHq3qsu 6PK`us3-n!," 7QF QE_Zm2;ҚTWW9pBhcwD&{ ?[<| * Ƴk϶>/@/<ՂP`!s*ȟ3wӶ'VZK8ض̠]2uYZKz7 ǏTfhhh@3f!Mf_4@dӞĪ'oz.=e|OYYRJ(X Mӈ$4ҪSGwdv_] ukb&ibYըJ$/ϣq?8V )xTA@׉c㠪*m:a-#)4@^nQPTf@A @UU|>IΎP )9F1MEQH&\Rs>p hYRRipoޡ>F:l'٪޻ZjrsH޹atxEq1ҔW*9xs34MCu222p32<'§n This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef INCLUDED_PLAYER_H #define INCLUDED_PLAYER_H #include #include "song.h" class Player : public drumstick::ALSA::SequencerOutputThread { Q_OBJECT public: Player(drumstick::ALSA::MidiClient *seq, int portId); virtual ~Player(); virtual bool hasNext() override; virtual drumstick::ALSA::SequencerEvent* nextEvent() override; virtual unsigned int getInitialPosition() override; virtual unsigned int getEchoResolution() override; unsigned int getPitchShift(); unsigned int getVolumeFactor(); void setSong(Song* s); void resetPosition(); void setPosition(unsigned int pos); void setPitchShift(unsigned int pitch); void setVolumeFactor(unsigned int vol); void sendController(int chan, int control, int value); void allNotesOff(); void sendVolumeEvents(); private: Song* m_song; SongIterator* m_songIterator; drumstick::ALSA::SequencerEvent* m_lastEvent; unsigned int m_songPosition; unsigned int m_echoResolution; unsigned int m_pitchShift; unsigned int m_volumeFactor; int m_volume[MIDI_CHANNELS]; }; #endif /*INCLUDED_PLAYER_H*/ drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/guiplayer.ui0000644000000000000000000000013214200302440020761 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.445324578 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/guiplayer.ui0000644000175000001440000004631614200302440021554 0ustar00pedrousers00000000000000 GUIPlayerClass 0 0 438 302 Drumstick ALSA MIDI Player :/drumstick.png:/drumstick.png true Drumstick MIDI Player 0 0 255 255 255 255 255 255 0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 0 0 0 146 145 144 165 164 164 0 0 0 0 0 0 Playback time and current levels true QFrame::NoFrame QFrame::Plain 4 0 0 210 62 210 62 34 00:00:00 Tempo: 0 0 100 0 Volume: Pitch: 50 16777215 Pitch Control Pitch transpose between -12 and +12 semitones -12 12 Reset Volume Reset Volume to 100% :/resources/vol.png:/resources/vol.png 0 0 Volume Slider 200 100 false Qt::Vertical QSlider::TicksAbove 0 0 Playback progress 0 Qt::AlignCenter true QProgressBar::TopToBottom QFormLayout::ExpandingFieldsGrow File Name: 0 0 Currently loaded MIDI file name true Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse 0 0 Tempo Slider 0 200 1 10 100 Qt::Horizontal QSlider::TicksAbove 5 0 0 Reset Tempo Reset Tempo to 100% tempo=100% 0 0 438 23 File Help Settings Tool Bar Qt::ToolButtonTextUnderIcon BottomToolBarArea false :/resources/open.png:/resources/open.png Open Open a MIDI file :/resources/quit.png:/resources/quit.png Quit Quit the application :/resources/play.png:/resources/play.png Play Start playing the current MIDI file false true true :/resources/pause.png:/resources/pause.png Pause Pause the playback false :/resources/stop.png:/resources/stop.png Stop Stop the playback false :/resources/about.png:/resources/about.png About Show the about box :/resources/qtlogo.png:/resources/qtlogo.png About Qt Show the about Qt dialog box :/resources/setup.png:/resources/setup.png MIDI Setup Select a connection for the MIDI output port true true Show Tool Bar Show Tool Bar Show or hide the tool bar true true Show Status Bar Show or hide the status bar spinPitch sliderTempo btnTempo volumeSlider actionShowStatusbar toggled(bool) myStatusBar setVisible(bool) -1 -1 216 296 actionShowToolbar toggled(bool) toolBar setVisible(bool) -1 -1 216 51 drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/drumstick-guiplayer.metainfo.xml0000644000000000000000000000013214200302440024750 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.445324578 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/drumstick-guiplayer.metainfo.xml0000644000175000001440000000175414200302440025540 0ustar00pedrousers00000000000000 net.sourceforge.drumstick-guiplayer drumstick-guiplayer Simple MIDI file player based on ALSA Sequencer FSFAP GPL-3.0+

Simple MIDI file player for .MID (Standard MIDI Files), .RMI (RIFF RMID) and .WRK (Cakewalk) files based on the ALSA Sequencer.

This program is an example of the Drumstick libraries. For a fully featured MIDI file player see: dmidiplayer.sourceforge.io

net.sourceforge.drumstick-guiplayer.desktop https://drumstick.sourceforge.io/images/drumstick-guiplayer.png
drumstick-2.5.1/utils/guiplayer/PaxHeaders.27918/guiplayer.qrc0000644000000000000000000000013214200302440021131 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.445324578 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/guiplayer/guiplayer.qrc0000644000175000001440000000070214200302440021711 0ustar00pedrousers00000000000000 ../../icons/drumstick_32.png resources/qtlogo.png resources/about.png resources/open.png resources/pause.png resources/play.png resources/quit.png resources/setup.png resources/stop.png resources/vol.png drumstick-2.5.1/utils/PaxHeaders.27918/vpiano0000644000000000000000000000013214200302440015637 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/0000755000175000001440000000000014200302440016475 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020454 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/CMakeLists.txt0000644000175000001440000001333114200302440021236 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(CMAKE_INCLUDE_CURRENT_DIR TRUE) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Gui Widgets LinguistTools REQUIRED) set(EXTRA_LIBS) if(APPLE) find_library(CORELIBS CoreFoundation) set(EXTRA_LIBS ${CORELIBS}) endif() set(vpiano_SRCS connections.cpp connections.h connections.ui preferences.cpp preferences.h preferences.ui vpiano.cpp vpiano.h vpiano.ui vpiano.qrc vpianoabout.cpp vpianoabout.h vpianoabout.ui vpianomain.cpp vpianosettings.cpp vpianosettings.h ) if (WIN32) set(TARGET_DESCRIPTION "Drumstick Virtual Piano") set(TARGET_NAME drumstick-vpiano) set(TARGET_ORIGINAL_FILENAME drumstick-vpiano.exe) configure_file(${Drumstick_SOURCE_DIR}/versioninfo.rc.in versioninfo.rc @ONLY) list(APPEND vpiano_SRCS versioninfo.rc) endif() if (APPLE) set(ICON_FILE "${PROJECT_SOURCE_DIR}/icons/drumstick.icns") list(APPEND vpiano_SRCS ${ICON_FILE}) set_source_files_properties (${ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) endif() add_executable(drumstick-vpiano ${vpiano_SRCS} ) target_link_libraries(drumstick-vpiano PRIVATE Drumstick::RT Drumstick::Widgets Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Widgets ${EXTRA_LIBS} ) if (WIN32) set_target_properties( drumstick-vpiano PROPERTIES WIN32_EXECUTABLE TRUE ) endif() if (APPLE) set_target_properties(drumstick-vpiano PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_INFO_STRING "Drumstick Virtual Piano" MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_LONG_VERSION_STRING ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION} MACOSX_BUNDLE_ICON_FILE "drumstick.icns" MACOSX_BUNDLE_GUI_IDENTIFIER "net.sourceforge.drumstick-vpiano" MACOSX_BUNDLE_BUNDLE_NAME "drumstick-vpiano" MACOSX_BUNDLE_COPYRIGHT "© 2008-2021 Pedro López-Cabanillas" MACOSX_BUNDLE_INFO_PLIST "${PROJECT_SOURCE_DIR}/cmake_admin/CustomBundleInfo.plist.in" ) endif() set(TS_FILES drumstick-vpiano_en.ts drumstick-vpiano_es.ts ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_add_translation(QM_FILES ${TS_FILES}) else() qt_add_translation(QM_FILES ${TS_FILES}) endif() add_custom_command(TARGET drumstick-vpiano POST_BUILD COMMAND Qt${QT_VERSION_MAJOR}::lupdate ${CMAKE_CURRENT_SOURCE_DIR} -ts ${TS_FILES} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Updating translations" ) add_custom_target(drumstick-vpiano-translations ALL DEPENDS ${QM_FILES}) if (UNIX) install( FILES ${QM_FILES} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/drumstick ) endif () if(STATIC_DRUMSTICK) if (FALSE) target_compile_definitions(drumstick-vpiano PUBLIC DUMMY_BACKEND) target_link_libraries(drumstick-vpiano PRIVATE drumstick-rt-dummy-in drumstick-rt-dummy-out) endif() if(ALSA_FOUND) target_compile_definitions(drumstick-vpiano PUBLIC LINUX_BACKEND) target_link_libraries(drumstick-vpiano PRIVATE drumstick-rt-alsa-in drumstick-rt-alsa-out drumstick-rt-eassynth) endif() if(UNIX AND NOT APPLE) target_compile_definitions(drumstick-vpiano PUBLIC OSS_BACKEND) target_link_libraries(drumstick-vpiano PRIVATE drumstick-rt-oss-in drumstick-rt-oss-out) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") target_compile_definitions(drumstick-vpiano PUBLIC MAC_BACKEND) target_link_libraries(drumstick-vpiano PRIVATE drumstick-rt-mac-in drumstick-rt-mac-out drumstick-rt-macsynth "-framework CoreMIDI -framework CoreFoundation") endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") target_compile_definitions(drumstick-vpiano PUBLIC WIN_BACKEND) target_link_libraries(drumstick-vpiano PRIVATE drumstick-rt-win-in drumstick-rt-win-out winmm) endif() find_package(Qt${QT_VERSION_MAJOR}Network) if(Qt${QT_VERSION_MAJOR}Network_FOUND) target_compile_definitions(drumstick-vpiano PUBLIC NET_BACKEND) target_link_libraries(drumstick-vpiano PRIVATE drumstick-rt-net-in drumstick-rt-net-out) endif() if(FLUIDSYNTH_FOUND) target_compile_definitions(drumstick-vpiano PUBLIC FLUIDSYNTH_BACKEND) target_link_libraries(drumstick-vpiano PRIVATE drumstick-rt-fluidsynth) endif() endif() install(TARGETS drumstick-vpiano RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} BUNDLE DESTINATION "Applications" ) install(FILES drumstick-vpiano.desktop DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" RENAME net.sourceforge.drumstick-vpiano.desktop) install(FILES drumstick-vpiano.metainfo.xml DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo" RENAME net.sourceforge.drumstick-vpiano.metainfo.xml) drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/connections.cpp0000644000000000000000000000013214200302440020742 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/connections.cpp0000644000175000001440000002127214200302440021527 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "vpianosettings.h" #include "connections.h" using namespace drumstick::rt; Connections::Connections(QWidget *parent) : QDialog(parent), m_settingsChanged(false), m_midiIn(nullptr), m_savedIn(nullptr), m_midiOut(nullptr), m_savedOut(nullptr) { ui.setupUi(this); ui.m_advanced->setChecked(VPianoSettings::instance()->advanced()); ui.m_thru->setChecked(VPianoSettings::instance()->midiThru()); connect(ui.m_advanced, &QCheckBox::clicked, this, &Connections::clickedAdvanced); connect(ui.m_inputBackends, QOverload::of(&QComboBox::currentIndexChanged), this, &Connections::refreshInputs); connect(ui.m_outputBackends, QOverload::of(&QComboBox::currentIndexChanged), this, &Connections::refreshOutputs); connect(ui.btnInputDriverCfg, &QToolButton::clicked, this, &Connections::configureInputDriver); connect(ui.btnOutputDriverCfg, &QToolButton::clicked, this, &Connections::configureOutputDriver); } void Connections::setInput(MIDIInput *in) { m_savedIn = m_midiIn = in; m_connIn = in->currentConnection(); } void Connections::setOutput(MIDIOutput *out) { m_savedOut = m_midiOut = out; m_connOut = out->currentConnection(); } void Connections::setInputs(QList ins) { ui.m_inputBackends->disconnect(); ui.m_inputBackends->clear(); foreach(MIDIInput *i, ins) { ui.m_inputBackends->addItem(i->backendName(), QVariant::fromValue(i)); } connect(ui.m_inputBackends, QOverload::of(&QComboBox::currentIndexChanged), this, &Connections::refreshInputs); } void Connections::setOutputs(QList outs) { ui.m_outputBackends->disconnect(); foreach(MIDIOutput *o, outs) { ui.m_outputBackends->addItem(o->backendName(), QVariant::fromValue(o)); } connect(ui.m_outputBackends, QOverload::of(&QComboBox::currentIndexChanged), this, &Connections::refreshOutputs); } MIDIInput *Connections::getInput() { return m_midiIn; } MIDIOutput *Connections::getOutput() { return m_midiOut; } void Connections::reopenDrivers() { drumstick::widgets::SettingsFactory settings; if (m_midiOut != nullptr) { if (m_connOut != m_midiOut->currentConnection() || m_settingsChanged) { m_midiOut->close(); if (!m_connOut.first.isEmpty()) { m_midiOut->initialize(settings.getQSettings()); m_midiOut->open(m_connOut); auto metaObj = m_midiOut->metaObject(); if ((metaObj->indexOfProperty("status") != -1) && (metaObj->indexOfProperty("diagnostics") != -1)) { auto status = m_midiOut->property("status"); if (status.isValid() && !status.toBool()) { auto diagnostics = m_midiOut->property("diagnostics"); if (diagnostics.isValid()) { auto text = diagnostics.toStringList().join(QChar::LineFeed).trimmed(); QMessageBox::warning(this, tr("MIDI Output"), text); } } } } } } if (m_midiIn != nullptr) { if (m_connIn != m_midiIn->currentConnection() || m_settingsChanged) { m_midiIn->close(); m_midiIn->initialize(settings.getQSettings()); if (!m_connIn.first.isEmpty()) { m_midiIn->open(m_connIn); auto metaObj = m_midiIn->metaObject(); if ((metaObj->indexOfProperty("status") != -1) && (metaObj->indexOfProperty("diagnostics") != -1)) { auto status = m_midiIn->property("status"); if (status.isValid() && !status.toBool()) { auto diagnostics = m_midiIn->property("diagnostics"); if (diagnostics.isValid()) { auto text = diagnostics.toStringList().join(QChar::LineFeed).trimmed(); QMessageBox::warning(this, tr("MIDI Input"), text); } } } } } if (m_midiOut != nullptr) { m_midiIn->setMIDIThruDevice(m_midiOut); m_midiIn->enableMIDIThru(VPianoSettings::instance()->midiThru()); } } m_settingsChanged = false; } void Connections::accept() { m_connIn = ui.m_inputPorts->currentData().value(); m_connOut = ui.m_outputPorts->currentData().value(); VPianoSettings::instance()->setAdvanced(ui.m_advanced->isChecked()); VPianoSettings::instance()->setMidiThru(ui.m_thru->isChecked()); reopenDrivers(); VPianoSettings::instance()->setLastOutputBackend(m_midiOut->backendName()); VPianoSettings::instance()->setLastOutputConnection(m_midiOut->currentConnection().first); VPianoSettings::instance()->setLastInputBackend(m_midiIn->backendName()); VPianoSettings::instance()->setLastInputConnection(m_midiIn->currentConnection().first); QDialog::accept(); } void Connections::reject() { m_midiIn = m_savedIn; m_midiOut = m_savedOut; reopenDrivers(); QDialog::reject(); } void Connections::refresh() { if (m_midiIn != nullptr) { ui.m_inputBackends->setCurrentText(m_midiIn->backendName()); refreshInputs(ui.m_inputBackends->currentIndex()); } if (m_midiOut != nullptr) { ui.m_outputBackends->setCurrentText(m_midiOut->backendName()); refreshOutputs(ui.m_outputBackends->currentIndex()); } } void Connections::refreshInputs(int index) { QString id = ui.m_inputBackends->itemText(index); ui.btnInputDriverCfg->setEnabled(drumstick::widgets::inputDriverIsConfigurable(id)); if (m_midiIn != nullptr && m_midiIn->backendName() != id) { m_midiIn->close(); m_midiIn = ui.m_inputBackends->itemData(index).value(); } ui.m_inputPorts->clear(); if (m_midiIn != nullptr) { const QList conns = m_midiIn->connections(ui.m_advanced->isChecked()); for (const MIDIConnection& conn : conns) { ui.m_inputPorts->addItem(conn.first, QVariant::fromValue(conn)); } QString strconn = m_midiIn->currentConnection().first; if (strconn.isEmpty() && !conns.isEmpty()) { strconn = conns.first().first; } ui.m_inputPorts->setCurrentText(strconn); } } void Connections::refreshOutputs(int index) { QString id = ui.m_outputBackends->itemText(index); ui.btnOutputDriverCfg->setEnabled(drumstick::widgets::outputDriverIsConfigurable(id)); if (m_midiOut != nullptr && m_midiOut->backendName() != id) { m_midiOut->close(); m_midiOut = ui.m_outputBackends->itemData(index).value(); } ui.m_outputPorts->clear(); if (m_midiOut != nullptr) { const QList conns = m_midiOut->connections(ui.m_advanced->isChecked()); for(const MIDIConnection& conn : conns) { ui.m_outputPorts->addItem(conn.first, QVariant::fromValue(conn)); } QString strconn = m_midiOut->currentConnection().first; if (strconn.isEmpty() && !conns.isEmpty()) { strconn = conns.first().first; } ui.m_outputPorts->setCurrentText(strconn); } } void Connections::clickedAdvanced(bool value) { Q_UNUSED(value) refresh(); } void Connections::configureInputDriver() { QString driver = ui.m_inputBackends->currentText(); if (drumstick::widgets::inputDriverIsConfigurable(driver)) { m_settingsChanged |= drumstick::widgets::configureInputDriver(driver, this); } } void Connections::configureOutputDriver() { QString driver = ui.m_outputBackends->currentText(); if (drumstick::widgets::outputDriverIsConfigurable(driver)) { m_settingsChanged |= drumstick::widgets::configureOutputDriver(driver, this); } } drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/vpiano.cpp0000644000000000000000000000013214200302440017714 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/vpiano.cpp0000644000175000001440000005101114200302440020473 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #if defined(Q_OS_MACOS) #include #endif #include "connections.h" #include "preferences.h" #include "vpiano.h" #include "vpianoabout.h" #include "vpianosettings.h" #include #include #include using namespace drumstick::rt; using namespace drumstick::widgets; VPiano::VPiano( QWidget * parent, Qt::WindowFlags flags) : QMainWindow(parent, flags), m_midiIn(nullptr), m_midiOut(nullptr) { ui.setupUi(this); bool mouseInputEnabled = true; bool touchInputEnabled = false; #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) const QList devs = QTouchDevice::devices(); for(const QTouchDevice *dev : devs) { if (dev->type() == QTouchDevice::TouchScreen) { mouseInputEnabled = false; touchInputEnabled = true; break; } } #else foreach(const QInputDevice *dev, QInputDevice::devices()) { if (dev->type() == QInputDevice::DeviceType::TouchScreen) { mouseInputEnabled = false; touchInputEnabled = true; break; } } #endif ui.pianokeybd->setMouseEnabled(mouseInputEnabled); ui.pianokeybd->setTouchEnabled(touchInputEnabled); connect(ui.pianokeybd, &PianoKeybd::noteOn, this, QOverload::of(&VPiano::slotNoteOn)); connect(ui.pianokeybd, &PianoKeybd::noteOff, this, QOverload::of(&VPiano::slotNoteOff)); connect(ui.pianokeybd, &PianoKeybd::signalName, this, &VPiano::slotNoteName); connect(ui.actionExit, &QAction::triggered, this, &VPiano::close); connect(ui.actionAbout, &QAction::triggered, this, &VPiano::slotAbout); connect(ui.actionAbout_Qt, &QAction::triggered, qApp, &QApplication::aboutQt); connect(ui.actionConnections, &QAction::triggered, this, &VPiano::slotConnections); connect(ui.actionPreferences, &QAction::triggered, this, &VPiano::slotPreferences); connect(ui.actionNames_Font, &QAction::triggered, this, &VPiano::slotChangeFont); connect(ui.actionInverted_Keys_Color, &QAction::triggered, this, &VPiano::slotInvertedColors); QActionGroup* nameGroup = new QActionGroup(this); nameGroup->setExclusive(true); nameGroup->addAction(ui.actionStandard); nameGroup->addAction(ui.actionCustom_Sharps); nameGroup->addAction(ui.actionCustom_Flats); connect(ui.actionStandard, &QAction::triggered, this, &VPiano::slotStandardNames); connect(ui.actionCustom_Sharps, &QAction::triggered, this, [=]{ slotCustomNames(true); }); connect(ui.actionCustom_Flats, &QAction::triggered, this, [=]{ slotCustomNames(false); }); QActionGroup* nameVisibilityGroup = new QActionGroup(this); nameVisibilityGroup->setExclusive(true); nameVisibilityGroup->addAction(ui.actionNever); nameVisibilityGroup->addAction(ui.actionMinimal); nameVisibilityGroup->addAction(ui.actionWhen_Activated); nameVisibilityGroup->addAction(ui.actionAlways); connect(nameVisibilityGroup, &QActionGroup::triggered, this, &VPiano::slotNameVisibility); QActionGroup* blackKeysGroup = new QActionGroup(this); blackKeysGroup->setExclusive(true); blackKeysGroup->addAction(ui.actionFlats); blackKeysGroup->addAction(ui.actionSharps); blackKeysGroup->addAction(ui.actionNothing); connect(blackKeysGroup, &QActionGroup::triggered, this, &VPiano::slotNameVariant); QActionGroup* orientationGroup = new QActionGroup(this); orientationGroup->setExclusive(true); orientationGroup->addAction(ui.actionHorizontal); orientationGroup->addAction(ui.actionVertical); orientationGroup->addAction(ui.actionAutomatic); connect(orientationGroup, &QActionGroup::triggered, this, &VPiano::slotNameOrientation); QActionGroup* centralOctaveGroup = new QActionGroup(this); centralOctaveGroup->setExclusive(true); centralOctaveGroup->addAction(ui.actionNoOctaves); centralOctaveGroup->addAction(ui.actionC3); centralOctaveGroup->addAction(ui.actionC4); centralOctaveGroup->addAction(ui.actionC5); connect(centralOctaveGroup, &QActionGroup::triggered, this, &VPiano::slotCentralOctave); ui.statusBar->hide(); } VPiano::~VPiano() { m_midiIn->close(); m_midiOut->close(); } void VPiano::initialize() { readSettings(); BackendManager man; man.refresh(VPianoSettings::instance()->settingsMap()); m_inputs = man.availableInputs(); m_outputs = man.availableOutputs(); m_midiIn = man.findInput(VPianoSettings::instance()->lastInputBackend()); if (m_midiIn == nullptr) { qFatal("Unable to find a suitable input backend."); } m_midiOut = man.findOutput(VPianoSettings::instance()->lastOutputBackend()); if (m_midiOut == nullptr) { qFatal("Unable to find a suitable output backend"); } drumstick::widgets::SettingsFactory settings; if (m_midiIn != nullptr) { connect(m_midiIn, &MIDIInput::midiNoteOn, this, QOverload::of(&VPiano::slotNoteOn), Qt::QueuedConnection); connect(m_midiIn, &MIDIInput::midiNoteOff, this, QOverload::of(&VPiano::slotNoteOff), Qt::QueuedConnection); if (m_midiIn != nullptr) { m_midiIn->initialize(settings.getQSettings()); MIDIConnection conn; auto conin = m_midiIn->connections(VPianoSettings::instance()->advanced()); auto lastIn = VPianoSettings::instance()->lastInputConnection(); auto itr = std::find_if(conin.constBegin(), conin.constEnd(), [lastIn](const MIDIConnection& s) { return s.first == lastIn; }); if(itr == conin.constEnd()) { if (!conin.isEmpty()) { conn = conin.first(); } } else { conn = (*itr); } m_midiIn->open(conn); auto metaObj = m_midiIn->metaObject(); if ((metaObj->indexOfProperty("status") != -1) && (metaObj->indexOfProperty("diagnostics") != -1)) { auto status = m_midiIn->property("status"); if (status.isValid() && !status.toBool()) { auto diagnostics = m_midiIn->property("diagnostics"); if (diagnostics.isValid()) { auto text = diagnostics.toStringList().join(QChar::LineFeed).trimmed(); qWarning() << "MIDI Input" << text; } } } } } if (m_midiOut != nullptr) { m_midiOut->initialize(settings.getQSettings()); MIDIConnection conn; auto connOut = m_midiOut->connections(VPianoSettings::instance()->advanced()); auto lastOut = VPianoSettings::instance()->lastOutputConnection(); auto itr = std::find_if(connOut.constBegin(), connOut.constEnd(), [lastOut](const MIDIConnection& s) { return s.first == lastOut; }); if(itr == connOut.constEnd()) { if (!connOut.isEmpty()) { conn = connOut.first(); } } else { conn = (*itr); } m_midiOut->open(conn); auto metaObj = m_midiOut->metaObject(); if ((metaObj->indexOfProperty("status") != -1) && (metaObj->indexOfProperty("diagnostics") != -1)) { auto status = m_midiOut->property("status"); if (status.isValid() && !status.toBool()) { auto diagnostics = m_midiOut->property("diagnostics"); if (diagnostics.isValid()) { auto text = diagnostics.toStringList().join(QChar::LineFeed).trimmed(); qWarning() << "MIDI Output" << text; } } } if (m_midiIn != nullptr) { m_midiIn->setMIDIThruDevice(m_midiOut); m_midiIn->enableMIDIThru(VPianoSettings::instance()->midiThru()); } } } void VPiano::showEvent(QShowEvent *event) { initialize(); event->accept(); } void VPiano::closeEvent(QCloseEvent *event) { writeSettings(); event->accept(); } void VPiano::slotNoteOn(const int midiNote, const int vel) { int chan = VPianoSettings::instance()->outChannel(); m_midiOut->sendNoteOn(chan, midiNote, vel); } void VPiano::slotNoteOff(const int midiNote, const int vel) { int chan = VPianoSettings::instance()->outChannel(); m_midiOut->sendNoteOff(chan, midiNote, vel); } void VPiano::slotNoteOn(const int chan, const int note, const int vel) { if (VPianoSettings::instance()->inChannel() == chan) { if (vel > 0) { ui.pianokeybd->showNoteOn(note, vel); } else { ui.pianokeybd->showNoteOff(note); } } } void VPiano::slotNoteOff(const int chan, const int note, const int vel) { Q_UNUSED(vel) if (VPianoSettings::instance()->inChannel() == chan) { ui.pianokeybd->showNoteOff(note); } } void VPiano::slotAbout() { About dlgAbout(this); dlgAbout.exec(); } void VPiano::slotConnections() { Connections dlgConnections(this); dlgConnections.setInputs(m_inputs); dlgConnections.setOutputs(m_outputs); dlgConnections.setInput(m_midiIn); dlgConnections.setOutput(m_midiOut); dlgConnections.refresh(); if (dlgConnections.exec() == QDialog::Accepted) { if (m_midiIn != nullptr) { m_midiIn->disconnect(); } if (m_midiOut != nullptr) { m_midiOut->disconnect(); } m_midiIn = dlgConnections.getInput(); m_midiOut = dlgConnections.getOutput(); if (m_midiIn != nullptr) { connect(m_midiIn, &MIDIInput::midiNoteOn, this, QOverload::of(&VPiano::slotNoteOn), Qt::QueuedConnection); connect(m_midiIn, &MIDIInput::midiNoteOff, this, QOverload::of(&VPiano::slotNoteOff), Qt::QueuedConnection); } } } void VPiano::slotPreferences() { Preferences dlgPreferences(this); if (dlgPreferences.exec() == QDialog::Accepted) { if (ui.pianokeybd->baseOctave() != VPianoSettings::instance()->baseOctave()) { ui.pianokeybd->setBaseOctave(VPianoSettings::instance()->baseOctave()); } if (ui.pianokeybd->numKeys() != VPianoSettings::instance()->numKeys() || ui.pianokeybd->startKey() != VPianoSettings::instance()->startingKey()) { ui.pianokeybd->setNumKeys(VPianoSettings::instance()->numKeys(), VPianoSettings::instance()->startingKey()); } ui.pianokeybd->setChannel(VPianoSettings::instance()->outChannel()); ui.pianokeybd->setVelocity(VPianoSettings::instance()->velocity()); } } void VPiano::writeSettings() { VPianoSettings::instance()->setGeometry(saveGeometry()); VPianoSettings::instance()->setState(saveState()); VPianoSettings::instance()->SaveSettings(); } void VPiano::readSettings() { VPianoSettings::instance()->ReadSettings(); restoreGeometry(VPianoSettings::instance()->geometry()); restoreState(VPianoSettings::instance()->state()); ui.pianokeybd->setFont(VPianoSettings::instance()->namesFont()); LabelNaming namingPolicy = VPianoSettings::instance()->namingPolicy(); switch(namingPolicy) { case StandardNames: ui.actionStandard->setChecked(true); ui.pianokeybd->useStandardNoteNames(); break; case CustomNamesWithSharps: ui.actionCustom_Sharps->setChecked(true); ui.pianokeybd->useCustomNoteNames(VPianoSettings::instance()->names_sharps()); break; case CustomNamesWithFlats: ui.actionCustom_Flats->setChecked(true); ui.pianokeybd->useCustomNoteNames(VPianoSettings::instance()->names_flats()); break; } LabelOrientation nOrientation = VPianoSettings::instance()->namesOrientation(); ui.pianokeybd->setLabelOrientation(nOrientation); switch(nOrientation) { case HorizontalOrientation: ui.actionHorizontal->setChecked(true); break; case VerticalOrientation: ui.actionVertical->setChecked(true); break; case AutomaticOrientation: ui.actionAutomatic->setChecked(true); break; default: break; } LabelAlteration alteration = VPianoSettings::instance()->alterations(); ui.pianokeybd->setLabelAlterations(alteration); switch(alteration) { case ShowSharps: ui.actionSharps->setChecked(true); break; case ShowFlats: ui.actionFlats->setChecked(true); break; case ShowNothing: ui.actionNothing->setChecked(true); break; default: break; } LabelVisibility visibility = VPianoSettings::instance()->namesVisibility(); ui.pianokeybd->setShowLabels(visibility); switch(visibility) { case ShowNever: ui.actionNever->setChecked(true); break; case ShowMinimum: ui.actionMinimal->setChecked(true); break; case ShowActivated: ui.actionWhen_Activated->setChecked(true); break; case ShowAlways: ui.actionAlways->setChecked(true); break; default: break; } LabelCentralOctave nOctave = VPianoSettings::instance()->namesOctave(); ui.pianokeybd->setLabelOctave(nOctave); switch(nOctave) { case OctaveNothing: ui.actionNoOctaves->setChecked(true); break; case OctaveC3: ui.actionC3->setChecked(true); break; case OctaveC4: ui.actionC4->setChecked(true); break; case OctaveC5: ui.actionC5->setChecked(true); break; default: break; } ui.statusBar->show(); ui.pianokeybd->setBaseOctave(VPianoSettings::instance()->baseOctave()); ui.pianokeybd->setNumKeys(VPianoSettings::instance()->numKeys(), VPianoSettings::instance()->startingKey()); /* * PianoKeybd::setKeyPressedColor(red) is equivalent to: * PianoPalette hpalette(PAL_SINGLE); * hpalette.setColor(0, Qt::red); * ui.pianokeybd->setHighlightPalette(hpalette); */ ui.pianokeybd->setKeyPressedColor(Qt::red); ui.pianokeybd->setVelocityTint(false); ui.actionInverted_Keys_Color->setChecked(VPianoSettings::instance()->invertedKeys()); slotInvertedColors(ui.actionInverted_Keys_Color->isChecked()); } void VPiano::setPortableConfig(const QString fileName) { if (fileName.isEmpty()) { QFileInfo appInfo(QCoreApplication::applicationFilePath()); #if defined(Q_OS_MACOS) CFURLRef url = static_cast(CFAutorelease(static_cast(CFBundleCopyBundleURL(CFBundleGetMainBundle())))); QString path = QUrl::fromCFURL(url).path() + "../"; QFileInfo cfgInfo(path, appInfo.baseName() + ".conf"); #else QFileInfo cfgInfo(appInfo.absoluteDir(), appInfo.baseName() + ".conf"); #endif drumstick::widgets::SettingsFactory::setFileName(cfgInfo.absoluteFilePath()); } else { drumstick::widgets::SettingsFactory::setFileName(fileName); } } void VPiano::useCustomNoteNames() { if (ui.pianokeybd->labelAlterations() == ShowFlats) { ui.pianokeybd->useCustomNoteNames(VPianoSettings::instance()->names_flats()); } else { ui.pianokeybd->useCustomNoteNames(VPianoSettings::instance()->names_sharps()); } } void VPiano::slotChangeFont() { bool ok; QFont font = QFontDialog::getFont(&ok, VPianoSettings::instance()->namesFont(), this, tr("Font to display note names"), QFontDialog::DontUseNativeDialog | QFontDialog::ScalableFonts); if (ok) { VPianoSettings::instance()->setNamesFont(font); ui.pianokeybd->setFont(font); } } void VPiano::slotNameOrientation(QAction* action) { if(action == ui.actionHorizontal) { VPianoSettings::instance()->setNamesOrientation(HorizontalOrientation); } else if(action == ui.actionVertical) { VPianoSettings::instance()->setNamesOrientation(VerticalOrientation); } else if(action == ui.actionAutomatic) { VPianoSettings::instance()->setNamesOrientation(AutomaticOrientation); } ui.pianokeybd->setLabelOrientation(VPianoSettings::instance()->namesOrientation()); } void VPiano::slotNameVisibility(QAction* action) { if(action == ui.actionNever) { VPianoSettings::instance()->setNamesVisibility(ShowNever); } else if(action == ui.actionMinimal) { VPianoSettings::instance()->setNamesVisibility(ShowMinimum); } else if(action == ui.actionWhen_Activated) { VPianoSettings::instance()->setNamesVisibility(ShowActivated); } else if(action == ui.actionAlways) { VPianoSettings::instance()->setNamesVisibility(ShowAlways); } ui.pianokeybd->setShowLabels(VPianoSettings::instance()->namesVisibility()); } void VPiano::slotNameVariant(QAction* action) { if(action == ui.actionSharps) { VPianoSettings::instance()->setNamesAlterations(ShowSharps); } else if(action == ui.actionFlats) { VPianoSettings::instance()->setNamesAlterations(ShowFlats); } else if(action == ui.actionNothing) { VPianoSettings::instance()->setNamesAlterations(ShowNothing); } ui.pianokeybd->setLabelAlterations(VPianoSettings::instance()->alterations()); } void VPiano::slotCentralOctave(QAction *action) { if (action == ui.actionNoOctaves) { VPianoSettings::instance()->setNamesOctave(OctaveNothing); } else if (action == ui.actionC3) { VPianoSettings::instance()->setNamesOctave(OctaveC3); } else if(action == ui.actionC4) { VPianoSettings::instance()->setNamesOctave(OctaveC4); } else if(action == ui.actionC5) { VPianoSettings::instance()->setNamesOctave(OctaveC5); } ui.pianokeybd->setLabelOctave(VPianoSettings::instance()->namesOctave()); } void VPiano::slotStandardNames() { VPianoSettings::instance()->setNamingPolicy(StandardNames); ui.pianokeybd->useStandardNoteNames(); ui.actionStandard->setChecked(true); } void VPiano::slotCustomNames(bool sharps) { bool ok; QString names; if ( sharps ) { names = VPianoSettings::instance()->names_sharps().join('\n'); } else { names = VPianoSettings::instance()->names_flats().join('\n'); } QString text = QInputDialog::getMultiLineText(this,tr("Custom Note Names"),tr("Names:"), names, &ok); if (ok && !text.isEmpty()) { QStringList customNames = text.split('\n'); if (sharps) { VPianoSettings::instance()->setNames_sharps(customNames); VPianoSettings::instance()->setNamingPolicy(CustomNamesWithSharps); } else { VPianoSettings::instance()->setNames_flats(customNames); VPianoSettings::instance()->setNamingPolicy(CustomNamesWithFlats); } ui.pianokeybd->useCustomNoteNames(customNames); } else { slotStandardNames(); } } void VPiano::slotNoteName(const QString& name) { if (name.isEmpty()) { ui.statusBar->clearMessage(); } else { ui.statusBar->showMessage(name); } } void VPiano::slotInvertedColors(bool checked) { PianoPalette bgpal(PAL_KEYS); PianoPalette fpal(PAL_FONT); if (checked) { bgpal.setColor(0, Qt::black); bgpal.setColor(1, Qt::white); fpal.setColor(0, Qt::white); fpal.setColor(1, Qt::black); fpal.setColor(2, Qt::white); fpal.setColor(3, Qt::white); } else { bgpal.setColor(0, QColor("ivory")); bgpal.setColor(1, QColor(0x40,0x10,0x10)); fpal.setColor(0, Qt::black); fpal.setColor(1, Qt::white); fpal.setColor(2, Qt::white); fpal.setColor(3, Qt::white); } ui.pianokeybd->setBackgroundPalette(bgpal); ui.pianokeybd->setForegroundPalette(fpal); VPianoSettings::instance()->setInvertedKeys(checked); } drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/drumstick-vpiano_en.ts0000644000000000000000000000013214200302440022245 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/drumstick-vpiano_en.ts0000644000175000001440000004240414200302440023032 0ustar00pedrousers00000000000000 About Revision AboutClass About <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Virtual Piano %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:16pt; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Using Qt version: %QT_VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> Connections MIDI Output MIDI Input ConnectionsClass Connections MIDI IN Enable MIDI THRU MIDI OUT ... Show advanced connections PreferencesClass Preferences Output Channel Number of keys Velocity Input Channel Base octave Starting Key C C# D D# E F F# G G# A A# B VPiano Drumstick Virtual Piano File Edit Help View Show Note Names Black Keys Names Names Orientation Central Octave Name Note Names &Exit &Preferences &Connections About About Qt Never When Activated Always Sharps Flats Nothing Horizontal Vertical Automatic Names Font Minimal C3 C4 C5 Standard Custom with Sharps Custom with Flats C Inverted Keys Color Font to display note names Custom Note Names Names: main Drumstick Simple Virtual Piano Copyright (C) 2006-2022 Pedro Lopez-Cabanillas This program comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under certain conditions; see the LICENSE file for details. Portable settings mode Fatal error from a MIDI backend. drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/drumstick-vpiano.desktop0000644000000000000000000000013214200302440022606 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/drumstick-vpiano.desktop0000644000175000001440000000042014200302440023363 0ustar00pedrousers00000000000000[Desktop Entry] Name=Drumstick Virtual Piano Exec=drumstick-vpiano Icon=drumstick Terminal=false Type=Application Categories=AudioVideo;Audio;Midi;Education;Music; Keywords=Music;Midi;Piano;Virtual; Comment=Drumstick Virtual Piano Comment[es]=Piano virtual de Drumstick drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/vpianoabout.h0000644000000000000000000000013214200302440020414 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/vpianoabout.h0000644000175000001440000000200414200302440021171 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ABOUT_H #define ABOUT_H #include #include "ui_vpianoabout.h" class About : public QDialog { Q_OBJECT public: explicit About(QWidget *parent = nullptr); private: Ui::AboutClass ui; }; #endif // ABOUT_H drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/preferences.ui0000644000000000000000000000013214200302440020554 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/preferences.ui0000644000175000001440000001601414200302440021337 0ustar00pedrousers00000000000000 PreferencesClass 0 0 270 213 Preferences 127 100 15 0 0 Output Channel spinOutChan 0 9 0 0 Number of keys spinNumKeys 0 0 Velocity spinVelocity 0 0 Input Channel spinInChan QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok 0 0 Base octave spinBaseOctave 15 12 120 88 0 0 Starting Key comboNotes 5 12 C C# D D# E F F# G G# A A# B spinInChan spinOutChan spinVelocity spinBaseOctave spinNumKeys comboNotes buttonBox buttonBox accepted() PreferencesClass accept() 237 412 263 11 buttonBox rejected() PreferencesClass reject() 127 412 155 14 drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/vpiano.pro0000644000000000000000000000013214200302440017732 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/vpiano.pro0000644000175000001440000000470314200302440020517 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = drumstick-vpiano QT += gui widgets network CONFIG += qt c++11 thread exceptions CONFIG += lrelease DESTDIR = ../../build/bin LRELEASE_DIR=. include (../../global.pri) INCLUDEPATH += . ../../library/include # Input FORMS += \ vpiano.ui \ connections.ui \ vpianoabout.ui \ preferences.ui HEADERS += \ vpiano.h \ connections.h \ vpianoabout.h \ preferences.h \ vpianosettings.h SOURCES += \ vpiano.cpp \ connections.cpp \ vpianoabout.cpp \ preferences.cpp \ vpianomain.cpp \ vpianosettings.cpp TRANSLATIONS += \ drumstick-vpiano_en.ts \ drumstick-vpiano_es.ts # libs macx:!static { QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib LIBS += -framework drumstick-rt -framework drumstick-widgets LIBS += -framework CoreFoundation ICON = ../../icons/drumstick.icns QMAKE_TARGET_BUNDLE_PREFIX = net.sourceforge QMAKE_BUNDLE = drumstick-vpiano QMAKE_INFO_PLIST = ../Info.plist.app } else { LIBS += -L$$OUT_PWD/../../build/lib/ LIBS += -l$$drumstickLib(drumstick-rt) -l$$drumstickLib(drumstick-widgets) } static { CONFIG += link_prl DEFINES += DRUMSTICK_STATIC DEFINES += NET_BACKEND LIBS += -L$$OUT_PWD/../../build/lib/drumstick/ LIBS += -ldrumstick-rt-net-in \ -ldrumstick-rt-net-out packagesExist(fluidsynth) { DEFINES += FLUIDSYNTH_BACKEND LIBS += -ldrumstick-rt-fluidsynth macx { QMAKE_LFLAGS += -F/Library/Frameworks LIBS += -framework FluidSynth } else { CONFIG += link_pkgconfig PKGCONFIG += fluidsynth } } linux { DEFINES += LINUX_BACKEND LIBS += -ldrumstick-rt-alsa-in \ -ldrumstick-rt-alsa-out \ -ldrumstick-rt-eassynth \ -ldrumstick-alsa \ -lasound \ -lsonivox } unix:!macx { DEFINES += OSS_BACKEND LIBS += -ldrumstick-rt-oss-in \ -ldrumstick-rt-oss-out } macx { DEFINES += MAC_BACKEND LIBS += -ldrumstick-rt-mac-in \ -ldrumstick-rt-mac-out \ -ldrumstick-rt-macsynth \ -framework CoreMIDI \ -framework CoreFoundation } win32 { DEFINES += WIN_BACKEND LIBS += -ldrumstick-rt-win-in \ -ldrumstick-rt-win-out \ -lwinmm } } drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/preferences.h0000644000000000000000000000013214200302440020366 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/preferences.h0000644000175000001440000000233314200302440021150 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef PREFERENCES_H #define PREFERENCES_H #include #include "ui_preferences.h" class Preferences : public QDialog { Q_OBJECT public: explicit Preferences(QWidget *parent = nullptr); void apply(); public slots: void slotButtonClicked(QAbstractButton *button); void accept() override; protected: void showEvent ( QShowEvent *event ) override; private: Ui::PreferencesClass ui; }; #endif // PREFERENCES_H drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/drumstick-vpiano.metainfo.xml0000644000000000000000000000013214200302440023536 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/drumstick-vpiano.metainfo.xml0000644000175000001440000000167114200302440024324 0ustar00pedrousers00000000000000 net.sourceforge.drumstick-vpiano drumstick-vpiano Simple Virtual MIDI Piano FSFAP GPL-3.0+

Simple multiplatform virtual MIDI piano based on the Drumstick::RT library, also using Drumstick::Widgets.

This program is an example of the Drumstick libraries. For a fully featured virtual MIDI piano keyboard see: vmpk.sourceforge.io

net.sourceforge.drumstick-vpiano.desktop https://drumstick.sourceforge.io/images/drumstick-vpiano.png
drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/vpiano.ui0000644000000000000000000000013214200302440017547 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/vpiano.ui0000644000175000001440000002011414200302440020326 0ustar00pedrousers00000000000000 VPiano 0 0 664 139 Drumstick Virtual Piano :/drumstick.png:/drumstick.png 0 0 664 23 File Edit Help View Show Note Names Black Keys Names Names Orientation Central Octave Name Note Names true &Exit &Preferences &Connections About About Qt true true Never true When Activated true Always true true Sharps true false Flats true Nothing true true Horizontal true Vertical true Automatic Names Font true Minimal true C3 true true C4 true C5 true true Standard true Custom with Sharps true Custom with Flats true C true Inverted Keys Color drumstick::widgets::PianoKeybd QGraphicsView
drumstick/pianokeybd.h
drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/vpianomain.cpp0000644000000000000000000000013214200302440020561 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/vpianomain.cpp0000644000175000001440000001176614200302440021355 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "vpiano.h" const char* PGM_DESCRIPTION = QT_TRANSLATE_NOOP("main", "Drumstick Simple Virtual Piano\n" "Copyright (C) 2006-2022 Pedro Lopez-Cabanillas\n" "This program comes with ABSOLUTELY NO WARRANTY; " "This is free software, and you are welcome to redistribute it " "under certain conditions; see the LICENSE file for details."); #if defined(LINUX_BACKEND) Q_IMPORT_PLUGIN(ALSAMIDIInput) Q_IMPORT_PLUGIN(ALSAMIDIOutput) Q_IMPORT_PLUGIN(SynthController) #endif #if defined(MAC_BACKEND) Q_IMPORT_PLUGIN(MacMIDIInput) Q_IMPORT_PLUGIN(MacMIDIOutput) Q_IMPORT_PLUGIN(MacSynthOutput) #endif #if defined(WIN_BACKEND) Q_IMPORT_PLUGIN(WinMIDIInput) Q_IMPORT_PLUGIN(WinMIDIOutput) #endif #if defined(NET_BACKEND) Q_IMPORT_PLUGIN(NetMIDIInput) Q_IMPORT_PLUGIN(NetMIDIOutput) #endif #if defined(DUMMY_BACKEND) Q_IMPORT_PLUGIN(DummyInput) Q_IMPORT_PLUGIN(DummyOutput) #endif #if defined(FLUIDSYNTH_BACKEND) Q_IMPORT_PLUGIN(SynthOutput) #endif #if defined(OSS_BACKEND) Q_IMPORT_PLUGIN(OSSInput) Q_IMPORT_PLUGIN(OSSOutput) #endif int main(int argc, char *argv[]) { QApplication app(argc, argv); QCoreApplication::setOrganizationName("drumstick.sourceforge.net"); QCoreApplication::setOrganizationDomain("drumstick.sourceforge.net"); QCoreApplication::setApplicationName("drumstick-vpiano"); QCoreApplication::setApplicationVersion(QStringLiteral(QT_STRINGIFY(VERSION))); QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false); QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false); QLocale locale; QTranslator qtTranslator; if ((locale.language() != QLocale::C) && (locale.language() != QLocale::English)) { if (qtTranslator.load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { if (!QCoreApplication::installTranslator(&qtTranslator)) { qWarning() << "Failure installing qt translator" << locale; } } else { qWarning() << "Unable to load Qt translator:" << locale; } } #if defined(Q_OS_WIN32) QString dataDir = QApplication::applicationDirPath() + "/"; #elif defined(Q_OS_MAC) QString dataDir = QApplication::applicationDirPath() + "/../Resources/"; #else QString dataDir = QApplication::applicationDirPath() + "/../share/drumstick/"; #endif QTranslator libTranslator, appTranslator; if ((locale.language() != QLocale::C) && (locale.language() != QLocale::English)) { if (libTranslator.load(locale, "drumstick-widgets", "_", dataDir)) { if (!QCoreApplication::installTranslator(&libTranslator)) { qWarning() << "installing lib translator" << locale << "failed"; } } else { qWarning() << "Unable to load lib translator:" << locale << "from" << dataDir; } if (appTranslator.load(locale, "drumstick-vpiano", "_", dataDir)) { if (!QCoreApplication::installTranslator(&appTranslator)) { qWarning() << "installing app translator" << locale << "failed"; } } else { qWarning() << "Unable to load app translator:" << locale << "from" << dataDir; } } QCommandLineParser parser; parser.setApplicationDescription(QString("%1 v.%2\n\n%3").arg(QCoreApplication::applicationName(), QCoreApplication::applicationVersion(), QCoreApplication::translate("main", PGM_DESCRIPTION))); auto helpOption = parser.addHelpOption(); auto versionOption = parser.addVersionOption(); QCommandLineOption portableOption({"p", "portable"}, QCoreApplication::translate("main", "Portable settings mode")); parser.addOption(portableOption); parser.process(app); try { VPiano w; if (parser.isSet(portableOption)) { w.setPortableConfig(); } else { QSettings::setDefaultFormat(QSettings::NativeFormat); } w.show(); return app.exec(); } catch (...) { qWarning() << QCoreApplication::translate("main", "Fatal error from a MIDI backend."); } return EXIT_FAILURE; } drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/connections.ui0000644000000000000000000000013214200302440020575 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/connections.ui0000644000175000001440000000664314200302440021367 0ustar00pedrousers00000000000000 ConnectionsClass 0 0 289 253 Connections MIDI IN Enable MIDI THRU MIDI OUT false ... Show advanced connections Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok false ... m_inputBackends btnInputDriverCfg m_inputPorts m_thru m_outputBackends btnOutputDriverCfg m_outputPorts m_advanced buttonBox accepted() ConnectionsClass accept() 264 303 283 112 buttonBox rejected() ConnectionsClass reject() 65 303 93 74 drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/vpiano.h0000644000000000000000000000013214200302440017361 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/vpiano.h0000644000175000001440000000500514200302440020142 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef VPIANO_H #define VPIANO_H #include #include #include #include #include "ui_vpiano.h" class VPiano : public QMainWindow { Q_OBJECT public: VPiano( QWidget* parent = nullptr, Qt::WindowFlags flags = Qt::Window); virtual ~VPiano(); void showEvent(QShowEvent *event) override; void closeEvent(QCloseEvent *event) override; void setPortableConfig(const QString fileName = QString()); public slots: void readSettings(); void writeSettings(); void slotAbout(); void slotConnections(); void slotPreferences(); void slotNoteOn(const int midiNote, const int vel); void slotNoteOn(const int chan, const int note, const int vel); void slotNoteOff(const int midiNote, const int vel); void slotNoteOff(const int chan, const int note, const int vel); void slotChangeFont(); void slotNameOrientation(QAction* action); void slotNameVisibility(QAction* action); void slotNameVariant(QAction* action); void slotCentralOctave(QAction* action); void slotStandardNames(); void slotCustomNames(bool sharps); void slotNoteName(const QString& name); void slotInvertedColors(bool checked); private: void initialize(); void useCustomNoteNames(); QList m_inputs; QList m_outputs; drumstick::rt::MIDIInput * m_midiIn; drumstick::rt::MIDIOutput* m_midiOut; Ui::VPiano ui; // QStringList m_names_s{"do", "do♯", "re", "re♯", "mi", "fa", "fa♯", "sol", "sol♯", "la", "la♯", "si"}; // QStringList m_names_f{"do", "re♭", "re", "mi♭", "mi", "fa", "sol♭", "sol", "la♭", "la", "si♭", "si"}; }; #endif // VPIANO_H drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/vpianoabout.cpp0000644000000000000000000000013214200302440020747 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/vpianoabout.cpp0000644000175000001440000000240714200302440021533 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "vpianoabout.h" About::About(QWidget *parent) : QDialog(parent) { ui.setupUi(this); QString aboutText = ui.AboutTextView->toHtml(); QString strver(QT_STRINGIFY(VERSION)); #ifdef REVISION strver.append("
"); strver.append(tr("Revision")); strver.append(" "); strver.append(QT_STRINGIFY(REVISION)); #endif aboutText.replace("%VERSION%", strver); aboutText.replace("%QT_VERSION%", qVersion()); ui.AboutTextView->setHtml(aboutText); } drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/vpianosettings.cpp0000644000000000000000000000013214200302440021475 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/vpianosettings.cpp0000644000175000001440000002576514200302440022275 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022 Pedro Lopez-Cabanillas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "vpianosettings.h" #include #include #include using namespace drumstick::rt; using namespace drumstick::widgets; VPianoSettings::VPianoSettings(QObject *parent) : QObject(parent) { ResetDefaults(); } VPianoSettings* VPianoSettings::instance() { static VPianoSettings inst; return &inst; } void VPianoSettings::ResetDefaults() { m_midiThru = false; m_advanced = false; m_inChannel = 0; m_outChannel = 0; m_velocity = 100; m_baseOctave = 1; m_numKeys = 88; m_startingKey = 9; m_defaultsMap = QVariantMap{ { BackendManager::QSTR_DRUMSTICKRT_PUBLICNAMEIN, QStringLiteral("Virtual Piano IN")}, { BackendManager::QSTR_DRUMSTICKRT_PUBLICNAMEOUT, QStringLiteral("Virtual Piano OUT")} }; emit ValuesChanged(); } void VPianoSettings::ReadSettings() { SettingsFactory settings; internalRead(*settings.getQSettings()); } void VPianoSettings::SaveSettings() { SettingsFactory settings; internalSave(*settings.getQSettings()); } void VPianoSettings::ReadFromFile(const QString &filepath) { QSettings settings(filepath, QSettings::IniFormat); internalRead(settings); } void VPianoSettings::SaveToFile(const QString &filepath) { QSettings settings(filepath, QSettings::IniFormat); internalSave(settings); } void VPianoSettings::internalRead(QSettings &settings) { const QStringList STD_NAMES_S{"do", "do♯", "re", "re♯", "mi", "fa", "fa♯", "sol", "sol♯", "la", "la♯", "si"}; const QStringList STD_NAMES_F{"do", "re♭", "re", "mi♭", "mi", "fa", "sol♭", "sol", "la♭", "la", "si♭", "si"}; settings.beginGroup("Window"); m_geometry = settings.value("Geometry").toByteArray(); m_state = settings.value("State").toByteArray(); settings.endGroup(); settings.beginGroup(BackendManager::QSTR_DRUMSTICKRT_GROUP); QStringList keys = settings.allKeys(); for(auto it = m_defaultsMap.begin(); it != m_defaultsMap.end(); ++it) { if (!keys.contains(it.key())) { keys.append(it.key()); } } for(const QString& key : qAsConst(keys)) { QVariant defval = m_defaultsMap.contains(key) ? m_defaultsMap[key] : QString(); m_settingsMap.insert(key, settings.value(key, defval)); } settings.endGroup(); settings.beginGroup("Connections"); m_lastInputBackend = settings.value("inputBackend").toString(); m_lastOutputBackend = settings.value("outputBackend").toString(); m_lastInputConnection = settings.value("inputConnection").toString(); m_lastOutputConnection = settings.value("outputConnection").toString(); m_midiThru = settings.value("midiThru", false).toBool(); m_advanced = settings.value("advanced", false).toBool(); settings.endGroup(); settings.beginGroup("Preferences"); setInChannel(settings.value("inputChannel", 0).toInt()); setOutChannel(settings.value("outputChannel", 0).toInt()); setVelocity(settings.value("velocity", 100).toInt()); setBaseOctave(settings.value("baseOctave", 1).toInt()); setNumKeys(settings.value("numKeys", 88).toInt()); setStartingKey(settings.value("startingKey", 9).toInt()); setBaseOctave(settings.value("baseOctave", 1).toInt()); setNumKeys(settings.value("numKeys", 88).toInt()); setStartingKey(settings.value("startingKey", 9).toInt()); settings.endGroup(); settings.beginGroup("TextSettings"); QFont f = QGuiApplication::font(); f.setPointSize(50); if (f.fromString(settings.value("namesFont", f.toString()).toString())) { setNamesFont(f); } setNamesOrientation(static_cast(settings.value("namesOrientation", HorizontalOrientation).toInt())); setNamesVisibility(static_cast(settings.value("namesVisibility", ShowNever).toInt())); setNamesAlterations(static_cast(settings.value("namesAlteration", ShowSharps).toInt())); setNamingPolicy(static_cast(settings.value("namingPolicy", StandardNames).toInt())); setNamesOctave(static_cast(settings.value("namesOctave", OctaveC4).toInt())); setNames_sharps(settings.value("names_sharps", STD_NAMES_S).toStringList()); setNames_flats(settings.value("names_flats", STD_NAMES_F).toStringList()); setInvertedKeys(settings.value("inverted_keys", false).toBool()); settings.endGroup(); emit ValuesChanged(); } void VPianoSettings::internalSave(QSettings &settings) { settings.beginGroup("Window"); settings.setValue("Geometry", m_geometry); settings.setValue("State", m_state); settings.endGroup(); settings.beginGroup(BackendManager::QSTR_DRUMSTICKRT_GROUP); for (auto it = m_settingsMap.begin(); it != m_settingsMap.end(); ++it) { settings.setValue(it.key(), it.value()); } settings.endGroup(); settings.beginGroup("Connections"); settings.setValue("inputBackend", m_lastInputBackend); settings.setValue("outputBackend", m_lastOutputBackend); settings.setValue("inputConnection", m_lastInputConnection); settings.setValue("outputConnection", m_lastOutputConnection); settings.setValue("midiThru", m_midiThru); settings.setValue("advanced", m_advanced); settings.endGroup(); settings.beginGroup("Preferences"); settings.setValue("inputChannel", m_inChannel); settings.setValue("outputChannel", m_outChannel); settings.setValue("velocity", m_velocity); settings.setValue("baseOctave", m_baseOctave); settings.setValue("numKeys", m_numKeys); settings.setValue("startingKey", m_startingKey); settings.endGroup(); settings.beginGroup("TextSettings"); settings.setValue("namesFont", m_namesFont.toString()); settings.setValue("namesOrientation", m_namesOrientation); settings.setValue("namesVisibility", m_namesVisibility); settings.setValue("namesAlteration", m_namesAlteration); settings.setValue("namingPolicy", m_namingPolicy); settings.setValue("namesOctave", m_namesOctave); settings.setValue("names_sharps", m_names_sharps); settings.setValue("names_flats", m_names_flats); settings.setValue("inverted_keys", m_invertedKeys); settings.endGroup(); settings.sync(); } bool VPianoSettings::invertedKeys() const { return m_invertedKeys; } void VPianoSettings::setInvertedKeys(bool newInvertedKeys) { m_invertedKeys = newInvertedKeys; } QStringList VPianoSettings::names_flats() const { return m_names_flats; } void VPianoSettings::setNames_flats(const QStringList &names_flats) { m_names_flats = names_flats; } QStringList VPianoSettings::names_sharps() const { return m_names_sharps; } void VPianoSettings::setNames_sharps(const QStringList &names_sharps) { m_names_sharps = names_sharps; } LabelNaming VPianoSettings::namingPolicy() const { return m_namingPolicy; } void VPianoSettings::setNamingPolicy(const LabelNaming namingPolicy) { m_namingPolicy = namingPolicy; } LabelCentralOctave VPianoSettings::namesOctave() const { return m_namesOctave; } void VPianoSettings::setNamesOctave(const LabelCentralOctave namesOctave) { m_namesOctave = namesOctave; } QFont VPianoSettings::namesFont() const { return m_namesFont; } void VPianoSettings::setNamesFont(const QFont &namesFont) { m_namesFont = namesFont; } LabelAlteration VPianoSettings::alterations() const { return m_namesAlteration; } void VPianoSettings::setNamesAlterations(const LabelAlteration alterations) { m_namesAlteration = alterations; } LabelVisibility VPianoSettings::namesVisibility() const { return m_namesVisibility; } void VPianoSettings::setNamesVisibility(const LabelVisibility namesVisibility) { m_namesVisibility = namesVisibility; } LabelOrientation VPianoSettings::namesOrientation() const { return m_namesOrientation; } void VPianoSettings::setNamesOrientation(const LabelOrientation namesOrientation) { m_namesOrientation = namesOrientation; } QVariantMap VPianoSettings::settingsMap() const { return m_settingsMap; } int VPianoSettings::startingKey() const { return m_startingKey; } void VPianoSettings::setStartingKey(int startingKey) { m_startingKey = startingKey; } int VPianoSettings::numKeys() const { return m_numKeys; } void VPianoSettings::setNumKeys(int numKeys) { m_numKeys = numKeys; } int VPianoSettings::baseOctave() const { return m_baseOctave; } void VPianoSettings::setBaseOctave(int baseOctave) { m_baseOctave = baseOctave; } int VPianoSettings::velocity() const { return m_velocity; } void VPianoSettings::setVelocity(int velocity) { m_velocity = velocity; } int VPianoSettings::outChannel() const { return m_outChannel; } void VPianoSettings::setOutChannel(int outChannel) { m_outChannel = outChannel; } int VPianoSettings::inChannel() const { return m_inChannel; } void VPianoSettings::setInChannel(int inChannel) { m_inChannel = inChannel; } bool VPianoSettings::advanced() const { return m_advanced; } void VPianoSettings::setAdvanced(bool advanced) { m_advanced = advanced; } bool VPianoSettings::midiThru() const { return m_midiThru; } void VPianoSettings::setMidiThru(bool midiThru) { m_midiThru = midiThru; } QString VPianoSettings::lastOutputConnection() const { return m_lastOutputConnection; } void VPianoSettings::setLastOutputConnection(const QString &lastOutputConnection) { m_lastOutputConnection = lastOutputConnection; } QString VPianoSettings::lastInputConnection() const { return m_lastInputConnection; } void VPianoSettings::setLastInputConnection(const QString &lastInputConnection) { m_lastInputConnection = lastInputConnection; } QString VPianoSettings::lastOutputBackend() const { return m_lastOutputBackend; } void VPianoSettings::setLastOutputBackend(const QString &lastOutputBackend) { m_lastOutputBackend = lastOutputBackend; } QString VPianoSettings::lastInputBackend() const { return m_lastInputBackend; } void VPianoSettings::setLastInputBackend(const QString &lastInputBackend) { m_lastInputBackend = lastInputBackend; } QByteArray VPianoSettings::state() const { return m_state; } void VPianoSettings::setState(const QByteArray &state) { m_state = state; } QByteArray VPianoSettings::geometry() const { return m_geometry; } void VPianoSettings::setGeometry(const QByteArray &geometry) { m_geometry = geometry; } drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/drumstick-vpiano_es.ts0000644000000000000000000000013214200302440022252 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/drumstick-vpiano_es.ts0000644000175000001440000005722114200302440023042 0ustar00pedrousers00000000000000 About Revision Revisión AboutClass About Acerca de <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Virtual Piano %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:16pt; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Using Qt version: %QT_VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Virtual Piano %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:16pt; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Using Qt version: %QT_VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> Connections MIDI Output Salida MIDI MIDI Input Entrada MIDI ConnectionsClass Connections Conexiones MIDI IN MIDI IN Enable MIDI THRU Habilitar MIDI THRU MIDI OUT MIDI OUT ... ... Show advanced connections Mostrar conexiones avanzadas PreferencesClass Preferences Preferencias Output Channel Canal de salida Number of keys Número de teclas Velocity Velocidad Input Channel Canal de entrada Base octave Octava base Starting Key Tecla inicial C do C# do# D re D# re# E mi F fa F# fa# G sol G# sol# A la A# la# B si QCoreApplication Portable settings mode Modo de ajustes portables QObject Drumstick Simple Virtual Piano Copyright (C) 2006-2022 Pedro López-Cabanillas This program comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under certain conditions; see the LICENSE file for details. Drumstick Piano Virtual Sencillo Copyright (C) 2006-2022 Pedro López-Cabanillas Este programa se ofrece SIN GARANTÍA ALGUNA. Este programa es software libre, y usted puede redistribuirlo bajo ciertas condiciones. Portable settings mode Modo de ajustes portables VPiano Drumstick Virtual Piano Piano virtual Drumstick File Archivo Edit Edición Help Ayuda View Ver Show Note Names Mostrar nombres de notas Black Keys Names Nombres de las teclas negras Names Orientation Orientación de los nombres Central Octave Name Nombre de la octava central Note Names Nombres de notas &Exit &Salir &Preferences &Preferencias &Connections &Conexiones About Acerca de About Qt Acerca de Qt Never Nunca When Activated Cuando se activen Always Siempre Sharps Sostenidos Flats Bemoles Nothing Nada Horizontal Horizontal Vertical Vertical Automatic Automática Names Font Fuente para nombres Minimal Mínimo C3 do3 C4 do4 C5 do5 Standard Estándar Custom with Sharps Personalizadas con sostenidos Custom with Flats Personalizadas con bemoles C do Inverted Keys Color Teclas de color invertido Font to display note names Fuente para mostrar nombres de notas Custom Note Names Nombres personalizados de notas Names: Nombres: main Drumstick Simple Virtual Piano Copyright (C) 2006-2022 Pedro Lopez-Cabanillas This program comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under certain conditions; see the LICENSE file for details. Drumstick Simple Virtual Piano Copyright (C) 2006-2022 Pedro López-Cabanillas This program comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under certain conditions; see the LICENSE file for details. Drumstick Piano Virtual Sencillo Copyright (C) 2006-2022 Pedro Lopez-Cabanillas Este programa se ofrece SIN GARANTÍA ALGUNA. Este programa es software libre, y usted puede redistribuirlo bajo ciertas condiciones; vea el archivo LICENSE para detalles. Drumstick Simple Virtual Piano Copyright (C) 2006-2022 Pedro Lopez-Cabanillas This program comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under certain conditions; see the LICENSE file for details. Drumstick Piano Virtual Sencillo Copyright (C) 2006-2022 Pedro Lopez-Cabanillas Este programa se ofrece SIN GARANTÍA ALGUNA. Este programa es software libre, y usted puede redistribuirlo bajo ciertas condiciones; vea el archivo LICENSE para detalles. Portable settings mode Modo de ajustes portables Fatal error from a MIDI backend. Error grave en el soporte MIDI. drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/vpianoabout.ui0000644000000000000000000000013214200302440020602 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/vpianoabout.ui0000644000175000001440000001371614200302440021373 0ustar00pedrousers00000000000000 AboutClass 0 0 487 334 About false true <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Virtual Piano %VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:16pt; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Using Qt version: %QT_VERSION%</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2022, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl@users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl@users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along with this program. If not, see </span><a href="http://www.gnu.org/licenses/"><span style=" font-family:'Sans Serif'; text-decoration: underline; color:#0057ae;">http://www.gnu.org/licenses/</span></a><span style=" font-family:'Sans Serif'; font-size:8pt;">.</span></p></body></html> true QDialogButtonBox::Close buttonBox rejected() AboutClass close() 306 315 325 335 drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/connections.h0000644000000000000000000000013214200302440020407 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/connections.h0000644000175000001440000000365714200302440021203 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef CONNECTIONS_H #define CONNECTIONS_H #include #include #include #include #include #include "ui_connections.h" class Connections : public QDialog { Q_OBJECT public: explicit Connections(QWidget *parent = nullptr); void setInput(drumstick::rt::MIDIInput *in); void setOutput(drumstick::rt::MIDIOutput *out); void setInputs(QList ins); void setOutputs(QList outs); drumstick::rt::MIDIInput *getInput(); drumstick::rt::MIDIOutput *getOutput(); public slots: void configureInputDriver(); void configureOutputDriver(); void clickedAdvanced(bool value); void refreshInputs(int index); void refreshOutputs(int index); void refresh(); void reopenDrivers(); void accept() override; void reject() override; private: bool m_settingsChanged; drumstick::rt::MIDIInput *m_midiIn, *m_savedIn; drumstick::rt::MIDIOutput *m_midiOut, *m_savedOut; drumstick::rt::MIDIConnection m_connIn, m_connOut; Ui::ConnectionsClass ui; }; #endif // CONNECTIONS_H drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/vpiano.qrc0000644000000000000000000000013214200302440017717 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/vpiano.qrc0000644000175000001440000000020114200302440020471 0ustar00pedrousers00000000000000 ../../icons/drumstick_32.png drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/preferences.cpp0000644000000000000000000000013214200302440020721 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.445324578 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/preferences.cpp0000644000175000001440000000456514200302440021514 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "preferences.h" #include "vpianosettings.h" #include #include Preferences::Preferences(QWidget *parent) : QDialog(parent) { ui.setupUi( this ); connect(ui.buttonBox, &QDialogButtonBox::clicked, this, &Preferences::slotButtonClicked); } void Preferences::slotButtonClicked(QAbstractButton *button) { if (dynamic_cast(button) == ui.buttonBox->button(QDialogButtonBox::Apply)) { apply(); } } void Preferences::showEvent ( QShowEvent *event ) { if (event->type() == QEvent::Show) { ui.spinInChan->setValue( VPianoSettings::instance()->inChannel() ); ui.spinOutChan->setValue( VPianoSettings::instance()->outChannel() ); ui.spinVelocity->setValue( VPianoSettings::instance()->velocity() ); ui.spinBaseOctave->setValue( VPianoSettings::instance()->baseOctave() ); ui.spinNumKeys->setValue( VPianoSettings::instance()->numKeys() ); ui.comboNotes->setCurrentIndex( VPianoSettings::instance()->startingKey() ); } } void Preferences::apply() { VPianoSettings::instance()->setInChannel(ui.spinInChan->value()); VPianoSettings::instance()->setOutChannel(ui.spinOutChan->value()); VPianoSettings::instance()->setVelocity(ui.spinVelocity->value()); VPianoSettings::instance()->setBaseOctave(ui.spinBaseOctave->value()); VPianoSettings::instance()->setNumKeys(ui.spinNumKeys->value()); VPianoSettings::instance()->setStartingKey(ui.comboNotes->currentIndex()); VPianoSettings::instance()->SaveSettings(); } void Preferences::accept() { apply(); QDialog::accept(); } drumstick-2.5.1/utils/vpiano/PaxHeaders.27918/vpianosettings.h0000644000000000000000000000013214200302440021142 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.533324633 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/vpiano/vpianosettings.h0000644000175000001440000001067414200302440021733 0ustar00pedrousers00000000000000/* Virtual Piano test using the MIDI Sequencer C++ library Copyright (C) 2006-2022 Pedro Lopez-Cabanillas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef PORTABLESETTINGS_H #define PORTABLESETTINGS_H #include #include #include #include #include #include class VPianoSettings : public QObject { Q_OBJECT public: static VPianoSettings* instance(); QByteArray geometry() const; void setGeometry(const QByteArray &geometry); QByteArray state() const; void setState(const QByteArray &state); QString lastInputBackend() const; void setLastInputBackend(const QString &lastInputBackend); QString lastOutputBackend() const; void setLastOutputBackend(const QString &lastOutputBackend); QString lastInputConnection() const; void setLastInputConnection(const QString &lastInputConnection); QString lastOutputConnection() const; void setLastOutputConnection(const QString &lastOutputConnection); bool midiThru() const; void setMidiThru(bool midiThru); bool advanced() const; void setAdvanced(bool advanced); int inChannel() const; void setInChannel(int inChannel); int outChannel() const; void setOutChannel(int outChannel); int velocity() const; void setVelocity(int velocity); int baseOctave() const; void setBaseOctave(int baseOctave); int numKeys() const; void setNumKeys(int numKeys); int startingKey() const; void setStartingKey(int startingKey); QVariantMap settingsMap() const; drumstick::widgets::LabelOrientation namesOrientation() const; void setNamesOrientation(const drumstick::widgets::LabelOrientation namesOrientation); drumstick::widgets::LabelVisibility namesVisibility() const; void setNamesVisibility(const drumstick::widgets::LabelVisibility namesVisibility); drumstick::widgets::LabelAlteration alterations() const; void setNamesAlterations(const drumstick::widgets::LabelAlteration alterations); QFont namesFont() const; void setNamesFont(const QFont &namesFont); drumstick::widgets::LabelCentralOctave namesOctave() const; void setNamesOctave(const drumstick::widgets::LabelCentralOctave namesOctave); drumstick::widgets::LabelNaming namingPolicy() const; void setNamingPolicy(const drumstick::widgets::LabelNaming namingPolicy); QStringList names_sharps() const; void setNames_sharps(const QStringList &names_sharps); QStringList names_flats() const; void setNames_flats(const QStringList &names_flats); bool invertedKeys() const; void setInvertedKeys(bool newInvertedKeys); signals: void ValuesChanged(); public slots: void ResetDefaults(); void ReadSettings(); void ReadFromFile(const QString &filepath); void SaveSettings(); void SaveToFile(const QString &filepath); private: explicit VPianoSettings(QObject *parent = nullptr); void internalRead(QSettings &settings); void internalSave(QSettings &settings); QByteArray m_geometry; QByteArray m_state; QString m_lastInputBackend; QString m_lastOutputBackend; QString m_lastInputConnection; QString m_lastOutputConnection; bool m_midiThru; bool m_advanced; int m_inChannel; int m_outChannel; int m_velocity; int m_baseOctave; int m_numKeys; int m_startingKey; QVariantMap m_settingsMap; QVariantMap m_defaultsMap; drumstick::widgets::LabelVisibility m_namesVisibility; drumstick::widgets::LabelAlteration m_namesAlteration; drumstick::widgets::LabelCentralOctave m_namesOctave; drumstick::widgets::LabelOrientation m_namesOrientation; drumstick::widgets::LabelNaming m_namingPolicy; QStringList m_names_sharps; QStringList m_names_flats; QFont m_namesFont; bool m_invertedKeys; }; #endif // PORTABLESETTINGS_H drumstick-2.5.1/utils/PaxHeaders.27918/utils.pro0000644000000000000000000000013214200302440016302 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.533324633 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/utils.pro0000644000175000001440000000046714200302440017072 0ustar00pedrousers00000000000000TEMPLATE = subdirs include (../global.pri) DEFINES += VERSION=$$VERSION SUBDIRS += \ dumprmi \ dumpsmf \ dumpwrk \ vpiano linux { SUBDIRS += \ drumgrid \ dumpmid \ guiplayer \ metronome \ playsmf \ sysinfo } macx { OTHER_FILES += Info.plist.app } drumstick-2.5.1/utils/PaxHeaders.27918/dumpmid0000644000000000000000000000013214200302440016002 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.533324633 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/dumpmid/0000755000175000001440000000000014200302440016640 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/dumpmid/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020617 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.533324633 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/dumpmid/CMakeLists.txt0000644000175000001440000000237514200302440021407 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(dumpmid_SRCS dumpmid.cpp dumpmid.h ) set(dumpmid_qtobject_SRCS dumpmid.h ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(dumpmid_moc_SRCS ${dumpmid_qtobject_SRCS}) else() qt_wrap_cpp(dumpmid_moc_SRCS ${dumpmid_qtobject_SRCS}) endif() add_executable(drumstick-dumpmid ${dumpmid_moc_SRCS} ${dumpmid_SRCS} ) target_link_libraries(drumstick-dumpmid PRIVATE Drumstick::ALSA Qt${QT_VERSION_MAJOR}::Core ) install(TARGETS drumstick-dumpmid RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) drumstick-2.5.1/utils/dumpmid/PaxHeaders.27918/dumpmid.cpp0000644000000000000000000000013214200302440020222 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.533324633 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/dumpmid/dumpmid.cpp0000644000175000001440000004026414200302440021011 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "dumpmid.h" #include #include #include #include #include #include #include #include #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #define right Qt::right #define left Qt::left #define hex Qt::hex #define dec Qt::dec #define endl Qt::endl #endif QTextStream cout(stdout, QIODevice::WriteOnly); QTextStream cerr(stderr, QIODevice::WriteOnly); using namespace drumstick::ALSA; QDumpMIDI::QDumpMIDI() : QObject(), m_Stopped(false) { m_Client = new MidiClient(this); m_Client->open(); m_Client->setClientName("DumpMIDI"); #ifndef USE_QEVENTS // using signals instead connect( m_Client, &MidiClient::eventReceived, this, &QDumpMIDI::sequencerEvent, Qt::DirectConnection ); #endif m_Port = new MidiPort(this); m_Port->attach( m_Client ); m_Port->setPortName("DumpMIDI port"); m_Port->setCapability( SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE ); m_Port->setPortType( SND_SEQ_PORT_TYPE_APPLICATION | SND_SEQ_PORT_TYPE_MIDI_GENERIC ); #ifdef WANT_TIMESTAMPS m_Queue = m_Client->createQueue("DumpMIDI"); m_Port->setTimestamping(true); //m_Port->setTimestampReal(true); m_Port->setTimestampQueue(m_Queue->getId()); #endif connect( m_Port, &MidiPort::subscribed, this, &QDumpMIDI::subscription); qDebug() << "Trying to subscribe from Announce"; m_Port->subscribeFromAnnounce(); } QDumpMIDI::~QDumpMIDI() { m_Port->detach(); delete m_Port; m_Client->close(); delete m_Client; } bool QDumpMIDI::stopped() { QReadLocker locker(&m_mutex); return m_Stopped; } void QDumpMIDI::stop() { QWriteLocker locker(&m_mutex); m_Stopped = true; } void QDumpMIDI::subscription(MidiPort*, Subscription* subs) { qDebug() << "Subscription made from" << subs->getSender()->client << ":" << subs->getSender()->port; } void QDumpMIDI::subscribe(const QString& portName) { try { qDebug() << "Trying to subscribe" << portName.toLocal8Bit().data(); m_Port->subscribeFrom(portName); } catch (const SequencerError& err) { cerr << "SequencerError exception. Error code: " << err.code() << " (" << err.qstrError() << ")" << endl; cerr << "Location: " << err.location() << endl; throw; } } void QDumpMIDI::run() { cout << "Press Ctrl+C to exit" << endl; #ifdef WANT_TIMESTAMPS cout << "___Ticks "; #endif cout << "Source_ Event_________________ Ch _Data__" << endl; try { #ifdef USE_QEVENTS m_Client->addListener(this); m_Client->setEventsEnabled(true); #endif m_Client->setRealTimeInput(false); m_Client->startSequencerInput(); #ifdef WANT_TIMESTAMPS m_Queue->start(); #endif m_Stopped = false; while (!stopped()) { #ifdef USE_QEVENTS QCoreApplication::sendPostedEvents(); #endif sleep(1); } #ifdef WANT_TIMESTAMPS m_Queue->stop(); #endif m_Client->stopSequencerInput(); } catch (const SequencerError& err) { cerr << "SequencerError exception. Error code: " << err.code() << " (" << err.qstrError() << ")" << endl; cerr << "Location: " << err.location() << endl; throw; } } #ifdef USE_QEVENTS void QDumpMIDI::customEvent(QEvent *ev) { if (ev->type() == SequencerEventType) { SequencerEvent* sev = static_cast(ev); if (sev != nullptr) { dumpEvent(sev); } } } #else void QDumpMIDI::sequencerEvent(SequencerEvent *ev) { dumpEvent(ev); delete ev; } #endif void QDumpMIDI::dumpEvent(SequencerEvent* sev) { #ifdef WANT_TIMESTAMPS cout << qSetFieldWidth(8) << right << sev->getTick(); /* More timestamp options: cout << sev->getRealTimeSecs(); cout << sev->getRealTimeNanos(); */ /* Getting the time from the queue status object; QueueStatus sts = m_Queue->getStatus(); cout << qSetFieldWidth(8) << right << sts.getClockTime(); cout << sts.getTickTime(); */ cout << qSetFieldWidth(0) << " "; #endif cout << qSetFieldWidth(3) << right << sev->getSourceClient() << qSetFieldWidth(0) << ":"; cout << qSetFieldWidth(3) << left << sev->getSourcePort() << qSetFieldWidth(0) << " "; switch (sev->getSequencerType()) { case SND_SEQ_EVENT_NOTEON: { NoteOnEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(23) << left << "Note on"; cout << qSetFieldWidth(2) << right << e->getChannel() << " "; cout << qSetFieldWidth(3) << e->getKey() << " "; cout << qSetFieldWidth(3) << e->getVelocity(); } break; } case SND_SEQ_EVENT_NOTEOFF: { NoteOffEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(23) << left << "Note off"; cout << qSetFieldWidth(2) << right << e->getChannel() << " "; cout << qSetFieldWidth(3) << e->getKey() << " "; cout << qSetFieldWidth(3) << e->getVelocity(); } break; } case SND_SEQ_EVENT_KEYPRESS: { KeyPressEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(23) << left << "Polyphonic aftertouch"; cout << qSetFieldWidth(2) << right << e->getChannel() << " "; cout << qSetFieldWidth(3) << e->getKey() << " "; cout << qSetFieldWidth(3) << e->getVelocity(); } break; } case SND_SEQ_EVENT_CONTROL14: case SND_SEQ_EVENT_NONREGPARAM: case SND_SEQ_EVENT_REGPARAM: case SND_SEQ_EVENT_CONTROLLER: { ControllerEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(23) << left << "Control change"; cout << qSetFieldWidth(2) << right << e->getChannel() << " "; cout << qSetFieldWidth(3) << e->getParam() << " "; cout << qSetFieldWidth(3) << e->getValue(); } break; } case SND_SEQ_EVENT_PGMCHANGE: { ProgramChangeEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(23) << left << "Program change"; cout << qSetFieldWidth(2) << right << e->getChannel() << " "; cout << qSetFieldWidth(3) << e->getValue(); } break; } case SND_SEQ_EVENT_CHANPRESS: { ChanPressEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(23) << left << "Channel aftertouch"; cout << qSetFieldWidth(2) << right << e->getChannel() << " "; cout << qSetFieldWidth(3) << e->getValue(); } break; } case SND_SEQ_EVENT_PITCHBEND: { PitchBendEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(23) << left << "Pitch bend"; cout << qSetFieldWidth(2) << right << e->getChannel() << " "; cout << qSetFieldWidth(5) << e->getValue(); } break; } case SND_SEQ_EVENT_SONGPOS: { ValueEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Song position pointer" << qSetFieldWidth(0); cout << e->getValue(); } break; } case SND_SEQ_EVENT_SONGSEL: { ValueEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Song select" << qSetFieldWidth(0); cout << e->getValue(); } break; } case SND_SEQ_EVENT_QFRAME: { ValueEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "MTC quarter frame" << qSetFieldWidth(0); cout << e->getValue(); } break; } case SND_SEQ_EVENT_TIMESIGN: { ValueEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "SMF time signature" << qSetFieldWidth(0); cout << hex << e->getValue(); cout << dec; } break; } case SND_SEQ_EVENT_KEYSIGN: { ValueEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "SMF key signature" << qSetFieldWidth(0); cout << hex << e->getValue(); cout << dec; } break; } case SND_SEQ_EVENT_SETPOS_TICK: { QueueControlEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Set tick queue pos." << qSetFieldWidth(0); cout << e->getQueue(); } break; } case SND_SEQ_EVENT_SETPOS_TIME: { QueueControlEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Set rt queue pos." << qSetFieldWidth(0); cout << e->getQueue(); } break; } case SND_SEQ_EVENT_TEMPO: { TempoEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Set queue tempo"; cout << qSetFieldWidth(3) << right << e->getQueue() << qSetFieldWidth(0) << " "; cout << e->getValue(); } break; } case SND_SEQ_EVENT_QUEUE_SKEW: { QueueControlEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Queue timer skew" << qSetFieldWidth(0); cout << e->getQueue(); } break; } case SND_SEQ_EVENT_START: cout << left << "Start"; break; case SND_SEQ_EVENT_STOP: cout << left << "Stop"; break; case SND_SEQ_EVENT_CONTINUE: cout << left << "Continue"; break; case SND_SEQ_EVENT_CLOCK: cout << left << "Clock"; break; case SND_SEQ_EVENT_TICK: cout << left << "Tick"; break; case SND_SEQ_EVENT_TUNE_REQUEST: cout << left << "Tune request"; break; case SND_SEQ_EVENT_RESET: cout << left << "Reset"; break; case SND_SEQ_EVENT_SENSING: cout << left << "Active Sensing"; break; case SND_SEQ_EVENT_CLIENT_START: { ClientEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Client start" << qSetFieldWidth(0) << e->getClient(); } break; } case SND_SEQ_EVENT_CLIENT_EXIT: { ClientEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Client exit" << qSetFieldWidth(0) << e->getClient(); } break; } case SND_SEQ_EVENT_CLIENT_CHANGE: { ClientEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Client changed" << qSetFieldWidth(0) << e->getClient(); } break; } case SND_SEQ_EVENT_PORT_START: { PortEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Port start" << qSetFieldWidth(0); cout << e->getClient() << ":" << e->getPort(); } break; } case SND_SEQ_EVENT_PORT_EXIT: { PortEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Port exit" << qSetFieldWidth(0); cout << e->getClient() << ":" << e->getPort(); } break; } case SND_SEQ_EVENT_PORT_CHANGE: { PortEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Port changed" << qSetFieldWidth(0); cout << e->getClient() << ":" << e->getPort(); } break; } case SND_SEQ_EVENT_PORT_SUBSCRIBED: { SubscriptionEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Port subscribed" << qSetFieldWidth(0); cout << e->getSenderClient() << ":" << e->getSenderPort() << " -> "; cout << e->getDestClient() << ":" << e->getDestPort(); } break; } case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: { SubscriptionEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "Port unsubscribed" << qSetFieldWidth(0); cout << e->getSenderClient() << ":" << e->getSenderPort() << " -> "; cout << e->getDestClient() << ":" << e->getDestPort(); } break; } case SND_SEQ_EVENT_SYSEX: { SysExEvent* e = static_cast(sev); if (e != nullptr) { cout << qSetFieldWidth(26) << left << "System exclusive" << qSetFieldWidth(0); unsigned int i; for (i = 0; i < e->getLength(); ++i) { cout << hex << (unsigned char) e->getData()[i] << " "; } cout << dec; } break; } default: cout << qSetFieldWidth(26) << "Unknown event type" << qSetFieldWidth(0); cout << sev->getSequencerType(); }; cout << qSetFieldWidth(0) << endl; } QDumpMIDI* test; void signalHandler(int sig) { if (sig == SIGINT) qDebug() << "Caught a SIGINT. Exiting"; else if (sig == SIGTERM) qDebug() << "Caught a SIGTERM. Exiting"; test->stop(); } int main(int argc, char **argv) { const QString ERRORSTR = QStringLiteral("Fatal error from the ALSA sequencer. " "This usually happens when the kernel doesn't have ALSA support, " "or the device node (/dev/snd/seq) doesn't exists, " "or the kernel module (snd_seq) is not loaded. " "Please check your ALSA/MIDI configuration."); const QString PGM_NAME = QStringLiteral("drumstick-dumpmid"); const QString PGM_DESCRIPTION = QStringLiteral("Drumstick command line utility for decoding MIDI events"); QCoreApplication app(argc, argv); QCoreApplication::setApplicationName(PGM_NAME); QCoreApplication::setApplicationVersion(QStringLiteral(QT_STRINGIFY(VERSION))); QCommandLineParser parser; parser.setApplicationDescription(PGM_DESCRIPTION); auto helpOption = parser.addHelpOption(); auto versionOption = parser.addVersionOption(); QCommandLineOption portOption({"p", "port"}, "Source MIDI Port.", "client:port"); parser.addOption(portOption); parser.process(app); if (parser.isSet(versionOption) || parser.isSet(helpOption)) { return 0; } try { test = new QDumpMIDI(); signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); if (parser.isSet(portOption)) { QString portName = parser.value(portOption); test->subscribe(portName); } else { cerr << "Port argument is mandatory" << endl; parser.showHelp(); } test->run(); } catch (const SequencerError& ex) { cerr << ERRORSTR << " Returned error was: " << ex.qstrError() << endl; } catch (...) { cerr << ERRORSTR << endl; } delete test; return 0; } drumstick-2.5.1/utils/dumpmid/PaxHeaders.27918/dumpmid.pro0000644000000000000000000000013214200302440020240 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.533324633 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/dumpmid/dumpmid.pro0000644000175000001440000000062614200302440021025 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = drumstick-dumpmid #QT += dbus CONFIG += c++11 cmdline CONFIG += qt console thread exceptions static { CONFIG += link_prl } DESTDIR = ../../build/bin INCLUDEPATH += . ../../library/include DEPENDPATH += . ../../library ../../library/include include (../../global.pri) # Input HEADERS += dumpmid.h SOURCES += dumpmid.cpp LIBS = -L$$OUT_PWD/../../build/lib \ -ldrumstick-alsa drumstick-2.5.1/utils/dumpmid/PaxHeaders.27918/dumpmid.h0000644000000000000000000000013214200302440017667 xustar0030 mtime=1644266784.837324189 30 atime=1644266785.533324633 30 ctime=1644266784.837324189 drumstick-2.5.1/utils/dumpmid/dumpmid.h0000644000175000001440000000377314200302440020462 0ustar00pedrousers00000000000000/* MIDI Sequencer C++ library Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DUMPMIDI_H_ #define DUMPMIDI_H_ /* MidiClient can deliver SequencerEvents with only * signals or posting QEvents to the QApplication loop */ #undef USE_QEVENTS //#define USE_QEVENTS /* To get timestamped events from ALSA, you need a running queue */ //#undef WANT_TIMESTAMPS #define WANT_TIMESTAMPS #include #include #include #include #include #include #include class QDumpMIDI : public QObject { Q_OBJECT public: QDumpMIDI(); virtual ~QDumpMIDI(); void dumpEvent(drumstick::ALSA::SequencerEvent* ev); void subscribe(const QString& portName); void stop(); bool stopped(); void run(); public slots: void subscription( drumstick::ALSA::MidiPort* port, drumstick::ALSA::Subscription* subs ); #ifdef USE_QEVENTS protected: virtual void customEvent( QEvent *ev ); #else void sequencerEvent( drumstick::ALSA::SequencerEvent* ev ); #endif private: drumstick::ALSA::MidiClient* m_Client; drumstick::ALSA::MidiPort* m_Port; #ifdef WANT_TIMESTAMPS drumstick::ALSA::MidiQueue* m_Queue; #endif bool m_Stopped; QReadWriteLock m_mutex; }; #endif /*DUMPMIDI_H_*/ drumstick-2.5.1/utils/PaxHeaders.27918/dumpwrk0000644000000000000000000000013214200302440016034 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.533324633 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumpwrk/0000755000175000001440000000000014200302440016672 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/dumpwrk/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020651 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.533324633 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumpwrk/CMakeLists.txt0000644000175000001440000000256714200302440021444 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(dumpwrk_SRCS dumpwrk.cpp dumpwrk.h ) set(dumpwrk_qtobject_SRCS dumpwrk.h ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(dumpwrk_moc_SRCS ${dumpwrk_qtobject_SRCS}) else() qt_wrap_cpp(dumpwrk_moc_SRCS ${dumpwrk_qtobject_SRCS}) endif() add_executable(drumstick-dumpwrk ${dumpwrk_moc_SRCS} ${dumpwrk_SRCS} ) target_link_libraries(drumstick-dumpwrk PRIVATE Drumstick::File Qt${QT_VERSION_MAJOR}::Core ) if(QT_VERSION VERSION_GREATER_EQUAL 6.0.0) target_link_libraries(drumstick-dumpwrk PRIVATE Qt6::Core5Compat) endif() install(TARGETS drumstick-dumpwrk RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) drumstick-2.5.1/utils/dumpwrk/PaxHeaders.27918/dumpwrk.pro0000644000000000000000000000013214200302440020324 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.533324633 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumpwrk/dumpwrk.pro0000644000175000001440000000076614200302440021116 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = drumstick-dumpwrk CONFIG += c++11 cmdline qt static { CONFIG += link_prl DEFINES += DRUMSTICK_STATIC } DESTDIR = ../../build/bin INCLUDEPATH += . ../../library/include include (../../global.pri) # Input HEADERS += dumpwrk.h SOURCES += dumpwrk.cpp macx:!static { QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib LIBS += -framework drumstick-file } else { LIBS = -L$$OUT_PWD/../../build/lib \ -l$$drumstickLib(drumstick-file) } drumstick-2.5.1/utils/dumpwrk/PaxHeaders.27918/dumpwrk.h0000644000000000000000000000013214200302440017753 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.533324633 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumpwrk/dumpwrk.h0000644000175000001440000000775414200302440020551 0ustar00pedrousers00000000000000/* Cakewalk WRK file dump program Copyright (C) 2006-2022, Pedro Lopez-Cabanillas Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include class QSpyWrk : public QObject { Q_OBJECT public: QSpyWrk(); void run(QString fileName); void dump(const long time, const int track, const QString& chan, const QString& event, const QString& data); void dumpStr(const long time, const QString& event, const QString& data); void dumpHex(const QByteArray& data); void dumpVar(const QString& name, bool value); void dumpVar(const QString& name, int value); void dumpVar(const QString& name, unsigned int value); void setVerbosity(bool enable); bool verbosityEnabled() const; int returnCode() const { return m_rc; } static const QString NO_CHANNEL; public slots: void unknownChunk(int type, const QByteArray& data); void fileHeader(int verh, int verl); void trackHeader(const QString& name1, const QString& name2, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop); void timeBase(int timebase); void globalVars(); void noteEvent(int track, long time, int chan, int pitch, int vol, int dur); void keyPressEvent(int track, long time, int chan, int pitch, int press); void ctlChangeEvent(int track, long time, int chan, int ctl, int value); void pitchBendEvent(int track, long time, int chan, int value); void programEvent(int track, long time, int chan, int patch); void chanPressEvent(int track, long time, int chan, int press); void sysexEvent(int track, long time, int bank); void sysexEventBank(int bank, const QString& name, bool autosend, int port, const QByteArray& data); void forcedChannel(int channel); void forcedPort(int port); void textEvent(int track, long time, int typ, const QString& data); void timeSigEvent(int bar, int num, int den); void keySigEvent(int bar, int alt); void tempoEvent(long time, int tempo); void errorHandler(const QString& errorStr); void thruMode(int mode, int port, int channel, int keyPlus, int velPlus, int localPort); void trackOffset(int track, int ofs); void trackReps(int track, int reps); void trackPatch(int track, int patch); void timeFormat(int frsec, int ofs); void comments(const QString& cmt); void variableRecord(const QString& name, const QByteArray& data); void newTrackHeader(const QString& name, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop); void softVersion(const QString& version); void trackName(int trackno, const QString& name); void stringTable(const QStringList& table); void trackVol(int track, int vol); void trackBank(int track, int bank); void segment(int track, long time, const QString& name); void chord(int track, long time, const QString& name, const QByteArray& data); void expression(int track, long time, int code, const QString& text); void hairpin(int track, long time, int code, int dur); void marker(long time, int smpte, const QString& text); private: bool m_verbosity; drumstick::File::QWrk *m_engine; int m_rc; }; drumstick-2.5.1/utils/dumpwrk/PaxHeaders.27918/dumpwrk.cpp0000644000000000000000000000013214200302440020306 xustar0030 mtime=1644266784.845324194 30 atime=1644266785.533324633 30 ctime=1644266784.845324194 drumstick-2.5.1/utils/dumpwrk/dumpwrk.cpp0000644000175000001440000004056614200302440021102 0ustar00pedrousers00000000000000/* Cakewalk WRK file dump program Copyright (C) 2006-2022, Pedro Lopez-Cabanillas Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "dumpwrk.h" #include #include #include #include #include #include #include #include #include #include #include DISABLE_WARNING_PUSH DISABLE_WARNING_DEPRECATED_DECLARATIONS #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #define right Qt::right #define left Qt::left #define endl Qt::endl #endif QTextStream cout(stdout, QIODevice::WriteOnly); QTextStream cerr(stderr, QIODevice::WriteOnly); using drumstick::File::QWrk; const QString QSpyWrk::NO_CHANNEL = QStringLiteral("--"); QSpyWrk::QSpyWrk(): m_verbosity(false), m_engine(nullptr), m_rc(0) { m_engine = new QWrk(this); m_engine->setTextCodec(QTextCodec::codecForName("Windows-1252")); connect(m_engine, &QWrk::signalWRKError, this, &QSpyWrk::errorHandler); connect(m_engine, &QWrk::signalWRKUnknownChunk, this, &QSpyWrk::unknownChunk); connect(m_engine, &QWrk::signalWRKHeader, this, &QSpyWrk::fileHeader); connect(m_engine, &QWrk::signalWRKGlobalVars, this, &QSpyWrk::globalVars); connect(m_engine, &QWrk::signalWRKTrack, this, &QSpyWrk::trackHeader); connect(m_engine, &QWrk::signalWRKTimeBase, this, &QSpyWrk::timeBase); connect(m_engine, &QWrk::signalWRKNote, this, &QSpyWrk::noteEvent); connect(m_engine, &QWrk::signalWRKKeyPress, this, &QSpyWrk::keyPressEvent); connect(m_engine, &QWrk::signalWRKCtlChange, this, &QSpyWrk::ctlChangeEvent); connect(m_engine, &QWrk::signalWRKPitchBend, this, &QSpyWrk::pitchBendEvent); connect(m_engine, &QWrk::signalWRKProgram, this, &QSpyWrk::programEvent); connect(m_engine, &QWrk::signalWRKChanPress, this, &QSpyWrk::chanPressEvent); connect(m_engine, &QWrk::signalWRKSysexEvent, this, &QSpyWrk::sysexEvent); connect(m_engine, &QWrk::signalWRKSysex, this, &QSpyWrk::sysexEventBank); connect(m_engine, &QWrk::signalWRKText, this, &QSpyWrk::textEvent); connect(m_engine, &QWrk::signalWRKTimeSig, this, &QSpyWrk::timeSigEvent); connect(m_engine, &QWrk::signalWRKKeySig, this, &QSpyWrk::keySigEvent); connect(m_engine, &QWrk::signalWRKTempo, this, &QSpyWrk::tempoEvent); connect(m_engine, &QWrk::signalWRKThru, this, &QSpyWrk::thruMode); connect(m_engine, &QWrk::signalWRKTrackOffset, this, &QSpyWrk::trackOffset); connect(m_engine, &QWrk::signalWRKTrackReps, this, &QSpyWrk::trackReps); connect(m_engine, &QWrk::signalWRKTrackPatch, this, &QSpyWrk::trackPatch); connect(m_engine, &QWrk::signalWRKTimeFormat, this, &QSpyWrk::timeFormat); connect(m_engine, &QWrk::signalWRKComments, this, &QSpyWrk::comments); connect(m_engine, &QWrk::signalWRKVariableRecord, this, &QSpyWrk::variableRecord); connect(m_engine, &QWrk::signalWRKNewTrack, this, &QSpyWrk::newTrackHeader); connect(m_engine, &QWrk::signalWRKSoftVer, this, &QSpyWrk::softVersion); connect(m_engine, &QWrk::signalWRKTrackName, this, &QSpyWrk::trackName); connect(m_engine, &QWrk::signalWRKStringTable, this, &QSpyWrk::stringTable); connect(m_engine, &QWrk::signalWRKTrackVol, this, &QSpyWrk::trackVol); connect(m_engine, &QWrk::signalWRKTrackBank, this, &QSpyWrk::trackBank); connect(m_engine, &QWrk::signalWRKSegment, this, &QSpyWrk::segment); connect(m_engine, &QWrk::signalWRKChord, this, &QSpyWrk::chord); connect(m_engine, &QWrk::signalWRKExpression, this, &QSpyWrk::expression); connect(m_engine, &QWrk::signalWRKHairpin, this, &QSpyWrk::hairpin); connect(m_engine, &QWrk::signalWRKMarker, this, &QSpyWrk::marker); cout.setRealNumberNotation(QTextStream::FixedNotation); cout.setRealNumberPrecision(4); #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) cout.setCodec("UTF-8"); #else cout.setEncoding(QStringConverter::Utf8); #endif } void QSpyWrk::dump(const long time, const int track, const QString& chan, const QString& event, const QString& data) { cout << right << qSetFieldWidth(7) << time; cout << qSetFieldWidth(0) << left << ' '; cout << qSetFieldWidth(5) << right << track; cout << qSetFieldWidth(3) << chan; cout << qSetFieldWidth(0) << left << ' '; cout << qSetFieldWidth(25) << event; cout << qSetFieldWidth(0) << ' ' << data << endl; } void QSpyWrk::dumpStr(const long time, const QString& event, const QString& data) { cout << right << qSetFieldWidth(7) << time; cout << qSetFieldWidth(6) << NO_CHANNEL; cout << qSetFieldWidth(3) << NO_CHANNEL; cout << qSetFieldWidth(0) << left << ' '; cout << qSetFieldWidth(25) << event; cout << qSetFieldWidth(0) << ' ' << data << endl; } void QSpyWrk::dumpHex(const QByteArray& data) { int i = 0, j = 0; QString s; if (m_verbosity) { while ( i < data.count() ) { s.clear(); for (j = 0; j < 16 && i < data.count(); ++j) { quint8 c = static_cast(data[i++]); s += QString(" %1").arg(c & 0xff, 2, 16, QChar('0')); } cout << qSetFieldWidth(42) << ' ' << qSetFieldWidth(0) << s << endl; } } } void QSpyWrk::dumpVar(const QString& name, int value) { cout << qSetFieldWidth(43) << ' ' << qSetFieldWidth(0) << name << " = " << value << endl; } void QSpyWrk::dumpVar(const QString& name, unsigned int value) { cout << qSetFieldWidth(43) << ' ' << qSetFieldWidth(0) << name << " = " << value << endl; } void QSpyWrk::dumpVar(const QString& name, bool value) { cout << qSetFieldWidth(43) << ' ' << qSetFieldWidth(0) << name << " = " << (value ? "true" : "false" ) << endl; } void QSpyWrk::setVerbosity(bool enabled) { m_verbosity = enabled; } bool QSpyWrk::verbosityEnabled() const { return m_verbosity; } void QSpyWrk::errorHandler(const QString& errorStr) { m_rc++; cerr << "*** Warning! " << errorStr << endl; } void QSpyWrk::fileHeader(int verh, int verl) { dumpStr(0, "WRK File Version", QString("%1.%2").arg(verh).arg(verl)); } void QSpyWrk::globalVars() { dumpStr(0, "Global Vars", QString()); if (m_verbosity) { dumpVar("Now", m_engine->getNow()); dumpVar("From", m_engine->getFrom()); dumpVar("Thru", m_engine->getThru()); dumpVar("KeySig", m_engine->getKeySig()); dumpVar("Clock", m_engine->getClock()); dumpVar("AutoSave", m_engine->getAutoSave()); dumpVar("PlayDelay", m_engine->getPlayDelay()); dumpVar("ZeroCtrls", m_engine->getZeroCtrls()); dumpVar("SendSPP", m_engine->getSendSPP()); dumpVar("SendCont", m_engine->getSendCont()); dumpVar("PatchSearch", m_engine->getPatchSearch()); dumpVar("AutoStop", m_engine->getAutoStop()); dumpVar("StopTime", m_engine->getStopTime()); dumpVar("AutoRewind", m_engine->getAutoRewind()); dumpVar("RewindTime", m_engine->getRewindTime()); dumpVar("MetroPlay", m_engine->getMetroPlay()); dumpVar("MetroRecord", m_engine->getMetroRecord()); dumpVar("MetroAccent", m_engine->getMetroAccent()); dumpVar("CountIn", m_engine->getCountIn()); dumpVar("ThruOn", m_engine->getThruOn()); dumpVar("AutoRestart", m_engine->getAutoRestart()); dumpVar("CurTempoOfs", m_engine->getCurTempoOfs()); dumpVar("TempoOfs1", m_engine->getTempoOfs1()); dumpVar("TempoOfs2", m_engine->getTempoOfs2()); dumpVar("TempoOfs3", m_engine->getTempoOfs3()); dumpVar("PunchEnabled", m_engine->getPunchEnabled()); dumpVar("PunchInTime", m_engine->getPunchInTime()); dumpVar("PunchOutTime", m_engine->getPunchOutTime()); dumpVar("EndAllTime", m_engine->getEndAllTime()); } } void QSpyWrk::trackHeader( const QString& name1, const QString& name2, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop ) { dump(0, trackno, QString::number(channel), "Track", QString("name1='%2' name2='%3'").arg(name1, name2)); if (m_verbosity) { dumpVar("pitch", pitch); dumpVar("velocity",velocity); dumpVar("port", port); dumpVar("selected", selected); dumpVar("muted", muted); dumpVar("loop", loop); } } void QSpyWrk::timeBase(int timebase) { dumpStr(0, "Ticks per Quarter Note", QString::number(timebase)); } void QSpyWrk::noteEvent(int track, long time, int chan, int pitch, int vol, int dur) { dump(time, track, QString::number(chan), "Note", QString("key=%1 vel=%2 dur=%3").arg(pitch).arg(vol).arg(dur)); } void QSpyWrk::keyPressEvent(int track, long time, int chan, int pitch, int press) { dump(time, track, QString::number(chan), "Key Pressure", QString("key=%1 press=%2").arg(pitch).arg(press)); } void QSpyWrk::ctlChangeEvent(int track, long time, int chan, int ctl, int value) { dump(time, track, QString::number(chan), "Control Change", QString("ctl=%1 val=%2").arg(ctl).arg(value)); } void QSpyWrk::pitchBendEvent(int track, long time, int chan, int value) { dump(time, track, QString::number(chan), "Pitch Bend", QString::number(value)); } void QSpyWrk::programEvent(int track, long time, int chan, int patch) { dump(time, track, QString::number(chan), "Program Change", QString::number(patch)); } void QSpyWrk::chanPressEvent(int track, long time, int chan, int press) { dump(time, track, QString::number(chan), "Channel Pressure", QString::number(press)); } void QSpyWrk::sysexEvent(int track, long time, int bank) { dump(time, track, NO_CHANNEL, "System Exclusive", QString::number(bank)); } void QSpyWrk::sysexEventBank(int bank, const QString& name, bool autosend, int port, const QByteArray& data) { dumpStr(0, "System Exclusive Bank", QString("bank=%1 name='%2' auto=%3 port=%4").arg(bank).arg(name).arg(autosend).arg(port)); dumpHex(data); } void QSpyWrk::forcedChannel(int channel) { dump(0, 0, NO_CHANNEL, "Forced channel", QString::number(channel)); } void QSpyWrk::forcedPort(int port) { dump(0, 0, NO_CHANNEL, "Forced port", QString::number(port)); } void QSpyWrk::textEvent(int track, long time, int typ, const QString& data) { dump(time, track, NO_CHANNEL, QString("Text (%1)").arg(typ), data); } void QSpyWrk::timeSigEvent(int bar, int num, int den) { dumpStr(0, "Time Signature", QString("bar=%1, %2/%3").arg(bar).arg(num).arg(den)); } void QSpyWrk::keySigEvent(int bar, int alt) { dumpStr(0, "Key Signature", QString("bar=%1, alt=%2").arg(bar).arg(alt)); } void QSpyWrk::tempoEvent(long time, int tempo) { double bpm = tempo / 100.0; dumpStr(time, "Tempo", QString::number(bpm, 'f', 2)); } void QSpyWrk::thruMode(int mode, int port, int channel, int keyPlus, int velPlus, int localPort) { dumpStr(0, "Thru Mode", QString("mode=%1 port=%2 chan=%3 key+=%4 vel+=%5 port=%6").arg(mode).arg(port).arg(channel).arg(keyPlus).arg(velPlus).arg(localPort)); } void QSpyWrk::trackOffset(int track, int ofs) { dump(0, track, NO_CHANNEL, "Track Offset", QString::number(ofs)); } void QSpyWrk::trackReps(int track, int reps) { dump(0, track, NO_CHANNEL, "Track Repetitions", QString::number(reps)); } void QSpyWrk::trackPatch(int track, int patch) { dump(0, track, NO_CHANNEL, "Track Patch", QString::number(patch)); } void QSpyWrk::timeFormat(int frsec, int ofs) { dumpStr(0, "SMPTE Time Format", QString("%1 frames/second, offset=%2").arg(frsec).arg(ofs)); } void QSpyWrk::comments(const QString& cmt) { dumpStr(0, "Comment", cmt.trimmed()); } void QSpyWrk::variableRecord(const QString& name, const QByteArray& data) { QString s = name; bool isReadable = ( name == "Title" || name == "Author" || name == "Copyright" || name == "Subtitle" || name == "Instructions" || name == "Keywords" ); if (isReadable) { s += ": "; if (m_engine->getTextCodec() == nullptr) s += QString(data); else s += m_engine->getTextCodec()->toUnicode(data); } dumpStr(0, "Variable Record", s.trimmed()); if (!isReadable) dumpHex(data); } void QSpyWrk::newTrackHeader( const QString& name, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop ) { dump(0, trackno, QString::number(channel), "Track", name); if (m_verbosity) { dumpVar("pitch", pitch); dumpVar("velocity",velocity); dumpVar("port", port); dumpVar("selected", selected); dumpVar("muted", muted); dumpVar("loop", loop); } } void QSpyWrk::softVersion(const QString& version) { dumpStr(0, "Software Version", version); } void QSpyWrk::trackName(int trackno, const QString& name) { dump(0, trackno, NO_CHANNEL, "Track Name", name); } void QSpyWrk::stringTable(const QStringList& table) { dumpStr(0, "String Table", table.join(", ")); } void QSpyWrk::trackVol(int track, int vol) { dump(0, track, NO_CHANNEL, "Track Volume", QString::number(vol)); } void QSpyWrk::trackBank(int track, int bank) { dump(0, track, NO_CHANNEL, "Track Bank", QString::number(bank)); } void QSpyWrk::segment(int track, long time, const QString& name) { dump(time, track, NO_CHANNEL, "Track Segment", name); } void QSpyWrk::chord(int track, long time, const QString& name, const QByteArray& data) { dump(time, track, NO_CHANNEL, "Chord Diagram", name); dumpHex(data); } void QSpyWrk::expression(int track, long time, int code, const QString& text) { dump(time, track, NO_CHANNEL, "Expression", QString("text=%1 code=%2").arg(text).arg(code)); } void QSpyWrk::hairpin(int track, long time, int code, int dur) { dump(time, track, NO_CHANNEL, "Hairpin", QString("code=%1, dur=%2").arg(code).arg(dur)); } void QSpyWrk::marker(long time, int smpte, const QString &text) { dumpStr(time, smpte == 0 ? "Marker" : "SMPTE Marker", text); } void QSpyWrk::unknownChunk(int type, const QByteArray& data) { QString name = QString("Unknown Chunk %1 (0x%2)").arg(type).arg(type, 2, 16, QChar('0')); dumpStr(0, name, QString("size=%2").arg(data.length())); dumpHex(data); } void QSpyWrk::run(QString fileName) { cout << "__ticks track ch event____________________ data____" << endl; m_engine->readFromFile(fileName); } int main(int argc, char *argv[]) { const QString PGM_NAME = QStringLiteral("drumstick-dumpwrk"); const QString PGM_DESCRIPTION = QStringLiteral("Drumstick command line utility for decoding WRK (Cakewalk) files"); QSpyWrk spy; QCoreApplication app(argc, argv); QCoreApplication::setApplicationName(PGM_NAME); QCoreApplication::setApplicationVersion(QStringLiteral(QT_STRINGIFY(VERSION))); QCommandLineParser parser; parser.setApplicationDescription(PGM_DESCRIPTION); auto helpOption = parser.addHelpOption(); auto versionOption = parser.addVersionOption(); QCommandLineOption verboseOption("verbose", "Verbose output."); parser.addOption(verboseOption); parser.addPositionalArgument("file", "Input WRK File Name(s).", "files..."); parser.process(app); if (parser.isSet(versionOption) || parser.isSet(helpOption)) { return 0; } if (parser.isSet(verboseOption)) { spy.setVerbosity(true); } QStringList fileNames, positionalArgs = parser.positionalArguments(); foreach(const QVariant& a, positionalArgs) { QFileInfo f(a.toString()); if (f.exists()) fileNames += f.canonicalFilePath(); else cerr << "File not found: " << a.toString() << endl; } foreach(const QString& file, fileNames) { spy.run(file); } return spy.returnCode(); } DISABLE_WARNING_POP drumstick-2.5.1/utils/PaxHeaders.27918/playsmf0000644000000000000000000000013214200302440016016 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.533324633 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/playsmf/0000755000175000001440000000000014200302440016654 5ustar00pedrousers00000000000000drumstick-2.5.1/utils/playsmf/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440020633 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.533324633 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/playsmf/CMakeLists.txt0000644000175000001440000000261314200302440021416 0ustar00pedrousers00000000000000# MIDI Sequencer C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(playsmf_SRCS playsmf.cpp playsmf.h ) set(playsmf_qtobject_SRCS playsmf.h ) if (QT_VERSION VERSION_LESS 5.15.0) qt5_wrap_cpp(playsmf_moc_SRCS ${playsmf_qtobject_SRCS}) else() qt_wrap_cpp(playsmf_moc_SRCS ${playsmf_qtobject_SRCS}) endif() add_executable(drumstick-playsmf ${playsmf_moc_SRCS} ${playsmf_SRCS} ) target_link_libraries(drumstick-playsmf PRIVATE Drumstick::ALSA Drumstick::File Qt${QT_VERSION_MAJOR}::Core ) if(QT_VERSION VERSION_GREATER_EQUAL 6.0.0) target_link_libraries(drumstick-playsmf PRIVATE Qt6::Core5Compat) endif() install(TARGETS drumstick-playsmf RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) drumstick-2.5.1/utils/playsmf/PaxHeaders.27918/playsmf.pro0000644000000000000000000000013214200302440020270 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.533324633 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/playsmf/playsmf.pro0000644000175000001440000000053114200302440021050 0ustar00pedrousers00000000000000TEMPLATE = app TARGET = drumstick-playsmf #QT += dbus CONFIG += c++11 cmdline qt thread exceptions static { CONFIG += link_prl } DESTDIR = ../../build/bin INCLUDEPATH += . ../../library/include LIBS = -L../../build/lib -ldrumstick-alsa -ldrumstick-file -lasound include (../../global.pri) # Input HEADERS += playsmf.h SOURCES += playsmf.cpp drumstick-2.5.1/utils/playsmf/PaxHeaders.27918/playsmf.cpp0000644000000000000000000000013214200302440020252 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.533324633 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/playsmf/playsmf.cpp0000644000175000001440000002610414200302440021036 0ustar00pedrousers00000000000000/* Standard MIDI File player program Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "playsmf.h" #include #include #include #include #include #include #include #include #include #include DISABLE_WARNING_PUSH DISABLE_WARNING_DEPRECATED_DECLARATIONS #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) #define right Qt::right #define left Qt::left #define endl Qt::endl #endif QTextStream cout(stdout, QIODevice::WriteOnly); QTextStream cerr(stderr, QIODevice::WriteOnly); /* ********** * * Song class * ********** */ using namespace drumstick; using namespace ALSA; using namespace File; static inline bool eventLessThan(const SequencerEvent* s1, const SequencerEvent *s2) { return s1->getTick() < s2->getTick(); } void Song::sort() { std::sort(begin(), end(), eventLessThan); } void Song::clear() { while (!isEmpty()) delete takeFirst(); } Song::~Song() { clear(); } /* ************* * * PlaySMF class * ************* */ PlaySMF::PlaySMF() : m_division(-1), m_portId(-1), m_queueId(-1), m_initialTempo(-1), m_Stopped(true) { m_Client = new MidiClient(this); m_Client->open(); m_Client->setClientName("MIDI Player"); m_Port = new MidiPort(this); m_Port->attach( m_Client ); m_Port->setPortName("MIDI Player port"); m_Port->setCapability(SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ); m_Port->setPortType(SND_SEQ_PORT_TYPE_APPLICATION); m_Queue = m_Client->createQueue(); m_queueId = m_Queue->getId(); m_portId = m_Port->getPortId(); m_engine = new QSmf(this); connect(m_engine, &QSmf::signalSMFHeader, this, &PlaySMF::headerEvent); connect(m_engine, &QSmf::signalSMFNoteOn, this, &PlaySMF::noteOnEvent); connect(m_engine, &QSmf::signalSMFNoteOff, this, &PlaySMF::noteOffEvent); connect(m_engine, &QSmf::signalSMFKeyPress, this, &PlaySMF::keyPressEvent); connect(m_engine, &QSmf::signalSMFCtlChange, this, &PlaySMF::ctlChangeEvent); connect(m_engine, &QSmf::signalSMFPitchBend, this, &PlaySMF::pitchBendEvent); connect(m_engine, &QSmf::signalSMFProgram, this, &PlaySMF::programEvent); connect(m_engine, &QSmf::signalSMFChanPress, this, &PlaySMF::chanPressEvent); connect(m_engine, &QSmf::signalSMFSysex, this, &PlaySMF::sysexEvent); connect(m_engine, &QSmf::signalSMFText, this, &PlaySMF::textEvent); connect(m_engine, &QSmf::signalSMFTempo, this, &PlaySMF::tempoEvent); connect(m_engine, &QSmf::signalSMFTimeSig, this, &PlaySMF::timeSigEvent); connect(m_engine, &QSmf::signalSMFKeySig, this, &PlaySMF::keySigEvent); connect(m_engine, &QSmf::signalSMFError, this, &PlaySMF::errorHandler); } PlaySMF::~PlaySMF() { m_Port->detach(); m_Client->close(); } void PlaySMF::subscribe(const QString& portName) { try { qDebug() << "Trying to subscribe to " << portName.toLocal8Bit().data(); m_Port->subscribeTo(portName); } catch (const SequencerError& err) { cerr << "SequencerError exception. Error code: " << err.code() << " (" << err.qstrError() << ")" << endl; cerr << "Location: " << err.location() << endl; throw; } } bool PlaySMF::stopped() { QReadLocker locker(&m_mutex); return m_Stopped; } void PlaySMF::stop() { QWriteLocker locker(&m_mutex); m_Stopped = true; m_Client->dropOutput(); } void PlaySMF::shutupSound() { int channel; for (channel = 0; channel < 16; ++channel) { ControllerEvent ev(channel, MIDI_CTL_ALL_SOUNDS_OFF, 0); ev.setSource(static_cast(m_portId)); ev.setSubscribers(); ev.setDirect(); m_Client->outputDirect(&ev); } m_Client->drainOutput(); } void PlaySMF::appendEvent(SequencerEvent* ev) { long tick = m_engine->getCurrentTime(); ev->setSource(static_cast(m_portId)); if (ev->getSequencerType() != SND_SEQ_EVENT_TEMPO) { ev->setSubscribers(); } ev->scheduleTick(m_queueId, static_cast(tick), false); m_song.append(ev); } void PlaySMF::dump(const QString& chan, const QString& event, const QString& data) { cout << right << qSetFieldWidth(7) << m_engine->getCurrentTime(); cout << qSetFieldWidth(3) << chan; cout << qSetFieldWidth(0) << left << " "; cout << qSetFieldWidth(15) << event; cout << qSetFieldWidth(0) << " " << data << endl; } void PlaySMF::dumpStr(const QString& event, const QString& data) { cout << right << qSetFieldWidth(7) << m_engine->getCurrentTime(); cout << qSetFieldWidth(3) << "--"; cout << qSetFieldWidth(0) << left << " "; cout << qSetFieldWidth(15) << event; cout << qSetFieldWidth(0) << " " << data << endl; } void PlaySMF::headerEvent(int format, int ntrks, int division) { m_division = division; dumpStr("SMF Header", QString("Format=%1, Tracks=%2, Division=%3"). arg(format).arg(ntrks).arg(division)); } void PlaySMF::noteOnEvent(int chan, int pitch, int vol) { NoteOnEvent* ev = new NoteOnEvent (chan, pitch, vol); appendEvent(ev); } void PlaySMF::noteOffEvent(int chan, int pitch, int vol) { SequencerEvent* ev = new NoteOffEvent(chan, pitch, vol); appendEvent(ev); } void PlaySMF::keyPressEvent(int chan, int pitch, int press) { SequencerEvent* ev = new KeyPressEvent (chan, pitch, press); appendEvent(ev); } void PlaySMF::ctlChangeEvent(int chan, int ctl, int value) { SequencerEvent* ev = new ControllerEvent (chan, ctl, value); appendEvent(ev); } void PlaySMF::pitchBendEvent(int chan, int value) { SequencerEvent* ev = new PitchBendEvent (chan, value); appendEvent(ev); } void PlaySMF::programEvent(int chan, int patch) { SequencerEvent* ev = new ProgramChangeEvent (chan, patch); appendEvent(ev); } void PlaySMF::chanPressEvent(int chan, int press) { SequencerEvent* ev = new ChanPressEvent (chan, press); appendEvent(ev); } void PlaySMF::sysexEvent(const QByteArray& data) { SysExEvent* ev = new SysExEvent(data); appendEvent(ev); } void PlaySMF::textEvent(int typ, const QString& data) { dumpStr(QString("Text (%1)").arg(typ), data); } void PlaySMF::timeSigEvent(int b0, int b1, int b2, int b3) { dump("--", "Time Signature", QString("%1, %2, %3, %4").arg(b0).arg(b1).arg(b2).arg(b3)); } void PlaySMF::keySigEvent(int b0, int b1) { dump("--", "Key Signature", QString("%1, %2").arg(b0).arg(b1)); } void PlaySMF::tempoEvent(int tempo) { if ( m_initialTempo < 0 ) { m_initialTempo = tempo; } TempoEvent* ev = new TempoEvent(m_queueId, tempo); appendEvent(ev); } void PlaySMF::errorHandler(const QString& errorStr) { cout << "*** Warning! " << errorStr << " at file offset " << m_engine->getFilePos() << endl; } void PlaySMF::play(QString fileName) { cout << "Reading song: " << fileName << endl; cout << "___time ch event__________ data____" << endl; m_engine->readFromFile(fileName); m_song.sort(); m_Client->setPoolOutput(100); QueueTempo firstTempo = m_Queue->getTempo(); firstTempo.setPPQ(m_division); if (m_initialTempo > 0) firstTempo.setTempo(static_cast(m_initialTempo)); m_Queue->setTempo(firstTempo); m_Client->drainOutput(); cout << "Starting playback" << endl; cout << "Press Ctrl+C to exit" << endl; try { QListIterator i(m_song); m_Stopped = false; m_Queue->start(); while (!stopped() && i.hasNext()) { //m_Client->outputDirect(i.next()); m_Client->output(i.next()); } if (stopped()) { m_Queue->clear(); shutupSound(); } else { m_Client->drainOutput(); m_Client->synchronizeOutput(); } m_Queue->stop(); } catch (const SequencerError& err) { cerr << "SequencerError exception. Error code: " << err.code() << " (" << err.qstrError() << ")" << endl; cerr << "Location: " << err.location() << endl; throw; } } static PlaySMF* player = nullptr; void signalHandler(int sig) { if (sig == SIGINT) qDebug() << "Caught a SIGINT. Exiting"; else if (sig == SIGTERM) qDebug() << "Caught a SIGTERM. Exiting"; if (player != nullptr) player->stop(); } int main(int argc, char **argv) { const QString PGM_NAME = QStringLiteral("drumstick-playsmf"); const QString PGM_DESCRIPTION = QStringLiteral("Drumstick command line MIDI file player"); const QString ERRORSTR = QStringLiteral("Fatal error from the ALSA sequencer. " "This usually happens when the kernel doesn't have ALSA support, " "or the device node (/dev/snd/seq) doesn't exists, " "or the kernel module (snd_seq) is not loaded. " "Please check your ALSA/MIDI configuration."); signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); QCoreApplication app(argc, argv); QCoreApplication::setApplicationName(PGM_NAME); QCoreApplication::setApplicationVersion(QStringLiteral(QT_STRINGIFY(VERSION))); QCommandLineParser parser; parser.setApplicationDescription(PGM_DESCRIPTION); auto helpOption = parser.addHelpOption(); auto versionOption = parser.addVersionOption(); QCommandLineOption portOption({"p","port"}, "Destination, MIDI port.", "client:port"); parser.addOption(portOption); parser.addPositionalArgument("file", "Input SMF File(s).", "files..."); parser.process(app); if (parser.isSet(versionOption) || parser.isSet(helpOption)) { return 0; } try { player = new PlaySMF(); if (parser.isSet(portOption)) { QString port = parser.value(portOption); player->subscribe(port); } else { cerr << "Port argument is missing" << endl; parser.showHelp(); } QStringList files = parser.positionalArguments(); if (files.isEmpty()) { cerr << "No input files" << endl; parser.showHelp(); } foreach(const QString& f, files) { QFileInfo file(f); if (file.exists()) player->play(file.canonicalFilePath()); } } catch (const SequencerError& ex) { cerr << ERRORSTR << " Returned error was: " << ex.qstrError() << endl; } catch (...) { cerr << ERRORSTR << endl; } delete player; return 0; } DISABLE_WARNING_POP drumstick-2.5.1/utils/playsmf/PaxHeaders.27918/playsmf.h0000644000000000000000000000013214200302440017717 xustar0030 mtime=1644266784.841324191 30 atime=1644266785.533324633 30 ctime=1644266784.841324191 drumstick-2.5.1/utils/playsmf/playsmf.h0000644000175000001440000000513514200302440020504 0ustar00pedrousers00000000000000/* Standard MIDI File player program Copyright (C) 2006-2022, Pedro Lopez-Cabanillas This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef PLAYSMF_H_ #define PLAYSMF_H_ #include #include #include #include #include #include #include #include #include class Song : public QList { public: virtual ~Song(); void sort(); void clear(); }; class PlaySMF : public QObject { Q_OBJECT public: PlaySMF(); virtual ~PlaySMF(); void play(QString fileName); bool stopped(); void stop(); void appendEvent(drumstick::ALSA::SequencerEvent* ev); void subscribe(const QString& portName); void dump(const QString& chan, const QString& event, const QString& data); void dumpStr(const QString& event, const QString& data); void shutupSound(); public slots: void headerEvent(int format, int ntrks, int division); void noteOnEvent(int chan, int pitch, int vol); void noteOffEvent(int chan, int pitch, int vol); void keyPressEvent(int chan, int pitch, int press); void ctlChangeEvent(int chan, int ctl, int value); void pitchBendEvent(int chan, int value); void programEvent(int chan, int patch); void chanPressEvent(int chan, int press); void sysexEvent(const QByteArray& data); void textEvent(int typ, const QString& data); void tempoEvent(int tempo); void timeSigEvent(int b0, int b1, int b2, int b3); void keySigEvent(int b0, int b1); void errorHandler(const QString& errorStr); private: int m_division; int m_portId; int m_queueId; int m_initialTempo; bool m_Stopped; QReadWriteLock m_mutex; Song m_song; drumstick::File::QSmf* m_engine; drumstick::ALSA::MidiClient* m_Client; drumstick::ALSA::MidiPort* m_Port; drumstick::ALSA::MidiQueue* m_Queue; }; #endif /*PLAYSMF_H_*/ drumstick-2.5.1/PaxHeaders.27918/global.pri0000644000000000000000000000013214200302440015234 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.533324633 30 ctime=1644266784.865324206 drumstick-2.5.1/global.pri0000644000175000001440000000047314200302440016021 0ustar00pedrousers00000000000000VERSION = 2.5.0 DEFINES += VERSION=$$VERSION VER_MAJ = 2 VER_MIN = 5 VER_PAT = 0 defineReplace(drumstickLib) { LIBRARY_NAME = $$1 !static:win32: LIBRARY_NAME = $$LIBRARY_NAME$$VER_MAJ return($$LIBRARY_NAME) } win32-msvc { QMAKE_CXXFLAGS += /utf-8 #/source-charset:utf-8 /execution-charset:utf-8 } drumstick-2.5.1/PaxHeaders.27918/NEWS0000644000000000000000000000013214200302440013757 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.533324633 30 ctime=1644266784.865324206 drumstick-2.5.1/NEWS0000644000175000001440000000035314200302440014541 0ustar00pedrousers00000000000000Barcelona. Thursday, January 7, 2010 Project "aseqmm" has been renamed to "drumstick" RSS newsfeed available at: https://sourceforge.net/p/drumstick/news/feed.rss Activity RSS feed: https://sourceforge.net/p/drumstick/activity/feed drumstick-2.5.1/PaxHeaders.27918/ChangeLog0000644000000000000000000000013214200302440015032 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.533324633 30 ctime=1644266784.865324206 drumstick-2.5.1/ChangeLog0000644000175000001440000003616014200302440015621 0ustar00pedrousers000000000000002022-02-07 * Release 2.5.1 2022-02-03 * Utils: fixed loading translations, program names and messages * cmake buildsystem: run qt::lupdate after building targets 2022-01-28 * Widgets: Fluidsynth soundfonts dialog, updated filters * RT: Fluidsynth backend initialization: failure report for invalid soundfonts 2022-01-27 * Avoid loading translations for English 2022-01-15 * AppStream MetaInfo added for the three GUI utilities 2021-12-16 * Bump version for the next development cycle 2021-12-12 * Fixed install: header macros.h missing when only BUILD_ALSA is selected. * Fixed linking tests when using qmake 2021-12-10 * Release 2.5.0 2021-12-07 * Documentation/deprecation of Drumstick::File functions affected by QTextCodec * Documented new build options and Qt6Core5Compat dependency for Drumstick::File * Raised macOS deployment target to 10.13 (High Sierra) 2021-12-03 * RT, VPiano: Fixed ALSA backend, enable empty input connection. * New build options: BUILD_ALSA, BUILD_FILE, BUILD_RT, BUILD_WIDGETS * Reduced usage of Qt6Core5Compat to the minimum 2021-11-08 * Widgets: changed the white keys background picture depending on the key background color * VPiano: new option to display inverted key colors 2021-10-28 * fix for ticket #37: WRK format markers are not decoded * bump version to 2.5.0 for the new development cycle 2021-10-24 * Widgets library Swedish translation updated. Thanks to Magnus Johansson. * Widgets library Czech translation updated. Thanks to Pavel Fric. * Release 2.4.1 2021-10-22 * New build option USE_QT to choose among Qt major versions (5 or 6). By default (if not set) it uses whatever is found. note: Qt6 support is still experimental. 2021-10-21 * fix for ticket #35: build with Qt 5.11 is possible again. 2021-10-20 * Vpiano: fix for a similar bug to vmpk ticket #74: crash in Linux. 2021-10-17 * Widgets: using buffer time in FluidSynth configuration dialog when the driver is pulseaudio. Default is 30 ms on both FluidSynth and Sonivox EAS. * RT FluidSynth backend: adjust-latency when using pulseaudio driver. 2021-10-10 * fixed wrong license in two documents (images): should be CC-BY-SA * removed obsolete images 2021-10-8 * revised defaults and ranges for the FluidSynth RT backend parameters, using the same values as the upstream library. * fixed validation of parameters in the FluidSynth configuration dialog. 2021-09-19 * Release 2.4.0 2021-09-11 * implementation of ticket #29: RIFF RMID file support * New utility: dumprmi 2021-08-20 * Enable by default the internal reverb on macOS DLS Synth * Avoid hardcoded font family name in vpiano 2021-08-19 * cmake buildsystem: macOS revision 2021-08-17 * widgets: new italian translation 2021-08-02 * implementation for ticket #33: versioninfo object for windows libraries 2021-08-01 * bumped version to 2.4.0 for the next development cycle * exported targets cleanups * implemented ticket #32: missing library version functions in File and RT libs 2021-07-29 * Release 2.3.1 2021-07-28 * New option: BUILD_FRAMEWORKS for macOS style frameworks instead of plain Unix libraries 2021-07-22 * Fixed SMF system exclusive event write method 2021-07-14 * Fixed WRK file processing in guiplayer utility * updated documentation * bumped version to 2.3.1 for the next development cycle 2021-06-29 * Release 2.3.0 2021-06-23 * Widgets: Fixed touch events - checked pressure capability 2021-06-14 * Fixes after ticket #31 tests 2021-06-10 * implementation of ticket #31: fallback OUT drivers for Drumstick::RT two new methods in class BackendManager: MIDIInput* findInput(QString name); MIDIOutput* findOutput(QString name); They return the requested backend or another suitable replacement. * Bump version number to 2.3.0 2021-06-09 * New options: USE_PULSEAUDIO, USE_FLUIDSYNTH, USE_NETWORK * Revised CMake buildsystem and documents 2021-06-08 * Bump version number to 2.2.2 for the next development cycle * fix incomplete ALSA RT output plugin 2021-05-31 * Release 2.2.1 2021-05-30 * experimental cmake support for building with Qt6 2021-05-29 * fixed ticket #30: RT initialization diagnostics 2021-05-17 * bump version to 2.2.1 for the next development cycle 2021-05-09 * Release 2.2.0 2021-05-04 * French and German translations updated (Thanks to Frank Kober) 2021-04-28 * removed warnings when buiding with Qt >= 5.15 2021-04-25 * Standarization: MIDI texts/lyrics encoding defaults to Latin1 2021-04-21 * Drumstick::File * new QWrk class signals with a QByteArray parameter instead of QString: * signalWRKText2 * signalWRKTrack2 * signalWRKComments2 * signalWRKNewTrack2 * signalWRKTrackName2 * signalWRKStringTable2 * signalWRKSegment2 * signalWRKExpression2 * the old signals are still emitted when a QTextCodec is assigned 2021-04-06 * Drumstick::RT * FluidSynth backend: initialization moved to a background thread * retrieve dynamically the audio driver names for using in configuration dialog 2021-04-05 * Drumstick::Widgets * added wasapi option to fluidsynth settings dialog in Windows (WIP) * removed background settings from pianokeybd, to allow better dark theme transitions 2021-04-04 * new option: BUILD_UTILS (ON by default). * documentation for BUILD_UTILS and BUILD_TESTING options. 2021-04-01 * added SCM Revision to the about box of GUI utils 2021-03-31 * release 2.1.1 2021-03-28 * New build option: BUILD_DOCS (ON by default in Unix) 2021-03-21 * fix for ticket #28: highlight color is wrong unless velocity tint is active 2021-03-20 * release 2.1.0 2021-03-11 * Russian translation update. Thanks to Sergey Basalaev 2021-03-06 * Czech translation update. Thanks to Pavel Fric 2021-02-20 * Implemented palette serialization methods. Fixed lost attributes when piano scene is rebuilt. 2021-02-19 * Implemented ticket #26: customizable texture for black and white keys 2021-02-17 * Implemented ticket #25: chromatic scale highlight palette 2021-02-10 * fix for ticket #27: error parsing a wrk file 2021-02-03 * copyright years updated * drumstick-guiplayer: fixed stop playback, removed Overture mimetype from desktop file * library headers: fix for ticket #23 2020-12-29 * release 2.0.0 2020-11-02 * documentation updated 2020-10-12 * designer plugin renamed to "drumstick-vpiano-plugin" and fixed deploy location. Central C naming revised 2020-10-08 * License upgrade: GPLv3 or later. Translations updated. 2020-09-28 * fixed SequencerOutputThread troubles finishing songs properly * enhanced guiplayer usability 2020-09-25 * plugins versioning, allowing runtime coexistence between plugins of drumstick-1 and drumstick-2 2020-09-18 * Enabled translations for drumstick-widgets and GUI utils 2020-09-16 * fixed ticket #2 Removed unmaintained OVE support 2020-09-11 * Piano palette refactoring * New unit tests for the Widgets library 2020-09-09 * fixed ticket #20 Same names for ALSA Sequencer clients of two hw USB controllers 2020-09-04 * fixed ticket #22 implementation: better rendering of note names in piano keyboard widget 2020-03-20 * New library drumstick-gui, applied to drumstick-vpiano 2020-01-02 * Synchronization of EAS Synth code with upstream AOSP repository ('android10' branch) 2019-12-30 * Code and namespaces reorganization. drumstick-alsa classes placed in the new 'drumstick::ALSA' namespace 2019-12-19 * Revised ALSA RT plugins. ALSA Client is now created only when needed 2019-12-16 * Modernization of the cmake buildsystem, producing cmake configuration scripts 2019-09-01 * release 1.1.3 2019-08-29 * release preparations 2019-07-07 * Avoid endless loops on unexpected end of input. 2019-07-06 * Fix for ticket #17: CoreMIDI.framework using wrong name-case 2019-07-06 * Generate SMFError when the parser finds unexpected end of input. Fix for ticket #16 2019-07-05 * Fix for ticket #16: bad MIDI files (drumstick-file) 2019-07-02 * Fixed macOS deprecation warnings 2019-01-29 * general cleanups and bringing back the fluidsynth backend 2019-01-28 * Fix for ticket #14: migration to full GNUInstallDirs support 2019-01-27 * modernization started of the CMake build system 2019-01-26 * Library includes reorganization 2019-01-20 * Fixed drumstick-file unit test * Tweaks on qmake build system 2019-01-15 * Custom commandline parser replaced by standard Qt5 QCommandLineParser 2019-01-13 * Removed custom commanline parser class, replaced by standard Qt5 QCommandLineParser 2019-01-08 * fixed spurious error message for ALSA input 2019-01-07 * Fixed differences between unix and windows semantics 2019-01-06 * Network backend: support for IPv6 2018-11-25 * release 1.1.2 2018-11-24 * Fix for ticket #13 - some macOS input events lost * Added some bundle metadata for macOS * Solution for ticket #8: Path for plugins hardcoded 2018-02-24 * release 1.1.1 2018-01-07 * disabled fluidsynth output driver * Fixed build on macOS < 10.11, thanks to Andreas 2017-08-14 * fixed unit test for more tolerance * release preparations 2017-08-13 * fix for ticket #11: replaced assert() by Q_ASSERT() * fix for ticket #9: removed ALSA/Linux dependency where possible. 2017-05-10 * rt: fixed pitch bend events on several output backends 2017-04-16 * fixed tab order on forms 2017-04-03 * added keywords to the desktop files. Patch by Ross Gammon 2016-09-25 * release 1.1.0 2016-09-11 * reverted audio backend for sonivox eas to pulseaudio again * rt: settings for sonivox eas and mac native synth * vpiano: dialogs for synth settings 2016-08-18 * release 1.1.0 preparation * removed four utilities, now implemented as unit tests 2016-08-17 * drumstick-rt: fix backendmanager initialization, added two new methods to retrieve backends by name * documentation updated * copyright years updated 2016-07-03 * guiplayer accepts a single file argument in the command line: mid, kar, wrk, and ove * Missing cmake scripts license, patch by Maximiliano Curia 2016-05-22 * Fix for mac osx static builds 2016-05-21 * Fix for static build using the new backends 2016-05-16 * Fix for cmake/qmake builds on mac 2016-05-15 * new backend: Apple DLS Synth 2016-05-08 * version number changed provisionally to 1.0.99 * new backend: sonivox eas synthesizer for Linux 2016-02-17 * Fix build with GCC 6, patch by Robin Lee 2016-01-30 * guiplayer: there is no need for a quit() slot. Fix for hanging notes when closing the window with the corner icon. * Use GNUInstallDirs to install arch-independent data, patch by Heiko Becker 2015-12-29 * release 1.0.2 2015-10-10 * RT library: fixed ticket #6 - MIDI input connection on Mac OSX 2015-08-20 * release 1.0.1 2015-04-26 * RT library: fixed ticket #4: ALSA Midi Input not working 2014-11-22 * RT library: fixed windows midi input 2014-08-30 * release 1.0.0 2014-08-02 * vpiano using RT library 2014-07-26 * documentation updates 2014-04-27 * RT library: OSS backend 2014-04-13 * RT library: FluidSynth backend 2014-03-30 * RT library: Windows backend 2014-02-09 * RT library: Mac OSX backend 2014-02-09 * RT library: Network and ALSA backends 2013-12-31 * Qt5 compatibility 2010-09-13 * fixed dumpove: file header text 2010-09-08 * documentation updated * release 0.5.0 2010-09-08 * remaining warnings removed * guiplayer simplified, and optimizations * compile with -fvisibility=hidden if it is available * compile always with -fexceptions * fixes in both buildsystems, cmake and qmake 2010-09-02 * Use RealtimeKit support for the MIDI input thread. 2010-08-31 * OVE file format support, by Rui Fan * guiplayer adds OVE format playback 2010-07-24 * Fixed static build support 2010-07-12 * removed PCH build option * release 0.4.1 2010-07-11 * Fixed bug in class SequencerInputThread: realtime priority must be applied in run() instead of start() to avoid changing the scheduling policy of the parent. This is a problem when running FluidSynth in systems affected by a glib-2.22 bug that has not yet been fixed. Reference: https://bugzilla.gnome.org/show_bug.cgi?id=599079 2010-07-07 * smfplayer renamed as guiplayer, with a new windows layout and supporting Cakewalk WRK files playback * release 0.4.0 2010-07-03 * subdirectory "tests" renamed as "utils". * visibility attribute for public classes. 2010-06-10 * Compile fix for 0.3.2 * release 0.3.2a 2010-06-09 * Command line arguments for all the utilities/test programs. 2010-05-28 * fix a crash in drumstick-sysinfo when a timer module is not loaded. 2010-05-13 * Man pages for the utilities/test programs. 2010-05-10 * New test program: DrumGrid 2010-04-19 * Release 0.3.1 * Allow to build drumstick-file library under Windows * New method MidiClient::parseAddress() replacing the ALSA function snd_seq_parse_address() in MidiPort::subscribeTo() and similar methods. * Fixed MidiClient::getAvailableInputs() and getAvailableOutputs() forcing to always retrieve the clients list. 2010-03-09 * Release 0.3.0 * API changes: SequencerEvent::isChannel() returns true for SND_SEQ_EVENT_NOTE QueueTimer::setId(const TimerId& id) new method overload Timer::bestGlobalTimerId() new static function getRuntimeALSALibraryVersion() new global function getRuntimeALSALibraryNumber() new global function getRuntimeALSADriverVersion() new global function getRuntimeALSADriverNumber() new global function 2010-03-02 * New class QWrk, for reading Cakewalk files 2010-02-17 * Split: drumstick-file and drumstick-alsa 2010-01-07 * Renamed to 'drumstick' and moved to a new project repository 2009-12-27 * Release 0.2.0 * API changes: SequencerInputThread::start() added a priority parameter SequencerEvent::isChannel() new static method SequencerOutputThread::stopped() method removed, converted into a signal SequencerOutputThread::start() added a priority parameter SequencerOutputThread::shutupSound() method removed SequencerOutputThread::stopRequested() method added QSmfPrivate class added QSmf::writeMetaEvent() new method overload QSmf::getTextCodec() new method QSmf::setTextCodec() new method QSmf::signalSMFVariable() signal dropped QSmf::signalSMFMetaUnregistered() signal added Subscriber::operator==() removed unimplemented operator prototype 2009-08-27 * Public release 0.1.0 2008-12-29 0.0.2pre5 * Snapshot included in kmetronome-0.9.0 and kmidimon-0.6.0 2008-11-09 0.0.2pre1 * Initial pre-release 2008-05-12 0.0.1 * Development started drumstick-2.5.1/PaxHeaders.27918/icons0000644000000000000000000000013214200302440014316 xustar0030 mtime=1644266784.857324201 30 atime=1644266785.533324633 30 ctime=1644266784.857324201 drumstick-2.5.1/icons/0000755000175000001440000000000014200302440015154 5ustar00pedrousers00000000000000drumstick-2.5.1/icons/PaxHeaders.27918/CMakeLists.txt0000644000000000000000000000013214200302440017133 xustar0030 mtime=1644266784.857324201 30 atime=1644266785.533324633 30 ctime=1644266784.857324201 drumstick-2.5.1/icons/CMakeLists.txt0000644000175000001440000000252214200302440017715 0ustar00pedrousers00000000000000# MIDI C++ Library # Copyright (C) 2005-2022 Pedro Lopez-Cabanillas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . install(FILES drumstick_16.png DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps" RENAME drumstick.png) install(FILES drumstick_32.png DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps" RENAME drumstick.png) install(FILES drumstick_48.png DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps" RENAME drumstick.png) install(FILES drumstick_64.png DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps" RENAME drumstick.png) install(FILES drumstick.svgz DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps") drumstick-2.5.1/icons/PaxHeaders.27918/drumstick.icns0000644000000000000000000000013214200302440017256 xustar0030 mtime=1644266784.857324201 30 atime=1644266785.533324633 30 ctime=1644266784.857324201 drumstick-2.5.1/icons/drumstick.icns0000644000175000001440000006646214200302440020055 0ustar00pedrousers00000000000000icnsm2is325t_YhߝoHE Sqxu^GD^eJ2]htkH1>),HS_jv}]\cdSR6;DJVamt~|=Fr^*'47FKDouG$M_T?92+4IF2]cwN Wn_RuwsoWJA;&De[$(/$"-82$/8 &1oT65 !ZXG5s8mk{j ܑ;󓐐[=Lk3eE9%1il32/mR /lp X0V70Up_,GzK TԌق6Eg~nI =n>  Y^X:* CRo{x^9C_ekpv|`< $OUZ`flqw}aC7"DJPV[agmsx~y^R'AND4 '#DDEKQW]bhnty~Rr|~zcKDc90DGLRX^ciouzhxjpxovvB'bI"3DHMSY_djpjƧi.@zt]<%?DINTZ`eZ4$Q|pZ>'",3@CBGA4)!BfWMIJoq`L:,"'1981(sko}L/6.!RJC@>?BGPZ``YL8+[]Pp|E1rmhfeRXkpuxxtk[F;<9<,SlkP6Z{}~q~{sgaD 9FH7Eq}qV58  +498+ $*/5:?-  %+06;?+  !&,17<6  "'-28: #(.39IG"5 $)4_y9 8)   .S~/bB FBl8mk ;na1  Aڂ Aވt 1Ks|fG U+˒)b} ͚i!I 'm{h-w%c2it32##BeiI A; ".I {/ #w%GI'$):,, .m0-1  -v.s3D21 ]0!1$O24 4'e OkQ*NחG -ۀ#$(>{-!%C] <$<А߄~!Mf b5ƚ0 )ۚ[ Vn}Y)KؔSͭ!   h ]Ʃ[ 6ȏ CqMQی} ! 'FD8 ADE*DcsrqqC-$[xz{X 2xtoiaXND:0&BD(FGHJKMNPQSTUWXZ[]^`abdeghjklnoqrtuwxy{|& j/3Kfk_vxy-\qkd[RI>5+#AD%FGIJLMOPQSTVWYZ[]^`acdfghjkmnpqrtuwx_4S |DEGHJKMNPQRTUWXZ[]^_abdeghikLGz~}|zwsnibZRJA91*#"ADFGIJLMNPQSTVWXZ[]^`acdegh7jW~~}{yurmg`YQIA91*$ $BDEFGIJLMOPQSTVWYZ\]^`acde@ ]~}|zxtpke_XPIA:2,&  !;DEFHIKLMOPRSUVXYZ\]_`R Y‘2:- l~}|zwtoke_XQIB;4.(#  %>D EGHIKLNOQRSUVXY[N+0q T`hn]2 !Z~}{yvsoje_XRKD=71+&"  -;DEGHJKMNOQRP@$  F m0_gmsxyY&(~|{yvsoke`ZSMGA:5/*&" !*18?DCA=:6-  !  _ ^fmswz|~t " e~~}{yvsokfa\VPJD>94/+'#  %  #%'()**)('%$"   ]emrwz|~<'v~~|{yvtplhc^YSNHC>950-)&#!!$'*,.124310.,*'%# \elrvz|~X&@y~|{ywtqnjea\WRMHC?;730-*'%#" & "#&(+.1469;=>?>=<:8630-*'$ ^$\elrvz|~"%/Pl{zxurokhd_[WRMIEA>:742/-+)('&%$$#"#$%&'(*+-0358;>ADFHIGEC@=:730,($"D[dlrwz|~@ #2AHGGFECBCEFGEB?=:864310//.-,--../013468;=@CFILOQSTSRPNKHEA>950+&"O$R\dlrvz|~ /PMJHECA@><<;:9887899:;<>?ACFHKMQSVY[]^]\ZXVROLHC?94/)$A%&HS]elrvz|~Z YZWURPNLKIHGFEDC@DDEFGIKLNPSUX[]`bdefgffeca_\YVRMIC>71,&!+AKU^fmrwz|~SBC*  _zyxwvvuttssrrqpT brssttuvwxyzz{{||}||{zyxwtrokgb]XSNJGEGK  >||{{zyyxxwv uuqG>vw xxyyz{{||}}~}}|{zxvtqmie`\WTQOQT f}|{zyj5tz{{|}}~~~}|{ywurokgc`]ZYXYZ\f~}{cE ;||}~~}|{zxvspmjgecbaabd8]qux{{bB  \~e;B~~}|zyvurpnljijk@   "F`lw xgUC+  -~ ~}|{zxvtsrpopo   $|~~}|{zxwvuthy ~}||{zyyx^4 I{~}|]2  3KL;'  (+($  !.0234678:;=>?@?@: #%&')*+-./1245689:<=>@/!"$%&()*,-.01245689;<=?@;" !"$%&()+,-/01345789;<>?@0   !#$%'()+,./0234678:;<>?@)#  "#$&'(*+,./0235679:;=>?@=$ "#%&')*+-./1235679:<=>@8' !"#%&')*,-.01245689:<=?@0 )  !"$%&()*,-/01345789;<=?@?%+  !#$%'()+,-/0134678:;<>?@9 -  !#$&'(*+,./0234678:;=>?@?-  "#$&'(*+-./1235679:;=>@-- !"#%&')*+-.01245689:<=>@: -  !"$%&()*,-.01245789;<=?@?.  !"$%'()+,-/01345789;<>?@02  !#$%'()+,./0234678:;<>?@@92  "#$&'(*+,./1235679:;=>?@:1 !"#%&')*+-./1235689:<=>@:0 !"#%&()*,-.01245689:<=?;1  !"$%&()*,-/01345789;<=: 2  !#$%'()+,-/0234678:;<: c' 4  "#$&'(*+,./0234679:;L ;Q=*  "#$&')*+-./123567*3q5"( !"#%&')*+-.01245\"  %  !"$%&()*,-.01(*~Em.$  !#$%'()+,-/l_!  !#$%'(*+ 1M  "#$&'($ !"#%< !"^   8s  N   (e  =w^ SR  C  8| t8mk@    !3)! 7 q1)! H{& V҈C K̀? ?q8[  DѨwR r }s #h 5\fK0icnV Bdrumstick-2.5.1/icons/PaxHeaders.27918/drumstick_48.png0000644000000000000000000000013214200302440017421 xustar0030 mtime=1644266784.857324201 30 atime=1644266785.537324637 30 ctime=1644266784.857324201 drumstick-2.5.1/icons/drumstick_48.png0000644000175000001440000000361614200302440020210 0ustar00pedrousers00000000000000PNG  IHDR00WsBIT|d pHYsRR$JtEXtSoftwarewww.inkscape.org< IDATh[lsf/B@&'UP0 )BJiӛBHо J-U@7*I$n&ė^o=}3^46hgR_ oe2Pn([.yy>7 ! ܿܢ@]佉k>!K>\K $2+^qP?PwKsնuU*j+Hm?0:e{,>m S=o?MOYH)xC^~q[\]MWU7&!1)_)%':U]K `ûhzcd]EAth]H.['/g@ QRTPfR /"dm˖ג6LuW˃Xl .ڑ4!}'hB|zҌ0iR1N}wC*h im[bֻ)%5ױl,ȃ} ɻVZA q=N(QUq cL2i^Q/!AQ*;( 55ȇNW('gK)ͻ1&#Q05zhorVK[Obωw7xz,Bf6F$Mlf Ā3?`2iE?xRtYyi+>Ç/# c!^SJY%/fVs8I2ik]6Kܕu%ʯ-u2zG7RYԄyoϪ1F B>PwHr#%H8@h>'Ckn^Nl, Z$/Q._ݷȢa`n6Mj4/nd-'4PMH@ N&* 1aQV@}yL>ӊᔢ;k*_m¾-MW٥˸u m_\)M9ڞyg M^13[X 6L`g<ǔKQتY`Z= `.K{9G xb"t\L`$OUz@v|B6&Dab"DY=uO<Y^$U(SI@- S,{~3=zz.^F21I:8N'[udN s[Fcl ғàаrsP IYCVMpgb],!3]SXd$T8YcjDg@!aYXQ%eylOR 8`b7kI˸Y?aWj* BrRr!I"E | fnjiﱀz|L418{YSl`u;2d'JNtBh+ihz#I| /Q5I^BpjRu4rZ([-yr˿O)IENDB`drumstick-2.5.1/icons/PaxHeaders.27918/drumstick_64.png0000644000000000000000000000013214200302440017417 xustar0030 mtime=1644266784.857324201 30 atime=1644266785.537324637 30 ctime=1644266784.857324201 drumstick-2.5.1/icons/drumstick_64.png0000644000175000001440000000532214200302440020202 0ustar00pedrousers00000000000000PNG  IHDR@@iqsBIT|d pHYsnnУhtEXtSoftwarewww.inkscape.org< OIDATxkpUgw+٤I)i -Bb,-**2LFȀ-|((*:AGALVQZH%mڐ6iڼwͦXgݽ_lh~+[e -Vo~<[b !ld)EO>">ߏP1\ Qlc*'o 1^k:*/6hʫ"rMhr0>=Hdu %[`&. pͺ2<7\em}d͖ -1t]1t93/LnͩDY Bhg; >R~ϺX\U꺆;v h󝆦مf_| IKH; Ӱa}λyϘu+ 0l8^dϱ-G?3[Cr X)쇀2&ۯ0G]hE5G{RYOk 1ģ$h] NPy@(4YR ô0u C, Ӳ0, 0, ˲0M C,LS}l!CW^mCfOsd3l crt*1;*} mAHX- ]mcϙδ0G~QFʹ1]:V$[XA먦abDI0ccb#$eA2arR{C@vR+xּŝ#Ҧga{*J9ձ9ǁ~8QΰXJ.쿀(cU\@5qo l^t Mۚ!Au?馛;).a˨c`/|%jgyf+Y ='9$JGU@\vkvK'<'oI%w:&H`wL;ݱr$C]CCXxR$y 27VrUj9" S& $ ag3~%%V6;3I2T 052pM3e1n~3ڿ8]S}Q0h'3Ktp'«j(cfWF "`^{W@me.+FyDq7((#B=h;B5/gϐif<+0g˓INTb髇ҋr]\ds/`-FrU@9 s4|Ύ9 )ha]%|rA&w?T)S$;O$Y PYKŬinbuiX4K9r$1qq%{`bV4]*,Y6Ix`>ez (sh.E%`Z` !4&%IZ i2HԩFDŽRQ²,_. 뉄C3 zC.zGJiz z\L&'ilot B•}VlwnXPlF6 [X1fb&#; 0˶ =N3˩&BQHZѫ?2-V3L49ÀogbrhI#ig2{ tV^q묛Bp \E5PKr$ALHXa93=( ))茕qk,ɞ/}Iu&Lw,r)ĹlN\|Z~&>sU^-n@=k!3AE1=a.m/ɇZ覃M͐R:krei`,2={y{W^&.!N϶(f E7 sAKzίƜB !:A'2֍Sg(QZŽuU8E'2brqZȲHY\ :L0HVpe~ &iZH.2T],ޢB&B~;U:^'k/G!WI5WzN N/b< >6e4-pL'r"{ ڻ:ht vz4ѷP\Okɒ`dx\]d^RŝӀd$& >.4D B¢0eVa,`ζxE4[XEe40q#f^@BPǭAҌ^~ p.˥߷9Ԙ#~<[2oy~+[e -[WPWIENDB`drumstick-2.5.1/icons/PaxHeaders.27918/drumstick.svgz0000644000000000000000000000013214200302440017313 xustar0030 mtime=1644266784.857324201 30 atime=1644266785.537324637 30 ctime=1644266784.857324201 drumstick-2.5.1/icons/drumstick.svgz0000644000175000001440000000346114200302440020100 0ustar00pedrousers00000000000000Xێ7}W_<@"" 66X`y4h$疯a-&C6A0F:,u9uCմv3ύyVmnz?s͢\o7dYk7 _h#b-?Y~i+/ٚ_Ys G@Zbg6U7iqբ[9FyvYjwMNx, xl}D 4d TDr:+Q&-6rޣ~Tw^X}jM ٻweOB D1H$_YCIOphqn3 Tnq31[UcR:zz0Rl4"Y,L?]d45/fX>d:e ( '1+E"$lnDfm)=ȋ8ϦE v " )!ѶDŽ3E2b2q*x5!hb[Tk_tƹ"XgpQ(g" i7,0@h1BTL"r H@w98*4lZf0@5D2L`FmaHoF+K\Puq*N,TK{ JwB9T]Gd hR$)DRkTOL.Bt:Iڣг" AQ//8 q I2%](GN\_[j ߥ/üh?Wi59|?w5fƏ=bfO?Z̎Cm5tFpuQ b0A z=l} W8Ϝ>2%BO׋(&,i &yd}IOvGdNrDw$IXG; [0uxeؠYPON;%A}4.+xǹDM'q`D)w 2B2#11r?an ?b0F!Zx09"b/mSwF"@*D'OH:gq|)8a|cA9h.NK}mϑrPhLW[m4l_~ǽ(aS¡8N87t_Q7ꏖtNIGK6\g羉7qĹ7R.zqnK4þ\_կ|f{I?L߿sdrumstick-2.5.1/icons/PaxHeaders.27918/drumstick_32.png0000644000000000000000000000013214200302440017412 xustar0030 mtime=1644266784.857324201 30 atime=1644266785.537324637 30 ctime=1644266784.857324201 drumstick-2.5.1/icons/drumstick_32.png0000644000175000001440000000226214200302440020175 0ustar00pedrousers00000000000000PNG  IHDR szzsBIT|d pHYs77DtEXtSoftwarewww.inkscape.org</IDATX[lTEsvݶ.`[JTij"i,`4I|"!&ԄhbH0LD[Bl"`n/6>`Ce\}}sRlڜz?o CW殸і8H /Uc*O/SLbZ6.1mӒ,ۘvޜR`ʲ/w?]~^ԉ7(L$0#$HpR)5qSjUS =YUrsxFir_V B^gsbE ͪ4 8Y36Mf) CfC1 A1Rx C]čczh\E3X[tIg˶XS1m +`S)DJ$8[54װy׻_:" 4* ,)ow>(Zju|= q4Ymxsld[RI@93.*'$#!!!!"#$'*.39?CEEB=82+$'!yL ju|O"9R~{wqi_TI>5,%    %*.00.*&"AMWEkv|p"#1~|wpg\OB6+"+9G(d7ACBA?@A=)] A*  #1.>KRoIkvtF @~|xqgZL=0$%%YADDDDDDDDEHK N QTVYV 4k&"4AEWft&B2I;+,u}zsi\L<-  21yDDDDDDDDDEGJ M PSVY\_ad-0wDDDDDDDDDDGJM PSUX[^ad!g#j#d[pALV> nGgWD2 #;DDDDDDDDDFIL O RUX[]`c f#i&l(o+r0Raw&L`n`N:$4ADDDDDDDDFIL O QTWZ]`c f"h%k(n*q-t0w0s\pRjm2UBK C'AYVv9*vk[G2 BDDDDDDDEHK N QTWZ\_be"h%k'n*q-s/v2y5|7@[g}<]Q!P, X quup)L6VorHc` ]{qm[GhWB&-kDDDDDDEHK M PSVY\_be!g$j'm)p,s/v2y4|7~:; 8U+T:Qjxy{{|{{zxt|~?. \!3>/DDDDDDGJM PSVY[^ad!g$j&m)p,r.u1x4{6~9<>9Jhuy{}}~~~~~~~~w9@ .h 4DDDDGJL O RUX[^ac f#i&l(o+r.u1x3{6}9;>==Hjn{}~~pX1)H ADDFIL O RUWZ]`c f#i%l(o+q-t0w3z5}8;>?6v==mD0DP\P?70'l 3!< CFHK N QTWZ]`be"h%k'n*q-t0w2y5|8:=??'\ G#tOw) . @K N QSVY\_be"h$k'm*p,s/v2y5|7:=??=B`J 3 > ?$U PSVY\^ad!g$j&m)p,s/v1x4{7~9??7s1Z W  &=T`c f#i%l(o+r.t0w3z6}8;>??<@w 1  5M"h%k(n*q-t0w3z5}8;=??1g6f 5 !\ $J=|)j/v2y5|7:=9z/e D&J S  "(~ ?+Q4c5e,Q: %n=  ???(0` '5HSC2m)in/+-=??<*DJH~{xuo4$2`{|fI9O /_}~~om~}ztmfd\i Xzywusra9 svxz{|}}|zwpfZPLE9 >\olheb`__\]fjnruvvtpj`RC63<JC>9* $3BS,[UPKGECDEHMSY_dggc]UI;, % ,?;$=0 ?Znz~I3%n;BGNLHB??83.+(''),06=EKOOJC;0%.$_uNmy~00v{ul_QC7,$  ")/33/*$P^j(T5my~g'h(sg|uj[I8**D$U,m;CCAAC@.e%I-  (:6JZcvN"ngD&]"<Cr}wkZF2"?4DDDDDDDHL PTX[_>&(l{yhTJD6K8)DGK OSWZ^b f#j'n+q.u2y6}9=?*dWk,Kl"y]* '+J N RVZ]ae#i&m*q.u1x5|8?9zAz 0K   6uB#h(o,r/v3z6~:>?.bAz 7b !B?BGPZ``YL8 +F[^B]XPp|EJoq`L:,"  '1981(bsBkYo}L$+Q|pZ>'"E,g3~@CBG A 4n)I !.B=Sfn~/W>MI@zt]< %T?DDDDI NTZ`e8Z)46'bI"3zDDDDH MSY_d$j)p4j_y9iK.UDc90pDDDGL RX^c#i(o.u3z9IhGx_"j,pxo5vGvB '#0DDEK QW]b"h'n-t2y8:~RUr|~zcK 1"VDJ PV[a!g&m,s1x7~<6y ^7R'KAsND|4fG $X OUZ` f%l+q0w6};?+a C07t AC_e$k*p/v5|:?-`DGJMPSVY[^adgjmprux{~9huy{}}~w9 GhWB&-DEHKMPSVY\_begjmpsvy|~8TQjxy{{|{{zxt|~?*vk[G2BDEHKNQTWZ\_behknqsvy|[Ƹ}]PXquupLoc]{q`n`N:$ADFILOQTWZ]`cfhknqtwspjUKCYv9GgWD2 ;DFILORUX[]`cfilorRw&#Aj|wm`P>-0 DGJMPSUX[^adgjdp L,u}zsi\L<- 1DEGJMPSVY\_ad5,%  %*.00.*&"MEkv|p"4Ymxsld[RI@93.*'$#!"#$'*.39?CEEB=82+$'Lju|O',+('%!EHC?<97656794* ,ĉ>Zju|= ^\XUROMLKKLLNORUY]bfijjhd`YQG;0&!,22J\kv|}A ,oligeca`abdgjmpsutrnibYMA7006BQ`aV5#5xvusrqpoh8+qrsuwxz{||{zwtog^SJCBF'"w|{{zye1hyz{{|}~|zwrkc\WUX&`y|wX8(+]}~~oW{~|yuokgfh"$379<<3$ h~}zxusrI0Gq~|tI)2'.(8 4-*  & )/257:=9/ $"%(*-0358;=??1 ! #%(+.0368;>??< !#&)+.1469<>??7 !$&),/1479<?- "$'*,/257:=??= "%'*-0258:=??'   #%(+-0358;>?6   #&(+.1369;>=  !$&),.1469<>  !$'),/247:; + "%'*-/257@go*A)y)ow ( 2/-)&0 2 8 4-  * "~n= &\S $  ΐ ! &ہ  #W  ?jW .ګ>!<w))H˺l3  .h*̍  \.@ [1.3m1n/L 0> 1p- 1Ɋ#494q3"5q*  ))c  &Ӧ" Ȭ~Bכ1 ׷n *  I2GԿi, 0^ 2t#8 00drumstick_48.png!? "     %$#0000 "Bw{\6z7=z0yd+) "/ ~D +묱iK!W㭲g;gyJ򮲷؎6ڕ  ?󫯴̂(QN *DUmeI- 6c"   j5$ ;0% "# 'G "!l{yhTJD6*+5DEILPTX\`cgkosw{~zBpy{}~~~l;!`\A DEIMQUY\`dhlptw{Kg[lyzo^r}:;saH*&DFJNRVY]aeimptx|yÒpaZglzm?0eS9!CDGKORVZ^bfimqa<*Nszp_I2?DHKOSW[_bfjm "Cr}wkZF2"4DHLPTX[_>&LpJ)&(g|uj[I8*$,;CCAAC@.%:ZNngD&0v{ul_QC7,$")/33/*$^Tmy~g'%;BGNLHB??83.+(''),06=EKOOJC;0%.uNmy~0,[UPKGECDEHMSY_dggc]UI;,%?=?Znz~I\olheb`__\]fjnruvvtpj`RC639* Xzywusra9 svxz{|}}|zwpfZPLE2`{|fI9/_}~~om~}ztmfd\-=??<*H~{xuo4#5HSC2'G " #)%" #(,/36:>?. !%),047;>?9 "&)-148;??1 #&*.158Ҫ 9ԩO i )in/+DJ$#'Ὶm' G drumstick_32.png!? "     %$#? [ s/mR/lp X0 V70Up쭴_,GzK TԌ6Eg~nI =n>  Y^X :*CRo{x^9C_ekpv|`< $OUZ`flqw}aC7 "DJPV[agmsx~y^R'AND4 '#DDEKQW]bhnty~Rr|~zcKDc90DGLRX^ciouzhxjpxovvB'bI"3DHMSY_djpjƧi.@zt]<%?DINTZ`eZ4$Q|pZ>'",3@CBGA4)!BfWMIJoq`L:,"'1981(sko}L/6.!RJC@>?BGPZ``YL8+[]Pp|E1rmhfeRXkpuxxtk[F;<9<,SlkP6Z{}~q~{sgaD 9FH7Eq}qV58  +498+$*/5:?-  %+06;?+  !&,17<6  "'-28: #(.39IG"5  $)4_y9  8)   .S~/bB FB  ;na1  Aڂ Aވ t 1 Ks|fG U+˒)b}  ͚i!I  'm{h-w%c2drumstick_16.png!? "     %$#  : R@t_YhߝoHE Sqxu^G A@D^eJ2]htkH1),HS_jv}]\cdSR6;DJVamt~|=Fr^*'47FKDouG$M_T?92+4IF2]cwNWn_RuwsoWJA;&De[$A@(/$"-82$/8&1oT65!ZX G5 A@{j ܑ;󓐐[ =L k3 eE9%1Adrumstick-2.5.1/icons/PaxHeaders.27918/drumstick_16.png0000644000000000000000000000013214200302440017414 xustar0030 mtime=1644266784.857324201 30 atime=1644266785.537324637 30 ctime=1644266784.857324201 drumstick-2.5.1/icons/drumstick_16.png0000644000175000001440000000103614200302440020175 0ustar00pedrousers00000000000000PNG  IHDRasBIT|d pHYsNtEXtSoftwarewww.inkscape.org<IDAT8Kﳭ{׻" H/bD!(b)LA֭i%:B)"QT(ba(fcctק"?DU$  "rǝuΝ>bqJ|MQUD|b 4,쨅mY彅 lRgwQZެVZ ˛t9>$#@:뗸8pNPcG#Hm#esG':AY#S]+nyKEWnTӞhR7VJ d2[᚜h G3'pA\>MWȆ ;ܕ?("zIQ-֙a3\&QoASZD$D+ȑ( x+~,TRHIENDB`drumstick-2.5.1/PaxHeaders.27918/TODO0000644000000000000000000000013214200302440013750 xustar0030 mtime=1644266784.865324206 30 atime=1644266785.537324637 30 ctime=1644266784.865324206 drumstick-2.5.1/TODO0000644000175000001440000000066214200302440014535 0ustar00pedrousers00000000000000Functions from ALSA library reported by chkcoverage. The following functions won't be used in drumstick. MISC (event filter) snd_seq_change_bit snd_seq_get_bit snd_seq_set_bit snd_seq_unset_bit CLIENT - private functions snd_seq_hw_open snd_seq_hw_ops snd_seq_create_event snd_seq_event_types TIMER - private functions snd_timer_async snd_timer_name snd_timer_hw_open snd_timer_nonblock snd_timer_query_hw_open snd_timer_type