Merged the differential pair router & length tuning tool.
This commit is contained in:
commit
0dd9efd9db
|
@ -569,6 +569,12 @@ set( BMAPS_BIG
|
||||||
wizard_add_fplib_icon
|
wizard_add_fplib_icon
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set( BMAPS_OTHER
|
||||||
|
tune_diff_pair_length_legend
|
||||||
|
tune_diff_pair_skew_legend
|
||||||
|
tune_single_track_length_legend
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# @todo keep these in sync with .bzrignore
|
# @todo keep these in sync with .bzrignore
|
||||||
set( TMP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tmp" )
|
set( TMP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tmp" )
|
||||||
|
@ -742,5 +748,10 @@ foreach( bmn ${BMAPS_BIG} )
|
||||||
list( APPEND CPP_LIST cpp_48/${bmn}.cpp )
|
list( APPEND CPP_LIST cpp_48/${bmn}.cpp )
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
foreach( bmn ${BMAPS_OTHER} )
|
||||||
|
#message( "library add cpp_other/${bmn}.cpp" )
|
||||||
|
list( APPEND CPP_LIST cpp_other/${bmn}.cpp )
|
||||||
|
endforeach()
|
||||||
|
|
||||||
#add_library( bitmaps SHARED ${CPP_LIST} )
|
#add_library( bitmaps SHARED ${CPP_LIST} )
|
||||||
add_library( bitmaps STATIC ${CPP_LIST} )
|
add_library( bitmaps STATIC ${CPP_LIST} )
|
||||||
|
|
|
@ -0,0 +1,871 @@
|
||||||
|
|
||||||
|
/* Do not modify this file, it was automatically generated by the
|
||||||
|
* PNG2cpp CMake script, using a *.png file as input.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bitmaps.h>
|
||||||
|
|
||||||
|
static const unsigned char png[] = {
|
||||||
|
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
|
||||||
|
0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0xbd, 0x08, 0x02, 0x00, 0x00, 0x01, 0x62, 0xd4, 0xc7,
|
||||||
|
0x28, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x1e, 0xc2, 0x00, 0x00, 0x1e,
|
||||||
|
0xc2, 0x01, 0x6e, 0xd0, 0x75, 0x3e, 0x00, 0x00, 0x00, 0x09, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f,
|
||||||
|
0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x89, 0x2a, 0x8d, 0x06, 0x00, 0x00, 0x20, 0x00, 0x49,
|
||||||
|
0x44, 0x41, 0x54, 0x78, 0x9c, 0xec, 0x5d, 0x89, 0x5f, 0x13, 0x47, 0xdf, 0xf7, 0xbf, 0x78, 0x9f,
|
||||||
|
0xb7, 0x87, 0x56, 0x6b, 0xa5, 0x9e, 0xd5, 0x5a, 0xab, 0x4f, 0xb5, 0x6a, 0xd5, 0xbe, 0xad, 0x3e,
|
||||||
|
0x56, 0xad, 0xad, 0x55, 0x6b, 0xb5, 0x7d, 0xb4, 0x15, 0x10, 0xf0, 0x40, 0x0e, 0x45, 0xee, 0x53,
|
||||||
|
0xb9, 0x54, 0x3c, 0x50, 0xf1, 0x00, 0xc5, 0x03, 0x39, 0xaa, 0x56, 0x2e, 0x41, 0x45, 0x2b, 0x2a,
|
||||||
|
0x2a, 0xa2, 0x45, 0x41, 0x39, 0xc2, 0x4d, 0x20, 0x1c, 0xe1, 0x0a, 0x10, 0x92, 0x90, 0x77, 0xc2,
|
||||||
|
0x84, 0xc9, 0x64, 0xef, 0xdd, 0x84, 0x24, 0x46, 0xbe, 0x9f, 0xf9, 0x2c, 0xcb, 0xec, 0xec, 0x6f,
|
||||||
|
0xbe, 0xfb, 0xcd, 0xec, 0xec, 0xdc, 0x33, 0x42, 0x6d, 0x0c, 0x54, 0x36, 0xc9, 0xe8, 0x2e, 0x8d,
|
||||||
|
0x80, 0x7f, 0x9a, 0x9b, 0x9b, 0x04, 0xd8, 0xf5, 0x89, 0x7b, 0xba, 0xd9, 0xe3, 0xaf, 0x47, 0x65,
|
||||||
|
0xad, 0x5d, 0xbd, 0x0a, 0x70, 0x02, 0x1c, 0x6d, 0x04, 0x02, 0x10, 0x79, 0xf5, 0xd5, 0x9e, 0x73,
|
||||||
|
0xff, 0x10, 0x3c, 0xc9, 0x71, 0x08, 0x8f, 0x00, 0xda, 0x2a, 0xf9, 0xe8, 0xfd, 0xca, 0x65, 0xdf,
|
||||||
|
0x34, 0x1f, 0x3f, 0x04, 0x4e, 0xc0, 0xbf, 0xee, 0x31, 0x8f, 0x8d, 0x16, 0x81, 0x63, 0x58, 0x0e,
|
||||||
|
0x8c, 0x00, 0x1c, 0x3b, 0x3a, 0x3a, 0xfa, 0x15, 0x0a, 0x69, 0x72, 0x02, 0x38, 0x77, 0x39, 0x94,
|
||||||
|
0x6b, 0x9c, 0x08, 0xbc, 0xe3, 0x0a, 0xc0, 0xb1, 0x6a, 0xf5, 0x0a, 0xe4, 0xd3, 0x18, 0xe2, 0x07,
|
||||||
|
0x8e, 0xf6, 0x81, 0x59, 0xb4, 0x11, 0xf4, 0xf7, 0xf7, 0x73, 0x8f, 0xc0, 0x4b, 0x40, 0x04, 0x32,
|
||||||
|
0x99, 0x36, 0xb5, 0x25, 0x27, 0x5e, 0xae, 0xad, 0xad, 0x61, 0x8e, 0xc0, 0x3b, 0xee, 0xe9, 0x40,
|
||||||
|
0x04, 0xcb, 0x79, 0x44, 0xc0, 0x0b, 0x14, 0x11, 0xec, 0x1d, 0xb2, 0x08, 0xe6, 0xcd, 0x9e, 0x65,
|
||||||
|
0xfc, 0x08, 0xbc, 0x60, 0x04, 0x3f, 0x2d, 0x1f, 0xf5, 0xce, 0xff, 0x00, 0x07, 0xce, 0x2b, 0x16,
|
||||||
|
0x7f, 0xa5, 0x26, 0xbd, 0x0a, 0x9a, 0x08, 0x36, 0xfd, 0xba, 0x1e, 0x86, 0x80, 0xb0, 0xf3, 0xcd,
|
||||||
|
0x80, 0x6e, 0x4b, 0x60, 0x56, 0x5e, 0x69, 0x2b, 0x6b, 0x04, 0xe0, 0x08, 0x6f, 0x87, 0x49, 0x36,
|
||||||
|
0xf0, 0xc2, 0x73, 0x10, 0x87, 0xad, 0x57, 0x9a, 0xad, 0x77, 0x9a, 0x6b, 0xf4, 0x43, 0x96, 0x27,
|
||||||
|
0x60, 0xc8, 0x03, 0xbc, 0x62, 0x61, 0x04, 0xcb, 0xc0, 0x31, 0x24, 0xd0, 0x1f, 0x1c, 0x95, 0xb2,
|
||||||
|
0xae, 0xf2, 0x59, 0x53, 0x09, 0xc1, 0xb4, 0x11, 0xd8, 0xfe, 0xbe, 0x11, 0x79, 0xd5, 0xbb, 0x38,
|
||||||
|
0xd5, 0xbb, 0x6c, 0xad, 0x77, 0xdd, 0xd6, 0x18, 0xe2, 0x8b, 0x3c, 0xc9, 0x71, 0xe0, 0x11, 0x20,
|
||||||
|
0x28, 0x9a, 0x9b, 0xc0, 0x73, 0x94, 0xcf, 0xf9, 0xac, 0xc1, 0x67, 0x97, 0xd8, 0xdb, 0xbd, 0x21,
|
||||||
|
0xc0, 0x93, 0xe5, 0x09, 0x6a, 0xfe, 0xfb, 0x33, 0x7c, 0x70, 0x4d, 0x1c, 0x9e, 0xa9, 0xac, 0x11,
|
||||||
|
0x90, 0xc1, 0xe9, 0x47, 0x86, 0x71, 0x10, 0x1e, 0xc2, 0x98, 0x11, 0x88, 0xbe, 0xfa, 0x37, 0x38,
|
||||||
|
0xb6, 0x74, 0xca, 0xab, 0x9b, 0xbb, 0x87, 0x24, 0x02, 0x80, 0xe6, 0xe3, 0x87, 0xc1, 0xd1, 0xe5,
|
||||||
|
0xf0, 0x7d, 0x62, 0x04, 0xab, 0xbe, 0x13, 0x12, 0xc1, 0x94, 0x09, 0x36, 0x04, 0x1f, 0x49, 0x78,
|
||||||
|
0x30, 0x38, 0x3a, 0xee, 0xbb, 0x6d, 0x9c, 0x08, 0xc8, 0x90, 0x84, 0x07, 0x81, 0xa3, 0x03, 0x39,
|
||||||
|
0x02, 0x63, 0x49, 0x44, 0xf8, 0x9d, 0xe1, 0x09, 0xc8, 0x7d, 0xbb, 0x72, 0xef, 0x18, 0x33, 0x02,
|
||||||
|
0x68, 0x1a, 0xb8, 0x6b, 0x4f, 0xc4, 0xb8, 0x27, 0x7b, 0x04, 0x78, 0x56, 0xc1, 0x1a, 0x07, 0xfa,
|
||||||
|
0x57, 0x2e, 0x2a, 0x63, 0x8f, 0xa0, 0x42, 0x24, 0x4a, 0x4f, 0x4b, 0xe3, 0xe8, 0x92, 0x76, 0x6e,
|
||||||
|
0x4b, 0xdc, 0xe1, 0x04, 0x1c, 0x17, 0xee, 0x7a, 0x4f, 0x60, 0x08, 0x8a, 0xeb, 0x3a, 0x98, 0xac,
|
||||||
|
0x73, 0x11, 0x87, 0x12, 0xe0, 0x97, 0xd8, 0x1a, 0x79, 0x47, 0xd5, 0xdf, 0x7f, 0x24, 0xad, 0x14,
|
||||||
|
0x9c, 0x93, 0x3f, 0xb7, 0x86, 0x16, 0x58, 0x98, 0x7d, 0x04, 0x5a, 0x0f, 0x4a, 0x2a, 0x82, 0x27,
|
||||||
|
0xe0, 0x37, 0xe8, 0xca, 0xcb, 0x05, 0xc7, 0x96, 0x53, 0xd1, 0xe4, 0x08, 0x04, 0x5a, 0x47, 0x25,
|
||||||
|
0x2d, 0x70, 0xf4, 0xf5, 0xf2, 0x54, 0xd3, 0x64, 0x82, 0x46, 0xb0, 0x0e, 0x31, 0x54, 0xd6, 0xe1,
|
||||||
|
0xc7, 0x8b, 0xc5, 0xfa, 0x98, 0xf7, 0xdf, 0xf9, 0x71, 0x05, 0x4b, 0x26, 0x45, 0x69, 0x1d, 0xe2,
|
||||||
|
0xcd, 0x54, 0x66, 0xc8, 0xad, 0xcf, 0x9e, 0xf9, 0x19, 0xad, 0x75, 0xca, 0x32, 0x0f, 0x70, 0xbe,
|
||||||
|
0xf1, 0xcf, 0xb8, 0x58, 0x5f, 0xb7, 0xe6, 0x27, 0x70, 0x94, 0x26, 0xc4, 0x2b, 0x7b, 0xba, 0xe1,
|
||||||
|
0x25, 0xf0, 0xf5, 0x07, 0x65, 0x1e, 0xe0, 0x34, 0xd6, 0xb3, 0xb3, 0x6e, 0xd0, 0x59, 0xd9, 0x7d,
|
||||||
|
0xea, 0x09, 0x65, 0x81, 0x87, 0xac, 0x0c, 0xf9, 0x5f, 0x0a, 0xee, 0xf5, 0x3b, 0x1d, 0x35, 0x05,
|
||||||
|
0x1e, 0x57, 0x4d, 0x81, 0xa7, 0xfb, 0x59, 0x3e, 0x6e, 0x8b, 0xd5, 0x3a, 0xf4, 0x01, 0xae, 0xde,
|
||||||
|
0x7d, 0x07, 0x2c, 0xf0, 0x30, 0xe9, 0xae, 0xea, 0xed, 0x05, 0x41, 0x3b, 0x6f, 0x67, 0x91, 0x23,
|
||||||
|
0xa0, 0xb3, 0x4e, 0xc1, 0x9d, 0x19, 0xba, 0xcf, 0xd3, 0x9e, 0xeb, 0xc6, 0xb7, 0xae, 0xa6, 0x4a,
|
||||||
|
0x6d, 0x42, 0xac, 0x47, 0x1f, 0x39, 0x3c, 0x54, 0xd6, 0xed, 0xff, 0xd8, 0x84, 0xce, 0x93, 0x93,
|
||||||
|
0x12, 0x8d, 0xcf, 0x9d, 0x0e, 0xa6, 0xb0, 0x1e, 0x98, 0x58, 0x94, 0x74, 0xbf, 0xc6, 0xf8, 0xd6,
|
||||||
|
0x01, 0xca, 0x66, 0x4c, 0x01, 0x47, 0xb7, 0xa8, 0x7b, 0x78, 0x85, 0xa2, 0x8c, 0x54, 0x5f, 0xa0,
|
||||||
|
0xb0, 0xce, 0xb1, 0x48, 0x53, 0xbd, 0x76, 0x25, 0xfa, 0x57, 0xd9, 0xd9, 0xc1, 0xa9, 0xcc, 0xc4,
|
||||||
|
0xbd, 0x3c, 0x93, 0x9e, 0x7a, 0x1d, 0x95, 0x67, 0x24, 0x61, 0x81, 0xac, 0xa6, 0x35, 0xd6, 0x8b,
|
||||||
|
0x8b, 0x8a, 0xfe, 0x4c, 0x49, 0x36, 0x97, 0x0b, 0x8d, 0x8c, 0x81, 0x0e, 0x0a, 0x0e, 0x9d, 0xff,
|
||||||
|
0xc5, 0x42, 0x2e, 0xd4, 0xd5, 0xf8, 0xef, 0x8a, 0xaa, 0xa8, 0x26, 0x80, 0x83, 0x77, 0x2a, 0x60,
|
||||||
|
0xe9, 0x10, 0x92, 0x4d, 0x79, 0x55, 0xa9, 0xea, 0x87, 0x8f, 0x91, 0x2f, 0x92, 0x32, 0xdb, 0x31,
|
||||||
|
0x42, 0x59, 0x92, 0x2f, 0x08, 0x15, 0x65, 0xd1, 0xc2, 0x39, 0x30, 0xef, 0x86, 0xae, 0xed, 0x5a,
|
||||||
|
0x32, 0x1e, 0x12, 0x7c, 0x86, 0x18, 0x4c, 0x99, 0x9a, 0x3d, 0x4e, 0xbd, 0xc1, 0xdf, 0x13, 0xd0,
|
||||||
|
0x45, 0x5f, 0x2a, 0x08, 0xf8, 0x0c, 0x78, 0xf8, 0x33, 0x37, 0x2b, 0xe8, 0xac, 0x99, 0x81, 0x3d,
|
||||||
|
0x6c, 0xd2, 0x52, 0x0f, 0x10, 0x85, 0x6d, 0x1e, 0x6a, 0xfd, 0x7c, 0x03, 0xf8, 0x37, 0xee, 0xf5,
|
||||||
|
0x47, 0xe1, 0xb7, 0xe8, 0xb7, 0xe3, 0xe0, 0xa0, 0x65, 0x9f, 0x92, 0x9c, 0x48, 0x77, 0xc9, 0x10,
|
||||||
|
0x10, 0xd9, 0x0f, 0x36, 0xcb, 0x01, 0xf6, 0xa8, 0xa1, 0x4d, 0xc3, 0x7e, 0xa0, 0x05, 0x0d, 0x86,
|
||||||
|
0xb7, 0xe7, 0xcb, 0x7e, 0xb7, 0x9b, 0x0b, 0x38, 0x7e, 0x32, 0xf1, 0x63, 0x63, 0x91, 0x46, 0xa0,
|
||||||
|
0x63, 0x0f, 0x0b, 0xd5, 0xc8, 0xdf, 0x20, 0xf6, 0x08, 0xf9, 0x4f, 0xb4, 0xcd, 0xb8, 0xaf, 0x5f,
|
||||||
|
0x15, 0x6f, 0x77, 0x72, 0xb0, 0x19, 0x33, 0x6a, 0xab, 0x83, 0xbd, 0x60, 0xea, 0x90, 0x0d, 0x6c,
|
||||||
|
0xe9, 0x53, 0x6b, 0xd9, 0x2f, 0x27, 0x87, 0x19, 0x48, 0x39, 0xc6, 0x60, 0x6f, 0x74, 0x58, 0x17,
|
||||||
|
0x7b, 0xac, 0x29, 0x14, 0x9e, 0x44, 0x1d, 0x88, 0x04, 0xfe, 0x0d, 0xfe, 0x7b, 0x50, 0x78, 0x7b,
|
||||||
|
0xff, 0x4c, 0x3a, 0x6b, 0x66, 0xc9, 0x73, 0xf4, 0xd8, 0x93, 0xc3, 0xe0, 0x99, 0x66, 0x73, 0x87,
|
||||||
|
0x1c, 0xdc, 0x62, 0xe7, 0x43, 0x9d, 0xeb, 0xeb, 0x7d, 0x6b, 0x3f, 0x78, 0xf7, 0x5f, 0x94, 0xf1,
|
||||||
|
0xb1, 0x3a, 0xbc, 0x65, 0x50, 0x18, 0x7b, 0x10, 0x7b, 0xfc, 0xd9, 0x38, 0xca, 0x07, 0x00, 0x68,
|
||||||
|
0xed, 0x92, 0x83, 0xcf, 0x16, 0x21, 0x52, 0xd7, 0x23, 0x0f, 0x74, 0xec, 0x55, 0x2a, 0x15, 0x47,
|
||||||
|
0x06, 0x64, 0x04, 0x5e, 0x2a, 0xa4, 0x6b, 0x6a, 0xa6, 0x60, 0x1f, 0x8b, 0xb3, 0xa7, 0x6d, 0xdb,
|
||||||
|
0x6b, 0x39, 0x73, 0x02, 0x3e, 0x43, 0xcf, 0xeb, 0x62, 0xba, 0x30, 0x5a, 0xf6, 0x4f, 0x1e, 0x3f,
|
||||||
|
0xa2, 0x2b, 0xe7, 0xe0, 0x9f, 0x71, 0xb2, 0x2b, 0x9d, 0x34, 0x16, 0x85, 0x54, 0x28, 0x55, 0xac,
|
||||||
|
0xcf, 0xc0, 0x9d, 0x3d, 0x82, 0x34, 0xf1, 0x42, 0xc9, 0xb8, 0x91, 0xe4, 0xa8, 0xab, 0x7f, 0x59,
|
||||||
|
0x65, 0x84, 0x74, 0xaf, 0x55, 0xa8, 0xf8, 0x05, 0xfc, 0xd7, 0x23, 0xee, 0x19, 0xc3, 0x03, 0x08,
|
||||||
|
0x60, 0xcf, 0x00, 0xa3, 0xbd, 0xb5, 0x80, 0x8a, 0x68, 0xd1, 0x1c, 0x78, 0xbe, 0xed, 0xe0, 0x3d,
|
||||||
|
0xba, 0x07, 0x30, 0x11, 0xfb, 0x2f, 0x3e, 0x9f, 0xce, 0xcb, 0x90, 0xa2, 0xa5, 0x19, 0xb0, 0x51,
|
||||||
|
0x48, 0x1a, 0xe1, 0xbf, 0x80, 0x65, 0x40, 0x62, 0x11, 0x39, 0x18, 0x91, 0x3d, 0x5b, 0xa3, 0x39,
|
||||||
|
0x33, 0xa8, 0xd9, 0x8f, 0x1b, 0x3d, 0x72, 0xc3, 0xba, 0x35, 0xf0, 0x35, 0x58, 0x30, 0x77, 0xf6,
|
||||||
|
0x57, 0x5f, 0x7e, 0xa1, 0x1e, 0x68, 0xc8, 0x1f, 0x3f, 0x76, 0x0c, 0x83, 0x2d, 0x4d, 0x9d, 0x28,
|
||||||
|
0x22, 0x18, 0xb1, 0x74, 0x0c, 0xbd, 0x4d, 0x0e, 0x63, 0x0a, 0xf6, 0xc2, 0xa0, 0x61, 0x1f, 0xae,
|
||||||
|
0x63, 0x8f, 0xf7, 0x1e, 0x20, 0x58, 0x34, 0xfb, 0x7a, 0x67, 0x47, 0x78, 0x4e, 0x97, 0xf9, 0x00,
|
||||||
|
0xcf, 0x88, 0x6b, 0x25, 0x28, 0xbc, 0xd8, 0x63, 0xa7, 0x21, 0x31, 0x1a, 0x93, 0xbd, 0x78, 0x8f,
|
||||||
|
0x2b, 0xa1, 0x62, 0xa1, 0xf9, 0x4c, 0xfa, 0x65, 0x9c, 0xb9, 0x29, 0x0a, 0x4c, 0x2c, 0x82, 0xff,
|
||||||
|
0x1e, 0xbc, 0xae, 0xa5, 0x5e, 0xb9, 0xe2, 0x5b, 0xee, 0xbd, 0x09, 0x74, 0x30, 0x72, 0x49, 0xa1,
|
||||||
|
0x31, 0xd0, 0x1b, 0xaf, 0x5b, 0xd0, 0x81, 0xf0, 0x29, 0x15, 0x0c, 0xbd, 0x92, 0x42, 0x79, 0x39,
|
||||||
|
0x7b, 0xaf, 0x0d, 0x17, 0x80, 0xef, 0x08, 0xe4, 0x57, 0xf3, 0xdb, 0xda, 0xee, 0xc2, 0xe7, 0xea,
|
||||||
|
0x81, 0xa6, 0xc4, 0xe6, 0x13, 0x87, 0xd1, 0x87, 0xc6, 0x28, 0xb1, 0xa8, 0x4d, 0x50, 0x4a, 0xeb,
|
||||||
|
0xef, 0x93, 0xf7, 0x96, 0xbc, 0xea, 0xab, 0xab, 0x1d, 0x0a, 0xe3, 0x66, 0x68, 0x53, 0x20, 0x43,
|
||||||
|
0x2c, 0xed, 0x79, 0x51, 0xd3, 0x01, 0x0a, 0x1a, 0xbc, 0xee, 0x1a, 0x81, 0x5a, 0x85, 0x2e, 0x5d,
|
||||||
|
0xbc, 0x60, 0xe2, 0x76, 0xa8, 0xa8, 0x98, 0x78, 0xd8, 0x0e, 0xe5, 0xe0, 0xf9, 0xa7, 0x80, 0xe2,
|
||||||
|
0xaa, 0x5e, 0x8a, 0xe7, 0xa7, 0x95, 0x61, 0x40, 0x44, 0x83, 0x12, 0x8b, 0x3a, 0x7a, 0x14, 0xfd,
|
||||||
|
0xfd, 0xfd, 0xaf, 0xea, 0x3a, 0xdc, 0x8e, 0xe5, 0x41, 0x4f, 0x07, 0xbf, 0x74, 0x56, 0x0b, 0xba,
|
||||||
|
0x2e, 0x59, 0xe0, 0x40, 0x01, 0x73, 0x88, 0x09, 0x6b, 0x01, 0xf9, 0x3d, 0x2e, 0xa3, 0x1e, 0x1a,
|
||||||
|
0xb2, 0xfb, 0xe4, 0x13, 0x2e, 0xc5, 0x6c, 0x9d, 0xea, 0xf7, 0xef, 0xdd, 0x33, 0x26, 0x3b, 0x7a,
|
||||||
|
0x40, 0x5a, 0xbd, 0x7d, 0x4c, 0x29, 0x7b, 0xdf, 0x95, 0xd7, 0x20, 0xcc, 0xae, 0xa3, 0xf7, 0x19,
|
||||||
|
0xc2, 0x98, 0x9a, 0x3a, 0x1c, 0x30, 0x87, 0xfe, 0xed, 0xba, 0xff, 0x37, 0x5e, 0x46, 0x2f, 0x9b,
|
||||||
|
0x31, 0x19, 0x5d, 0xda, 0xbe, 0xff, 0x2e, 0xb3, 0xf0, 0xa6, 0xa6, 0x3e, 0xf0, 0xad, 0xd5, 0xd6,
|
||||||
|
0xa9, 0xdb, 0x52, 0x12, 0x20, 0xe3, 0xa6, 0xc3, 0x91, 0x5d, 0x0f, 0xfe, 0x46, 0xdf, 0x04, 0x3c,
|
||||||
|
0xb0, 0xd3, 0xbe, 0x5b, 0x74, 0xa6, 0x4c, 0x4a, 0x5d, 0xda, 0xd5, 0x07, 0xd8, 0x14, 0xd5, 0x6a,
|
||||||
|
0x3b, 0xfb, 0x09, 0x44, 0xdb, 0xa4, 0x52, 0x65, 0x7b, 0xdb, 0x40, 0xaf, 0xd9, 0x76, 0xe8, 0x03,
|
||||||
|
0xab, 0xad, 0x74, 0xd6, 0x4c, 0x4a, 0x7d, 0xdf, 0x95, 0x57, 0x88, 0x4a, 0xf7, 0xd3, 0xc7, 0x80,
|
||||||
|
0xa5, 0xaa, 0x5b, 0x33, 0xb4, 0xae, 0xb7, 0xa7, 0x47, 0x22, 0x91, 0x40, 0x7f, 0xfc, 0x79, 0x02,
|
||||||
|
0x2e, 0xbf, 0xb4, 0x14, 0xea, 0x7e, 0x17, 0x0b, 0x11, 0x15, 0xc9, 0xfe, 0x7d, 0x88, 0xa2, 0x97,
|
||||||
|
0xc7, 0xae, 0x0f, 0x47, 0xbe, 0x0b, 0xcf, 0xeb, 0xb6, 0xd9, 0x21, 0xff, 0xe3, 0x37, 0xca, 0x2d,
|
||||||
|
0x93, 0xfa, 0x5e, 0xca, 0x22, 0x4d, 0xdd, 0xf6, 0x2d, 0xc8, 0xff, 0x84, 0xe5, 0x53, 0x3f, 0x7a,
|
||||||
|
0x28, 0xaa, 0xb5, 0xa5, 0x05, 0x9e, 0x1b, 0x4a, 0x1d, 0xfc, 0x7c, 0x43, 0xf1, 0x71, 0x65, 0xa0,
|
||||||
|
0x8e, 0xc2, 0x18, 0x4a, 0x3d, 0x74, 0x6f, 0xf0, 0xdd, 0x9c, 0x1c, 0x23, 0x92, 0x86, 0xe0, 0x46,
|
||||||
|
0xdd, 0x5e, 0x38, 0xf5, 0xaa, 0xca, 0x4a, 0xd9, 0x00, 0xf6, 0xec, 0x72, 0x73, 0x77, 0x71, 0xfe,
|
||||||
|
0x61, 0xf9, 0xd2, 0x69, 0x93, 0x27, 0x28, 0x14, 0x8a, 0x98, 0xe3, 0xd1, 0xe0, 0x64, 0x28, 0xa8,
|
||||||
|
0xe3, 0x30, 0x88, 0x3a, 0x4a, 0x2a, 0xe0, 0x64, 0x7f, 0x78, 0xd8, 0xfa, 0x9f, 0x57, 0x03, 0xc6,
|
||||||
|
0x53, 0x27, 0x8d, 0x77, 0xb0, 0xdb, 0x0c, 0x3c, 0x95, 0x4a, 0xa5, 0xe5, 0x52, 0x1f, 0x3a, 0xd0,
|
||||||
|
0x65, 0x8e, 0x38, 0x86, 0xa9, 0x1b, 0x1b, 0x74, 0xd4, 0x9d, 0xb7, 0x3a, 0xa9, 0x07, 0x47, 0xc5,
|
||||||
|
0xeb, 0x51, 0xcf, 0xb2, 0x60, 0xea, 0x79, 0x0f, 0x1f, 0x10, 0xba, 0x40, 0xc4, 0x1e, 0x3b, 0x11,
|
||||||
|
0xf5, 0xf8, 0xbb, 0x55, 0x96, 0x4b, 0x1d, 0x9c, 0x38, 0xda, 0xdb, 0x22, 0xea, 0x40, 0xf8, 0xa6,
|
||||||
|
0xa8, 0x70, 0x42, 0xe1, 0x31, 0xf4, 0xca, 0x2b, 0x4a, 0x6b, 0xe6, 0xa7, 0x4e, 0x80, 0x76, 0x1c,
|
||||||
|
0xd5, 0x4d, 0x6d, 0xc1, 0x18, 0xd6, 0x4b, 0xe4, 0x0a, 0x8a, 0x7a, 0x89, 0x5e, 0x05, 0x8f, 0xfc,
|
||||||
|
0x05, 0x05, 0xb5, 0x74, 0x7c, 0xe4, 0x9a, 0xd6, 0xf9, 0x65, 0x80, 0x7a, 0x00, 0x9d, 0x18, 0x02,
|
||||||
|
0xa8, 0x4f, 0x9f, 0x32, 0xc9, 0xd5, 0x79, 0x3b, 0x0a, 0x46, 0x2e, 0xb5, 0x43, 0xa7, 0x19, 0xf2,
|
||||||
|
0x3f, 0x30, 0xea, 0x5f, 0x37, 0x08, 0x0e, 0x60, 0x7f, 0x44, 0x18, 0xe5, 0x97, 0x5f, 0xa1, 0xec,
|
||||||
|
0x67, 0xed, 0x6f, 0x0a, 0xbe, 0x44, 0x9c, 0xc8, 0xc3, 0x97, 0xfa, 0x36, 0xc7, 0x2d, 0x63, 0x47,
|
||||||
|
0xbd, 0x87, 0x82, 0x35, 0x1f, 0x3d, 0x00, 0x2e, 0xb5, 0x9e, 0xd7, 0xf5, 0x40, 0x85, 0x24, 0x14,
|
||||||
|
0x92, 0xe3, 0xd5, 0x25, 0x98, 0xf1, 0x63, 0x47, 0x73, 0x64, 0x80, 0x70, 0x7e, 0xe0, 0x35, 0x82,
|
||||||
|
0xee, 0x6a, 0x1e, 0x7b, 0x3b, 0x11, 0x1d, 0x75, 0xa8, 0x9a, 0xdb, 0xce, 0x1d, 0x28, 0x24, 0x14,
|
||||||
|
0x5e, 0x56, 0xf0, 0x84, 0xc1, 0x9a, 0x8e, 0xba, 0x87, 0xbb, 0x2b, 0x5f, 0xea, 0x10, 0xdd, 0x72,
|
||||||
|
0x25, 0x64, 0xef, 0x1c, 0xc9, 0x32, 0xe4, 0xdc, 0x9f, 0x43, 0x5a, 0x47, 0xd0, 0x36, 0x00, 0x6e,
|
||||||
|
0xfa, 0x85, 0x2e, 0x80, 0x6e, 0x52, 0x19, 0x65, 0x82, 0x01, 0xb5, 0x98, 0x81, 0x79, 0x1d, 0x4e,
|
||||||
|
0x68, 0xb0, 0x23, 0x70, 0x62, 0x4f, 0xd7, 0xe6, 0xe8, 0x83, 0x84, 0x90, 0xee, 0x31, 0x8f, 0x35,
|
||||||
|
0xf5, 0x4e, 0xaf, 0x54, 0xb2, 0x11, 0x04, 0x2e, 0xaf, 0x29, 0x8e, 0x8a, 0xef, 0xbe, 0xd6, 0xf5,
|
||||||
|
0x8a, 0xad, 0x5f, 0xd5, 0xe0, 0xb3, 0x0b, 0x3a, 0xb1, 0xb7, 0xbb, 0x6e, 0xd0, 0x24, 0x7c, 0x47,
|
||||||
|
0xe1, 0x74, 0x1e, 0x02, 0x75, 0xe6, 0x2e, 0xbe, 0xd6, 0xf3, 0xb1, 0x28, 0xb0, 0xff, 0xb9, 0x02,
|
||||||
|
0xc0, 0xcc, 0xf7, 0xd2, 0x0b, 0x63, 0x51, 0x87, 0xa8, 0xf9, 0x6d, 0x2d, 0x65, 0xd4, 0xba, 0x04,
|
||||||
|
0x83, 0x06, 0x3f, 0x70, 0x44, 0x6b, 0xfc, 0x19, 0x72, 0xfb, 0x2d, 0xa8, 0xed, 0x33, 0x7c, 0x44,
|
||||||
|
0x84, 0x51, 0xa7, 0x83, 0x70, 0xea, 0x5a, 0x06, 0xe1, 0x41, 0x94, 0x79, 0x19, 0x65, 0x60, 0xcb,
|
||||||
|
0xa2, 0x0e, 0xd0, 0x71, 0x23, 0x0d, 0x90, 0xa8, 0x73, 0xda, 0x0c, 0xff, 0xf5, 0xb9, 0xf4, 0x82,
|
||||||
|
0x96, 0x3a, 0x76, 0xc9, 0x22, 0xa8, 0xab, 0x07, 0x66, 0x1b, 0x11, 0x84, 0xf7, 0x1e, 0xec, 0xfd,
|
||||||
|
0xc2, 0x61, 0x89, 0xd4, 0xd5, 0x70, 0xd0, 0x4b, 0x90, 0x0f, 0x3c, 0xa7, 0x4b, 0x33, 0xa6, 0xa0,
|
||||||
|
0xde, 0xdb, 0xd3, 0xf3, 0xf5, 0x57, 0xf3, 0x78, 0x19, 0xc2, 0x53, 0xfc, 0x8e, 0xa8, 0x5c, 0xb3,
|
||||||
|
0x51, 0x07, 0x19, 0xe5, 0xc6, 0x0d, 0xb4, 0xdf, 0x02, 0x4a, 0x88, 0x16, 0xce, 0x46, 0x54, 0x7c,
|
||||||
|
0x69, 0x92, 0xbb, 0xbf, 0x09, 0xa8, 0x2f, 0xff, 0xcf, 0xe2, 0x0d, 0xeb, 0xd6, 0x88, 0xeb, 0xeb,
|
||||||
|
0x57, 0x2e, 0x5b, 0x7a, 0x20, 0x22, 0xfc, 0x97, 0xb5, 0xab, 0x1f, 0xe5, 0x3d, 0xfc, 0x7c, 0xda,
|
||||||
|
0x14, 0x06, 0x43, 0x30, 0xf7, 0x85, 0xe7, 0x61, 0x58, 0x03, 0x9d, 0x49, 0xa9, 0xfb, 0x78, 0x7a,
|
||||||
|
0xc0, 0x13, 0xa0, 0x3d, 0x48, 0x36, 0xe0, 0xf8, 0xf1, 0xd8, 0xd1, 0x80, 0x3a, 0xb3, 0x21, 0x9c,
|
||||||
|
0x7a, 0xf8, 0x40, 0xeb, 0xb8, 0x19, 0xa8, 0x0b, 0x43, 0xcd, 0x46, 0xdd, 0xd4, 0xcc, 0xf0, 0xab,
|
||||||
|
0x6f, 0x16, 0xf5, 0x4d, 0xbf, 0x20, 0x2a, 0x11, 0xd7, 0xa8, 0xa9, 0x5b, 0xdc, 0x27, 0x09, 0xa2,
|
||||||
|
0x31, 0xc8, 0x1b, 0x51, 0x29, 0xac, 0x6e, 0x07, 0x14, 0x1b, 0xdb, 0x7a, 0x09, 0x61, 0xec, 0xfd,
|
||||||
|
0x75, 0xc5, 0x04, 0xf1, 0x6e, 0x67, 0x4b, 0xa1, 0xde, 0xfd, 0xf2, 0x1f, 0x40, 0xa5, 0x7f, 0x70,
|
||||||
|
0x90, 0x19, 0x39, 0x6b, 0xaf, 0x6a, 0x92, 0x01, 0x1f, 0xd7, 0x28, 0x6d, 0x35, 0xd2, 0xf0, 0xce,
|
||||||
|
0x6b, 0xa3, 0x51, 0x87, 0x6c, 0x2a, 0xbf, 0x5f, 0x0c, 0xcf, 0x25, 0xd2, 0x6e, 0xc8, 0xde, 0xf7,
|
||||||
|
0xd2, 0xcb, 0xd8, 0x9b, 0x22, 0xc7, 0xb0, 0x1c, 0xc2, 0xc3, 0x30, 0x97, 0xc5, 0xb9, 0xc0, 0x98,
|
||||||
|
0xd4, 0x45, 0xf3, 0xf5, 0x8a, 0x03, 0x2f, 0x6b, 0x3a, 0xf0, 0xfa, 0x98, 0x23, 0x36, 0x5a, 0xbf,
|
||||||
|
0x64, 0xfc, 0x68, 0x63, 0x0e, 0xd1, 0x30, 0x9c, 0xba, 0x9a, 0x5b, 0x32, 0x68, 0x3a, 0x10, 0xaa,
|
||||||
|
0xe9, 0x30, 0x72, 0xdb, 0xce, 0x1c, 0x8c, 0x15, 0x7a, 0x55, 0x8d, 0xd4, 0xbf, 0xae, 0x19, 0x68,
|
||||||
|
0x0e, 0xf6, 0x63, 0x01, 0x27, 0xaf, 0xa9, 0xa2, 0x0c, 0x50, 0xb3, 0x61, 0xf5, 0x90, 0x0c, 0x2d,
|
||||||
|
0x31, 0xdc, 0x1c, 0x04, 0xaa, 0x82, 0x34, 0x1d, 0xd9, 0xaf, 0xea, 0xd6, 0x74, 0xf8, 0xf7, 0x56,
|
||||||
|
0x8a, 0x50, 0x65, 0xa7, 0x62, 0xf1, 0x02, 0xa3, 0xc4, 0xa2, 0x9b, 0xc7, 0x73, 0xe2, 0x58, 0x34,
|
||||||
|
0x8f, 0x39, 0x3d, 0x6c, 0xee, 0x4a, 0xd4, 0x7e, 0x38, 0xe9, 0x07, 0xba, 0x14, 0x27, 0x7b, 0xe3,
|
||||||
|
0x8e, 0x87, 0x51, 0x9b, 0x60, 0x50, 0x49, 0x5f, 0x83, 0xb8, 0xb7, 0xe4, 0x95, 0xaa, 0x97, 0x98,
|
||||||
|
0xc7, 0x1b, 0x0e, 0x8b, 0x18, 0x0f, 0x63, 0x46, 0xfc, 0x95, 0x5f, 0x1f, 0x78, 0xf9, 0xa5, 0x43,
|
||||||
|
0x70, 0x36, 0xb9, 0x89, 0xca, 0xce, 0x37, 0xdd, 0xeb, 0x4c, 0xfe, 0xf1, 0x2c, 0x91, 0x52, 0xc5,
|
||||||
|
0x63, 0x61, 0x16, 0x8e, 0xa0, 0xd0, 0xbd, 0xe0, 0xe9, 0xd3, 0x4f, 0x27, 0x4f, 0x34, 0x7a, 0x4c,
|
||||||
|
0x96, 0x83, 0xd4, 0xfc, 0x7a, 0x5b, 0x2f, 0xe2, 0xd8, 0x73, 0x9d, 0xf3, 0xbc, 0x4e, 0x77, 0x29,
|
||||||
|
0x34, 0x99, 0x62, 0x24, 0xad, 0x30, 0x10, 0x75, 0x8f, 0x3f, 0x1b, 0x07, 0xf3, 0x79, 0xbc, 0x0d,
|
||||||
|
0xd3, 0x3a, 0xd0, 0x23, 0x57, 0x6e, 0x0d, 0xce, 0xc2, 0x75, 0xf4, 0x8a, 0x2b, 0x90, 0x76, 0xf5,
|
||||||
|
0x31, 0xdf, 0xa5, 0x52, 0xf5, 0x07, 0x25, 0x15, 0x13, 0x7e, 0x80, 0x17, 0xd5, 0xed, 0x06, 0x92,
|
||||||
|
0xd1, 0xd3, 0x7d, 0x97, 0xeb, 0x4e, 0xd4, 0xdc, 0x6e, 0xca, 0x89, 0x89, 0x26, 0xc0, 0xae, 0x63,
|
||||||
|
0x0f, 0x91, 0x6a, 0x1e, 0xb1, 0x05, 0xc2, 0x8c, 0x04, 0x27, 0x63, 0x3f, 0x80, 0x27, 0x53, 0x1b,
|
||||||
|
0x2b, 0x2b, 0xa8, 0xf3, 0x77, 0x93, 0x8d, 0x07, 0x33, 0x01, 0xaa, 0x9a, 0xbb, 0x91, 0x58, 0x3b,
|
||||||
|
0xf5, 0xd7, 0xef, 0x42, 0xe8, 0xbc, 0x95, 0x25, 0xde, 0xe5, 0x5c, 0x3e, 0x6b, 0xaa, 0xa6, 0x68,
|
||||||
|
0x6b, 0x33, 0xaa, 0xec, 0xf3, 0x29, 0xa0, 0x46, 0xd4, 0x9e, 0x7a, 0x95, 0x32, 0x70, 0x48, 0xe2,
|
||||||
|
0x4b, 0x64, 0x30, 0x31, 0xb7, 0x5a, 0x18, 0x2b, 0x2b, 0xd7, 0x5d, 0xd2, 0xde, 0xab, 0xeb, 0x42,
|
||||||
|
0x4a, 0x21, 0x76, 0x83, 0xb5, 0xc6, 0x9d, 0x64, 0x6e, 0x8c, 0x87, 0xae, 0xf9, 0xf8, 0x21, 0xc2,
|
||||||
|
0x8d, 0xe5, 0x0d, 0x9d, 0xc8, 0xec, 0xa1, 0x74, 0x21, 0x03, 0xa3, 0xad, 0x5c, 0x77, 0x3b, 0xbf,
|
||||||
|
0x0c, 0xa8, 0x8e, 0x5f, 0x82, 0x5e, 0xe7, 0x85, 0xb2, 0x4d, 0xaa, 0x53, 0xd6, 0x66, 0x54, 0x7b,
|
||||||
|
0x1a, 0x45, 0xa5, 0xa5, 0x2a, 0x23, 0x15, 0x57, 0xbf, 0xbf, 0x4f, 0xef, 0x4b, 0x90, 0x57, 0xda,
|
||||||
|
0x82, 0xa4, 0xef, 0xea, 0x55, 0xf0, 0x25, 0x66, 0xcd, 0xba, 0x5f, 0x7e, 0x50, 0x4b, 0x97, 0x17,
|
||||||
|
0xa3, 0x29, 0x5d, 0x92, 0xb0, 0x20, 0x66, 0x23, 0x4d, 0x87, 0x23, 0x75, 0xd2, 0xcb, 0xe5, 0xf8,
|
||||||
|
0x25, 0xd7, 0xc1, 0xf1, 0xc8, 0x01, 0x09, 0xb4, 0x3d, 0x52, 0x74, 0xb0, 0x66, 0xdd, 0x83, 0x06,
|
||||||
|
0x27, 0x8f, 0xb8, 0x1d, 0xcb, 0xc3, 0xfd, 0x5b, 0x62, 0x8e, 0x40, 0x1d, 0xcb, 0xe7, 0x7c, 0x86,
|
||||||
|
0xfb, 0xaf, 0x5b, 0xbd, 0x8a, 0xb2, 0x34, 0x51, 0xb9, 0xfc, 0x1b, 0x6d, 0xfd, 0xf5, 0x50, 0x04,
|
||||||
|
0xee, 0x7f, 0xe0, 0xaf, 0xd7, 0xd0, 0xfe, 0x96, 0x60, 0xea, 0xa5, 0x0a, 0x18, 0x60, 0xcd, 0xba,
|
||||||
|
0xc3, 0x46, 0x4f, 0x4d, 0x7f, 0x51, 0x9c, 0x5e, 0x01, 0x06, 0x8e, 0xe6, 0x02, 0xae, 0x6a, 0xcd,
|
||||||
|
0x0a, 0xc2, 0x2d, 0xa5, 0x25, 0xaf, 0xc9, 0x76, 0xe0, 0xb0, 0xc0, 0x12, 0x6c, 0xe6, 0x38, 0x04,
|
||||||
|
0x1c, 0x7b, 0xb4, 0x99, 0x71, 0x26, 0x33, 0x1d, 0xde, 0x6e, 0xdd, 0x57, 0xeb, 0xe9, 0x7e, 0x21,
|
||||||
|
0xfe, 0x5c, 0xce, 0xed, 0x5b, 0x1f, 0x8f, 0x1d, 0xed, 0xbc, 0xcd, 0x09, 0xf7, 0x37, 0xbf, 0xee,
|
||||||
|
0xd9, 0x59, 0x37, 0xe6, 0xcc, 0x9c, 0xb1, 0x3f, 0x3c, 0x8c, 0x6f, 0x34, 0x66, 0x01, 0xd2, 0xdd,
|
||||||
|
0x8b, 0x9b, 0xee, 0x47, 0x0f, 0x45, 0xad, 0xff, 0x79, 0x35, 0xd9, 0x8e, 0xf9, 0x75, 0x87, 0x79,
|
||||||
|
0x9f, 0xcd, 0x98, 0x51, 0x95, 0x15, 0x15, 0x7c, 0x63, 0x32, 0x3d, 0x04, 0xe8, 0x8e, 0x2f, 0x49,
|
||||||
|
0x81, 0x60, 0x66, 0xdd, 0x81, 0xe8, 0x1b, 0xd6, 0xad, 0x81, 0x0e, 0x7d, 0x7c, 0xc0, 0x2b, 0xb9,
|
||||||
|
0x60, 0xee, 0xec, 0xcc, 0xf4, 0xb4, 0x45, 0xf3, 0xbe, 0x3c, 0x17, 0x17, 0xab, 0x52, 0xa9, 0xc0,
|
||||||
|
0x7b, 0x3a, 0x7d, 0xca, 0xa4, 0x36, 0xa9, 0xf4, 0xeb, 0xf9, 0x73, 0xd5, 0x83, 0x2b, 0xd2, 0x9a,
|
||||||
|
0x05, 0x7c, 0x75, 0xa7, 0x03, 0x1c, 0x94, 0x69, 0x1e, 0xdd, 0x67, 0x7d, 0x36, 0xed, 0xda, 0x95,
|
||||||
|
0x3f, 0xd1, 0xbf, 0x32, 0x99, 0x0c, 0x4a, 0x0f, 0xf3, 0x1c, 0xf8, 0x7a, 0x4e, 0x9b, 0x3c, 0x21,
|
||||||
|
0x38, 0xc0, 0xaf, 0xa5, 0xa5, 0x19, 0x9c, 0x47, 0x1f, 0xd6, 0xd4, 0x35, 0xec, 0xff, 0xd8, 0x74,
|
||||||
|
0xfe, 0x5c, 0x9c, 0xda, 0x4c, 0xc0, 0xf2, 0x77, 0xbd, 0x71, 0x18, 0x98, 0xee, 0x14, 0x2b, 0x50,
|
||||||
|
0x90, 0x61, 0x4e, 0xdd, 0xdf, 0x44, 0xd0, 0xeb, 0xbe, 0x4f, 0xa0, 0xee, 0x7b, 0x87, 0x75, 0xe7,
|
||||||
|
0x80, 0x61, 0xdd, 0xcd, 0x83, 0x21, 0xd7, 0x3d, 0x6b, 0x58, 0x77, 0x2a, 0x70, 0xd7, 0xfd, 0xd4,
|
||||||
|
0x89, 0xe3, 0x78, 0x4d, 0x15, 0x9e, 0xa3, 0xe5, 0xd5, 0x87, 0x75, 0xe7, 0x07, 0x76, 0xdd, 0x7f,
|
||||||
|
0x5a, 0x1e, 0x75, 0x20, 0x12, 0xef, 0x6f, 0x80, 0xd3, 0xb6, 0x70, 0x9f, 0x5f, 0xd7, 0xad, 0xad,
|
||||||
|
0x0f, 0xf6, 0x85, 0xe1, 0xeb, 0x9d, 0x1d, 0x70, 0x3b, 0xb9, 0xaf, 0x75, 0x4d, 0x63, 0xbd, 0x7d,
|
||||||
|
0xfc, 0x66, 0x46, 0xbd, 0x15, 0xba, 0x7b, 0xd1, 0xeb, 0x8e, 0xfb, 0x2f, 0x9c, 0xf7, 0x25, 0x3c,
|
||||||
|
0x19, 0x37, 0x7a, 0xa4, 0xb4, 0x55, 0x37, 0xb5, 0xbd, 0xf3, 0xee, 0x2d, 0xf2, 0x28, 0x67, 0x08,
|
||||||
|
0x9f, 0xf8, 0xe7, 0x5a, 0xe9, 0xb1, 0xa5, 0x6a, 0xb9, 0x60, 0x58, 0x77, 0x22, 0x28, 0xd7, 0xf5,
|
||||||
|
0xaa, 0xfc, 0x7e, 0x09, 0xbc, 0x05, 0xe4, 0x39, 0x84, 0x4b, 0xc1, 0x29, 0x7a, 0xbd, 0x80, 0x41,
|
||||||
|
0x49, 0xc5, 0x92, 0x76, 0xf6, 0xf1, 0x07, 0x44, 0xdd, 0xf1, 0x57, 0x2c, 0x23, 0x8d, 0xbd, 0x2b,
|
||||||
|
0x8b, 0xcb, 0x9c, 0x15, 0x06, 0xe7, 0x7a, 0xe4, 0xfe, 0xb1, 0xcc, 0x72, 0x60, 0x84, 0x35, 0x22,
|
||||||
|
0x01, 0xe0, 0xab, 0x3b, 0xca, 0xdf, 0x6f, 0x66, 0x67, 0xe1, 0xe9, 0x1d, 0xa2, 0xc4, 0x66, 0x94,
|
||||||
|
0x56, 0xfa, 0xad, 0xb6, 0xe4, 0xb8, 0xf6, 0xfd, 0xf9, 0x8a, 0xcf, 0x53, 0x3f, 0xa0, 0x48, 0xef,
|
||||||
|
0x50, 0xf4, 0x0a, 0x91, 0x88, 0xcb, 0xb3, 0xf5, 0x29, 0x54, 0x97, 0x73, 0x6b, 0xb8, 0xb8, 0xf8,
|
||||||
|
0x9c, 0xca, 0x23, 0xe9, 0x65, 0x81, 0x89, 0x45, 0xde, 0x67, 0x0b, 0xb6, 0x04, 0x66, 0x51, 0x12,
|
||||||
|
0x0a, 0x4e, 0x28, 0xec, 0xe1, 0x99, 0x51, 0x32, 0x80, 0x83, 0xee, 0x14, 0x6b, 0x80, 0xd5, 0xd6,
|
||||||
|
0xd6, 0xcc, 0x9c, 0x3e, 0x15, 0x9f, 0xdc, 0x83, 0x20, 0x5a, 0xa4, 0x5b, 0xd6, 0xb5, 0xeb, 0xd1,
|
||||||
|
0x03, 0xba, 0x78, 0x2b, 0x9b, 0x64, 0x77, 0x8a, 0x9b, 0x33, 0x0a, 0x1a, 0x90, 0x4b, 0x2f, 0x68,
|
||||||
|
0x48, 0x7b, 0x2a, 0x4e, 0xcd, 0x1f, 0x74, 0x4f, 0xc5, 0x23, 0x3a, 0x3a, 0x3a, 0xea, 0x48, 0xc8,
|
||||||
|
0xb9, 0x7d, 0x8b, 0xec, 0x69, 0x20, 0xda, 0xda, 0xa8, 0x97, 0xcb, 0x95, 0xca, 0xfa, 0x82, 0x93,
|
||||||
|
0x8a, 0x08, 0x3f, 0x80, 0xff, 0x05, 0xae, 0xd3, 0xba, 0x18, 0xa0, 0xd3, 0x3d, 0x96, 0x93, 0xee,
|
||||||
|
0x0f, 0xee, 0xe7, 0xc2, 0x34, 0xb7, 0xea, 0x7b, 0xda, 0xf2, 0x65, 0x47, 0x66, 0x1a, 0xde, 0x09,
|
||||||
|
0xd5, 0x1a, 0x1b, 0x23, 0x8c, 0x1b, 0x45, 0x7a, 0x9f, 0x35, 0x7d, 0x9a, 0xb9, 0x46, 0x12, 0x88,
|
||||||
|
0x1a, 0x3a, 0x6d, 0xf7, 0xe8, 0xd4, 0xdf, 0xe2, 0xcb, 0xbe, 0xae, 0x0c, 0x03, 0xf8, 0xea, 0xce,
|
||||||
|
0x1d, 0xf8, 0x7c, 0xa2, 0x92, 0xc1, 0xd5, 0xa2, 0xda, 0x92, 0x2e, 0xf6, 0x2b, 0xb8, 0x76, 0xf8,
|
||||||
|
0x11, 0x75, 0x1f, 0x3b, 0xea, 0x3d, 0x94, 0xbf, 0x73, 0xd9, 0xc0, 0x8a, 0x75, 0x9e, 0x16, 0x9d,
|
||||||
|
0xab, 0x75, 0xf8, 0xbd, 0x23, 0x93, 0xf6, 0xfb, 0xe1, 0x73, 0xee, 0x99, 0x2e, 0x37, 0x8c, 0x66,
|
||||||
|
0x19, 0x6e, 0x4f, 0x87, 0xa1, 0xd3, 0x1d, 0xa1, 0x35, 0xee, 0x64, 0xe9, 0x27, 0x36, 0x7c, 0x9f,
|
||||||
|
0x9d, 0xb8, 0x46, 0xe4, 0xf3, 0x67, 0x05, 0xd0, 0x25, 0x5c, 0xbc, 0x00, 0x4f, 0x58, 0x23, 0x06,
|
||||||
|
0xba, 0x37, 0x06, 0xfb, 0x70, 0x71, 0x62, 0x2f, 0xf7, 0x9a, 0xdf, 0xd7, 0x8b, 0x16, 0xcc, 0x26,
|
||||||
|
0xf3, 0xa8, 0x5a, 0xbd, 0x82, 0xd0, 0x6b, 0x0c, 0xe1, 0x7e, 0x3c, 0x0f, 0xa9, 0x9f, 0xfe, 0x54,
|
||||||
|
0xcc, 0x57, 0x14, 0x13, 0xe8, 0x4e, 0x40, 0xf7, 0xf3, 0xa7, 0xcd, 0x31, 0x47, 0x81, 0xfd, 0xc6,
|
||||||
|
0x20, 0x1f, 0x34, 0xcf, 0x90, 0xc2, 0x05, 0x78, 0x51, 0x97, 0x23, 0x8d, 0x32, 0xa4, 0x99, 0x15,
|
||||||
|
0xf2, 0xca, 0x8a, 0x8a, 0x25, 0x0b, 0xf1, 0x1f, 0x40, 0x96, 0x4f, 0x5c, 0x7f, 0xaa, 0x12, 0x1b,
|
||||||
|
0x31, 0x11, 0x48, 0xb5, 0xe0, 0x24, 0x03, 0x4c, 0xaf, 0x3b, 0x77, 0x98, 0x53, 0x77, 0x84, 0x8e,
|
||||||
|
0xb4, 0x6b, 0xe8, 0x6d, 0x2d, 0x9d, 0x32, 0x8e, 0x1c, 0x00, 0x49, 0x1f, 0x70, 0x99, 0x87, 0xf4,
|
||||||
|
0x70, 0xee, 0xd7, 0xb0, 0xee, 0x2c, 0x68, 0x0c, 0xf1, 0xd3, 0x95, 0xd2, 0xfe, 0xd6, 0x5b, 0x1e,
|
||||||
|
0x46, 0xae, 0x50, 0x21, 0xe9, 0x2f, 0xde, 0x63, 0xd9, 0xc9, 0x10, 0x61, 0x58, 0x77, 0xae, 0xe8,
|
||||||
|
0xc8, 0xce, 0xa0, 0xcb, 0x73, 0xe0, 0xe6, 0x59, 0x9b, 0x35, 0x6b, 0x11, 0x70, 0x1d, 0x98, 0x68,
|
||||||
|
0x55, 0xba, 0xa7, 0x24, 0x27, 0x76, 0x75, 0x75, 0x0d, 0x19, 0x1f, 0xed, 0x24, 0x16, 0xe0, 0xca,
|
||||||
|
0xa6, 0x13, 0xc7, 0x82, 0xdb, 0xf9, 0xa6, 0x43, 0x1d, 0xcf, 0xe6, 0x54, 0x72, 0x31, 0xc5, 0xae,
|
||||||
|
0xbb, 0x61, 0x2b, 0xe0, 0x1a, 0x02, 0x7e, 0xba, 0xaf, 0x5d, 0xf5, 0x03, 0xac, 0x5c, 0x0c, 0x25,
|
||||||
|
0x25, 0x75, 0xe9, 0xe4, 0x8f, 0xa0, 0x2e, 0xed, 0x19, 0x7a, 0x8d, 0x4d, 0x9e, 0x67, 0xb5, 0x85,
|
||||||
|
0x4b, 0x9f, 0xb3, 0x9c, 0x06, 0xf4, 0xfa, 0x5b, 0x87, 0xee, 0x77, 0x73, 0x72, 0xe0, 0xd2, 0xd1,
|
||||||
|
0x72, 0xb9, 0x9c, 0x41, 0xfa, 0xaa, 0x4a, 0x4e, 0x89, 0x91, 0x01, 0xe0, 0xf5, 0x87, 0xba, 0x80,
|
||||||
|
0xb4, 0x8f, 0xfb, 0x87, 0x0c, 0x0e, 0x83, 0x76, 0x0a, 0xe7, 0xb4, 0x38, 0x98, 0x95, 0xe8, 0x8e,
|
||||||
|
0x9a, 0xa7, 0x01, 0x8e, 0x47, 0x1f, 0x85, 0xb3, 0x9e, 0xa7, 0x8c, 0x1f, 0xa7, 0x1e, 0x6c, 0x51,
|
||||||
|
0x1a, 0x37, 0x7a, 0x24, 0x38, 0x3e, 0xca, 0x7b, 0x08, 0x37, 0xe7, 0xbc, 0x10, 0x7f, 0x4e, 0x18,
|
||||||
|
0x27, 0x34, 0x85, 0x0b, 0xad, 0xfb, 0x0d, 0x01, 0x67, 0x4f, 0x6f, 0xa6, 0x59, 0x03, 0x9c, 0x0c,
|
||||||
|
0x6b, 0xd0, 0x1d, 0x28, 0xdb, 0xa7, 0x5f, 0xb5, 0x99, 0xf5, 0xd9, 0xb4, 0x40, 0x3f, 0x5f, 0x38,
|
||||||
|
0xf7, 0x1f, 0xea, 0xfe, 0xf1, 0xc0, 0x4a, 0x35, 0x48, 0x77, 0xc2, 0xc6, 0x61, 0xdc, 0x01, 0xb7,
|
||||||
|
0xb3, 0x2d, 0xc1, 0x56, 0x2c, 0x87, 0x80, 0xf3, 0xa7, 0x35, 0xba, 0x53, 0xad, 0x5e, 0x4e, 0x86,
|
||||||
|
0x35, 0xe8, 0x6e, 0x4a, 0xd4, 0x6c, 0x5c, 0xc7, 0xac, 0x3b, 0xe5, 0xaa, 0xf1, 0x64, 0x0c, 0xeb,
|
||||||
|
0xce, 0x0f, 0xf5, 0x2e, 0x5b, 0xb5, 0xfd, 0x99, 0x41, 0xde, 0xb8, 0xff, 0x89, 0x2c, 0x91, 0xb6,
|
||||||
|
0x3f, 0x33, 0x80, 0x76, 0x23, 0x47, 0x1c, 0x6e, 0xc7, 0x1f, 0x69, 0x5b, 0x37, 0xf5, 0x37, 0x40,
|
||||||
|
0x93, 0x84, 0x06, 0x68, 0xdb, 0x88, 0x36, 0xff, 0x6a, 0x44, 0xda, 0xbc, 0x60, 0x89, 0xba, 0x37,
|
||||||
|
0x47, 0x47, 0x41, 0x5d, 0xca, 0x67, 0x13, 0xf7, 0xb2, 0xd0, 0x35, 0x14, 0x9f, 0x7f, 0xce, 0x6c,
|
||||||
|
0xe4, 0x50, 0x7a, 0x19, 0x0a, 0x5c, 0xdf, 0xda, 0x83, 0x5f, 0x42, 0xcd, 0xe8, 0x4d, 0x51, 0xe1,
|
||||||
|
0x46, 0xa6, 0xce, 0x19, 0x96, 0xa8, 0xbb, 0x1a, 0xeb, 0xdc, 0x81, 0x9b, 0xf5, 0xe2, 0xc0, 0x9b,
|
||||||
|
0xe9, 0x41, 0xce, 0x43, 0xbe, 0xf7, 0x7e, 0x51, 0x23, 0x1e, 0xa6, 0xa0, 0xa2, 0x0d, 0xbf, 0xda,
|
||||||
|
0x12, 0x1b, 0x83, 0xaa, 0x66, 0x5c, 0x1a, 0x5c, 0x87, 0x08, 0x16, 0xaa, 0x7b, 0xf7, 0xf3, 0x02,
|
||||||
|
0xa4, 0x4e, 0xc7, 0x0d, 0xe2, 0x46, 0x4d, 0xa7, 0x6f, 0x57, 0x72, 0xe9, 0x4e, 0x3b, 0x34, 0xb8,
|
||||||
|
0x57, 0x05, 0x82, 0xec, 0xf1, 0x43, 0x64, 0xb6, 0xed, 0x6a, 0x92, 0xa9, 0x9e, 0x86, 0x02, 0x16,
|
||||||
|
0xaa, 0x3b, 0x40, 0xd7, 0xc3, 0x5c, 0xa4, 0x91, 0xd8, 0xcb, 0x9d, 0x32, 0xcc, 0xd3, 0x0a, 0xe9,
|
||||||
|
0xde, 0xe4, 0xa2, 0x6d, 0x91, 0x77, 0xec, 0xfd, 0x33, 0xed, 0xfc, 0x32, 0x1c, 0xc3, 0x6e, 0xfb,
|
||||||
|
0x5e, 0x7c, 0xf1, 0xac, 0xb2, 0x8d, 0x32, 0x30, 0x30, 0x82, 0x0c, 0xb6, 0xa7, 0xb3, 0x6f, 0x29,
|
||||||
|
0x35, 0xa4, 0xd0, 0xd3, 0x7d, 0xe5, 0xb2, 0xa5, 0x96, 0x36, 0x7f, 0xb5, 0xe2, 0x9b, 0xf9, 0x48,
|
||||||
|
0xac, 0x86, 0x40, 0x2f, 0x61, 0x46, 0x1a, 0x83, 0x7c, 0x74, 0xad, 0xcd, 0xe3, 0x47, 0xf7, 0x1b,
|
||||||
|
0xb0, 0x0a, 0xb0, 0xb1, 0x40, 0x4c, 0xef, 0xde, 0x7b, 0x76, 0x5b, 0x8e, 0xe8, 0x10, 0x40, 0x26,
|
||||||
|
0x42, 0x9f, 0x4e, 0x63, 0xa0, 0xb7, 0xb2, 0xb3, 0x93, 0xf9, 0x2e, 0x4d, 0x87, 0x0c, 0xd6, 0xc0,
|
||||||
|
0xa9, 0x71, 0x36, 0xa3, 0x54, 0x54, 0xbd, 0x2b, 0x66, 0x01, 0x45, 0x3e, 0x93, 0x98, 0x70, 0x49,
|
||||||
|
0xc0, 0x5a, 0x9d, 0x26, 0x40, 0xd3, 0x91, 0xfd, 0xc2, 0xfa, 0x14, 0x9b, 0x8f, 0x45, 0xb1, 0x5b,
|
||||||
|
0x37, 0x2d, 0xde, 0xd4, 0xf5, 0x38, 0xa4, 0xc9, 0x97, 0xc4, 0x5e, 0x6e, 0x65, 0x9f, 0x4e, 0x20,
|
||||||
|
0xab, 0x5c, 0x36, 0x63, 0xb2, 0xd8, 0x7d, 0xbb, 0xf4, 0xf2, 0x79, 0x73, 0x73, 0x64, 0xc2, 0x9b,
|
||||||
|
0xaa, 0xbb, 0xd1, 0xd1, 0xd9, 0xa3, 0x28, 0x6f, 0xec, 0x2a, 0xac, 0x6e, 0x2f, 0xae, 0xeb, 0x6c,
|
||||||
|
0xe9, 0x94, 0xb3, 0xdf, 0x60, 0x18, 0xde, 0x6a, 0xdd, 0x81, 0xd6, 0x07, 0xaf, 0x97, 0xee, 0x89,
|
||||||
|
0x79, 0x64, 0xeb, 0x95, 0x4a, 0x2e, 0x86, 0x3a, 0x85, 0xe7, 0x84, 0x24, 0x15, 0x15, 0xd0, 0x94,
|
||||||
|
0x8e, 0x0c, 0xc4, 0x08, 0xf2, 0x1e, 0x4f, 0xa7, 0x4f, 0x9d, 0x34, 0xe3, 0x4e, 0xe7, 0xa6, 0x71,
|
||||||
|
0xf1, 0x17, 0x13, 0x0e, 0x1c, 0x8d, 0x45, 0xbb, 0xaa, 0x93, 0xf7, 0x56, 0xc7, 0x9d, 0x63, 0x48,
|
||||||
|
0xf6, 0xb1, 0x1b, 0x9c, 0x46, 0xcf, 0xf1, 0xd0, 0x9d, 0xec, 0x05, 0x4a, 0x32, 0x3d, 0xdd, 0x5c,
|
||||||
|
0x77, 0x7d, 0x7d, 0x13, 0xe1, 0x1f, 0x9b, 0xcf, 0xa5, 0xda, 0x45, 0x54, 0x3f, 0x30, 0xb3, 0xac,
|
||||||
|
0x81, 0xa5, 0x10, 0xc5, 0x1d, 0x44, 0xdd, 0x6f, 0x64, 0x66, 0x00, 0xdd, 0x27, 0xd9, 0x8c, 0xa5,
|
||||||
|
0x0c, 0xfd, 0xa6, 0xe3, 0x48, 0xa6, 0x88, 0xa0, 0xa6, 0xad, 0x77, 0x9a, 0xe7, 0xd9, 0x67, 0x67,
|
||||||
|
0x6f, 0x55, 0xd4, 0xb4, 0x74, 0xc3, 0x8d, 0xe7, 0x14, 0xca, 0xfe, 0xfa, 0xd6, 0x9e, 0x94, 0x87,
|
||||||
|
0x75, 0x7e, 0x97, 0x5e, 0xd8, 0x07, 0xdc, 0x20, 0x84, 0x3f, 0x96, 0x4a, 0xd1, 0x32, 0x21, 0x00,
|
||||||
|
0xb4, 0xe3, 0x81, 0x45, 0xe5, 0xe5, 0x46, 0x89, 0xc0, 0x72, 0x70, 0x34, 0xa3, 0x0c, 0x57, 0xd0,
|
||||||
|
0x21, 0xe4, 0x66, 0xfc, 0x2d, 0xf6, 0xdc, 0x23, 0xeb, 0x79, 0xe3, 0xce, 0x43, 0xf7, 0xf1, 0x1b,
|
||||||
|
0x83, 0xcf, 0x3f, 0x33, 0x9c, 0x8c, 0x9e, 0xee, 0x91, 0x61, 0xa1, 0x48, 0x77, 0xca, 0x9d, 0xa9,
|
||||||
|
0xdf, 0x5c, 0x84, 0x5d, 0x2b, 0xc1, 0xb5, 0xf3, 0xe7, 0xb9, 0x82, 0x46, 0x4c, 0x76, 0x85, 0x9e,
|
||||||
|
0xf4, 0xe7, 0x28, 0x16, 0xc8, 0xe6, 0x05, 0x3d, 0xdd, 0x09, 0x8d, 0x04, 0x69, 0xd7, 0xcd, 0xdc,
|
||||||
|
0x88, 0x61, 0x2c, 0x3c, 0x29, 0x6b, 0xc5, 0x55, 0xab, 0x69, 0x14, 0x92, 0x4d, 0x97, 0x88, 0xbb,
|
||||||
|
0xec, 0xb0, 0x9d, 0xc8, 0xf7, 0x26, 0xd3, 0xee, 0xee, 0xcd, 0x05, 0x14, 0xdf, 0xd5, 0xbd, 0xc1,
|
||||||
|
0x81, 0x86, 0x58, 0xb4, 0x40, 0xd8, 0xfa, 0xa4, 0x23, 0xbd, 0x24, 0x6d, 0x3d, 0xec, 0x37, 0xd0,
|
||||||
|
0x40, 0xa5, 0xea, 0xb7, 0xc3, 0x56, 0xdb, 0xbb, 0x57, 0xdc, 0x24, 0xd8, 0x94, 0xf5, 0xeb, 0x0e,
|
||||||
|
0x37, 0x8b, 0xd0, 0x2a, 0x55, 0x24, 0x21, 0x07, 0x50, 0x75, 0xcb, 0x9a, 0x0e, 0x86, 0x56, 0xaf,
|
||||||
|
0xf9, 0xbe, 0x74, 0xea, 0xc7, 0x25, 0xe3, 0x46, 0x96, 0x4e, 0xfc, 0xb0, 0x62, 0xe9, 0xd7, 0x4d,
|
||||||
|
0x07, 0x42, 0x95, 0x52, 0xea, 0xdd, 0x3b, 0x6d, 0x07, 0x53, 0xbd, 0x43, 0x08, 0xef, 0x65, 0x67,
|
||||||
|
0x10, 0xac, 0x5c, 0xf7, 0xaa, 0x26, 0xdd, 0xa2, 0x6e, 0x94, 0xfb, 0x74, 0x48, 0x42, 0x03, 0x19,
|
||||||
|
0x1a, 0x76, 0xd0, 0xce, 0x01, 0x38, 0xb2, 0x9f, 0x89, 0x91, 0xcd, 0xa8, 0xd4, 0x52, 0x61, 0xc4,
|
||||||
|
0xac, 0x5c, 0x77, 0xef, 0xb3, 0xba, 0x71, 0xf4, 0xe4, 0xab, 0xa2, 0x6f, 0xe6, 0xb1, 0xb6, 0xa9,
|
||||||
|
0x95, 0xcd, 0x9c, 0xda, 0x5b, 0x46, 0xec, 0x3f, 0x71, 0x3f, 0xa1, 0xed, 0xb9, 0xb5, 0x15, 0xba,
|
||||||
|
0x9a, 0xa1, 0x35, 0xeb, 0xae, 0x54, 0xe9, 0xe6, 0xbc, 0x1d, 0xbe, 0x4e, 0x2c, 0x77, 0xe3, 0x2d,
|
||||||
|
0xfb, 0x20, 0x7b, 0x69, 0xf0, 0xf7, 0x6c, 0xbb, 0x9a, 0xd4, 0xf3, 0xf2, 0x9f, 0xf6, 0xd4, 0xab,
|
||||||
|
0x70, 0x19, 0x78, 0xe4, 0x4a, 0xa7, 0x8e, 0x27, 0xdc, 0x5b, 0x8d, 0xad, 0x8d, 0x98, 0xca, 0x7f,
|
||||||
|
0x60, 0xbe, 0xda, 0xba, 0x75, 0x3f, 0x83, 0x75, 0x07, 0x12, 0xd6, 0xf8, 0x95, 0x84, 0x07, 0x23,
|
||||||
|
0x59, 0x6b, 0x6d, 0x7f, 0x23, 0xdf, 0xdb, 0xdf, 0xd7, 0x97, 0xb2, 0x7e, 0x35, 0x43, 0x97, 0xcb,
|
||||||
|
0xf6, 0x03, 0x7f, 0x6b, 0xb3, 0xaf, 0x0b, 0x85, 0xe4, 0xdb, 0x59, 0x61, 0xcd, 0xba, 0xfb, 0x5f,
|
||||||
|
0xf8, 0x07, 0x4a, 0xe3, 0xa6, 0x3f, 0x53, 0xa7, 0x4f, 0x5c, 0xa7, 0x13, 0x9d, 0x66, 0x28, 0xc7,
|
||||||
|
0x86, 0x75, 0x6b, 0xfb, 0x95, 0xca, 0x06, 0x3f, 0x0f, 0x14, 0x92, 0xf0, 0x99, 0x8d, 0x18, 0x1c,
|
||||||
|
0xbc, 0x66, 0xef, 0x9f, 0x29, 0x80, 0x9b, 0x35, 0xeb, 0x8e, 0x6a, 0xf9, 0xfb, 0x52, 0xf4, 0xca,
|
||||||
|
0xda, 0x68, 0xdc, 0x52, 0x09, 0xcd, 0xaa, 0xe8, 0x2b, 0x96, 0x2e, 0x46, 0xe7, 0x68, 0x90, 0xac,
|
||||||
|
0x24, 0x22, 0x04, 0x0f, 0x53, 0x39, 0xb0, 0x6d, 0x03, 0x74, 0x32, 0x39, 0xef, 0x8e, 0x43, 0x6b,
|
||||||
|
0xd6, 0x7d, 0xf3, 0xe0, 0xd4, 0xc0, 0xbf, 0xf5, 0x0b, 0xda, 0x95, 0x2b, 0x97, 0xa0, 0xfe, 0x42,
|
||||||
|
0xdc, 0xbf, 0xbd, 0xad, 0x6d, 0xc7, 0x56, 0xc7, 0xb5, 0x3f, 0xfd, 0x80, 0x7b, 0xa2, 0x41, 0x4e,
|
||||||
|
0x65, 0x33, 0x3f, 0xc1, 0xfd, 0xf1, 0x8f, 0xc7, 0xf3, 0x2a, 0xde, 0xcb, 0x34, 0x5b, 0xad, 0xee,
|
||||||
|
0xf8, 0x14, 0x11, 0x91, 0x44, 0x86, 0x5f, 0x2a, 0x9d, 0x32, 0x6e, 0x70, 0x28, 0x47, 0x32, 0xee,
|
||||||
|
0x0f, 0x6b, 0xe9, 0x0b, 0xe7, 0xcd, 0xc1, 0x3d, 0x65, 0xf9, 0x8f, 0xd0, 0xb7, 0x97, 0x10, 0x05,
|
||||||
|
0x2a, 0xc8, 0xa7, 0x15, 0x34, 0xf0, 0xa5, 0x67, 0xb5, 0xba, 0x77, 0xf5, 0x2a, 0x90, 0xee, 0x0d,
|
||||||
|
0xfa, 0x9b, 0xd2, 0xa0, 0x4c, 0xa6, 0xa7, 0xf8, 0x25, 0xee, 0x0f, 0xe7, 0x90, 0x6e, 0xfc, 0x75,
|
||||||
|
0x3d, 0xee, 0xd9, 0x57, 0x5f, 0xab, 0x1b, 0xe7, 0xa4, 0xdf, 0x2d, 0x6e, 0xe7, 0xab, 0x5d, 0x04,
|
||||||
|
0xf7, 0x72, 0x2e, 0xd7, 0xa9, 0x3f, 0x08, 0xc3, 0xba, 0xeb, 0xe1, 0x45, 0x21, 0x71, 0x9e, 0x78,
|
||||||
|
0x5f, 0x7d, 0x1d, 0xab, 0xee, 0x09, 0xf7, 0x78, 0xaf, 0x8a, 0xfd, 0x96, 0xeb, 0xce, 0xde, 0x2a,
|
||||||
|
0xc9, 0x25, 0xbd, 0x0f, 0xeb, 0xae, 0x83, 0x00, 0xdd, 0x17, 0xcc, 0x9d, 0xbd, 0x3f, 0x3c, 0x6c,
|
||||||
|
0xf4, 0x7b, 0xff, 0x8b, 0x7b, 0x5a, 0x84, 0xee, 0x8f, 0xf3, 0xf2, 0x6e, 0x66, 0xf3, 0x5e, 0xd3,
|
||||||
|
0xc9, 0x2c, 0x10, 0xa0, 0x3b, 0xc8, 0xdc, 0x3d, 0xdc, 0xdd, 0x4a, 0xf4, 0x97, 0x08, 0xb6, 0x08,
|
||||||
|
0xdd, 0x2d, 0x6a, 0x1c, 0x19, 0x33, 0x84, 0xe9, 0x4e, 0xb6, 0x63, 0x7e, 0xdd, 0x9b, 0x9b, 0x9b,
|
||||||
|
0xa6, 0x4d, 0x9e, 0xf0, 0xf3, 0x4f, 0x3f, 0xa6, 0x73, 0x58, 0x0f, 0xc8, 0xec, 0xb0, 0x1e, 0xdd,
|
||||||
|
0xbf, 0x9e, 0x3f, 0xf7, 0xde, 0xdd, 0x3b, 0xed, 0xed, 0xed, 0x6f, 0x44, 0x17, 0xa0, 0xac, 0x57,
|
||||||
|
0x69, 0x25, 0xba, 0xe3, 0xcb, 0xfc, 0xf5, 0x0e, 0xc1, 0x16, 0x5e, 0xc6, 0x85, 0x95, 0xe8, 0x9e,
|
||||||
|
0x9c, 0x94, 0xf8, 0xd1, 0x07, 0xef, 0xc3, 0x45, 0x99, 0x3f, 0xfb, 0x64, 0xf2, 0xca, 0x65, 0x4b,
|
||||||
|
0x81, 0xe7, 0xc6, 0x0d, 0xbf, 0x7c, 0x3a, 0x79, 0xa2, 0xcd, 0x87, 0x1f, 0x7c, 0xbb, 0x68, 0xc1,
|
||||||
|
0x98, 0xf7, 0xdf, 0x01, 0x3e, 0xae, 0xce, 0xdb, 0x57, 0x2c, 0x5d, 0x02, 0xde, 0x8c, 0xde, 0x9e,
|
||||||
|
0x1e, 0x77, 0x17, 0x67, 0x99, 0x4c, 0xb6, 0x2f, 0x84, 0x65, 0x23, 0x87, 0x21, 0x82, 0x00, 0xdd,
|
||||||
|
0x29, 0x61, 0x66, 0xdd, 0x41, 0xde, 0x52, 0x5b, 0x5b, 0x83, 0xe6, 0xaf, 0xc2, 0xa4, 0x01, 0x77,
|
||||||
|
0x21, 0x86, 0x4b, 0x33, 0xc3, 0x72, 0x4e, 0x5f, 0x5f, 0xdf, 0xeb, 0x57, 0xc5, 0xff, 0x9e, 0xf1,
|
||||||
|
0x29, 0x38, 0x8f, 0x3e, 0x72, 0x18, 0xce, 0x6e, 0x35, 0x0b, 0x70, 0xdd, 0xc5, 0x52, 0xbd, 0x3e,
|
||||||
|
0xd5, 0x37, 0x46, 0x77, 0x95, 0x4a, 0x45, 0x78, 0x07, 0x27, 0x7c, 0x34, 0x26, 0xfe, 0x6c, 0x1c,
|
||||||
|
0xd4, 0x3d, 0xea, 0x40, 0x24, 0x38, 0xde, 0xb9, 0x7d, 0x1b, 0x1c, 0x41, 0xc2, 0x07, 0xc7, 0x2f,
|
||||||
|
0x67, 0x7d, 0xae, 0x1e, 0x58, 0x24, 0x7b, 0xc6, 0xd4, 0xc9, 0x7c, 0x09, 0x19, 0x0b, 0xd6, 0xa0,
|
||||||
|
0xfb, 0x96, 0xcd, 0xbf, 0xbb, 0xec, 0xd8, 0x86, 0xfb, 0xe4, 0x3f, 0x79, 0x8c, 0x76, 0xdd, 0xc6,
|
||||||
|
0x75, 0x07, 0x29, 0x7d, 0xe6, 0xf4, 0xa9, 0x3b, 0x9c, 0x1c, 0x4b, 0x5e, 0xbf, 0xca, 0xbe, 0xa1,
|
||||||
|
0x69, 0x98, 0x5e, 0xb6, 0xe4, 0x5b, 0xbe, 0x9c, 0x8c, 0x02, 0x6b, 0xd0, 0xfd, 0x4d, 0x04, 0x93,
|
||||||
|
0xee, 0x83, 0x9b, 0x08, 0x0d, 0xeb, 0x6e, 0x7c, 0x0c, 0xeb, 0x6e, 0x1e, 0xc8, 0xe4, 0xc3, 0xba,
|
||||||
|
0x9b, 0x03, 0xc3, 0xba, 0x9b, 0x07, 0xc3, 0xba, 0x9b, 0x07, 0x7c, 0x75, 0x07, 0xb5, 0x93, 0x45,
|
||||||
|
0xf3, 0x35, 0xeb, 0x90, 0x5f, 0x88, 0x3f, 0xf7, 0xd7, 0x35, 0xdd, 0x0e, 0xa0, 0xc3, 0xba, 0xf3,
|
||||||
|
0x03, 0x77, 0xdd, 0xe5, 0x72, 0xf9, 0xd4, 0x89, 0xe3, 0x41, 0xb1, 0x78, 0xc1, 0x5c, 0x4d, 0xcf,
|
||||||
|
0x2a, 0xd0, 0x1d, 0x36, 0xbb, 0x96, 0x97, 0x6b, 0x36, 0xf8, 0xe4, 0xa2, 0xfb, 0xa5, 0x61, 0xdd,
|
||||||
|
0x11, 0x38, 0xe9, 0x5e, 0xf4, 0x62, 0xc5, 0xd2, 0xc5, 0x68, 0xdc, 0x39, 0x41, 0x77, 0xe0, 0x26,
|
||||||
|
0x8e, 0xfb, 0xb0, 0xbd, 0xa2, 0x5c, 0xa7, 0xbb, 0xfe, 0x7e, 0x94, 0xf6, 0xfe, 0x99, 0xd0, 0xfe,
|
||||||
|
0xa9, 0x6c, 0xde, 0xb3, 0x9f, 0xde, 0x6a, 0xdd, 0xeb, 0x1f, 0xe4, 0x4e, 0x19, 0x3f, 0x0e, 0xa9,
|
||||||
|
0xfc, 0xd5, 0x97, 0x5f, 0xc8, 0x64, 0xb2, 0xd8, 0xd3, 0xa7, 0xf0, 0x49, 0x00, 0x05, 0xb9, 0xf7,
|
||||||
|
0x90, 0xee, 0xca, 0xd6, 0x16, 0xdc, 0xce, 0x8e, 0xc8, 0xbb, 0xd0, 0xbe, 0x1f, 0xd5, 0x88, 0x57,
|
||||||
|
0x66, 0xbc, 0xd5, 0xba, 0x83, 0xf4, 0x0e, 0xfe, 0xad, 0xae, 0xaa, 0xfa, 0xe0, 0xdd, 0x7f, 0x91,
|
||||||
|
0xd3, 0xfb, 0x95, 0x14, 0xed, 0x28, 0x0f, 0xa4, 0x7b, 0xe7, 0x9d, 0x9b, 0xb8, 0x1d, 0xdd, 0x7e,
|
||||||
|
0xe7, 0x9e, 0xfc, 0x36, 0x99, 0x50, 0x0f, 0xeb, 0x8e, 0x3c, 0x6f, 0x64, 0x66, 0x20, 0xdd, 0x03,
|
||||||
|
0x7c, 0x7d, 0xf0, 0xf0, 0x68, 0x04, 0x6b, 0xe3, 0x3e, 0xbd, 0xdd, 0xfb, 0xda, 0xbb, 0xfb, 0x50,
|
||||||
|
0x14, 0x7c, 0xb7, 0xbe, 0x1d, 0xd6, 0x9d, 0x1d, 0x92, 0x88, 0x10, 0x18, 0xbe, 0xe2, 0xff, 0xe6,
|
||||||
|
0x12, 0x2e, 0xed, 0x89, 0x7d, 0x8a, 0x62, 0x09, 0x4e, 0xe1, 0x31, 0xf3, 0x66, 0x58, 0x77, 0x3d,
|
||||||
|
0xb4, 0x49, 0x29, 0x36, 0x65, 0x90, 0x3d, 0xd2, 0xad, 0x16, 0xa4, 0x18, 0xd8, 0x7d, 0x10, 0x07,
|
||||||
|
0x8a, 0x05, 0xb8, 0x9d, 0x47, 0x1f, 0xa6, 0xe5, 0x73, 0x1a, 0x96, 0xcd, 0x34, 0xaf, 0x2c, 0xee,
|
||||||
|
0xcc, 0x69, 0xd6, 0xfb, 0xfd, 0x13, 0x5e, 0x82, 0xe2, 0x14, 0x17, 0x07, 0xbe, 0xfe, 0x0e, 0x21,
|
||||||
|
0x37, 0x3d, 0x62, 0x1e, 0x81, 0x5b, 0xce, 0xdd, 0xa9, 0x6a, 0xe4, 0xb0, 0xe9, 0x8b, 0x21, 0xe0,
|
||||||
|
0xab, 0x3b, 0x28, 0xbf, 0x83, 0x5c, 0xde, 0xcf, 0xdb, 0x73, 0xca, 0x04, 0x9b, 0x2d, 0xb6, 0x7f,
|
||||||
|
0x10, 0xac, 0x95, 0xcf, 0x9e, 0x0e, 0x6f, 0x11, 0xef, 0x71, 0x21, 0x5c, 0xea, 0x53, 0x28, 0x71,
|
||||||
|
0xe9, 0xa1, 0xb3, 0xf5, 0x4a, 0xd3, 0x3a, 0x6f, 0x0a, 0x57, 0x54, 0xdb, 0xa1, 0xa7, 0xfb, 0x6e,
|
||||||
|
0x37, 0x17, 0xbe, 0x8b, 0xfe, 0x00, 0x11, 0xc9, 0xb1, 0x72, 0x74, 0xe0, 0x97, 0xf0, 0xbf, 0xf4,
|
||||||
|
0xe2, 0x79, 0xd5, 0x90, 0x2c, 0x00, 0xc0, 0x57, 0x77, 0xb7, 0x9d, 0x3b, 0x4e, 0x9f, 0xd4, 0x6e,
|
||||||
|
0xd6, 0x41, 0xee, 0xb8, 0x6f, 0x3a, 0x14, 0x81, 0x92, 0xbc, 0xbc, 0xba, 0x8a, 0x70, 0xb5, 0xb7,
|
||||||
|
0x4f, 0xb5, 0x3d, 0x3c, 0x87, 0xfb, 0x83, 0x13, 0x75, 0x57, 0x63, 0x49, 0x9e, 0xe3, 0x52, 0x57,
|
||||||
|
0x86, 0xe8, 0x8e, 0x9c, 0x43, 0x50, 0xd6, 0xe5, 0x5c, 0xde, 0x55, 0x0f, 0x66, 0xe0, 0xba, 0xd7,
|
||||||
|
0x73, 0xd0, 0x5d, 0xa9, 0x54, 0xc2, 0x07, 0xdf, 0xb0, 0x6e, 0x0d, 0xe5, 0x32, 0x01, 0x48, 0x77,
|
||||||
|
0xd1, 0xc2, 0x39, 0xe4, 0xab, 0x6a, 0xcd, 0x36, 0x89, 0xa2, 0x9d, 0x07, 0xef, 0x09, 0xd4, 0xfd,
|
||||||
|
0xfc, 0xb9, 0xb3, 0x20, 0xee, 0x8f, 0x3e, 0xa0, 0x1e, 0x18, 0x4e, 0x46, 0x4a, 0x5e, 0x1d, 0x97,
|
||||||
|
0x4d, 0x84, 0x40, 0x4d, 0xfa, 0x74, 0xb6, 0x28, 0xe2, 0xea, 0x6b, 0x50, 0xd4, 0x75, 0x8e, 0xba,
|
||||||
|
0x67, 0x8b, 0x4d, 0x04, 0x45, 0xce, 0xce, 0x37, 0x3d, 0xe1, 0x3e, 0xef, 0x01, 0x9e, 0x74, 0xe0,
|
||||||
|
0xab, 0x3b, 0x42, 0xcc, 0xf1, 0x68, 0xca, 0x77, 0xbd, 0xed, 0x4a, 0x12, 0x92, 0xbe, 0x66, 0xe3,
|
||||||
|
0x3a, 0xba, 0x78, 0xe5, 0x0a, 0xd5, 0x13, 0x91, 0xf4, 0xc6, 0xf3, 0x46, 0xc2, 0x26, 0x42, 0xf8,
|
||||||
|
0x3e, 0x42, 0x75, 0xad, 0x3d, 0xd4, 0xeb, 0x42, 0xb4, 0x90, 0xbe, 0x1e, 0x46, 0x07, 0xf8, 0xcd,
|
||||||
|
0xf7, 0x26, 0x17, 0xdb, 0xf9, 0x65, 0x12, 0xd4, 0xf7, 0x3d, 0x49, 0xdc, 0x6a, 0x42, 0x18, 0xf8,
|
||||||
|
0xea, 0xbe, 0x79, 0xd3, 0x7f, 0xc3, 0xf6, 0x6a, 0x67, 0x16, 0xd0, 0xe5, 0xb1, 0x0d, 0xde, 0xbb,
|
||||||
|
0x90, 0xf4, 0xd5, 0xeb, 0x29, 0x76, 0xe2, 0xe6, 0x8e, 0x11, 0xe4, 0x8d, 0x96, 0x22, 0xc2, 0x42,
|
||||||
|
0x8d, 0xbe, 0x79, 0x13, 0x00, 0x1d, 0x83, 0x5b, 0x85, 0x8d, 0x3b, 0x22, 0x72, 0xf4, 0x13, 0x7e,
|
||||||
|
0x46, 0x41, 0x05, 0xf5, 0x66, 0x4f, 0xdc, 0x21, 0x20, 0xbd, 0x2f, 0x5b, 0xf2, 0x2d, 0x5c, 0x20,
|
||||||
|
0xa0, 0xf0, 0x1f, 0xda, 0xdd, 0xa3, 0xaa, 0x7e, 0x5c, 0x8a, 0xa4, 0xaf, 0x5a, 0xbd, 0x9c, 0x5c,
|
||||||
|
0xbc, 0xe1, 0x08, 0x8a, 0xf4, 0x3e, 0x75, 0x12, 0x71, 0xfa, 0x9a, 0x09, 0x90, 0xf3, 0xa2, 0xd1,
|
||||||
|
0xde, 0x2f, 0x03, 0x57, 0x5f, 0x40, 0xa3, 0x07, 0x0e, 0xc1, 0xf9, 0x0c, 0x2b, 0x44, 0xf3, 0x67,
|
||||||
|
0x21, 0xe9, 0x81, 0x6b, 0x3a, 0x18, 0x26, 0xc0, 0x08, 0x51, 0x77, 0xf0, 0x49, 0x01, 0xbf, 0xb9,
|
||||||
|
0x97, 0xc7, 0x2e, 0x01, 0xb6, 0x0c, 0x47, 0x64, 0x62, 0x21, 0x2e, 0x3d, 0xe5, 0x72, 0xa8, 0x1c,
|
||||||
|
0xd1, 0x3d, 0x64, 0xba, 0x03, 0x54, 0xad, 0x5d, 0x89, 0x4b, 0x5f, 0x32, 0x61, 0x8c, 0x24, 0x34,
|
||||||
|
0xb0, 0xe7, 0xb5, 0x01, 0xf5, 0xa6, 0x49, 0x36, 0x63, 0x79, 0x0d, 0x3e, 0x95, 0x84, 0x07, 0xd7,
|
||||||
|
0xbb, 0x38, 0x11, 0x9d, 0xeb, 0xd6, 0x41, 0xb7, 0x4d, 0xeb, 0xdc, 0xb7, 0x37, 0xf8, 0x7a, 0x48,
|
||||||
|
0x22, 0xf7, 0x4a, 0x13, 0xe2, 0x15, 0xcd, 0x4c, 0xd3, 0xfa, 0xcf, 0xdc, 0xd2, 0x5b, 0x0b, 0x35,
|
||||||
|
0xe2, 0x1a, 0x71, 0xce, 0x2e, 0x47, 0x0c, 0xa9, 0xee, 0x00, 0x4d, 0x51, 0xe1, 0x7a, 0xd2, 0x0f,
|
||||||
|
0xb8, 0xd2, 0x69, 0xe3, 0x2b, 0x97, 0x2e, 0xaa, 0x73, 0xda, 0x2c, 0xf6, 0x76, 0xc7, 0x37, 0x6c,
|
||||||
|
0x12, 0x7b, 0x03, 0xe7, 0x8e, 0x5c, 0x6f, 0x49, 0xb1, 0x9e, 0xee, 0xe5, 0xe5, 0x65, 0xa8, 0x1c,
|
||||||
|
0xf9, 0xfd, 0x77, 0xff, 0xe1, 0x12, 0x7d, 0x43, 0x80, 0x17, 0x39, 0x7a, 0x56, 0x57, 0xfe, 0xc5,
|
||||||
|
0xa7, 0xa0, 0xf2, 0xdd, 0xf7, 0xff, 0xec, 0x9d, 0x89, 0x5f, 0x13, 0xd7, 0x16, 0xc7, 0xfb, 0x5f,
|
||||||
|
0xbc, 0xf7, 0xda, 0x5a, 0x14, 0x77, 0xad, 0x5b, 0x15, 0xad, 0xf5, 0xa9, 0x7d, 0xad, 0xda, 0xd6,
|
||||||
|
0x7d, 0xa9, 0xd6, 0x3e, 0x6b, 0xfb, 0xac, 0x56, 0x16, 0x51, 0xeb, 0xc6, 0xbe, 0x2f, 0x82, 0xec,
|
||||||
|
0x82, 0x80, 0x80, 0x28, 0xe0, 0x02, 0x88, 0x0b, 0x0a, 0x88, 0x82, 0x08, 0xa8, 0xb8, 0x20, 0x04,
|
||||||
|
0x65, 0x87, 0x04, 0x42, 0x20, 0x40, 0x16, 0x08, 0x7b, 0xf6, 0xc4, 0x77, 0x71, 0x70, 0x98, 0xcc,
|
||||||
|
0x4c, 0x26, 0x93, 0x98, 0x15, 0xe7, 0xfb, 0x39, 0x1f, 0x3f, 0x71, 0x32, 0x73, 0xb9, 0x73, 0xf2,
|
||||||
|
0xcb, 0xcd, 0xbd, 0x73, 0xef, 0x3d, 0x87, 0xd3, 0x85, 0x5b, 0x66, 0x45, 0x8b, 0x4a, 0xf8, 0x8c,
|
||||||
|
0x4a, 0xba, 0x2e, 0x6d, 0xa8, 0xa1, 0xfd, 0x0e, 0x50, 0x0c, 0x0f, 0x75, 0x9d, 0x70, 0xd4, 0xe1,
|
||||||
|
0xf6, 0xc5, 0x4d, 0xaa, 0x7e, 0x87, 0x1e, 0xcb, 0xc1, 0x26, 0x25, 0x11, 0xe5, 0x52, 0x37, 0xbf,
|
||||||
|
0xc3, 0xc6, 0xf1, 0x76, 0x95, 0x0f, 0x0e, 0x62, 0x8b, 0xa5, 0x77, 0x0d, 0x21, 0x5d, 0xaf, 0x43,
|
||||||
|
0x00, 0x65, 0x23, 0xf8, 0x1d, 0x42, 0xca, 0xe9, 0x06, 0x8d, 0x0c, 0x50, 0xba, 0x8e, 0x7e, 0x07,
|
||||||
|
0x5e, 0x86, 0x72, 0xc3, 0x1d, 0x76, 0xb0, 0x83, 0x5e, 0x30, 0x18, 0x9a, 0x83, 0x1e, 0x80, 0xaf,
|
||||||
|
0x1b, 0x99, 0x24, 0x71, 0xe0, 0xe3, 0xe9, 0x3a, 0x71, 0xb8, 0x6d, 0xf3, 0x0f, 0xa0, 0x29, 0xc4,
|
||||||
|
0xd6, 0x03, 0x37, 0xae, 0x66, 0x35, 0x73, 0x5c, 0xf5, 0xc7, 0x23, 0x4a, 0xb5, 0x75, 0x87, 0x8a,
|
||||||
|
0xdf, 0x05, 0x06, 0xf4, 0x3b, 0x0c, 0xe8, 0xdb, 0xf4, 0x65, 0x5d, 0x03, 0x23, 0x5b, 0x5e, 0x68,
|
||||||
|
0x20, 0xc7, 0xc7, 0x95, 0x20, 0x4f, 0x1c, 0xba, 0x9d, 0x81, 0xf0, 0xf5, 0xd6, 0x31, 0x0c, 0x2f,
|
||||||
|
0x49, 0xa4, 0x5d, 0x9d, 0xdc, 0x20, 0x1f, 0xb4, 0xf0, 0xfd, 0xdc, 0xb1, 0x67, 0xc6, 0xe4, 0x34,
|
||||||
|
0x21, 0x1a, 0x7a, 0xed, 0x7e, 0x63, 0x8d, 0xef, 0x77, 0xad, 0x30, 0x81, 0xdf, 0x21, 0x40, 0xd3,
|
||||||
|
0x81, 0x0c, 0x12, 0x00, 0x8c, 0x6d, 0xff, 0x27, 0xf6, 0x34, 0xa7, 0xa4, 0x57, 0x63, 0xee, 0xd3,
|
||||||
|
0x32, 0x81, 0x35, 0x39, 0xbf, 0xeb, 0x12, 0x5a, 0x40, 0x2f, 0x98, 0xcc, 0xef, 0x10, 0x52, 0x2e,
|
||||||
|
0x67, 0x34, 0xda, 0xce, 0x7b, 0xd7, 0x83, 0x9e, 0x00, 0xea, 0x84, 0x11, 0xc4, 0xb6, 0x0d, 0xdf,
|
||||||
|
0x4c, 0xf4, 0xb6, 0x47, 0x02, 0x28, 0xbf, 0x6b, 0x86, 0xb1, 0x64, 0xde, 0xf8, 0x30, 0x24, 0x26,
|
||||||
|
0x1c, 0xf5, 0xae, 0xe7, 0xd5, 0xf1, 0x4e, 0x3d, 0xf9, 0x32, 0x29, 0xbf, 0x93, 0x82, 0xb5, 0x7b,
|
||||||
|
0x1b, 0xec, 0x7a, 0x51, 0x23, 0x3a, 0xe9, 0x24, 0xec, 0xc1, 0xd0, 0x6c, 0xb2, 0xad, 0xbc, 0x88,
|
||||||
|
0xf2, 0x3b, 0x19, 0x14, 0x42, 0x21, 0xec, 0x77, 0xd6, 0xcf, 0xe8, 0xf4, 0x3e, 0xae, 0x29, 0x63,
|
||||||
|
0x31, 0xc2, 0x1c, 0xfc, 0xc9, 0x06, 0x1d, 0xa1, 0xfc, 0x4e, 0x96, 0xbe, 0x8c, 0xcb, 0xb0, 0xeb,
|
||||||
|
0x51, 0x79, 0x20, 0x68, 0x88, 0x91, 0x14, 0xbb, 0x97, 0x54, 0x0c, 0x5d, 0xca, 0xef, 0x5a, 0xc0,
|
||||||
|
0x5c, 0xff, 0x1d, 0xe4, 0x91, 0xf6, 0xdd, 0xdb, 0x50, 0x6f, 0xc1, 0x8b, 0xb3, 0xa2, 0x30, 0xd9,
|
||||||
|
0x52, 0x70, 0x41, 0xfa, 0xbd, 0x93, 0xf2, 0x3b, 0x31, 0xfd, 0xb7, 0xb3, 0x60, 0xc9, 0x2b, 0xc4,
|
||||||
|
0x2a, 0xce, 0x72, 0x49, 0x1e, 0x0b, 0xa6, 0xec, 0x9e, 0x5c, 0x41, 0xa6, 0xa8, 0x09, 0xe5, 0xf7,
|
||||||
|
0x4e, 0x36, 0xfb, 0xd6, 0x4d, 0x1d, 0xb3, 0xee, 0x91, 0x84, 0xfe, 0xe5, 0x34, 0xc8, 0x29, 0xbd,
|
||||||
|
0x97, 0x12, 0x91, 0xc7, 0xa3, 0xee, 0x8e, 0x8d, 0xa1, 0x48, 0xc6, 0x95, 0x9a, 0x50, 0x7e, 0x9f,
|
||||||
|
0x37, 0x6b, 0xba, 0xa1, 0x37, 0x0d, 0x77, 0x9d, 0x3c, 0x0c, 0x39, 0xa5, 0xdb, 0xc3, 0x09, 0x79,
|
||||||
|
0xbc, 0xae, 0x63, 0x50, 0xab, 0xc7, 0x35, 0x13, 0xca, 0xef, 0x56, 0x9f, 0xfe, 0xe3, 0x72, 0x6a,
|
||||||
|
0xca, 0x51, 0x47, 0x07, 0xc3, 0x55, 0x08, 0x7e, 0xbe, 0xda, 0xb2, 0x72, 0x29, 0xf2, 0xf8, 0x90,
|
||||||
|
0x48, 0xed, 0xbe, 0x77, 0x5c, 0x26, 0x8e, 0xdf, 0x23, 0x42, 0x43, 0xdc, 0x9c, 0x47, 0x35, 0x68,
|
||||||
|
0xd0, 0xd0, 0x10, 0x83, 0x0f, 0xf2, 0x20, 0xa7, 0xd0, 0xe7, 0x4e, 0x45, 0xbd, 0x05, 0xfb, 0xb1,
|
||||||
|
0xba, 0x5d, 0x73, 0x3c, 0xaf, 0x89, 0xe3, 0x77, 0xd8, 0xdd, 0x0b, 0xe6, 0xce, 0x82, 0x76, 0x4d,
|
||||||
|
0x62, 0xf1, 0xf3, 0xf6, 0xc2, 0x3d, 0x4e, 0x1e, 0x51, 0x53, 0x3d, 0xfc, 0xd3, 0x8a, 0x7a, 0xeb,
|
||||||
|
0xa0, 0xfb, 0x58, 0x4c, 0xe4, 0x17, 0x74, 0xfc, 0xc8, 0xbd, 0x2a, 0xe5, 0x4c, 0x0c, 0xbf, 0xf7,
|
||||||
|
0xf7, 0xf5, 0x41, 0x6b, 0x4b, 0x80, 0xfd, 0xb4, 0x76, 0x6c, 0x57, 0x7c, 0x56, 0x66, 0xc6, 0xc6,
|
||||||
|
0x1f, 0xd7, 0xce, 0xb4, 0xb6, 0x3a, 0x7e, 0xc4, 0x71, 0xf6, 0x34, 0x6b, 0x70, 0x04, 0xbc, 0x1e,
|
||||||
|
0x2d, 0xc1, 0xcb, 0x63, 0xc5, 0xd2, 0x25, 0x8f, 0x4b, 0x48, 0x65, 0x63, 0x46, 0x21, 0xa6, 0x37,
|
||||||
|
0xa9, 0xf5, 0xfb, 0xfb, 0x58, 0xd4, 0x4f, 0x1a, 0x34, 0xcf, 0x84, 0x4c, 0x10, 0xbf, 0xaf, 0x5f,
|
||||||
|
0xf7, 0x7d, 0x5a, 0xca, 0x25, 0xe4, 0x3e, 0x79, 0xb9, 0x5c, 0x0e, 0xfc, 0x0e, 0xde, 0x6a, 0x6c,
|
||||||
|
0xa8, 0xe7, 0xf1, 0x46, 0xe3, 0x4c, 0x97, 0xbf, 0x7c, 0x01, 0xf9, 0xfd, 0xce, 0xed, 0x5b, 0xe0,
|
||||||
|
0x5f, 0x28, 0x15, 0xb1, 0xb6, 0x90, 0xf1, 0xfb, 0xe3, 0x7a, 0xcd, 0x01, 0xc0, 0x27, 0x88, 0xdf,
|
||||||
|
0x51, 0x6d, 0xba, 0xfd, 0x5f, 0xfb, 0xf7, 0xfc, 0xb2, 0x13, 0xf2, 0x3b, 0x9d, 0xde, 0x2c, 0x14,
|
||||||
|
0x8e, 0x06, 0x0a, 0x7c, 0xf9, 0xe2, 0x39, 0xe4, 0x77, 0x48, 0xe9, 0xa8, 0x80, 0x80, 0x24, 0x11,
|
||||||
|
0x33, 0x9a, 0x35, 0xfa, 0xbd, 0x54, 0x4b, 0xbf, 0xb3, 0x2d, 0xd4, 0xef, 0x39, 0x77, 0xb2, 0x51,
|
||||||
|
0x8b, 0x3b, 0xa0, 0x88, 0x05, 0x94, 0xdf, 0x75, 0xc6, 0xbc, 0xc6, 0xab, 0x6f, 0x49, 0xfa, 0xbd,
|
||||||
|
0x8e, 0xf2, 0xbb, 0xbe, 0x11, 0xb7, 0xd0, 0xd5, 0xfb, 0x7d, 0x2c, 0xab, 0x58, 0x49, 0x1d, 0x4e,
|
||||||
|
0xda, 0x02, 0x14, 0xa4, 0xfc, 0x5e, 0x47, 0xf9, 0xfd, 0x3d, 0x64, 0xfc, 0x5e, 0x54, 0xc3, 0xd5,
|
||||||
|
0x58, 0x0e, 0xa5, 0x77, 0xed, 0x90, 0xb2, 0xdb, 0x61, 0xbf, 0x2b, 0x65, 0x32, 0xe4, 0x5b, 0x76,
|
||||||
|
0x3e, 0x63, 0xe9, 0x51, 0x92, 0x1e, 0x30, 0x34, 0x96, 0xd3, 0xd1, 0x3b, 0x1e, 0x1a, 0xbf, 0x7f,
|
||||||
|
0x44, 0x65, 0x41, 0xca, 0xf8, 0x7a, 0x0a, 0xba, 0x7e, 0x92, 0x60, 0xe9, 0x80, 0xd9, 0xf9, 0x5d,
|
||||||
|
0x21, 0x1c, 0x81, 0xfd, 0x22, 0xe5, 0xa8, 0xec, 0x59, 0x71, 0x8e, 0x7b, 0x0e, 0xf9, 0xd1, 0xed,
|
||||||
|
0x62, 0xa5, 0xc6, 0x72, 0x62, 0xf3, 0xde, 0x27, 0x6c, 0x52, 0x9d, 0x10, 0x97, 0xf5, 0xf0, 0xe1,
|
||||||
|
0xf2, 0x65, 0x3c, 0xcd, 0xdf, 0x1b, 0x03, 0x61, 0x76, 0x7e, 0x07, 0xd0, 0xe7, 0x4e, 0x85, 0xfc,
|
||||||
|
0xd2, 0x97, 0x75, 0x0d, 0x79, 0xfc, 0x4c, 0xf6, 0xf8, 0xb2, 0x0e, 0xae, 0xa6, 0x47, 0x34, 0xb6,
|
||||||
|
0x9e, 0x63, 0x4b, 0xec, 0xbd, 0x53, 0xab, 0x90, 0xc7, 0x07, 0x1f, 0xde, 0x1f, 0xf3, 0xfb, 0x4c,
|
||||||
|
0x2b, 0xbd, 0xd7, 0x9c, 0x3c, 0xe6, 0xe8, 0x77, 0xd6, 0x7f, 0x77, 0x40, 0xae, 0xc1, 0xa6, 0x93,
|
||||||
|
0x81, 0x43, 0xba, 0x1f, 0x0b, 0x7d, 0x44, 0x50, 0x82, 0xe7, 0xe5, 0xf1, 0x74, 0x2a, 0xcf, 0x1a,
|
||||||
|
0x55, 0x36, 0xfb, 0x72, 0x4f, 0x8f, 0x2d, 0xdd, 0x61, 0xae, 0xff, 0x4e, 0xef, 0x35, 0x27, 0x8f,
|
||||||
|
0x39, 0xfa, 0x9d, 0x17, 0x15, 0x32, 0xf6, 0x48, 0xf2, 0x9b, 0xaf, 0x50, 0x6f, 0x05, 0xdf, 0x6e,
|
||||||
|
0x84, 0x1d, 0x7a, 0x22, 0xfe, 0x25, 0x07, 0x2f, 0x09, 0x96, 0x4b, 0xca, 0x78, 0xc2, 0x26, 0x4f,
|
||||||
|
0xcc, 0x2e, 0x06, 0xc6, 0xe2, 0xb9, 0x50, 0xe1, 0xbc, 0x88, 0x60, 0x43, 0xdd, 0x00, 0x09, 0xcc,
|
||||||
|
0xd1, 0xef, 0xf2, 0x3e, 0x01, 0xdc, 0x04, 0x0f, 0x3d, 0x2a, 0x40, 0xbd, 0xeb, 0x72, 0x71, 0x7c,
|
||||||
|
0xcb, 0x28, 0x30, 0xd7, 0xa4, 0x57, 0xe1, 0x77, 0x9b, 0x32, 0x9e, 0xb6, 0x9f, 0xcd, 0x69, 0xf2,
|
||||||
|
0x48, 0xa1, 0xc1, 0xcf, 0xce, 0x80, 0xd9, 0x79, 0xdf, 0x43, 0x5d, 0x3b, 0x54, 0xfa, 0x68, 0x7c,
|
||||||
|
0xd5, 0x42, 0xcd, 0x1b, 0x63, 0xdd, 0x10, 0x0e, 0xe6, 0xe8, 0x77, 0x40, 0xfb, 0x6f, 0x3b, 0xc7,
|
||||||
|
0x5a, 0x83, 0x8d, 0x6b, 0xb0, 0xef, 0xfa, 0xc6, 0x3e, 0x41, 0xba, 0x1e, 0xd7, 0x0e, 0xf9, 0x17,
|
||||||
|
0x74, 0x60, 0x66, 0xc0, 0x59, 0xbb, 0xb7, 0xbe, 0x7f, 0xb8, 0x6f, 0x63, 0x94, 0xfb, 0x50, 0x8b,
|
||||||
|
0x99, 0xfa, 0x7d, 0x20, 0xe7, 0x16, 0x2c, 0xcc, 0x9e, 0xb8, 0xb3, 0xd8, 0x13, 0x42, 0xee, 0x34,
|
||||||
|
0x11, 0x38, 0x3d, 0x38, 0x0b, 0x67, 0xe1, 0x63, 0x4f, 0xfc, 0x59, 0xb8, 0xcc, 0xbe, 0x1b, 0xe9,
|
||||||
|
0x86, 0xbf, 0x09, 0x22, 0xcc, 0xd4, 0xef, 0x80, 0x76, 0xc4, 0x4a, 0x26, 0xdc, 0xb5, 0xda, 0x0a,
|
||||||
|
0xa5, 0xf2, 0x62, 0x51, 0xab, 0x4f, 0x4a, 0xa5, 0x7d, 0x40, 0xc1, 0xe8, 0xbe, 0xe4, 0x80, 0x42,
|
||||||
|
0xb7, 0x0b, 0xa0, 0xcd, 0x69, 0x46, 0xa5, 0x6a, 0x82, 0x40, 0x76, 0x1f, 0x99, 0x3f, 0xfd, 0xc7,
|
||||||
|
0xf0, 0xd5, 0xd7, 0x80, 0xf9, 0xfa, 0x5d, 0x21, 0x11, 0xc3, 0x9e, 0xa2, 0xcf, 0x9f, 0x21, 0xac,
|
||||||
|
0xae, 0xd2, 0x7c, 0x8d, 0x1a, 0x24, 0x6d, 0x4c, 0xd0, 0xb0, 0x98, 0xc3, 0x70, 0x09, 0x66, 0xdc,
|
||||||
|
0xef, 0x4a, 0xa5, 0x12, 0xb5, 0x4f, 0xfe, 0x52, 0xf2, 0x05, 0x13, 0xd6, 0x0c, 0x00, 0xfa, 0xef,
|
||||||
|
0xb0, 0xb3, 0x9a, 0xf1, 0xd6, 0xef, 0x91, 0x41, 0x31, 0x32, 0xd2, 0x3c, 0x6b, 0xf2, 0x78, 0xab,
|
||||||
|
0x85, 0xb7, 0xd6, 0xde, 0xf8, 0xa8, 0xe8, 0xdd, 0xee, 0xaf, 0xfd, 0xda, 0xee, 0x93, 0x37, 0x34,
|
||||||
|
0xfc, 0xf7, 0x7d, 0x4a, 0xc8, 0xf8, 0xd1, 0x61, 0x5a, 0x5d, 0xde, 0x93, 0x70, 0x0e, 0x79, 0x39,
|
||||||
|
0x2f, 0xd4, 0x34, 0x41, 0xa2, 0xb1, 0xa8, 0xdd, 0x27, 0xff, 0xaa, 0xfc, 0xa5, 0x49, 0x2a, 0x84,
|
||||||
|
0x42, 0xa9, 0x50, 0xf0, 0x11, 0xe9, 0xc5, 0x80, 0x31, 0xbe, 0x5e, 0x88, 0xca, 0xbb, 0x84, 0xcb,
|
||||||
|
0x40, 0xde, 0x5d, 0xe6, 0xda, 0x55, 0x2a, 0x4e, 0x0f, 0x0b, 0x54, 0xca, 0xb5, 0x4e, 0x2c, 0x66,
|
||||||
|
0x20, 0xd0, 0x7e, 0x8f, 0x8d, 0x3e, 0x0b, 0x9c, 0x3e, 0xcd, 0xea, 0x73, 0x93, 0xd4, 0x46, 0x1d,
|
||||||
|
0x3d, 0x09, 0x31, 0x48, 0x0f, 0x8e, 0x7a, 0xdf, 0x66, 0x1e, 0x18, 0x79, 0xf6, 0xdf, 0xcc, 0x90,
|
||||||
|
0x71, 0x39, 0xe0, 0xb3, 0x79, 0xfb, 0xee, 0x13, 0x02, 0x1d, 0xff, 0x81, 0xbc, 0x3b, 0x1c, 0x7f,
|
||||||
|
0x4f, 0x86, 0xcd, 0x7c, 0xd4, 0xf9, 0xbd, 0xc9, 0xf1, 0xa6, 0xbe, 0x09, 0x15, 0xf0, 0xf7, 0xc9,
|
||||||
|
0xf7, 0x10, 0x6e, 0x75, 0x34, 0x09, 0xe2, 0x16, 0x3a, 0x6b, 0xc7, 0x46, 0x94, 0x37, 0xc9, 0x18,
|
||||||
|
0x73, 0xf3, 0x3a, 0x31, 0xbd, 0xd1, 0xd4, 0xd5, 0x47, 0xf3, 0x49, 0xfe, 0xbd, 0x7b, 0x28, 0xb3,
|
||||||
|
0x3d, 0xb0, 0x1f, 0x7b, 0xd0, 0x4c, 0x2c, 0x27, 0x2d, 0xe5, 0xa6, 0x87, 0x6b, 0xd6, 0xb1, 0xc3,
|
||||||
|
0xea, 0x0c, 0xe9, 0xf1, 0xb6, 0xad, 0x3f, 0x0d, 0x95, 0x14, 0x69, 0xf6, 0x81, 0x29, 0xc0, 0xd1,
|
||||||
|
0xbb, 0xf9, 0x23, 0x65, 0x77, 0xf0, 0x22, 0xcf, 0xb4, 0x6d, 0x5a, 0x07, 0xcf, 0x60, 0x8c, 0xdb,
|
||||||
|
0x8c, 0x2f, 0xda, 0x36, 0xaf, 0xe3, 0x45, 0x85, 0x80, 0xef, 0x87, 0xa9, 0xab, 0x49, 0x84, 0x45,
|
||||||
|
0xfa, 0x1d, 0x09, 0x68, 0xd3, 0x25, 0xad, 0x0c, 0x71, 0x53, 0xbd, 0x84, 0xd9, 0x82, 0x3b, 0xbc,
|
||||||
|
0x32, 0x4f, 0x2c, 0xde, 0xef, 0x14, 0x1f, 0x8e, 0x50, 0x22, 0x6f, 0xe8, 0x1c, 0xcc, 0x2e, 0xef,
|
||||||
|
0x8c, 0xcc, 0x69, 0xf6, 0xcf, 0xaa, 0xf7, 0xcf, 0xa8, 0xf1, 0x4e, 0xab, 0xf2, 0x48, 0x7e, 0xe5,
|
||||||
|
0x92, 0xf0, 0xf2, 0xe4, 0xb9, 0x67, 0xce, 0xf1, 0xcf, 0xdd, 0x93, 0xca, 0xbd, 0x53, 0x68, 0x3e,
|
||||||
|
0x57, 0xde, 0xf8, 0x67, 0xd6, 0x05, 0xdd, 0x6a, 0x4c, 0x2a, 0x6c, 0x2d, 0x6b, 0xec, 0x69, 0xef,
|
||||||
|
0x11, 0x8a, 0xa5, 0xe6, 0xd2, 0x3f, 0x24, 0x09, 0x25, 0xf7, 0x8f, 0x91, 0x4a, 0x66, 0x7f, 0x78,
|
||||||
|
0x0e, 0xdd, 0xe7, 0x6a, 0xf5, 0xa1, 0xa0, 0x22, 0x5b, 0xcf, 0x3c, 0x8d, 0xcf, 0x76, 0x09, 0xcc,
|
||||||
|
0xd6, 0x3b, 0xdf, 0x29, 0xf6, 0x79, 0x40, 0x56, 0xfd, 0xed, 0x97, 0x9d, 0x03, 0x42, 0xcd, 0x71,
|
||||||
|
0x15, 0x4c, 0xcb, 0x27, 0x4a, 0x25, 0x18, 0xc2, 0x69, 0x66, 0xcd, 0xb7, 0x2b, 0x83, 0x02, 0xfc,
|
||||||
|
0xc9, 0x9c, 0x49, 0x61, 0x9e, 0xbc, 0x66, 0xf6, 0x85, 0x67, 0x37, 0x38, 0xc7, 0x3d, 0x3b, 0xe8,
|
||||||
|
0x76, 0x97, 0x84, 0xe9, 0xa8, 0x7e, 0x3b, 0xef, 0x7b, 0x41, 0x19, 0xd5, 0x29, 0x25, 0xac, 0xde,
|
||||||
|
0x21, 0x89, 0x66, 0xf5, 0x19, 0x1d, 0x52, 0xad, 0xfb, 0x2f, 0x3b, 0xb6, 0x41, 0x4f, 0x6c, 0x62,
|
||||||
|
0xa3, 0x71, 0xe6, 0x1f, 0x28, 0xcc, 0x99, 0x56, 0xee, 0xf0, 0xe9, 0x9b, 0x0d, 0xa4, 0x62, 0x5b,
|
||||||
|
0xba, 0xe7, 0xda, 0x07, 0x14, 0x1e, 0x8d, 0x7c, 0xec, 0x7a, 0xe1, 0x95, 0x47, 0xda, 0x6b, 0xaf,
|
||||||
|
0x6b, 0x35, 0x3e, 0x19, 0xb5, 0xfe, 0xd7, 0xeb, 0xfd, 0xae, 0xd7, 0xf9, 0x66, 0xd4, 0xfa, 0x5c,
|
||||||
|
0xab, 0xf1, 0x4a, 0xa5, 0x9d, 0x38, 0xf7, 0xcc, 0x21, 0xb0, 0xd0, 0xce, 0x3b, 0x9f, 0x8c, 0xf4,
|
||||||
|
0xdd, 0x93, 0x2b, 0xe2, 0x1e, 0xb4, 0x98, 0xda, 0x01, 0x2a, 0x68, 0x90, 0xbb, 0x4c, 0x26, 0xfb,
|
||||||
|
0x7e, 0xf5, 0x4a, 0xe4, 0x83, 0x61, 0x2f, 0x77, 0x57, 0xe3, 0xd4, 0x8c, 0xe2, 0x03, 0x49, 0x29,
|
||||||
|
0x6e, 0x73, 0x3a, 0xf3, 0x90, 0x68, 0xfa, 0x39, 0xb8, 0xc8, 0xe5, 0x22, 0x2d, 0xe2, 0x4e, 0xe3,
|
||||||
|
0xf3, 0xa6, 0xde, 0x41, 0x91, 0x4c, 0x73, 0x89, 0x08, 0xe4, 0x0a, 0x25, 0x83, 0x33, 0x7c, 0xa5,
|
||||||
|
0xb4, 0x0d, 0x7c, 0x25, 0x8e, 0x84, 0x15, 0x13, 0xfc, 0x15, 0x87, 0xc0, 0x87, 0xbe, 0x99, 0x75,
|
||||||
|
0x8d, 0x9d, 0x43, 0x06, 0xba, 0x4d, 0xad, 0x20, 0x92, 0xfb, 0xf0, 0xf0, 0xf0, 0x92, 0x85, 0xf3,
|
||||||
|
0x50, 0xf3, 0x4f, 0xc0, 0xec, 0xfe, 0xda, 0x6f, 0xb4, 0xfa, 0x51, 0xe8, 0xc0, 0xe5, 0xe2, 0x56,
|
||||||
|
0xc7, 0xc0, 0x42, 0x75, 0x4d, 0xb8, 0x73, 0xdc, 0xf3, 0xf4, 0x52, 0x26, 0x7f, 0x50, 0xcf, 0x9d,
|
||||||
|
0x0d, 0x5a, 0x8b, 0xc0, 0x2f, 0xb3, 0xce, 0xc1, 0xef, 0xbe, 0x3a, 0xdd, 0xbb, 0x5f, 0xa9, 0x16,
|
||||||
|
0x4b, 0xb4, 0xfb, 0x52, 0xe9, 0x1d, 0xb5, 0x72, 0xe7, 0x72, 0x38, 0xb3, 0xa7, 0x4d, 0xc1, 0x6a,
|
||||||
|
0x1d, 0xb2, 0xed, 0x98, 0xf7, 0xe3, 0xca, 0x00, 0x00, 0x15, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x9b,
|
||||||
|
0x37, 0xea, 0x10, 0x65, 0x8d, 0xc2, 0xd0, 0x94, 0x56, 0x73, 0x8e, 0x45, 0x97, 0xe1, 0xaa, 0xcd,
|
||||||
|
0x29, 0xb9, 0xf2, 0x5a, 0x09, 0xd3, 0x08, 0x75, 0x60, 0x72, 0x87, 0x42, 0x33, 0x6b, 0xd4, 0x89,
|
||||||
|
0xde, 0x3f, 0xa3, 0x76, 0x60, 0xc4, 0x64, 0x23, 0x5a, 0x7c, 0xb9, 0x83, 0x3e, 0x4c, 0x72, 0x62,
|
||||||
|
0x42, 0x42, 0x7c, 0x2c, 0x6c, 0xbb, 0x77, 0x6e, 0x77, 0x73, 0x3a, 0x85, 0x3c, 0x92, 0x97, 0x73,
|
||||||
|
0xd7, 0xc8, 0x75, 0xa5, 0x20, 0x00, 0xf4, 0x16, 0xfc, 0xd3, 0xaa, 0x70, 0x15, 0xe6, 0x9b, 0x4a,
|
||||||
|
0x13, 0x0c, 0x9a, 0x20, 0x21, 0x77, 0x54, 0x4e, 0xb3, 0x63, 0x60, 0x01, 0xb6, 0x3e, 0x87, 0x43,
|
||||||
|
0x8a, 0xb3, 0x9f, 0xeb, 0x2d, 0xe2, 0xb9, 0x56, 0x90, 0x7d, 0x10, 0x19, 0x7c, 0x3a, 0xe0, 0xd9,
|
||||||
|
0xd3, 0xa7, 0x06, 0xad, 0x0a, 0x85, 0xce, 0xe4, 0x55, 0x74, 0xe1, 0x0e, 0x46, 0x3d, 0x92, 0xca,
|
||||||
|
0x69, 0xad, 0x9a, 0xf7, 0xb4, 0x23, 0x91, 0x76, 0xb1, 0x45, 0x75, 0x35, 0x7d, 0x59, 0xe9, 0xbd,
|
||||||
|
0x17, 0xe2, 0xf9, 0xe7, 0x22, 0xf9, 0x51, 0x21, 0xfc, 0x73, 0x11, 0xbd, 0x17, 0xe2, 0xfa, 0xb2,
|
||||||
|
0xae, 0x0d, 0xbf, 0x28, 0x43, 0xed, 0x00, 0x21, 0x43, 0xc8, 0xed, 0x46, 0x78, 0x23, 0x20, 0xd2,
|
||||||
|
0x7c, 0xb4, 0x4f, 0x76, 0xf5, 0xe1, 0x50, 0x72, 0xb7, 0x78, 0xe2, 0xee, 0x33, 0xb0, 0x69, 0x23,
|
||||||
|
0x6c, 0xdd, 0x73, 0x42, 0x49, 0x47, 0xb2, 0x1e, 0xc8, 0xcd, 0xe6, 0x06, 0x78, 0xc1, 0xd9, 0xa9,
|
||||||
|
0x34, 0x5a, 0xeb, 0xea, 0x65, 0x1c, 0x6f, 0x17, 0x41, 0x7a, 0x9a, 0x8c, 0xaf, 0x79, 0x3f, 0x25,
|
||||||
|
0x60, 0x70, 0x44, 0xea, 0x96, 0xfa, 0x1a, 0xab, 0x78, 0xaf, 0xb4, 0xaa, 0x1e, 0x7d, 0x0f, 0x21,
|
||||||
|
0x88, 0xa1, 0xe4, 0x6e, 0xd9, 0xc4, 0x03, 0xad, 0x7b, 0xa3, 0xb5, 0xee, 0x94, 0x54, 0xc1, 0xe6,
|
||||||
|
0x8f, 0x68, 0xbc, 0xb6, 0x3f, 0xfb, 0x46, 0xc7, 0x81, 0xbd, 0xcd, 0xef, 0xf7, 0x90, 0xe9, 0x66,
|
||||||
|
0x6d, 0x1b, 0xd6, 0x08, 0xd2, 0x92, 0xc9, 0x54, 0x35, 0xf8, 0x66, 0x03, 0xb6, 0x99, 0xf7, 0x48,
|
||||||
|
0xae, 0x60, 0x70, 0x86, 0x3f, 0xd8, 0x0d, 0x64, 0xa1, 0xe4, 0x6e, 0xc1, 0x5c, 0x2f, 0xeb, 0xb0,
|
||||||
|
0x0f, 0x40, 0x3f, 0x81, 0x71, 0x4e, 0x2c, 0x6f, 0xd1, 0x24, 0x20, 0xc1, 0xd5, 0x14, 0xe4, 0x6a,
|
||||||
|
0x74, 0xac, 0xd1, 0xe7, 0x4e, 0x6d, 0x5d, 0xb5, 0x0c, 0x48, 0xb9, 0x6d, 0xdb, 0x7a, 0xe6, 0xfa,
|
||||||
|
0xef, 0x5b, 0xbf, 0x5f, 0x41, 0x5f, 0x30, 0x93, 0x68, 0x25, 0xde, 0x86, 0xef, 0x05, 0x29, 0x9a,
|
||||||
|
0x97, 0x8c, 0x47, 0xe7, 0x36, 0x63, 0x9f, 0xd9, 0xfb, 0xa4, 0xd7, 0x48, 0x64, 0x0a, 0x3d, 0xb9,
|
||||||
|
0x44, 0x03, 0x94, 0xdc, 0x2d, 0x95, 0x3a, 0xf6, 0xa0, 0x7b, 0xe2, 0x4b, 0x94, 0x74, 0x4e, 0xc4,
|
||||||
|
0x94, 0x55, 0xb6, 0x12, 0xa5, 0xff, 0x91, 0xb0, 0xda, 0x3a, 0x8f, 0xda, 0xe1, 0xb7, 0xd3, 0x9b,
|
||||||
|
0x7f, 0xe0, 0x85, 0xf8, 0x0f, 0x97, 0x3d, 0x56, 0x08, 0xf1, 0x7f, 0x19, 0x14, 0x42, 0xa1, 0xa8,
|
||||||
|
0xe6, 0x0d, 0x2f, 0x3c, 0x08, 0xb9, 0xfd, 0x46, 0xa5, 0x84, 0x2d, 0x3f, 0x0e, 0x16, 0xa0, 0xf7,
|
||||||
|
0xef, 0xa1, 0x18, 0x4f, 0x98, 0x0a, 0xf7, 0xbb, 0x3c, 0xef, 0x45, 0x6a, 0x19, 0x58, 0x5e, 0x67,
|
||||||
|
0x28, 0xb9, 0x5b, 0x24, 0x0a, 0xa5, 0x12, 0xab, 0x1b, 0x7b, 0xbf, 0x07, 0x17, 0x8b, 0x98, 0x04,
|
||||||
|
0x57, 0x0d, 0xe4, 0xde, 0x46, 0x6d, 0x03, 0x80, 0x8c, 0x6d, 0xb7, 0x4f, 0x54, 0xfd, 0x9a, 0xe4,
|
||||||
|
0x9f, 0x66, 0xb3, 0x3b, 0x1c, 0x0e, 0x1e, 0x90, 0x72, 0xba, 0x38, 0x3e, 0x6e, 0x38, 0x3f, 0x0b,
|
||||||
|
0x8b, 0x66, 0xa3, 0x62, 0x7d, 0xa2, 0x10, 0x4b, 0x15, 0x9e, 0x57, 0xaa, 0x51, 0x35, 0x3f, 0x76,
|
||||||
|
0xf6, 0x29, 0x8d, 0xf0, 0x5b, 0xaa, 0x2f, 0x28, 0xb9, 0x5b, 0x24, 0xcf, 0xe9, 0x02, 0xe7, 0x73,
|
||||||
|
0xe8, 0xe7, 0xeb, 0xa0, 0x57, 0x40, 0xb0, 0x44, 0xb1, 0x3f, 0xe7, 0x56, 0xcb, 0xaa, 0xa5, 0x68,
|
||||||
|
0x81, 0x2e, 0x98, 0xd9, 0x9b, 0x92, 0x44, 0xf2, 0x8f, 0x8a, 0xc5, 0xe2, 0x5d, 0xdb, 0xb7, 0x22,
|
||||||
|
0x8f, 0x0c, 0x3e, 0xc8, 0x03, 0x1d, 0x1e, 0x54, 0x99, 0x2d, 0xcb, 0x17, 0xf5, 0xdf, 0xcc, 0x24,
|
||||||
|
0x28, 0xe7, 0xd6, 0x0b, 0xb6, 0x43, 0x20, 0x7a, 0xba, 0x37, 0x48, 0x9b, 0x3c, 0xc1, 0x3a, 0x43,
|
||||||
|
0xc9, 0xdd, 0x22, 0x89, 0xbe, 0x47, 0x47, 0xad, 0x64, 0xb4, 0x0f, 0x28, 0x48, 0x2b, 0x66, 0xaa,
|
||||||
|
0x3b, 0x1f, 0xf4, 0x61, 0xba, 0x9d, 0xff, 0x46, 0x3f, 0x60, 0x59, 0xbb, 0x52, 0x63, 0xdf, 0x03,
|
||||||
|
0x66, 0xc7, 0x96, 0x4d, 0x32, 0x19, 0xce, 0x9c, 0xe8, 0xf0, 0xcb, 0x67, 0xac, 0x9d, 0x9b, 0x50,
|
||||||
|
0x25, 0x83, 0x11, 0xb0, 0xa8, 0x41, 0x6d, 0x16, 0x90, 0x21, 0x91, 0xcc, 0xeb, 0xf2, 0x1b, 0xf4,
|
||||||
|
0x53, 0x9a, 0x14, 0x5a, 0x7b, 0x0f, 0xa9, 0x90, 0xf2, 0x1f, 0x02, 0x25, 0x77, 0xcb, 0x43, 0xae,
|
||||||
|
0x50, 0x9e, 0xbe, 0x89, 0xee, 0xc9, 0x1c, 0x8b, 0x29, 0x6b, 0xec, 0x52, 0xbb, 0x2e, 0x45, 0x70,
|
||||||
|
0x2d, 0x95, 0x61, 0x33, 0x4f, 0xa5, 0xd7, 0xb1, 0x70, 0x56, 0x4f, 0xbc, 0xda, 0x05, 0x7f, 0x22,
|
||||||
|
0x91, 0x68, 0xd1, 0xbc, 0x39, 0xd0, 0x0c, 0xfa, 0x34, 0xab, 0xcf, 0xdb, 0xdb, 0x89, 0xb2, 0x10,
|
||||||
|
0xf7, 0x81, 0xc2, 0x97, 0x2d, 0x50, 0x29, 0x7c, 0xfe, 0x8c, 0xde, 0xe4, 0xf3, 0x04, 0x97, 0x04,
|
||||||
|
0xdf, 0x6a, 0x44, 0x46, 0xec, 0x80, 0xe6, 0x9e, 0x1e, 0x93, 0x08, 0xbf, 0xfa, 0x81, 0x50, 0x72,
|
||||||
|
0xb7, 0x3c, 0x46, 0x24, 0xf2, 0x80, 0xcc, 0x5a, 0x94, 0xdc, 0xdd, 0x92, 0x2b, 0x51, 0xd9, 0xef,
|
||||||
|
0x90, 0x8c, 0xa6, 0x03, 0x9f, 0x69, 0x85, 0x1a, 0x98, 0x8e, 0xd0, 0xd4, 0x66, 0xee, 0x5e, 0xb1,
|
||||||
|
0x74, 0x09, 0x72, 0xcd, 0xc8, 0x72, 0x1b, 0x74, 0xdc, 0x1f, 0x24, 0x92, 0x0e, 0x56, 0xc7, 0xfe,
|
||||||
|
0x3d, 0xa8, 0x06, 0x9e, 0x17, 0x11, 0xac, 0xc4, 0xfb, 0x35, 0x80, 0x88, 0xcd, 0xa7, 0xc3, 0xc1,
|
||||||
|
0xe1, 0x0e, 0x8e, 0xad, 0x24, 0x2b, 0xbc, 0xfd, 0x52, 0x6d, 0x4e, 0x5e, 0x7d, 0x41, 0xc9, 0xdd,
|
||||||
|
0xf2, 0x18, 0x16, 0xcb, 0x7c, 0xd3, 0xd1, 0x8b, 0x52, 0xbc, 0x52, 0xab, 0x08, 0x82, 0xe0, 0xf3,
|
||||||
|
0x22, 0x83, 0x51, 0x72, 0x64, 0xed, 0xde, 0x4a, 0xd0, 0xdf, 0x00, 0x1c, 0x39, 0x64, 0xbf, 0xdc,
|
||||||
|
0x66, 0xf1, 0x8a, 0x65, 0x4b, 0xfe, 0xfc, 0x7d, 0x2f, 0x71, 0x7d, 0xa4, 0x5d, 0x9d, 0x9d, 0x7f,
|
||||||
|
0x3b, 0xa0, 0xca, 0xe7, 0x06, 0xf9, 0x2a, 0xd5, 0x67, 0xd1, 0x4c, 0x2c, 0x68, 0x81, 0xd3, 0xb3,
|
||||||
|
0xbc, 0xef, 0x8c, 0x15, 0x66, 0x3e, 0xd5, 0x73, 0x26, 0x7b, 0x2c, 0x94, 0xdc, 0x2d, 0x0f, 0xfd,
|
||||||
|
0xc8, 0xfd, 0x17, 0x20, 0x77, 0xfd, 0x4c, 0xe3, 0x53, 0x72, 0xa7, 0x30, 0x20, 0x46, 0x96, 0xbb,
|
||||||
|
0x58, 0x2c, 0x96, 0x48, 0x88, 0xa6, 0xfa, 0xa5, 0x5d, 0x6c, 0x4a, 0xee, 0x14, 0x86, 0x02, 0x57,
|
||||||
|
0xee, 0x9e, 0x7a, 0x95, 0x7b, 0x5c, 0x4c, 0x34, 0xe8, 0xb2, 0x3b, 0xda, 0xdb, 0x4e, 0xfe, 0xec,
|
||||||
|
0x9f, 0x50, 0xa2, 0x6f, 0x57, 0xa7, 0x93, 0xea, 0x4e, 0xa6, 0xe4, 0x3e, 0x8a, 0x5c, 0x2e, 0xb7,
|
||||||
|
0x79, 0xb7, 0x3b, 0xc4, 0x7a, 0xd2, 0xa7, 0xdd, 0x5d, 0xf8, 0x49, 0xe2, 0x29, 0x74, 0xc0, 0x68,
|
||||||
|
0x72, 0x5f, 0xba, 0x68, 0x3e, 0x99, 0x2c, 0xf6, 0x94, 0xdc, 0x47, 0x39, 0xb8, 0x7f, 0x1f, 0x70,
|
||||||
|
0xd9, 0xc3, 0xc2, 0x82, 0x29, 0x9f, 0xff, 0x6b, 0xe9, 0x57, 0x0b, 0xe4, 0x66, 0x13, 0xc4, 0xcb,
|
||||||
|
0xd2, 0x31, 0x9a, 0xdc, 0x3d, 0xdd, 0x5c, 0xc8, 0xd4, 0x87, 0x92, 0xfb, 0xdb, 0xa4, 0x84, 0x78,
|
||||||
|
0xe0, 0xaf, 0xe3, 0x47, 0x1c, 0xc1, 0xeb, 0x6b, 0x57, 0x2e, 0x83, 0xd7, 0x7b, 0x76, 0xef, 0xd2,
|
||||||
|
0xa5, 0x82, 0x14, 0x18, 0x46, 0xc4, 0x72, 0xe3, 0xc8, 0x3d, 0x28, 0xc0, 0x8f, 0x4c, 0x7d, 0x3e,
|
||||||
|
0x76, 0xb9, 0x57, 0xd1, 0x2a, 0x81, 0xb3, 0xbe, 0x5e, 0xb2, 0x08, 0xde, 0xe0, 0x77, 0xd8, 0xc1,
|
||||||
|
0x0e, 0x1c, 0x09, 0xf4, 0xf3, 0xd5, 0xa5, 0x8e, 0x14, 0xaa, 0x50, 0x72, 0xd7, 0x19, 0xfd, 0xcb,
|
||||||
|
0x5d, 0x24, 0x14, 0x7e, 0x39, 0x73, 0x1a, 0x18, 0xdf, 0xb4, 0xb6, 0x8c, 0x07, 0x5d, 0x50, 0x28,
|
||||||
|
0x14, 0xcb, 0x16, 0x2f, 0x04, 0x1e, 0xbc, 0x79, 0x63, 0x3c, 0x29, 0xb1, 0xa0, 0xb7, 0x17, 0x9c,
|
||||||
|
0x0c, 0xac, 0xfa, 0xcd, 0x6b, 0xf0, 0x2f, 0x74, 0x5a, 0x6d, 0x4d, 0x4d, 0x47, 0x87, 0xca, 0x6d,
|
||||||
|
0x83, 0xd3, 0x68, 0x95, 0x15, 0x0c, 0x3a, 0x1d, 0xea, 0x0e, 0x49, 0x24, 0x12, 0x30, 0x12, 0x80,
|
||||||
|
0x9f, 0x15, 0x0c, 0x0d, 0x0d, 0x71, 0x39, 0x1c, 0x92, 0x77, 0x31, 0x31, 0x30, 0x4b, 0xb9, 0xdb,
|
||||||
|
0x7f, 0xa4, 0x72, 0x87, 0x83, 0xd2, 0xa8, 0xb3, 0x86, 0xfa, 0xb1, 0xd9, 0x8d, 0x3f, 0x7f, 0xff,
|
||||||
|
0x0d, 0xfc, 0x02, 0xf4, 0xf6, 0x8e, 0x4e, 0x1d, 0xff, 0xb1, 0xe7, 0xd7, 0x99, 0xd6, 0x56, 0x2d,
|
||||||
|
0x8c, 0xd1, 0xec, 0x4b, 0xe7, 0xa2, 0xa3, 0xd6, 0x7e, 0xbb, 0x0a, 0xbc, 0x78, 0x54, 0xf4, 0x70,
|
||||||
|
0xfe, 0xec, 0x19, 0x40, 0xee, 0xe0, 0xf5, 0xc8, 0xc8, 0xc8, 0x9c, 0xe9, 0xd6, 0x99, 0xe9, 0xa3,
|
||||||
|
0x69, 0x6c, 0xea, 0x6a, 0x6b, 0xa7, 0x4f, 0x9e, 0xf4, 0xf4, 0xc9, 0x63, 0xe7, 0x93, 0xc7, 0xb7,
|
||||||
|
0x6d, 0xda, 0xf0, 0xb1, 0x8d, 0x0a, 0x8c, 0x20, 0x77, 0xad, 0xf8, 0x78, 0xe5, 0x1e, 0x1a, 0x1c,
|
||||||
|
0x04, 0x04, 0xbd, 0x6f, 0xef, 0x1e, 0xdc, 0x77, 0xaf, 0x67, 0xa4, 0x83, 0x77, 0x81, 0x6a, 0x87,
|
||||||
|
0x87, 0x47, 0xf7, 0x1f, 0x00, 0xb9, 0x87, 0x87, 0x9c, 0x81, 0xde, 0x8a, 0x8e, 0x8a, 0xd8, 0xfb,
|
||||||
|
0xdf, 0x5f, 0xa0, 0xd7, 0xa5, 0xc5, 0xc5, 0x8b, 0xe6, 0xcd, 0x79, 0xfb, 0xae, 0xe5, 0x76, 0x38,
|
||||||
|
0x78, 0x00, 0x28, 0x7b, 0xcd, 0xea, 0x95, 0xae, 0x4e, 0x27, 0x57, 0x2c, 0x5d, 0x92, 0x78, 0x3e,
|
||||||
|
0x0e, 0x3a, 0x07, 0x34, 0xf0, 0xd6, 0x93, 0x3e, 0xfd, 0x75, 0xe7, 0x0e, 0x92, 0xf5, 0x9f, 0x48,
|
||||||
|
0xe0, 0xca, 0xdd, 0x2b, 0x95, 0xd6, 0xad, 0x7e, 0x11, 0x01, 0x9e, 0xdc, 0xb7, 0x50, 0x72, 0x57,
|
||||||
|
0x0b, 0x19, 0xb9, 0x97, 0x14, 0x3f, 0x02, 0x6a, 0x9e, 0x3b, 0x63, 0xaa, 0x58, 0xa4, 0xd6, 0xef,
|
||||||
|
0x4e, 0x27, 0x8e, 0x81, 0x73, 0x7e, 0x5c, 0x33, 0x9a, 0x96, 0x0a, 0xc8, 0x3d, 0x32, 0x2c, 0x14,
|
||||||
|
0x3a, 0x8e, 0x2b, 0xf7, 0xe3, 0x47, 0x0f, 0xef, 0xd8, 0xb2, 0x11, 0x6a, 0xbc, 0xc1, 0x57, 0x05,
|
||||||
|
0x74, 0x90, 0x22, 0x42, 0x43, 0xc0, 0xeb, 0x8b, 0x17, 0x92, 0x6c, 0x16, 0xce, 0x1b, 0xe8, 0xef,
|
||||||
|
0x2f, 0xb8, 0x9f, 0x3f, 0x6b, 0xda, 0x14, 0x64, 0xaf, 0xe9, 0x63, 0xc0, 0x32, 0xe4, 0x1e, 0x3c,
|
||||||
|
0xd1, 0xe5, 0x6e, 0x08, 0x40, 0x6f, 0xbe, 0x93, 0xcd, 0x16, 0x8b, 0x4d, 0x10, 0x37, 0xc2, 0x6c,
|
||||||
|
0xd1, 0x51, 0xee, 0xaa, 0xd1, 0xc1, 0x29, 0xb9, 0x13, 0x41, 0xcd, 0xaa, 0x9a, 0x0f, 0x3a, 0xc9,
|
||||||
|
0xfd, 0x0c, 0x25, 0xf7, 0xb7, 0x94, 0xdc, 0x2d, 0x11, 0x4a, 0xee, 0x3a, 0x43, 0xc9, 0xdd, 0xf2,
|
||||||
|
0x18, 0x91, 0x50, 0x72, 0xd7, 0x11, 0x4a, 0xee, 0x96, 0xc7, 0x44, 0x90, 0x7b, 0x21, 0x25, 0x77,
|
||||||
|
0x0a, 0x72, 0x18, 0x47, 0xee, 0xed, 0x2c, 0x16, 0xfc, 0x1a, 0x39, 0xaf, 0x87, 0x85, 0x92, 0x3b,
|
||||||
|
0x85, 0x01, 0x31, 0x9c, 0xdc, 0x07, 0xfa, 0xfb, 0x83, 0x02, 0xfc, 0x66, 0x58, 0x5b, 0x59, 0x7d,
|
||||||
|
0xfa, 0x8f, 0xef, 0x56, 0xfd, 0x1b, 0x3e, 0x0e, 0xad, 0x7a, 0x02, 0xb6, 0x6d, 0xd3, 0x06, 0x6c,
|
||||||
|
0x12, 0x52, 0x4a, 0xee, 0x14, 0x06, 0x44, 0xbf, 0x72, 0x57, 0x2a, 0x95, 0x39, 0x77, 0xef, 0xac,
|
||||||
|
0xfa, 0x66, 0x19, 0x6a, 0xf2, 0x1b, 0x57, 0xee, 0xb0, 0x4d, 0xb3, 0xfa, 0xdc, 0xc3, 0xd5, 0x99,
|
||||||
|
0xcf, 0x1f, 0x4d, 0x49, 0x2a, 0xed, 0x64, 0x77, 0x1d, 0x3f, 0x84, 0x99, 0x66, 0xf2, 0x21, 0x90,
|
||||||
|
0x7b, 0x52, 0x61, 0x2b, 0x56, 0xee, 0xe9, 0x4f, 0x28, 0xb9, 0x53, 0x60, 0xd0, 0x8b, 0xdc, 0xe9,
|
||||||
|
0x3f, 0x6f, 0x5a, 0xb6, 0xe0, 0x4b, 0x82, 0xb5, 0x1e, 0xb3, 0xa6, 0x4e, 0xfe, 0x75, 0xe7, 0x0e,
|
||||||
|
0xc8, 0xbe, 0x5b, 0xb9, 0x82, 0xe0, 0xcc, 0x19, 0x93, 0x27, 0x45, 0xfe, 0xbc, 0x05, 0x25, 0xf7,
|
||||||
|
0x6e, 0xf7, 0x93, 0xf2, 0x21, 0xb5, 0x91, 0x11, 0xf2, 0x68, 0xdd, 0x0e, 0xa7, 0x55, 0x42, 0xcd,
|
||||||
|
0xd8, 0x7a, 0xe4, 0x85, 0xdd, 0x31, 0x78, 0x2c, 0x31, 0x4a, 0xee, 0x96, 0x07, 0xae, 0xdc, 0x3d,
|
||||||
|
0xb5, 0x6d, 0xdd, 0x77, 0x6d, 0x11, 0xd5, 0x8f, 0xb6, 0xee, 0x7d, 0x02, 0x81, 0xbf, 0x8f, 0xf7,
|
||||||
|
0x8c, 0x29, 0x5f, 0x68, 0xd5, 0xba, 0x03, 0xdb, 0xf8, 0xe3, 0x3a, 0x48, 0x12, 0x4a, 0xa9, 0x84,
|
||||||
|
0x17, 0x81, 0x9e, 0xb5, 0x6d, 0xdf, 0xbb, 0x93, 0x20, 0x7f, 0x73, 0xa7, 0x40, 0xe4, 0x7b, 0x05,
|
||||||
|
0x1d, 0x13, 0xf8, 0x54, 0x42, 0x79, 0x1b, 0xcf, 0xb0, 0xe1, 0x51, 0x29, 0xb9, 0x5b, 0x1e, 0xfa,
|
||||||
|
0x95, 0x3b, 0x92, 0x2a, 0x1a, 0x6d, 0xd7, 0xf6, 0xad, 0x04, 0x72, 0x5f, 0x30, 0x67, 0x56, 0x52,
|
||||||
|
0x42, 0x3c, 0x76, 0x92, 0xbb, 0x37, 0x25, 0x91, 0xbe, 0x70, 0x16, 0xb2, 0x7c, 0x86, 0xcd, 0xbc,
|
||||||
|
0xde, 0xa4, 0x58, 0x82, 0xbb, 0xb8, 0x50, 0xc4, 0xb4, 0xc3, 0xc4, 0x2e, 0x76, 0x4d, 0x7a, 0x45,
|
||||||
|
0x57, 0x1f, 0x2d, 0xe7, 0xc3, 0xa1, 0xe4, 0x6e, 0x79, 0x18, 0x4e, 0xee, 0x30, 0x32, 0x99, 0xac,
|
||||||
|
0xb0, 0xe0, 0x01, 0xfc, 0xdf, 0xda, 0x9a, 0x6a, 0xe4, 0x83, 0x1a, 0x2c, 0x92, 0xb6, 0xd6, 0xae,
|
||||||
|
0x93, 0x87, 0x51, 0x0d, 0x3c, 0x18, 0xbf, 0x12, 0xa7, 0x3f, 0xb8, 0x00, 0x7a, 0xf0, 0xbe, 0xe8,
|
||||||
|
0x5c, 0x4e, 0x76, 0x3e, 0xf9, 0xd1, 0xb9, 0x64, 0x23, 0xd3, 0x6b, 0x0b, 0x25, 0x77, 0xcb, 0xc3,
|
||||||
|
0x08, 0x72, 0xd7, 0x81, 0xde, 0xe4, 0xf3, 0xf4, 0x79, 0xd3, 0x51, 0x8a, 0xe7, 0x85, 0x07, 0x11,
|
||||||
|
0x5f, 0x75, 0xa5, 0x94, 0x75, 0xf8, 0x34, 0x26, 0x6b, 0xda, 0xbb, 0x00, 0x63, 0x7e, 0x19, 0xb5,
|
||||||
|
0xf5, 0x1d, 0xfd, 0x7a, 0xac, 0xe1, 0x5b, 0x82, 0xdc, 0x4c, 0x25, 0x8f, 0x8a, 0x90, 0xe6, 0x60,
|
||||||
|
0xfb, 0x57, 0xfc, 0xb9, 0x18, 0xe4, 0x11, 0x5a, 0x65, 0xe5, 0x87, 0xff, 0x79, 0x89, 0x4c, 0x91,
|
||||||
|
0x52, 0xc2, 0x4a, 0x2c, 0x68, 0xc5, 0x58, 0x0b, 0xca, 0x12, 0x80, 0x3d, 0xd0, 0x6c, 0xe0, 0xda,
|
||||||
|
0xe4, 0x22, 0xe6, 0xe5, 0xd2, 0xb6, 0xac, 0x67, 0x1d, 0xf7, 0x5f, 0x73, 0xca, 0x5b, 0xfa, 0x9a,
|
||||||
|
0xbb, 0x87, 0xf9, 0x83, 0x12, 0x99, 0xdc, 0x48, 0x11, 0xc4, 0x8d, 0x80, 0x11, 0xe4, 0xde, 0xdc,
|
||||||
|
0xd4, 0x68, 0x7b, 0x60, 0xdf, 0xec, 0x69, 0xd6, 0xa0, 0x03, 0x33, 0xd3, 0xda, 0xea, 0xa7, 0xb5,
|
||||||
|
0xdf, 0x85, 0x87, 0x9c, 0x21, 0x58, 0xe8, 0x0a, 0x50, 0xca, 0x64, 0xdc, 0x20, 0x5f, 0x94, 0xdc,
|
||||||
|
0x41, 0x0f, 0xa7, 0xf7, 0x42, 0xbc, 0xc6, 0x3b, 0xf2, 0xba, 0x86, 0xbe, 0x1d, 0xa4, 0x39, 0x06,
|
||||||
|
0x17, 0x79, 0xa5, 0x55, 0xf9, 0x66, 0xd6, 0x9d, 0xb9, 0xd5, 0x10, 0x99, 0xd3, 0x14, 0x95, 0xd3,
|
||||||
|
0xac, 0xd6, 0x72, 0x9b, 0xcf, 0xa2, 0x8d, 0x0e, 0x59, 0xcc, 0x3d, 0x3a, 0x9d, 0x33, 0xac, 0xb6,
|
||||||
|
0x75, 0xa7, 0x37, 0x37, 0x4d, 0xfd, 0xe2, 0x33, 0x75, 0x83, 0xf1, 0xff, 0xfc, 0xfb, 0x1b, 0x32,
|
||||||
|
0x7b, 0xd4, 0x35, 0x22, 0x93, 0x2b, 0xfd, 0x32, 0xeb, 0x08, 0x6e, 0x55, 0x9f, 0xe6, 0x9e, 0x6b,
|
||||||
|
0xef, 0xf7, 0xe0, 0x68, 0xe4, 0x63, 0xcf, 0xd4, 0x2a, 0xff, 0xac, 0xfa, 0x94, 0x47, 0xcc, 0x6a,
|
||||||
|
0xd6, 0x00, 0x41, 0xc8, 0x5c, 0xb3, 0xc5, 0xd0, 0x72, 0x8f, 0x0a, 0x0f, 0x03, 0x1f, 0x31, 0x68,
|
||||||
|
0xdd, 0xe0, 0x23, 0x9c, 0xee, 0xee, 0x05, 0x73, 0x67, 0x4d, 0xf9, 0xfc, 0x5f, 0xc4, 0x1b, 0xc7,
|
||||||
|
0x64, 0x82, 0xde, 0xae, 0x53, 0x47, 0xd0, 0x8a, 0x9f, 0x3b, 0x95, 0x1f, 0x17, 0xa5, 0xf1, 0xa6,
|
||||||
|
0x3a, 0x7a, 0x84, 0xfe, 0x99, 0xb5, 0xb8, 0x59, 0x9c, 0xf4, 0x62, 0xa7, 0x62, 0x9f, 0xd7, 0xb3,
|
||||||
|
0x07, 0x89, 0x3a, 0x33, 0x3c, 0x2e, 0x77, 0xce, 0x74, 0x6b, 0xac, 0xd6, 0x77, 0x6c, 0xd9, 0xa4,
|
||||||
|
0xb1, 0xf6, 0x24, 0x31, 0xaa, 0xdc, 0xd5, 0x98, 0x9d, 0x77, 0xbe, 0x4b, 0xfc, 0x8b, 0xc0, 0x1b,
|
||||||
|
0xf5, 0x99, 0x65, 0x1d, 0x5d, 0x02, 0xa2, 0x06, 0xcc, 0x4c, 0x50, 0x27, 0x77, 0x82, 0x18, 0x91,
|
||||||
|
0x5a, 0xc9, 0xfd, 0xf6, 0xcd, 0x1b, 0xe0, 0x53, 0x06, 0xe2, 0x3e, 0xea, 0xe8, 0x70, 0x37, 0xfb,
|
||||||
|
0xf6, 0xc0, 0xc0, 0x00, 0xf9, 0xba, 0x49, 0xbb, 0x3b, 0xbb, 0x30, 0xfb, 0x56, 0x9b, 0x67, 0x4d,
|
||||||
|
0xe6, 0x06, 0x93, 0xdd, 0xa6, 0x9c, 0x4f, 0xeb, 0x0e, 0xc8, 0xa8, 0xb1, 0xf7, 0x21, 0x95, 0x98,
|
||||||
|
0x5b, 0x9f, 0x72, 0x7f, 0xfb, 0x2e, 0x93, 0xb0, 0xcd, 0xa2, 0xf9, 0x48, 0xad, 0xdb, 0x1f, 0x3c,
|
||||||
|
0x40, 0xfe, 0xe6, 0x35, 0x02, 0xfa, 0x18, 0xa3, 0xb9, 0x67, 0x03, 0x0a, 0xf5, 0x68, 0xf6, 0xfe,
|
||||||
|
0x05, 0xa0, 0x15, 0xb7, 0xf5, 0xce, 0x47, 0x85, 0x84, 0x26, 0x69, 0x87, 0x4e, 0x17, 0xfa, 0x5f,
|
||||||
|
0x79, 0x9d, 0x58, 0xd8, 0xca, 0x55, 0xbf, 0x17, 0xce, 0xb4, 0xe8, 0x49, 0xee, 0x9b, 0x89, 0xfb,
|
||||||
|
0xee, 0x0c, 0x3a, 0xfd, 0x5c, 0x74, 0xd4, 0xc6, 0x1f, 0xd7, 0x41, 0x61, 0x95, 0x80, 0x81, 0x2e,
|
||||||
|
0x4d, 0x57, 0xa7, 0xe6, 0xa8, 0xa5, 0xd2, 0xce, 0x0e, 0x6c, 0x1b, 0x0f, 0x8c, 0x6d, 0xfb, 0x3f,
|
||||||
|
0x61, 0x55, 0x05, 0xf9, 0xdb, 0x04, 0xb7, 0x53, 0xce, 0x10, 0x80, 0x4e, 0x88, 0x5f, 0x66, 0xad,
|
||||||
|
0x6f, 0x1a, 0xcd, 0xed, 0xfc, 0xf3, 0xa3, 0x61, 0x25, 0x87, 0x82, 0x8b, 0xc6, 0x2c, 0x48, 0x3b,
|
||||||
|
0x3b, 0x95, 0x50, 0xae, 0x59, 0xee, 0x6f, 0xdf, 0x45, 0x47, 0x5a, 0xf3, 0xed, 0x58, 0x9e, 0x78,
|
||||||
|
0x1f, 0x4f, 0x77, 0xf2, 0xd5, 0x35, 0x13, 0xa4, 0x72, 0x05, 0x77, 0x40, 0xfc, 0xba, 0xad, 0xff,
|
||||||
|
0x7a, 0x59, 0x07, 0xe8, 0xde, 0x81, 0x5f, 0x4c, 0xe7, 0xf8, 0xe7, 0xe0, 0x2b, 0x71, 0xd0, 0x43,
|
||||||
|
0xf3, 0x97, 0xe1, 0x48, 0xd0, 0xc3, 0xe0, 0x9b, 0x0d, 0x65, 0x4d, 0xbd, 0xa6, 0xbe, 0x09, 0x15,
|
||||||
|
0x0c, 0x2d, 0x77, 0x2f, 0x77, 0xd7, 0x9f, 0xb7, 0x6e, 0xea, 0x13, 0xa8, 0x64, 0xa8, 0xcc, 0xb9,
|
||||||
|
0x93, 0x0d, 0x04, 0x00, 0x8e, 0x93, 0xac, 0x24, 0x3f, 0x2a, 0x04, 0x34, 0xea, 0x58, 0xd1, 0x77,
|
||||||
|
0x39, 0xff, 0x4d, 0x32, 0x75, 0x99, 0x21, 0x20, 0xfb, 0x64, 0x66, 0xb9, 0xcd, 0x57, 0xce, 0x27,
|
||||||
|
0x8f, 0x1b, 0xb4, 0x2a, 0xc6, 0x07, 0x74, 0x5d, 0x2e, 0x16, 0x31, 0x03, 0x33, 0x6b, 0x8f, 0x86,
|
||||||
|
0x97, 0x12, 0xf7, 0x1a, 0x8f, 0x84, 0x16, 0x47, 0xdd, 0x69, 0xe4, 0x9b, 0x22, 0x19, 0x2f, 0x16,
|
||||||
|
0x7c, 0xb9, 0xa7, 0xe8, 0x4d, 0xee, 0x35, 0xd5, 0xd5, 0x33, 0xa7, 0x4e, 0x86, 0xf6, 0x1c, 0x27,
|
||||||
|
0xc4, 0xc7, 0x5d, 0x48, 0x3c, 0x0f, 0x86, 0xad, 0xa0, 0x8d, 0xff, 0x72, 0xe6, 0x34, 0x68, 0xef,
|
||||||
|
0x3c, 0x49, 0x06, 0xef, 0xe7, 0xb2, 0xb6, 0x6f, 0xc0, 0x2a, 0x7e, 0xb4, 0xa5, 0x3f, 0xf8, 0xc7,
|
||||||
|
0x50, 0xf1, 0x43, 0xad, 0xef, 0xfc, 0x83, 0xf9, 0xa4, 0xa3, 0xbd, 0xbd, 0xac, 0xec, 0xa9, 0x46,
|
||||||
|
0x03, 0xdd, 0xb8, 0x6b, 0x57, 0xaf, 0x90, 0x39, 0xd3, 0xe4, 0xd6, 0xd2, 0xa2, 0xc5, 0x47, 0x82,
|
||||||
|
0x24, 0xbf, 0x8a, 0x13, 0x74, 0xb3, 0xfe, 0xef, 0xc8, 0xc7, 0x04, 0xba, 0xf7, 0x48, 0x2a, 0xcf,
|
||||||
|
0x7d, 0x65, 0xe2, 0x00, 0x80, 0x40, 0xee, 0x7e, 0x86, 0x94, 0x3b, 0x4c, 0x4f, 0x0f, 0xbf, 0xfa,
|
||||||
|
0xcd, 0x6b, 0x5a, 0x65, 0x05, 0x78, 0xa1, 0x73, 0x6d, 0x7b, 0x12, 0x62, 0x18, 0x8b, 0xe7, 0xe2,
|
||||||
|
0xb6, 0xf4, 0x2d, 0xab, 0x96, 0x72, 0xfc, 0x3d, 0x45, 0xf5, 0x35, 0x3a, 0x17, 0xae, 0x2d, 0xa4,
|
||||||
|
0x5a, 0xf7, 0xac, 0xcc, 0x0c, 0xf0, 0x5d, 0x9f, 0x3d, 0x6d, 0xca, 0x87, 0xdc, 0xb6, 0x05, 0xc1,
|
||||||
|
0x1f, 0x94, 0x24, 0x16, 0xb4, 0xb8, 0x24, 0xbd, 0x52, 0x27, 0x7a, 0xc7, 0x80, 0xc2, 0xe8, 0x3c,
|
||||||
|
0xba, 0xa9, 0xaa, 0x27, 0x34, 0x70, 0xeb, 0x6e, 0x08, 0xfa, 0xd2, 0xd3, 0x88, 0x53, 0x5b, 0xb2,
|
||||||
|
0xed, 0xf6, 0xf1, 0xe3, 0xa2, 0x44, 0x8d, 0xf5, 0x06, 0xad, 0x86, 0x66, 0xb9, 0xc7, 0x46, 0x9f,
|
||||||
|
0x45, 0xae, 0x83, 0xd3, 0xb9, 0xed, 0xc4, 0x45, 0x29, 0x95, 0x4a, 0x39, 0xdd, 0xba, 0x99, 0x8c,
|
||||||
|
0xcb, 0xc1, 0xb7, 0x1e, 0xbe, 0x7c, 0xa0, 0x5f, 0xa1, 0x8f, 0xdd, 0xdc, 0x35, 0xed, 0x03, 0xa1,
|
||||||
|
0x77, 0x9a, 0x8e, 0x60, 0xe7, 0x41, 0xa0, 0x47, 0x3a, 0x9e, 0x79, 0xe7, 0xf3, 0xe9, 0x46, 0xc8,
|
||||||
|
0x28, 0x84, 0xc2, 0x12, 0xe5, 0x0e, 0x31, 0x54, 0x52, 0xc4, 0xf1, 0x72, 0x46, 0xe5, 0x11, 0x41,
|
||||||
|
0xdb, 0x8c, 0x2f, 0x5a, 0x56, 0x2c, 0xee, 0xf8, 0xfd, 0x17, 0xd0, 0xf0, 0xf3, 0xa3, 0xc3, 0xfa,
|
||||||
|
0x6f, 0x64, 0x8c, 0xbc, 0x7a, 0x21, 0x61, 0xb6, 0x80, 0x4f, 0x5c, 0xde, 0x27, 0x00, 0x9f, 0xac,
|
||||||
|
0xce, 0xa6, 0x10, 0x09, 0x35, 0xc8, 0x1d, 0x8c, 0x5a, 0xb0, 0x0f, 0x22, 0xb1, 0x2b, 0x9e, 0x75,
|
||||||
|
0x46, 0x21, 0x1c, 0x01, 0x77, 0x45, 0x74, 0xf3, 0x1f, 0x68, 0x73, 0xa7, 0xb6, 0x7c, 0xbd, 0x90,
|
||||||
|
0xb5, 0x63, 0x63, 0xb7, 0xfb, 0x29, 0x5e, 0x78, 0x50, 0x5f, 0xe6, 0x55, 0x09, 0xab, 0x4d, 0x87,
|
||||||
|
0x7a, 0x36, 0xb3, 0x07, 0x7d, 0x2e, 0x55, 0xe0, 0x8a, 0x1e, 0x74, 0x7e, 0xf2, 0x5e, 0x19, 0x3c,
|
||||||
|
0xcb, 0x0a, 0x12, 0xcb, 0x95, 0x3b, 0xcc, 0xe0, 0x83, 0x3c, 0x8e, 0xb7, 0x2b, 0x63, 0xc9, 0x97,
|
||||||
|
0x06, 0xfc, 0xe8, 0x55, 0xad, 0xfd, 0xb7, 0x9d, 0xe2, 0xa6, 0x06, 0x22, 0xb9, 0xdb, 0xfd, 0xb5,
|
||||||
|
0x5f, 0xdd, 0x34, 0x53, 0x5e, 0xce, 0x5d, 0xbd, 0xdc, 0xb6, 0xc1, 0xe5, 0xae, 0xc6, 0x98, 0xeb,
|
||||||
|
0x56, 0x77, 0x7b, 0xb9, 0xf4, 0x5e, 0x4a, 0x54, 0x8c, 0x68, 0xb1, 0x04, 0x8f, 0x23, 0x10, 0x62,
|
||||||
|
0xd7, 0xf1, 0x41, 0xe6, 0x76, 0x89, 0xc6, 0xe9, 0x33, 0x52, 0x33, 0x3f, 0x01, 0xe4, 0x0e, 0x23,
|
||||||
|
0xed, 0xee, 0x04, 0x9d, 0xfb, 0x6e, 0x97, 0x63, 0x8c, 0xa5, 0xf3, 0x4d, 0x26, 0x77, 0xa5, 0x52,
|
||||||
|
0xb9, 0x7d, 0xf3, 0x46, 0xe2, 0xd8, 0x77, 0x97, 0x92, 0x35, 0x27, 0x05, 0xd7, 0x88, 0xa9, 0xe4,
|
||||||
|
0x8e, 0x34, 0x86, 0xcd, 0x3c, 0x5e, 0x48, 0xc0, 0xf0, 0x93, 0x12, 0x38, 0x80, 0x2b, 0x31, 0xbc,
|
||||||
|
0x7e, 0x91, 0x5b, 0x4a, 0x15, 0x56, 0xf1, 0xb6, 0x5e, 0xf7, 0x8c, 0xd3, 0xa1, 0x57, 0x2b, 0x77,
|
||||||
|
0xf5, 0x73, 0x64, 0x66, 0x2b, 0x77, 0x24, 0x40, 0x0c, 0x22, 0x7a, 0x93, 0xe0, 0x6a, 0x0a, 0xff,
|
||||||
|
0x6c, 0x08, 0xc7, 0xc7, 0xad, 0x7d, 0xf7, 0x36, 0xc6, 0xb2, 0x05, 0xa3, 0x0b, 0x2d, 0x55, 0x6b,
|
||||||
|
0xae, 0x7f, 0xb9, 0x63, 0xf1, 0xf5, 0xf6, 0xac, 0xac, 0x50, 0x9b, 0xa8, 0x4d, 0x67, 0x94, 0x0a,
|
||||||
|
0x05, 0xe8, 0x64, 0x2b, 0x24, 0x08, 0x13, 0x13, 0x98, 0x48, 0xb3, 0x89, 0x44, 0xc0, 0x6b, 0xa0,
|
||||||
|
0x93, 0x27, 0x65, 0xb7, 0x8f, 0xd0, 0x2a, 0x06, 0x72, 0x6f, 0xf3, 0x63, 0xc2, 0xb9, 0x81, 0xde,
|
||||||
|
0x9d, 0x0e, 0xfb, 0x5b, 0x96, 0x7f, 0xa5, 0xc1, 0x29, 0x33, 0xad, 0x78, 0x11, 0xc1, 0x72, 0x31,
|
||||||
|
0xa9, 0x89, 0xd5, 0x7b, 0x15, 0x5d, 0x47, 0x23, 0x4a, 0xb1, 0xa2, 0xf7, 0xbc, 0xf2, 0x66, 0x44,
|
||||||
|
0x62, 0xd8, 0x85, 0x09, 0x13, 0x55, 0xee, 0x04, 0x28, 0xe5, 0x72, 0x85, 0x50, 0x28, 0x1f, 0x1c,
|
||||||
|
0x30, 0x6c, 0xdf, 0x1d, 0xc6, 0x40, 0x72, 0x37, 0x32, 0xc0, 0x65, 0xa2, 0xc6, 0x3a, 0xa0, 0x69,
|
||||||
|
0xb6, 0xdd, 0x3e, 0xdc, 0x47, 0x63, 0x63, 0x2d, 0xc1, 0xde, 0x5d, 0x04, 0x49, 0x18, 0x61, 0x7a,
|
||||||
|
0x06, 0xc5, 0xbe, 0x57, 0xd1, 0xe9, 0x70, 0x81, 0x39, 0x9d, 0x7d, 0x52, 0x58, 0xcd, 0x35, 0xdc,
|
||||||
|
0x5d, 0xe8, 0x4f, 0xee, 0xc6, 0x7b, 0x02, 0x68, 0x26, 0x7c, 0x5c, 0x72, 0x47, 0x31, 0x98, 0x9f,
|
||||||
|
0xdb, 0xe5, 0x72, 0x0c, 0x57, 0xf1, 0xe0, 0x37, 0x94, 0x6d, 0xff, 0x27, 0x19, 0xd1, 0xc7, 0xdf,
|
||||||
|
0xa3, 0xdb, 0xfb, 0x3d, 0x40, 0x4f, 0x4b, 0x9d, 0x79, 0x74, 0xbb, 0xdc, 0x50, 0xe3, 0x57, 0x4a,
|
||||||
|
0xee, 0x3a, 0xf3, 0x51, 0xcb, 0x1d, 0x02, 0x8c, 0x56, 0x7b, 0x12, 0x63, 0x59, 0x3b, 0x37, 0xe3,
|
||||||
|
0xea, 0x9e, 0xe3, 0xeb, 0x2e, 0x61, 0x31, 0x89, 0x4b, 0xb8, 0xf1, 0x94, 0x75, 0xe8, 0xcc, 0x23,
|
||||||
|
0x94, 0xfe, 0x8e, 0x86, 0x97, 0x16, 0xd7, 0x18, 0xa4, 0x8d, 0x1f, 0x95, 0x7b, 0x06, 0x3a, 0x8d,
|
||||||
|
0x30, 0x25, 0x77, 0x32, 0x50, 0x72, 0x1f, 0xa7, 0x27, 0x29, 0x96, 0xf9, 0xc3, 0xb7, 0x58, 0xc5,
|
||||||
|
0xb3, 0xb6, 0xad, 0x1f, 0x7c, 0x90, 0x47, 0x7c, 0x6d, 0x41, 0x55, 0xf7, 0xe1, 0x30, 0x74, 0x57,
|
||||||
|
0xfe, 0x64, 0x4c, 0xd9, 0x2b, 0x86, 0x80, 0xf8, 0x42, 0x1d, 0x10, 0x51, 0x72, 0xd7, 0x15, 0x4a,
|
||||||
|
0xee, 0x68, 0x40, 0x4b, 0xdf, 0xba, 0x7a, 0x19, 0x5a, 0xf4, 0x73, 0xac, 0xf9, 0xd1, 0x61, 0xc4,
|
||||||
|
0x17, 0xa6, 0x16, 0xb7, 0x61, 0x7b, 0x35, 0xde, 0xa9, 0x34, 0x96, 0xbe, 0xe7, 0xa1, 0x28, 0xb9,
|
||||||
|
0xeb, 0x0c, 0x25, 0x77, 0x1c, 0xa4, 0x7c, 0x2e, 0x76, 0xe7, 0x25, 0x30, 0x5e, 0x88, 0xbf, 0x42,
|
||||||
|
0x42, 0x34, 0x59, 0x1b, 0x75, 0xa7, 0x11, 0xbd, 0xf9, 0xd2, 0x3d, 0x37, 0xf8, 0x56, 0x83, 0x7e,
|
||||||
|
0xab, 0x47, 0xc9, 0x5d, 0x67, 0x28, 0xb9, 0xe3, 0xa3, 0x94, 0xcb, 0xb9, 0x81, 0xde, 0x68, 0xc5,
|
||||||
|
0xcf, 0xf8, 0x82, 0x17, 0x41, 0xb4, 0xf9, 0x52, 0x26, 0x57, 0x62, 0xf7, 0xa1, 0x1d, 0x0a, 0x2c,
|
||||||
|
0xd4, 0xef, 0xb0, 0x95, 0x92, 0xbb, 0xce, 0x50, 0x72, 0x57, 0x0b, 0xae, 0xe2, 0x19, 0x8b, 0xe7,
|
||||||
|
0x12, 0x6f, 0xbe, 0x7c, 0x52, 0xcf, 0x77, 0xc4, 0x74, 0xe2, 0xfd, 0x32, 0xeb, 0xa4, 0xfa, 0xdb,
|
||||||
|
0x2c, 0xab, 0x4e, 0xee, 0x9d, 0x94, 0xdc, 0x35, 0x41, 0xc9, 0x9d, 0x08, 0x79, 0x9f, 0xa0, 0xdb,
|
||||||
|
0xf5, 0x38, 0x7a, 0xe4, 0xfa, 0xeb, 0x36, 0x61, 0xf5, 0x6b, 0x82, 0xab, 0xbc, 0xd3, 0xd1, 0x5a,
|
||||||
|
0x3c, 0x12, 0x56, 0x52, 0xd6, 0xd8, 0xa3, 0xaf, 0x5a, 0x51, 0x72, 0xd7, 0x19, 0xc3, 0xca, 0xdd,
|
||||||
|
0xdd, 0xc5, 0x09, 0x5a, 0x71, 0x90, 0x7a, 0xe9, 0xa2, 0xb6, 0xd7, 0x9a, 0x09, 0x03, 0x79, 0xd9,
|
||||||
|
0xad, 0xab, 0xbf, 0x46, 0x77, 0xe2, 0xc3, 0x4e, 0x13, 0xac, 0x38, 0xc8, 0x7c, 0xda, 0xee, 0x10,
|
||||||
|
0xa8, 0x12, 0x11, 0xee, 0xa0, 0x5e, 0x23, 0xc2, 0xe9, 0x47, 0xee, 0x3b, 0x37, 0x51, 0x72, 0x57,
|
||||||
|
0x8b, 0x0e, 0x72, 0x87, 0x76, 0xf8, 0x06, 0x07, 0xfa, 0xef, 0xdc, 0xb6, 0x65, 0x74, 0x1d, 0xe5,
|
||||||
|
0x4b, 0xbd, 0xad, 0xa3, 0x34, 0x26, 0x40, 0xd6, 0xdc, 0x20, 0x1f, 0xf4, 0xb4, 0xeb, 0x9e, 0x9f,
|
||||||
|
0x45, 0x35, 0x6f, 0xd4, 0x5d, 0xd2, 0xdd, 0x27, 0x72, 0x4b, 0xae, 0x44, 0xf7, 0x67, 0xd2, 0x6b,
|
||||||
|
0x86, 0xc5, 0x32, 0xbd, 0x54, 0x89, 0x92, 0xbb, 0xce, 0x18, 0x4a, 0xee, 0xed, 0xed, 0xac, 0xc9,
|
||||||
|
0x9f, 0xfd, 0x73, 0xfe, 0xec, 0x19, 0x32, 0x99, 0xac, 0xa7, 0x87, 0x6f, 0x3d, 0xe9, 0xd3, 0xe9,
|
||||||
|
0x93, 0x27, 0x41, 0x29, 0x54, 0x2d, 0x8e, 0xd1, 0xad, 0x09, 0x2b, 0x16, 0xab, 0xf4, 0xe0, 0x97,
|
||||||
|
0x2d, 0x10, 0x5c, 0x49, 0x51, 0x77, 0x3e, 0xee, 0x80, 0xd5, 0x35, 0xb1, 0x9c, 0xc1, 0xd1, 0x4f,
|
||||||
|
0x00, 0x44, 0x20, 0x77, 0x3f, 0x4a, 0xee, 0x3a, 0x61, 0x10, 0xb9, 0x83, 0x16, 0x71, 0xb9, 0xcd,
|
||||||
|
0x57, 0xa0, 0x45, 0xa7, 0x55, 0x8e, 0xed, 0x3c, 0xbf, 0x97, 0x97, 0x0b, 0xfe, 0xbb, 0x72, 0xf9,
|
||||||
|
0x32, 0x92, 0xab, 0x0e, 0x61, 0xb6, 0x6c, 0xf8, 0xa9, 0xb6, 0xc6, 0xc4, 0x9f, 0xca, 0x48, 0x45,
|
||||||
|
0x79, 0xdb, 0x96, 0x1f, 0x50, 0x8b, 0xc9, 0xf8, 0xe7, 0x22, 0x08, 0x2e, 0xf1, 0xbf, 0x5e, 0x8f,
|
||||||
|
0x92, 0xe3, 0xb1, 0xc8, 0x27, 0x15, 0xad, 0x7d, 0x7a, 0xa9, 0x0f, 0x25, 0x77, 0x9d, 0x31, 0x88,
|
||||||
|
0xdc, 0x1d, 0xed, 0x6d, 0x81, 0xb8, 0xe3, 0x62, 0xa2, 0x91, 0x07, 0xbd, 0x3d, 0xdc, 0xc0, 0xc1,
|
||||||
|
0x03, 0xfb, 0xfe, 0x80, 0x8f, 0x08, 0x85, 0x23, 0x82, 0xde, 0x5e, 0xf0, 0x05, 0x68, 0x6c, 0xa8,
|
||||||
|
0xe7, 0x74, 0x8f, 0x05, 0x13, 0xec, 0xe8, 0x68, 0xaf, 0xa9, 0xae, 0x56, 0x28, 0xc6, 0x9e, 0x63,
|
||||||
|
0x80, 0xe3, 0x50, 0xde, 0x08, 0x2e, 0x87, 0x23, 0x97, 0xcb, 0x07, 0xfa, 0xfb, 0xab, 0x68, 0x95,
|
||||||
|
0x43, 0xea, 0x23, 0x29, 0x1b, 0x02, 0x31, 0xbd, 0xa9, 0xfd, 0xf7, 0x5d, 0xe8, 0xee, 0x3b, 0x61,
|
||||||
|
0x38, 0xb8, 0x90, 0xec, 0x46, 0xd4, 0x5e, 0x6f, 0xc7, 0x90, 0xe2, 0x27, 0x0d, 0xfa, 0xf9, 0x71,
|
||||||
|
0xfb, 0x7f, 0x7b, 0x67, 0xfe, 0xd4, 0xc4, 0x19, 0xc6, 0xf1, 0xfe, 0x21, 0x1d, 0x1c, 0x5a, 0x0a,
|
||||||
|
0x85, 0xaa, 0x48, 0x6d, 0x47, 0x66, 0xac, 0x62, 0xc7, 0xe3, 0x17, 0xb5, 0xc7, 0x54, 0x64, 0x14,
|
||||||
|
0xe8, 0x28, 0xc3, 0x08, 0x72, 0xd4, 0x82, 0x65, 0x38, 0x0c, 0x10, 0xae, 0x10, 0x2e, 0x47, 0xa0,
|
||||||
|
0x2d, 0x08, 0x16, 0x19, 0x3a, 0x9c, 0xc2, 0xa0, 0x23, 0x11, 0x4a, 0xa0, 0xc4, 0x58, 0x20, 0x81,
|
||||||
|
0x8e, 0x22, 0x02, 0x53, 0xc9, 0x01, 0xe4, 0x30, 0x27, 0x77, 0x0e, 0x48, 0x08, 0xf4, 0x8d, 0xb1,
|
||||||
|
0x14, 0xde, 0xdd, 0x6c, 0xb2, 0x99, 0x25, 0x10, 0xd8, 0xef, 0xbc, 0x3f, 0x2c, 0x9b, 0x3d, 0x9e,
|
||||||
|
0x30, 0x9f, 0x7d, 0xf3, 0xbc, 0xef, 0x3e, 0xef, 0xf3, 0x90, 0xb8, 0x3b, 0x2c, 0xe2, 0x71, 0xaf,
|
||||||
|
0xae, 0xfa, 0x0d, 0x3b, 0x50, 0xde, 0x52, 0x0a, 0x78, 0xed, 0xbf, 0x25, 0xb0, 0xdd, 0x5d, 0x4c,
|
||||||
|
0xb0, 0xdd, 0x50, 0x57, 0x0b, 0xb6, 0xef, 0x55, 0x94, 0x83, 0x6d, 0x01, 0x9f, 0x0f, 0xb6, 0xf9,
|
||||||
|
0x3c, 0x73, 0xec, 0xb8, 0xd7, 0x07, 0xfb, 0x06, 0xb8, 0x1c, 0xb0, 0x71, 0xd0, 0xc7, 0xeb, 0x6a,
|
||||||
|
0x68, 0x30, 0x70, 0x8d, 0xc0, 0x76, 0x5c, 0x6c, 0xcc, 0xe5, 0x8b, 0x17, 0xf0, 0x7f, 0x59, 0x07,
|
||||||
|
0x05, 0x70, 0x17, 0x5f, 0xb9, 0x84, 0xc0, 0x9d, 0x86, 0x71, 0x4a, 0x01, 0x1a, 0xee, 0xec, 0x31,
|
||||||
|
0x62, 0x56, 0xfa, 0x92, 0xb8, 0x3b, 0x2c, 0x82, 0x71, 0x07, 0x8e, 0x87, 0x39, 0xbf, 0xbd, 0xbb,
|
||||||
|
0x1b, 0x6a, 0xea, 0x29, 0xd0, 0x97, 0x7b, 0xec, 0x7b, 0x1f, 0x1c, 0xd0, 0xfe, 0xc4, 0x1c, 0x82,
|
||||||
|
0x02, 0x70, 0x3f, 0x15, 0x70, 0xcc, 0xf2, 0x11, 0x8f, 0x37, 0x0e, 0xf6, 0x83, 0xfe, 0xde, 0xf2,
|
||||||
|
0xe7, 0xc7, 0x1e, 0xee, 0x5c, 0x4e, 0xff, 0xda, 0x66, 0xdc, 0xd9, 0x2c, 0x96, 0xe5, 0xd3, 0x96,
|
||||||
|
0xe6, 0x07, 0x27, 0x03, 0xbe, 0x40, 0x5e, 0x7f, 0x8b, 0xb4, 0xc4, 0x1f, 0xc7, 0x8b, 0x7b, 0xe1,
|
||||||
|
0xc3, 0xd7, 0x24, 0xee, 0x3b, 0x50, 0x44, 0xe2, 0x0e, 0xbc, 0x0e, 0x00, 0x25, 0xa0, 0x96, 0xf9,
|
||||||
|
0x47, 0x87, 0xb5, 0x63, 0x7a, 0xfe, 0xec, 0x06, 0x07, 0x80, 0x51, 0xec, 0x84, 0x50, 0x08, 0x70,
|
||||||
|
0x3f, 0xfd, 0x65, 0x80, 0x65, 0xff, 0x4e, 0xc7, 0xfd, 0xea, 0x65, 0xe4, 0x5c, 0x24, 0xc6, 0x29,
|
||||||
|
0x28, 0xb8, 0xe7, 0xf5, 0x3c, 0xdd, 0x62, 0xdc, 0x25, 0x24, 0xee, 0xb6, 0x44, 0xbe, 0x66, 0xb2,
|
||||||
|
0x2d, 0x47, 0x70, 0x7f, 0x04, 0xe3, 0x1e, 0x0d, 0x70, 0x1f, 0x25, 0x71, 0xdf, 0x66, 0x91, 0xb8,
|
||||||
|
0xdb, 0xd6, 0x92, 0x80, 0x27, 0x0e, 0x0b, 0xc6, 0x8f, 0x3b, 0x03, 0xc2, 0x9d, 0x45, 0xe2, 0xbe,
|
||||||
|
0xdd, 0x22, 0x71, 0xb7, 0x2d, 0xe2, 0x70, 0x57, 0x12, 0x62, 0x0f, 0x61, 0xb8, 0x8f, 0x92, 0xb8,
|
||||||
|
0x5b, 0xd1, 0x5e, 0xc6, 0x7d, 0x79, 0x42, 0x20, 0x8d, 0x0e, 0x87, 0x70, 0x57, 0xe4, 0x65, 0x62,
|
||||||
|
0xbc, 0x43, 0x28, 0x66, 0xf0, 0xa0, 0xfc, 0xc3, 0xd1, 0xf4, 0xee, 0xd6, 0x7e, 0x31, 0x21, 0xf6,
|
||||||
|
0x2c, 0xe8, 0x8d, 0xa9, 0x35, 0x70, 0xfe, 0x0f, 0xea, 0xef, 0x43, 0x72, 0xeb, 0x29, 0x8b, 0xc1,
|
||||||
|
0xc3, 0x09, 0xbf, 0x18, 0x0e, 0x09, 0x24, 0xaa, 0x6a, 0xb6, 0x0b, 0x89, 0xc4, 0xdd, 0xb6, 0x8c,
|
||||||
|
0x6a, 0x95, 0x39, 0xf7, 0xd5, 0x66, 0x5c, 0xe4, 0xe9, 0x49, 0x18, 0x39, 0x6a, 0x1e, 0x0d, 0x4a,
|
||||||
|
0xa1, 0xb0, 0x99, 0x08, 0x0a, 0x83, 0xa8, 0xc0, 0x77, 0x30, 0xe4, 0x8d, 0xc9, 0xef, 0x81, 0x70,
|
||||||
|
0xcf, 0x7e, 0x30, 0x66, 0x5c, 0x41, 0x7f, 0xfc, 0x4c, 0x7a, 0x9d, 0x82, 0x06, 0x87, 0x76, 0x4a,
|
||||||
|
0xe3, 0xa3, 0x0d, 0x12, 0x62, 0x1e, 0x3f, 0x17, 0x12, 0x89, 0xbb, 0x6d, 0x81, 0x5e, 0x5c, 0x59,
|
||||||
|
0x98, 0x03, 0xc7, 0x45, 0x7e, 0x77, 0x4e, 0xf7, 0xf2, 0x85, 0xb5, 0x53, 0x40, 0x07, 0x9c, 0x51,
|
||||||
|
0x3f, 0x0c, 0x11, 0x09, 0x1e, 0x80, 0x5a, 0x96, 0x23, 0x39, 0xcc, 0x36, 0x6a, 0x46, 0x63, 0x48,
|
||||||
|
0xb9, 0xff, 0x1c, 0xbe, 0x72, 0x76, 0x67, 0x53, 0xbf, 0xc4, 0xda, 0x29, 0x60, 0xa8, 0x2d, 0xfa,
|
||||||
|
0x3e, 0x08, 0xfe, 0x75, 0xa2, 0x67, 0x10, 0x92, 0x57, 0xd0, 0xb5, 0x44, 0xe2, 0x6e, 0x97, 0xe6,
|
||||||
|
0x9a, 0xeb, 0xf9, 0x9f, 0x1f, 0x80, 0xe3, 0x08, 0x30, 0x97, 0xf3, 0xf5, 0xbd, 0x9e, 0x8e, 0xbf,
|
||||||
|
0xf3, 0x0c, 0xe6, 0x92, 0xd6, 0x75, 0x9f, 0xe9, 0x78, 0x92, 0xcd, 0x57, 0x93, 0xb3, 0x89, 0x77,
|
||||||
|
0xb9, 0xd0, 0x35, 0xaf, 0xdd, 0x6a, 0xcb, 0x6b, 0xb5, 0x5a, 0xc1, 0x74, 0xcd, 0x5c, 0x24, 0xac,
|
||||||
|
0x8c, 0x7f, 0xc4, 0x77, 0xa3, 0xf1, 0x3c, 0x5f, 0xaf, 0xe9, 0xea, 0x4a, 0x87, 0xcd, 0x70, 0x5d,
|
||||||
|
0x91, 0xb8, 0xdb, 0x25, 0xe0, 0x0f, 0xc8, 0xa9, 0xc9, 0x70, 0x07, 0x1f, 0xf4, 0xb5, 0x6e, 0x08,
|
||||||
|
0xab, 0x1e, 0x9b, 0x40, 0xb6, 0x70, 0xb3, 0x1c, 0x41, 0x67, 0xca, 0xe3, 0x84, 0x72, 0x2e, 0x77,
|
||||||
|
0x0c, 0x5f, 0x92, 0x82, 0xb9, 0xc5, 0x25, 0x5a, 0xdd, 0x50, 0x44, 0x1a, 0x5c, 0x88, 0xf4, 0x7a,
|
||||||
|
0x76, 0xe7, 0x2f, 0x6d, 0x58, 0xa1, 0xc5, 0xfa, 0x91, 0x61, 0x51, 0xf0, 0x05, 0xd8, 0x93, 0xf9,
|
||||||
|
0x31, 0x6a, 0x59, 0x48, 0x64, 0x6a, 0x5b, 0x57, 0x11, 0x89, 0xbb, 0xbd, 0x5a, 0xe8, 0xea, 0x10,
|
||||||
|
0x9e, 0x39, 0x0e, 0x7b, 0xf0, 0x59, 0x94, 0xd5, 0x15, 0xac, 0x9c, 0x61, 0xa8, 0xa5, 0x07, 0xde,
|
||||||
|
0x79, 0xf3, 0xa9, 0x8c, 0xb4, 0x9a, 0xa1, 0x8a, 0x4e, 0xc1, 0x94, 0x4a, 0x8b, 0x7a, 0x2e, 0x18,
|
||||||
|
0x7a, 0x3e, 0x19, 0x94, 0x66, 0x36, 0x8c, 0xc4, 0x95, 0xf6, 0xa1, 0x5e, 0x21, 0x36, 0xb7, 0xab,
|
||||||
|
0xf1, 0x2f, 0x11, 0xb6, 0xd9, 0x0a, 0x1a, 0x1c, 0xbd, 0x0c, 0xba, 0xf6, 0x99, 0x5a, 0xab, 0xe1,
|
||||||
|
0x9c, 0xbb, 0x5b, 0x24, 0xee, 0x38, 0x04, 0xbc, 0x17, 0x08, 0x9d, 0xb7, 0xc4, 0xa7, 0x9a, 0x74,
|
||||||
|
0xe8, 0xbc, 0xae, 0xab, 0xaa, 0x67, 0x92, 0x72, 0x87, 0x85, 0x8a, 0xec, 0xff, 0x8d, 0xc2, 0xb8,
|
||||||
|
0x9e, 0xd5, 0x69, 0xae, 0x2d, 0x95, 0xdd, 0x19, 0x49, 0xed, 0xb0, 0xd4, 0x16, 0xb5, 0xd6, 0xa2,
|
||||||
|
0x72, 0x98, 0x65, 0x98, 0x9d, 0xfa, 0xda, 0xdb, 0x84, 0x84, 0x8a, 0xbc, 0x2c, 0xa4, 0xc1, 0xca,
|
||||||
|
0xa2, 0xdc, 0x3d, 0xe8, 0xb5, 0x5b, 0x44, 0xe2, 0x8e, 0x4f, 0xc8, 0x19, 0x3d, 0x33, 0xf1, 0xd4,
|
||||||
|
0x14, 0x7b, 0x00, 0xaa, 0x61, 0x8b, 0xf2, 0xea, 0x51, 0x92, 0xec, 0xe1, 0x6a, 0x49, 0x25, 0xec,
|
||||||
|
0x4a, 0xa6, 0xd0, 0xe6, 0xbd, 0x8c, 0x0a, 0xb9, 0x3c, 0x1d, 0xf6, 0xbe, 0xcc, 0xac, 0xe7, 0x65,
|
||||||
|
0xad, 0x12, 0x51, 0x21, 0xd4, 0x45, 0x45, 0xe2, 0x8e, 0x4f, 0x26, 0xbd, 0x1e, 0x95, 0x78, 0x51,
|
||||||
|
0x48, 0xa0, 0x96, 0xdb, 0x67, 0xe7, 0x45, 0x58, 0xa3, 0x2a, 0x7a, 0xeb, 0x3f, 0x94, 0xbb, 0x5c,
|
||||||
|
0x64, 0x5e, 0x1a, 0xb4, 0x5e, 0xbf, 0x2d, 0xae, 0xa4, 0x37, 0xa3, 0x71, 0xb4, 0xb9, 0x5f, 0xa2,
|
||||||
|
0x5e, 0x5c, 0xb6, 0xe7, 0xfa, 0x9a, 0x5e, 0xf6, 0x54, 0xd0, 0x37, 0x48, 0x23, 0x15, 0x39, 0x69,
|
||||||
|
0x2b, 0x73, 0xc4, 0xc4, 0xdc, 0xbb, 0xa8, 0x48, 0xdc, 0x1d, 0x91, 0xba, 0xe2, 0x67, 0xde, 0x41,
|
||||||
|
0x4f, 0xd4, 0x6e, 0xde, 0x88, 0x73, 0xc5, 0x96, 0x66, 0xc9, 0x38, 0x2e, 0x5b, 0xe4, 0xf0, 0x66,
|
||||||
|
0x5a, 0x38, 0xd2, 0x1a, 0xd6, 0x24, 0x70, 0xe5, 0xab, 0xba, 0x27, 0x9a, 0xfa, 0xc4, 0xec, 0x31,
|
||||||
|
0xd5, 0xa4, 0x4a, 0xeb, 0x40, 0xb1, 0x6f, 0x73, 0xe9, 0x6a, 0xb4, 0xf2, 0x18, 0xaa, 0xd2, 0xdb,
|
||||||
|
0xab, 0xa6, 0xdd, 0x53, 0x3a, 0xdc, 0x31, 0xa1, 0xe3, 0x6e, 0x30, 0x18, 0x5e, 0x0e, 0xbd, 0xd8,
|
||||||
|
0xd8, 0x62, 0xa3, 0x22, 0x1b, 0xeb, 0xeb, 0x36, 0xee, 0xe1, 0xf3, 0xb7, 0xad, 0x38, 0xd1, 0x4e,
|
||||||
|
0x90, 0x7e, 0x64, 0x58, 0x1c, 0x1e, 0x8a, 0xa4, 0x6a, 0xf2, 0xdc, 0x29, 0x25, 0x8d, 0x6a, 0x72,
|
||||||
|
0xba, 0xc3, 0x60, 0x7e, 0x39, 0x50, 0x94, 0x3b, 0xee, 0xed, 0x8e, 0x34, 0x49, 0x78, 0xfc, 0xc8,
|
||||||
|
0x6c, 0x4b, 0x83, 0x93, 0xed, 0xd9, 0x99, 0xb2, 0xda, 0xbb, 0xff, 0x3d, 0x38, 0xb0, 0x5e, 0x3f,
|
||||||
|
0x16, 0xd9, 0x02, 0x8e, 0xfa, 0x13, 0x52, 0x24, 0xde, 0xd5, 0xf5, 0xae, 0xac, 0x1c, 0x82, 0x30,
|
||||||
|
0xf3, 0x64, 0x5f, 0x5c, 0x94, 0xa6, 0xef, 0x99, 0x13, 0x6c, 0xd0, 0x3e, 0x1f, 0x94, 0x53, 0x93,
|
||||||
|
0xcd, 0x69, 0xff, 0x91, 0x66, 0x78, 0xba, 0xa9, 0x8a, 0x0b, 0x9c, 0x60, 0x83, 0xab, 0x08, 0xcb,
|
||||||
|
0x99, 0x11, 0x08, 0xf8, 0x96, 0xd5, 0x18, 0x50, 0xfb, 0xf6, 0xfc, 0x59, 0xbc, 0x4b, 0x4e, 0x77,
|
||||||
|
0xb1, 0x80, 0x87, 0xa0, 0xcc, 0x47, 0x99, 0x00, 0x59, 0x6f, 0xb2, 0xe4, 0x9b, 0xb3, 0x4d, 0xb5,
|
||||||
|
0x26, 0x0d, 0x91, 0x0b, 0x0e, 0xc1, 0x70, 0x73, 0xbe, 0xa3, 0x0d, 0xf8, 0x4e, 0x7c, 0x3f, 0x1f,
|
||||||
|
0x6b, 0xf7, 0x55, 0x80, 0x1f, 0x99, 0x65, 0xbb, 0x7c, 0xfd, 0xbd, 0x23, 0x1b, 0xbe, 0xbb, 0x5a,
|
||||||
|
0xad, 0xda, 0xef, 0xe5, 0xb1, 0x91, 0xf5, 0x88, 0xf0, 0x30, 0xe7, 0x58, 0xe6, 0x5a, 0x5a, 0x99,
|
||||||
|
0x9d, 0x51, 0x97, 0x15, 0xf3, 0x7c, 0x3e, 0xc4, 0xe0, 0x5e, 0x70, 0xc2, 0x5f, 0x9e, 0x71, 0x6b,
|
||||||
|
0xfa, 0xde, 0xaf, 0x4b, 0xbc, 0x71, 0xbc, 0xfd, 0x85, 0x49, 0xa7, 0x5b, 0xe2, 0x8f, 0x4f, 0x57,
|
||||||
|
0x57, 0xca, 0xb3, 0x28, 0xc2, 0xd3, 0xc7, 0x30, 0xee, 0xc2, 0x3b, 0xfc, 0x89, 0xaa, 0xa4, 0x70,
|
||||||
|
0x0f, 0xc6, 0xc3, 0xd8, 0x23, 0xdb, 0x43, 0x55, 0xbd, 0x4e, 0xe7, 0x7f, 0xd8, 0xcf, 0xc2, 0x7a,
|
||||||
|
0x6a, 0x4a, 0x92, 0x13, 0x6c, 0x72, 0x69, 0x69, 0x07, 0x38, 0xb2, 0x54, 0x38, 0x9e, 0x0c, 0x9d,
|
||||||
|
0xcb, 0x03, 0x1f, 0x09, 0x8e, 0x7e, 0x36, 0x75, 0xf1, 0xab, 0x37, 0x09, 0x37, 0xc0, 0x63, 0xa0,
|
||||||
|
0xc8, 0xa5, 0x2a, 0xf3, 0xb3, 0x81, 0xff, 0xad, 0x2c, 0xc8, 0x51, 0xd0, 0x33, 0x15, 0xd9, 0x69,
|
||||||
|
0xb2, 0xe4, 0x78, 0xf1, 0x95, 0x4b, 0xc2, 0x13, 0xfe, 0xf6, 0x54, 0xa8, 0xe3, 0xf9, 0x79, 0xcb,
|
||||||
|
0x12, 0xe3, 0xe6, 0xdb, 0x1f, 0x6f, 0xf7, 0x3f, 0x60, 0x47, 0xcb, 0xae, 0x99, 0x19, 0x93, 0xc9,
|
||||||
|
0x74, 0x68, 0xbf, 0x77, 0x4a, 0x62, 0xc2, 0x56, 0x5b, 0xb3, 0x9b, 0xa4, 0x61, 0xf7, 0x28, 0x0b,
|
||||||
|
0x73, 0x26, 0xce, 0x9e, 0xb4, 0x07, 0x7d, 0x87, 0xdb, 0xe4, 0xf9, 0x33, 0x0a, 0x7a, 0xc6, 0x02,
|
||||||
|
0xb3, 0x7d, 0xbb, 0xbf, 0xae, 0x6b, 0xe8, 0x3d, 0x83, 0x61, 0x59, 0x43, 0x6a, 0x2b, 0x35, 0x2f,
|
||||||
|
0x95, 0xc8, 0x3b, 0x18, 0xa2, 0xd2, 0x22, 0x41, 0x52, 0xfc, 0x48, 0x80, 0xff, 0xab, 0x43, 0xde,
|
||||||
|
0x38, 0x9a, 0xef, 0xe6, 0x01, 0xa8, 0xa7, 0x1b, 0xff, 0x53, 0x1f, 0x69, 0xcc, 0x35, 0xe5, 0x6d,
|
||||||
|
0xba, 0xa6, 0xf7, 0x29, 0x39, 0xb1, 0x88, 0x57, 0xf6, 0xce, 0xbb, 0x93, 0x22, 0x50, 0x26, 0xf0,
|
||||||
|
0x10, 0x70, 0x7a, 0x67, 0xea, 0x6b, 0x54, 0xa5, 0x45, 0x60, 0x98, 0x0b, 0x3c, 0x19, 0xe0, 0xb7,
|
||||||
|
0x48, 0x6f, 0x44, 0x4a, 0xc2, 0x43, 0x45, 0x21, 0x81, 0xe2, 0xb0, 0x60, 0x69, 0x74, 0xf8, 0x9b,
|
||||||
|
0x9f, 0x7e, 0x90, 0xa7, 0x27, 0x81, 0x4f, 0xc1, 0x31, 0x33, 0xb5, 0xd5, 0xda, 0x81, 0x7e, 0x83,
|
||||||
|
0xcc, 0xa9, 0xc5, 0x8a, 0x77, 0xa5, 0xfe, 0x05, 0x34, 0x91, 0x5b, 0x5a, 0x71, 0xf0, 0xe8, 0x07,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
|
||||||
|
};
|
||||||
|
|
||||||
|
const BITMAP_OPAQUE tune_diff_pair_length_legend_xpm[1] = {{ png, sizeof( png ), "tune_diff_pair_length_legend_xpm" }};
|
||||||
|
|
||||||
|
//EOF
|
|
@ -0,0 +1,362 @@
|
||||||
|
|
||||||
|
/* Do not modify this file, it was automatically generated by the
|
||||||
|
* PNG2cpp CMake script, using a *.png file as input.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bitmaps.h>
|
||||||
|
|
||||||
|
static const unsigned char png[] = {
|
||||||
|
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
|
||||||
|
0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x62, 0x08, 0x02, 0x00, 0x00, 0x01, 0x81, 0xbc, 0x69,
|
||||||
|
0xd2, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x1e, 0xc2, 0x00, 0x00, 0x1e,
|
||||||
|
0xc2, 0x01, 0x6e, 0xd0, 0x75, 0x3e, 0x00, 0x00, 0x00, 0x09, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f,
|
||||||
|
0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x89, 0x2a, 0x8d, 0x06, 0x00, 0x00, 0x15, 0x65, 0x49,
|
||||||
|
0x44, 0x41, 0x54, 0x78, 0x9c, 0xed, 0x5d, 0x89, 0x5f, 0x13, 0xd7, 0x1a, 0xed, 0x7f, 0xf1, 0x6c,
|
||||||
|
0x5d, 0x00, 0x37, 0xac, 0x56, 0xad, 0x6d, 0xad, 0xb6, 0xd5, 0xda, 0x45, 0x5f, 0xad, 0x4f, 0xfb,
|
||||||
|
0xac, 0xaf, 0x8b, 0xad, 0xd6, 0xf7, 0x6c, 0x1b, 0x54, 0x04, 0x91, 0x55, 0x14, 0x10, 0x41, 0x14,
|
||||||
|
0x14, 0x14, 0x5b, 0x15, 0x5c, 0xd9, 0x41, 0x01, 0xc1, 0x8d, 0x4d, 0x76, 0x64, 0x47, 0x05, 0x64,
|
||||||
|
0x0b, 0x88, 0x0a, 0x84, 0x7d, 0xdf, 0x03, 0x01, 0x02, 0xef, 0x9b, 0xdc, 0x38, 0x0c, 0x59, 0x27,
|
||||||
|
0xc9, 0x4c, 0x26, 0x81, 0x39, 0xbf, 0x43, 0x7e, 0x93, 0xc9, 0xcc, 0xbd, 0x5f, 0x0e, 0x27, 0x77,
|
||||||
|
0xee, 0xdc, 0xb9, 0xcb, 0x5b, 0x13, 0xe4, 0x30, 0x32, 0x32, 0x42, 0xf2, 0x48, 0x09, 0xbc, 0x45,
|
||||||
|
0xe6, 0x20, 0xb3, 0x03, 0xfb, 0x0c, 0xde, 0xf9, 0x07, 0xf5, 0x19, 0x38, 0x1e, 0x3d, 0x22, 0xbd,
|
||||||
|
0x73, 0xfe, 0xdc, 0x77, 0x28, 0xcb, 0x80, 0x12, 0xbc, 0x55, 0x59, 0x59, 0xf9, 0xe0, 0xfe, 0x7d,
|
||||||
|
0x99, 0x0c, 0x0c, 0x8b, 0xf4, 0x38, 0x77, 0x83, 0x48, 0xc7, 0xd3, 0x21, 0x4e, 0x7e, 0x4f, 0x55,
|
||||||
|
0xcb, 0x00, 0xfe, 0xc8, 0xeb, 0xab, 0xc6, 0x7f, 0x82, 0xac, 0x44, 0x5b, 0x37, 0x6f, 0x1a, 0x1c,
|
||||||
|
0x1c, 0x44, 0xdb, 0x39, 0xd5, 0x5d, 0x6a, 0x66, 0x10, 0x17, 0x1b, 0x03, 0xaf, 0xa1, 0xc1, 0x81,
|
||||||
|
0x03, 0x03, 0x03, 0x12, 0xc7, 0xf5, 0xf7, 0xf7, 0xe3, 0xdb, 0xdc, 0xa6, 0xfe, 0x09, 0xd2, 0x90,
|
||||||
|
0x2b, 0x11, 0xc7, 0x25, 0x41, 0xde, 0x39, 0x26, 0xc7, 0x1e, 0xaa, 0x96, 0x01, 0x11, 0x76, 0xa1,
|
||||||
|
0xa5, 0x1c, 0x87, 0x18, 0xce, 0xf1, 0x38, 0xc5, 0xa7, 0x71, 0x5c, 0x13, 0x39, 0x4e, 0xb1, 0x4a,
|
||||||
|
0x29, 0x23, 0x03, 0xca, 0xa1, 0xf5, 0x0c, 0x5a, 0x4f, 0x1f, 0xaf, 0xfb, 0xe5, 0x7b, 0xaa, 0x48,
|
||||||
|
0xf6, 0x1b, 0x50, 0x5f, 0x10, 0xb5, 0xb5, 0xb5, 0xa9, 0x97, 0x22, 0xa9, 0xd4, 0x73, 0x72, 0xb2,
|
||||||
|
0xa5, 0x43, 0x56, 0xf5, 0x4b, 0x28, 0x4a, 0x5d, 0xa5, 0x84, 0x64, 0xa7, 0x2e, 0xaf, 0x74, 0x0b,
|
||||||
|
0x0e, 0x0a, 0x94, 0x28, 0xdd, 0x80, 0x2a, 0xfd, 0xac, 0x26, 0x14, 0xfc, 0x74, 0x9d, 0x3d, 0x82,
|
||||||
|
0xa4, 0x77, 0xc2, 0x91, 0xea, 0xfc, 0x6e, 0x3d, 0x4e, 0xbb, 0x49, 0x7c, 0x20, 0x91, 0x0a, 0xaf,
|
||||||
|
0xae, 0xf6, 0xc2, 0x79, 0x2f, 0xe9, 0xfd, 0xa4, 0x52, 0x07, 0x58, 0x9a, 0x9b, 0x75, 0x76, 0x76,
|
||||||
|
0x18, 0xce, 0x9e, 0x95, 0x9d, 0x95, 0xa9, 0x20, 0x15, 0x95, 0x53, 0x97, 0xa9, 0x8c, 0xf9, 0xc5,
|
||||||
|
0x1c, 0x99, 0x27, 0x5c, 0x4f, 0x7e, 0xad, 0x5a, 0xea, 0x44, 0x60, 0xc5, 0x99, 0x43, 0x8c, 0x53,
|
||||||
|
0x64, 0x85, 0x82, 0x73, 0x62, 0x8a, 0x5a, 0xc8, 0x14, 0x67, 0x40, 0x7a, 0x4b, 0x1b, 0xed, 0xa6,
|
||||||
|
0x4e, 0x61, 0x29, 0x06, 0xa4, 0x2c, 0x76, 0xdf, 0x4b, 0x17, 0xd1, 0xa5, 0x54, 0x9b, 0x50, 0x27,
|
||||||
|
0x7a, 0x79, 0x85, 0x50, 0x51, 0xe1, 0x33, 0xcd, 0x82, 0x51, 0x19, 0x6a, 0x46, 0xbf, 0x72, 0xe9,
|
||||||
|
0x12, 0x32, 0x25, 0x32, 0x1c, 0xa3, 0xf6, 0xd5, 0x87, 0x0c, 0xa8, 0xd4, 0x5e, 0xfb, 0x10, 0x47,
|
||||||
|
0xbf, 0x7a, 0xd5, 0x0a, 0x1b, 0x4b, 0x0b, 0x92, 0xe7, 0x5c, 0x08, 0x8a, 0x81, 0x12, 0xf3, 0x55,
|
||||||
|
0xab, 0x64, 0x3d, 0x51, 0x26, 0xe0, 0x48, 0xb3, 0x93, 0x8f, 0xd4, 0x8c, 0x4e, 0x19, 0x64, 0x68,
|
||||||
|
0x6f, 0x34, 0xe7, 0x6d, 0xc5, 0xe7, 0xc8, 0xbc, 0x80, 0x49, 0x63, 0xef, 0x6f, 0xbb, 0x90, 0x6d,
|
||||||
|
0xe0, 0x0b, 0xa4, 0x71, 0x3b, 0xd4, 0x08, 0x4e, 0x29, 0x24, 0xa3, 0x87, 0xfc, 0x76, 0xfd, 0xfc,
|
||||||
|
0x23, 0x5c, 0xad, 0xa0, 0x00, 0x59, 0xba, 0x68, 0xfe, 0xaa, 0xe5, 0x4b, 0x53, 0x53, 0x92, 0x17,
|
||||||
|
0x1a, 0xcc, 0x31, 0x5e, 0x60, 0x08, 0xdb, 0xe8, 0x18, 0x05, 0x97, 0xaa, 0xd6, 0xd6, 0x56, 0x78,
|
||||||
|
0x5d, 0xb7, 0x66, 0xf5, 0xba, 0xb5, 0xab, 0xf1, 0x9d, 0x70, 0x7c, 0x61, 0x5d, 0x0f, 0x0d, 0xc1,
|
||||||
|
0x8b, 0xa2, 0x0f, 0xbf, 0x15, 0xf6, 0xd9, 0x9a, 0x8f, 0x80, 0x8d, 0x8d, 0x0d, 0x64, 0xce, 0x51,
|
||||||
|
0xb5, 0x16, 0x02, 0xc7, 0x07, 0x3f, 0xae, 0x53, 0x27, 0x3a, 0x65, 0x10, 0x6b, 0xdf, 0x26, 0xd2,
|
||||||
|
0x4c, 0x1a, 0x91, 0xf9, 0x8d, 0x01, 0x19, 0x75, 0x88, 0x17, 0x62, 0xab, 0x21, 0x0e, 0x55, 0x43,
|
||||||
|
0x47, 0x80, 0x5b, 0x11, 0x38, 0xd1, 0x29, 0xbc, 0xdc, 0x37, 0xf1, 0x15, 0x55, 0x9c, 0xd0, 0xc2,
|
||||||
|
0x5d, 0x03, 0xad, 0x98, 0xd6, 0xd1, 0xb7, 0x5d, 0x38, 0xd3, 0xe2, 0xe6, 0xa8, 0x9b, 0x54, 0x1e,
|
||||||
|
0x3d, 0x79, 0xec, 0xf8, 0x6e, 0xeb, 0xc6, 0x0d, 0xeb, 0xa9, 0x4a, 0x8d, 0x0c, 0x28, 0x0b, 0x7d,
|
||||||
|
0xc1, 0xbc, 0xd9, 0x54, 0x25, 0x45, 0x12, 0x94, 0x85, 0x3e, 0x36, 0x36, 0x26, 0xef, 0x23, 0x3e,
|
||||||
|
0x9f, 0x4f, 0x55, 0x2e, 0x44, 0xa8, 0x1f, 0xba, 0x74, 0xeb, 0x66, 0x77, 0xd7, 0x94, 0xd6, 0x29,
|
||||||
|
0xbc, 0xa5, 0xa9, 0xa7, 0xa7, 0x5b, 0xed, 0x5c, 0x14, 0x40, 0xcd, 0xd0, 0xc9, 0x54, 0x18, 0x8b,
|
||||||
|
0x8b, 0x0a, 0xe1, 0x98, 0xe6, 0xa6, 0x26, 0x1d, 0x0a, 0x7d, 0x78, 0x78, 0x98, 0x7c, 0xe8, 0x3e,
|
||||||
|
0x17, 0xff, 0xd6, 0xa1, 0xd0, 0x11, 0xb2, 0x32, 0x1f, 0x2b, 0x3e, 0x80, 0x57, 0x27, 0xae, 0x0b,
|
||||||
|
0xe8, 0x5c, 0xe8, 0xe4, 0x41, 0x57, 0xe8, 0xa8, 0xed, 0xe7, 0x82, 0xf7, 0x39, 0x79, 0xcd, 0x42,
|
||||||
|
0x32, 0xe9, 0xe1, 0xed, 0x27, 0xdd, 0x56, 0x24, 0xdd, 0x74, 0x04, 0x1c, 0x14, 0x8c, 0xd1, 0xab,
|
||||||
|
0xba, 0x4a, 0x37, 0x69, 0x10, 0x90, 0xa9, 0x67, 0x3a, 0x99, 0x23, 0x2d, 0xfc, 0x0a, 0xe0, 0x60,
|
||||||
|
0x1a, 0x43, 0x9f, 0x3f, 0xf7, 0x1d, 0x08, 0xfd, 0x9b, 0xaf, 0xbf, 0x20, 0x73, 0xc2, 0xa9, 0x7b,
|
||||||
|
0x55, 0x64, 0x2a, 0x92, 0x28, 0x4d, 0xa0, 0xed, 0xcd, 0x67, 0x07, 0x4f, 0xdc, 0xd7, 0x34, 0x4c,
|
||||||
|
0x59, 0x10, 0xab, 0xfe, 0xfb, 0x9e, 0xdd, 0x68, 0x03, 0x6e, 0x38, 0x14, 0x9f, 0xc0, 0x71, 0x4b,
|
||||||
|
0xb2, 0x0f, 0x2b, 0x25, 0x93, 0xf4, 0xc7, 0x1f, 0xac, 0x74, 0x77, 0x73, 0x1d, 0x1e, 0x15, 0x9a,
|
||||||
|
0x39, 0x45, 0x6b, 0x12, 0xa2, 0x3c, 0x48, 0x86, 0xee, 0x74, 0xcc, 0x5e, 0xb1, 0x79, 0x38, 0xae,
|
||||||
|
0x89, 0x4e, 0x11, 0xe5, 0x32, 0x3f, 0x32, 0x9e, 0x6f, 0x80, 0xaa, 0x03, 0xb6, 0x56, 0x87, 0xf1,
|
||||||
|
0x9d, 0x23, 0x63, 0x42, 0xf5, 0xaa, 0xfb, 0x4a, 0x31, 0x25, 0xf4, 0x8e, 0x8e, 0x76, 0xb8, 0xdf,
|
||||||
|
0xdb, 0xbc, 0xf1, 0xab, 0x09, 0x51, 0x75, 0xca, 0xf1, 0xe8, 0x11, 0x81, 0x40, 0xf0, 0xcd, 0xd7,
|
||||||
|
0x5f, 0x92, 0x0f, 0x1d, 0x6d, 0x10, 0xbf, 0x3c, 0xfc, 0x4c, 0xb5, 0x11, 0x3a, 0x9e, 0xe5, 0xf7,
|
||||||
|
0xdb, 0xfe, 0x05, 0xaf, 0xf5, 0xf5, 0xbc, 0x07, 0xf7, 0xee, 0xa2, 0x3d, 0x47, 0xed, 0x6c, 0xd1,
|
||||||
|
0x06, 0x99, 0xd0, 0x89, 0xe8, 0x1e, 0x1c, 0xa1, 0x31, 0x74, 0xb8, 0x49, 0x85, 0x5c, 0xe1, 0x95,
|
||||||
|
0xcc, 0x09, 0x9c, 0x63, 0x0f, 0xaf, 0xa7, 0xd6, 0xa8, 0x94, 0x07, 0x8d, 0xa1, 0x67, 0x67, 0x66,
|
||||||
|
0x82, 0xde, 0xf8, 0x33, 0x3e, 0xca, 0xe3, 0x80, 0x53, 0xae, 0xa6, 0xd4, 0xa8, 0x7a, 0x96, 0x52,
|
||||||
|
0x28, 0x29, 0xd7, 0xf1, 0xfb, 0x6b, 0xa0, 0xd5, 0x8d, 0xa7, 0x10, 0x04, 0x14, 0x8e, 0x6a, 0x64,
|
||||||
|
0x03, 0x27, 0xee, 0x77, 0x4f, 0xf1, 0xa1, 0xee, 0xfe, 0xfa, 0x66, 0x7a, 0xad, 0x92, 0x8a, 0x00,
|
||||||
|
0x6a, 0x94, 0xc7, 0xe8, 0x1c, 0x7f, 0xf0, 0x42, 0x96, 0x1a, 0x41, 0xe3, 0x70, 0x08, 0x2c, 0x24,
|
||||||
|
0xd9, 0x76, 0x4f, 0x86, 0xb6, 0x21, 0xa5, 0x7a, 0x7c, 0x73, 0xcd, 0x86, 0xce, 0x04, 0xa6, 0x6f,
|
||||||
|
0xe8, 0x8c, 0xb7, 0xb7, 0xc8, 0x63, 0xbb, 0x8f, 0xb7, 0x92, 0xd0, 0xa9, 0x7d, 0xb8, 0x45, 0x21,
|
||||||
|
0xdb, 0xbc, 0xdd, 0x75, 0xce, 0x30, 0x56, 0x16, 0xe6, 0xb1, 0x0f, 0x1f, 0xc0, 0x46, 0x5d, 0x6d,
|
||||||
|
0xad, 0xcc, 0x9a, 0xc5, 0xf4, 0x80, 0xce, 0xe9, 0x0e, 0xe0, 0x56, 0x94, 0x7f, 0xbb, 0xe9, 0x2b,
|
||||||
|
0xb8, 0xc4, 0x7f, 0xb7, 0x65, 0x33, 0xd3, 0xb1, 0xd0, 0x05, 0x2d, 0xe9, 0x4e, 0xfe, 0x99, 0x60,
|
||||||
|
0x7a, 0x5a, 0xaa, 0xe1, 0xec, 0x59, 0xd7, 0xaf, 0xfa, 0xee, 0xd9, 0xb5, 0xf3, 0xc3, 0x15, 0xef,
|
||||||
|
0x91, 0xcf, 0x82, 0xa6, 0xbb, 0x60, 0x9a, 0xc0, 0x80, 0xee, 0x70, 0x17, 0xa6, 0xf9, 0xb3, 0x62,
|
||||||
|
0xd4, 0xc0, 0x96, 0x93, 0x35, 0x59, 0x2f, 0x64, 0x75, 0x97, 0x81, 0xbd, 0x7b, 0x76, 0xa3, 0x36,
|
||||||
|
0x0e, 0x9c, 0xfb, 0x39, 0x7f, 0x68, 0xc2, 0x9d, 0x3f, 0xfe, 0x87, 0x98, 0xda, 0x22, 0xc3, 0xb9,
|
||||||
|
0xac, 0xee, 0x32, 0x80, 0xfb, 0xbd, 0xa1, 0xa1, 0xde, 0x68, 0xce, 0xdb, 0x54, 0xf9, 0xfd, 0xd0,
|
||||||
|
0xc1, 0x03, 0xf8, 0x1e, 0x56, 0x77, 0x19, 0xd0, 0x42, 0x9f, 0x0f, 0x56, 0x77, 0x19, 0x20, 0xea,
|
||||||
|
0x1e, 0xf5, 0xa4, 0xc9, 0x36, 0xb4, 0xd4, 0xca, 0xbf, 0xd0, 0xfa, 0xfa, 0x13, 0xab, 0x6b, 0x18,
|
||||||
|
0x2d, 0xaf, 0x16, 0x58, 0x5d, 0x2d, 0xb0, 0xbc, 0x92, 0x0f, 0x3c, 0xec, 0x0b, 0xcc, 0xb3, 0xf0,
|
||||||
|
0xc9, 0xb3, 0xb8, 0x9c, 0x7b, 0x08, 0x78, 0x09, 0x98, 0x63, 0x7e, 0x31, 0xc7, 0xec, 0xef, 0x6c,
|
||||||
|
0xb3, 0xbf, 0xb2, 0xe0, 0x46, 0xff, 0xa0, 0x77, 0x26, 0xd0, 0xf6, 0xe6, 0x53, 0xc7, 0x88, 0x72,
|
||||||
|
0x62, 0x47, 0x68, 0x3d, 0xd6, 0x7d, 0x6c, 0x6c, 0x8c, 0xa6, 0xde, 0x51, 0xa0, 0xbb, 0xeb, 0x9d,
|
||||||
|
0x0a, 0xf4, 0xf0, 0x00, 0xc8, 0xf1, 0x48, 0xb5, 0xbc, 0xf6, 0xc4, 0xda, 0xaf, 0xd0, 0xc6, 0x5f,
|
||||||
|
0xc4, 0x00, 0x78, 0x2d, 0xb2, 0x09, 0x10, 0x31, 0xb0, 0x18, 0x68, 0x8b, 0x18, 0x04, 0x7c, 0x2e,
|
||||||
|
0x66, 0x30, 0x62, 0x09, 0xa2, 0xe5, 0x8d, 0x67, 0x1c, 0x87, 0x18, 0x94, 0xda, 0x3e, 0x87, 0x87,
|
||||||
|
0xe3, 0xe3, 0xe3, 0xfa, 0xaa, 0x7b, 0x6b, 0x4b, 0x0b, 0x7e, 0x99, 0xa2, 0x3c, 0x1b, 0x67, 0x8f,
|
||||||
|
0x20, 0xec, 0xe9, 0xc8, 0xa5, 0xbc, 0xae, 0x01, 0x35, 0x47, 0x97, 0x10, 0x11, 0x1a, 0x1c, 0xb4,
|
||||||
|
0xd0, 0x60, 0x0e, 0x0a, 0x35, 0x30, 0x55, 0xdc, 0x11, 0xe6, 0x54, 0x84, 0xb6, 0xbb, 0x08, 0x6a,
|
||||||
|
0x02, 0xb1, 0xee, 0x99, 0x8f, 0x33, 0x24, 0xea, 0x1b, 0x78, 0x8b, 0x2a, 0xdc, 0x37, 0x86, 0x04,
|
||||||
|
0x05, 0x6a, 0x92, 0x87, 0xa5, 0x6f, 0x3e, 0xe8, 0x7e, 0xc8, 0x27, 0x4f, 0xd3, 0x60, 0xdf, 0x60,
|
||||||
|
0xe9, 0xa2, 0xf9, 0x28, 0x48, 0x34, 0xb0, 0xe6, 0xe9, 0xeb, 0x6e, 0xac, 0x23, 0x9d, 0x53, 0x74,
|
||||||
|
0x47, 0xbf, 0x80, 0xaa, 0x2c, 0xe8, 0x86, 0x64, 0xf9, 0x8e, 0x3f, 0xaf, 0xc1, 0x01, 0x5f, 0xef,
|
||||||
|
0x56, 0x68, 0xc8, 0xbe, 0x3f, 0xf7, 0xaa, 0x9d, 0x07, 0xc7, 0x35, 0x11, 0x74, 0x97, 0xf7, 0x98,
|
||||||
|
0x41, 0x31, 0x5a, 0xa5, 0xfa, 0x7e, 0xd9, 0xdb, 0x5a, 0xa3, 0x8d, 0xcd, 0x1b, 0xbf, 0x44, 0x9d,
|
||||||
|
0x13, 0x84, 0xc2, 0x71, 0xa4, 0xfb, 0xe3, 0x4a, 0x5a, 0xba, 0x00, 0xd2, 0x01, 0x25, 0xba, 0xe3,
|
||||||
|
0x65, 0xce, 0x47, 0x2b, 0x97, 0x27, 0xc4, 0x29, 0x19, 0x29, 0x23, 0x0f, 0xa0, 0x3b, 0xd6, 0xaf,
|
||||||
|
0x4d, 0x45, 0xdd, 0x8d, 0xe7, 0x1b, 0xf8, 0xdf, 0xbc, 0x81, 0xbf, 0x7d, 0x7f, 0x19, 0xd6, 0x81,
|
||||||
|
0xf7, 0x83, 0xe5, 0xcb, 0xa4, 0x8f, 0x1c, 0x1e, 0x11, 0xa2, 0xa2, 0xa6, 0xe0, 0xb5, 0xde, 0x14,
|
||||||
|
0xf1, 0x8a, 0x74, 0xdf, 0xb8, 0x61, 0xfd, 0xed, 0xb0, 0xd0, 0xe1, 0x37, 0x80, 0xaf, 0x0d, 0xaf,
|
||||||
|
0x71, 0xb1, 0x31, 0x42, 0xa1, 0x10, 0x6c, 0x58, 0xc9, 0xc5, 0xba, 0xf7, 0x3f, 0xb8, 0x77, 0x17,
|
||||||
|
0xae, 0x69, 0x2d, 0xcd, 0xcd, 0xd6, 0x87, 0x0f, 0xc1, 0xdb, 0x9e, 0xee, 0xee, 0xf7, 0xdf, 0x7b,
|
||||||
|
0x57, 0x22, 0x4d, 0xb5, 0x75, 0x27, 0x8e, 0xe1, 0x9a, 0x10, 0xd5, 0xd9, 0x65, 0x1e, 0xd9, 0x37,
|
||||||
|
0x34, 0x8a, 0x74, 0x2f, 0xad, 0xef, 0x53, 0x29, 0x0b, 0x06, 0x21, 0x57, 0xf7, 0xc8, 0xf0, 0xdb,
|
||||||
|
0xd2, 0xcd, 0x23, 0x20, 0x3d, 0xea, 0x9f, 0xdf, 0xd9, 0xd9, 0x51, 0x5f, 0xcf, 0x9b, 0x10, 0xe9,
|
||||||
|
0x6e, 0x67, 0x6d, 0xf9, 0xc5, 0xba, 0x4f, 0xc2, 0x42, 0x82, 0x79, 0xbc, 0xba, 0xed, 0x5b, 0xb7,
|
||||||
|
0xc0, 0x4e, 0xb8, 0x7b, 0x24, 0x9e, 0x85, 0x74, 0x3f, 0x71, 0x47, 0xd1, 0x30, 0x0c, 0x69, 0x48,
|
||||||
|
0xeb, 0x2e, 0x0f, 0x50, 0xac, 0x23, 0xdd, 0x5f, 0xb4, 0x90, 0xea, 0x55, 0xad, 0x0b, 0x98, 0xd4,
|
||||||
|
0x9d, 0x78, 0x51, 0x5d, 0xb6, 0x78, 0x01, 0x55, 0x19, 0x84, 0x65, 0xf1, 0x90, 0x28, 0x94, 0xd4,
|
||||||
|
0x64, 0xe4, 0x61, 0xbf, 0x67, 0x3a, 0x64, 0x71, 0xd0, 0x27, 0x9f, 0xbe, 0x2c, 0xa8, 0xc5, 0x14,
|
||||||
|
0xbf, 0xa3, 0x9e, 0x22, 0x70, 0xbd, 0xa2, 0x24, 0xe9, 0x86, 0xae, 0x21, 0x53, 0xd7, 0x04, 0x24,
|
||||||
|
0x7a, 0x43, 0x27, 0x2d, 0xfd, 0x09, 0x89, 0x30, 0x75, 0x4f, 0x41, 0x79, 0xf9, 0x88, 0x7a, 0x35,
|
||||||
|
0xeb, 0x38, 0x26, 0x75, 0x2f, 0x17, 0x61, 0xef, 0x9e, 0xdd, 0xe5, 0xa4, 0xe1, 0xea, 0x97, 0x68,
|
||||||
|
0xef, 0x16, 0x26, 0xcd, 0xc9, 0xfb, 0x23, 0x87, 0x98, 0xf8, 0xa2, 0x66, 0x6d, 0x7e, 0x1f, 0x6b,
|
||||||
|
0xcf, 0x54, 0x3c, 0x77, 0xdd, 0xa4, 0x6d, 0x48, 0xe9, 0x84, 0x6e, 0x3e, 0xf7, 0x98, 0x09, 0x60,
|
||||||
|
0x75, 0x67, 0x06, 0xac, 0xee, 0xcc, 0x80, 0xd5, 0x9d, 0x19, 0xb0, 0xba, 0x33, 0x03, 0x8d, 0x74,
|
||||||
|
0x6f, 0x71, 0x73, 0x7c, 0xb1, 0x68, 0x2e, 0x4b, 0x95, 0xd8, 0x76, 0xfe, 0xb4, 0xa6, 0xba, 0xd3,
|
||||||
|
0x81, 0xbc, 0xdc, 0x1c, 0xc3, 0xd9, 0xb3, 0x16, 0xcc, 0x9b, 0x7d, 0xde, 0xf3, 0x2c, 0xd3, 0xb1,
|
||||||
|
0xd0, 0x08, 0x9d, 0xd3, 0x1d, 0x6f, 0x89, 0x5b, 0xb2, 0xd0, 0xa8, 0xaf, 0x4f, 0x6f, 0xda, 0x5b,
|
||||||
|
0x54, 0x85, 0x2e, 0xea, 0x6e, 0x63, 0x69, 0x41, 0xb2, 0x65, 0x46, 0x7f, 0xa1, 0x73, 0xba, 0x03,
|
||||||
|
0xbc, 0xbd, 0x3c, 0x51, 0x33, 0x51, 0x7b, 0x3b, 0x05, 0xd3, 0xf7, 0xe8, 0x26, 0xb4, 0xa1, 0x3b,
|
||||||
|
0xc9, 0xc1, 0x00, 0x80, 0xe1, 0xa1, 0xa1, 0x1f, 0xb6, 0x6f, 0x43, 0xdb, 0x81, 0xfe, 0x7e, 0x7f,
|
||||||
|
0xee, 0xfd, 0x2f, 0xc9, 0x13, 0x2b, 0xb9, 0x5c, 0x35, 0x02, 0x63, 0x10, 0xda, 0xd0, 0xbd, 0xb1,
|
||||||
|
0x81, 0xd4, 0x3c, 0x07, 0x08, 0x46, 0x73, 0xde, 0xde, 0xff, 0xe7, 0xef, 0xbe, 0x97, 0x2f, 0x81,
|
||||||
|
0xdf, 0x5b, 0x9a, 0xc9, 0xb6, 0xed, 0x24, 0x25, 0x25, 0xaa, 0x15, 0x1a, 0x63, 0x60, 0x46, 0x77,
|
||||||
|
0xc5, 0xc5, 0x77, 0x6b, 0x4b, 0x4b, 0xe1, 0x33, 0x25, 0xf3, 0xf9, 0x0d, 0x0f, 0x0f, 0x13, 0xdf,
|
||||||
|
0xb2, 0xba, 0xcb, 0x00, 0x51, 0xf7, 0x27, 0x05, 0xf9, 0x60, 0xe4, 0x5c, 0x8d, 0xbb, 0x31, 0x41,
|
||||||
|
0x22, 0xdb, 0xbe, 0xfd, 0x06, 0x7f, 0xcb, 0xea, 0x2e, 0x03, 0x48, 0xf7, 0xb6, 0xb6, 0x36, 0xa8,
|
||||||
|
0x95, 0xa3, 0x0b, 0x26, 0x25, 0xba, 0x8b, 0x07, 0x95, 0x8a, 0x86, 0x3a, 0xb2, 0xba, 0xcb, 0x00,
|
||||||
|
0xe8, 0xbe, 0xd8, 0x68, 0x1e, 0xf1, 0x79, 0xd6, 0x4f, 0x3b, 0xb6, 0x6b, 0xd8, 0x2f, 0x55, 0xa2,
|
||||||
|
0xd7, 0xc9, 0xcf, 0x3f, 0xec, 0xd0, 0xc2, 0x17, 0xa1, 0x10, 0xda, 0xf3, 0xfb, 0xf5, 0xab, 0xbe,
|
||||||
|
0xb8, 0x4c, 0x14, 0xfa, 0x7d, 0xf9, 0xbb, 0x8b, 0x87, 0xf8, 0x7c, 0xd6, 0xef, 0x32, 0x40, 0x2c,
|
||||||
|
0xdf, 0xad, 0x0e, 0x99, 0x53, 0xa5, 0xbb, 0xe1, 0xec, 0x59, 0xf8, 0x5c, 0x0d, 0xac, 0xee, 0x32,
|
||||||
|
0x20, 0x5d, 0x9f, 0x79, 0xf5, 0xea, 0xa5, 0x86, 0x69, 0xa6, 0x26, 0x27, 0x11, 0xdf, 0xb2, 0xba,
|
||||||
|
0xcb, 0x80, 0x4a, 0xf5, 0x77, 0xf5, 0xc0, 0xea, 0x2e, 0x03, 0xac, 0xee, 0xd2, 0xd0, 0xb6, 0xee,
|
||||||
|
0x1d, 0xfd, 0x82, 0x33, 0x0f, 0xaa, 0x8e, 0x04, 0x3f, 0xc7, 0x3a, 0xbf, 0xbf, 0xe9, 0xff, 0x8e,
|
||||||
|
0x75, 0x7e, 0x17, 0xf5, 0x7f, 0x3f, 0x2c, 0xea, 0xff, 0x8e, 0x75, 0x7e, 0xf7, 0xc9, 0x3b, 0x24,
|
||||||
|
0xea, 0xff, 0x6e, 0x7e, 0x29, 0xe7, 0x10, 0xea, 0xfc, 0xfe, 0x77, 0x36, 0xd6, 0xf9, 0xfd, 0x42,
|
||||||
|
0x96, 0xa9, 0x77, 0xa6, 0xe5, 0xe5, 0x5c, 0xfb, 0xa0, 0xe2, 0x9b, 0xe9, 0x93, 0x93, 0xf2, 0xe9,
|
||||||
|
0x9f, 0xee, 0xc4, 0x09, 0x70, 0xee, 0x46, 0x47, 0xa9, 0x34, 0x61, 0x0e, 0x49, 0x46, 0x46, 0x84,
|
||||||
|
0xa3, 0x0d, 0xaf, 0x2b, 0x21, 0x4a, 0x27, 0xd8, 0x21, 0xc3, 0xc9, 0x7e, 0x22, 0xc7, 0x1e, 0xde,
|
||||||
|
0xca, 0xc2, 0xba, 0xad, 0xe9, 0x9f, 0xee, 0xc4, 0x37, 0x5f, 0x6f, 0x58, 0xef, 0x75, 0xc6, 0x83,
|
||||||
|
0xf2, 0x3c, 0xc0, 0xef, 0x7d, 0x43, 0xa3, 0xfb, 0x9c, 0xc4, 0xc3, 0x04, 0x38, 0x8e, 0xb1, 0x66,
|
||||||
|
0x17, 0x73, 0xb0, 0x41, 0x07, 0xc4, 0x71, 0x07, 0x01, 0x93, 0xe3, 0x0e, 0xf0, 0x41, 0x07, 0x36,
|
||||||
|
0xf8, 0xb8, 0x83, 0x60, 0xf4, 0xfa, 0x66, 0xd0, 0x41, 0x40, 0xf1, 0x01, 0xcf, 0x0c, 0x5c, 0xfd,
|
||||||
|
0x63, 0xb7, 0xcb, 0xf4, 0x58, 0xf7, 0x81, 0x81, 0x01, 0x9a, 0x06, 0x1d, 0x80, 0xee, 0x07, 0x5d,
|
||||||
|
0xc4, 0x1d, 0xc7, 0x9c, 0x23, 0xd5, 0xe9, 0x8d, 0x2d, 0x13, 0x05, 0x2f, 0x5a, 0x38, 0xc7, 0xc5,
|
||||||
|
0xd2, 0x5f, 0x0c, 0x8c, 0xa2, 0x2a, 0x59, 0xed, 0x60, 0x52, 0x77, 0xbc, 0x33, 0xff, 0xee, 0x9d,
|
||||||
|
0x3f, 0x51, 0x9b, 0x87, 0x6b, 0x48, 0x36, 0x52, 0x27, 0x8b, 0x4b, 0x41, 0x7b, 0x7a, 0x7b, 0x7b,
|
||||||
|
0xfb, 0x6f, 0xbf, 0xfc, 0x8c, 0x42, 0x35, 0x5e, 0xb2, 0xd4, 0xdc, 0x2b, 0x0d, 0x52, 0x76, 0xf3,
|
||||||
|
0xf2, 0xd7, 0x3c, 0x65, 0x6d, 0x42, 0xac, 0x7b, 0x25, 0x97, 0x4b, 0xbc, 0xed, 0x56, 0x30, 0x73,
|
||||||
|
0xa2, 0x1a, 0xb0, 0x74, 0xbd, 0x03, 0xd2, 0x58, 0x04, 0x14, 0x6b, 0x9e, 0x54, 0xf8, 0xad, 0x30,
|
||||||
|
0x62, 0x9c, 0xae, 0xce, 0xc7, 0x79, 0x9d, 0x7c, 0x4c, 0x77, 0x4f, 0xff, 0xf3, 0xf1, 0x9a, 0xde,
|
||||||
|
0x13, 0x68, 0x13, 0x93, 0xf3, 0xfd, 0x10, 0xf9, 0xf1, 0x07, 0x2b, 0xf1, 0x23, 0x42, 0x82, 0x02,
|
||||||
|
0x7b, 0x7b, 0xd4, 0x9f, 0x8c, 0x98, 0xdb, 0xd4, 0x6f, 0x79, 0x22, 0x12, 0xa4, 0x51, 0x69, 0x11,
|
||||||
|
0x12, 0x05, 0x20, 0x0e, 0x09, 0xea, 0xed, 0xed, 0x85, 0x3d, 0x50, 0xc3, 0x01, 0xdd, 0xad, 0xfd,
|
||||||
|
0x65, 0xf7, 0x8e, 0xd7, 0x4d, 0x4c, 0xb9, 0xae, 0x76, 0x74, 0xb4, 0x4b, 0x7c, 0xcc, 0xe7, 0x0f,
|
||||||
|
0xae, 0x5f, 0xfb, 0xf1, 0x86, 0xcf, 0xd6, 0xaa, 0x9d, 0xc1, 0x9d, 0x82, 0x46, 0xd0, 0x9d, 0x43,
|
||||||
|
0xe9, 0x04, 0x57, 0x05, 0xf9, 0x79, 0xc4, 0x4b, 0x91, 0x75, 0xd0, 0x73, 0xd0, 0xdd, 0x54, 0xb3,
|
||||||
|
0xb9, 0x94, 0xb4, 0x0c, 0x25, 0xba, 0xff, 0xf0, 0xfd, 0x77, 0xf9, 0x79, 0xb9, 0x9a, 0x5c, 0x6c,
|
||||||
|
0xfd, 0xd3, 0x6b, 0x31, 0xdd, 0x1d, 0xd4, 0x5c, 0x4d, 0x40, 0xba, 0xc4, 0xab, 0x28, 0xc7, 0xae,
|
||||||
|
0xcc, 0x6d, 0xad, 0xad, 0x0b, 0x0d, 0xe6, 0xa0, 0x3d, 0xb6, 0x21, 0x25, 0xa0, 0x3b, 0xc7, 0x23,
|
||||||
|
0x4d, 0xed, 0x20, 0xb5, 0x0f, 0x25, 0xba, 0x23, 0xc5, 0xf7, 0xfd, 0xb9, 0xf7, 0xc2, 0x39, 0x2f,
|
||||||
|
0xf5, 0x32, 0x00, 0xdd, 0x51, 0x87, 0x6c, 0x55, 0x4f, 0xfc, 0xf4, 0xe3, 0x0f, 0x51, 0xe3, 0x17,
|
||||||
|
0x7a, 0x9b, 0x98, 0x90, 0x10, 0xf3, 0xe0, 0xbe, 0x44, 0xb3, 0x0c, 0x02, 0xd4, 0x2c, 0xb1, 0x51,
|
||||||
|
0xac, 0x9e, 0x19, 0xea, 0x45, 0xc8, 0x08, 0x14, 0xe9, 0x9e, 0x9c, 0x94, 0xb8, 0xe9, 0x8b, 0xcf,
|
||||||
|
0x27, 0x34, 0x1b, 0x4f, 0xac, 0xb6, 0xee, 0xc4, 0x1c, 0x6b, 0x6b, 0x6a, 0x50, 0xc1, 0x72, 0x37,
|
||||||
|
0xea, 0x8e, 0xf4, 0x91, 0x36, 0x41, 0xcf, 0xb1, 0xc1, 0xb1, 0xe7, 0x95, 0x4c, 0x34, 0xab, 0x53,
|
||||||
|
0x50, 0xa4, 0xfb, 0x82, 0x79, 0xb3, 0xb7, 0x7d, 0xfb, 0xcd, 0xae, 0x9f, 0x7f, 0x04, 0xc2, 0x77,
|
||||||
|
0xae, 0x79, 0x8d, 0x2d, 0x35, 0xb3, 0x79, 0xe3, 0x57, 0xff, 0xfc, 0xea, 0x0b, 0x07, 0x7b, 0x3b,
|
||||||
|
0xf8, 0x97, 0xa0, 0xe9, 0x24, 0x57, 0x2d, 0x5f, 0xba, 0x7d, 0xeb, 0x96, 0xb0, 0x90, 0xa0, 0x3b,
|
||||||
|
0x11, 0xe1, 0x20, 0x50, 0x70, 0x60, 0x40, 0x6b, 0x4b, 0x0b, 0x9e, 0x08, 0x25, 0xba, 0x37, 0x36,
|
||||||
|
0x36, 0x20, 0xdd, 0x4b, 0x4b, 0x9e, 0x4b, 0x1f, 0x89, 0x74, 0xd7, 0x70, 0xae, 0x3c, 0x2d, 0x43,
|
||||||
|
0x91, 0xee, 0x68, 0x00, 0x1f, 0x42, 0xa0, 0xbf, 0xdf, 0xca, 0x65, 0x4b, 0x60, 0x27, 0x2a, 0x55,
|
||||||
|
0x91, 0x28, 0xeb, 0xd6, 0x60, 0x6b, 0x30, 0x8c, 0x8f, 0x8f, 0xc3, 0x2f, 0x03, 0x2d, 0xde, 0x00,
|
||||||
|
0x15, 0xa1, 0x53, 0xae, 0x2e, 0xc4, 0x44, 0xfc, 0xa8, 0xd0, 0x7d, 0x42, 0x34, 0xd1, 0x36, 0xd4,
|
||||||
|
0xdc, 0x65, 0x1e, 0x09, 0xb7, 0xb8, 0x90, 0x85, 0xbc, 0x95, 0x89, 0x74, 0x13, 0x72, 0x75, 0xb7,
|
||||||
|
0xb7, 0xb5, 0x36, 0x37, 0xdd, 0x4f, 0xfc, 0x14, 0x09, 0xb1, 0xf6, 0xa3, 0x55, 0xf8, 0x36, 0xd4,
|
||||||
|
0x73, 0x9a, 0x1a, 0x1b, 0xa1, 0xd8, 0x85, 0xed, 0xe5, 0x4b, 0x16, 0xc1, 0xab, 0xf1, 0x02, 0xc3,
|
||||||
|
0xf5, 0x9f, 0xac, 0x21, 0x9e, 0x45, 0x95, 0xee, 0x0a, 0x60, 0x13, 0x50, 0x84, 0xdd, 0x1f, 0x5c,
|
||||||
|
0xce, 0x55, 0x35, 0x0b, 0x06, 0x21, 0x57, 0x77, 0xe9, 0xbb, 0x27, 0x10, 0xf4, 0xa8, 0x9d, 0xad,
|
||||||
|
0x84, 0xee, 0x13, 0xa2, 0x1e, 0x2f, 0x9f, 0x7f, 0xba, 0x06, 0x2e, 0x80, 0x07, 0xf7, 0x9b, 0x08,
|
||||||
|
0x85, 0xc2, 0x17, 0x55, 0x95, 0xc4, 0x11, 0xc6, 0xd7, 0x53, 0x6a, 0xe8, 0xd6, 0xdd, 0x36, 0x10,
|
||||||
|
0xd3, 0xdd, 0xec, 0x92, 0x1e, 0xea, 0x8e, 0x16, 0x52, 0xf9, 0x64, 0xf5, 0x07, 0x68, 0x43, 0x93,
|
||||||
|
0x0a, 0xbb, 0x04, 0x8e, 0x84, 0x95, 0x61, 0xba, 0xcb, 0x5f, 0x73, 0x51, 0x73, 0xd8, 0x85, 0x96,
|
||||||
|
0x62, 0x59, 0xb8, 0xc9, 0xa8, 0xea, 0xe8, 0x2c, 0xc4, 0xba, 0xc3, 0x25, 0x91, 0x78, 0xbf, 0x2a,
|
||||||
|
0x6f, 0x45, 0x18, 0x35, 0x60, 0x72, 0x2a, 0x09, 0x1b, 0xc4, 0x16, 0x48, 0x41, 0x23, 0x81, 0x3c,
|
||||||
|
0xa4, 0x57, 0xb4, 0x6b, 0x6d, 0xb4, 0x26, 0x55, 0x90, 0x31, 0x6e, 0x98, 0xd8, 0x48, 0xa0, 0x21,
|
||||||
|
0xce, 0x3f, 0xac, 0x42, 0x8a, 0x94, 0xd4, 0xf5, 0x52, 0x95, 0xa6, 0x4c, 0x70, 0x4e, 0x62, 0x43,
|
||||||
|
0xc2, 0xcd, 0x4e, 0x27, 0x0f, 0x0c, 0x8f, 0xd2, 0x9a, 0x11, 0x55, 0x98, 0xd4, 0xbd, 0xaa, 0xb2,
|
||||||
|
0x92, 0xda, 0x46, 0x31, 0xa7, 0x88, 0x0a, 0x8e, 0x63, 0x2c, 0xc8, 0x71, 0xf8, 0xda, 0x13, 0x4a,
|
||||||
|
0x12, 0x54, 0x80, 0xd0, 0x37, 0xa3, 0xc2, 0x0f, 0x5f, 0xc8, 0xec, 0x1b, 0xd2, 0x03, 0xe9, 0xa7,
|
||||||
|
0x5c, 0x57, 0xdf, 0x5d, 0x68, 0xb4, 0xe7, 0xd7, 0x9d, 0xe4, 0x4f, 0x26, 0xce, 0x92, 0x8d, 0xd3,
|
||||||
|
0x3f, 0xbd, 0xe6, 0xe8, 0xad, 0x32, 0x93, 0x37, 0x0d, 0xee, 0x26, 0xbe, 0xb4, 0x8b, 0x8e, 0x60,
|
||||||
|
0x1f, 0x56, 0x8a, 0x3f, 0x09, 0xb1, 0xf2, 0x2f, 0x3c, 0x7b, 0xbf, 0x8a, 0xc2, 0x65, 0xad, 0x28,
|
||||||
|
0xa4, 0x50, 0x38, 0x3e, 0x81, 0xeb, 0x5e, 0x55, 0x55, 0x59, 0x5e, 0x5e, 0x9e, 0x95, 0xf9, 0x98,
|
||||||
|
0xfc, 0x60, 0x6d, 0x80, 0x9c, 0xc1, 0xda, 0x0f, 0xf0, 0xef, 0x7f, 0xe4, 0x2a, 0x65, 0x73, 0xfd,
|
||||||
|
0x90, 0xc1, 0xe9, 0x7b, 0x55, 0x8c, 0x0f, 0xc7, 0x56, 0x4a, 0xb8, 0xdd, 0x99, 0xd0, 0xf0, 0xb9,
|
||||||
|
0x36, 0x36, 0x8f, 0x39, 0x3e, 0xbb, 0x3a, 0x4e, 0xc7, 0x18, 0x8e, 0xcb, 0x23, 0xdb, 0xa0, 0xe2,
|
||||||
|
0xac, 0x2a, 0x06, 0x66, 0xe1, 0x19, 0x1d, 0x13, 0x1e, 0x8f, 0xac, 0xd8, 0x7f, 0x26, 0x95, 0x73,
|
||||||
|
0x3c, 0x8e, 0xe3, 0x1c, 0x47, 0xe1, 0x74, 0xed, 0x54, 0x91, 0x02, 0xdd, 0x59, 0xa8, 0x0d, 0x56,
|
||||||
|
0x77, 0x66, 0xc0, 0xea, 0xce, 0x0c, 0x58, 0xdd, 0x99, 0x01, 0xab, 0x3b, 0x33, 0x60, 0x75, 0x67,
|
||||||
|
0x06, 0xac, 0xee, 0xcc, 0x80, 0xd5, 0x9d, 0x19, 0xb0, 0xba, 0x33, 0x03, 0xf5, 0x75, 0x17, 0x0a,
|
||||||
|
0x04, 0x8c, 0xaf, 0x25, 0xa4, 0x8f, 0xd4, 0x54, 0xf7, 0x71, 0x81, 0x80, 0xf1, 0xb9, 0x5c, 0xf4,
|
||||||
|
0x8f, 0xc6, 0x06, 0x14, 0xf8, 0x9d, 0xf1, 0x05, 0xa8, 0xf4, 0x8e, 0xbc, 0x5f, 0x77, 0x68, 0xaa,
|
||||||
|
0xfb, 0x0c, 0x41, 0x51, 0xe1, 0x33, 0xe3, 0xf9, 0x06, 0x8b, 0x8d, 0xe6, 0x99, 0x1d, 0xd8, 0x77,
|
||||||
|
0xc6, 0xfd, 0x94, 0xbd, 0xad, 0xf5, 0xf2, 0x25, 0x8b, 0x0c, 0xde, 0xf9, 0x07, 0x3e, 0x2d, 0x37,
|
||||||
|
0x0b, 0x3d, 0x02, 0x6b, 0x77, 0x25, 0xd8, 0xb5, 0xf3, 0x27, 0x30, 0x37, 0xea, 0xaa, 0x82, 0xe3,
|
||||||
|
0x51, 0x7c, 0x5c, 0x6a, 0x4a, 0x32, 0x9a, 0x7c, 0x9e, 0x85, 0x1e, 0x81, 0xb5, 0xbb, 0x12, 0x0c,
|
||||||
|
0xf1, 0xf9, 0x7b, 0x7f, 0xdb, 0x85, 0x3f, 0xf2, 0x5f, 0x68, 0x30, 0x67, 0xcf, 0xae, 0x9d, 0x21,
|
||||||
|
0x41, 0x81, 0x12, 0xd3, 0xb0, 0xb0, 0xd0, 0x0b, 0xb0, 0x76, 0x57, 0x0d, 0xbc, 0xba, 0x5a, 0xdf,
|
||||||
|
0xcb, 0x97, 0x56, 0x2d, 0x5f, 0x0a, 0xd6, 0x97, 0xe8, 0x06, 0xca, 0x42, 0xf7, 0x31, 0x7d, 0xec,
|
||||||
|
0xde, 0xd8, 0xd0, 0x40, 0xc7, 0x4a, 0x74, 0x5b, 0x37, 0x6f, 0x02, 0x67, 0x07, 0x07, 0x06, 0x10,
|
||||||
|
0x77, 0xda, 0x58, 0x5a, 0xc0, 0x4e, 0x8f, 0x53, 0x27, 0x29, 0xcf, 0x2e, 0x29, 0x29, 0x51, 0xbf,
|
||||||
|
0x16, 0xff, 0xd2, 0x2f, 0xb0, 0x76, 0x57, 0x8e, 0x84, 0xb8, 0xb8, 0xaf, 0x37, 0xac, 0xc3, 0xeb,
|
||||||
|
0x33, 0x46, 0x73, 0xde, 0x86, 0xfa, 0xcc, 0xeb, 0x57, 0xb4, 0x2c, 0x64, 0xc1, 0xda, 0x9d, 0x56,
|
||||||
|
0xcc, 0x08, 0xbb, 0x8f, 0x8f, 0x8f, 0xc7, 0xc7, 0xc6, 0x7c, 0xb9, 0xee, 0x53, 0xcd, 0x67, 0x78,
|
||||||
|
0xd2, 0x10, 0xc5, 0x45, 0x85, 0xeb, 0xd6, 0xae, 0xbe, 0x17, 0x1d, 0x85, 0xfa, 0x2d, 0x49, 0x83,
|
||||||
|
0xb5, 0x3b, 0xad, 0x98, 0xce, 0x76, 0x7f, 0xf9, 0xb2, 0x7a, 0xdf, 0x9f, 0xbf, 0x13, 0x3b, 0xf4,
|
||||||
|
0xeb, 0x82, 0xdd, 0x89, 0xf1, 0xfc, 0xef, 0xb7, 0x5f, 0x25, 0xa6, 0xd6, 0x65, 0xed, 0x4e, 0x2b,
|
||||||
|
0xa6, 0x9b, 0xdd, 0x07, 0x07, 0x07, 0x2f, 0x9c, 0xf7, 0x5a, 0xb6, 0x78, 0x81, 0xc4, 0x4c, 0x0b,
|
||||||
|
0xba, 0x69, 0x77, 0x9c, 0x4b, 0x16, 0x18, 0x9e, 0xf5, 0x38, 0xdd, 0xd7, 0xd7, 0xc7, 0xda, 0x9d,
|
||||||
|
0x56, 0x4c, 0x2b, 0xbb, 0xc7, 0xc5, 0xc5, 0x06, 0xdc, 0xbc, 0xf1, 0xc9, 0x47, 0x1f, 0xc8, 0xb4,
|
||||||
|
0x14, 0x30, 0xf6, 0xe1, 0x83, 0xa6, 0xc6, 0x46, 0x06, 0x99, 0x9c, 0x98, 0x28, 0x2f, 0xb6, 0xd5,
|
||||||
|
0xef, 0xaf, 0xb8, 0xea, 0xeb, 0x73, 0x27, 0x32, 0x82, 0xb5, 0x3b, 0x7d, 0x98, 0x56, 0x76, 0x27,
|
||||||
|
0x56, 0x66, 0x7a, 0x7b, 0x7a, 0xdc, 0xdd, 0x5c, 0x17, 0xcf, 0x37, 0xd0, 0xe5, 0xd2, 0x7d, 0xb1,
|
||||||
|
0xd1, 0xbc, 0x93, 0x27, 0x9c, 0xbb, 0xba, 0x3a, 0xf1, 0x03, 0xd8, 0xd2, 0x9d, 0x56, 0x4c, 0x5b,
|
||||||
|
0xbb, 0x13, 0x51, 0x5e, 0x56, 0xb6, 0x67, 0xd7, 0x2f, 0xba, 0x63, 0xf7, 0x5f, 0x7e, 0xfc, 0x4f,
|
||||||
|
0xc9, 0x73, 0xd9, 0xa3, 0x78, 0x59, 0xbb, 0xd3, 0x8a, 0x19, 0x61, 0x77, 0x3d, 0x02, 0x6b, 0x77,
|
||||||
|
0x5a, 0xc1, 0xda, 0x5d, 0xb7, 0xc0, 0xda, 0x9d, 0x56, 0xcc, 0x2c, 0xbb, 0xf7, 0x0d, 0x8d, 0x96,
|
||||||
|
0x35, 0xf4, 0xf2, 0x3a, 0xf9, 0x75, 0x1d, 0x18, 0x6b, 0x81, 0xed, 0xfc, 0x9a, 0xf6, 0x41, 0xe0,
|
||||||
|
0xeb, 0xb6, 0xc1, 0x57, 0x22, 0xbe, 0x6c, 0x1d, 0x00, 0x56, 0xb7, 0x0c, 0xbc, 0x10, 0xb1, 0xaa,
|
||||||
|
0x19, 0xb1, 0xbf, 0xb2, 0xb9, 0x9f, 0xdb, 0x24, 0x66, 0x45, 0x23, 0xc6, 0xf2, 0xc6, 0xbe, 0xb2,
|
||||||
|
0x06, 0x8c, 0xa5, 0xc0, 0xfa, 0xbe, 0x92, 0xfa, 0xde, 0xe7, 0x3c, 0x8c, 0xc5, 0xc0, 0xba, 0xde,
|
||||||
|
0xa2, 0xba, 0xde, 0xc2, 0xba, 0x9e, 0xc2, 0xda, 0x9e, 0x67, 0xc0, 0x9a, 0x9e, 0xa7, 0x35, 0xd8,
|
||||||
|
0x36, 0xa4, 0xdf, 0xd6, 0x27, 0x50, 0x10, 0x21, 0x6b, 0x77, 0x5a, 0xf1, 0xd6, 0xd8, 0xd8, 0x98,
|
||||||
|
0x60, 0x5a, 0xa0, 0xb6, 0xb6, 0x36, 0x2b, 0xf3, 0x31, 0x71, 0x4f, 0xdf, 0xe0, 0x90, 0xef, 0xa3,
|
||||||
|
0x2a, 0xfb, 0xc0, 0xa7, 0xe6, 0x67, 0x92, 0xf6, 0x39, 0xc7, 0xec, 0x77, 0xb8, 0xcf, 0x20, 0xf7,
|
||||||
|
0x11, 0xe6, 0x69, 0xe0, 0x38, 0x3c, 0x34, 0x71, 0x49, 0xb0, 0xbb, 0xf1, 0xe4, 0x44, 0x14, 0xb7,
|
||||||
|
0xe0, 0xf5, 0x14, 0x73, 0xb3, 0x76, 0xa7, 0x15, 0x8a, 0x4a, 0xf7, 0xfb, 0xf7, 0xa2, 0x17, 0x19,
|
||||||
|
0xce, 0xd5, 0x97, 0x25, 0x38, 0x89, 0xa5, 0xbb, 0x4b, 0x54, 0xa5, 0xa9, 0x77, 0x16, 0xe3, 0x53,
|
||||||
|
0x6d, 0x90, 0xe4, 0xc1, 0x33, 0xa9, 0xae, 0xd1, 0x95, 0x28, 0x72, 0xd6, 0xee, 0xb4, 0x42, 0xae,
|
||||||
|
0xdd, 0x6f, 0x85, 0x86, 0xe0, 0x4f, 0x40, 0x9a, 0x9b, 0x9a, 0xb4, 0x19, 0x93, 0x7a, 0x40, 0x76,
|
||||||
|
0x3f, 0x19, 0xc5, 0x35, 0x39, 0x1e, 0x47, 0x34, 0x13, 0xc7, 0x31, 0xc6, 0xe2, 0x4a, 0x81, 0x73,
|
||||||
|
0x44, 0x79, 0x5c, 0x61, 0x33, 0xd4, 0x43, 0x1a, 0xba, 0x86, 0x5a, 0x7a, 0x87, 0x5b, 0x7b, 0x87,
|
||||||
|
0xa1, 0x52, 0x01, 0x6c, 0x07, 0xf6, 0x0b, 0x3a, 0xde, 0xb0, 0x73, 0x40, 0xd0, 0x35, 0x30, 0x02,
|
||||||
|
0xec, 0x1e, 0x14, 0xb3, 0x87, 0x3f, 0xd2, 0x2b, 0xe6, 0x28, 0xd4, 0x85, 0x10, 0xfb, 0x87, 0x46,
|
||||||
|
0x07, 0x86, 0x81, 0x63, 0xc0, 0x41, 0x81, 0x98, 0x7c, 0xc1, 0xd8, 0xd0, 0x88, 0x98, 0xc3, 0x23,
|
||||||
|
0x42, 0x8c, 0xa3, 0x18, 0x05, 0xa3, 0xc2, 0x91, 0x31, 0x8c, 0x70, 0x22, 0xe4, 0x9b, 0x56, 0xd1,
|
||||||
|
0xee, 0x12, 0xc5, 0xb5, 0xbb, 0xfe, 0x44, 0xd2, 0xf7, 0xce, 0xf1, 0x67, 0xee, 0x57, 0xb1, 0x76,
|
||||||
|
0xa7, 0x15, 0xb2, 0xed, 0xee, 0x7d, 0xce, 0x93, 0xd8, 0x3c, 0x6c, 0x34, 0xe7, 0xed, 0xf2, 0xb2,
|
||||||
|
0x32, 0x2d, 0x47, 0xa6, 0x2a, 0x4a, 0xab, 0x6a, 0x4e, 0xfa, 0x46, 0x11, 0x0d, 0x64, 0xfd, 0x57,
|
||||||
|
0x66, 0x74, 0x7e, 0x3d, 0xd3, 0x71, 0x4d, 0x41, 0x57, 0x57, 0x67, 0xf8, 0xad, 0xb0, 0xdf, 0xf7,
|
||||||
|
0xec, 0x46, 0xcb, 0x13, 0x6e, 0x3d, 0x74, 0xde, 0xcc, 0x2b, 0x95, 0x18, 0xb3, 0x87, 0xef, 0xed,
|
||||||
|
0x6a, 0x1e, 0x65, 0x53, 0x17, 0xb2, 0x90, 0x80, 0x0c, 0xbb, 0x1f, 0xb1, 0xb1, 0x92, 0xf9, 0xd8,
|
||||||
|
0x2f, 0x3d, 0x35, 0x45, 0xfb, 0xf1, 0x91, 0x44, 0x72, 0x79, 0xfb, 0xd1, 0xbf, 0xe2, 0x9d, 0x3d,
|
||||||
|
0x82, 0xc4, 0x25, 0xba, 0x5b, 0xb2, 0x7f, 0xca, 0x6b, 0xa6, 0x83, 0xc2, 0x26, 0x0d, 0xf7, 0xbf,
|
||||||
|
0x79, 0xe3, 0xa7, 0x1d, 0xdb, 0xe7, 0xcf, 0x7d, 0x47, 0xa6, 0xa4, 0xdf, 0x6e, 0xfa, 0x7a, 0x02,
|
||||||
|
0xab, 0x7a, 0x71, 0x39, 0x0e, 0xe2, 0x95, 0x7d, 0xdc, 0x3c, 0xfd, 0x8f, 0xf8, 0x66, 0xc0, 0xed,
|
||||||
|
0x2f, 0xd3, 0xb1, 0x4f, 0x4f, 0x48, 0xda, 0xfd, 0xbf, 0xbb, 0x7f, 0x95, 0xf7, 0x94, 0x1b, 0x78,
|
||||||
|
0x3b, 0x2c, 0x94, 0x91, 0x28, 0x15, 0x63, 0x4c, 0x38, 0x6e, 0x13, 0x5c, 0x62, 0x79, 0x22, 0x12,
|
||||||
|
0xd9, 0x9d, 0x73, 0x3a, 0x25, 0x32, 0x97, 0xc7, 0x74, 0x50, 0x93, 0x88, 0x8b, 0x79, 0x28, 0xb1,
|
||||||
|
0xd4, 0x2c, 0xce, 0xa4, 0xc4, 0x47, 0xe8, 0x98, 0xb3, 0x0f, 0xaa, 0x38, 0xa2, 0x3a, 0x18, 0xd8,
|
||||||
|
0xdd, 0xcc, 0x29, 0xda, 0x2e, 0xac, 0x94, 0xd9, 0x98, 0xa7, 0x2b, 0xa6, 0xd8, 0xfd, 0xe5, 0xcb,
|
||||||
|
0xea, 0xdc, 0xec, 0x6c, 0x9c, 0x09, 0xf1, 0x71, 0xdf, 0x6f, 0xdb, 0x42, 0xdc, 0x03, 0xec, 0xee,
|
||||||
|
0xea, 0x92, 0x48, 0x02, 0xbf, 0x1a, 0x5c, 0xbb, 0xe2, 0xa3, 0xc5, 0xc8, 0x27, 0xf1, 0xa8, 0xb4,
|
||||||
|
0xcd, 0xf4, 0x6c, 0x1a, 0x6e, 0x77, 0xdb, 0xe0, 0xe7, 0x50, 0x93, 0x66, 0x24, 0x12, 0x05, 0x28,
|
||||||
|
0x2a, 0x2c, 0xc4, 0x57, 0xb4, 0x46, 0xfc, 0x6e, 0xcb, 0xe4, 0x52, 0xe0, 0x70, 0x63, 0x60, 0xe5,
|
||||||
|
0x57, 0x88, 0xdb, 0xdd, 0xca, 0x37, 0xbf, 0xa2, 0x51, 0x3f, 0x5a, 0x08, 0xf4, 0x0b, 0x8a, 0x5a,
|
||||||
|
0x66, 0x3a, 0x3a, 0xda, 0xa1, 0x96, 0xa9, 0xf8, 0xfc, 0xc8, 0xf0, 0xdb, 0xf0, 0x9f, 0x3b, 0xe3,
|
||||||
|
0x7e, 0x0a, 0xad, 0x3a, 0x91, 0x99, 0x91, 0x4e, 0x69, 0x78, 0xa4, 0x10, 0x90, 0x51, 0xcb, 0x71,
|
||||||
|
0x4d, 0x44, 0x76, 0x87, 0x5a, 0x81, 0x53, 0x04, 0x65, 0x8b, 0xce, 0x51, 0x05, 0xb3, 0x03, 0xfb,
|
||||||
|
0xd0, 0x22, 0xc8, 0xf5, 0x3c, 0xde, 0x86, 0xcf, 0xd6, 0x4a, 0x57, 0x0e, 0x85, 0xe3, 0xe3, 0xb6,
|
||||||
|
0x21, 0x25, 0xb8, 0xdd, 0x39, 0xee, 0xa9, 0x69, 0x15, 0x0c, 0xcc, 0x6f, 0x3a, 0xed, 0xa1, 0x91,
|
||||||
|
0xdd, 0x5f, 0xbf, 0x7a, 0x65, 0x38, 0x7b, 0xd6, 0x8a, 0xa5, 0xc6, 0xa3, 0xa3, 0xa3, 0x3d, 0xdd,
|
||||||
|
0xdd, 0x0b, 0x0d, 0xe6, 0x40, 0x25, 0xb5, 0xa5, 0xb9, 0x99, 0xea, 0x20, 0x95, 0xc0, 0x3f, 0x1d,
|
||||||
|
0xb3, 0x3b, 0xb8, 0xc4, 0xc6, 0x35, 0x5c, 0x0b, 0x76, 0xff, 0xfc, 0xd3, 0x35, 0x3f, 0x7e, 0xff,
|
||||||
|
0x6f, 0x1e, 0xaf, 0x0e, 0x19, 0x17, 0xbe, 0x7e, 0x56, 0xa6, 0xdc, 0x35, 0x73, 0xdc, 0x5c, 0x4e,
|
||||||
|
0x14, 0xe4, 0x4b, 0xce, 0x86, 0xdc, 0xdb, 0xd3, 0x73, 0xfa, 0xe4, 0x94, 0x71, 0xae, 0xa3, 0x50,
|
||||||
|
0x1f, 0x13, 0xd9, 0x1d, 0x7e, 0xb4, 0xfb, 0x1d, 0xee, 0x9b, 0x9c, 0x49, 0xcb, 0x7a, 0xd1, 0x39,
|
||||||
|
0xc1, 0x82, 0x6a, 0xa8, 0x6f, 0x77, 0xb8, 0x0f, 0x5b, 0xfd, 0xfe, 0x72, 0xf8, 0x7f, 0x3f, 0x2f,
|
||||||
|
0x2e, 0x42, 0x7b, 0x92, 0x13, 0x1f, 0xa1, 0xe9, 0xf9, 0xa9, 0x5d, 0x3e, 0x51, 0x29, 0x90, 0xdd,
|
||||||
|
0xdf, 0x3c, 0xc1, 0xa1, 0xdd, 0xee, 0xc6, 0xa2, 0x5e, 0x96, 0x2b, 0x97, 0x2d, 0x29, 0x2a, 0x7c,
|
||||||
|
0x26, 0x10, 0x08, 0x0a, 0x9f, 0x3d, 0x25, 0x7e, 0x7a, 0xcd, 0xd7, 0xe7, 0x3d, 0xe3, 0x85, 0x68,
|
||||||
|
0xce, 0x82, 0x1f, 0xb6, 0x7f, 0x47, 0x32, 0x4d, 0xc1, 0xa8, 0xd0, 0x46, 0xb4, 0xca, 0x17, 0xe2,
|
||||||
|
0x01, 0xaf, 0x8c, 0xbc, 0x97, 0x6c, 0x73, 0x24, 0xf5, 0x50, 0xdf, 0xee, 0x26, 0x7f, 0xec, 0x85,
|
||||||
|
0x7f, 0xea, 0x15, 0x9f, 0xcb, 0xc4, 0x9d, 0x50, 0x98, 0xc1, 0xce, 0x5d, 0x84, 0x85, 0x5a, 0x87,
|
||||||
|
0xf8, 0xfc, 0xb6, 0xb6, 0xb6, 0xf1, 0xf1, 0xf1, 0xf2, 0xb2, 0xb2, 0x97, 0xd5, 0xd5, 0x68, 0x27,
|
||||||
|
0xaf, 0xae, 0xf6, 0x49, 0x7e, 0x3e, 0x78, 0x85, 0x78, 0x58, 0x69, 0x49, 0x49, 0x7e, 0x5e, 0x2e,
|
||||||
|
0xbe, 0x74, 0x4e, 0x6b, 0x6b, 0x2b, 0x9c, 0x88, 0x1f, 0x50, 0x5f, 0xcf, 0x93, 0xf7, 0xc0, 0x8b,
|
||||||
|
0x11, 0xbb, 0x43, 0xfc, 0xd2, 0x1f, 0xdd, 0x89, 0x08, 0xc7, 0x57, 0xab, 0x05, 0xc2, 0xb5, 0xee,
|
||||||
|
0xc6, 0xb5, 0x2b, 0x64, 0xd2, 0x1c, 0x1a, 0x19, 0x43, 0x8b, 0x7c, 0x89, 0x1f, 0x3c, 0x79, 0x67,
|
||||||
|
0x3e, 0xad, 0x51, 0x7f, 0xa9, 0x4f, 0x16, 0xf2, 0xa0, 0xa6, 0xdd, 0xe1, 0xae, 0x54, 0x41, 0x03,
|
||||||
|
0x0e, 0x10, 0x7c, 0x8f, 0x8e, 0x8c, 0x8b, 0x8d, 0xc1, 0xa7, 0x25, 0x4a, 0x4c, 0x88, 0x87, 0x6d,
|
||||||
|
0xb4, 0x50, 0x77, 0x57, 0x67, 0xe7, 0x62, 0xa3, 0x79, 0xa8, 0x1a, 0xf0, 0xe5, 0xfa, 0x4f, 0x71,
|
||||||
|
0x5b, 0x78, 0x7a, 0xb8, 0x43, 0x6d, 0x01, 0x6d, 0x1f, 0xe0, 0xfc, 0xf1, 0xd3, 0x8e, 0xed, 0x2f,
|
||||||
|
0xaa, 0x2a, 0x8d, 0x17, 0x18, 0xa6, 0xa6, 0x24, 0xcb, 0x8b, 0x93, 0x11, 0xbb, 0xcb, 0xfb, 0xed,
|
||||||
|
0xf1, 0xf9, 0x83, 0x6b, 0x3f, 0x5c, 0xb5, 0x7a, 0xd5, 0x8a, 0x8f, 0x56, 0x2e, 0x47, 0x8b, 0xc0,
|
||||||
|
0x92, 0xc1, 0xc0, 0xf0, 0x28, 0x5a, 0x5b, 0x0d, 0xd1, 0xec, 0xef, 0xec, 0x62, 0x1e, 0xbd, 0xeb,
|
||||||
|
0xcd, 0xcc, 0x4c, 0xa8, 0x63, 0x77, 0xb8, 0x7c, 0xc3, 0xff, 0x1b, 0x2c, 0x28, 0x73, 0x1a, 0xad,
|
||||||
|
0xbe, 0xbe, 0x3e, 0xf8, 0x08, 0x0e, 0x88, 0x8a, 0x8c, 0x98, 0x10, 0xd9, 0x1d, 0x5f, 0x7d, 0xa8,
|
||||||
|
0xb3, 0xb3, 0x03, 0xf6, 0x43, 0x39, 0x8d, 0xde, 0x42, 0xdd, 0xf7, 0xc1, 0xbd, 0xbb, 0xb0, 0x11,
|
||||||
|
0x71, 0xfb, 0xd6, 0x87, 0x2b, 0xde, 0x7b, 0xff, 0xbd, 0x77, 0xff, 0xf8, 0xdf, 0x1e, 0x73, 0xd3,
|
||||||
|
0xfd, 0xb0, 0x81, 0xa7, 0x86, 0x9a, 0x7d, 0xf2, 0x72, 0x15, 0x2d, 0xb0, 0xe7, 0xa7, 0x4b, 0x76,
|
||||||
|
0x57, 0x0f, 0xbd, 0xfc, 0x11, 0xb4, 0xa4, 0x1d, 0xe2, 0xa1, 0x4b, 0xb9, 0x6c, 0xd3, 0x3b, 0x1d,
|
||||||
|
0x50, 0xd9, 0xee, 0x50, 0x7a, 0xa1, 0x91, 0xa0, 0x69, 0xf2, 0x9f, 0x3a, 0xe5, 0xe6, 0x64, 0xa3,
|
||||||
|
0x32, 0x1e, 0x2a, 0x30, 0x60, 0x77, 0xb4, 0x6c, 0xdf, 0x84, 0x1c, 0xbb, 0xc3, 0x31, 0x58, 0xdd,
|
||||||
|
0xa0, 0xa0, 0x60, 0x02, 0x5b, 0x0f, 0xbe, 0x6d, 0xd3, 0x17, 0x9f, 0xa3, 0x65, 0x2d, 0xe1, 0x7e,
|
||||||
|
0x0e, 0x4e, 0xbc, 0xea, 0xeb, 0x23, 0x14, 0x0a, 0xb7, 0x7d, 0xfb, 0x8d, 0xad, 0xd5, 0x61, 0x79,
|
||||||
|
0xd9, 0x4d, 0xb1, 0xbb, 0x73, 0xfc, 0x91, 0x30, 0x7a, 0x1f, 0x00, 0xd3, 0x61, 0xf7, 0xce, 0x01,
|
||||||
|
0x81, 0x8d, 0xff, 0xa4, 0xdd, 0x0f, 0xfb, 0xe6, 0x55, 0x36, 0xb3, 0x0d, 0x91, 0xd4, 0x43, 0xd3,
|
||||||
|
0x86, 0x48, 0xaa, 0x00, 0xe6, 0x6e, 0x55, 0x77, 0xdd, 0x3f, 0xec, 0x19, 0x8d, 0x73, 0xbc, 0xd8,
|
||||||
|
0xee, 0x4e, 0xb1, 0xee, 0xf7, 0xab, 0xa8, 0x8d, 0x4d, 0x0b, 0xe8, 0x1b, 0x1a, 0xb5, 0x0b, 0x9e,
|
||||||
|
0xac, 0xbb, 0x9b, 0x9c, 0x4d, 0xcf, 0xac, 0x64, 0x1b, 0x22, 0xa9, 0xc7, 0x14, 0xbb, 0xc3, 0xfd,
|
||||||
|
0xa2, 0x82, 0x71, 0xcd, 0xc0, 0x63, 0x47, 0x6c, 0x99, 0x0a, 0x54, 0x1e, 0x06, 0x86, 0xc7, 0x2c,
|
||||||
|
0x6e, 0x16, 0xe2, 0x46, 0x31, 0xf5, 0xca, 0xc8, 0xe0, 0xea, 0xa5, 0x51, 0xf0, 0x07, 0xab, 0xe8,
|
||||||
|
0x47, 0xeb, 0x74, 0x5b, 0xd7, 0x3b, 0x29, 0xe9, 0x23, 0x24, 0x4b, 0x77, 0xa8, 0x39, 0x6c, 0xf9,
|
||||||
|
0xe7, 0x46, 0x99, 0x5e, 0xff, 0xcb, 0xfb, 0x1c, 0x23, 0x21, 0x2a, 0x40, 0x7b, 0x9f, 0xc0, 0x8e,
|
||||||
|
0x50, 0xe5, 0xe5, 0x38, 0xc5, 0x9d, 0x8a, 0xe6, 0x2a, 0x3f, 0x4d, 0x27, 0x31, 0x3c, 0x2a, 0xb4,
|
||||||
|
0x0a, 0x28, 0x26, 0x7e, 0x97, 0x93, 0x51, 0xfa, 0xfa, 0x5d, 0x74, 0x16, 0xb2, 0x2b, 0x33, 0xc4,
|
||||||
|
0x39, 0x6f, 0x11, 0xe1, 0x6e, 0x52, 0xcb, 0x91, 0x29, 0x85, 0x73, 0x54, 0xa5, 0xa9, 0x4b, 0x3c,
|
||||||
|
0xa1, 0xa3, 0x6f, 0xac, 0xcb, 0x9d, 0x0a, 0xa6, 0x83, 0xd2, 0x08, 0x43, 0x23, 0x63, 0x16, 0x7e,
|
||||||
|
0x93, 0xbf, 0x5e, 0xac, 0x53, 0xe7, 0xe5, 0xdc, 0xb8, 0x62, 0x6d, 0x3f, 0xb6, 0x9b, 0xc6, 0x90,
|
||||||
|
0x5b, 0x77, 0x3f, 0x6a, 0x67, 0x83, 0x7b, 0x3d, 0x23, 0x3d, 0x4d, 0x8b, 0x21, 0x29, 0x42, 0x53,
|
||||||
|
0xf7, 0xd0, 0xd5, 0x94, 0x1a, 0x7b, 0x28, 0xd1, 0x1d, 0xa6, 0x74, 0x16, 0xb7, 0xf0, 0x4a, 0xbf,
|
||||||
|
0x9d, 0xa3, 0x5b, 0x7d, 0x7d, 0xd5, 0xc3, 0xc8, 0x98, 0xd0, 0x31, 0xbc, 0x5c, 0xa2, 0x2b, 0xfc,
|
||||||
|
0x81, 0x93, 0x89, 0x0e, 0xb7, 0x4a, 0xa3, 0x9f, 0x34, 0xf5, 0xf2, 0x47, 0x98, 0x0e, 0x50, 0xbf,
|
||||||
|
0xa1, 0xe8, 0x56, 0xd5, 0xdd, 0xcd, 0xd5, 0x70, 0xf6, 0x2c, 0x6e, 0x05, 0x2d, 0x45, 0xa6, 0x5d,
|
||||||
|
0x68, 0x29, 0xc7, 0x2d, 0x89, 0xe3, 0x9a, 0x48, 0x8a, 0x27, 0x13, 0x39, 0x27, 0x12, 0x38, 0x53,
|
||||||
|
0x2d, 0x8e, 0x68, 0xee, 0xfd, 0x38, 0xe1, 0x69, 0xe3, 0xeb, 0xb6, 0x41, 0x3a, 0x82, 0x64, 0x0a,
|
||||||
|
0x1d, 0xfd, 0x02, 0x97, 0x88, 0x72, 0x93, 0xe3, 0xb1, 0xd2, 0xdf, 0x17, 0x5b, 0x34, 0xf8, 0x78,
|
||||||
|
0x3c, 0xc7, 0xe5, 0x11, 0xc7, 0x25, 0x81, 0x25, 0x19, 0xda, 0x86, 0x94, 0xe2, 0x33, 0x72, 0x4a,
|
||||||
|
0xda, 0x1d, 0xad, 0xa2, 0xad, 0x05, 0xb8, 0xfa, 0x25, 0xca, 0x5c, 0x7b, 0x5b, 0xe9, 0x82, 0xdc,
|
||||||
|
0xd8, 0xbf, 0xfc, 0xd8, 0xc3, 0xc3, 0x7f, 0x67, 0x1f, 0x8f, 0xac, 0xc8, 0xa9, 0x96, 0xec, 0x9e,
|
||||||
|
0x39, 0xcd, 0x70, 0x2d, 0xad, 0xd6, 0x2e, 0xa4, 0xc4, 0xf4, 0x6c, 0x1a, 0xde, 0x21, 0x9e, 0xa5,
|
||||||
|
0xaa, 0x54, 0x64, 0x77, 0xad, 0xc1, 0x2b, 0xb6, 0x1a, 0xfc, 0x4a, 0x92, 0x2e, 0x51, 0x5c, 0xaf,
|
||||||
|
0x98, 0xea, 0x9b, 0xe9, 0xb5, 0xcf, 0x6a, 0xba, 0xfb, 0x87, 0x46, 0x99, 0x8a, 0x99, 0x59, 0x54,
|
||||||
|
0xb7, 0x0c, 0x3c, 0x2a, 0x69, 0x0b, 0xce, 0xe4, 0x9d, 0x8b, 0xad, 0x3e, 0x75, 0xb7, 0xd2, 0xe5,
|
||||||
|
0x0e, 0xd7, 0x2d, 0xba, 0x92, 0xa5, 0x52, 0x7a, 0xc6, 0x56, 0x0b, 0x85, 0x4c, 0xdb, 0x9d, 0x05,
|
||||||
|
0x0b, 0xed, 0x83, 0xb5, 0x3b, 0x8b, 0x19, 0x04, 0xd6, 0xee, 0x2c, 0x66, 0x10, 0x58, 0xbb, 0xb3,
|
||||||
|
0x98, 0x41, 0x60, 0xed, 0xce, 0x62, 0x06, 0x81, 0xb5, 0x3b, 0x8b, 0x19, 0x04, 0xd6, 0xee, 0x2c,
|
||||||
|
0x66, 0x10, 0x58, 0xbb, 0xb3, 0x98, 0x41, 0x60, 0xc6, 0xee, 0xe3, 0x00, 0x81, 0x80, 0x25, 0x4b,
|
||||||
|
0x2d, 0x50, 0xc8, 0xe7, 0x33, 0x6d, 0x77, 0x81, 0xa0, 0xc5, 0xcd, 0xf1, 0xc5, 0xa2, 0xb9, 0x2c,
|
||||||
|
0x59, 0xd2, 0x4b, 0x63, 0x83, 0xb6, 0xf3, 0xa7, 0x59, 0xbb, 0xb3, 0x9c, 0x19, 0xd4, 0x09, 0xbb,
|
||||||
|
0x8f, 0x8c, 0x0c, 0x71, 0xcb, 0x87, 0x2a, 0x59, 0xb2, 0xa4, 0x99, 0xdc, 0xf2, 0xe1, 0xaa, 0xc9,
|
||||||
|
0x51, 0x32, 0xff, 0x07, 0xaa, 0x57, 0x6f, 0xac, 0x69, 0xfa, 0xc1, 0x9f, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
|
||||||
|
};
|
||||||
|
|
||||||
|
const BITMAP_OPAQUE tune_diff_pair_skew_legend_xpm[1] = {{ png, sizeof( png ), "tune_diff_pair_skew_legend_xpm" }};
|
||||||
|
|
||||||
|
//EOF
|
|
@ -0,0 +1,655 @@
|
||||||
|
|
||||||
|
/* Do not modify this file, it was automatically generated by the
|
||||||
|
* PNG2cpp CMake script, using a *.png file as input.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bitmaps.h>
|
||||||
|
|
||||||
|
static const unsigned char png[] = {
|
||||||
|
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
|
||||||
|
0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0xa2, 0x08, 0x02, 0x00, 0x00, 0x01, 0x90, 0x54, 0x77,
|
||||||
|
0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x1e, 0xc2, 0x00, 0x00, 0x1e,
|
||||||
|
0xc2, 0x01, 0x6e, 0xd0, 0x75, 0x3e, 0x00, 0x00, 0x00, 0x09, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f,
|
||||||
|
0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x89, 0x2a, 0x8d, 0x06, 0x00, 0x00, 0x20, 0x00, 0x49,
|
||||||
|
0x44, 0x41, 0x54, 0x78, 0x9c, 0xec, 0x5d, 0x87, 0x5f, 0x14, 0x47, 0xfb, 0xf7, 0xbf, 0xf8, 0x25,
|
||||||
|
0xaf, 0x89, 0xd1, 0x18, 0x45, 0x45, 0x40, 0x63, 0x09, 0x56, 0x14, 0x03, 0xaf, 0xbd, 0xc5, 0x82,
|
||||||
|
0x05, 0x15, 0x45, 0x2c, 0x09, 0x28, 0x16, 0x90, 0x2e, 0x28, 0x0a, 0x8a, 0xd1, 0x68, 0x6c, 0x49,
|
||||||
|
0x34, 0x18, 0xa3, 0xd1, 0xe4, 0x35, 0x89, 0x46, 0xd4, 0x20, 0xbd, 0x88, 0x20, 0x20, 0xed, 0x80,
|
||||||
|
0xa3, 0x2b, 0x45, 0x3d, 0x3a, 0x07, 0x47, 0xbb, 0xf2, 0x9b, 0xbb, 0x81, 0x61, 0xbd, 0xdd, 0xdb,
|
||||||
|
0x9d, 0xbd, 0x9b, 0xbb, 0x83, 0x83, 0xef, 0x67, 0x3e, 0x7c, 0xf6, 0x86, 0xd9, 0x67, 0x9e, 0xfd,
|
||||||
|
0xee, 0xec, 0xd4, 0x67, 0x9e, 0x19, 0xa6, 0xd0, 0x0d, 0x0d, 0x09, 0x71, 0xec, 0x09, 0x86, 0xe1,
|
||||||
|
0xcb, 0xfa, 0xe4, 0x3f, 0xff, 0x47, 0xfd, 0x19, 0x39, 0x6e, 0x6c, 0xa1, 0xcf, 0x11, 0x70, 0x51,
|
||||||
|
0x1c, 0xe8, 0x07, 0xae, 0x09, 0x64, 0xa0, 0x26, 0x1d, 0x5e, 0x4c, 0x34, 0xfb, 0x0c, 0xe6, 0xad,
|
||||||
|
0x29, 0x0f, 0x2d, 0x33, 0xc8, 0x72, 0x76, 0x42, 0xd7, 0x36, 0xb3, 0xac, 0xc1, 0xdf, 0xca, 0xf0,
|
||||||
|
0x6b, 0xc4, 0x32, 0x68, 0x2d, 0x2c, 0x40, 0xd7, 0x40, 0xf7, 0xd6, 0x5e, 0x14, 0x1d, 0xf5, 0x25,
|
||||||
|
0x93, 0x81, 0x38, 0x2f, 0x87, 0x31, 0x5e, 0xe8, 0xef, 0x83, 0x9b, 0x81, 0xd9, 0xa7, 0x9f, 0x68,
|
||||||
|
0x95, 0x81, 0x37, 0x6e, 0x06, 0x00, 0xe6, 0x63, 0x47, 0x8b, 0xc5, 0xe2, 0xe5, 0x8b, 0x17, 0x82,
|
||||||
|
0x0b, 0x5a, 0x06, 0xb9, 0x8c, 0xb7, 0x14, 0xfa, 0x7a, 0xf1, 0xc8, 0x80, 0x05, 0x30, 0x03, 0x7b,
|
||||||
|
0xdb, 0x79, 0x28, 0x66, 0xc7, 0xb6, 0x2d, 0xe0, 0xaf, 0xd0, 0xf7, 0x08, 0xa1, 0x0c, 0x04, 0xca,
|
||||||
|
0x0c, 0xa8, 0x9f, 0xc5, 0x26, 0x87, 0x75, 0xe0, 0xaf, 0xc0, 0xdd, 0x8d, 0x54, 0x06, 0x79, 0x8c,
|
||||||
|
0xf1, 0x8c, 0x9f, 0x02, 0xc9, 0x0c, 0xb2, 0x76, 0x6c, 0xad, 0xb9, 0x7b, 0x5b, 0x3d, 0x83, 0xd6,
|
||||||
|
0x02, 0x41, 0xd5, 0xcd, 0x1b, 0x3d, 0x21, 0xfc, 0x1a, 0x0c, 0xb5, 0x4f, 0x1e, 0xd1, 0xef, 0x5f,
|
||||||
|
0x64, 0x67, 0xdb, 0x93, 0x41, 0x3e, 0x73, 0x06, 0x00, 0x99, 0x9b, 0x37, 0x80, 0xe7, 0x00, 0x1f,
|
||||||
|
0x44, 0x49, 0x70, 0x20, 0x0c, 0x1a, 0x9f, 0x20, 0xc9, 0xd6, 0x46, 0xd3, 0xd7, 0xcf, 0x92, 0x01,
|
||||||
|
0x1d, 0xec, 0x14, 0xc9, 0xa3, 0x27, 0x59, 0x30, 0x65, 0x20, 0x20, 0x95, 0x01, 0xf3, 0x7b, 0x23,
|
||||||
|
0x99, 0x41, 0xea, 0xca, 0x65, 0xf4, 0x48, 0xf0, 0xda, 0xd4, 0x62, 0xe4, 0x72, 0xb9, 0x96, 0x19,
|
||||||
|
0xbc, 0xf9, 0xe3, 0x2e, 0x3d, 0x32, 0xc3, 0x71, 0x23, 0xf5, 0xa7, 0xeb, 0xde, 0xdd, 0xcd, 0xcd,
|
||||||
|
0xcd, 0xbb, 0x9d, 0xb7, 0x6b, 0x93, 0x81, 0x82, 0x89, 0x25, 0x96, 0xe6, 0x45, 0x9b, 0x0c, 0xa8,
|
||||||
|
0x12, 0x9b, 0xd2, 0x9e, 0xab, 0x49, 0x6f, 0x6b, 0x6b, 0x23, 0x90, 0x01, 0x40, 0xf5, 0x6f, 0xbf,
|
||||||
|
0x66, 0x38, 0x6e, 0xe8, 0xa8, 0xae, 0xc2, 0x4c, 0xcf, 0x3b, 0x03, 0x46, 0x74, 0xd5, 0xd5, 0x4a,
|
||||||
|
0xca, 0x4a, 0xc8, 0x48, 0x17, 0xe4, 0xf5, 0x7d, 0x5c, 0x25, 0x27, 0x82, 0x00, 0x51, 0x5d, 0x0d,
|
||||||
|
0xf5, 0xf2, 0xee, 0x6e, 0x70, 0x91, 0xe7, 0xb6, 0x57, 0x57, 0xe9, 0x54, 0xc4, 0xcf, 0xb4, 0x46,
|
||||||
|
0xd7, 0xa0, 0x42, 0x15, 0xfa, 0x79, 0xd5, 0xc7, 0xc5, 0x90, 0x91, 0xce, 0x58, 0x78, 0x88, 0xd5,
|
||||||
|
0xa0, 0x54, 0x41, 0xa8, 0x95, 0xd7, 0x8b, 0x74, 0xf6, 0x48, 0x66, 0xe9, 0x4d, 0x8d, 0x8d, 0xfa,
|
||||||
|
0x92, 0x5e, 0x5d, 0xa5, 0x2c, 0xd7, 0x09, 0x71, 0xca, 0xfe, 0x25, 0xec, 0xa3, 0x91, 0x94, 0xce,
|
||||||
|
0x09, 0xbd, 0x4b, 0x6f, 0x97, 0x48, 0xa8, 0x31, 0xe0, 0x53, 0x20, 0xaf, 0x7b, 0x4d, 0x75, 0x35,
|
||||||
|
0xea, 0x3d, 0x64, 0xbb, 0x38, 0x13, 0x96, 0xce, 0x19, 0x3f, 0x8c, 0xde, 0x9a, 0x83, 0x20, 0x97,
|
||||||
|
0x76, 0x6b, 0x21, 0x1d, 0xfe, 0x2b, 0xd9, 0xce, 0x96, 0xa3, 0x35, 0x6f, 0xce, 0x78, 0xc1, 0x2e,
|
||||||
|
0x02, 0x5e, 0xa8, 0x8d, 0x35, 0xe8, 0x60, 0x63, 0x86, 0x93, 0x81, 0xc2, 0x82, 0x7c, 0xed, 0xa5,
|
||||||
|
0x03, 0xa4, 0x3b, 0xac, 0xd5, 0xa3, 0x74, 0xf6, 0xa2, 0x6d, 0x20, 0xe9, 0x57, 0x2e, 0x5d, 0x9c,
|
||||||
|
0xc6, 0xd4, 0x1d, 0xe2, 0x90, 0x9e, 0xb3, 0xc7, 0xa5, 0xab, 0x56, 0x44, 0x8d, 0xc9, 0xd8, 0xe4,
|
||||||
|
0x20, 0x97, 0x4a, 0xd5, 0xa4, 0x6b, 0x02, 0x56, 0xe7, 0x20, 0x7b, 0x97, 0x33, 0xba, 0xce, 0xdb,
|
||||||
|
0xef, 0x8a, 0xfe, 0xa5, 0x53, 0x99, 0xa1, 0x42, 0xb0, 0xdf, 0x95, 0x71, 0x9c, 0x46, 0x46, 0x3a,
|
||||||
|
0x27, 0xae, 0x5c, 0xbe, 0x84, 0x1b, 0x2e, 0x5d, 0x8c, 0xb3, 0x9e, 0x06, 0x68, 0x50, 0x0b, 0x6d,
|
||||||
|
0xc5, 0x42, 0xa3, 0x69, 0x4f, 0x05, 0x78, 0x23, 0x8c, 0x2f, 0xa5, 0x34, 0x34, 0x18, 0x68, 0x99,
|
||||||
|
0x68, 0x33, 0x87, 0xf1, 0xae, 0xec, 0xc3, 0xee, 0x4f, 0xcc, 0xc6, 0xe4, 0xec, 0x62, 0xa8, 0x0f,
|
||||||
|
0x35, 0x41, 0x2f, 0xda, 0x33, 0xe2, 0xd9, 0x22, 0x7b, 0x96, 0xfa, 0xcb, 0x65, 0x87, 0x13, 0x7c,
|
||||||
|
0x60, 0xf8, 0x1e, 0x30, 0x65, 0x1a, 0x4e, 0x7b, 0xa0, 0x53, 0x4b, 0x4e, 0x36, 0x3d, 0x7e, 0xd2,
|
||||||
|
0xc4, 0xf1, 0xf4, 0x94, 0x15, 0x17, 0xce, 0xe2, 0xc8, 0x34, 0x90, 0xf6, 0xe2, 0xdc, 0x1c, 0x7c,
|
||||||
|
0x46, 0x41, 0x4a, 0xc6, 0x89, 0x10, 0x3a, 0xf8, 0x69, 0xcf, 0x59, 0xc5, 0x68, 0x82, 0x38, 0x8f,
|
||||||
|
0xaf, 0xf6, 0x0c, 0xb3, 0x2c, 0x74, 0xf0, 0xd0, 0xde, 0xd9, 0x69, 0x6b, 0x60, 0x80, 0x5f, 0x80,
|
||||||
|
0xaf, 0xf7, 0xf7, 0xe7, 0xcf, 0x65, 0x67, 0xbd, 0x84, 0x91, 0x0d, 0xf5, 0xf5, 0x8d, 0x0d, 0x0d,
|
||||||
|
0x9c, 0xf7, 0x8a, 0xf3, 0x72, 0xf9, 0x69, 0xef, 0xc7, 0x30, 0x85, 0x43, 0x87, 0xa1, 0x4a, 0xce,
|
||||||
|
0xc0, 0xd6, 0x5e, 0xa0, 0xd4, 0xfe, 0xc7, 0xab, 0x97, 0x61, 0x65, 0xfa, 0xe7, 0xbd, 0x3f, 0xe8,
|
||||||
|
0xc1, 0x6e, 0xbe, 0x0d, 0xf8, 0xd7, 0x8e, 0x6d, 0x5b, 0x94, 0xda, 0xfb, 0x30, 0xcc, 0x6e, 0xd1,
|
||||||
|
0x61, 0x50, 0xed, 0xd5, 0x22, 0x85, 0xaa, 0xc9, 0xd1, 0x92, 0xe2, 0x62, 0xb5, 0x78, 0x90, 0x32,
|
||||||
|
0x66, 0xb2, 0x25, 0x8e, 0x58, 0x83, 0x69, 0xcf, 0xdc, 0xe9, 0x2f, 0x60, 0x9e, 0xb2, 0x91, 0x83,
|
||||||
|
0xc4, 0x05, 0x1e, 0x07, 0x39, 0xc5, 0x1a, 0xa8, 0xad, 0xd5, 0xa4, 0x3d, 0x0b, 0xa2, 0x2c, 0xcc,
|
||||||
|
0x39, 0x3f, 0x80, 0x61, 0xf5, 0x71, 0xd1, 0xf4, 0x2e, 0x07, 0x7b, 0x28, 0xf0, 0xf1, 0xcc, 0xcd,
|
||||||
|
0xc9, 0xe1, 0x15, 0x04, 0x8f, 0x23, 0xc0, 0x8d, 0x6a, 0x91, 0x59, 0x59, 0x2f, 0xb9, 0xef, 0xcd,
|
||||||
|
0xcc, 0x48, 0x5d, 0xb9, 0x8c, 0x51, 0x8d, 0xf4, 0xf5, 0x6b, 0xb4, 0xe1, 0xbe, 0xab, 0xae, 0x96,
|
||||||
|
0x57, 0x7b, 0xae, 0x50, 0x4d, 0x4b, 0xaa, 0xa5, 0x8f, 0x8f, 0x8d, 0xd5, 0xd4, 0x1d, 0xc2, 0x87,
|
||||||
|
0xf6, 0x25, 0xa7, 0x2c, 0x2c, 0x04, 0x28, 0xd4, 0xf1, 0xa6, 0x06, 0x27, 0xb1, 0x38, 0x5f, 0x40,
|
||||||
|
0x7f, 0x5a, 0xce, 0xce, 0x3b, 0x27, 0x74, 0x2a, 0xf7, 0x51, 0x96, 0x13, 0x31, 0xdf, 0x40, 0x6b,
|
||||||
|
0x01, 0x87, 0xf6, 0x23, 0x87, 0x7f, 0xa0, 0x85, 0x02, 0x3a, 0x69, 0x2f, 0x70, 0x77, 0xc3, 0xd4,
|
||||||
|
0xfe, 0xcd, 0xdd, 0xdb, 0x2c, 0xda, 0x7f, 0x69, 0x33, 0x07, 0x96, 0x22, 0xd0, 0xf5, 0x37, 0x1f,
|
||||||
|
0x3b, 0x7a, 0xfa, 0xe7, 0x56, 0x20, 0xf2, 0xcc, 0xa9, 0x50, 0x4e, 0xb1, 0xba, 0xd6, 0x39, 0x40,
|
||||||
|
0xa7, 0x2c, 0xa7, 0x2d, 0x38, 0xc9, 0x9e, 0x2d, 0xb4, 0x53, 0x8b, 0x34, 0x72, 0xc9, 0x81, 0x80,
|
||||||
|
0x5f, 0x70, 0x57, 0x7d, 0x1d, 0xe3, 0x7f, 0x0b, 0xbd, 0x3c, 0x94, 0x8b, 0x11, 0xb4, 0x3e, 0xe3,
|
||||||
|
0xb9, 0x6f, 0xc3, 0x8c, 0xf9, 0xd5, 0xaa, 0x21, 0x7b, 0xe7, 0x76, 0xc6, 0x7a, 0xed, 0xdd, 0xfd,
|
||||||
|
0xbf, 0x34, 0xdd, 0x52, 0x53, 0x5d, 0xad, 0x63, 0xa6, 0x86, 0x1b, 0x9d, 0xd0, 0xd1, 0x92, 0x95,
|
||||||
|
0xd9, 0xf4, 0x22, 0x55, 0xeb, 0xdb, 0xc9, 0xa8, 0xae, 0x36, 0xe8, 0x3e, 0x77, 0xf6, 0x5b, 0x96,
|
||||||
|
0x21, 0x79, 0xbe, 0xbf, 0x37, 0x43, 0xf3, 0xe7, 0xed, 0x61, 0x1c, 0xd5, 0xd5, 0xc0, 0x52, 0x8e,
|
||||||
|
0xa1, 0xa2, 0xd1, 0x96, 0x13, 0xe1, 0x0a, 0x4f, 0x57, 0x57, 0x17, 0x20, 0x3e, 0xd9, 0x7e, 0x01,
|
||||||
|
0x8c, 0x97, 0x75, 0x74, 0xe0, 0xe7, 0x42, 0x5e, 0x75, 0xf8, 0x09, 0xde, 0xb9, 0x7d, 0x8b, 0xfe,
|
||||||
|
0x2f, 0xa8, 0x5f, 0x5d, 0x4c, 0x14, 0x8a, 0xe9, 0xee, 0xea, 0x82, 0x17, 0xb2, 0x8e, 0x76, 0x87,
|
||||||
|
0x4f, 0x3e, 0x22, 0xbf, 0x76, 0xc4, 0x17, 0x97, 0x2f, 0x7e, 0x4f, 0x8f, 0x7c, 0xb1, 0x7e, 0x8d,
|
||||||
|
0xb2, 0x3d, 0xae, 0xe9, 0xfb, 0x3a, 0x51, 0x3d, 0x93, 0xfa, 0x3c, 0x05, 0x5c, 0x80, 0x21, 0xb9,
|
||||||
|
0xf1, 0x27, 0x11, 0x18, 0x55, 0x8f, 0x54, 0x1a, 0x7e, 0x78, 0x52, 0x63, 0x80, 0xba, 0x52, 0xd5,
|
||||||
|
0x1c, 0x1f, 0xf8, 0x5b, 0x57, 0x57, 0x0b, 0x2e, 0x44, 0x11, 0x0f, 0x40, 0x32, 0xd1, 0xe3, 0x08,
|
||||||
|
0x9c, 0x5c, 0x0c, 0xa4, 0x7a, 0xd1, 0x51, 0x5f, 0x3a, 0x9d, 0x40, 0x75, 0x99, 0x4c, 0xa6, 0x16,
|
||||||
|
0x09, 0x92, 0xc5, 0x4e, 0x9d, 0x8c, 0x93, 0x8b, 0x81, 0x54, 0x8f, 0xb6, 0x62, 0xee, 0xfc, 0xd0,
|
||||||
|
0x17, 0x72, 0xd3, 0x56, 0xaf, 0xc0, 0x2c, 0x33, 0x06, 0x52, 0x5d, 0x59, 0xab, 0x30, 0x4d, 0x24,
|
||||||
|
0x53, 0xad, 0x62, 0x7a, 0x6c, 0x63, 0x02, 0x7c, 0xfa, 0x9d, 0xea, 0x98, 0xc5, 0x80, 0xb1, 0x68,
|
||||||
|
0x31, 0x62, 0x70, 0xa8, 0x8e, 0xdf, 0x61, 0xd2, 0x45, 0x75, 0x76, 0xc3, 0x33, 0x2a, 0xf8, 0xb1,
|
||||||
|
0x3e, 0xc5, 0x72, 0x22, 0x4e, 0x32, 0x66, 0xd5, 0xa7, 0xe0, 0xa9, 0x4e, 0x9c, 0xf5, 0xa3, 0x7e,
|
||||||
|
0x3e, 0x81, 0x01, 0x7e, 0x0e, 0x6b, 0x56, 0x2b, 0x54, 0x6b, 0xb3, 0x4f, 0xff, 0x7d, 0x92, 0x18,
|
||||||
|
0x1f, 0x07, 0x62, 0x4e, 0x1e, 0x0f, 0xa2, 0x27, 0xd6, 0x4d, 0x75, 0xd2, 0xac, 0xa3, 0xd9, 0xe7,
|
||||||
|
0xec, 0xac, 0x97, 0xa0, 0xe3, 0x91, 0xf2, 0x2c, 0xd9, 0x62, 0xdc, 0x98, 0x75, 0xab, 0x57, 0x32,
|
||||||
|
0x26, 0xee, 0x5f, 0xac, 0xf3, 0x02, 0xa3, 0xea, 0x31, 0x03, 0x43, 0xf5, 0xef, 0x2f, 0xa8, 0xc5,
|
||||||
|
0xe0, 0xa8, 0xde, 0xd2, 0xd2, 0xa2, 0x30, 0x7e, 0xe5, 0xa8, 0x41, 0x75, 0x96, 0xf9, 0x54, 0x10,
|
||||||
|
0xe0, 0x7f, 0xfb, 0xa9, 0xea, 0x0a, 0x95, 0x61, 0xa5, 0xa6, 0xbb, 0x60, 0xe5, 0x5b, 0x7c, 0x2c,
|
||||||
|
0xa0, 0x1f, 0xaa, 0x3e, 0x49, 0x2d, 0x72, 0xdb, 0xe6, 0x8d, 0x0a, 0x1a, 0x1a, 0x53, 0x92, 0x95,
|
||||||
|
0xaa, 0x6b, 0x36, 0x52, 0x43, 0x30, 0xa6, 0xea, 0x55, 0x55, 0x95, 0x12, 0x09, 0x83, 0xa9, 0x98,
|
||||||
|
0x72, 0x02, 0x95, 0xc9, 0xc2, 0x54, 0x0d, 0xc6, 0x54, 0x5d, 0x13, 0x12, 0xe7, 0xcf, 0xc5, 0x29,
|
||||||
|
0x33, 0xfd, 0x51, 0x75, 0x98, 0xfe, 0xe9, 0x84, 0x71, 0xec, 0x69, 0xc8, 0xab, 0x0e, 0x3e, 0x44,
|
||||||
|
0xf0, 0xc1, 0xa9, 0x95, 0x04, 0xa5, 0xea, 0x9f, 0xf3, 0x50, 0xbd, 0x2e, 0x2a, 0x12, 0x0e, 0xf6,
|
||||||
|
0xa4, 0xaa, 0x1a, 0x93, 0x11, 0x14, 0x6b, 0x1d, 0x6a, 0xa0, 0x58, 0xee, 0xf4, 0x84, 0x9b, 0xe1,
|
||||||
|
0xf8, 0x46, 0xb1, 0xf4, 0x8e, 0x1a, 0x5f, 0xd5, 0x01, 0x24, 0xe5, 0x65, 0x7d, 0x53, 0x1d, 0x1e,
|
||||||
|
0x07, 0x41, 0xcd, 0x83, 0x8c, 0x80, 0x7a, 0x4c, 0x81, 0xf8, 0xae, 0x17, 0x80, 0xf7, 0x98, 0x97,
|
||||||
|
0x98, 0xc0, 0x77, 0xc9, 0x00, 0xaa, 0xce, 0xf7, 0x2e, 0x10, 0x84, 0x41, 0xfe, 0x9a, 0x34, 0xe1,
|
||||||
|
0x57, 0x60, 0x8a, 0x7a, 0x05, 0x15, 0x7a, 0x7b, 0x72, 0xa7, 0xa6, 0x80, 0xce, 0xfa, 0x9b, 0x9a,
|
||||||
|
0x1a, 0x23, 0x4c, 0x3b, 0xe6, 0xec, 0x71, 0xe1, 0xab, 0x3d, 0x5d, 0x75, 0xd8, 0x76, 0x72, 0xda,
|
||||||
|
0xd1, 0xb2, 0x40, 0xcb, 0xcf, 0x14, 0x6a, 0xdf, 0xf9, 0xee, 0x2d, 0x66, 0x7a, 0x2d, 0xca, 0x3a,
|
||||||
|
0x27, 0xb4, 0xaf, 0x61, 0x70, 0xea, 0x2f, 0x6a, 0xe2, 0x7e, 0xa4, 0x3a, 0x2c, 0xf7, 0x98, 0x89,
|
||||||
|
0x55, 0xaa, 0x5b, 0x69, 0x9d, 0x17, 0x23, 0x74, 0xaa, 0xd7, 0x81, 0x42, 0x2d, 0xb9, 0x0c, 0x56,
|
||||||
|
0x31, 0x8c, 0x29, 0xd9, 0x55, 0x7f, 0x91, 0x96, 0xc6, 0x37, 0x77, 0x5d, 0x55, 0xaf, 0xfc, 0xf9,
|
||||||
|
0x27, 0xcc, 0x94, 0x2c, 0xaa, 0x83, 0xef, 0x75, 0xf4, 0x88, 0xe1, 0x7c, 0x73, 0xd7, 0x55, 0x75,
|
||||||
|
0x30, 0x80, 0xc7, 0x4c, 0x99, 0xdc, 0xbb, 0xa1, 0x84, 0x0e, 0x34, 0x6f, 0xea, 0xb2, 0xc3, 0x29,
|
||||||
|
0x38, 0x28, 0x30, 0x23, 0xfd, 0xc5, 0x02, 0x9b, 0xd9, 0xa0, 0x07, 0xcf, 0x2e, 0x53, 0x57, 0xd5,
|
||||||
|
0xe3, 0xac, 0xa7, 0x61, 0xa6, 0x2c, 0x0e, 0xf2, 0x67, 0xfc, 0xd7, 0x1f, 0x77, 0xef, 0xc0, 0x0b,
|
||||||
|
0xb4, 0x1c, 0x09, 0x54, 0xf7, 0xf3, 0x3e, 0xa2, 0x69, 0xe3, 0x04, 0x82, 0x4e, 0xaa, 0xe7, 0x1f,
|
||||||
|
0xdc, 0x8f, 0xf3, 0xa5, 0xe2, 0x0f, 0x37, 0x79, 0x81, 0xc0, 0x2a, 0x64, 0x9c, 0xf5, 0x74, 0xd6,
|
||||||
|
0x24, 0x4a, 0x23, 0x0c, 0xd0, 0x8f, 0xd5, 0x31, 0x23, 0x3a, 0x74, 0x55, 0xbd, 0x34, 0xf4, 0x04,
|
||||||
|
0xd0, 0x2c, 0xd3, 0x91, 0x61, 0xbc, 0xa3, 0x84, 0x4c, 0xaa, 0x69, 0xb6, 0x1f, 0x96, 0x6f, 0x5d,
|
||||||
|
0xd6, 0x50, 0x09, 0x74, 0x7a, 0x61, 0x79, 0x50, 0x2e, 0x35, 0xfe, 0x73, 0x9f, 0x1a, 0x0f, 0x7a,
|
||||||
|
0x0a, 0x30, 0x5e, 0xde, 0xcd, 0x60, 0x35, 0x1e, 0x1b, 0x13, 0xdd, 0x2f, 0x96, 0x4e, 0xa1, 0xf5,
|
||||||
|
0x1d, 0x3d, 0x3c, 0x5f, 0xb2, 0x88, 0x88, 0x7c, 0x46, 0x90, 0x1c, 0x6a, 0x80, 0x61, 0x01, 0xa8,
|
||||||
|
0x2b, 0x33, 0xb7, 0x6e, 0xce, 0x75, 0xdd, 0xf3, 0xea, 0x92, 0xfa, 0x40, 0x89, 0x38, 0x8c, 0xb9,
|
||||||
|
0xe4, 0x6b, 0x68, 0xc8, 0x64, 0x95, 0xd7, 0x7f, 0xcc, 0x3f, 0xec, 0x1e, 0x3f, 0xd3, 0x5a, 0xad,
|
||||||
|
0x74, 0x44, 0x5b, 0x4e, 0xcc, 0xd8, 0xe4, 0x00, 0x46, 0x33, 0x5a, 0x6c, 0xe1, 0xd2, 0x0e, 0x03,
|
||||||
|
0x86, 0x77, 0x50, 0x1b, 0xb1, 0xef, 0x1e, 0xd6, 0x84, 0xda, 0xc7, 0x11, 0xcf, 0x16, 0xda, 0xd1,
|
||||||
|
0xbf, 0xc4, 0xb8, 0x2f, 0xa6, 0x25, 0xce, 0x9b, 0x0b, 0xde, 0xc1, 0xd3, 0xf1, 0x66, 0xea, 0x63,
|
||||||
|
0x41, 0xf3, 0xf1, 0xe0, 0x1d, 0x10, 0x7e, 0x80, 0xf7, 0x31, 0x30, 0x78, 0xff, 0xdf, 0xef, 0x77,
|
||||||
|
0x61, 0x5b, 0xc0, 0xab, 0x4e, 0x2d, 0x7e, 0x7f, 0x6c, 0x0b, 0xaa, 0x91, 0xee, 0xa6, 0x26, 0xb5,
|
||||||
|
0x34, 0x5d, 0xbd, 0x4b, 0xe6, 0x10, 0xaf, 0xaf, 0x5c, 0x4c, 0x98, 0x33, 0x0b, 0xdd, 0x92, 0xbe,
|
||||||
|
0x61, 0x9d, 0xac, 0x5d, 0xa2, 0xd0, 0x03, 0x06, 0x00, 0xef, 0x8d, 0x0d, 0x0d, 0x39, 0xd9, 0x59,
|
||||||
|
0x20, 0x04, 0xf8, 0x7a, 0xc3, 0x0b, 0xee, 0x5b, 0x52, 0x92, 0xc1, 0x38, 0xae, 0xa7, 0x85, 0x59,
|
||||||
|
0xb6, 0xb8, 0x53, 0xf4, 0x4e, 0x53, 0xca, 0x6e, 0x4a, 0xa3, 0x29, 0x16, 0x8b, 0x77, 0x39, 0x3b,
|
||||||
|
0xa1, 0x17, 0x4c, 0x7d, 0x61, 0x64, 0x9e, 0x84, 0x82, 0x01, 0xc0, 0x3b, 0x02, 0xa3, 0x09, 0x02,
|
||||||
|
0x1d, 0xe5, 0x67, 0xc3, 0x10, 0x65, 0x6f, 0xef, 0xfd, 0xae, 0x29, 0x19, 0x9c, 0x97, 0x90, 0xf6,
|
||||||
|
0x6e, 0x48, 0x82, 0x10, 0xe4, 0xe5, 0x41, 0xd2, 0x7f, 0x09, 0xff, 0x59, 0x2e, 0x95, 0xa6, 0x2e,
|
||||||
|
0x5f, 0x02, 0xe5, 0x68, 0xec, 0xac, 0x69, 0x0b, 0x53, 0xe3, 0xbd, 0x3e, 0xb6, 0xcf, 0x12, 0xb8,
|
||||||
|
0xad, 0x88, 0x6d, 0xcf, 0x11, 0xac, 0xb2, 0xa8, 0x96, 0x16, 0xab, 0x96, 0x2d, 0x81, 0x17, 0xd4,
|
||||||
|
0x8d, 0x96, 0xd9, 0x2e, 0x3b, 0x7a, 0xa6, 0x11, 0xbd, 0x0e, 0x6b, 0xa9, 0x37, 0x13, 0x4c, 0x8d,
|
||||||
|
0xf7, 0xe7, 0xcb, 0x7a, 0x4a, 0x68, 0xe9, 0xa9, 0x13, 0x38, 0x32, 0x21, 0xef, 0x8c, 0xfb, 0xf9,
|
||||||
|
0x20, 0xe4, 0x9d, 0x9d, 0x51, 0xe6, 0x3d, 0xf6, 0x46, 0x4d, 0xa9, 0x29, 0xf8, 0xda, 0xb2, 0xc3,
|
||||||
|
0xa4, 0x78, 0x07, 0xbd, 0x40, 0x54, 0xd8, 0x71, 0xec, 0xe1, 0x30, 0x1b, 0xea, 0xc2, 0x23, 0x1e,
|
||||||
|
0xc4, 0x2b, 0x7a, 0x93, 0xe2, 0x1d, 0x6e, 0xfc, 0x8a, 0xc4, 0xb6, 0x0a, 0x01, 0x60, 0x5c, 0x97,
|
||||||
|
0x53, 0x43, 0x91, 0xca, 0x78, 0x24, 0x92, 0xc9, 0xe8, 0x57, 0x6b, 0x98, 0x16, 0xef, 0x79, 0xbc,
|
||||||
|
0x79, 0xc7, 0x41, 0x51, 0xef, 0x4c, 0x02, 0xe6, 0x06, 0x3d, 0x1c, 0xe8, 0x8b, 0xf7, 0x33, 0xa7,
|
||||||
|
0x42, 0xff, 0xfe, 0xf3, 0x1e, 0x59, 0x99, 0xc6, 0xe7, 0xdd, 0x0f, 0x6b, 0x6b, 0x21, 0x0e, 0xf4,
|
||||||
|
0xc2, 0x7b, 0x52, 0x62, 0x82, 0xb7, 0xa7, 0xc7, 0x8a, 0x25, 0x8b, 0x2a, 0x2b, 0x5f, 0x13, 0x14,
|
||||||
|
0xcb, 0x83, 0x77, 0x3c, 0x8b, 0x1c, 0x4c, 0x14, 0xf7, 0x95, 0xf7, 0xfe, 0xcd, 0xfb, 0xc8, 0xe1,
|
||||||
|
0x1f, 0x48, 0x55, 0x40, 0xad, 0x96, 0x48, 0x24, 0xba, 0xfd, 0xeb, 0x2f, 0xe0, 0xef, 0xdd, 0xdf,
|
||||||
|
0x94, 0xbe, 0xa0, 0x8a, 0x8b, 0x8b, 0x7e, 0xfa, 0xe1, 0x0a, 0xb8, 0x80, 0x93, 0xeb, 0x7f, 0xdd,
|
||||||
|
0xfb, 0x1f, 0x8e, 0x58, 0xe3, 0xf3, 0x8e, 0xb7, 0x9d, 0x13, 0x07, 0x7a, 0xb1, 0x6c, 0xa7, 0xff,
|
||||||
|
0x4c, 0x88, 0x8b, 0x03, 0x23, 0x72, 0x30, 0x20, 0x4c, 0x79, 0x96, 0x0c, 0x7e, 0x6e, 0xdf, 0xb2,
|
||||||
|
0xb9, 0xb5, 0xb5, 0xd5, 0xe7, 0x88, 0x72, 0x0f, 0x01, 0xd5, 0x9b, 0x19, 0x3b, 0x30, 0x78, 0xcf,
|
||||||
|
0xd5, 0x0b, 0xef, 0xbd, 0xed, 0x6a, 0xbf, 0xe6, 0x5d, 0x7f, 0x30, 0x1a, 0xef, 0x03, 0xa2, 0xbc,
|
||||||
|
0xeb, 0x0f, 0x74, 0xfb, 0x21, 0x35, 0x20, 0xde, 0x31, 0x2d, 0x2e, 0x31, 0xd1, 0xc7, 0x3b, 0x93,
|
||||||
|
0xdf, 0x42, 0xed, 0x60, 0x5a, 0xbc, 0x0b, 0xd4, 0x79, 0xdf, 0xef, 0xfa, 0xb5, 0x16, 0x9b, 0xea,
|
||||||
|
0x36, 0x39, 0xac, 0x03, 0xb7, 0xcc, 0x99, 0xf1, 0x05, 0xfc, 0xd9, 0xd7, 0x9f, 0xc1, 0x30, 0xb6,
|
||||||
|
0xc3, 0x84, 0x29, 0xf3, 0x0e, 0x5a, 0x0e, 0x2d, 0x66, 0x8f, 0x15, 0xbd, 0xbc, 0x83, 0x30, 0x76,
|
||||||
|
0xd4, 0x88, 0x96, 0x96, 0x16, 0xc4, 0x3b, 0x5f, 0x13, 0x27, 0x16, 0x98, 0x32, 0xef, 0x08, 0x65,
|
||||||
|
0xa5, 0xa5, 0xf4, 0xc4, 0x80, 0xd6, 0xbd, 0x2e, 0xce, 0xa3, 0x3e, 0xfa, 0x90, 0xea, 0x6a, 0x0f,
|
||||||
|
0xe2, 0x65, 0x66, 0x06, 0xf5, 0x67, 0xc5, 0x85, 0x73, 0x50, 0x6c, 0xda, 0xea, 0x15, 0x5a, 0x29,
|
||||||
|
0xce, 0x00, 0x53, 0xe5, 0x9d, 0xdb, 0x2e, 0x0a, 0x3a, 0xea, 0xb1, 0x1c, 0x3f, 0xb6, 0x45, 0xb3,
|
||||||
|
0xc1, 0x25, 0x84, 0x5c, 0xda, 0x0d, 0xbd, 0x22, 0x80, 0x50, 0x17, 0x15, 0xc9, 0x43, 0x63, 0xcd,
|
||||||
|
0x30, 0x31, 0xde, 0xf3, 0x30, 0x79, 0x6f, 0x97, 0x48, 0xc0, 0x20, 0x23, 0x3a, 0xea, 0xa9, 0x97,
|
||||||
|
0xc7, 0xa1, 0xcd, 0x1b, 0xd6, 0x73, 0x66, 0xfd, 0xea, 0xca, 0xc5, 0xc8, 0x5e, 0x73, 0x50, 0x22,
|
||||||
|
0x6b, 0xb0, 0x83, 0x94, 0x77, 0x2d, 0x50, 0x76, 0x26, 0x14, 0x4d, 0x76, 0x96, 0x9f, 0x3d, 0xad,
|
||||||
|
0xa3, 0xb4, 0x01, 0xc0, 0x3b, 0xa8, 0x9d, 0x51, 0xf3, 0x08, 0xc2, 0xf8, 0xcf, 0x3e, 0xd5, 0x94,
|
||||||
|
0xb2, 0x8f, 0x77, 0xd2, 0xf6, 0x97, 0x10, 0x1d, 0x35, 0xd5, 0xb1, 0xd3, 0xa6, 0xa0, 0x82, 0xff,
|
||||||
|
0xea, 0xe2, 0x79, 0xad, 0x45, 0x0d, 0x00, 0xde, 0x01, 0x3a, 0xda, 0xdb, 0x21, 0xe9, 0xec, 0x83,
|
||||||
|
0x5b, 0x7d, 0xf3, 0x0e, 0x51, 0x1b, 0xf9, 0x04, 0xb4, 0xdb, 0xa8, 0xec, 0xc7, 0x4c, 0xb6, 0x2a,
|
||||||
|
0x0a, 0xf4, 0x6b, 0x2d, 0xe4, 0x67, 0x7c, 0xa5, 0x8d, 0x8b, 0x1c, 0xcc, 0x00, 0x4a, 0x44, 0xfa,
|
||||||
|
0x86, 0x75, 0xc5, 0xc7, 0x8f, 0x76, 0xbe, 0x7d, 0x43, 0xe4, 0x81, 0x0f, 0xb8, 0x7d, 0xc3, 0x9e,
|
||||||
|
0x00, 0xba, 0xb2, 0xd1, 0x37, 0xef, 0x08, 0x25, 0xc1, 0x41, 0xb1, 0x53, 0x3f, 0xd7, 0x82, 0x19,
|
||||||
|
0xa5, 0x73, 0x1f, 0xc0, 0x7b, 0xea, 0xca, 0x65, 0x58, 0x61, 0xd5, 0x72, 0xac, 0xb0, 0x62, 0x69,
|
||||||
|
0xb2, 0xfd, 0x82, 0x68, 0x95, 0xef, 0x19, 0x6a, 0x88, 0x9e, 0x64, 0x51, 0x1a, 0x8a, 0xb5, 0xf6,
|
||||||
|
0xa6, 0x35, 0xf0, 0x79, 0xff, 0xdc, 0xc2, 0xdc, 0xdd, 0x95, 0xe3, 0x2d, 0xf2, 0x02, 0x68, 0x6c,
|
||||||
|
0x5f, 0xff, 0x74, 0xb5, 0x38, 0xd0, 0x0f, 0x8c, 0x69, 0xf3, 0x0f, 0xee, 0x17, 0xb8, 0xbb, 0xb1,
|
||||||
|
0x84, 0x42, 0x6f, 0x0f, 0x43, 0xd4, 0x33, 0x65, 0x61, 0xa1, 0xb1, 0xd3, 0xa7, 0xa0, 0x17, 0x20,
|
||||||
|
0x70, 0x77, 0xe5, 0xbe, 0x47, 0x2b, 0x60, 0xf2, 0x0e, 0x7a, 0x32, 0xb0, 0xd6, 0xb2, 0x9b, 0x47,
|
||||||
|
0xde, 0xd8, 0x14, 0x13, 0x86, 0xac, 0xdf, 0xe5, 0xd0, 0x45, 0x0e, 0x0c, 0xa5, 0xa1, 0xc1, 0xc4,
|
||||||
|
0x33, 0x80, 0x4e, 0xa7, 0x70, 0xca, 0xbb, 0xee, 0xfe, 0x84, 0x74, 0x84, 0xa1, 0xdb, 0xd5, 0xae,
|
||||||
|
0xba, 0x5a, 0x54, 0x27, 0x12, 0x9c, 0xde, 0x83, 0x18, 0xe2, 0x9d, 0x1d, 0xf2, 0xa4, 0xf9, 0x36,
|
||||||
|
0x90, 0x20, 0xd0, 0xea, 0x12, 0x94, 0x4b, 0xe1, 0x9d, 0x63, 0x33, 0xcc, 0xe0, 0xe4, 0x5d, 0xd1,
|
||||||
|
0x94, 0x9e, 0x86, 0xfa, 0x3c, 0xf2, 0xae, 0x4e, 0x52, 0x62, 0x87, 0x78, 0xe7, 0x46, 0xb2, 0xfd,
|
||||||
|
0x97, 0x90, 0x23, 0x16, 0xcf, 0x62, 0x7c, 0x01, 0xdd, 0xf2, 0x69, 0xcd, 0x7b, 0xc8, 0x89, 0xe3,
|
||||||
|
0x19, 0xe9, 0x2f, 0xc6, 0x8c, 0xfc, 0x98, 0x94, 0x3e, 0x2c, 0x30, 0x1a, 0xef, 0x19, 0x8e, 0x1b,
|
||||||
|
0x7b, 0xc7, 0xdc, 0x61, 0xa4, 0x64, 0xa2, 0xcf, 0x28, 0x6e, 0x06, 0xfb, 0xce, 0x19, 0x06, 0xde,
|
||||||
|
0x6b, 0x6b, 0x45, 0xb0, 0x7b, 0xf3, 0xe4, 0xd1, 0x23, 0x67, 0xa7, 0xad, 0xf4, 0x5b, 0xde, 0xbd,
|
||||||
|
0xc5, 0xdd, 0x6b, 0x89, 0x03, 0xa3, 0xf1, 0x8e, 0x16, 0x71, 0x04, 0x07, 0x18, 0x8e, 0x6e, 0xd2,
|
||||||
|
0x52, 0x66, 0xaf, 0xe1, 0x75, 0xce, 0x5e, 0x17, 0xf6, 0x94, 0x74, 0xde, 0xa9, 0x73, 0xf4, 0x4b,
|
||||||
|
0x17, 0xda, 0x47, 0x3c, 0xfc, 0xe7, 0xca, 0xa5, 0x8b, 0xe0, 0x1a, 0xee, 0x0d, 0x9b, 0x36, 0xc9,
|
||||||
|
0x02, 0x7c, 0x0a, 0xe0, 0xc2, 0xcb, 0xe3, 0x30, 0x8a, 0xd4, 0x05, 0x46, 0xe3, 0x5d, 0xda, 0xd6,
|
||||||
|
0x86, 0xec, 0x0e, 0x19, 0x8f, 0x16, 0xe2, 0x0b, 0xc9, 0xab, 0x0a, 0xd4, 0x49, 0x6d, 0x7c, 0x96,
|
||||||
|
0xc4, 0x9e, 0x78, 0xf0, 0xd6, 0xef, 0x00, 0x75, 0x4f, 0xff, 0x45, 0x4c, 0x55, 0x5e, 0xfb, 0x41,
|
||||||
|
0x17, 0x51, 0x60, 0xc4, 0x84, 0x0c, 0xde, 0x4b, 0x43, 0x8e, 0x73, 0xa6, 0x1f, 0xd4, 0xbc, 0x2b,
|
||||||
|
0x54, 0x2d, 0xe1, 0xd3, 0xde, 0x52, 0x9f, 0xb9, 0xd9, 0x41, 0xbb, 0xbe, 0x0d, 0xda, 0x79, 0x07,
|
||||||
|
0x42, 0xd5, 0xf5, 0x1f, 0xb1, 0x6e, 0x19, 0xe4, 0xbc, 0x43, 0xa0, 0xba, 0x1e, 0x84, 0xf8, 0x99,
|
||||||
|
0xd6, 0xd5, 0xbf, 0xde, 0xc0, 0xb9, 0xab, 0x31, 0x25, 0x39, 0x6d, 0xed, 0x6a, 0x74, 0x63, 0x9e,
|
||||||
|
0xdb, 0xd7, 0x98, 0xd9, 0xa1, 0x29, 0xe5, 0x71, 0x9f, 0x8d, 0xd2, 0x41, 0x6b, 0x9d, 0xd0, 0x2f,
|
||||||
|
0x78, 0x87, 0x28, 0x0d, 0x09, 0x46, 0x75, 0x05, 0x0c, 0x09, 0xb3, 0x67, 0x40, 0xa7, 0x21, 0xe5,
|
||||||
|
0xe7, 0xce, 0x94, 0x7f, 0x77, 0xb6, 0xe4, 0xf8, 0x51, 0xa1, 0xef, 0x91, 0x64, 0xbb, 0x05, 0x6a,
|
||||||
|
0x33, 0x6e, 0xc5, 0x47, 0x79, 0x9b, 0x47, 0x8f, 0x1c, 0xfe, 0xc1, 0x02, 0x9b, 0xd9, 0xfa, 0x78,
|
||||||
|
0x0a, 0x4c, 0xf4, 0x23, 0xde, 0x11, 0x44, 0x0f, 0xef, 0xe7, 0xed, 0xfb, 0x46, 0xed, 0x1d, 0xa8,
|
||||||
|
0x85, 0x4c, 0xc7, 0x8d, 0x65, 0xdf, 0x7f, 0xd7, 0xa2, 0x4f, 0xe8, 0xf5, 0x19, 0xfb, 0x23, 0xef,
|
||||||
|
0x7a, 0x87, 0x4c, 0xd6, 0x2a, 0x2c, 0x68, 0x4c, 0x4d, 0x69, 0x48, 0x4a, 0x68, 0xc9, 0xc9, 0xea,
|
||||||
|
0x6e, 0x69, 0x36, 0xbc, 0x0a, 0x83, 0x88, 0xf7, 0xd6, 0xc2, 0xfc, 0xa2, 0x40, 0xbf, 0xb4, 0xd5,
|
||||||
|
0x2b, 0x51, 0x4b, 0x8e, 0x42, 0xe2, 0xbc, 0x39, 0x42, 0x1f, 0xcf, 0xb7, 0x7f, 0x13, 0x36, 0x1c,
|
||||||
|
0x67, 0x41, 0x3f, 0xe2, 0x3d, 0x23, 0x23, 0x83, 0xc5, 0x3b, 0xf6, 0xe9, 0x53, 0xa1, 0x3c, 0x4e,
|
||||||
|
0xb7, 0x7a, 0x3f, 0x3c, 0x3a, 0x1d, 0x9a, 0xb9, 0xcb, 0x19, 0x67, 0x25, 0x28, 0xf9, 0xcb, 0xf9,
|
||||||
|
0x65, 0x67, 0xb8, 0x5d, 0xe2, 0xeb, 0x8e, 0x7e, 0xc4, 0x3b, 0x3b, 0x46, 0x7d, 0xf4, 0xa1, 0x36,
|
||||||
|
0x8e, 0xe0, 0xe5, 0xf2, 0x22, 0x4a, 0x67, 0x09, 0x85, 0xa8, 0x89, 0x13, 0x40, 0xa3, 0x9d, 0x68,
|
||||||
|
0x33, 0x87, 0x71, 0xa1, 0x2e, 0x7d, 0xe3, 0x7a, 0x4d, 0x67, 0x47, 0x93, 0xc2, 0xc0, 0xe0, 0x3d,
|
||||||
|
0x29, 0x21, 0x1e, 0x74, 0xfb, 0xf8, 0x1e, 0x36, 0xd1, 0x59, 0x2b, 0x4a, 0x77, 0x58, 0x4b, 0x25,
|
||||||
|
0x34, 0x6d, 0xd5, 0xf2, 0x92, 0x13, 0x41, 0xca, 0xc3, 0xa6, 0x55, 0x1e, 0x11, 0x7f, 0xb8, 0xaa,
|
||||||
|
0xb4, 0xc1, 0xef, 0x7c, 0xfb, 0x46, 0xe9, 0xb7, 0xe0, 0xc0, 0x7e, 0xea, 0x86, 0xf9, 0x28, 0x4b,
|
||||||
|
0xf3, 0x57, 0x97, 0xf5, 0xe8, 0x1d, 0x62, 0x60, 0xf0, 0x8e, 0x7a, 0xdc, 0xb1, 0x31, 0xd1, 0x98,
|
||||||
|
0xb7, 0x74, 0x54, 0x57, 0x25, 0xd9, 0xce, 0x43, 0x3c, 0x3e, 0x5f, 0xb6, 0xf8, 0x2d, 0xcd, 0x81,
|
||||||
|
0x10, 0xe4, 0x1d, 0xa1, 0xfd, 0xf5, 0xab, 0x42, 0x1f, 0x4f, 0xea, 0x7b, 0x2a, 0x0b, 0x0b, 0x21,
|
||||||
|
0xf3, 0x00, 0x34, 0x0c, 0x00, 0xde, 0x2f, 0x9e, 0xff, 0x8e, 0x6a, 0x3f, 0x83, 0x73, 0x8b, 0xac,
|
||||||
|
0xbd, 0x1d, 0x6d, 0xb5, 0x8e, 0x54, 0x9d, 0x04, 0x0e, 0x6a, 0x1c, 0x7a, 0xb2, 0xab, 0x57, 0x2e,
|
||||||
|
0xd3, 0x23, 0xab, 0xc2, 0xaf, 0x9f, 0x31, 0x1f, 0x3f, 0x65, 0xf8, 0x87, 0x3d, 0x03, 0x60, 0x3c,
|
||||||
|
0x1f, 0x58, 0x7c, 0x31, 0x00, 0x78, 0x87, 0x3e, 0x09, 0xf6, 0x7d, 0xb3, 0x17, 0x5e, 0x88, 0xc5,
|
||||||
|
0x62, 0xce, 0x5b, 0x0a, 0x3c, 0x0f, 0x23, 0xd2, 0x4b, 0x82, 0x19, 0xbc, 0x43, 0x43, 0xa8, 0xf1,
|
||||||
|
0xfe, 0xf7, 0x9f, 0xf7, 0xcc, 0x46, 0x8f, 0x84, 0x6f, 0xd7, 0xbb, 0xf7, 0x6c, 0x82, 0xd8, 0x29,
|
||||||
|
0x93, 0xdb, 0xab, 0x2a, 0x09, 0x3c, 0xc6, 0xfb, 0x18, 0x00, 0xbc, 0x43, 0x1c, 0x3b, 0x1a, 0x80,
|
||||||
|
0x99, 0x12, 0x54, 0xd6, 0x7d, 0x43, 0x59, 0x0d, 0x1e, 0xc1, 0x44, 0x22, 0xd1, 0x9e, 0x9d, 0x3b,
|
||||||
|
0xd4, 0x4e, 0xba, 0x98, 0x68, 0xf6, 0x19, 0xfa, 0xaa, 0x9a, 0xd2, 0x52, 0xa3, 0x7a, 0x4d, 0x51,
|
||||||
|
0xf2, 0xf6, 0x93, 0xb4, 0xf8, 0x80, 0x30, 0x41, 0xde, 0x93, 0xed, 0x6c, 0x7b, 0x66, 0xe1, 0x77,
|
||||||
|
0x6b, 0x9c, 0x85, 0x07, 0xbc, 0x8f, 0x19, 0xf9, 0x31, 0xe8, 0x62, 0xaa, 0xc5, 0x8f, 0x1d, 0x35,
|
||||||
|
0x02, 0xd5, 0x66, 0xe5, 0xe7, 0x28, 0xfe, 0x25, 0x48, 0x77, 0xed, 0x4d, 0x8d, 0xf7, 0x8a, 0x4b,
|
||||||
|
0x17, 0x7a, 0x56, 0x6e, 0xc7, 0x9b, 0x89, 0x99, 0xcf, 0xca, 0x53, 0x02, 0xf0, 0xee, 0xb8, 0x71,
|
||||||
|
0xbd, 0x1a, 0xef, 0xbb, 0x9c, 0x9d, 0xa4, 0x52, 0xe9, 0x62, 0xfb, 0x05, 0x53, 0xad, 0x7a, 0xdc,
|
||||||
|
0x15, 0x64, 0xef, 0xda, 0x09, 0xa5, 0xbd, 0xdc, 0xe6, 0xa8, 0x83, 0xee, 0x0c, 0x30, 0x35, 0xde,
|
||||||
|
0xb3, 0xb6, 0x6f, 0x81, 0x4c, 0xb1, 0xef, 0xcd, 0x00, 0xbc, 0x3b, 0x39, 0x6e, 0xba, 0xac, 0x5a,
|
||||||
|
0x51, 0x82, 0x08, 0xf4, 0xf7, 0x45, 0xee, 0x5a, 0xb3, 0x5e, 0x66, 0xc2, 0x0b, 0xea, 0x0a, 0x41,
|
||||||
|
0x5b, 0x49, 0x91, 0x96, 0xaa, 0x33, 0xc1, 0xa4, 0x78, 0xef, 0x6e, 0x6e, 0x42, 0x34, 0x35, 0x24,
|
||||||
|
0xc4, 0xb1, 0xa4, 0x54, 0xe3, 0xfd, 0xda, 0x8f, 0x57, 0x6b, 0xdf, 0x3f, 0x2b, 0x1b, 0x21, 0x65,
|
||||||
|
0xe9, 0xa2, 0x48, 0x3d, 0x98, 0x9c, 0x98, 0x14, 0xef, 0x35, 0x77, 0x6e, 0xf5, 0x4c, 0xe2, 0xcf,
|
||||||
|
0x9a, 0x81, 0x23, 0xf3, 0x92, 0x6a, 0x63, 0xe6, 0xa3, 0x88, 0x87, 0xf4, 0x83, 0x47, 0x11, 0xd0,
|
||||||
|
0xe6, 0xd5, 0x6c, 0x97, 0x1d, 0xd8, 0xca, 0x72, 0xc3, 0xa4, 0x78, 0x47, 0x1c, 0xe5, 0xed, 0xc3,
|
||||||
|
0x5a, 0x03, 0x09, 0x3e, 0x16, 0xf4, 0x22, 0x2d, 0x2d, 0x2d, 0xf5, 0x39, 0x4b, 0x1a, 0x78, 0x5c,
|
||||||
|
0x14, 0x9c, 0x3b, 0xc3, 0x54, 0x15, 0x07, 0x26, 0xc5, 0xbb, 0xd0, 0xf7, 0x48, 0xef, 0x4a, 0x08,
|
||||||
|
0xf7, 0xd9, 0xf4, 0x33, 0xa7, 0x4f, 0x81, 0x67, 0x88, 0xb1, 0x27, 0x93, 0x54, 0x94, 0xa1, 0x86,
|
||||||
|
0x9a, 0x71, 0xf0, 0xa5, 0x1d, 0x4c, 0x8a, 0x77, 0xc1, 0x81, 0x7d, 0xec, 0xdd, 0x76, 0x2a, 0x66,
|
||||||
|
0x4d, 0x9f, 0x0a, 0x78, 0xb7, 0x9e, 0xfa, 0x79, 0x2b, 0x2b, 0x9a, 0xab, 0xab, 0x51, 0x9b, 0xd1,
|
||||||
|
0xdd, 0x4c, 0x6c, 0xa6, 0xde, 0xa4, 0x78, 0xcf, 0x73, 0xdb, 0xdb, 0x33, 0x46, 0x3d, 0xa1, 0x71,
|
||||||
|
0x8c, 0x4a, 0x05, 0x8e, 0xbb, 0x10, 0x69, 0x5b, 0x1b, 0xe2, 0x5d, 0xd3, 0x51, 0xa0, 0x5a, 0x60,
|
||||||
|
0x50, 0xf3, 0x8e, 0x03, 0x99, 0x64, 0x88, 0x77, 0x2e, 0xe4, 0xb9, 0x7d, 0xad, 0x07, 0xde, 0x25,
|
||||||
|
0x7d, 0xbc, 0xab, 0x0e, 0x66, 0x24, 0x82, 0x21, 0xde, 0x39, 0x20, 0x6b, 0x1f, 0x50, 0xbc, 0xef,
|
||||||
|
0x77, 0xc5, 0xb5, 0x66, 0xc1, 0x84, 0xf1, 0x78, 0x6f, 0xef, 0xe3, 0x5d, 0xc3, 0xd8, 0x4a, 0x0b,
|
||||||
|
0xe8, 0x85, 0xf7, 0x73, 0xdf, 0x86, 0x1d, 0xd8, 0xe7, 0x1a, 0x1d, 0xf5, 0x94, 0xa0, 0x4c, 0xa3,
|
||||||
|
0xf1, 0xde, 0xd1, 0xc7, 0x7b, 0x67, 0x3f, 0xe7, 0x1d, 0xce, 0xe7, 0x8d, 0xfa, 0xe8, 0x43, 0x82,
|
||||||
|
0x32, 0xf9, 0xf1, 0xae, 0x79, 0xce, 0x9d, 0x2f, 0x64, 0x1d, 0x1d, 0x7d, 0xbc, 0x6b, 0xf6, 0x33,
|
||||||
|
0xcc, 0x17, 0xe4, 0x79, 0x6f, 0x6e, 0x6a, 0x9a, 0x3b, 0x53, 0xe9, 0xb9, 0x65, 0xcc, 0xc8, 0x8f,
|
||||||
|
0xd5, 0xbc, 0x4d, 0xeb, 0x02, 0xa3, 0xf1, 0xde, 0x39, 0x40, 0x78, 0x5f, 0xba, 0xd0, 0xee, 0xf5,
|
||||||
|
0xab, 0x0a, 0xa9, 0x54, 0x1a, 0xf5, 0x34, 0x12, 0x9e, 0xa8, 0x19, 0x13, 0x1d, 0xf5, 0xe7, 0xbd,
|
||||||
|
0x3f, 0xea, 0xeb, 0xeb, 0x6e, 0xde, 0x08, 0xef, 0xec, 0x54, 0x5a, 0x9e, 0xfe, 0xfa, 0xcb, 0x8d,
|
||||||
|
0xf4, 0x17, 0x2f, 0x5a, 0x5a, 0x5a, 0x9a, 0x9b, 0x9b, 0x3b, 0xda, 0xdb, 0x9b, 0x1a, 0x1b, 0x39,
|
||||||
|
0xc5, 0x1a, 0x8b, 0x77, 0x79, 0x67, 0x67, 0x1f, 0xef, 0xd8, 0xc7, 0x3c, 0x71, 0x42, 0x2f, 0x7e,
|
||||||
|
0xdd, 0x02, 0x03, 0xfc, 0x60, 0x80, 0x15, 0xce, 0x62, 0xfb, 0x05, 0x8a, 0xde, 0xca, 0x47, 0x69,
|
||||||
|
0xd2, 0xff, 0xcf, 0x03, 0x70, 0xe1, 0xeb, 0xa5, 0x9c, 0xa7, 0x9d, 0x3e, 0xd9, 0xd2, 0x1a, 0xcf,
|
||||||
|
0xd7, 0x23, 0x16, 0xef, 0xfb, 0xf4, 0xc0, 0x7b, 0xd7, 0x40, 0xe0, 0xfd, 0xe1, 0x83, 0xfb, 0x7b,
|
||||||
|
0x5d, 0x9c, 0xd1, 0xcf, 0x35, 0xab, 0x96, 0xdf, 0xb9, 0x7d, 0x8b, 0xca, 0xbb, 0xbd, 0xed, 0x3c,
|
||||||
|
0x90, 0x20, 0x21, 0x4e, 0x79, 0x2e, 0xae, 0x42, 0xe5, 0x58, 0x6f, 0x93, 0xc3, 0x3a, 0x1c, 0xc9,
|
||||||
|
0xc6, 0xe3, 0xbd, 0x6b, 0x00, 0xf0, 0x3e, 0x72, 0xf8, 0x07, 0x54, 0x4f, 0xf6, 0x12, 0x49, 0x1b,
|
||||||
|
0xa0, 0x5b, 0x8d, 0xf7, 0x1b, 0x3f, 0x5f, 0xff, 0x6a, 0xc5, 0xd2, 0xa3, 0x7e, 0x3e, 0xa5, 0x25,
|
||||||
|
0x25, 0xb9, 0x39, 0x39, 0x05, 0xf9, 0x02, 0x61, 0x61, 0x01, 0xa7, 0x64, 0xa3, 0xf1, 0xde, 0x4d,
|
||||||
|
0xe1, 0x9d, 0x90, 0xa3, 0x05, 0x85, 0xa9, 0x8d, 0x9b, 0xf4, 0xc2, 0x7b, 0xf7, 0x10, 0xef, 0x1c,
|
||||||
|
0xd0, 0x0b, 0xef, 0xd2, 0x3e, 0xde, 0x3b, 0xde, 0xd4, 0x90, 0x12, 0x3b, 0xc4, 0x3b, 0x07, 0xe4,
|
||||||
|
0x52, 0xe9, 0x10, 0xef, 0x1c, 0x60, 0xe4, 0x1d, 0xf4, 0x62, 0xf3, 0x05, 0x1a, 0x0d, 0x0b, 0x18,
|
||||||
|
0x71, 0x2a, 0x84, 0xe2, 0xaf, 0x45, 0x46, 0xe1, 0xbd, 0x86, 0xbf, 0x61, 0xac, 0x06, 0x98, 0x18,
|
||||||
|
0xef, 0xdf, 0x50, 0x79, 0xaf, 0xaa, 0xaa, 0x84, 0x2e, 0x4f, 0xf8, 0xf2, 0x0e, 0x4d, 0x68, 0x40,
|
||||||
|
0xdf, 0x4c, 0xf9, 0x43, 0x26, 0x1b, 0xe2, 0x9d, 0x03, 0x14, 0xde, 0x03, 0x2d, 0x27, 0x98, 0x21,
|
||||||
|
0xe3, 0xaf, 0xef, 0xcf, 0x9f, 0xd3, 0x74, 0x58, 0x3d, 0xcb, 0x09, 0xf6, 0x30, 0x14, 0x0b, 0x0b,
|
||||||
|
0xfb, 0x78, 0x27, 0x77, 0x9a, 0x99, 0xa9, 0xf2, 0x1e, 0x04, 0xaa, 0x17, 0xc4, 0x9d, 0x76, 0xe5,
|
||||||
|
0x1d, 0x84, 0x90, 0x13, 0xc7, 0x15, 0x72, 0x39, 0xe2, 0x9d, 0xa0, 0xa1, 0xa4, 0xc9, 0xf2, 0x0e,
|
||||||
|
0x63, 0x40, 0x49, 0xd7, 0x8e, 0x77, 0xaa, 0x53, 0xc9, 0x98, 0xc9, 0x96, 0x50, 0x6c, 0x2b, 0xb9,
|
||||||
|
0x5d, 0xaf, 0xa6, 0xca, 0x7b, 0x20, 0x35, 0xbe, 0x9e, 0xb6, 0x3e, 0xe7, 0xe7, 0x7d, 0x64, 0x81,
|
||||||
|
0xcd, 0xec, 0x0d, 0x6b, 0xbf, 0xb2, 0x32, 0x67, 0x38, 0x9e, 0x5a, 0x2e, 0x7f, 0xcf, 0x6e, 0x20,
|
||||||
|
0x71, 0xde, 0x5c, 0x28, 0x56, 0xf4, 0xf0, 0x01, 0x6f, 0xbd, 0x35, 0x60, 0x50, 0xf0, 0x4e, 0x07,
|
||||||
|
0x28, 0xd1, 0x70, 0x5c, 0xfd, 0xf4, 0xdf, 0x27, 0x9c, 0x62, 0xb3, 0x9c, 0xb6, 0xe0, 0x9b, 0x29,
|
||||||
|
0x60, 0x62, 0x90, 0xf2, 0x5e, 0x5b, 0xab, 0xb4, 0x07, 0x06, 0xec, 0x7b, 0x1e, 0x3a, 0xc0, 0x29,
|
||||||
|
0x16, 0x99, 0x43, 0x65, 0x6e, 0xdd, 0x8c, 0xa9, 0x2d, 0x27, 0x06, 0x29, 0xef, 0x11, 0x0f, 0xff,
|
||||||
|
0x81, 0x17, 0x8b, 0xed, 0x17, 0x54, 0x94, 0x97, 0xb3, 0x27, 0x6e, 0x48, 0x4e, 0x44, 0x4d, 0xab,
|
||||||
|
0xa4, 0xa2, 0x0c, 0x4b, 0x5d, 0x2e, 0x0c, 0x18, 0xde, 0x8f, 0x07, 0x72, 0x9b, 0x85, 0xe2, 0xf3,
|
||||||
|
0x3e, 0x7f, 0xce, 0x4c, 0x7f, 0x1f, 0xaf, 0xa8, 0xa7, 0x91, 0x98, 0x1b, 0x77, 0x9e, 0xfd, 0xb7,
|
||||||
|
0xc7, 0x3b, 0x54, 0x51, 0x00, 0x99, 0x23, 0x9c, 0x06, 0x29, 0xef, 0x0a, 0xd5, 0xba, 0x18, 0x67,
|
||||||
|
0x49, 0x47, 0x28, 0x3b, 0x75, 0x02, 0x15, 0xf9, 0xe6, 0xf4, 0x34, 0xcc, 0xbb, 0x58, 0x30, 0x78,
|
||||||
|
0x79, 0xe7, 0x07, 0xb9, 0x0c, 0x39, 0x44, 0x4b, 0x5d, 0xbe, 0x44, 0xde, 0xad, 0xeb, 0xfa, 0xa5,
|
||||||
|
0x69, 0xf1, 0xbe, 0xbf, 0x97, 0x77, 0xa2, 0xb6, 0xea, 0x10, 0x35, 0x77, 0x6e, 0xa3, 0x22, 0x2f,
|
||||||
|
0x70, 0x77, 0x53, 0xc8, 0x75, 0xb2, 0x51, 0x1d, 0x00, 0xbc, 0x8f, 0x1e, 0x31, 0x9c, 0x3a, 0x70,
|
||||||
|
0x17, 0x89, 0x34, 0x1a, 0x53, 0xe8, 0x95, 0x77, 0x05, 0xa5, 0x63, 0x03, 0x42, 0xee, 0xd7, 0xbb,
|
||||||
|
0xa4, 0x62, 0xed, 0x7d, 0x76, 0x0c, 0x00, 0xde, 0xc1, 0xa8, 0x07, 0x91, 0x3e, 0x7d, 0xb2, 0x25,
|
||||||
|
0x4b, 0x4a, 0x7d, 0xf3, 0xae, 0xa0, 0x9c, 0x09, 0x0a, 0x42, 0xc2, 0xdc, 0xd9, 0xd5, 0xbf, 0x84,
|
||||||
|
0x6b, 0x27, 0x67, 0x00, 0xf0, 0x0e, 0x60, 0x3d, 0x75, 0x32, 0xe4, 0x9d, 0x7a, 0x3c, 0x30, 0x1d,
|
||||||
|
0x02, 0xfd, 0xf3, 0x0e, 0x20, 0xf4, 0x39, 0x82, 0xa8, 0x87, 0x9d, 0xfa, 0xca, 0xf0, 0x6b, 0x0a,
|
||||||
|
0x99, 0x94, 0xfb, 0x4e, 0x0a, 0x86, 0x55, 0xdd, 0xbc, 0x81, 0x15, 0x6e, 0x5c, 0xaf, 0x0a, 0xbf,
|
||||||
|
0x86, 0x13, 0xde, 0xfe, 0xef, 0xf7, 0x86, 0xc4, 0x78, 0x82, 0xa6, 0x26, 0x0a, 0xd5, 0xc0, 0x1d,
|
||||||
|
0x90, 0xbe, 0x69, 0xfd, 0x5a, 0xf6, 0x64, 0x86, 0xe1, 0x5d, 0xa1, 0xf2, 0xfc, 0x4e, 0x75, 0x66,
|
||||||
|
0x00, 0x42, 0xb4, 0xd5, 0xc4, 0x97, 0xdb, 0x1c, 0x41, 0x2f, 0x13, 0xd4, 0x45, 0xa0, 0x55, 0x67,
|
||||||
|
0x0f, 0x8d, 0x29, 0xc9, 0xc3, 0x5e, 0xac, 0xfb, 0x8a, 0x7a, 0x3f, 0xc1, 0x90, 0x68, 0x33, 0xbb,
|
||||||
|
0xd0, 0xdb, 0x53, 0xf4, 0xf0, 0x3e, 0x91, 0x47, 0xdd, 0xba, 0x69, 0x03, 0x67, 0x1a, 0x83, 0xf1,
|
||||||
|
0xae, 0x50, 0x9d, 0x9d, 0x93, 0xb3, 0x1b, 0xcb, 0xb7, 0x0a, 0x3d, 0xd4, 0xc7, 0xc5, 0xe8, 0x91,
|
||||||
|
0x77, 0x14, 0x52, 0x96, 0x2c, 0x2c, 0x0c, 0x3b, 0x95, 0x9b, 0x93, 0xa3, 0xef, 0x90, 0xd3, 0x6b,
|
||||||
|
0xff, 0x2e, 0x0c, 0xf2, 0x67, 0x4f, 0x79, 0xe6, 0x74, 0x28, 0x91, 0x1c, 0x0b, 0x7e, 0xff, 0x2d,
|
||||||
|
0xdf, 0xeb, 0x70, 0xcc, 0x64, 0x2b, 0xde, 0xbc, 0xe7, 0xec, 0xd9, 0x49, 0xf2, 0xb0, 0x83, 0x55,
|
||||||
|
0xcb, 0x01, 0xcb, 0x09, 0xb3, 0x67, 0xd0, 0x33, 0x03, 0xa5, 0x83, 0xe0, 0x7a, 0x3c, 0x23, 0x30,
|
||||||
|
0xcb, 0xbb, 0x58, 0x2c, 0xe6, 0x7b, 0x82, 0x19, 0x07, 0xe4, 0x72, 0x50, 0xb5, 0x96, 0x84, 0x04,
|
||||||
|
0x17, 0xf9, 0xfb, 0x14, 0x1e, 0x39, 0xc4, 0x7e, 0xd8, 0x01, 0x08, 0x4a, 0xde, 0x49, 0x66, 0x4f,
|
||||||
|
0x41, 0x57, 0x43, 0x7d, 0x65, 0xf8, 0x75, 0x34, 0x90, 0x81, 0x21, 0x76, 0xda, 0x14, 0x51, 0x04,
|
||||||
|
0xb1, 0xa9, 0x54, 0x3a, 0x30, 0x79, 0x87, 0xce, 0x1f, 0x36, 0xac, 0xfd, 0x4a, 0x7f, 0x9a, 0x70,
|
||||||
|
0x42, 0xef, 0xfd, 0x99, 0x56, 0x61, 0x81, 0xe0, 0x80, 0x1b, 0xa2, 0x3e, 0xca, 0x7c, 0x7c, 0xcd,
|
||||||
|
0x6f, 0xb7, 0xb8, 0x6f, 0xd3, 0x0a, 0x38, 0xbc, 0xe7, 0x0b, 0x04, 0xa8, 0x57, 0xca, 0xde, 0x3b,
|
||||||
|
0xd2, 0x2b, 0x0c, 0xd4, 0x8f, 0x2c, 0xff, 0xf6, 0x34, 0xf2, 0xa6, 0x16, 0x6d, 0x39, 0xb1, 0x29,
|
||||||
|
0x35, 0x45, 0x1f, 0xb9, 0x08, 0xf6, 0xbb, 0x72, 0xf2, 0x4e, 0x1d, 0x82, 0x4d, 0x9b, 0x64, 0xa1,
|
||||||
|
0x0f, 0x35, 0x70, 0x60, 0xb8, 0xfe, 0xfb, 0xbb, 0x07, 0x7f, 0x21, 0xcf, 0x22, 0x29, 0x0b, 0xed,
|
||||||
|
0xe4, 0x9d, 0xc4, 0xdc, 0xed, 0x23, 0xe0, 0xf0, 0x0e, 0x61, 0x3b, 0x77, 0x16, 0xf1, 0xdc, 0x79,
|
||||||
|
0xc1, 0xa0, 0xe3, 0xa6, 0xea, 0x5b, 0xbf, 0xa0, 0x0a, 0x07, 0x67, 0x6b, 0x2f, 0x5f, 0x0c, 0xf1,
|
||||||
|
0xae, 0x11, 0xc8, 0x45, 0x3b, 0x18, 0x77, 0x90, 0x5a, 0x43, 0x40, 0x18, 0xe2, 0x5d, 0x33, 0x64,
|
||||||
|
0xb2, 0xa4, 0x2f, 0xe7, 0x43, 0x76, 0x48, 0xad, 0x21, 0x20, 0x0c, 0xf1, 0xce, 0x86, 0xb2, 0xb0,
|
||||||
|
0x10, 0xd4, 0xad, 0x54, 0x10, 0xed, 0x51, 0x0c, 0xf1, 0xce, 0x06, 0x59, 0x47, 0x7b, 0xb4, 0x55,
|
||||||
|
0x4f, 0x03, 0x2b, 0x7a, 0x1c, 0x41, 0x50, 0xf2, 0x10, 0xef, 0x1c, 0xc8, 0xd9, 0xe3, 0xa2, 0x8f,
|
||||||
|
0xd6, 0x55, 0xe0, 0x3e, 0xc4, 0x3b, 0x2b, 0xf8, 0x3a, 0x8a, 0xc1, 0x84, 0x8e, 0xbc, 0xaf, 0x59,
|
||||||
|
0xb5, 0x9c, 0xf0, 0xfc, 0x81, 0x66, 0x18, 0x87, 0xf7, 0xca, 0x6b, 0x3d, 0xae, 0x06, 0x53, 0x57,
|
||||||
|
0x2c, 0x23, 0x28, 0x56, 0x47, 0xde, 0x01, 0xe9, 0x2b, 0x97, 0x2e, 0x6e, 0xa8, 0xaf, 0x27, 0xa8,
|
||||||
|
0x92, 0x26, 0x18, 0x87, 0xf7, 0x77, 0x0f, 0xfe, 0x86, 0x04, 0x25, 0xdb, 0x7f, 0x49, 0x50, 0xac,
|
||||||
|
0x2e, 0xbc, 0x47, 0x45, 0xfe, 0xeb, 0xeb, 0xe5, 0x59, 0x5b, 0x2b, 0x9a, 0x33, 0xe3, 0x0b, 0x82,
|
||||||
|
0x2a, 0x69, 0x82, 0x71, 0x78, 0x47, 0x96, 0x40, 0x09, 0x73, 0x48, 0xd6, 0xb3, 0xd9, 0x2e, 0x3b,
|
||||||
|
0xa0, 0xd8, 0xd2, 0xd3, 0x27, 0xd9, 0x53, 0xd2, 0x79, 0x1f, 0x3d, 0x62, 0x38, 0xbc, 0xd0, 0x54,
|
||||||
|
0xd5, 0x50, 0x3d, 0x7c, 0xea, 0x0e, 0xe3, 0xf0, 0x8e, 0x0e, 0xd2, 0x8b, 0x9a, 0x38, 0x41, 0xc7,
|
||||||
|
0x85, 0x79, 0x2a, 0x9e, 0x2f, 0x5b, 0x0c, 0xc5, 0xbe, 0xfe, 0xf1, 0x0a, 0x7b, 0x4a, 0x3a, 0xef,
|
||||||
|
0xd4, 0x79, 0x9b, 0x33, 0xa7, 0x94, 0x2e, 0xe0, 0x6d, 0x66, 0x59, 0x07, 0x06, 0xf8, 0xed, 0xd9,
|
||||||
|
0xb9, 0x63, 0xdf, 0x37, 0x7b, 0xbb, 0xbb, 0xbb, 0xe7, 0xce, 0xfc, 0xe2, 0xdc, 0x99, 0x30, 0x27,
|
||||||
|
0xc7, 0x4d, 0x96, 0x13, 0xcc, 0x74, 0x57, 0xd5, 0x38, 0xbc, 0xcb, 0xa5, 0xdd, 0xe8, 0xf8, 0x0e,
|
||||||
|
0x62, 0x9e, 0xd6, 0x65, 0x32, 0xd4, 0x3d, 0x6d, 0xce, 0x4c, 0x67, 0x4f, 0xab, 0xc6, 0xbb, 0xe7,
|
||||||
|
0xa1, 0x03, 0x7f, 0xdc, 0xbd, 0x83, 0x7e, 0xc2, 0x22, 0xef, 0xba, 0x77, 0xb7, 0x42, 0xb5, 0xb5,
|
||||||
|
0x1c, 0xfc, 0x2d, 0x12, 0x16, 0x42, 0xde, 0xc1, 0xf5, 0xad, 0x9b, 0x58, 0xc7, 0xed, 0xb0, 0xc3,
|
||||||
|
0x68, 0xeb, 0xda, 0xa9, 0x2b, 0x97, 0xf5, 0xd4, 0xc5, 0x27, 0x8e, 0x11, 0x11, 0x58, 0x17, 0x15,
|
||||||
|
0xd9, 0x33, 0xdf, 0x69, 0x65, 0xc1, 0x39, 0x1c, 0x53, 0xe3, 0x5d, 0xad, 0x6e, 0x31, 0xfb, 0xf4,
|
||||||
|
0x93, 0xd2, 0x92, 0x92, 0x43, 0xee, 0xfb, 0x14, 0xbd, 0x2c, 0x9b, 0x0e, 0xef, 0xe8, 0x18, 0x82,
|
||||||
|
0x17, 0x5f, 0xad, 0x24, 0x22, 0x50, 0xe8, 0xeb, 0x05, 0x05, 0x66, 0x53, 0x36, 0x8c, 0x6b, 0xc2,
|
||||||
|
0x20, 0xed, 0xbf, 0x03, 0xb4, 0xe4, 0x66, 0xa3, 0xb9, 0x49, 0x51, 0xc4, 0x3f, 0x3a, 0x4a, 0xeb,
|
||||||
|
0x7c, 0xf7, 0x16, 0xcd, 0xef, 0xbf, 0xba, 0x72, 0x91, 0x33, 0xfd, 0xe0, 0xe5, 0x1d, 0x20, 0x7b,
|
||||||
|
0xe7, 0xf6, 0x9e, 0x22, 0xbf, 0x4e, 0xd7, 0x25, 0x37, 0x74, 0x54, 0x9c, 0xb2, 0x83, 0x24, 0xe7,
|
||||||
|
0x9e, 0xf3, 0x19, 0xd4, 0xbc, 0xd7, 0x3e, 0x8e, 0xe8, 0x9b, 0x8e, 0xd7, 0x61, 0x2b, 0xc5, 0xeb,
|
||||||
|
0x1f, 0x2e, 0x23, 0x39, 0xa5, 0x27, 0xb9, 0x0f, 0x45, 0x54, 0x0c, 0x72, 0xde, 0x15, 0x4a, 0xdb,
|
||||||
|
0xab, 0xbe, 0xf3, 0x34, 0x2a, 0xce, 0x9f, 0xd5, 0x42, 0x42, 0x7d, 0x42, 0x1c, 0x5a, 0xc6, 0x4a,
|
||||||
|
0xc7, 0x73, 0xed, 0xa1, 0x18, 0xe2, 0x5d, 0xde, 0xd9, 0x99, 0xb2, 0xc8, 0x1e, 0x51, 0x5f, 0x76,
|
||||||
|
0x9a, 0xdf, 0x39, 0x26, 0x6f, 0xff, 0xba, 0x87, 0x36, 0xdb, 0x81, 0x6e, 0x4c, 0x5b, 0x91, 0x90,
|
||||||
|
0xf3, 0x16, 0x6a, 0x3f, 0x9d, 0xac, 0x27, 0x2e, 0x5e, 0x30, 0xbe, 0x7d, 0x64, 0x5b, 0x71, 0x51,
|
||||||
|
0xdc, 0xf4, 0xa9, 0x88, 0x7a, 0xd0, 0x2d, 0x91, 0x62, 0x9c, 0xe0, 0x01, 0x46, 0x5b, 0xc5, 0xc7,
|
||||||
|
0x02, 0xd0, 0x5d, 0x4f, 0xc7, 0x9b, 0xd5, 0xdc, 0xfe, 0x15, 0x27, 0x3b, 0x30, 0xec, 0x44, 0xbc,
|
||||||
|
0x93, 0x3d, 0xba, 0x99, 0x17, 0x8c, 0xcf, 0x3b, 0x40, 0x73, 0x66, 0x46, 0xfc, 0x2c, 0x6b, 0xaa,
|
||||||
|
0x99, 0x0d, 0xe0, 0x54, 0x93, 0x91, 0x93, 0xac, 0x5d, 0x52, 0x76, 0x26, 0x14, 0x1d, 0x26, 0x01,
|
||||||
|
0x6d, 0x43, 0x2a, 0xaf, 0xf3, 0x38, 0x75, 0x06, 0x92, 0x8e, 0x0e, 0x35, 0x30, 0x0a, 0xfa, 0x05,
|
||||||
|
0xef, 0x00, 0x1d, 0x35, 0xd5, 0x68, 0xbb, 0x22, 0x0a, 0xa0, 0x9f, 0x03, 0xba, 0xf9, 0xa5, 0xa7,
|
||||||
|
0x43, 0x2a, 0x2e, 0x5d, 0x28, 0x0b, 0x0b, 0x29, 0x3e, 0xea, 0x9b, 0xb5, 0x63, 0x5b, 0x94, 0xa5,
|
||||||
|
0x39, 0x35, 0x4d, 0x92, 0xad, 0x4d, 0x7d, 0x7c, 0x2c, 0xaf, 0xbc, 0x04, 0x79, 0x79, 0x80, 0x77,
|
||||||
|
0xa9, 0x94, 0x9f, 0x05, 0x2f, 0x59, 0xf4, 0x17, 0xde, 0x21, 0x4a, 0x82, 0x03, 0xa3, 0x27, 0x59,
|
||||||
|
0xaa, 0xb1, 0xaf, 0x29, 0x80, 0xba, 0x05, 0xbc, 0x09, 0x59, 0x47, 0x87, 0x16, 0x19, 0xe1, 0x58,
|
||||||
|
0xb9, 0xea, 0x15, 0xfd, 0x8b, 0x77, 0x00, 0x50, 0xb9, 0x17, 0x07, 0xfa, 0x51, 0xab, 0x11, 0x7a,
|
||||||
|
0x88, 0xb3, 0x9e, 0x2e, 0x0c, 0xf0, 0xa9, 0xcb, 0x17, 0xe8, 0xef, 0xf0, 0x55, 0x89, 0x44, 0xa2,
|
||||||
|
0xd7, 0xc7, 0xec, 0x77, 0xbc, 0x23, 0xb4, 0x64, 0xbf, 0x2c, 0x3d, 0x79, 0x4c, 0xe8, 0xe7, 0x95,
|
||||||
|
0xbd, 0xdb, 0x39, 0xdd, 0x61, 0x6d, 0xd6, 0xce, 0xed, 0x85, 0x5e, 0x87, 0x41, 0xbd, 0xaf, 0x3c,
|
||||||
|
0xb8, 0x83, 0xdc, 0x14, 0xa6, 0xb1, 0xd0, 0x7f, 0x79, 0x1f, 0x82, 0xee, 0x00, 0x95, 0x70, 0xab,
|
||||||
|
0xb0, 0xe0, 0xdd, 0xfd, 0xbf, 0x4a, 0x4f, 0x9f, 0x04, 0xb5, 0x88, 0xd0, 0xdf, 0x27, 0xff, 0xe0,
|
||||||
|
0xbe, 0xdc, 0xbd, 0xbb, 0x40, 0x33, 0x99, 0xb1, 0xd1, 0x21, 0xc3, 0x71, 0x03, 0x28, 0xcd, 0xb9,
|
||||||
|
0xae, 0x7b, 0x0a, 0x3c, 0x0f, 0x81, 0x1a, 0x1b, 0x0c, 0x5d, 0x2b, 0x2e, 0x9c, 0xad, 0x8f, 0x89,
|
||||||
|
0x6a, 0x7f, 0xfd, 0x8a, 0xac, 0x9d, 0x47, 0xff, 0xc1, 0x50, 0x71, 0x67, 0x86, 0x5c, 0x2e, 0x97,
|
||||||
|
0x0e, 0x40, 0x74, 0xb7, 0x4b, 0xea, 0xe2, 0x63, 0x41, 0xef, 0x24, 0xdf, 0xe3, 0x40, 0xca, 0xe2,
|
||||||
|
0x85, 0x51, 0x16, 0xe6, 0x98, 0x7d, 0x14, 0xb5, 0x10, 0x33, 0x65, 0x52, 0xfa, 0xfa, 0x35, 0x42,
|
||||||
|
0x7f, 0xef, 0xf2, 0xb3, 0xa7, 0x5b, 0x0b, 0x89, 0x39, 0x7f, 0x31, 0x3a, 0x86, 0x8a, 0x3b, 0x79,
|
||||||
|
0x78, 0x1c, 0x74, 0x0f, 0x3d, 0x19, 0x6c, 0xc8, 0x1c, 0xdb, 0x2b, 0x5f, 0x83, 0x91, 0xa4, 0xc0,
|
||||||
|
0xdd, 0x2d, 0xee, 0x8b, 0xa9, 0xda, 0x95, 0x6f, 0xf6, 0x90, 0xb4, 0x60, 0x3e, 0xe8, 0xde, 0x54,
|
||||||
|
0x85, 0x5f, 0x27, 0x78, 0xae, 0x8c, 0x51, 0x30, 0x54, 0xdc, 0x09, 0x63, 0xcb, 0x26, 0x07, 0x38,
|
||||||
|
0x09, 0x71, 0x60, 0x9f, 0xab, 0xbe, 0xf3, 0x02, 0x03, 0x9d, 0x57, 0x97, 0x2e, 0x08, 0xdc, 0x5d,
|
||||||
|
0xa3, 0xad, 0x2c, 0x58, 0xc7, 0x3a, 0xd3, 0x52, 0x57, 0x2c, 0x15, 0x1c, 0x70, 0xeb, 0xd9, 0xe3,
|
||||||
|
0x19, 0x72, 0xbc, 0xec, 0xdb, 0x53, 0x15, 0x17, 0xbf, 0xcb, 0x50, 0x4d, 0x04, 0x94, 0x9c, 0x08,
|
||||||
|
0x52, 0xf6, 0x73, 0x40, 0x67, 0x7d, 0xd7, 0xce, 0x67, 0x0b, 0xed, 0xd8, 0x07, 0xad, 0xf1, 0x33,
|
||||||
|
0xad, 0x41, 0x4a, 0xd0, 0x3b, 0xe2, 0xbb, 0x59, 0xb7, 0x9f, 0x60, 0xa8, 0xb8, 0x13, 0x03, 0xe8,
|
||||||
|
0xff, 0x2c, 0xb2, 0xb3, 0xa5, 0xce, 0x31, 0x73, 0x6e, 0x72, 0xd6, 0x1a, 0xed, 0x55, 0x95, 0x60,
|
||||||
|
0xf8, 0x98, 0xb2, 0xe8, 0xbf, 0x8c, 0x85, 0x12, 0x94, 0xfe, 0x8c, 0x8d, 0xeb, 0x41, 0x21, 0xae,
|
||||||
|
0xb9, 0x7d, 0x93, 0x65, 0x83, 0xc1, 0x0f, 0x57, 0xaf, 0xd0, 0x0f, 0x45, 0x90, 0x77, 0x77, 0xb5,
|
||||||
|
0xe4, 0x64, 0x55, 0x5c, 0x3c, 0x5f, 0xe4, 0xef, 0xfd, 0x7c, 0xd9, 0x62, 0x64, 0xf2, 0xa1, 0x36,
|
||||||
|
0x3b, 0x93, 0xb5, 0x7d, 0x6b, 0xf9, 0xb9, 0x30, 0x69, 0x6b, 0xab, 0x9e, 0x1e, 0x50, 0x4f, 0x18,
|
||||||
|
0x2a, 0xee, 0x64, 0xd0, 0xd1, 0xde, 0x8e, 0xfc, 0x27, 0x50, 0x83, 0xbd, 0xed, 0x3c, 0xb2, 0x1b,
|
||||||
|
0x06, 0xbb, 0x1a, 0xea, 0x8b, 0x8f, 0x1f, 0x4d, 0xee, 0xdd, 0xb6, 0xf1, 0x5e, 0x87, 0x7b, 0xb2,
|
||||||
|
0x55, 0xfe, 0xa1, 0xfd, 0x15, 0xe7, 0xcf, 0x62, 0xba, 0xa8, 0xbf, 0x7a, 0xe5, 0x72, 0x37, 0xd7,
|
||||||
|
0x19, 0x20, 0xe2, 0xfc, 0xbc, 0x92, 0xe0, 0xa0, 0x2c, 0xa7, 0x2d, 0xa8, 0xdc, 0x3f, 0x36, 0x1b,
|
||||||
|
0xf3, 0xc4, 0x6c, 0x0c, 0xbc, 0xce, 0x74, 0xdc, 0x58, 0x71, 0xe1, 0x9c, 0xee, 0x8e, 0x78, 0x0c,
|
||||||
|
0x86, 0xa1, 0xe2, 0x4e, 0x00, 0xf5, 0xf5, 0x75, 0xe6, 0x63, 0x47, 0xd3, 0xcb, 0x3a, 0xf2, 0xda,
|
||||||
|
0x22, 0x91, 0xb4, 0x11, 0xc9, 0xa8, 0x2a, 0xfc, 0xda, 0xcb, 0x6d, 0x8e, 0xf4, 0x82, 0x9e, 0xb2,
|
||||||
|
0xd0, 0x1e, 0x54, 0xf6, 0x92, 0xb2, 0x52, 0x5e, 0xd2, 0x94, 0xc5, 0x9d, 0x72, 0x3c, 0x02, 0x23,
|
||||||
|
0xda, 0x25, 0x92, 0xc7, 0x8f, 0x22, 0x5c, 0xf7, 0xee, 0x1e, 0xff, 0xe9, 0x27, 0xf0, 0x71, 0x56,
|
||||||
|
0x8c, 0x18, 0xfe, 0x5e, 0x4d, 0x3f, 0x61, 0x5c, 0x81, 0xe7, 0xc1, 0x86, 0xc4, 0x78, 0x1d, 0x1e,
|
||||||
|
0xcb, 0x70, 0x18, 0x2a, 0xee, 0xe4, 0x71, 0xec, 0x68, 0xc0, 0x65, 0xd5, 0x11, 0xc6, 0x04, 0xd1,
|
||||||
|
0xdd, 0xd8, 0x50, 0x1c, 0xe4, 0x1f, 0x3b, 0x6d, 0x8a, 0x5a, 0x41, 0x4f, 0xb6, 0xb3, 0x2d, 0x39,
|
||||||
|
0x1e, 0x08, 0xaa, 0x7c, 0x4c, 0x39, 0x62, 0xb1, 0xd8, 0xdb, 0xd3, 0x23, 0xf2, 0xc9, 0xe3, 0xa4,
|
||||||
|
0x84, 0xf8, 0xb9, 0x33, 0xad, 0x37, 0xae, 0x5f, 0x9b, 0x18, 0xaf, 0x7e, 0x12, 0x76, 0x79, 0x59,
|
||||||
|
0x99, 0xc5, 0xb8, 0x31, 0x9a, 0xbe, 0xde, 0x27, 0xae, 0x7b, 0x18, 0xd4, 0xb0, 0x5f, 0xa0, 0x34,
|
||||||
|
0x46, 0xe8, 0xf7, 0x1d, 0xfa, 0xa1, 0xe2, 0x4e, 0x1e, 0xc4, 0x8b, 0x7b, 0x5b, 0x71, 0x91, 0xd0,
|
||||||
|
0xf7, 0x88, 0x5a, 0x37, 0x3a, 0xca, 0xc2, 0x5c, 0xe8, 0xeb, 0x25, 0xce, 0xcb, 0xe5, 0x25, 0x4a,
|
||||||
|
0x24, 0x12, 0xc1, 0x52, 0xeb, 0xf6, 0xf5, 0x9e, 0x53, 0x21, 0x27, 0x9f, 0x25, 0x27, 0xfd, 0x7f,
|
||||||
|
0x7b, 0x67, 0xe2, 0xd5, 0xc4, 0xb5, 0x06, 0xf0, 0xf7, 0x5f, 0xb4, 0xa7, 0x9e, 0x67, 0x6b, 0x6d,
|
||||||
|
0xd5, 0x08, 0x22, 0x28, 0x22, 0x22, 0x8a, 0x88, 0x28, 0x22, 0xd5, 0xd7, 0xba, 0x80, 0xa2, 0xd6,
|
||||||
|
0xdd, 0xa2, 0x80, 0x82, 0x82, 0x10, 0x08, 0x61, 0x71, 0x17, 0xc5, 0x15, 0x50, 0x5a, 0xdc, 0xb1,
|
||||||
|
0xd6, 0x56, 0xc5, 0xad, 0x56, 0xb6, 0x10, 0x90, 0xdd, 0x05, 0x42, 0x02, 0x24, 0x10, 0x56, 0x45,
|
||||||
|
0x40, 0x90, 0x35, 0x10, 0x48, 0xe0, 0x7d, 0x71, 0x34, 0x0d, 0x93, 0x41, 0x43, 0xe6, 0x4e, 0x12,
|
||||||
|
0xc8, 0xfc, 0xce, 0x3d, 0x9e, 0x6c, 0xde, 0xf9, 0xa2, 0xbf, 0xb9, 0xb9, 0x77, 0xe6, 0xde, 0xfb,
|
||||||
|
0x75, 0x0e, 0xd1, 0xff, 0xe6, 0x15, 0x15, 0x5a, 0x4c, 0x99, 0x8c, 0x73, 0xdd, 0x63, 0xab, 0x22,
|
||||||
|
0xb9, 0x38, 0x0c, 0x55, 0x8b, 0xbd, 0x76, 0xe0, 0x8c, 0x4f, 0xb3, 0xb4, 0x80, 0x13, 0xd2, 0xc0,
|
||||||
|
0x2f, 0xdd, 0xd0, 0xba, 0xa3, 0x07, 0xad, 0xee, 0x5d, 0xe5, 0x22, 0x65, 0xba, 0x70, 0x65, 0xc9,
|
||||||
|
0xb0, 0xb3, 0x2d, 0x3f, 0x18, 0xd1, 0x3f, 0xfc, 0xec, 0x7b, 0x98, 0xee, 0xd8, 0x2c, 0xb9, 0xd8,
|
||||||
|
0x98, 0x68, 0xd9, 0xd0, 0x73, 0x29, 0xa4, 0x52, 0xe9, 0xda, 0xd5, 0xae, 0xe0, 0xf7, 0x3c, 0xdb,
|
||||||
|
0x59, 0x4a, 0xdd, 0x85, 0x1f, 0x27, 0x84, 0x49, 0x1b, 0x1b, 0x44, 0xa1, 0xc1, 0xb8, 0xcb, 0x38,
|
||||||
|
0xf0, 0x14, 0xc6, 0xc7, 0x1a, 0xcd, 0x7a, 0xd2, 0x13, 0xb4, 0xee, 0xe8, 0x41, 0xa8, 0x3b, 0xf4,
|
||||||
|
0x61, 0x84, 0xa1, 0xc1, 0xb8, 0x76, 0x3d, 0x6b, 0xd1, 0x02, 0x18, 0x20, 0x6a, 0x57, 0x21, 0xa6,
|
||||||
|
0xfb, 0xc6, 0x75, 0xee, 0xf0, 0x38, 0x26, 0xfa, 0xdc, 0x50, 0xc3, 0x68, 0xdf, 0x5d, 0x5e, 0xee,
|
||||||
|
0xae, 0x2b, 0xa5, 0x1f, 0x77, 0x4a, 0x69, 0x6f, 0x6f, 0x5f, 0xf1, 0xe3, 0x52, 0x4f, 0x8f, 0xed,
|
||||||
|
0xaa, 0x9f, 0x91, 0x4b, 0x7b, 0x60, 0xc0, 0x80, 0xeb, 0xd8, 0x70, 0x66, 0x5a, 0x2a, 0xb6, 0xa8,
|
||||||
|
0x35, 0xd4, 0xe9, 0x06, 0xb4, 0xee, 0xe8, 0x41, 0xa8, 0xbb, 0xf8, 0xe8, 0x41, 0xae, 0xad, 0x8d,
|
||||||
|
0xaa, 0x4f, 0xdc, 0x39, 0xb3, 0xe1, 0x45, 0xad, 0x2b, 0xfc, 0xac, 0xee, 0x51, 0x91, 0xc7, 0x16,
|
||||||
|
0x39, 0xd8, 0xb7, 0xb5, 0xb6, 0x6a, 0x52, 0x9b, 0x5c, 0x22, 0x11, 0x86, 0xb2, 0x70, 0xd3, 0xf6,
|
||||||
|
0x72, 0x97, 0xb9, 0xbc, 0x4a, 0xb8, 0xaa, 0x75, 0x84, 0x94, 0x42, 0xeb, 0x8e, 0x1e, 0x54, 0xba,
|
||||||
|
0xb7, 0x17, 0xbe, 0xe0, 0x79, 0x0f, 0xea, 0x22, 0x27, 0x31, 0x26, 0x82, 0x5e, 0x7d, 0x6d, 0x1a,
|
||||||
|
0xb9, 0x48, 0xc8, 0x27, 0x74, 0xbf, 0x79, 0x23, 0xc1, 0xda, 0xd2, 0xa2, 0xb6, 0xb6, 0x66, 0x58,
|
||||||
|
0x15, 0x76, 0x96, 0x0a, 0x4a, 0xfc, 0x7c, 0x71, 0x7d, 0x2d, 0x61, 0x08, 0x13, 0xed, 0x66, 0xad,
|
||||||
|
0xa8, 0xa0, 0x75, 0x47, 0x0f, 0x2a, 0xdd, 0xc5, 0x91, 0x47, 0x70, 0x9b, 0x6f, 0xe6, 0x2f, 0xff,
|
||||||
|
0xdf, 0x9b, 0xbb, 0xb7, 0xc9, 0xd7, 0x8c, 0x11, 0x7d, 0xee, 0x2c, 0x96, 0xac, 0x87, 0xcb, 0xe1,
|
||||||
|
0x4c, 0x9b, 0x62, 0x52, 0xcc, 0x1b, 0xde, 0xa8, 0x57, 0x49, 0xe5, 0xa9, 0x13, 0xca, 0x2c, 0x3f,
|
||||||
|
0x58, 0xc9, 0xf9, 0x61, 0x49, 0xfd, 0xad, 0x9b, 0xa8, 0xe2, 0x44, 0x08, 0xad, 0x3b, 0x7a, 0x90,
|
||||||
|
0xe8, 0x2e, 0x6b, 0x6f, 0x57, 0x2e, 0xea, 0x55, 0x96, 0xd2, 0xe0, 0x00, 0x24, 0x59, 0x01, 0xa1,
|
||||||
|
0x51, 0x9f, 0x35, 0x63, 0x9a, 0xe9, 0xc4, 0xef, 0x2c, 0xa7, 0x4e, 0x31, 0x37, 0x65, 0xa4, 0xa5,
|
||||||
|
0xa6, 0x90, 0xa9, 0xad, 0xed, 0x59, 0x7e, 0xe1, 0xc7, 0x2d, 0x84, 0x94, 0x37, 0xbc, 0x44, 0xd4,
|
||||||
|
0x6f, 0xca, 0xac, 0x05, 0xb4, 0xee, 0xe8, 0x41, 0xa2, 0xbb, 0xa4, 0xb2, 0xa2, 0x64, 0x9f, 0xdf,
|
||||||
|
0xa0, 0x9e, 0x8c, 0x09, 0x43, 0x14, 0xc6, 0x22, 0x1f, 0x5e, 0x4d, 0x75, 0x95, 0xea, 0x0d, 0x60,
|
||||||
|
0x90, 0x3e, 0xf2, 0xd8, 0x91, 0x4b, 0x17, 0xe3, 0xb5, 0x2e, 0x7f, 0x9c, 0x8f, 0xe1, 0x07, 0xf8,
|
||||||
|
0xe1, 0xce, 0x4c, 0xad, 0xd7, 0x80, 0x50, 0x0a, 0xad, 0x3b, 0x7a, 0x90, 0xe8, 0xde, 0x51, 0x5c,
|
||||||
|
0x54, 0xec, 0xbd, 0x73, 0xd0, 0x85, 0xed, 0xe9, 0x16, 0xa8, 0xf2, 0x26, 0x43, 0x1f, 0x66, 0xb6,
|
||||||
|
0x95, 0x25, 0x48, 0x0f, 0x7f, 0x92, 0x9f, 0xe3, 0x20, 0xeb, 0xea, 0x14, 0xaa, 0x64, 0x3a, 0xf9,
|
||||||
|
0xd0, 0x7d, 0x67, 0x07, 0x69, 0x7e, 0xf3, 0x4b, 0x67, 0xd0, 0xba, 0xa3, 0x07, 0x8d, 0xee, 0x3c,
|
||||||
|
0xd0, 0x7d, 0xd0, 0x38, 0x35, 0xcd, 0xd2, 0xa2, 0xfc, 0x20, 0xb2, 0x34, 0xe1, 0x08, 0x91, 0x4b,
|
||||||
|
0xba, 0xd4, 0xfb, 0x5d, 0x30, 0x5a, 0xed, 0x55, 0xcb, 0xfa, 0xa9, 0x77, 0x68, 0xdd, 0xd1, 0x83,
|
||||||
|
0x4e, 0xf7, 0x9d, 0x23, 0x44, 0x77, 0x89, 0xba, 0xee, 0x65, 0x21, 0x41, 0xb4, 0xee, 0x46, 0x01,
|
||||||
|
0x55, 0x9d, 0x19, 0x83, 0xd5, 0xbd, 0x7b, 0x08, 0xdd, 0xdf, 0x36, 0xe9, 0x3b, 0x34, 0x3c, 0xb4,
|
||||||
|
0xee, 0xe8, 0x31, 0x3e, 0xdd, 0xbb, 0x09, 0x74, 0x67, 0xd1, 0xba, 0x93, 0xe3, 0x55, 0x5d, 0xdd,
|
||||||
|
0x37, 0x63, 0xbe, 0x84, 0x02, 0x03, 0xac, 0x7e, 0x43, 0xbd, 0x4d, 0x3d, 0x60, 0x84, 0xba, 0xf7,
|
||||||
|
0x74, 0xab, 0x0f, 0x55, 0xcb, 0x58, 0xcc, 0xde, 0xa6, 0x21, 0x93, 0x84, 0xea, 0x8b, 0x11, 0xa3,
|
||||||
|
0x3b, 0xf8, 0x6d, 0x3b, 0x73, 0x06, 0x88, 0x5e, 0x53, 0x53, 0x0d, 0xc6, 0x6f, 0x5a, 0x8f, 0x2c,
|
||||||
|
0x89, 0x3b, 0x72, 0x28, 0xd4, 0x1d, 0xd1, 0x95, 0x19, 0xb4, 0xc8, 0x7b, 0x7a, 0x44, 0x04, 0x9d,
|
||||||
|
0x19, 0xa6, 0x94, 0xd6, 0x5d, 0x6b, 0xbc, 0x77, 0x7a, 0x7c, 0xfd, 0xd5, 0x17, 0xf9, 0xb9, 0xb9,
|
||||||
|
0xf0, 0xf8, 0xf2, 0xc5, 0x78, 0x78, 0x7c, 0xf4, 0xb0, 0xf6, 0x53, 0x47, 0x28, 0xc5, 0xf0, 0x2f,
|
||||||
|
0x44, 0xa2, 0x45, 0x31, 0x57, 0x8c, 0x50, 0x77, 0xc3, 0x9b, 0x47, 0x30, 0x32, 0x74, 0xbf, 0x72,
|
||||||
|
0xe9, 0x22, 0xf8, 0x7d, 0xfa, 0xe4, 0x09, 0xe5, 0x2b, 0x3b, 0xb6, 0x6f, 0x85, 0x57, 0xee, 0x27,
|
||||||
|
0xde, 0xd5, 0x63, 0x54, 0x43, 0x61, 0x6c, 0xba, 0xf7, 0x4b, 0xa5, 0x04, 0xba, 0xb3, 0x68, 0xdd,
|
||||||
|
0xb5, 0x42, 0x35, 0x51, 0x24, 0xae, 0x40, 0xaf, 0x46, 0x39, 0x03, 0xdb, 0x79, 0xa1, 0xc3, 0x62,
|
||||||
|
0xc7, 0xf9, 0x87, 0x0f, 0x44, 0xb8, 0xbb, 0xae, 0x74, 0x71, 0x5a, 0xb8, 0x6e, 0x8d, 0xeb, 0x99,
|
||||||
|
0x53, 0x51, 0x0b, 0xe7, 0xcf, 0x0b, 0x0b, 0x51, 0x64, 0xc6, 0x49, 0x49, 0x4e, 0xb2, 0xb6, 0xb4,
|
||||||
|
0x88, 0x8a, 0x3c, 0x76, 0x20, 0x3c, 0xcc, 0x8c, 0x31, 0xe1, 0xd1, 0xc3, 0x07, 0xf0, 0xe2, 0xb6,
|
||||||
|
0xcd, 0x1b, 0xf7, 0xec, 0xf6, 0x86, 0x07, 0x21, 0x41, 0x81, 0x9b, 0x7f, 0x5e, 0x87, 0x2a, 0x60,
|
||||||
|
0x64, 0xba, 0xef, 0x1a, 0xd1, 0xba, 0x07, 0x6a, 0xb8, 0x64, 0x56, 0x97, 0x18, 0xba, 0xee, 0x52,
|
||||||
|
0xa9, 0x74, 0xaa, 0xc9, 0xa4, 0x09, 0xe3, 0xc6, 0xb6, 0xb7, 0xb7, 0xe3, 0xde, 0x12, 0x57, 0x54,
|
||||||
|
0x80, 0xee, 0x53, 0x26, 0x7d, 0x8f, 0xad, 0x04, 0x05, 0xdd, 0x93, 0xfe, 0x79, 0x0c, 0x0f, 0x7a,
|
||||||
|
0x7b, 0x7b, 0xe1, 0x4c, 0x68, 0x7b, 0xbf, 0xac, 0x26, 0x3b, 0xeb, 0x29, 0x18, 0x0f, 0x0f, 0xe0,
|
||||||
|
0x33, 0xf1, 0x71, 0x17, 0xe0, 0x37, 0xc1, 0x71, 0xde, 0x5c, 0xa8, 0x90, 0xc5, 0x0c, 0xc0, 0x2a,
|
||||||
|
0x81, 0xdf, 0x07, 0xf8, 0x30, 0x66, 0x3f, 0x2a, 0x10, 0xe9, 0xce, 0x1b, 0x31, 0xba, 0xf7, 0x4a,
|
||||||
|
0x45, 0x04, 0x43, 0x55, 0x5a, 0xf7, 0xe1, 0xb3, 0x76, 0xb5, 0x2b, 0xe8, 0x98, 0xfc, 0xe4, 0x1f,
|
||||||
|
0xc2, 0x77, 0xff, 0xfc, 0xe3, 0x26, 0xbc, 0xeb, 0xe2, 0xe4, 0x38, 0xf0, 0x5e, 0x77, 0x2e, 0x47,
|
||||||
|
0xb1, 0xec, 0x12, 0xd3, 0xbd, 0xe3, 0xfd, 0x9a, 0x1a, 0xa5, 0xee, 0xb3, 0x66, 0x4c, 0x7b, 0x78,
|
||||||
|
0x5f, 0x91, 0x47, 0xba, 0xf5, 0xdd, 0xbb, 0x79, 0xb6, 0xb3, 0xb0, 0x46, 0xfd, 0xea, 0xe5, 0x4b,
|
||||||
|
0x8b, 0x1c, 0xec, 0xbb, 0x25, 0x12, 0xa8, 0xe1, 0xb7, 0xb8, 0xf3, 0xa8, 0x62, 0x36, 0x3e, 0xdd,
|
||||||
|
0x7b, 0x89, 0x74, 0x67, 0x52, 0x9d, 0x33, 0x5d, 0x0b, 0x0c, 0x5d, 0x77, 0x84, 0x40, 0x03, 0xdf,
|
||||||
|
0xa4, 0x93, 0x6b, 0x05, 0x46, 0xa7, 0x7b, 0x5f, 0x2f, 0x71, 0x67, 0x86, 0xd6, 0xdd, 0x18, 0x30,
|
||||||
|
0x3e, 0xdd, 0xfb, 0x08, 0x75, 0xef, 0xa9, 0x7f, 0xad, 0xef, 0xd0, 0xf0, 0xd0, 0xba, 0xa3, 0x47,
|
||||||
|
0xa1, 0xfb, 0xd9, 0x33, 0x24, 0x2b, 0x51, 0xd7, 0x3d, 0xd5, 0x60, 0x75, 0x97, 0x11, 0xe9, 0x1e,
|
||||||
|
0x4c, 0xeb, 0x6e, 0x1c, 0xe8, 0x45, 0x77, 0xb9, 0x5c, 0xae, 0x5c, 0x49, 0x4d, 0x05, 0xdd, 0x43,
|
||||||
|
0xef, 0x78, 0xdf, 0x2f, 0x93, 0x11, 0xe9, 0x8e, 0x66, 0x25, 0x0a, 0x5a, 0x68, 0xdd, 0xd1, 0x83,
|
||||||
|
0x4e, 0x77, 0xcf, 0xcf, 0xea, 0xce, 0x2b, 0x2a, 0x5a, 0xb3, 0x6a, 0x05, 0x76, 0x59, 0x56, 0xc0,
|
||||||
|
0xe7, 0x93, 0x3c, 0xe8, 0x27, 0x70, 0x77, 0x5b, 0x05, 0x87, 0x30, 0x37, 0x65, 0xc4, 0xff, 0x1a,
|
||||||
|
0x87, 0xdf, 0x59, 0x52, 0x2e, 0x23, 0x98, 0x33, 0x43, 0xeb, 0x6e, 0x24, 0xa0, 0xd1, 0x9d, 0x3f,
|
||||||
|
0xa4, 0xee, 0x6d, 0xad, 0xad, 0x87, 0xf6, 0x87, 0x4f, 0x18, 0x37, 0x16, 0x77, 0x17, 0x42, 0x07,
|
||||||
|
0xba, 0xab, 0x96, 0xa5, 0xce, 0x4e, 0x39, 0xd9, 0x59, 0x8a, 0xf7, 0xe4, 0x72, 0x02, 0xdd, 0x83,
|
||||||
|
0x02, 0x7a, 0x5e, 0xd5, 0x51, 0x17, 0x8f, 0x76, 0xd0, 0xba, 0xa3, 0x87, 0x3a, 0xdd, 0x85, 0x11,
|
||||||
|
0x6c, 0x75, 0xed, 0x94, 0x65, 0xbd, 0xbb, 0x9b, 0xa7, 0xc7, 0x76, 0x8a, 0xca, 0x74, 0x33, 0x53,
|
||||||
|
0xc2, 0x83, 0x42, 0x7b, 0x7f, 0xf5, 0x62, 0x3c, 0xad, 0xbb, 0xf1, 0x42, 0x75, 0xeb, 0x3e, 0xf0,
|
||||||
|
0xbe, 0xa7, 0x7e, 0xf3, 0x46, 0xc2, 0xcc, 0xe9, 0xe6, 0x7a, 0x69, 0xdd, 0xbf, 0x19, 0xf3, 0xa5,
|
||||||
|
0xaf, 0xb7, 0xe7, 0xab, 0xba, 0x7f, 0x6d, 0x16, 0x85, 0xb1, 0x92, 0x4d, 0x27, 0xab, 0x46, 0x5b,
|
||||||
|
0xe2, 0xbf, 0x57, 0x22, 0x2e, 0xa7, 0x2e, 0x1e, 0xed, 0xa0, 0x75, 0x47, 0x0f, 0x95, 0xba, 0x87,
|
||||||
|
0xa9, 0x7f, 0xb2, 0xb9, 0xf9, 0x6d, 0x28, 0x2b, 0x68, 0xfc, 0xd8, 0x31, 0x9a, 0xe8, 0x0e, 0xe7,
|
||||||
|
0xc9, 0xed, 0xbf, 0x6e, 0x6d, 0xdf, 0xb2, 0x71, 0xc9, 0xa2, 0x05, 0x9b, 0xd6, 0xaf, 0x3d, 0x7c,
|
||||||
|
0x20, 0x42, 0xc3, 0x84, 0x9b, 0xa0, 0xbb, 0xd3, 0x82, 0xf9, 0xd8, 0x8d, 0x3c, 0x75, 0xca, 0x0f,
|
||||||
|
0x86, 0xe3, 0xb6, 0x13, 0x2b, 0xdc, 0xbe, 0xa5, 0xb5, 0x20, 0x4f, 0x93, 0x9a, 0x75, 0x09, 0xad,
|
||||||
|
0x3b, 0x7a, 0x28, 0xd3, 0xdd, 0x9c, 0x50, 0x77, 0xcd, 0x69, 0x6a, 0x6a, 0x84, 0x86, 0x79, 0xdb,
|
||||||
|
0xe6, 0x8d, 0xca, 0x57, 0x92, 0x93, 0x9e, 0x40, 0x6b, 0xed, 0xe7, 0xbb, 0x9b, 0x64, 0xb4, 0xf5,
|
||||||
|
0xb7, 0x6e, 0xe6, 0x2c, 0x5d, 0xa2, 0x1a, 0x6d, 0xe6, 0x02, 0x7b, 0x4d, 0x72, 0xc7, 0xeb, 0x18,
|
||||||
|
0x5a, 0x77, 0xf4, 0x18, 0xac, 0xee, 0x80, 0xfd, 0x1c, 0x1b, 0xf0, 0xdb, 0x76, 0xe6, 0x8c, 0x90,
|
||||||
|
0xa0, 0x40, 0x68, 0xaa, 0x3f, 0xbb, 0xbf, 0xbb, 0x86, 0x48, 0x2a, 0xc5, 0xa5, 0x4c, 0x7f, 0x82,
|
||||||
|
0x4b, 0xef, 0x06, 0x76, 0x71, 0x86, 0xd6, 0x1d, 0x3d, 0x86, 0xac, 0xfb, 0x87, 0xca, 0x3b, 0x3a,
|
||||||
|
0xee, 0xdd, 0xbd, 0xb3, 0x63, 0xdb, 0x16, 0xc6, 0x77, 0xdf, 0x82, 0xfd, 0x8b, 0x1d, 0xe7, 0x93,
|
||||||
|
0xaf, 0xb3, 0x2a, 0xfa, 0x4c, 0xa6, 0xc3, 0x3c, 0xd5, 0x80, 0xd3, 0x6d, 0xac, 0x2b, 0x0e, 0xed,
|
||||||
|
0x27, 0x5f, 0x33, 0x42, 0x68, 0xdd, 0xd1, 0xb3, 0x3f, 0x2c, 0x14, 0x85, 0xee, 0xc5, 0xc8, 0x75,
|
||||||
|
0x7f, 0x70, 0x2f, 0x11, 0xe4, 0x0e, 0x63, 0x0f, 0xda, 0x9b, 0x69, 0xdd, 0x1a, 0xc5, 0x24, 0x3c,
|
||||||
|
0x71, 0xc5, 0xf0, 0x32, 0x7f, 0xa8, 0x23, 0xeb, 0x68, 0x17, 0xc2, 0x80, 0xd5, 0x84, 0xa1, 0x1a,
|
||||||
|
0x73, 0xce, 0x0f, 0xce, 0xd5, 0x17, 0x62, 0x48, 0xd6, 0x8c, 0x10, 0x5a, 0x77, 0xf4, 0x18, 0xac,
|
||||||
|
0xee, 0x03, 0xef, 0xb7, 0x10, 0xdb, 0xb0, 0x76, 0x0d, 0xf4, 0xe0, 0xb1, 0x6b, 0x2c, 0x26, 0x13,
|
||||||
|
0xc6, 0xfb, 0xee, 0xf2, 0x6a, 0x43, 0x94, 0x83, 0xa0, 0x43, 0x50, 0x5c, 0x12, 0xb0, 0x17, 0xd7,
|
||||||
|
0xa5, 0xc9, 0x71, 0x59, 0x5c, 0x75, 0x3a, 0x6a, 0x60, 0xc0, 0x20, 0xd6, 0x16, 0xd3, 0xba, 0xa3,
|
||||||
|
0xc7, 0x90, 0x75, 0xa7, 0x9a, 0xf6, 0x97, 0xcf, 0x05, 0x7e, 0x3e, 0x38, 0xe3, 0x39, 0xd6, 0x56,
|
||||||
|
0xa2, 0xf0, 0x10, 0x43, 0xd8, 0x76, 0x86, 0xd6, 0x1d, 0x3d, 0xc8, 0x74, 0xdf, 0x3d, 0xf2, 0x74,
|
||||||
|
0x07, 0xba, 0x6b, 0xaa, 0x85, 0xec, 0x20, 0xf5, 0x84, 0xdd, 0x45, 0xbf, 0x6c, 0xad, 0x8d, 0x8f,
|
||||||
|
0x1b, 0xe8, 0xd7, 0x67, 0xfa, 0x79, 0x5a, 0x77, 0x04, 0xe0, 0x32, 0xca, 0x87, 0xb3, 0x43, 0xce,
|
||||||
|
0x9d, 0x3e, 0xa5, 0xfa, 0x8a, 0x16, 0x75, 0x12, 0xe8, 0x3e, 0xcd, 0xbc, 0xdc, 0x20, 0xb7, 0xd5,
|
||||||
|
0x55, 0x47, 0xde, 0xd3, 0x53, 0x71, 0xf8, 0xc0, 0xd3, 0x45, 0x0b, 0x70, 0xc6, 0x27, 0x9b, 0x4e,
|
||||||
|
0xe6, 0xef, 0xd9, 0x55, 0x77, 0x39, 0xbe, 0x5f, 0x86, 0xe6, 0x8a, 0xd0, 0x70, 0xa1, 0x75, 0x47,
|
||||||
|
0x03, 0x8b, 0x19, 0x30, 0xd4, 0xbd, 0xfd, 0x93, 0x27, 0x22, 0xb5, 0xa8, 0x70, 0x44, 0xeb, 0x8e,
|
||||||
|
0xd1, 0x9a, 0x9f, 0x57, 0xc6, 0x0a, 0x24, 0x4c, 0xc3, 0x9d, 0xef, 0xba, 0x1c, 0xbe, 0x4b, 0x97,
|
||||||
|
0xa8, 0x4c, 0xc7, 0x21, 0xd1, 0xba, 0x23, 0x03, 0x5a, 0x74, 0x75, 0xd7, 0x7f, 0x4f, 0xb8, 0xae,
|
||||||
|
0x5d, 0x6d, 0xa0, 0x3b, 0x7f, 0x84, 0xeb, 0x8e, 0xf1, 0xe6, 0xee, 0xed, 0x92, 0x7d, 0x7b, 0x53,
|
||||||
|
0xcc, 0x09, 0xd2, 0xd8, 0x27, 0x99, 0x30, 0x0a, 0xdc, 0x56, 0x8a, 0xc2, 0x58, 0x0d, 0x89, 0x77,
|
||||||
|
0x74, 0x93, 0xb2, 0x8f, 0xd6, 0x1d, 0x25, 0xd8, 0xda, 0x59, 0x65, 0x21, 0x93, 0x26, 0xa0, 0x43,
|
||||||
|
0x30, 0x4a, 0x74, 0xcc, 0x4c, 0x34, 0x61, 0x00, 0x00, 0x07, 0xa9, 0x49, 0x44, 0x41, 0x54, 0xc7,
|
||||||
|
0x78, 0x97, 0x95, 0x29, 0x0a, 0x0d, 0xce, 0xb4, 0xb7, 0x53, 0x97, 0xfe, 0x43, 0x3f, 0xc7, 0xcc,
|
||||||
|
0x24, 0xdb, 0x65, 0x71, 0xc9, 0xbe, 0x3d, 0x30, 0xa8, 0xad, 0x8e, 0x3d, 0xd7, 0x92, 0x91, 0xde,
|
||||||
|
0x55, 0x2e, 0xec, 0x7b, 0xd7, 0x82, 0x36, 0xab, 0xd9, 0x7f, 0x9a, 0x39, 0x29, 0x2f, 0xb7, 0x6e,
|
||||||
|
0xcc, 0x72, 0x72, 0x34, 0xdc, 0xb2, 0x78, 0x61, 0xce, 0xd2, 0x25, 0x79, 0x3f, 0x2d, 0x7b, 0xe6,
|
||||||
|
0xee, 0xc6, 0xf7, 0xf1, 0x2a, 0x63, 0x31, 0xe1, 0x1f, 0xae, 0x32, 0x2a, 0xb2, 0xe9, 0xc9, 0x63,
|
||||||
|
0x45, 0x9e, 0x68, 0xbd, 0x0e, 0x7d, 0xd4, 0xc9, 0xe4, 0xa6, 0x63, 0x93, 0xa8, 0xa0, 0x33, 0x42,
|
||||||
|
0xa6, 0x9e, 0x51, 0xa6, 0x3b, 0x86, 0xac, 0xab, 0xb3, 0x36, 0x2e, 0xb6, 0x94, 0xe9, 0xcf, 0x9d,
|
||||||
|
0x33, 0x7b, 0x28, 0xef, 0x09, 0xce, 0x84, 0x29, 0x93, 0x53, 0x2d, 0xcc, 0x60, 0xa4, 0x4e, 0xa6,
|
||||||
|
0x3c, 0x5f, 0xbb, 0xba, 0x99, 0x93, 0xaa, 0xd0, 0x3d, 0x7f, 0xd5, 0x72, 0xcd, 0x8f, 0x6d, 0x68,
|
||||||
|
0x25, 0xcd, 0x6a, 0x7a, 0xc1, 0xea, 0x55, 0xa5, 0xc1, 0x81, 0xc5, 0x47, 0x0f, 0xe5, 0xde, 0xbf,
|
||||||
|
0x9b, 0xc1, 0xe5, 0xea, 0xbd, 0x24, 0x5c, 0xbf, 0x76, 0xf7, 0xce, 0x6d, 0x92, 0x95, 0xe4, 0xfd,
|
||||||
|
0xf9, 0x47, 0xa1, 0xa7, 0x07, 0x4e, 0xf7, 0x92, 0x30, 0x96, 0xde, 0xbf, 0x1d, 0x92, 0x92, 0x99,
|
||||||
|
0x9a, 0xfa, 0x22, 0x3e, 0xae, 0x94, 0x1d, 0xfc, 0x72, 0xdb, 0x66, 0xce, 0x2c, 0x2b, 0x1d, 0x78,
|
||||||
|
0x52, 0xe0, 0xba, 0x62, 0x34, 0xe8, 0xae, 0x5a, 0x92, 0x18, 0x13, 0x73, 0x97, 0x2e, 0x81, 0xb6,
|
||||||
|
0xbf, 0xe1, 0x7e, 0x62, 0x3f, 0x95, 0x2b, 0xd9, 0x74, 0x00, 0x15, 0xad, 0xfb, 0x95, 0x4b, 0x17,
|
||||||
|
0x27, 0x8c, 0x1b, 0xab, 0x3a, 0x71, 0xd7, 0x30, 0xe8, 0x97, 0x88, 0xcb, 0x5f, 0xdf, 0xb8, 0x26,
|
||||||
|
0x8a, 0x60, 0xc3, 0xd0, 0xf6, 0xc5, 0x86, 0x75, 0x4f, 0x17, 0x3a, 0x70, 0xac, 0xad, 0x92, 0x06,
|
||||||
|
0xdf, 0xa0, 0x45, 0xa3, 0x3b, 0xf4, 0x90, 0x1a, 0xee, 0xdd, 0x45, 0x58, 0x1a, 0x1f, 0x24, 0x36,
|
||||||
|
0x3e, 0xbc, 0x8f, 0xb0, 0x34, 0x24, 0xde, 0x7e, 0x95, 0x70, 0xad, 0x36, 0x3e, 0x4e, 0x7c, 0xfc,
|
||||||
|
0x28, 0x74, 0xec, 0x84, 0xec, 0xa0, 0xa2, 0x1d, 0xdb, 0xb2, 0x9d, 0x17, 0xa5, 0x4c, 0x35, 0xfd,
|
||||||
|
0xc4, 0xd7, 0xcb, 0x76, 0x5a, 0x08, 0x63, 0xa0, 0xd6, 0xfc, 0x5c, 0x7d, 0xff, 0x5f, 0x6a, 0x09,
|
||||||
|
0x72, 0xdd, 0x8f, 0x1d, 0x3e, 0xa4, 0x9c, 0xad, 0xce, 0x2b, 0x2a, 0x42, 0x18, 0x2a, 0x55, 0xc8,
|
||||||
|
0xe5, 0xbd, 0x2d, 0xcd, 0x3d, 0xf5, 0xaf, 0x25, 0x55, 0xe2, 0xce, 0xb2, 0xd2, 0xce, 0x52, 0x01,
|
||||||
|
0xc9, 0xd2, 0xfb, 0xb6, 0x69, 0x04, 0x0f, 0x55, 0xe5, 0xd2, 0x9e, 0xb6, 0x17, 0xcf, 0xc4, 0xc7,
|
||||||
|
0x8f, 0x40, 0x5f, 0x30, 0x73, 0x81, 0x3d, 0xa1, 0xf4, 0x70, 0x4a, 0x94, 0xf8, 0xfb, 0xbe, 0xbe,
|
||||||
|
0x71, 0x7d, 0x80, 0x74, 0x06, 0x22, 0x1d, 0x83, 0x56, 0xf7, 0x3d, 0xbb, 0xbd, 0x71, 0x97, 0x8c,
|
||||||
|
0x52, 0x92, 0x93, 0xd0, 0x06, 0x3c, 0x22, 0x18, 0xc1, 0xba, 0x0f, 0x42, 0x2e, 0x6f, 0xe1, 0x72,
|
||||||
|
0xa0, 0xed, 0xcf, 0x5d, 0xea, 0xa2, 0x2e, 0x7d, 0xb2, 0x09, 0x03, 0xa4, 0x6f, 0x7c, 0x70, 0x4f,
|
||||||
|
0xdf, 0x51, 0x0e, 0x03, 0x84, 0xba, 0x63, 0x3b, 0xb1, 0xa9, 0x97, 0x84, 0x6b, 0x06, 0x9a, 0xdb,
|
||||||
|
0x9a, 0x3a, 0x46, 0x8b, 0xee, 0x1f, 0xe9, 0xef, 0xeb, 0x7b, 0x75, 0xfd, 0x8a, 0x60, 0xaf, 0x0f,
|
||||||
|
0x2e, 0x73, 0x39, 0x94, 0xb4, 0x19, 0xd3, 0xa1, 0x7b, 0x63, 0x80, 0x9b, 0x9f, 0x10, 0xd2, 0x21,
|
||||||
|
0xe0, 0xf3, 0x77, 0x7b, 0x91, 0xd7, 0x7d, 0xf3, 0x86, 0xf5, 0xb3, 0xad, 0x2c, 0xb1, 0x62, 0x65,
|
||||||
|
0x61, 0x36, 0x7e, 0xec, 0x18, 0xe5, 0x53, 0x28, 0xd7, 0xae, 0x5c, 0xa6, 0x22, 0x78, 0x83, 0x65,
|
||||||
|
0xb4, 0xe9, 0xae, 0x04, 0x7a, 0xfc, 0x02, 0x3f, 0x1f, 0xf5, 0xe1, 0x4e, 0xd1, 0x2f, 0x5b, 0x1a,
|
||||||
|
0xee, 0x1b, 0xe2, 0x36, 0xd9, 0x38, 0x50, 0xe9, 0xae, 0x4a, 0x69, 0x89, 0x60, 0xfe, 0xdc, 0xd9,
|
||||||
|
0xa8, 0x22, 0x1c, 0x89, 0x8c, 0x5a, 0xdd, 0x07, 0xde, 0xb7, 0xf4, 0x95, 0xc7, 0x8f, 0xe5, 0x0e,
|
||||||
|
0x5e, 0x54, 0x06, 0x05, 0x5e, 0xa9, 0x3a, 0x77, 0x5a, 0xdf, 0xd1, 0x7d, 0x06, 0x5a, 0x77, 0x2a,
|
||||||
|
0x18, 0xcd, 0xba, 0x63, 0xb4, 0x64, 0xa4, 0xf3, 0x7d, 0xbc, 0x70, 0xc6, 0x67, 0x3b, 0x3b, 0x55,
|
||||||
|
0xc7, 0x92, 0xdd, 0xc6, 0x91, 0x52, 0x68, 0xdd, 0xa9, 0x60, 0xf4, 0xeb, 0x0e, 0x74, 0x96, 0xf0,
|
||||||
|
0x4b, 0x02, 0xf1, 0x59, 0xcc, 0x0b, 0xdc, 0x56, 0x35, 0xdc, 0xbb, 0xa3, 0xef, 0xd0, 0x86, 0x84,
|
||||||
|
0xd6, 0x9d, 0x0a, 0x8c, 0x42, 0x77, 0xa0, 0xad, 0x20, 0x8f, 0xe7, 0xb5, 0x13, 0x67, 0x3c, 0x9c,
|
||||||
|
0x03, 0x5d, 0x15, 0x22, 0x7d, 0x87, 0x46, 0x0c, 0x91, 0xee, 0x53, 0x69, 0xdd, 0x49, 0x62, 0x2c,
|
||||||
|
0xba, 0x03, 0xb5, 0x17, 0x7f, 0xcd, 0x5a, 0xbc, 0x50, 0x55, 0x20, 0xee, 0x5c, 0x5b, 0xf1, 0x89,
|
||||||
|
0xa3, 0xfa, 0x8e, 0x8b, 0x18, 0x5a, 0x77, 0x2a, 0x30, 0x22, 0xdd, 0x7b, 0x9b, 0xdf, 0x0a, 0xd9,
|
||||||
|
0x41, 0xb8, 0x06, 0x5e, 0xb1, 0x0d, 0xb9, 0x81, 0x6d, 0x0e, 0x81, 0x01, 0x1d, 0x30, 0xdc, 0x90,
|
||||||
|
0x43, 0xc7, 0xba, 0xa7, 0xa5, 0xa6, 0xec, 0xf6, 0xda, 0xc9, 0x0e, 0x66, 0x92, 0x39, 0xa2, 0xa1,
|
||||||
|
0x61, 0x44, 0xba, 0x03, 0xe2, 0xc8, 0xc3, 0xe9, 0xb3, 0x67, 0x0d, 0xee, 0xc1, 0xaf, 0x6c, 0x4e,
|
||||||
|
0xd3, 0x7e, 0x9a, 0x2e, 0x75, 0xe8, 0x57, 0x77, 0x2c, 0xef, 0x95, 0xaf, 0xb7, 0x27, 0xfc, 0x09,
|
||||||
|
0xd2, 0x93, 0x39, 0xa8, 0x41, 0x61, 0x5c, 0xba, 0xbf, 0xfe, 0x3d, 0x21, 0x7b, 0x89, 0xd3, 0xa0,
|
||||||
|
0x4b, 0x34, 0x4b, 0x9c, 0x14, 0x53, 0x0c, 0x0c, 0x0f, 0x3d, 0xea, 0x2e, 0x93, 0xc9, 0x66, 0x98,
|
||||||
|
0x4f, 0x99, 0x6a, 0x32, 0x49, 0x2e, 0x97, 0xc7, 0xc7, 0x5d, 0xf8, 0xfa, 0xab, 0x2f, 0x62, 0xa3,
|
||||||
|
0x0d, 0x6e, 0x3f, 0x30, 0xed, 0x30, 0x2e, 0xdd, 0xdf, 0xa6, 0x24, 0xe5, 0xaf, 0xf8, 0x51, 0xd5,
|
||||||
|
0xa1, 0xcc, 0xf9, 0x76, 0xd5, 0x31, 0x64, 0x97, 0x51, 0x53, 0x41, 0x7b, 0x51, 0x61, 0xb1, 0xd7,
|
||||||
|
0x8e, 0x41, 0x77, 0x85, 0x2d, 0xa7, 0x91, 0x4c, 0x12, 0xaf, 0xa1, 0xee, 0x5b, 0x37, 0x6d, 0x00,
|
||||||
|
0xc5, 0x0b, 0x5f, 0xbe, 0xc0, 0x9e, 0x6e, 0xde, 0xb0, 0x1e, 0x9e, 0xa6, 0xa7, 0xa5, 0x69, 0x7e,
|
||||||
|
0x14, 0x8f, 0xad, 0x9b, 0xb5, 0x0e, 0x92, 0x52, 0x8c, 0x4b, 0xf7, 0xd6, 0x82, 0xbc, 0xc2, 0x6d,
|
||||||
|
0x9b, 0x54, 0x1d, 0xe2, 0x58, 0x5b, 0x95, 0x1f, 0x39, 0xa0, 0xef, 0xb8, 0x08, 0x68, 0xc9, 0xe4,
|
||||||
|
0x3e, 0x73, 0x77, 0x1b, 0x34, 0xb0, 0x9e, 0x63, 0x53, 0x19, 0xa5, 0xcd, 0xb2, 0x57, 0x25, 0x9a,
|
||||||
|
0xe8, 0x7e, 0x3e, 0x26, 0x1a, 0xe4, 0x8e, 0x39, 0x7b, 0x46, 0xb9, 0xae, 0xbc, 0x5b, 0x22, 0x31,
|
||||||
|
0x37, 0x65, 0x7c, 0xfb, 0xdf, 0xaf, 0xea, 0x5f, 0x7f, 0x98, 0x7f, 0x21, 0x14, 0x96, 0x95, 0x08,
|
||||||
|
0xf8, 0x79, 0xb9, 0x39, 0xd0, 0xf6, 0x17, 0xf3, 0x78, 0xfd, 0xfd, 0xfd, 0x8f, 0x1e, 0x3e, 0x88,
|
||||||
|
0x3b, 0x1f, 0x53, 0x5b, 0x5b, 0xa3, 0x88, 0xbc, 0xb9, 0xf9, 0xc9, 0xe3, 0xbf, 0xe1, 0x01, 0x7c,
|
||||||
|
0x46, 0x58, 0x56, 0x9a, 0x93, 0x9d, 0x75, 0x21, 0x36, 0x3a, 0xeb, 0x69, 0x26, 0x99, 0xc8, 0x51,
|
||||||
|
0x61, 0x5c, 0xba, 0x4b, 0x1b, 0xde, 0x94, 0xb1, 0x98, 0xb8, 0xd1, 0x2a, 0x8c, 0x5f, 0x7b, 0x5b,
|
||||||
|
0x9a, 0xf5, 0x1d, 0x1a, 0x9e, 0xca, 0x53, 0x27, 0x32, 0xec, 0x6c, 0x55, 0xe3, 0x84, 0xdf, 0xa5,
|
||||||
|
0xc6, 0x47, 0x0f, 0xc9, 0xd4, 0xf9, 0x59, 0xdd, 0x9f, 0x15, 0xe4, 0x83, 0xeb, 0x0e, 0x76, 0xb6,
|
||||||
|
0x61, 0x6c, 0x96, 0x6a, 0x09, 0xf4, 0xf7, 0x83, 0xd7, 0xad, 0x2c, 0xcc, 0xb0, 0x3d, 0x25, 0xa1,
|
||||||
|
0x6f, 0xb3, 0xc8, 0xc1, 0x1e, 0xfb, 0x2b, 0xcb, 0x97, 0xb9, 0x44, 0x84, 0xb2, 0xb1, 0xc7, 0x93,
|
||||||
|
0xbe, 0x1b, 0x57, 0x29, 0x16, 0x43, 0x25, 0x73, 0x6d, 0x66, 0xc2, 0xd3, 0x93, 0xc7, 0x23, 0x57,
|
||||||
|
0xfc, 0xb8, 0x14, 0x7b, 0xeb, 0x54, 0xd4, 0xf1, 0x5d, 0x9e, 0x3b, 0xc8, 0x04, 0x8f, 0x04, 0xe3,
|
||||||
|
0xd2, 0x1d, 0xa8, 0x38, 0xbc, 0x1f, 0xb7, 0x7c, 0x26, 0x77, 0x99, 0x4b, 0xfd, 0xad, 0x9b, 0xfa,
|
||||||
|
0x8e, 0x6b, 0x10, 0xdd, 0x35, 0xd5, 0xa5, 0x41, 0xfb, 0x70, 0xa7, 0x65, 0x69, 0x70, 0x40, 0x77,
|
||||||
|
0x5d, 0x2d, 0x99, 0x6a, 0x3f, 0xad, 0xbb, 0x44, 0xd2, 0x35, 0xf9, 0xfb, 0x6f, 0x27, 0x8e, 0xff,
|
||||||
|
0xa6, 0xb3, 0xb3, 0x53, 0xfd, 0xdd, 0xab, 0x97, 0x2f, 0x81, 0xf1, 0x6b, 0x56, 0xad, 0x18, 0x78,
|
||||||
|
0xaf, 0xfb, 0x5e, 0x9f, 0x5d, 0xd8, 0xeb, 0xbf, 0x6c, 0xd9, 0x74, 0xfd, 0xea, 0x87, 0x79, 0x66,
|
||||||
|
0xd0, 0xe3, 0x87, 0xe6, 0x5c, 0x55, 0x77, 0x65, 0xba, 0x66, 0xf8, 0x0c, 0x7c, 0x92, 0x4c, 0xf0,
|
||||||
|
0x48, 0x30, 0x3a, 0xdd, 0x3b, 0x8a, 0x79, 0x7c, 0x5f, 0x6f, 0xfc, 0xe5, 0xc8, 0xe0, 0xc0, 0xee,
|
||||||
|
0xea, 0x2a, 0x7d, 0x87, 0xf6, 0x2f, 0x70, 0x4e, 0xa6, 0xdb, 0x58, 0xab, 0x46, 0xf8, 0xd4, 0xd1,
|
||||||
|
0xa1, 0xe6, 0x7c, 0x34, 0xc9, 0x6a, 0x3f, 0xad, 0x3b, 0xb4, 0xc4, 0x20, 0x74, 0x6a, 0x4a, 0xf2,
|
||||||
|
0x50, 0x1f, 0x80, 0xe6, 0x19, 0x3e, 0x10, 0xce, 0x0e, 0xa1, 0x75, 0x1f, 0x49, 0x54, 0xc7, 0x9e,
|
||||||
|
0xcb, 0x72, 0x72, 0x54, 0x95, 0x29, 0xc5, 0xdc, 0x4c, 0x14, 0xc6, 0x92, 0x75, 0x76, 0xe8, 0x3b,
|
||||||
|
0x34, 0x05, 0xb5, 0xf1, 0x71, 0xf0, 0x83, 0xa3, 0x1a, 0x5e, 0xb2, 0x09, 0x43, 0x08, 0xe1, 0x75,
|
||||||
|
0xb4, 0x93, 0xac, 0x99, 0xbe, 0xcd, 0x64, 0x8c, 0xba, 0x2b, 0xb2, 0x3c, 0x47, 0xb0, 0x71, 0xd9,
|
||||||
|
0x26, 0x52, 0xa7, 0x99, 0x8b, 0xc2, 0x43, 0x14, 0x3b, 0x3d, 0xe8, 0x95, 0x9a, 0xb8, 0xd8, 0xbc,
|
||||||
|
0x9f, 0x96, 0xe1, 0x7e, 0x7c, 0x04, 0xfe, 0xbe, 0x1d, 0xc5, 0x08, 0x96, 0xdb, 0xd1, 0xba, 0x1b,
|
||||||
|
0xa3, 0xee, 0x80, 0x5c, 0x22, 0x01, 0xb9, 0x41, 0x71, 0x55, 0xab, 0x92, 0x26, 0x4f, 0x2a, 0x65,
|
||||||
|
0xee, 0x6b, 0x7f, 0xf9, 0x5c, 0x2f, 0x21, 0xc9, 0x3a, 0x3b, 0xcb, 0xf7, 0x87, 0x72, 0xe7, 0xe2,
|
||||||
|
0x77, 0xa4, 0xe0, 0xfb, 0x78, 0xb7, 0x21, 0xca, 0xfa, 0x42, 0xeb, 0x6e, 0xa4, 0xba, 0x03, 0xfd,
|
||||||
|
0xbd, 0xd2, 0xf2, 0x83, 0xe1, 0x19, 0x76, 0x73, 0x70, 0x7a, 0xe5, 0xb8, 0x38, 0x57, 0x1c, 0x3d,
|
||||||
|
0x28, 0xeb, 0xea, 0xd2, 0x65, 0x30, 0x8d, 0x0f, 0x12, 0x05, 0x7b, 0x77, 0x27, 0x31, 0x26, 0xe2,
|
||||||
|
0x4e, 0xbf, 0xb2, 0xe0, 0x80, 0xce, 0xb2, 0x52, 0x54, 0x47, 0xa1, 0x75, 0x37, 0x5e, 0xdd, 0x31,
|
||||||
|
0x5e, 0x5d, 0xbb, 0x5c, 0xb8, 0x75, 0x13, 0xce, 0x78, 0x28, 0x2f, 0xb7, 0x6c, 0xa8, 0x3a, 0x1d,
|
||||||
|
0x25, 0x97, 0x50, 0x2e, 0xfd, 0xdb, 0x94, 0x24, 0x70, 0x3a, 0x75, 0xda, 0x54, 0x5c, 0x00, 0xdc,
|
||||||
|
0x39, 0xb3, 0x45, 0xfb, 0x43, 0xfb, 0xda, 0xc9, 0x6e, 0x25, 0x17, 0x1f, 0x77, 0xe1, 0xf4, 0xc9,
|
||||||
|
0x13, 0x58, 0x09, 0x09, 0x0a, 0x34, 0x37, 0x65, 0x28, 0x9f, 0x42, 0xd1, 0xfc, 0xe6, 0xd1, 0xe8,
|
||||||
|
0xc0, 0xd8, 0x75, 0x07, 0xa4, 0x6f, 0xea, 0x45, 0x61, 0x21, 0x5c, 0x5b, 0x1b, 0x75, 0xe9, 0x61,
|
||||||
|
0xc8, 0x08, 0x7d, 0x9e, 0x0e, 0x3e, 0x0f, 0xf9, 0x41, 0xfb, 0xda, 0x5a, 0xe1, 0x74, 0x2a, 0xde,
|
||||||
|
0xb5, 0x53, 0x7d, 0x4d, 0x6d, 0x92, 0x09, 0x43, 0xe0, 0xe7, 0xdb, 0xf8, 0x37, 0xa9, 0x4b, 0xec,
|
||||||
|
0x4a, 0x24, 0x92, 0x2e, 0x2b, 0x0b, 0x33, 0xc2, 0xa5, 0xd9, 0xfe, 0x7b, 0x7c, 0x90, 0x1c, 0x62,
|
||||||
|
0x04, 0x41, 0xeb, 0xfe, 0x81, 0xb6, 0xe7, 0xcf, 0x84, 0x21, 0x4c, 0x8e, 0x95, 0xa5, 0xba, 0xf4,
|
||||||
|
0xe0, 0xdf, 0xf3, 0xb5, 0x6e, 0x30, 0xba, 0x85, 0x96, 0x58, 0xde, 0xd3, 0x4d, 0xe6, 0x28, 0x9d,
|
||||||
|
0x65, 0x25, 0x95, 0x27, 0x8e, 0x09, 0xf6, 0xfa, 0x70, 0x66, 0x12, 0x1d, 0x68, 0xf2, 0xa4, 0x22,
|
||||||
|
0x8f, 0x6d, 0x35, 0x17, 0x62, 0x06, 0xe4, 0xda, 0xec, 0x91, 0x3d, 0x14, 0x72, 0xb9, 0xdc, 0xd1,
|
||||||
|
0xde, 0x0e, 0xe7, 0xfa, 0xf1, 0xa3, 0x47, 0x10, 0x1e, 0x62, 0xa4, 0x40, 0xeb, 0x3e, 0x08, 0xe8,
|
||||||
|
0x28, 0x8b, 0xc2, 0x58, 0x59, 0x6a, 0x1b, 0x93, 0xff, 0x3b, 0x71, 0x65, 0xba, 0x45, 0x81, 0xdb,
|
||||||
|
0x2a, 0x38, 0x31, 0xc4, 0xc7, 0x0e, 0x35, 0x3e, 0xbc, 0xd7, 0x25, 0x2a, 0x1b, 0xea, 0xf2, 0x65,
|
||||||
|
0xbf, 0x54, 0xda, 0x5d, 0x57, 0xdb, 0x92, 0xc9, 0xad, 0x8e, 0x39, 0x2b, 0x0c, 0x0f, 0xe1, 0x79,
|
||||||
|
0x79, 0x64, 0xd8, 0xcf, 0x1d, 0xaa, 0xda, 0xd4, 0xe9, 0xe6, 0x25, 0xfb, 0xf6, 0xbc, 0xfe, 0xfd,
|
||||||
|
0x3a, 0x75, 0x5b, 0x5e, 0xba, 0xbb, 0xae, 0x54, 0xba, 0xae, 0xbc, 0x52, 0x6e, 0x6c, 0xd0, 0xba,
|
||||||
|
0x13, 0x20, 0xef, 0xe9, 0xa9, 0xbb, 0x14, 0x5f, 0x1a, 0xb8, 0x8f, 0x3b, 0x87, 0xa0, 0x87, 0xa3,
|
||||||
|
0x5e, 0x52, 0xa6, 0x9a, 0x72, 0x66, 0x59, 0x41, 0x6f, 0x1b, 0x84, 0xce, 0xb0, 0xb3, 0x4d, 0xb7,
|
||||||
|
0xb1, 0x06, 0x7d, 0x35, 0xfc, 0x8b, 0x30, 0x72, 0x28, 0x3f, 0x18, 0xd1, 0x5d, 0x53, 0xad, 0x83,
|
||||||
|
0xef, 0xe5, 0xeb, 0xed, 0x09, 0xae, 0x27, 0x3f, 0xf9, 0x47, 0x07, 0xc7, 0x32, 0x4c, 0x68, 0xdd,
|
||||||
|
0x3f, 0x85, 0x5c, 0xda, 0xd3, 0x70, 0x3f, 0x11, 0xda, 0xfb, 0x17, 0x1b, 0xd6, 0xa5, 0x5a, 0xe0,
|
||||||
|
0x47, 0x93, 0xda, 0x95, 0x24, 0xc6, 0xc4, 0x6c, 0x67, 0x27, 0x01, 0xd3, 0xff, 0x79, 0x04, 0xfb,
|
||||||
|
0xaf, 0x0b, 0xe7, 0xaf, 0x5c, 0xbe, 0xa4, 0xcb, 0xf2, 0xdb, 0xaf, 0x71, 0x24, 0x6b, 0x48, 0x25,
|
||||||
|
0xb1, 0x8b, 0xb7, 0xde, 0xa1, 0x75, 0xd7, 0x14, 0xc5, 0x1e, 0x7d, 0xcf, 0x0b, 0x2a, 0x4f, 0x47,
|
||||||
|
0x09, 0x43, 0x59, 0x3c, 0xef, 0x1d, 0x39, 0x2e, 0xce, 0xd0, 0xff, 0xc6, 0x5d, 0x3a, 0x24, 0x68,
|
||||||
|
0xbf, 0xcd, 0xcd, 0x9e, 0x2e, 0xb0, 0x7f, 0xb9, 0x71, 0x7d, 0x59, 0x30, 0xb3, 0xfc, 0x40, 0x58,
|
||||||
|
0xd3, 0xe3, 0x47, 0xbd, 0x6f, 0x9b, 0xf4, 0xfd, 0x55, 0x8c, 0x17, 0x5a, 0x77, 0x52, 0xf4, 0xf7,
|
||||||
|
0xf5, 0x49, 0xdf, 0xd4, 0x77, 0x08, 0xf8, 0x6d, 0x2f, 0x9e, 0xbd, 0xcb, 0xc9, 0x6a, 0xe6, 0x72,
|
||||||
|
0x5a, 0x9e, 0x66, 0xb4, 0x16, 0xe4, 0x75, 0xf0, 0x8a, 0x24, 0xd5, 0x55, 0x3a, 0xb8, 0x8e, 0x49,
|
||||||
|
0x33, 0x2c, 0xfe, 0x0f, 0x35, 0xf0, 0x0d, 0xe1, 0x1b, 0xb4, 0xe3, 0xaf, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
|
||||||
|
};
|
||||||
|
|
||||||
|
const BITMAP_OPAQUE tune_single_track_length_legend_xpm[1] = {{ png, sizeof( png ), "tune_single_track_length_legend_xpm" }};
|
||||||
|
|
||||||
|
//EOF
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
|
@ -204,7 +204,8 @@ set( COMMON_SRCS
|
||||||
wildcards_and_files_ext.cpp
|
wildcards_and_files_ext.cpp
|
||||||
worksheet.cpp
|
worksheet.cpp
|
||||||
wxwineda.cpp
|
wxwineda.cpp
|
||||||
wxunittext.cpp
|
wx_unit_binder.cpp
|
||||||
|
wx_status_popup.cpp
|
||||||
xnode.cpp
|
xnode.cpp
|
||||||
zoom.cpp
|
zoom.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -35,6 +35,7 @@ bool SEG::PointCloserThan( const VECTOR2I& aP, int aDist ) const
|
||||||
{
|
{
|
||||||
VECTOR2I d = B - A;
|
VECTOR2I d = B - A;
|
||||||
ecoord dist_sq = (ecoord) aDist * aDist;
|
ecoord dist_sq = (ecoord) aDist * aDist;
|
||||||
|
ecoord dist_sq_thr = (ecoord) ( aDist + 1 ) * ( aDist + 1 );
|
||||||
|
|
||||||
SEG::ecoord l_squared = d.Dot( d );
|
SEG::ecoord l_squared = d.Dot( d );
|
||||||
SEG::ecoord t = d.Dot( aP - A );
|
SEG::ecoord t = d.Dot( aP - A );
|
||||||
|
@ -60,6 +61,7 @@ bool SEG::PointCloserThan( const VECTOR2I& aP, int aDist ) const
|
||||||
|
|
||||||
if( num > ( dist_sq + 100 ) )
|
if( num > ( dist_sq + 100 ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
else if( num < ( dist_sq - 100 ) )
|
else if( num < ( dist_sq - 100 ) )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -564,7 +564,7 @@ struct VIEW::drawItem
|
||||||
bool operator()( VIEW_ITEM* aItem )
|
bool operator()( VIEW_ITEM* aItem )
|
||||||
{
|
{
|
||||||
// Conditions that have te be fulfilled for an item to be drawn
|
// Conditions that have te be fulfilled for an item to be drawn
|
||||||
bool drawCondition = aItem->ViewIsVisible() &&
|
bool drawCondition = aItem->isRenderable() &&
|
||||||
aItem->ViewGetLOD( layer ) < view->m_scale;
|
aItem->ViewGetLOD( layer ) < view->m_scale;
|
||||||
if( !drawCondition )
|
if( !drawCondition )
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -29,17 +29,6 @@
|
||||||
|
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
void VIEW_ITEM::ViewSetVisible( bool aIsVisible )
|
|
||||||
{
|
|
||||||
// update only if the visibility has really changed
|
|
||||||
if( m_visible != aIsVisible )
|
|
||||||
{
|
|
||||||
m_visible = aIsVisible;
|
|
||||||
ViewUpdate( APPEARANCE );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void VIEW_ITEM::ViewRelease()
|
void VIEW_ITEM::ViewRelease()
|
||||||
{
|
{
|
||||||
if( m_view && m_view->IsDynamic() )
|
if( m_view && m_view->IsDynamic() )
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transient mouse following popup window implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <wx_status_popup.h>
|
||||||
|
#include <wxPcbStruct.h>
|
||||||
|
|
||||||
|
WX_STATUS_POPUP::WX_STATUS_POPUP( PCB_EDIT_FRAME* aParent ) :
|
||||||
|
wxPopupWindow( aParent )
|
||||||
|
{
|
||||||
|
m_panel = new wxPanel( this, wxID_ANY );
|
||||||
|
m_panel->SetBackgroundColour( *wxLIGHT_GREY );
|
||||||
|
|
||||||
|
m_topSizer = new wxBoxSizer( wxVERTICAL );
|
||||||
|
m_panel->SetSizer( m_topSizer );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WX_STATUS_POPUP::updateSize()
|
||||||
|
{
|
||||||
|
m_topSizer->Fit( m_panel );
|
||||||
|
SetClientSize( m_panel->GetSize() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WX_STATUS_POPUP::~WX_STATUS_POPUP()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WX_STATUS_POPUP::Popup( wxWindow* )
|
||||||
|
{
|
||||||
|
Show( true );
|
||||||
|
Raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WX_STATUS_POPUP::Move( const wxPoint& aWhere )
|
||||||
|
{
|
||||||
|
SetPosition ( aWhere );
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014-2015 CERN
|
||||||
|
* Author: Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <wx/stattext.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
|
#include <wx/textctrl.h>
|
||||||
|
#include <limits>
|
||||||
|
#include <base_units.h>
|
||||||
|
#if wxCHECK_VERSION( 2, 9, 0 )
|
||||||
|
#include <wx/valnum.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#include "wx_unit_binder.h"
|
||||||
|
|
||||||
|
WX_UNIT_BINDER::WX_UNIT_BINDER( wxWindow* aParent, wxTextCtrl* aTextInput, wxStaticText* aUnitLabel, wxSpinButton* aSpinButton )
|
||||||
|
{
|
||||||
|
// Use the currently selected units
|
||||||
|
m_units = g_UserUnit;
|
||||||
|
m_textCtrl = aTextInput;
|
||||||
|
m_textCtrl->SetValue( wxT( "0" ) );
|
||||||
|
m_unitLabel = aUnitLabel;
|
||||||
|
m_unitLabel->SetLabel( GetAbbreviatedUnitsLabel( m_units ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WX_UNIT_BINDER::~WX_UNIT_BINDER()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WX_UNIT_BINDER::SetValue( int aValue )
|
||||||
|
{
|
||||||
|
wxString s = StringFromValue( m_units, aValue, false );
|
||||||
|
|
||||||
|
m_textCtrl->SetValue( s );
|
||||||
|
|
||||||
|
m_unitLabel->SetLabel( GetAbbreviatedUnitsLabel( m_units ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int WX_UNIT_BINDER::GetValue() const
|
||||||
|
{
|
||||||
|
wxString s = m_textCtrl->GetValue();
|
||||||
|
|
||||||
|
return ValueFromString( m_units, s );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WX_UNIT_BINDER::Enable( bool aEnable )
|
||||||
|
{
|
||||||
|
m_textCtrl->Enable( aEnable );
|
||||||
|
m_unitLabel->Enable( aEnable );
|
||||||
|
}
|
|
@ -1697,11 +1697,11 @@ LIB_ALIAS* LIB_PART::RemoveAlias( LIB_ALIAS* aAlias )
|
||||||
bool rename = aAlias->IsRoot();
|
bool rename = aAlias->IsRoot();
|
||||||
|
|
||||||
wxLogTrace( traceSchLibMem,
|
wxLogTrace( traceSchLibMem,
|
||||||
wxT( "%s: part:'%s', alias:'%s', alias count %llu, reference count %ld." ),
|
wxT( "%s: part:'%s', alias:'%s', alias count %u, reference count %d." ),
|
||||||
GetChars( wxString::FromAscii( __WXFUNCTION__ ) ),
|
GetChars( wxString::FromAscii( __WXFUNCTION__ ) ),
|
||||||
GetChars( m_name ),
|
GetChars( m_name ),
|
||||||
GetChars( aAlias->GetName() ),
|
GetChars( aAlias->GetName() ),
|
||||||
(long long unsigned) m_aliases.size(),
|
m_aliases.size(),
|
||||||
m_me.use_count() );
|
m_me.use_count() );
|
||||||
|
|
||||||
it = m_aliases.erase( it );
|
it = m_aliases.erase( it );
|
||||||
|
|
|
@ -146,6 +146,9 @@ public:
|
||||||
#define HIGHLIGHTED (1 << 25) ///< item is drawn in normal colors, when the rest is darkened
|
#define HIGHLIGHTED (1 << 25) ///< item is drawn in normal colors, when the rest is darkened
|
||||||
#define BRIGHTENED (1 << 26) ///< item is drawn with a bright contour
|
#define BRIGHTENED (1 << 26) ///< item is drawn with a bright contour
|
||||||
|
|
||||||
|
#define DP_COUPLED (1 << 27) ///< item is coupled with another item making a differential pair
|
||||||
|
///< (applies to segments only)
|
||||||
|
|
||||||
#define EDA_ITEM_ALL_FLAGS -1
|
#define EDA_ITEM_ALL_FLAGS -1
|
||||||
|
|
||||||
typedef unsigned STATUS_FLAGS;
|
typedef unsigned STATUS_FLAGS;
|
||||||
|
|
|
@ -546,5 +546,8 @@ EXTERN_BITMAP( zoom_out_xpm )
|
||||||
EXTERN_BITMAP( zoom_page_xpm )
|
EXTERN_BITMAP( zoom_page_xpm )
|
||||||
EXTERN_BITMAP( zoom_selection_xpm )
|
EXTERN_BITMAP( zoom_selection_xpm )
|
||||||
EXTERN_BITMAP( zoom_xpm )
|
EXTERN_BITMAP( zoom_xpm )
|
||||||
|
EXTERN_BITMAP( tune_diff_pair_length_legend_xpm )
|
||||||
|
EXTERN_BITMAP( tune_diff_pair_skew_legend_xpm )
|
||||||
|
EXTERN_BITMAP( tune_single_track_length_legend_xpm )
|
||||||
|
|
||||||
#endif // BITMAPS_H_
|
#endif // BITMAPS_H_
|
||||||
|
|
|
@ -129,6 +129,23 @@ public:
|
||||||
m_List.erase( m_List.begin() + aIndex );
|
m_List.erase( m_List.begin() + aIndex );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Remove
|
||||||
|
* removes the item aItem (if exists in the collector).
|
||||||
|
* @param aItem the item to be removed.
|
||||||
|
*/
|
||||||
|
void Remove( const EDA_ITEM* aItem )
|
||||||
|
{
|
||||||
|
for( size_t i = 0; i < m_List.size(); i++ )
|
||||||
|
{
|
||||||
|
if( m_List[i] == aItem )
|
||||||
|
{
|
||||||
|
m_List.erase( m_List.begin() + i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function operator[int]
|
* Function operator[int]
|
||||||
* is used for read only access and returns the object at \a aIndex.
|
* is used for read only access and returns the object at \a aIndex.
|
||||||
|
@ -223,6 +240,22 @@ public:
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Function CountType
|
||||||
|
* counts the number of items matching aType
|
||||||
|
* @param aType type we are interested in
|
||||||
|
* @return number of occurences
|
||||||
|
*/
|
||||||
|
int CountType( KICAD_T aType )
|
||||||
|
{
|
||||||
|
int cnt = 0;
|
||||||
|
for( size_t i = 0; i < m_List.size(); i++ )
|
||||||
|
{
|
||||||
|
if( m_List[i]->Type() == aType )
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Collect
|
* Function Collect
|
||||||
|
|
|
@ -69,7 +69,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetVertices()
|
* Function GetVertices()
|
||||||
* areturn a pointer to the data used by the VERTEX_ITEM.
|
* Returns pointer to the data used by the VERTEX_ITEM.
|
||||||
*/
|
*/
|
||||||
VERTEX* GetVertices() const;
|
VERTEX* GetVertices() const;
|
||||||
|
|
||||||
|
|
|
@ -206,6 +206,13 @@ public:
|
||||||
return sqrt( SquaredDistance( aP ) );
|
return sqrt( SquaredDistance( aP ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanonicalCoefs( ecoord& qA, ecoord& qB, ecoord& qC ) const
|
||||||
|
{
|
||||||
|
qA = A.y - B.y;
|
||||||
|
qB = B.x - A.x;
|
||||||
|
qC = -qA * A.x - qB * A.y;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Collinear()
|
* Function Collinear()
|
||||||
*
|
*
|
||||||
|
@ -215,9 +222,8 @@ public:
|
||||||
*/
|
*/
|
||||||
bool Collinear( const SEG& aSeg ) const
|
bool Collinear( const SEG& aSeg ) const
|
||||||
{
|
{
|
||||||
ecoord qa = A.y - B.y;
|
ecoord qa, qb, qc;
|
||||||
ecoord qb = B.x - A.x;
|
CanonicalCoefs( qa, qb, qc );
|
||||||
ecoord qc = -qa * A.x - qb * A.y;
|
|
||||||
|
|
||||||
ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc );
|
ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc );
|
||||||
ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc );
|
ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc );
|
||||||
|
@ -225,6 +231,29 @@ public:
|
||||||
return ( d1 <= 1 && d2 <= 1 );
|
return ( d1 <= 1 && d2 <= 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ApproxCollinear( const SEG& aSeg ) const
|
||||||
|
{
|
||||||
|
ecoord p, q, r;
|
||||||
|
CanonicalCoefs( p, q, r );
|
||||||
|
|
||||||
|
ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q );
|
||||||
|
ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q );
|
||||||
|
|
||||||
|
return std::abs( dist1 ) <= 1 && std::abs( dist2 ) <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ApproxParallel ( const SEG& aSeg ) const
|
||||||
|
{
|
||||||
|
ecoord p, q, r;
|
||||||
|
CanonicalCoefs( p, q, r );
|
||||||
|
|
||||||
|
ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q );
|
||||||
|
ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q );
|
||||||
|
|
||||||
|
return std::abs( dist1 - dist2 ) <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Overlaps( const SEG& aSeg ) const
|
bool Overlaps( const SEG& aSeg ) const
|
||||||
{
|
{
|
||||||
if( aSeg.A == aSeg.B ) // single point corner case
|
if( aSeg.A == aSeg.B ) // single point corner case
|
||||||
|
@ -262,6 +291,8 @@ public:
|
||||||
return ( A - B ).SquaredEuclideanNorm();
|
return ( A - B ).SquaredEuclideanNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ecoord TCoef( const VECTOR2I& aP ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Index()
|
* Function Index()
|
||||||
*
|
*
|
||||||
|
@ -277,7 +308,11 @@ public:
|
||||||
|
|
||||||
bool PointCloserThan( const VECTOR2I& aP, int aDist ) const;
|
bool PointCloserThan( const VECTOR2I& aP, int aDist ) const;
|
||||||
|
|
||||||
// friend std::ostream& operator<<( std::ostream& stream, const SEG& aSeg );
|
void Reverse()
|
||||||
|
{
|
||||||
|
std::swap( A, B );
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I &aC ) const;
|
bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I &aC ) const;
|
||||||
|
|
||||||
|
@ -285,14 +320,21 @@ private:
|
||||||
int m_index;
|
int m_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const
|
inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const
|
||||||
{
|
{
|
||||||
// fixme: numerical errors for large integers
|
VECTOR2I d = B - A;
|
||||||
assert( false );
|
ecoord l_squared = d.Dot( d );
|
||||||
return VECTOR2I( 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if( l_squared == 0 )
|
||||||
|
return A;
|
||||||
|
|
||||||
|
ecoord t = d.Dot( aP - A );
|
||||||
|
|
||||||
|
int xp = rescale( t, (ecoord)d.x, l_squared );
|
||||||
|
int yp = rescale( t, (ecoord)d.y, l_squared );
|
||||||
|
|
||||||
|
return A + VECTOR2I( xp, yp );
|
||||||
|
}
|
||||||
|
|
||||||
inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const
|
inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const
|
||||||
{
|
{
|
||||||
|
@ -305,6 +347,11 @@ inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const
|
||||||
return aDetermineSide ? dist : abs( dist );
|
return aDetermineSide ? dist : abs( dist );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline SEG::ecoord SEG::TCoef( const VECTOR2I& aP ) const
|
||||||
|
{
|
||||||
|
VECTOR2I d = B - A;
|
||||||
|
return d.Dot( aP - A);
|
||||||
|
}
|
||||||
|
|
||||||
inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
|
inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
|
||||||
{
|
{
|
||||||
|
@ -327,7 +374,6 @@ inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
|
||||||
return A + VECTOR2I( xp, yp );
|
return A + VECTOR2I( xp, yp );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg )
|
inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg )
|
||||||
{
|
{
|
||||||
aStream << "[ " << aSeg.A << " - " << aSeg.B << " ]";
|
aStream << "[ " << aSeg.A << " - " << aSeg.B << " ]";
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <math/vector2d.h>
|
#include <math/vector2d.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BOX2
|
* Class BOX2
|
||||||
|
@ -467,6 +468,8 @@ public:
|
||||||
typedef BOX2<VECTOR2I> BOX2I;
|
typedef BOX2<VECTOR2I> BOX2I;
|
||||||
typedef BOX2<VECTOR2D> BOX2D;
|
typedef BOX2<VECTOR2D> BOX2D;
|
||||||
|
|
||||||
|
typedef boost::optional<BOX2I> OPT_BOX2I;
|
||||||
|
|
||||||
// FIXME should be removed to avoid multiple typedefs for the same type
|
// FIXME should be removed to avoid multiple typedefs for the same type
|
||||||
typedef BOX2D DBOX;
|
typedef BOX2D DBOX;
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,16 @@ public:
|
||||||
ALL = 0xff
|
ALL = 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
VIEW_ITEM() : m_view( NULL ), m_visible( true ), m_requiredUpdate( ALL ),
|
/**
|
||||||
|
* Enum VIEW_VISIBILITY_FLAGS.
|
||||||
|
* Defines the visibility of the item (temporarily hidden, invisible, etc).
|
||||||
|
*/
|
||||||
|
enum VIEW_VISIBILITY_FLAGS {
|
||||||
|
VISIBLE = 0x01, /// Item is visible (in general)
|
||||||
|
HIDDEN = 0x02 /// Item is temporarily hidden (e.g. being used by a tool). Overrides VISIBLE flag.
|
||||||
|
};
|
||||||
|
|
||||||
|
VIEW_ITEM() : m_view( NULL ), m_flags( VISIBLE ), m_requiredUpdate( ALL ),
|
||||||
m_groups( NULL ), m_groupsSize( 0 ) {}
|
m_groups( NULL ), m_groupsSize( 0 ) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,7 +137,39 @@ public:
|
||||||
*
|
*
|
||||||
* @param aIsVisible: whether the item is visible (on all layers), or not.
|
* @param aIsVisible: whether the item is visible (on all layers), or not.
|
||||||
*/
|
*/
|
||||||
void ViewSetVisible( bool aIsVisible = true );
|
void ViewSetVisible( bool aIsVisible = true )
|
||||||
|
{
|
||||||
|
bool cur_visible = m_flags & VISIBLE;
|
||||||
|
|
||||||
|
if( cur_visible != aIsVisible )
|
||||||
|
{
|
||||||
|
if( aIsVisible )
|
||||||
|
m_flags |= VISIBLE;
|
||||||
|
else
|
||||||
|
m_flags &= ~VISIBLE;
|
||||||
|
|
||||||
|
ViewUpdate( APPEARANCE | COLOR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function ViewHide()
|
||||||
|
* Temporarily hides the item in the view (e.g. for overlaying)
|
||||||
|
*
|
||||||
|
* @param aHide: whether the item is hidden (on all layers), or not.
|
||||||
|
*/
|
||||||
|
void ViewHide( bool aHide = true )
|
||||||
|
{
|
||||||
|
if( !( m_flags & VISIBLE ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( aHide )
|
||||||
|
m_flags |= HIDDEN;
|
||||||
|
else
|
||||||
|
m_flags &= ~HIDDEN;
|
||||||
|
|
||||||
|
ViewUpdate( APPEARANCE );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function ViewIsVisible()
|
* Function ViewIsVisible()
|
||||||
|
@ -139,7 +180,7 @@ public:
|
||||||
*/
|
*/
|
||||||
bool ViewIsVisible() const
|
bool ViewIsVisible() const
|
||||||
{
|
{
|
||||||
return m_visible;
|
return m_flags & VISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -201,7 +242,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
VIEW* m_view; ///< Current dynamic view the item is assigned to.
|
VIEW* m_view; ///< Current dynamic view the item is assigned to.
|
||||||
bool m_visible; ///< Are we visible in the current dynamic VIEW.
|
int m_flags; ///< Visibility flags
|
||||||
int m_requiredUpdate; ///< Flag required for updating
|
int m_requiredUpdate; ///< Flag required for updating
|
||||||
|
|
||||||
///* Helper for storing cached items group ids
|
///* Helper for storing cached items group ids
|
||||||
|
@ -295,6 +336,15 @@ protected:
|
||||||
{
|
{
|
||||||
m_requiredUpdate = NONE;
|
m_requiredUpdate = NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function isRenderable()
|
||||||
|
* Returns if the item should be drawn or not.
|
||||||
|
*/
|
||||||
|
bool isRenderable() const
|
||||||
|
{
|
||||||
|
return m_flags == VISIBLE;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // namespace KIGFX
|
} // namespace KIGFX
|
||||||
|
|
||||||
|
|
|
@ -658,6 +658,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void SetFastGrid2();
|
void SetFastGrid2();
|
||||||
|
|
||||||
|
void ClearSelection();
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __WX_STATUS_POPUP_H_
|
||||||
|
#define __WX_STATUS_POPUP_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <wx/popupwin.h>
|
||||||
|
|
||||||
|
class PCB_EDIT_FRAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class WX_STATUS_POPUP
|
||||||
|
*
|
||||||
|
* A tiny, headerless popup window used to display useful status (e.g. line length
|
||||||
|
* tuning info) next to the mouse cursor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class WX_STATUS_POPUP: public wxPopupWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WX_STATUS_POPUP( PCB_EDIT_FRAME* aParent );
|
||||||
|
virtual ~WX_STATUS_POPUP();
|
||||||
|
|
||||||
|
virtual void Popup(wxWindow* aFocus = NULL);
|
||||||
|
virtual void Move( const wxPoint &aWhere );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void updateSize();
|
||||||
|
|
||||||
|
wxPanel* m_panel;
|
||||||
|
wxBoxSizer* m_topSizer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __WX_STATUS_POPUP_H_*/
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014-2015 CERN
|
||||||
|
* Author: Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __WX_UNIT_BINDER_H_
|
||||||
|
#define __WX_UNIT_BINDER_H_
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <wx/spinbutt.h>
|
||||||
|
|
||||||
|
class wxTextCtrl;
|
||||||
|
class wxSpinButton;
|
||||||
|
class wxStaticText;
|
||||||
|
|
||||||
|
class WX_UNIT_BINDER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param aParent is the parent window.
|
||||||
|
* @param aTextInput is the text input widget used to edit the given value.
|
||||||
|
* @param aUnitLabel is the units label displayed next to the text field.
|
||||||
|
* @param aSpinButton is an optional spin button (for adjusting the input value)
|
||||||
|
*/
|
||||||
|
WX_UNIT_BINDER( wxWindow* aParent, wxTextCtrl* aTextInput, wxStaticText* aUnitLabel, wxSpinButton* aSpinButton = NULL );
|
||||||
|
|
||||||
|
virtual ~WX_UNIT_BINDER();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetValue
|
||||||
|
* Sets new value (in Internal Units) for the text field, taking care of units conversion.
|
||||||
|
* @param aValue is the new value.
|
||||||
|
*/
|
||||||
|
virtual void SetValue( int aValue );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetValue
|
||||||
|
* Returns the current value in Internal Units.
|
||||||
|
*/
|
||||||
|
virtual int GetValue() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Enable
|
||||||
|
* Enables/diasables the binded widgets
|
||||||
|
*/
|
||||||
|
void Enable( bool aEnable );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void onTextChanged( wxEvent& aEvent );
|
||||||
|
|
||||||
|
///> Text input control.
|
||||||
|
wxTextCtrl* m_textCtrl;
|
||||||
|
|
||||||
|
///> Label showing currently used units.
|
||||||
|
wxStaticText* m_unitLabel;
|
||||||
|
|
||||||
|
///> Currently used units.
|
||||||
|
EDA_UNITS_T m_units;
|
||||||
|
|
||||||
|
///> Step size (added/subtracted difference if spin buttons are used).
|
||||||
|
int m_step;
|
||||||
|
int m_min;
|
||||||
|
int m_max;
|
||||||
|
|
||||||
|
///> Default value (or non-specified)
|
||||||
|
static const wxString DEFAULT_VALUE;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __WX_UNIT_BINDER_H_ */
|
|
@ -108,6 +108,10 @@ set( PCBNEW_DIALOGS
|
||||||
dialogs/dialog_pns_settings_base.cpp
|
dialogs/dialog_pns_settings_base.cpp
|
||||||
dialogs/dialog_move_exact.cpp
|
dialogs/dialog_move_exact.cpp
|
||||||
dialogs/dialog_move_exact_base.cpp
|
dialogs/dialog_move_exact_base.cpp
|
||||||
|
dialogs/dialog_pns_diff_pair_dimensions.cpp
|
||||||
|
dialogs/dialog_pns_diff_pair_dimensions_base.cpp
|
||||||
|
dialogs/dialog_pns_length_tuning_settings.cpp
|
||||||
|
dialogs/dialog_pns_length_tuning_settings_base.cpp
|
||||||
dialogs/dialog_non_copper_zones_properties.cpp
|
dialogs/dialog_non_copper_zones_properties.cpp
|
||||||
dialogs/dialog_non_copper_zones_properties_base.cpp
|
dialogs/dialog_non_copper_zones_properties_base.cpp
|
||||||
dialogs/dialog_pad_properties.cpp
|
dialogs/dialog_pad_properties.cpp
|
||||||
|
@ -279,6 +283,8 @@ set( PCBNEW_CLASS_SRCS
|
||||||
tools/module_tools.cpp
|
tools/module_tools.cpp
|
||||||
tools/placement_tool.cpp
|
tools/placement_tool.cpp
|
||||||
tools/common_actions.cpp
|
tools/common_actions.cpp
|
||||||
|
tools/grid_helper.cpp
|
||||||
|
tools/tools_common.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set( PCBNEW_SRCS ${PCBNEW_AUTOROUTER_SRCS} ${PCBNEW_CLASS_SRCS} ${PCBNEW_DIALOGS} )
|
set( PCBNEW_SRCS ${PCBNEW_AUTOROUTER_SRCS} ${PCBNEW_CLASS_SRCS} ${PCBNEW_DIALOGS} )
|
||||||
|
|
|
@ -387,7 +387,7 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
|
||||||
BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii );
|
BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii );
|
||||||
|
|
||||||
// For texts belonging to modules, we need to save state of the parent module
|
// For texts belonging to modules, we need to save state of the parent module
|
||||||
if( item->Type() == PCB_MODULE_TEXT_T )
|
if( item->Type() == PCB_MODULE_TEXT_T || item->Type() == PCB_PAD_T )
|
||||||
{
|
{
|
||||||
item = item->GetParent();
|
item = item->GetParent();
|
||||||
wxASSERT( item->Type() == PCB_MODULE_T );
|
wxASSERT( item->Type() == PCB_MODULE_T );
|
||||||
|
|
|
@ -69,6 +69,11 @@ public:
|
||||||
/// skip the linked list stuff, and parent
|
/// skip the linked list stuff, and parent
|
||||||
const DRAWSEGMENT& operator = ( const DRAWSEGMENT& rhs );
|
const DRAWSEGMENT& operator = ( const DRAWSEGMENT& rhs );
|
||||||
|
|
||||||
|
static inline bool ClassOf( const EDA_ITEM* aItem )
|
||||||
|
{
|
||||||
|
return aItem && PCB_LINE_T == aItem->Type();
|
||||||
|
}
|
||||||
|
|
||||||
void SetWidth( int aWidth ) { m_Width = aWidth; }
|
void SetWidth( int aWidth ) { m_Width = aWidth; }
|
||||||
int GetWidth() const { return m_Width; }
|
int GetWidth() const { return m_Width; }
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ MODULE::MODULE( BOARD* parent ) :
|
||||||
m_Attributs = MOD_DEFAULT;
|
m_Attributs = MOD_DEFAULT;
|
||||||
m_Layer = F_Cu;
|
m_Layer = F_Cu;
|
||||||
m_Orient = 0;
|
m_Orient = 0;
|
||||||
m_ModuleStatus = 0;
|
m_ModuleStatus = MODULE_PADS_LOCKED;
|
||||||
flag = 0;
|
flag = 0;
|
||||||
m_CntRot90 = m_CntRot180 = 0;
|
m_CntRot90 = m_CntRot180 = 0;
|
||||||
m_Surface = 0.0;
|
m_Surface = 0.0;
|
||||||
|
@ -1241,3 +1241,20 @@ bool MODULE::IncrementReference( bool aFillSequenceGaps )
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double MODULE::PadCoverageRatio() const
|
||||||
|
{
|
||||||
|
double padArea = 0.0;
|
||||||
|
double moduleArea = GetFootprintRect().GetArea();
|
||||||
|
|
||||||
|
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
|
||||||
|
padArea += pad->GetBoundingBox().GetArea();
|
||||||
|
|
||||||
|
if( moduleArea == 0.0 )
|
||||||
|
return 1.0;
|
||||||
|
|
||||||
|
double ratio = padArea / moduleArea;
|
||||||
|
|
||||||
|
return std::min( ratio, 1.0 );
|
||||||
|
}
|
||||||
|
|
|
@ -232,6 +232,7 @@ public:
|
||||||
#define MODULE_is_LOCKED 0x01 ///< module LOCKED: no autoplace allowed
|
#define MODULE_is_LOCKED 0x01 ///< module LOCKED: no autoplace allowed
|
||||||
#define MODULE_is_PLACED 0x02 ///< In autoplace: module automatically placed
|
#define MODULE_is_PLACED 0x02 ///< In autoplace: module automatically placed
|
||||||
#define MODULE_to_PLACE 0x04 ///< In autoplace: module waiting for autoplace
|
#define MODULE_to_PLACE 0x04 ///< In autoplace: module waiting for autoplace
|
||||||
|
#define MODULE_PADS_LOCKED 0x08 ///< In autoplace: module waiting for autoplace
|
||||||
|
|
||||||
|
|
||||||
bool IsLocked() const
|
bool IsLocked() const
|
||||||
|
@ -270,6 +271,16 @@ public:
|
||||||
m_ModuleStatus &= ~MODULE_to_PLACE;
|
m_ModuleStatus &= ~MODULE_to_PLACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PadsLocked() const { return ( m_ModuleStatus & MODULE_PADS_LOCKED ); }
|
||||||
|
|
||||||
|
void SetPadsLocked( bool aPadsLocked )
|
||||||
|
{
|
||||||
|
if( aPadsLocked )
|
||||||
|
m_ModuleStatus |= MODULE_PADS_LOCKED;
|
||||||
|
else
|
||||||
|
m_ModuleStatus &= ~MODULE_PADS_LOCKED;
|
||||||
|
}
|
||||||
|
|
||||||
void SetLastEditTime( time_t aTime ) { m_LastEditTime = aTime; }
|
void SetLastEditTime( time_t aTime ) { m_LastEditTime = aTime; }
|
||||||
void SetLastEditTime( ) { m_LastEditTime = time( NULL ); }
|
void SetLastEditTime( ) { m_LastEditTime = time( NULL ); }
|
||||||
time_t GetLastEditTime() const { return m_LastEditTime; }
|
time_t GetLastEditTime() const { return m_LastEditTime; }
|
||||||
|
@ -606,6 +617,14 @@ public:
|
||||||
m_initial_comments = aInitialComments;
|
m_initial_comments = aInitialComments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function PadCoverageRatio
|
||||||
|
* Calculates the ratio of total area of the footprint pads to the area of the
|
||||||
|
* footprint. Used by selection tool heuristics.
|
||||||
|
* @return the ratio
|
||||||
|
*/
|
||||||
|
double PadCoverageRatio() const;
|
||||||
|
|
||||||
/// Return the initial comments block or NULL if none, without transfer of ownership.
|
/// Return the initial comments block or NULL if none, without transfer of ownership.
|
||||||
const wxArrayString* GetInitialComments() const { return m_initial_comments; }
|
const wxArrayString* GetInitialComments() const { return m_initial_comments; }
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,6 @@ const EDA_RECT D_PAD::GetBoundingBox() const
|
||||||
area.SetOrigin( m_Pos.x-dx, m_Pos.y-dy );
|
area.SetOrigin( m_Pos.x-dx, m_Pos.y-dy );
|
||||||
area.SetSize( 2*dx, 2*dy );
|
area.SetSize( 2*dx, 2*dy );
|
||||||
break;
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case PAD_RECT:
|
case PAD_RECT:
|
||||||
//Use two corners and track their rotation
|
//Use two corners and track their rotation
|
||||||
|
|
|
@ -94,6 +94,11 @@ public:
|
||||||
///< used for edge board connectors
|
///< used for edge board connectors
|
||||||
static LSET UnplatedHoleMask(); ///< layer set for a mechanical unplated through hole pad
|
static LSET UnplatedHoleMask(); ///< layer set for a mechanical unplated through hole pad
|
||||||
|
|
||||||
|
static inline bool ClassOf( const EDA_ITEM* aItem )
|
||||||
|
{
|
||||||
|
return aItem && PCB_PAD_T == aItem->Type();
|
||||||
|
}
|
||||||
|
|
||||||
void Copy( D_PAD* source );
|
void Copy( D_PAD* source );
|
||||||
|
|
||||||
D_PAD* Next() const { return static_cast<D_PAD*>( Pnext ); }
|
D_PAD* Next() const { return static_cast<D_PAD*>( Pnext ); }
|
||||||
|
|
|
@ -49,6 +49,11 @@ public:
|
||||||
|
|
||||||
~TEXTE_PCB();
|
~TEXTE_PCB();
|
||||||
|
|
||||||
|
static inline bool ClassOf( const EDA_ITEM* aItem )
|
||||||
|
{
|
||||||
|
return aItem && PCB_TEXT_T == aItem->Type();
|
||||||
|
}
|
||||||
|
|
||||||
virtual const wxPoint& GetPosition() const
|
virtual const wxPoint& GetPosition() const
|
||||||
{
|
{
|
||||||
return m_Pos;
|
return m_Pos;
|
||||||
|
|
|
@ -313,12 +313,19 @@ void DIALOG_MODULE_BOARD_EDITOR::InitModeditProperties()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_AutoPlaceCtrl->SetSelection( (m_CurrentModule->IsLocked()) ? 1 : 0 );
|
if( m_CurrentModule->IsLocked() )
|
||||||
|
m_AutoPlaceCtrl->SetSelection( 2 );
|
||||||
|
else if( m_CurrentModule->PadsLocked() )
|
||||||
|
m_AutoPlaceCtrl->SetSelection( 1 );
|
||||||
|
else
|
||||||
|
m_AutoPlaceCtrl->SetSelection( 0 );
|
||||||
|
|
||||||
m_AutoPlaceCtrl->SetItemToolTip( 0,
|
m_AutoPlaceCtrl->SetItemToolTip( 0,
|
||||||
_( "Enable hotkey move commands and Auto Placement" ) );
|
_( "Component can be freely moved and auto placed. User can arbitrarily select and edit component's pads." ) );
|
||||||
m_AutoPlaceCtrl->SetItemToolTip( 1,
|
m_AutoPlaceCtrl->SetItemToolTip( 1,
|
||||||
_( "Disable hotkey move commands and Auto Placement" ) );
|
_( "Component can be freely moved and auto placed, but its pads cannot be selected or edited." ) );
|
||||||
|
m_AutoPlaceCtrl->SetItemToolTip( 2,
|
||||||
|
_( "Component is locked: it cannot be freely moved or auto placed." ) );
|
||||||
|
|
||||||
m_CostRot90Ctrl->SetValue( m_CurrentModule->GetPlacementCost90() );
|
m_CostRot90Ctrl->SetValue( m_CurrentModule->GetPlacementCost90() );
|
||||||
|
|
||||||
|
@ -583,7 +590,8 @@ void DIALOG_MODULE_BOARD_EDITOR::OnOkClick( wxCommandEvent& event )
|
||||||
modpos.x = ValueFromTextCtrl( *m_ModPositionX );
|
modpos.x = ValueFromTextCtrl( *m_ModPositionX );
|
||||||
modpos.y = ValueFromTextCtrl( *m_ModPositionY );
|
modpos.y = ValueFromTextCtrl( *m_ModPositionY );
|
||||||
m_CurrentModule->SetPosition( modpos );
|
m_CurrentModule->SetPosition( modpos );
|
||||||
m_CurrentModule->SetLocked( m_AutoPlaceCtrl->GetSelection() == 1 );
|
m_CurrentModule->SetLocked( m_AutoPlaceCtrl->GetSelection() == 2 );
|
||||||
|
m_CurrentModule->SetPadsLocked( m_AutoPlaceCtrl->GetSelection() == 1 );
|
||||||
|
|
||||||
switch( m_AttributsCtrl->GetSelection() )
|
switch( m_AttributsCtrl->GetSelection() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -143,10 +143,10 @@ DIALOG_MODULE_BOARD_EDITOR_BASE::DIALOG_MODULE_BOARD_EDITOR_BASE( wxWindow* pare
|
||||||
m_AttributsCtrl->SetSelection( 0 );
|
m_AttributsCtrl->SetSelection( 0 );
|
||||||
bSizerAttrib->Add( m_AttributsCtrl, 1, wxALL|wxEXPAND, 5 );
|
bSizerAttrib->Add( m_AttributsCtrl, 1, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
wxString m_AutoPlaceCtrlChoices[] = { _("Free"), _("Locked") };
|
wxString m_AutoPlaceCtrlChoices[] = { _("Free"), _("Lock pads"), _("Lock module") };
|
||||||
int m_AutoPlaceCtrlNChoices = sizeof( m_AutoPlaceCtrlChoices ) / sizeof( wxString );
|
int m_AutoPlaceCtrlNChoices = sizeof( m_AutoPlaceCtrlChoices ) / sizeof( wxString );
|
||||||
m_AutoPlaceCtrl = new wxRadioBox( m_PanelProperties, wxID_ANY, _("Move and Place"), wxDefaultPosition, wxDefaultSize, m_AutoPlaceCtrlNChoices, m_AutoPlaceCtrlChoices, 1, wxRA_SPECIFY_COLS );
|
m_AutoPlaceCtrl = new wxRadioBox( m_PanelProperties, wxID_ANY, _("Move and Place"), wxDefaultPosition, wxDefaultSize, m_AutoPlaceCtrlNChoices, m_AutoPlaceCtrlChoices, 1, wxRA_SPECIFY_COLS );
|
||||||
m_AutoPlaceCtrl->SetSelection( 0 );
|
m_AutoPlaceCtrl->SetSelection( 1 );
|
||||||
bSizerAttrib->Add( m_AutoPlaceCtrl, 1, wxALL|wxEXPAND, 5 );
|
bSizerAttrib->Add( m_AutoPlaceCtrl, 1, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2260,7 +2260,7 @@
|
||||||
<property name="caption"></property>
|
<property name="caption"></property>
|
||||||
<property name="caption_visible">1</property>
|
<property name="caption_visible">1</property>
|
||||||
<property name="center_pane">0</property>
|
<property name="center_pane">0</property>
|
||||||
<property name="choices">"Free" "Locked"</property>
|
<property name="choices">"Free" "Lock pads" "Lock module"</property>
|
||||||
<property name="close_button">1</property>
|
<property name="close_button">1</property>
|
||||||
<property name="context_help"></property>
|
<property name="context_help"></property>
|
||||||
<property name="context_menu">1</property>
|
<property name="context_menu">1</property>
|
||||||
|
@ -2292,7 +2292,7 @@
|
||||||
<property name="pin_button">1</property>
|
<property name="pin_button">1</property>
|
||||||
<property name="pos"></property>
|
<property name="pos"></property>
|
||||||
<property name="resize">Resizable</property>
|
<property name="resize">Resizable</property>
|
||||||
<property name="selection">0</property>
|
<property name="selection">1</property>
|
||||||
<property name="show">1</property>
|
<property name="show">1</property>
|
||||||
<property name="size"></property>
|
<property name="size"></property>
|
||||||
<property name="style">wxRA_SPECIFY_COLS</property>
|
<property name="style">wxRA_SPECIFY_COLS</property>
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push and Shove diff pair dimensions (gap) settings dialog.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dialog_pns_diff_pair_dimensions.h"
|
||||||
|
#include <router/pns_sizes_settings.h>
|
||||||
|
|
||||||
|
DIALOG_PNS_DIFF_PAIR_DIMENSIONS::DIALOG_PNS_DIFF_PAIR_DIMENSIONS( wxWindow* aParent, PNS_SIZES_SETTINGS& aSizes ) :
|
||||||
|
DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE( aParent ),
|
||||||
|
m_traceWidth( this, m_traceWidthText, m_traceWidthUnit ),
|
||||||
|
m_traceGap( this, m_traceGapText, m_traceGapUnit ),
|
||||||
|
m_viaGap( this, m_viaGapText, m_viaGapUnit ),
|
||||||
|
m_sizes( aSizes )
|
||||||
|
{
|
||||||
|
m_traceWidth.SetValue( aSizes.DiffPairWidth() );
|
||||||
|
m_traceGap.SetValue( aSizes.DiffPairGap() );
|
||||||
|
m_viaGap.SetValue( aSizes.DiffPairViaGap() );
|
||||||
|
m_viaTraceGapEqual->SetValue( m_sizes.DiffPairViaGapSameAsTraceGap() );
|
||||||
|
|
||||||
|
updateCheckbox();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::updateCheckbox()
|
||||||
|
{
|
||||||
|
if( m_viaTraceGapEqual->GetValue() )
|
||||||
|
{
|
||||||
|
m_sizes.SetDiffPairViaGapSameAsTraceGap( true );
|
||||||
|
m_viaGapText->Disable();
|
||||||
|
m_viaGapLabel->Disable();
|
||||||
|
m_viaGapUnit->Disable();
|
||||||
|
} else {
|
||||||
|
m_sizes.SetDiffPairViaGapSameAsTraceGap( false );
|
||||||
|
m_viaGapText->Enable();
|
||||||
|
m_viaGapLabel->Enable();
|
||||||
|
m_viaGapUnit->Enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnClose( wxCloseEvent& aEvent )
|
||||||
|
{
|
||||||
|
// Do nothing, it is result of ESC pressing
|
||||||
|
EndModal( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnOkClick( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
// Save widgets' values to settings
|
||||||
|
m_sizes.SetDiffPairGap ( m_traceGap.GetValue() );
|
||||||
|
m_sizes.SetDiffPairViaGap ( m_viaGap.GetValue() );
|
||||||
|
m_sizes.SetDiffPairWidth ( m_traceWidth.GetValue() );
|
||||||
|
|
||||||
|
// todo: verify against design rules
|
||||||
|
EndModal( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnCancelClick( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
EndModal( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnViaTraceGapEqualCheck( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
event.Skip();
|
||||||
|
updateCheckbox();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.or/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push and Shove diff pair dimensions (gap) settings dialog.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __dialog_diff_pair_dimensions_settings__
|
||||||
|
#define __dialog_diff_pair_dimensions_settings__
|
||||||
|
|
||||||
|
#include <wx_unit_binder.h>
|
||||||
|
|
||||||
|
#include "dialog_pns_diff_pair_dimensions_base.h"
|
||||||
|
|
||||||
|
class PNS_SIZES_SETTINGS;
|
||||||
|
|
||||||
|
class DIALOG_PNS_DIFF_PAIR_DIMENSIONS : public DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DIALOG_PNS_DIFF_PAIR_DIMENSIONS( wxWindow* aParent, PNS_SIZES_SETTINGS& aSizes );
|
||||||
|
|
||||||
|
virtual void OnClose( wxCloseEvent& aEvent );
|
||||||
|
virtual void OnOkClick( wxCommandEvent& aEvent );
|
||||||
|
virtual void OnCancelClick( wxCommandEvent& aEvent );
|
||||||
|
virtual void OnViaTraceGapEqualCheck( wxCommandEvent& event );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateCheckbox();
|
||||||
|
|
||||||
|
WX_UNIT_BINDER m_traceWidth;
|
||||||
|
WX_UNIT_BINDER m_traceGap;
|
||||||
|
WX_UNIT_BINDER m_viaGap;
|
||||||
|
|
||||||
|
PNS_SIZES_SETTINGS& m_sizes;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __dialog_pns_settings__
|
|
@ -0,0 +1,102 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++ code generated with wxFormBuilder (version Jun 6 2014)
|
||||||
|
// http://www.wxformbuilder.org/
|
||||||
|
//
|
||||||
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "dialog_pns_diff_pair_dimensions_base.h"
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
|
||||||
|
{
|
||||||
|
this->SetSizeHints( wxSize( 400,-1 ), wxDefaultSize );
|
||||||
|
|
||||||
|
wxBoxSizer* bSizer7;
|
||||||
|
bSizer7 = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
wxFlexGridSizer* fgSizer1;
|
||||||
|
fgSizer1 = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||||
|
fgSizer1->AddGrowableCol( 1 );
|
||||||
|
fgSizer1->SetFlexibleDirection( wxBOTH );
|
||||||
|
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||||
|
|
||||||
|
m_traceWidthLabel = new wxStaticText( this, wxID_ANY, _("Width:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_traceWidthLabel->Wrap( -1 );
|
||||||
|
fgSizer1->Add( m_traceWidthLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
|
||||||
|
|
||||||
|
m_traceWidthText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer1->Add( m_traceWidthText, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_traceWidthUnit = new wxStaticText( this, wxID_ANY, _("u"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_traceWidthUnit->Wrap( -1 );
|
||||||
|
fgSizer1->Add( m_traceWidthUnit, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_traceGapLabel = new wxStaticText( this, wxID_ANY, _("Trace gap:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_traceGapLabel->Wrap( -1 );
|
||||||
|
fgSizer1->Add( m_traceGapLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
|
||||||
|
|
||||||
|
m_traceGapText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer1->Add( m_traceGapText, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_traceGapUnit = new wxStaticText( this, wxID_ANY, _("u"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_traceGapUnit->Wrap( -1 );
|
||||||
|
m_traceGapUnit->SetMaxSize( wxSize( 40,-1 ) );
|
||||||
|
|
||||||
|
fgSizer1->Add( m_traceGapUnit, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_viaGapLabel = new wxStaticText( this, wxID_ANY, _("Via gap:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_viaGapLabel->Wrap( -1 );
|
||||||
|
m_viaGapLabel->Enable( false );
|
||||||
|
|
||||||
|
fgSizer1->Add( m_viaGapLabel, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_viaGapText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_viaGapText->Enable( false );
|
||||||
|
|
||||||
|
fgSizer1->Add( m_viaGapText, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_viaGapUnit = new wxStaticText( this, wxID_ANY, _("u"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_viaGapUnit->Wrap( -1 );
|
||||||
|
m_viaGapUnit->Enable( false );
|
||||||
|
m_viaGapUnit->SetMaxSize( wxSize( 40,-1 ) );
|
||||||
|
|
||||||
|
fgSizer1->Add( m_viaGapUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
bSizer7->Add( fgSizer1, 0, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_viaTraceGapEqual = new wxCheckBox( this, wxID_ANY, _("Via gap same as trace gap"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_viaTraceGapEqual->SetValue(true);
|
||||||
|
bSizer7->Add( m_viaTraceGapEqual, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_stdButtons = new wxStdDialogButtonSizer();
|
||||||
|
m_stdButtonsOK = new wxButton( this, wxID_OK );
|
||||||
|
m_stdButtons->AddButton( m_stdButtonsOK );
|
||||||
|
m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
|
||||||
|
m_stdButtons->AddButton( m_stdButtonsCancel );
|
||||||
|
m_stdButtons->Realize();
|
||||||
|
|
||||||
|
bSizer7->Add( m_stdButtons, 0, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
this->SetSizer( bSizer7 );
|
||||||
|
this->Layout();
|
||||||
|
|
||||||
|
// Connect Events
|
||||||
|
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnClose ) );
|
||||||
|
m_viaTraceGapEqual->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::onViaTraceGapEqualCheck ), NULL, this );
|
||||||
|
m_stdButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnCancelClick ), NULL, this );
|
||||||
|
m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnOkClick ), NULL, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::~DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE()
|
||||||
|
{
|
||||||
|
// Disconnect Events
|
||||||
|
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnClose ) );
|
||||||
|
m_viaTraceGapEqual->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::onViaTraceGapEqualCheck ), NULL, this );
|
||||||
|
m_stdButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnCancelClick ), NULL, this );
|
||||||
|
m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnOkClick ), NULL, this );
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,68 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++ code generated with wxFormBuilder (version Jun 6 2014)
|
||||||
|
// http://www.wxformbuilder.org/
|
||||||
|
//
|
||||||
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE_H__
|
||||||
|
#define __DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE_H__
|
||||||
|
|
||||||
|
#include <wx/artprov.h>
|
||||||
|
#include <wx/xrc/xmlres.h>
|
||||||
|
#include <wx/intl.h>
|
||||||
|
class DIALOG_SHIM;
|
||||||
|
|
||||||
|
#include "dialog_shim.h"
|
||||||
|
#include <wx/string.h>
|
||||||
|
#include <wx/stattext.h>
|
||||||
|
#include <wx/gdicmn.h>
|
||||||
|
#include <wx/font.h>
|
||||||
|
#include <wx/colour.h>
|
||||||
|
#include <wx/settings.h>
|
||||||
|
#include <wx/textctrl.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
|
#include <wx/checkbox.h>
|
||||||
|
#include <wx/button.h>
|
||||||
|
#include <wx/dialog.h>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Class DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
class DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE : public DIALOG_SHIM
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxStaticText* m_traceWidthLabel;
|
||||||
|
wxTextCtrl* m_traceWidthText;
|
||||||
|
wxStaticText* m_traceWidthUnit;
|
||||||
|
wxStaticText* m_traceGapLabel;
|
||||||
|
wxTextCtrl* m_traceGapText;
|
||||||
|
wxStaticText* m_traceGapUnit;
|
||||||
|
wxStaticText* m_viaGapLabel;
|
||||||
|
wxTextCtrl* m_viaGapText;
|
||||||
|
wxStaticText* m_viaGapUnit;
|
||||||
|
wxCheckBox* m_viaTraceGapEqual;
|
||||||
|
wxStdDialogButtonSizer* m_stdButtons;
|
||||||
|
wxButton* m_stdButtonsOK;
|
||||||
|
wxButton* m_stdButtonsCancel;
|
||||||
|
|
||||||
|
// Virtual event handlers, overide them in your derived class
|
||||||
|
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||||
|
virtual void onViaTraceGapEqualCheck( wxCommandEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Differential Pair Dimensions"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 400,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||||
|
~DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE_H__
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length tuner settings dialog.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dialog_pns_length_tuning_settings.h"
|
||||||
|
#include <router/pns_meander_placer.h>
|
||||||
|
|
||||||
|
DIALOG_PNS_LENGTH_TUNING_SETTINGS::DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow* aParent, PNS_MEANDER_SETTINGS& aSettings, PNS_ROUTER_MODE aMode ) :
|
||||||
|
DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE( aParent ),
|
||||||
|
m_minAmpl( this, m_minAmplText, m_minAmplUnit ),
|
||||||
|
m_maxAmpl( this, m_maxAmplText, m_maxAmplUnit ),
|
||||||
|
m_spacing( this, m_spacingText, m_spacingUnit ),
|
||||||
|
m_targetLength( this, m_targetLengthText, m_targetLengthUnit ),
|
||||||
|
m_settings( aSettings ),
|
||||||
|
m_mode( aMode )
|
||||||
|
{
|
||||||
|
m_miterStyle->Enable( false );
|
||||||
|
m_radiusText->Enable( aMode != PNS_MODE_TUNE_DIFF_PAIR );
|
||||||
|
//m_minAmpl.Enable ( aMode != PNS_MODE_TUNE_DIFF_PAIR_SKEW );
|
||||||
|
|
||||||
|
m_minAmpl.SetValue( m_settings.m_minAmplitude );
|
||||||
|
m_maxAmpl.SetValue( m_settings.m_maxAmplitude );
|
||||||
|
|
||||||
|
m_spacing.SetValue( m_settings.m_spacing );
|
||||||
|
m_radiusText->SetValue( wxString::Format( wxT( "%i" ), m_settings.m_cornerRadiusPercentage ) );
|
||||||
|
|
||||||
|
m_miterStyle->SetSelection( m_settings.m_cornerType == PNS_MEANDER_SETTINGS::ROUND ? 1 : 0 );
|
||||||
|
|
||||||
|
switch( aMode )
|
||||||
|
{
|
||||||
|
case PNS_MODE_TUNE_SINGLE:
|
||||||
|
SetTitle( _( "Single track length tuning" ) );
|
||||||
|
m_legend->SetBitmap( KiBitmap( tune_single_track_length_legend_xpm ) );
|
||||||
|
m_targetLength.SetValue( m_settings.m_targetLength );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PNS_MODE_TUNE_DIFF_PAIR:
|
||||||
|
SetTitle( _( "Differential pair length tuning" ) );
|
||||||
|
m_legend->SetBitmap( KiBitmap( tune_diff_pair_length_legend_xpm ) );
|
||||||
|
m_targetLength.SetValue( m_settings.m_targetLength );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PNS_MODE_TUNE_DIFF_PAIR_SKEW:
|
||||||
|
SetTitle( _( "Differential pair skew tuning" ) );
|
||||||
|
m_legend->SetBitmap( KiBitmap( tune_diff_pair_skew_legend_xpm ) );
|
||||||
|
m_targetLengthLabel->SetLabel( _( "Target skew: " ) );
|
||||||
|
m_targetLength.SetValue ( m_settings.m_targetSkew );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stdButtonsOK->SetDefault();
|
||||||
|
m_targetLengthText->SetSelection( -1, -1 );
|
||||||
|
m_targetLengthText->SetFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_PNS_LENGTH_TUNING_SETTINGS::OnClose( wxCloseEvent& aEvent )
|
||||||
|
{
|
||||||
|
// Do nothing, it is result of ESC pressing
|
||||||
|
EndModal( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_PNS_LENGTH_TUNING_SETTINGS::OnOkClick( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
// fixme: use validators and TransferDataFromWindow
|
||||||
|
m_settings.m_minAmplitude = m_minAmpl.GetValue();
|
||||||
|
m_settings.m_maxAmplitude = m_maxAmpl.GetValue();
|
||||||
|
m_settings.m_spacing = m_spacing.GetValue();
|
||||||
|
|
||||||
|
m_settings.m_cornerRadiusPercentage = wxAtoi( m_radiusText->GetValue() );
|
||||||
|
|
||||||
|
if( m_mode == PNS_MODE_TUNE_DIFF_PAIR_SKEW )
|
||||||
|
m_settings.m_targetSkew = m_targetLength.GetValue();
|
||||||
|
else
|
||||||
|
m_settings.m_targetLength = m_targetLength.GetValue();
|
||||||
|
|
||||||
|
if( m_settings.m_maxAmplitude < m_settings.m_minAmplitude )
|
||||||
|
m_settings.m_maxAmplitude = m_settings.m_maxAmplitude;
|
||||||
|
|
||||||
|
m_settings.m_cornerType = m_miterStyle->GetSelection() ? PNS_MEANDER_SETTINGS::CHAMFER : PNS_MEANDER_SETTINGS::ROUND;
|
||||||
|
|
||||||
|
EndModal( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_PNS_LENGTH_TUNING_SETTINGS::OnCancelClick( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
EndModal( 0 );
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 CERN
|
||||||
|
* Author: Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.or/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push and Shove router settings dialog.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __dialog_pns_length_tuning_settings__
|
||||||
|
#define __dialog_pns_length_tuning_settings__
|
||||||
|
|
||||||
|
#include "dialog_pns_length_tuning_settings_base.h"
|
||||||
|
|
||||||
|
#include <wx_unit_binder.h>
|
||||||
|
|
||||||
|
#include <router/pns_router.h>
|
||||||
|
|
||||||
|
class PNS_MEANDER_SETTINGS;
|
||||||
|
|
||||||
|
class DIALOG_PNS_LENGTH_TUNING_SETTINGS : public DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow* aParent, PNS_MEANDER_SETTINGS& aSettings, PNS_ROUTER_MODE aMode );
|
||||||
|
|
||||||
|
virtual void OnClose( wxCloseEvent& aEvent );
|
||||||
|
virtual void OnOkClick( wxCommandEvent& aEvent );
|
||||||
|
virtual void OnCancelClick( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
private:
|
||||||
|
WX_UNIT_BINDER m_minAmpl;
|
||||||
|
WX_UNIT_BINDER m_maxAmpl;
|
||||||
|
WX_UNIT_BINDER m_spacing;
|
||||||
|
WX_UNIT_BINDER m_targetLength;
|
||||||
|
|
||||||
|
PNS_MEANDER_SETTINGS& m_settings;
|
||||||
|
PNS_ROUTER_MODE m_mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __dialog_pns_settings__
|
|
@ -0,0 +1,183 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++ code generated with wxFormBuilder (version Jun 6 2014)
|
||||||
|
// http://www.wxformbuilder.org/
|
||||||
|
//
|
||||||
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "dialog_pns_length_tuning_settings_base.h"
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
|
||||||
|
{
|
||||||
|
this->SetSizeHints( wxSize( 345,668 ), wxDefaultSize );
|
||||||
|
|
||||||
|
wxBoxSizer* bMainSizer;
|
||||||
|
bMainSizer = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
wxStaticBoxSizer* sbSizer1;
|
||||||
|
sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Length/skew") ), wxVERTICAL );
|
||||||
|
|
||||||
|
wxFlexGridSizer* fgSizer4;
|
||||||
|
fgSizer4 = new wxFlexGridSizer( 0, 2, 0, 0 );
|
||||||
|
fgSizer4->AddGrowableCol( 1 );
|
||||||
|
fgSizer4->SetFlexibleDirection( wxBOTH );
|
||||||
|
fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||||
|
|
||||||
|
m_staticText4 = new wxStaticText( this, wxID_ANY, _("Tune from:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText4->Wrap( -1 );
|
||||||
|
fgSizer4->Add( m_staticText4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
wxArrayString m_choicePathFromChoices;
|
||||||
|
m_choicePathFrom = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choicePathFromChoices, 0 );
|
||||||
|
m_choicePathFrom->SetSelection( 0 );
|
||||||
|
fgSizer4->Add( m_choicePathFrom, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_staticText15 = new wxStaticText( this, wxID_ANY, _("Tune to:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText15->Wrap( -1 );
|
||||||
|
fgSizer4->Add( m_staticText15, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
wxArrayString m_choice4Choices;
|
||||||
|
m_choice4 = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choice4Choices, 0 );
|
||||||
|
m_choice4->SetSelection( 0 );
|
||||||
|
fgSizer4->Add( m_choice4, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
m_staticText3 = new wxStaticText( this, wxID_ANY, _("Constraint:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText3->Wrap( -1 );
|
||||||
|
fgSizer4->Add( m_staticText3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
wxString m_constraintSourceChoices[] = { _("from Design Rules"), _("manual") };
|
||||||
|
int m_constraintSourceNChoices = sizeof( m_constraintSourceChoices ) / sizeof( wxString );
|
||||||
|
m_constraintSource = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_constraintSourceNChoices, m_constraintSourceChoices, 0 );
|
||||||
|
m_constraintSource->SetSelection( 1 );
|
||||||
|
m_constraintSource->Enable( false );
|
||||||
|
|
||||||
|
fgSizer4->Add( m_constraintSource, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_targetLengthLabel = new wxStaticText( this, wxID_ANY, _("Target length:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_targetLengthLabel->Wrap( -1 );
|
||||||
|
fgSizer4->Add( m_targetLengthLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
wxGridSizer* gSizer2;
|
||||||
|
gSizer2 = new wxGridSizer( 0, 2, 0, 0 );
|
||||||
|
|
||||||
|
m_targetLengthText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
gSizer2->Add( m_targetLengthText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_targetLengthUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_targetLengthUnit->Wrap( -1 );
|
||||||
|
gSizer2->Add( m_targetLengthUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
fgSizer4->Add( gSizer2, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
sbSizer1->Add( fgSizer4, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
bMainSizer->Add( sbSizer1, 0, wxEXPAND|wxALL, 5 );
|
||||||
|
|
||||||
|
wxStaticBoxSizer* sbSizer2;
|
||||||
|
sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Meandering") ), wxVERTICAL );
|
||||||
|
|
||||||
|
m_legend = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
sbSizer2->Add( m_legend, 1, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
wxFlexGridSizer* fgSizer3;
|
||||||
|
fgSizer3 = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||||
|
fgSizer3->AddGrowableCol( 2 );
|
||||||
|
fgSizer3->SetFlexibleDirection( wxBOTH );
|
||||||
|
fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||||
|
|
||||||
|
m_staticText9 = new wxStaticText( this, wxID_ANY, _("Min amplitude (Amin):"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText9->Wrap( -1 );
|
||||||
|
fgSizer3->Add( m_staticText9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_minAmplText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer3->Add( m_minAmplText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_minAmplUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_minAmplUnit->Wrap( -1 );
|
||||||
|
fgSizer3->Add( m_minAmplUnit, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
|
||||||
|
|
||||||
|
m_staticText91 = new wxStaticText( this, wxID_ANY, _("Max amplitude (Amax):"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText91->Wrap( -1 );
|
||||||
|
fgSizer3->Add( m_staticText91, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_maxAmplText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer3->Add( m_maxAmplText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_maxAmplUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_maxAmplUnit->Wrap( -1 );
|
||||||
|
fgSizer3->Add( m_maxAmplUnit, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
|
||||||
|
|
||||||
|
m_staticText11 = new wxStaticText( this, wxID_ANY, _("Spacing (s):"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText11->Wrap( -1 );
|
||||||
|
fgSizer3->Add( m_staticText11, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_spacingText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer3->Add( m_spacingText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_spacingUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_spacingUnit->Wrap( -1 );
|
||||||
|
fgSizer3->Add( m_spacingUnit, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
|
||||||
|
|
||||||
|
m_staticText13 = new wxStaticText( this, wxID_ANY, _("Miter radius (r):"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText13->Wrap( -1 );
|
||||||
|
fgSizer3->Add( m_staticText13, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_radiusText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer3->Add( m_radiusText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_radiusUnit = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_radiusUnit->Wrap( -1 );
|
||||||
|
fgSizer3->Add( m_radiusUnit, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
|
||||||
|
|
||||||
|
m_staticText14 = new wxStaticText( this, wxID_ANY, _("Miter style:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText14->Wrap( -1 );
|
||||||
|
m_staticText14->Enable( false );
|
||||||
|
|
||||||
|
fgSizer3->Add( m_staticText14, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
wxString m_miterStyleChoices[] = { _("45 degree"), _("arc") };
|
||||||
|
int m_miterStyleNChoices = sizeof( m_miterStyleChoices ) / sizeof( wxString );
|
||||||
|
m_miterStyle = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_miterStyleNChoices, m_miterStyleChoices, 0 );
|
||||||
|
m_miterStyle->SetSelection( 0 );
|
||||||
|
m_miterStyle->Enable( false );
|
||||||
|
|
||||||
|
fgSizer3->Add( m_miterStyle, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
sbSizer2->Add( fgSizer3, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
bMainSizer->Add( sbSizer2, 1, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_stdButtons = new wxStdDialogButtonSizer();
|
||||||
|
m_stdButtonsOK = new wxButton( this, wxID_OK );
|
||||||
|
m_stdButtons->AddButton( m_stdButtonsOK );
|
||||||
|
m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
|
||||||
|
m_stdButtons->AddButton( m_stdButtonsCancel );
|
||||||
|
m_stdButtons->Realize();
|
||||||
|
|
||||||
|
bMainSizer->Add( m_stdButtons, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
this->SetSizer( bMainSizer );
|
||||||
|
this->Layout();
|
||||||
|
|
||||||
|
// Connect Events
|
||||||
|
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::OnClose ) );
|
||||||
|
m_stdButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::OnCancelClick ), NULL, this );
|
||||||
|
m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::OnOkClick ), NULL, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::~DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE()
|
||||||
|
{
|
||||||
|
// Disconnect Events
|
||||||
|
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::OnClose ) );
|
||||||
|
m_stdButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::OnCancelClick ), NULL, this );
|
||||||
|
m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::OnOkClick ), NULL, this );
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,86 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++ code generated with wxFormBuilder (version Jun 6 2014)
|
||||||
|
// http://www.wxformbuilder.org/
|
||||||
|
//
|
||||||
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE_H__
|
||||||
|
#define __DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE_H__
|
||||||
|
|
||||||
|
#include <wx/artprov.h>
|
||||||
|
#include <wx/xrc/xmlres.h>
|
||||||
|
#include <wx/intl.h>
|
||||||
|
class DIALOG_SHIM;
|
||||||
|
|
||||||
|
#include "dialog_shim.h"
|
||||||
|
#include <wx/string.h>
|
||||||
|
#include <wx/stattext.h>
|
||||||
|
#include <wx/gdicmn.h>
|
||||||
|
#include <wx/font.h>
|
||||||
|
#include <wx/colour.h>
|
||||||
|
#include <wx/settings.h>
|
||||||
|
#include <wx/choice.h>
|
||||||
|
#include <wx/textctrl.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
|
#include <wx/statbox.h>
|
||||||
|
#include <wx/bitmap.h>
|
||||||
|
#include <wx/image.h>
|
||||||
|
#include <wx/icon.h>
|
||||||
|
#include <wx/statbmp.h>
|
||||||
|
#include <wx/button.h>
|
||||||
|
#include <wx/dialog.h>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Class DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
class DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE : public DIALOG_SHIM
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxStaticText* m_staticText4;
|
||||||
|
wxChoice* m_choicePathFrom;
|
||||||
|
wxStaticText* m_staticText15;
|
||||||
|
wxChoice* m_choice4;
|
||||||
|
wxStaticText* m_staticText3;
|
||||||
|
wxChoice* m_constraintSource;
|
||||||
|
wxStaticText* m_targetLengthLabel;
|
||||||
|
wxTextCtrl* m_targetLengthText;
|
||||||
|
wxStaticText* m_targetLengthUnit;
|
||||||
|
wxStaticBitmap* m_legend;
|
||||||
|
wxStaticText* m_staticText9;
|
||||||
|
wxTextCtrl* m_minAmplText;
|
||||||
|
wxStaticText* m_minAmplUnit;
|
||||||
|
wxStaticText* m_staticText91;
|
||||||
|
wxTextCtrl* m_maxAmplText;
|
||||||
|
wxStaticText* m_maxAmplUnit;
|
||||||
|
wxStaticText* m_staticText11;
|
||||||
|
wxTextCtrl* m_spacingText;
|
||||||
|
wxStaticText* m_spacingUnit;
|
||||||
|
wxStaticText* m_staticText13;
|
||||||
|
wxTextCtrl* m_radiusText;
|
||||||
|
wxStaticText* m_radiusUnit;
|
||||||
|
wxStaticText* m_staticText14;
|
||||||
|
wxChoice* m_miterStyle;
|
||||||
|
wxStdDialogButtonSizer* m_stdButtons;
|
||||||
|
wxButton* m_stdButtonsOK;
|
||||||
|
wxButton* m_stdButtonsCancel;
|
||||||
|
|
||||||
|
// Virtual event handlers, overide them in your derived class
|
||||||
|
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Trace length tuning"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 345,668 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||||
|
~DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE_H__
|
|
@ -31,14 +31,19 @@
|
||||||
|
|
||||||
DIALOG_TRACK_VIA_SIZE::DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings ) :
|
DIALOG_TRACK_VIA_SIZE::DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings ) :
|
||||||
DIALOG_TRACK_VIA_SIZE_BASE( aParent ),
|
DIALOG_TRACK_VIA_SIZE_BASE( aParent ),
|
||||||
|
m_trackWidth( aParent, m_trackWidthText, m_trackWidthLabel ),
|
||||||
|
m_viaDiameter( aParent, m_viaDiameterText, m_viaDiameterLabel ),
|
||||||
|
m_viaDrill( aParent, m_viaDrillText, m_viaDrillLabel ),
|
||||||
m_settings( aSettings )
|
m_settings( aSettings )
|
||||||
{
|
{
|
||||||
// Load router settings to dialog fields
|
// Load router settings to dialog fields
|
||||||
m_trackWidth->SetValue( To_User_Unit( m_trackWidth->GetUnits(), m_settings.GetCustomTrackWidth() ) );
|
m_trackWidth.SetValue( m_settings.GetCustomTrackWidth() );
|
||||||
m_viaDiameter->SetValue( To_User_Unit( m_viaDiameter->GetUnits(), m_settings.GetCustomViaSize() ) );
|
m_viaDiameter.SetValue( m_settings.GetCustomViaSize() );
|
||||||
m_viaDrill->SetValue( To_User_Unit( m_viaDrill->GetUnits(), m_settings.GetCustomViaDrill() ) );
|
m_viaDrill.SetValue( m_settings.GetCustomViaDrill() );
|
||||||
|
|
||||||
m_trackWidth->SetFocus();
|
m_trackWidthText->SetFocus();
|
||||||
|
m_trackWidthText->SetSelection( -1, -1 );
|
||||||
|
m_stdButtonsOK->SetDefault();
|
||||||
|
|
||||||
// Pressing ENTER when any of the text input fields is active applies changes
|
// Pressing ENTER when any of the text input fields is active applies changes
|
||||||
#if wxCHECK_VERSION( 3, 0, 0 )
|
#if wxCHECK_VERSION( 3, 0, 0 )
|
||||||
|
@ -54,11 +59,11 @@ DIALOG_TRACK_VIA_SIZE::DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SE
|
||||||
bool DIALOG_TRACK_VIA_SIZE::check()
|
bool DIALOG_TRACK_VIA_SIZE::check()
|
||||||
{
|
{
|
||||||
// Wrong input
|
// Wrong input
|
||||||
if( !m_trackWidth->GetValue() || !m_viaDiameter->GetValue() || !m_viaDrill->GetValue() )
|
if( m_trackWidth.GetValue() < 0 || m_viaDiameter.GetValue() < 0 || m_viaDrill.GetValue() < 0 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Via drill should be smaller than via diameter
|
// Via drill should be smaller than via diameter
|
||||||
if( m_viaDrill->GetValue() >= m_viaDiameter->GetValue() )
|
if( m_viaDrill.GetValue() >= m_viaDiameter.GetValue() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -76,15 +81,15 @@ void DIALOG_TRACK_VIA_SIZE::onOkClick( wxCommandEvent& aEvent )
|
||||||
if( check() )
|
if( check() )
|
||||||
{
|
{
|
||||||
// Store dialog values to the router settings
|
// Store dialog values to the router settings
|
||||||
m_settings.SetCustomTrackWidth( From_User_Unit( m_trackWidth->GetUnits(), *m_trackWidth->GetValue() ) );
|
m_settings.SetCustomTrackWidth( m_trackWidth.GetValue() );
|
||||||
m_settings.SetCustomViaSize( From_User_Unit( m_viaDiameter->GetUnits(), *m_viaDiameter->GetValue() ) );
|
m_settings.SetCustomViaSize( m_viaDiameter.GetValue() );
|
||||||
m_settings.SetCustomViaDrill( From_User_Unit( m_viaDrill->GetUnits(), *m_viaDrill->GetValue() ) );
|
m_settings.SetCustomViaDrill( m_viaDrill.GetValue() );
|
||||||
EndModal( 1 );
|
EndModal( 1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DisplayError( GetParent(), _( "Settings are incorrect" ) );
|
DisplayError( GetParent(), _( "Settings are incorrect" ) );
|
||||||
m_trackWidth->SetFocus();
|
m_trackWidthText->SetFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#ifndef __dialog_track_via_size__
|
#ifndef __dialog_track_via_size__
|
||||||
#define __dialog_track_via_size__
|
#define __dialog_track_via_size__
|
||||||
|
|
||||||
|
#include <wx_unit_binder.h>
|
||||||
|
|
||||||
#include "dialog_track_via_size_base.h"
|
#include "dialog_track_via_size_base.h"
|
||||||
|
|
||||||
class BOARD_DESIGN_SETTINGS;
|
class BOARD_DESIGN_SETTINGS;
|
||||||
|
@ -32,11 +34,15 @@ class BOARD_DESIGN_SETTINGS;
|
||||||
/** Implementing DIALOG_TRACK_VIA_SIZE_BASE */
|
/** Implementing DIALOG_TRACK_VIA_SIZE_BASE */
|
||||||
class DIALOG_TRACK_VIA_SIZE : public DIALOG_TRACK_VIA_SIZE_BASE
|
class DIALOG_TRACK_VIA_SIZE : public DIALOG_TRACK_VIA_SIZE_BASE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings );
|
DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
WX_UNIT_BINDER m_trackWidth;
|
||||||
|
WX_UNIT_BINDER m_viaDiameter;
|
||||||
|
WX_UNIT_BINDER m_viaDrill;
|
||||||
|
|
||||||
// Routings settings that are modified by the dialog.
|
// Routings settings that are modified by the dialog.
|
||||||
BOARD_DESIGN_SETTINGS& m_settings;
|
BOARD_DESIGN_SETTINGS& m_settings;
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,46 @@ DIALOG_TRACK_VIA_SIZE_BASE::DIALOG_TRACK_VIA_SIZE_BASE( wxWindow* parent, wxWind
|
||||||
wxBoxSizer* bSizes;
|
wxBoxSizer* bSizes;
|
||||||
bSizes = new wxBoxSizer( wxVERTICAL );
|
bSizes = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
m_trackWidth = new WX_UNIT_TEXT( this, _("Track width:") );
|
wxFlexGridSizer* fgSizer1;
|
||||||
bSizes->Add( m_trackWidth, 0, wxALL|wxEXPAND, 5 );
|
fgSizer1 = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||||
|
fgSizer1->SetFlexibleDirection( wxBOTH );
|
||||||
|
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||||
|
|
||||||
m_viaDiameter = new WX_UNIT_TEXT( this, _("Via diameter:") );
|
m_staticText3 = new wxStaticText( this, wxID_ANY, _("Track width:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
bSizes->Add( m_viaDiameter, 0, wxALL|wxEXPAND, 5 );
|
m_staticText3->Wrap( -1 );
|
||||||
|
fgSizer1->Add( m_staticText3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
m_viaDrill = new WX_UNIT_TEXT( this, _("Via drill:") );
|
m_trackWidthText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
bSizes->Add( m_viaDrill, 0, wxALL|wxEXPAND, 5 );
|
fgSizer1->Add( m_trackWidthText, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_trackWidthLabel = new wxStaticText( this, wxID_ANY, _("inch"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_trackWidthLabel->Wrap( -1 );
|
||||||
|
fgSizer1->Add( m_trackWidthLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_staticText5 = new wxStaticText( this, wxID_ANY, _("Via diameter:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText5->Wrap( -1 );
|
||||||
|
fgSizer1->Add( m_staticText5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_viaDiameterText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer1->Add( m_viaDiameterText, 1, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_viaDiameterLabel = new wxStaticText( this, wxID_ANY, _("u"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_viaDiameterLabel->Wrap( -1 );
|
||||||
|
fgSizer1->Add( m_viaDiameterLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_staticText7 = new wxStaticText( this, wxID_ANY, _("Via drill:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText7->Wrap( -1 );
|
||||||
|
fgSizer1->Add( m_staticText7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
m_viaDrillText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer1->Add( m_viaDrillText, 1, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_viaDrillLabel = new wxStaticText( this, wxID_ANY, _("u"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_viaDrillLabel->Wrap( -1 );
|
||||||
|
fgSizer1->Add( m_viaDrillLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
bSizes->Add( fgSizer1, 1, wxEXPAND|wxALL, 5 );
|
||||||
|
|
||||||
m_stdButtons = new wxStdDialogButtonSizer();
|
m_stdButtons = new wxStdDialogButtonSizer();
|
||||||
m_stdButtonsOK = new wxButton( this, wxID_OK );
|
m_stdButtonsOK = new wxButton( this, wxID_OK );
|
||||||
|
|
|
@ -95,9 +95,25 @@
|
||||||
<property name="permission">none</property>
|
<property name="permission">none</property>
|
||||||
<object class="sizeritem" expanded="1">
|
<object class="sizeritem" expanded="1">
|
||||||
<property name="border">5</property>
|
<property name="border">5</property>
|
||||||
<property name="flag">wxALL|wxEXPAND</property>
|
<property name="flag">wxEXPAND|wxALL</property>
|
||||||
|
<property name="proportion">1</property>
|
||||||
|
<object class="wxFlexGridSizer" expanded="1">
|
||||||
|
<property name="cols">3</property>
|
||||||
|
<property name="flexible_direction">wxBOTH</property>
|
||||||
|
<property name="growablecols"></property>
|
||||||
|
<property name="growablerows"></property>
|
||||||
|
<property name="hgap">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">fgSizer1</property>
|
||||||
|
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
|
||||||
|
<property name="permission">none</property>
|
||||||
|
<property name="rows">0</property>
|
||||||
|
<property name="vgap">0</property>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
|
||||||
<property name="proportion">0</property>
|
<property name="proportion">0</property>
|
||||||
<object class="CustomControl" expanded="1">
|
<object class="wxStaticText" expanded="1">
|
||||||
<property name="BottomDockable">1</property>
|
<property name="BottomDockable">1</property>
|
||||||
<property name="LeftDockable">1</property>
|
<property name="LeftDockable">1</property>
|
||||||
<property name="RightDockable">1</property>
|
<property name="RightDockable">1</property>
|
||||||
|
@ -111,12 +127,9 @@
|
||||||
<property name="caption"></property>
|
<property name="caption"></property>
|
||||||
<property name="caption_visible">1</property>
|
<property name="caption_visible">1</property>
|
||||||
<property name="center_pane">0</property>
|
<property name="center_pane">0</property>
|
||||||
<property name="class">WX_UNIT_TEXT</property>
|
|
||||||
<property name="close_button">1</property>
|
<property name="close_button">1</property>
|
||||||
<property name="construction">m_trackWidth = new WX_UNIT_TEXT( this, _("Track width:") );</property>
|
|
||||||
<property name="context_help"></property>
|
<property name="context_help"></property>
|
||||||
<property name="context_menu">1</property>
|
<property name="context_menu">1</property>
|
||||||
<property name="declaration">WX_UNIT_TEXT* m_trackWidth;</property>
|
|
||||||
<property name="default_pane">0</property>
|
<property name="default_pane">0</property>
|
||||||
<property name="dock">Dock</property>
|
<property name="dock">Dock</property>
|
||||||
<property name="dock_fixed">0</property>
|
<property name="dock_fixed">0</property>
|
||||||
|
@ -128,7 +141,7 @@
|
||||||
<property name="gripper">0</property>
|
<property name="gripper">0</property>
|
||||||
<property name="hidden">0</property>
|
<property name="hidden">0</property>
|
||||||
<property name="id">wxID_ANY</property>
|
<property name="id">wxID_ANY</property>
|
||||||
<property name="include">#include <wxunittext.h></property>
|
<property name="label">Track width:</property>
|
||||||
<property name="max_size"></property>
|
<property name="max_size"></property>
|
||||||
<property name="maximize_button">0</property>
|
<property name="maximize_button">0</property>
|
||||||
<property name="maximum_size"></property>
|
<property name="maximum_size"></property>
|
||||||
|
@ -136,7 +149,7 @@
|
||||||
<property name="minimize_button">0</property>
|
<property name="minimize_button">0</property>
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="moveable">1</property>
|
<property name="moveable">1</property>
|
||||||
<property name="name">m_trackWidth</property>
|
<property name="name">m_staticText3</property>
|
||||||
<property name="pane_border">1</property>
|
<property name="pane_border">1</property>
|
||||||
<property name="pane_position"></property>
|
<property name="pane_position"></property>
|
||||||
<property name="pane_size"></property>
|
<property name="pane_size"></property>
|
||||||
|
@ -144,15 +157,273 @@
|
||||||
<property name="pin_button">1</property>
|
<property name="pin_button">1</property>
|
||||||
<property name="pos"></property>
|
<property name="pos"></property>
|
||||||
<property name="resize">Resizable</property>
|
<property name="resize">Resizable</property>
|
||||||
<property name="settings"></property>
|
|
||||||
<property name="show">1</property>
|
<property name="show">1</property>
|
||||||
<property name="size"></property>
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
<property name="subclass"></property>
|
<property name="subclass"></property>
|
||||||
<property name="toolbar_pane">0</property>
|
<property name="toolbar_pane">0</property>
|
||||||
<property name="tooltip"></property>
|
<property name="tooltip"></property>
|
||||||
<property name="window_extra_style"></property>
|
<property name="window_extra_style"></property>
|
||||||
<property name="window_name"></property>
|
<property name="window_name"></property>
|
||||||
<property name="window_style"></property>
|
<property name="window_style"></property>
|
||||||
|
<property name="wrap">-1</property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
|
||||||
|
<property name="proportion">1</property>
|
||||||
|
<object class="wxTextCtrl" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="maxlength"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">m_trackWidthText</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="validator_data_type"></property>
|
||||||
|
<property name="validator_style">wxFILTER_NONE</property>
|
||||||
|
<property name="validator_type">wxDefaultValidator</property>
|
||||||
|
<property name="validator_variable"></property>
|
||||||
|
<property name="value"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnText"></event>
|
||||||
|
<event name="OnTextEnter"></event>
|
||||||
|
<event name="OnTextMaxLen"></event>
|
||||||
|
<event name="OnTextURL"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxStaticText" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">inch</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">m_trackWidthLabel</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<property name="wrap">-1</property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxStaticText" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">Via diameter:</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">m_staticText5</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<property name="wrap">-1</property>
|
||||||
<event name="OnChar"></event>
|
<event name="OnChar"></event>
|
||||||
<event name="OnEnterWindow"></event>
|
<event name="OnEnterWindow"></event>
|
||||||
<event name="OnEraseBackground"></event>
|
<event name="OnEraseBackground"></event>
|
||||||
|
@ -181,8 +452,8 @@
|
||||||
<object class="sizeritem" expanded="1">
|
<object class="sizeritem" expanded="1">
|
||||||
<property name="border">5</property>
|
<property name="border">5</property>
|
||||||
<property name="flag">wxALL|wxEXPAND</property>
|
<property name="flag">wxALL|wxEXPAND</property>
|
||||||
<property name="proportion">0</property>
|
<property name="proportion">1</property>
|
||||||
<object class="CustomControl" expanded="1">
|
<object class="wxTextCtrl" expanded="1">
|
||||||
<property name="BottomDockable">1</property>
|
<property name="BottomDockable">1</property>
|
||||||
<property name="LeftDockable">1</property>
|
<property name="LeftDockable">1</property>
|
||||||
<property name="RightDockable">1</property>
|
<property name="RightDockable">1</property>
|
||||||
|
@ -196,12 +467,9 @@
|
||||||
<property name="caption"></property>
|
<property name="caption"></property>
|
||||||
<property name="caption_visible">1</property>
|
<property name="caption_visible">1</property>
|
||||||
<property name="center_pane">0</property>
|
<property name="center_pane">0</property>
|
||||||
<property name="class">WX_UNIT_TEXT</property>
|
|
||||||
<property name="close_button">1</property>
|
<property name="close_button">1</property>
|
||||||
<property name="construction">m_viaDiameter = new WX_UNIT_TEXT( this, _("Via diameter:") );</property>
|
|
||||||
<property name="context_help"></property>
|
<property name="context_help"></property>
|
||||||
<property name="context_menu">1</property>
|
<property name="context_menu">1</property>
|
||||||
<property name="declaration">WX_UNIT_TEXT* m_viaDiameter;</property>
|
|
||||||
<property name="default_pane">0</property>
|
<property name="default_pane">0</property>
|
||||||
<property name="dock">Dock</property>
|
<property name="dock">Dock</property>
|
||||||
<property name="dock_fixed">0</property>
|
<property name="dock_fixed">0</property>
|
||||||
|
@ -213,15 +481,15 @@
|
||||||
<property name="gripper">0</property>
|
<property name="gripper">0</property>
|
||||||
<property name="hidden">0</property>
|
<property name="hidden">0</property>
|
||||||
<property name="id">wxID_ANY</property>
|
<property name="id">wxID_ANY</property>
|
||||||
<property name="include">#include <wxunittext.h></property>
|
|
||||||
<property name="max_size"></property>
|
<property name="max_size"></property>
|
||||||
<property name="maximize_button">0</property>
|
<property name="maximize_button">0</property>
|
||||||
<property name="maximum_size"></property>
|
<property name="maximum_size"></property>
|
||||||
|
<property name="maxlength"></property>
|
||||||
<property name="min_size"></property>
|
<property name="min_size"></property>
|
||||||
<property name="minimize_button">0</property>
|
<property name="minimize_button">0</property>
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="moveable">1</property>
|
<property name="moveable">1</property>
|
||||||
<property name="name">m_viaDiameter</property>
|
<property name="name">m_viaDiameterText</property>
|
||||||
<property name="pane_border">1</property>
|
<property name="pane_border">1</property>
|
||||||
<property name="pane_position"></property>
|
<property name="pane_position"></property>
|
||||||
<property name="pane_size"></property>
|
<property name="pane_size"></property>
|
||||||
|
@ -229,15 +497,190 @@
|
||||||
<property name="pin_button">1</property>
|
<property name="pin_button">1</property>
|
||||||
<property name="pos"></property>
|
<property name="pos"></property>
|
||||||
<property name="resize">Resizable</property>
|
<property name="resize">Resizable</property>
|
||||||
<property name="settings"></property>
|
|
||||||
<property name="show">1</property>
|
<property name="show">1</property>
|
||||||
<property name="size"></property>
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="validator_data_type"></property>
|
||||||
|
<property name="validator_style">wxFILTER_NONE</property>
|
||||||
|
<property name="validator_type">wxDefaultValidator</property>
|
||||||
|
<property name="validator_variable"></property>
|
||||||
|
<property name="value"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnText"></event>
|
||||||
|
<event name="OnTextEnter"></event>
|
||||||
|
<event name="OnTextMaxLen"></event>
|
||||||
|
<event name="OnTextURL"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxStaticText" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">u</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">m_viaDiameterLabel</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
<property name="subclass"></property>
|
<property name="subclass"></property>
|
||||||
<property name="toolbar_pane">0</property>
|
<property name="toolbar_pane">0</property>
|
||||||
<property name="tooltip"></property>
|
<property name="tooltip"></property>
|
||||||
<property name="window_extra_style"></property>
|
<property name="window_extra_style"></property>
|
||||||
<property name="window_name"></property>
|
<property name="window_name"></property>
|
||||||
<property name="window_style"></property>
|
<property name="window_style"></property>
|
||||||
|
<property name="wrap">-1</property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxStaticText" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">Via drill:</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">m_staticText7</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<property name="wrap">-1</property>
|
||||||
<event name="OnChar"></event>
|
<event name="OnChar"></event>
|
||||||
<event name="OnEnterWindow"></event>
|
<event name="OnEnterWindow"></event>
|
||||||
<event name="OnEraseBackground"></event>
|
<event name="OnEraseBackground"></event>
|
||||||
|
@ -266,8 +709,8 @@
|
||||||
<object class="sizeritem" expanded="1">
|
<object class="sizeritem" expanded="1">
|
||||||
<property name="border">5</property>
|
<property name="border">5</property>
|
||||||
<property name="flag">wxALL|wxEXPAND</property>
|
<property name="flag">wxALL|wxEXPAND</property>
|
||||||
<property name="proportion">0</property>
|
<property name="proportion">1</property>
|
||||||
<object class="CustomControl" expanded="1">
|
<object class="wxTextCtrl" expanded="1">
|
||||||
<property name="BottomDockable">1</property>
|
<property name="BottomDockable">1</property>
|
||||||
<property name="LeftDockable">1</property>
|
<property name="LeftDockable">1</property>
|
||||||
<property name="RightDockable">1</property>
|
<property name="RightDockable">1</property>
|
||||||
|
@ -281,12 +724,9 @@
|
||||||
<property name="caption"></property>
|
<property name="caption"></property>
|
||||||
<property name="caption_visible">1</property>
|
<property name="caption_visible">1</property>
|
||||||
<property name="center_pane">0</property>
|
<property name="center_pane">0</property>
|
||||||
<property name="class">WX_UNIT_TEXT</property>
|
|
||||||
<property name="close_button">1</property>
|
<property name="close_button">1</property>
|
||||||
<property name="construction">m_viaDrill = new WX_UNIT_TEXT( this, _("Via drill:") );</property>
|
|
||||||
<property name="context_help"></property>
|
<property name="context_help"></property>
|
||||||
<property name="context_menu">1</property>
|
<property name="context_menu">1</property>
|
||||||
<property name="declaration">WX_UNIT_TEXT* m_viaDrill;</property>
|
|
||||||
<property name="default_pane">0</property>
|
<property name="default_pane">0</property>
|
||||||
<property name="dock">Dock</property>
|
<property name="dock">Dock</property>
|
||||||
<property name="dock_fixed">0</property>
|
<property name="dock_fixed">0</property>
|
||||||
|
@ -298,15 +738,15 @@
|
||||||
<property name="gripper">0</property>
|
<property name="gripper">0</property>
|
||||||
<property name="hidden">0</property>
|
<property name="hidden">0</property>
|
||||||
<property name="id">wxID_ANY</property>
|
<property name="id">wxID_ANY</property>
|
||||||
<property name="include">#include <wxunittext.h></property>
|
|
||||||
<property name="max_size"></property>
|
<property name="max_size"></property>
|
||||||
<property name="maximize_button">0</property>
|
<property name="maximize_button">0</property>
|
||||||
<property name="maximum_size"></property>
|
<property name="maximum_size"></property>
|
||||||
|
<property name="maxlength"></property>
|
||||||
<property name="min_size"></property>
|
<property name="min_size"></property>
|
||||||
<property name="minimize_button">0</property>
|
<property name="minimize_button">0</property>
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="moveable">1</property>
|
<property name="moveable">1</property>
|
||||||
<property name="name">m_viaDrill</property>
|
<property name="name">m_viaDrillText</property>
|
||||||
<property name="pane_border">1</property>
|
<property name="pane_border">1</property>
|
||||||
<property name="pane_position"></property>
|
<property name="pane_position"></property>
|
||||||
<property name="pane_size"></property>
|
<property name="pane_size"></property>
|
||||||
|
@ -314,12 +754,17 @@
|
||||||
<property name="pin_button">1</property>
|
<property name="pin_button">1</property>
|
||||||
<property name="pos"></property>
|
<property name="pos"></property>
|
||||||
<property name="resize">Resizable</property>
|
<property name="resize">Resizable</property>
|
||||||
<property name="settings"></property>
|
|
||||||
<property name="show">1</property>
|
<property name="show">1</property>
|
||||||
<property name="size"></property>
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
<property name="subclass"></property>
|
<property name="subclass"></property>
|
||||||
<property name="toolbar_pane">0</property>
|
<property name="toolbar_pane">0</property>
|
||||||
<property name="tooltip"></property>
|
<property name="tooltip"></property>
|
||||||
|
<property name="validator_data_type"></property>
|
||||||
|
<property name="validator_style">wxFILTER_NONE</property>
|
||||||
|
<property name="validator_type">wxDefaultValidator</property>
|
||||||
|
<property name="validator_variable"></property>
|
||||||
|
<property name="value"></property>
|
||||||
<property name="window_extra_style"></property>
|
<property name="window_extra_style"></property>
|
||||||
<property name="window_name"></property>
|
<property name="window_name"></property>
|
||||||
<property name="window_style"></property>
|
<property name="window_style"></property>
|
||||||
|
@ -345,9 +790,98 @@
|
||||||
<event name="OnRightUp"></event>
|
<event name="OnRightUp"></event>
|
||||||
<event name="OnSetFocus"></event>
|
<event name="OnSetFocus"></event>
|
||||||
<event name="OnSize"></event>
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnText"></event>
|
||||||
|
<event name="OnTextEnter"></event>
|
||||||
|
<event name="OnTextMaxLen"></event>
|
||||||
|
<event name="OnTextURL"></event>
|
||||||
<event name="OnUpdateUI"></event>
|
<event name="OnUpdateUI"></event>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxStaticText" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">u</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">m_viaDrillLabel</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<property name="wrap">-1</property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
<object class="sizeritem" expanded="1">
|
<object class="sizeritem" expanded="1">
|
||||||
<property name="border">5</property>
|
<property name="border">5</property>
|
||||||
<property name="flag">wxEXPAND|wxALL</property>
|
<property name="flag">wxEXPAND|wxALL</property>
|
||||||
|
|
|
@ -11,12 +11,13 @@
|
||||||
#include <wx/artprov.h>
|
#include <wx/artprov.h>
|
||||||
#include <wx/xrc/xmlres.h>
|
#include <wx/xrc/xmlres.h>
|
||||||
#include <wx/intl.h>
|
#include <wx/intl.h>
|
||||||
#include <wxunittext.h>
|
#include <wx/string.h>
|
||||||
|
#include <wx/stattext.h>
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
#include <wx/font.h>
|
#include <wx/font.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
#include <wx/settings.h>
|
#include <wx/settings.h>
|
||||||
#include <wx/string.h>
|
#include <wx/textctrl.h>
|
||||||
#include <wx/sizer.h>
|
#include <wx/sizer.h>
|
||||||
#include <wx/button.h>
|
#include <wx/button.h>
|
||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
|
@ -32,9 +33,15 @@ class DIALOG_TRACK_VIA_SIZE_BASE : public wxDialog
|
||||||
private:
|
private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
WX_UNIT_TEXT* m_trackWidth;
|
wxStaticText* m_staticText3;
|
||||||
WX_UNIT_TEXT* m_viaDiameter;
|
wxTextCtrl* m_trackWidthText;
|
||||||
WX_UNIT_TEXT* m_viaDrill;
|
wxStaticText* m_trackWidthLabel;
|
||||||
|
wxStaticText* m_staticText5;
|
||||||
|
wxTextCtrl* m_viaDiameterText;
|
||||||
|
wxStaticText* m_viaDiameterLabel;
|
||||||
|
wxStaticText* m_staticText7;
|
||||||
|
wxTextCtrl* m_viaDrillText;
|
||||||
|
wxStaticText* m_viaDrillLabel;
|
||||||
wxStdDialogButtonSizer* m_stdButtons;
|
wxStdDialogButtonSizer* m_stdButtons;
|
||||||
wxButton* m_stdButtonsOK;
|
wxButton* m_stdButtonsOK;
|
||||||
wxButton* m_stdButtonsCancel;
|
wxButton* m_stdButtonsCancel;
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
* @brief Footprints selection and loading functions.
|
* @brief Footprints selection and loading functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <class_drawpanel.h>
|
#include <class_drawpanel.h>
|
||||||
#include <pcb_draw_panel_gal.h>
|
#include <pcb_draw_panel_gal.h>
|
||||||
|
@ -61,6 +63,10 @@ static void DisplayCmpDoc( wxString& aName, void* aData );
|
||||||
|
|
||||||
static FOOTPRINT_LIST MList;
|
static FOOTPRINT_LIST MList;
|
||||||
|
|
||||||
|
static void clearModuleItemFlags( BOARD_ITEM* aItem )
|
||||||
|
{
|
||||||
|
aItem->ClearFlags();
|
||||||
|
}
|
||||||
|
|
||||||
bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
|
bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
|
||||||
{
|
{
|
||||||
|
@ -92,9 +98,10 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
|
||||||
|
|
||||||
aModule = newModule;
|
aModule = newModule;
|
||||||
|
|
||||||
GetBoard()->Add( newModule );
|
|
||||||
|
|
||||||
newModule->ClearFlags();
|
newModule->ClearFlags();
|
||||||
|
newModule->RunOnChildren( boost::bind( &clearModuleItemFlags, _1 ) );
|
||||||
|
|
||||||
|
GetBoard()->Add( newModule );
|
||||||
|
|
||||||
// Clear references to any net info, because the footprint editor
|
// Clear references to any net info, because the footprint editor
|
||||||
// does know any thing about nets handled by the current edited board.
|
// does know any thing about nets handled by the current edited board.
|
||||||
|
|
|
@ -433,6 +433,49 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
||||||
_( "Set the origin point for the grid" ),
|
_( "Set the origin point for the grid" ),
|
||||||
KiBitmap( grid_select_axis_xpm ) );
|
KiBitmap( grid_select_axis_xpm ) );
|
||||||
|
|
||||||
|
wxMenu* routeMenu = new wxMenu;
|
||||||
|
|
||||||
|
AddMenuItem( routeMenu, ID_TRACK_BUTT,
|
||||||
|
_( "Single Track" ),
|
||||||
|
_( "Interactively route a single track" ),
|
||||||
|
KiBitmap( add_tracks_xpm ) );
|
||||||
|
|
||||||
|
AddMenuItem( routeMenu, ID_DIFF_PAIR_BUTT,
|
||||||
|
_( "Differential Pair" ),
|
||||||
|
_( "Interactively route a differential pair" ),
|
||||||
|
KiBitmap( add_tracks_xpm ) );
|
||||||
|
|
||||||
|
routeMenu->AppendSeparator();
|
||||||
|
|
||||||
|
AddMenuItem( routeMenu, ID_TUNE_SINGLE_TRACK_LEN_BUTT,
|
||||||
|
_( "Tune Track Length" ),
|
||||||
|
_( "Tune length of a single track" ),
|
||||||
|
KiBitmap( add_tracks_xpm ) );
|
||||||
|
|
||||||
|
AddMenuItem( routeMenu, ID_TUNE_DIFF_PAIR_LEN_BUTT,
|
||||||
|
_( "Tune Differential Pair Length" ),
|
||||||
|
_( "Tune length of a differential pair" ),
|
||||||
|
KiBitmap( add_tracks_xpm ) );
|
||||||
|
|
||||||
|
AddMenuItem( routeMenu, ID_TUNE_DIFF_PAIR_SKEW_BUTT,
|
||||||
|
_( "Tune Differential Pair Skew/Phase" ),
|
||||||
|
_( "Tune skew/phase of a differential pair" ),
|
||||||
|
KiBitmap( add_tracks_xpm ) );
|
||||||
|
|
||||||
|
/* Fixme: add icons & missing menu entries!
|
||||||
|
routeMenu->AppendSeparator();
|
||||||
|
|
||||||
|
AddMenuItem( routeMenu, ID_MENU_MITER_TRACES,
|
||||||
|
_( "Miter traces..." ),
|
||||||
|
_( "Miter trace corners with arcs" ),
|
||||||
|
KiBitmap( grid_select_axis_xpm ) );
|
||||||
|
|
||||||
|
AddMenuItem( routeMenu, ID_MENU_ADD_TEARDROPS,
|
||||||
|
_( "Teardrops..." ),
|
||||||
|
_( "Add teardrops to pads/vias" ),
|
||||||
|
KiBitmap( grid_select_axis_xpm ) );
|
||||||
|
*/
|
||||||
|
|
||||||
//----- Preferences and configuration menu------------------------------------
|
//----- Preferences and configuration menu------------------------------------
|
||||||
wxMenu* configmenu = new wxMenu;
|
wxMenu* configmenu = new wxMenu;
|
||||||
|
|
||||||
|
@ -467,6 +510,11 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
||||||
_( "Select how items (pads, tracks texts ... ) are displayed" ),
|
_( "Select how items (pads, tracks texts ... ) are displayed" ),
|
||||||
KiBitmap( display_options_xpm ) );
|
KiBitmap( display_options_xpm ) );
|
||||||
|
|
||||||
|
AddMenuItem( configmenu, ID_MENU_INTERACTIVE_ROUTER_SETTINGS,
|
||||||
|
_( "Interactive Routing" ),
|
||||||
|
_( "Configure Interactive Routing." ),
|
||||||
|
KiBitmap( add_tracks_xpm ) ); // fixme: icon
|
||||||
|
|
||||||
//--- dimensions submenu ------------------------------------------------------
|
//--- dimensions submenu ------------------------------------------------------
|
||||||
wxMenu* dimensionsMenu = new wxMenu;
|
wxMenu* dimensionsMenu = new wxMenu;
|
||||||
|
|
||||||
|
@ -488,6 +536,11 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
||||||
_( "Adjust the global clearance between pads and the solder resist mask" ),
|
_( "Adjust the global clearance between pads and the solder resist mask" ),
|
||||||
KiBitmap( pads_mask_layers_xpm ) );
|
KiBitmap( pads_mask_layers_xpm ) );
|
||||||
|
|
||||||
|
AddMenuItem( dimensionsMenu, ID_MENU_DIFF_PAIR_DIMENSIONS,
|
||||||
|
_( "Differential Pairs" ),
|
||||||
|
_( "Define the global gap/width for differential pairs." ),
|
||||||
|
KiBitmap( add_tracks_xpm ) ); // fixme: icon
|
||||||
|
|
||||||
dimensionsMenu->AppendSeparator();
|
dimensionsMenu->AppendSeparator();
|
||||||
AddMenuItem( dimensionsMenu, ID_CONFIG_SAVE,
|
AddMenuItem( dimensionsMenu, ID_CONFIG_SAVE,
|
||||||
_( "&Save" ), _( "Save dimension preferences" ),
|
_( "&Save" ), _( "Save dimension preferences" ),
|
||||||
|
@ -592,6 +645,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
||||||
menuBar->Append( editMenu, _( "&Edit" ) );
|
menuBar->Append( editMenu, _( "&Edit" ) );
|
||||||
menuBar->Append( viewMenu, _( "&View" ) );
|
menuBar->Append( viewMenu, _( "&View" ) );
|
||||||
menuBar->Append( placeMenu, _( "&Place" ) );
|
menuBar->Append( placeMenu, _( "&Place" ) );
|
||||||
|
menuBar->Append( routeMenu, _( "&Route" ) );
|
||||||
menuBar->Append( configmenu, _( "P&references" ) );
|
menuBar->Append( configmenu, _( "P&references" ) );
|
||||||
menuBar->Append( dimensionsMenu, _( "D&imensions" ) );
|
menuBar->Append( dimensionsMenu, _( "D&imensions" ) );
|
||||||
menuBar->Append( toolsMenu, _( "&Tools" ) );
|
menuBar->Append( toolsMenu, _( "&Tools" ) );
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include <modview_frame.h>
|
#include <modview_frame.h>
|
||||||
#include <collectors.h>
|
#include <collectors.h>
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
|
#include <tools/common_actions.h>
|
||||||
|
|
||||||
#include <dialog_edit_module_for_Modedit.h>
|
#include <dialog_edit_module_for_Modedit.h>
|
||||||
#include <dialog_move_exact.h>
|
#include <dialog_move_exact.h>
|
||||||
|
@ -433,6 +434,8 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
// Create the "new" module
|
// Create the "new" module
|
||||||
MODULE* newmodule = new MODULE( *module_in_edit );
|
MODULE* newmodule = new MODULE( *module_in_edit );
|
||||||
newmodule->SetParent( mainpcb );
|
newmodule->SetParent( mainpcb );
|
||||||
|
@ -485,6 +488,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
||||||
RN_DATA* ratsnest = pcbframe->GetBoard()->GetRatsnest();
|
RN_DATA* ratsnest = pcbframe->GetBoard()->GetRatsnest();
|
||||||
ratsnest->Update( newmodule );
|
ratsnest->Update( newmodule );
|
||||||
ratsnest->Recalculate();
|
ratsnest->Recalculate();
|
||||||
|
GetGalCanvas()->ForceRefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -68,15 +68,6 @@
|
||||||
|
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <tool/tool_dispatcher.h>
|
#include <tool/tool_dispatcher.h>
|
||||||
|
|
||||||
#include <tools/selection_tool.h>
|
|
||||||
#include <router/router_tool.h>
|
|
||||||
#include <tools/edit_tool.h>
|
|
||||||
#include <tools/drawing_tool.h>
|
|
||||||
#include <tools/point_editor.h>
|
|
||||||
#include <tools/pcbnew_control.h>
|
|
||||||
#include <tools/pcb_editor_control.h>
|
|
||||||
#include <tools/placement_tool.h>
|
|
||||||
#include <tools/common_actions.h>
|
#include <tools/common_actions.h>
|
||||||
|
|
||||||
#include <scripting/python_console_frame.h>
|
#include <scripting/python_console_frame.h>
|
||||||
|
@ -545,14 +536,8 @@ void PCB_EDIT_FRAME::setupTools()
|
||||||
m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
|
m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
|
||||||
|
|
||||||
// Register tools
|
// Register tools
|
||||||
m_toolManager->RegisterTool( new SELECTION_TOOL );
|
registerAllTools( m_toolManager );
|
||||||
m_toolManager->RegisterTool( new ROUTER_TOOL );
|
|
||||||
m_toolManager->RegisterTool( new EDIT_TOOL );
|
|
||||||
m_toolManager->RegisterTool( new DRAWING_TOOL );
|
|
||||||
m_toolManager->RegisterTool( new POINT_EDITOR );
|
|
||||||
m_toolManager->RegisterTool( new PCBNEW_CONTROL );
|
|
||||||
m_toolManager->RegisterTool( new PCB_EDITOR_CONTROL );
|
|
||||||
m_toolManager->RegisterTool( new PLACEMENT_TOOL );
|
|
||||||
m_toolManager->ResetTools( TOOL_BASE::RUN );
|
m_toolManager->ResetTools( TOOL_BASE::RUN );
|
||||||
|
|
||||||
// Run the selection tool, it is supposed to be always active
|
// Run the selection tool, it is supposed to be always active
|
||||||
|
|
|
@ -39,6 +39,15 @@ enum pcbnew_ids
|
||||||
ID_PCB_DELETE_ITEM_BUTT,
|
ID_PCB_DELETE_ITEM_BUTT,
|
||||||
ID_PCB_PLACE_OFFSET_COORD_BUTT,
|
ID_PCB_PLACE_OFFSET_COORD_BUTT,
|
||||||
ID_PCB_PLACE_GRID_COORD_BUTT,
|
ID_PCB_PLACE_GRID_COORD_BUTT,
|
||||||
|
ID_DIFF_PAIR_BUTT,
|
||||||
|
ID_TUNE_SINGLE_TRACK_LEN_BUTT,
|
||||||
|
ID_TUNE_DIFF_PAIR_LEN_BUTT,
|
||||||
|
ID_TUNE_DIFF_PAIR_SKEW_BUTT,
|
||||||
|
ID_MENU_REMOVE_MEANDERS,
|
||||||
|
ID_MENU_MITER_TRACES,
|
||||||
|
ID_MENU_ADD_TEARDROPS,
|
||||||
|
ID_MENU_DIFF_PAIR_DIMENSIONS,
|
||||||
|
ID_MENU_INTERACTIVE_ROUTER_SETTINGS,
|
||||||
|
|
||||||
ID_PCB_MASK_CLEARANCE,
|
ID_PCB_MASK_CLEARANCE,
|
||||||
ID_PCB_LAYERS_SETUP,
|
ID_PCB_LAYERS_SETUP,
|
||||||
|
|
|
@ -13,12 +13,19 @@ set( PCBNEW_PNS_SRCS
|
||||||
time_limit.cpp
|
time_limit.cpp
|
||||||
|
|
||||||
pns_algo_base.cpp
|
pns_algo_base.cpp
|
||||||
|
pns_diff_pair.cpp
|
||||||
|
pns_diff_pair_placer.cpp
|
||||||
|
pns_dp_meander_placer.cpp
|
||||||
pns_dragger.cpp
|
pns_dragger.cpp
|
||||||
pns_item.cpp
|
pns_item.cpp
|
||||||
pns_itemset.cpp
|
pns_itemset.cpp
|
||||||
pns_line.cpp
|
pns_line.cpp
|
||||||
pns_line_placer.cpp
|
pns_line_placer.cpp
|
||||||
pns_logger.cpp
|
pns_logger.cpp
|
||||||
|
pns_meander.cpp
|
||||||
|
pns_meander_placer.cpp
|
||||||
|
pns_meander_placer_base.cpp
|
||||||
|
pns_meander_skew_placer.cpp
|
||||||
pns_node.cpp
|
pns_node.cpp
|
||||||
pns_optimizer.cpp
|
pns_optimizer.cpp
|
||||||
pns_router.cpp
|
pns_router.cpp
|
||||||
|
@ -26,11 +33,15 @@ set( PCBNEW_PNS_SRCS
|
||||||
pns_shove.cpp
|
pns_shove.cpp
|
||||||
pns_sizes_settings.cpp
|
pns_sizes_settings.cpp
|
||||||
pns_solid.cpp
|
pns_solid.cpp
|
||||||
|
pns_tool_base.cpp
|
||||||
|
pns_topology.cpp
|
||||||
|
pns_tune_status_popup.cpp
|
||||||
pns_utils.cpp
|
pns_utils.cpp
|
||||||
pns_via.cpp
|
pns_via.cpp
|
||||||
pns_walkaround.cpp
|
pns_walkaround.cpp
|
||||||
router_preview_item.cpp
|
router_preview_item.cpp
|
||||||
router_tool.cpp
|
router_tool.cpp
|
||||||
|
length_tuner_tool.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library( pnsrouter STATIC ${PCBNEW_PNS_SRCS} )
|
add_library( pnsrouter STATIC ${PCBNEW_PNS_SRCS} )
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2014 CERN
|
* Copyright (C) 2013-2015 CERN
|
||||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
@ -73,7 +73,7 @@ public:
|
||||||
*/
|
*/
|
||||||
DIRECTION_45( const VECTOR2I& aVec )
|
DIRECTION_45( const VECTOR2I& aVec )
|
||||||
{
|
{
|
||||||
construct( aVec );
|
construct_( aVec );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,7 +82,7 @@ public:
|
||||||
*/
|
*/
|
||||||
DIRECTION_45( const SEG& aSeg )
|
DIRECTION_45( const SEG& aSeg )
|
||||||
{
|
{
|
||||||
construct( aSeg.B - aSeg.A );
|
construct_( aSeg.B - aSeg.A );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -309,14 +309,20 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Mask() const
|
||||||
|
{
|
||||||
|
return 1 << ( (int) m_dir );
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function construct()
|
* Function construct()
|
||||||
* Calculates the direction from a vector. If the vector's angle is not a multiple of 45
|
* Calculates the direction from a vector. If the vector's angle is not a multiple of 45
|
||||||
* degrees, the direction is rounded to the nearest octant.
|
* degrees, the direction is rounded to the nearest octant.
|
||||||
* @param aVec our vector */
|
* @param aVec our vector
|
||||||
void construct( const VECTOR2I& aVec )
|
*/
|
||||||
|
void construct_( const VECTOR2I& aVec )
|
||||||
{
|
{
|
||||||
m_dir = UNDEFINED;
|
m_dir = UNDEFINED;
|
||||||
|
|
||||||
|
@ -342,32 +348,6 @@ private:
|
||||||
m_dir = (Directions) dir;
|
m_dir = (Directions) dir;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( aVec.y < 0 )
|
|
||||||
{
|
|
||||||
if( aVec.x > 0 )
|
|
||||||
m_dir = NE;
|
|
||||||
else if( aVec.x < 0 )
|
|
||||||
m_dir = NW;
|
|
||||||
else
|
|
||||||
m_dir = N;
|
|
||||||
}
|
|
||||||
else if( aVec.y == 0 )
|
|
||||||
{
|
|
||||||
if( aVec.x > 0 )
|
|
||||||
m_dir = E;
|
|
||||||
else
|
|
||||||
m_dir = W;
|
|
||||||
}
|
|
||||||
else // aVec.y>0
|
|
||||||
{
|
|
||||||
if( aVec.x > 0 )
|
|
||||||
m_dir = SE;
|
|
||||||
else if( aVec.x < 0 )
|
|
||||||
m_dir = SW;
|
|
||||||
else
|
|
||||||
m_dir = S;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///> our actual direction
|
///> our actual direction
|
||||||
|
|
|
@ -0,0 +1,330 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#include "class_draw_panel_gal.h"
|
||||||
|
#include "class_board.h"
|
||||||
|
|
||||||
|
#include <wxPcbStruct.h>
|
||||||
|
#include <pcbnew_id.h>
|
||||||
|
#include <view/view_controls.h>
|
||||||
|
#include <pcb_painter.h>
|
||||||
|
#include <dialogs/dialog_pns_settings.h>
|
||||||
|
#include <dialogs/dialog_pns_length_tuning_settings.h>
|
||||||
|
|
||||||
|
#include <tool/context_menu.h>
|
||||||
|
#include <tools/common_actions.h>
|
||||||
|
|
||||||
|
#include "pns_segment.h"
|
||||||
|
#include "pns_router.h"
|
||||||
|
#include "pns_meander_placer.h" // fixme: move settings to separate header
|
||||||
|
#include "pns_tune_status_popup.h"
|
||||||
|
|
||||||
|
#include "length_tuner_tool.h"
|
||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
using namespace KIGFX;
|
||||||
|
using boost::optional;
|
||||||
|
|
||||||
|
static TOOL_ACTION ACT_StartTuning( "pcbnew.LengthTuner.StartTuning",
|
||||||
|
AS_CONTEXT, 'X',
|
||||||
|
"New Track", "Starts laying a new track.");
|
||||||
|
static TOOL_ACTION ACT_EndTuning( "pcbnew.LengthTuner.EndTuning",
|
||||||
|
AS_CONTEXT, WXK_END,
|
||||||
|
"End Track", "Stops laying the current meander.");
|
||||||
|
|
||||||
|
static TOOL_ACTION ACT_Settings( "pcbnew.LengthTuner.Settings",
|
||||||
|
AS_CONTEXT, 'L',
|
||||||
|
"Length Tuning Settings", "Sets the length tuning parameters for currently routed item.");
|
||||||
|
|
||||||
|
static TOOL_ACTION ACT_SpacingIncrease( "pcbnew.LengthTuner.SpacingIncrease",
|
||||||
|
AS_CONTEXT, '1',
|
||||||
|
"Increase spacing", "Increase meander spacing by one step.");
|
||||||
|
|
||||||
|
static TOOL_ACTION ACT_SpacingDecrease( "pcbnew.LengthTuner.SpacingDecrease",
|
||||||
|
AS_CONTEXT, '2',
|
||||||
|
"Decrease spacing ", "Decrease meander spacing by one step.");
|
||||||
|
|
||||||
|
static TOOL_ACTION ACT_AmplIncrease( "pcbnew.LengthTuner.AmplIncrease",
|
||||||
|
AS_CONTEXT, '3',
|
||||||
|
"Increase amplitude", "Increase meander amplitude by one step.");
|
||||||
|
|
||||||
|
static TOOL_ACTION ACT_AmplDecrease( "pcbnew.LengthTuner.AmplDecrease",
|
||||||
|
AS_CONTEXT, '4',
|
||||||
|
"Decrease amplitude", "Decrease meander amplitude by one step.");
|
||||||
|
|
||||||
|
|
||||||
|
LENGTH_TUNER_TOOL::LENGTH_TUNER_TOOL() :
|
||||||
|
PNS_TOOL_BASE( "pcbnew.LengthTuner" )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TUNER_TOOL_MENU: public CONTEXT_MENU
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TUNER_TOOL_MENU( BOARD* aBoard )
|
||||||
|
{
|
||||||
|
SetTitle( wxT( "Length Tuner" ) );
|
||||||
|
|
||||||
|
//Add( ACT_StartTuning );
|
||||||
|
//Add( ACT_EndTuning );
|
||||||
|
|
||||||
|
//AppendSeparator();
|
||||||
|
|
||||||
|
Add( ACT_SpacingIncrease );
|
||||||
|
Add( ACT_SpacingDecrease );
|
||||||
|
Add( ACT_AmplIncrease );
|
||||||
|
Add( ACT_AmplDecrease );
|
||||||
|
Add( ACT_Settings );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
LENGTH_TUNER_TOOL::~LENGTH_TUNER_TOOL()
|
||||||
|
{
|
||||||
|
delete m_router;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LENGTH_TUNER_TOOL::Reset( RESET_REASON aReason )
|
||||||
|
{
|
||||||
|
PNS_TOOL_BASE::Reset( aReason );
|
||||||
|
|
||||||
|
Go( &LENGTH_TUNER_TOOL::TuneSingleTrace, COMMON_ACTIONS::routerActivateTuneSingleTrace.MakeEvent() );
|
||||||
|
Go( &LENGTH_TUNER_TOOL::TuneDiffPair, COMMON_ACTIONS::routerActivateTuneDiffPair.MakeEvent() );
|
||||||
|
Go( &LENGTH_TUNER_TOOL::TuneDiffPairSkew, COMMON_ACTIONS::routerActivateTuneDiffPairSkew.MakeEvent() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LENGTH_TUNER_TOOL::handleCommonEvents( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
if( aEvent.IsAction( &ACT_RouterOptions ) )
|
||||||
|
{
|
||||||
|
DIALOG_PNS_SETTINGS settingsDlg( m_frame, m_router->Settings() );
|
||||||
|
|
||||||
|
if( settingsDlg.ShowModal() )
|
||||||
|
{
|
||||||
|
// FIXME: do we need an explicit update?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_MEANDER_PLACER_BASE* placer = static_cast<PNS_MEANDER_PLACER_BASE*>( m_router->Placer() );
|
||||||
|
|
||||||
|
if( !placer )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( aEvent.IsAction( &ACT_Settings ) )
|
||||||
|
{
|
||||||
|
PNS_MEANDER_SETTINGS settings = placer->MeanderSettings();
|
||||||
|
DIALOG_PNS_LENGTH_TUNING_SETTINGS settingsDlg( m_frame, settings, m_router->Mode() );
|
||||||
|
|
||||||
|
if( settingsDlg.ShowModal() )
|
||||||
|
{
|
||||||
|
placer->UpdateSettings ( settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_savedMeanderSettings = placer->MeanderSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LENGTH_TUNER_TOOL::performTuning()
|
||||||
|
{
|
||||||
|
bool saveUndoBuffer = true;
|
||||||
|
|
||||||
|
if( m_startItem )
|
||||||
|
{
|
||||||
|
m_frame->SetActiveLayer( ToLAYER_ID ( m_startItem->Layers().Start() ) );
|
||||||
|
|
||||||
|
if( m_startItem->Net() >= 0 )
|
||||||
|
highlightNet( true, m_startItem->Net() );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ctls->ForceCursorPosition( false );
|
||||||
|
m_ctls->SetAutoPan( true );
|
||||||
|
|
||||||
|
if( !m_router->StartRouting( m_startSnapPoint, m_startItem, 0 ) )
|
||||||
|
{
|
||||||
|
wxMessageBox( m_router->FailureReason(), _( "Error" ) );
|
||||||
|
highlightNet( false );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_TUNE_STATUS_POPUP statusPopup( m_frame );
|
||||||
|
statusPopup.Popup();
|
||||||
|
|
||||||
|
PNS_MEANDER_PLACER* placer = static_cast<PNS_MEANDER_PLACER*>( m_router->Placer() );
|
||||||
|
VECTOR2I end;
|
||||||
|
|
||||||
|
placer->UpdateSettings( m_savedMeanderSettings );
|
||||||
|
|
||||||
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
|
{
|
||||||
|
if( evt->IsCancel() || evt->IsActivate() )
|
||||||
|
break;
|
||||||
|
else if( evt->Action() == TA_UNDO_REDO )
|
||||||
|
{
|
||||||
|
saveUndoBuffer = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( evt->IsMotion() )
|
||||||
|
{
|
||||||
|
end = evt->Position();
|
||||||
|
m_router->Move( end, NULL );
|
||||||
|
|
||||||
|
wxPoint p = wxGetMousePosition();
|
||||||
|
|
||||||
|
p.x += 20;
|
||||||
|
p.y += 20;
|
||||||
|
|
||||||
|
statusPopup.Update( m_router );
|
||||||
|
statusPopup.Move( p );
|
||||||
|
}
|
||||||
|
else if( evt->IsClick( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
if( m_router->FixRoute( evt->Position(), NULL ) )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( evt->IsAction( &ACT_EndTuning ) )
|
||||||
|
{
|
||||||
|
if( m_router->FixRoute( end, NULL ) )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( evt->IsAction( &ACT_AmplDecrease ) )
|
||||||
|
{
|
||||||
|
placer->AmplitudeStep( -1 );
|
||||||
|
m_router->Move( end, NULL );
|
||||||
|
}
|
||||||
|
else if( evt->IsAction( &ACT_AmplIncrease ) )
|
||||||
|
{
|
||||||
|
placer->AmplitudeStep( 1 );
|
||||||
|
m_router->Move( end, NULL );
|
||||||
|
}
|
||||||
|
else if(evt->IsAction( &ACT_SpacingDecrease ) )
|
||||||
|
{
|
||||||
|
placer->SpacingStep( -1 );
|
||||||
|
m_router->Move( end, NULL );
|
||||||
|
}
|
||||||
|
else if( evt->IsAction( &ACT_SpacingIncrease ) )
|
||||||
|
{
|
||||||
|
placer->SpacingStep( 1 );
|
||||||
|
m_router->Move( end, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCommonEvents( *evt );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_router->StopRouting();
|
||||||
|
|
||||||
|
if( saveUndoBuffer )
|
||||||
|
{
|
||||||
|
// Save the recent changes in the undo buffer
|
||||||
|
m_frame->SaveCopyInUndoList( m_router->GetUndoBuffer(), UR_UNSPECIFIED );
|
||||||
|
m_router->ClearUndoBuffer();
|
||||||
|
m_frame->OnModify();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// It was interrupted by TA_UNDO_REDO event, so we have to sync the world now
|
||||||
|
m_needsSync = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ctls->SetAutoPan( false );
|
||||||
|
m_ctls->ForceCursorPosition( false );
|
||||||
|
highlightNet( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LENGTH_TUNER_TOOL::TuneSingleTrace( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Trace Length" ) );
|
||||||
|
return mainLoop( PNS_MODE_TUNE_SINGLE );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LENGTH_TUNER_TOOL::TuneDiffPair( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Diff Pair Length" ) );
|
||||||
|
return mainLoop( PNS_MODE_TUNE_DIFF_PAIR );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LENGTH_TUNER_TOOL::TuneDiffPairSkew( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Diff Pair Skew" ) );
|
||||||
|
return mainLoop( PNS_MODE_TUNE_DIFF_PAIR_SKEW );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LENGTH_TUNER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
|
||||||
|
{
|
||||||
|
// Deselect all items
|
||||||
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
|
Activate();
|
||||||
|
|
||||||
|
m_router->SetMode( aMode );
|
||||||
|
|
||||||
|
m_ctls->SetSnapping( true );
|
||||||
|
m_ctls->ShowCursor( true );
|
||||||
|
|
||||||
|
std::auto_ptr<TUNER_TOOL_MENU> ctxMenu( new TUNER_TOOL_MENU( m_board ) );
|
||||||
|
SetContextMenu( ctxMenu.get() );
|
||||||
|
|
||||||
|
// Main loop: keep receiving events
|
||||||
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
|
{
|
||||||
|
if( m_needsSync )
|
||||||
|
{
|
||||||
|
m_router->SyncWorld();
|
||||||
|
m_router->SetView( getView() );
|
||||||
|
m_needsSync = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( evt->IsCancel() || evt->IsActivate() )
|
||||||
|
break; // Finish
|
||||||
|
else if( evt->Action() == TA_UNDO_REDO )
|
||||||
|
m_needsSync = true;
|
||||||
|
else if( evt->IsMotion() )
|
||||||
|
updateStartItem( *evt );
|
||||||
|
else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_StartTuning ) )
|
||||||
|
{
|
||||||
|
updateStartItem( *evt );
|
||||||
|
performTuning( );
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCommonEvents( *evt );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore the default settings
|
||||||
|
m_ctls->SetAutoPan( false );
|
||||||
|
m_ctls->ShowCursor( false );
|
||||||
|
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
|
||||||
|
|
||||||
|
// Store routing settings till the next invocation
|
||||||
|
m_savedSettings = m_router->Settings();
|
||||||
|
m_savedSizes = m_router->Sizes();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
* Author: Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LENGTH_TUNER_TOOL_H
|
||||||
|
#define __LENGTH_TUNER_TOOL_H
|
||||||
|
|
||||||
|
#include "pns_tool_base.h"
|
||||||
|
#include "pns_meander.h"
|
||||||
|
|
||||||
|
class PNS_TUNE_STATUS_POPUP;
|
||||||
|
|
||||||
|
class APIEXPORT LENGTH_TUNER_TOOL : public PNS_TOOL_BASE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LENGTH_TUNER_TOOL();
|
||||||
|
~LENGTH_TUNER_TOOL();
|
||||||
|
|
||||||
|
void Reset( RESET_REASON aReason );
|
||||||
|
|
||||||
|
int TuneSingleTrace( const TOOL_EVENT& aEvent );
|
||||||
|
int TuneDiffPair( const TOOL_EVENT& aEvent );
|
||||||
|
int TuneDiffPairSkew( const TOOL_EVENT& aEvent );
|
||||||
|
int ClearMeanders( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void performTuning( );
|
||||||
|
int mainLoop( PNS_ROUTER_MODE aMode );
|
||||||
|
void handleCommonEvents( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
PNS_MEANDER_SETTINGS m_savedMeanderSettings;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,6 +21,8 @@
|
||||||
#ifndef __PNS_ALGO_BASE_H
|
#ifndef __PNS_ALGO_BASE_H
|
||||||
#define __PNS_ALGO_BASE_H
|
#define __PNS_ALGO_BASE_H
|
||||||
|
|
||||||
|
#include <wx/wx.h> // for wxString
|
||||||
|
|
||||||
#include "pns_routing_settings.h"
|
#include "pns_routing_settings.h"
|
||||||
|
|
||||||
class PNS_ROUTER;
|
class PNS_ROUTER;
|
||||||
|
@ -31,13 +33,12 @@ class PNS_LOGGER;
|
||||||
*
|
*
|
||||||
* Base class for all P&S algorithms (shoving, walkaround, line placement, dragging, etc.)
|
* Base class for all P&S algorithms (shoving, walkaround, line placement, dragging, etc.)
|
||||||
* Holds a bunch of objects commonly used by all algorithms (P&S settings, parent router instance, logging)
|
* Holds a bunch of objects commonly used by all algorithms (P&S settings, parent router instance, logging)
|
||||||
**/
|
*/
|
||||||
|
|
||||||
class PNS_ALGO_BASE
|
class PNS_ALGO_BASE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PNS_ALGO_BASE( PNS_ROUTER *aRouter ) :
|
PNS_ALGO_BASE( PNS_ROUTER* aRouter ) :
|
||||||
m_router ( aRouter )
|
m_router( aRouter )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~PNS_ALGO_BASE() {}
|
virtual ~PNS_ALGO_BASE() {}
|
||||||
|
|
|
@ -0,0 +1,850 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <geometry/shape.h>
|
||||||
|
#include <geometry/shape_rect.h>
|
||||||
|
#include <geometry/shape_circle.h>
|
||||||
|
#include <geometry/shape_segment.h>
|
||||||
|
|
||||||
|
#include "direction.h"
|
||||||
|
|
||||||
|
#include "pns_diff_pair.h"
|
||||||
|
#include "pns_router.h"
|
||||||
|
#include "pns_solid.h"
|
||||||
|
#include "pns_utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
class PNS_LINE;
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR( PNS_ITEM* aPrimP, PNS_ITEM* aPrimN )
|
||||||
|
{
|
||||||
|
m_primP = aPrimP->Clone();
|
||||||
|
m_primN = aPrimN->Clone();
|
||||||
|
|
||||||
|
m_anchorP = m_primP->Anchor( 0 );
|
||||||
|
m_anchorN = m_primN->Anchor( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DP_PRIMITIVE_PAIR::SetAnchors( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN )
|
||||||
|
{
|
||||||
|
m_anchorP = aAnchorP;
|
||||||
|
m_anchorN = aAnchorN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN )
|
||||||
|
{
|
||||||
|
m_anchorP = aAnchorP;
|
||||||
|
m_anchorN = aAnchorN;
|
||||||
|
m_primP = m_primN = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR( const PNS_DP_PRIMITIVE_PAIR& aOther )
|
||||||
|
{
|
||||||
|
if( aOther.m_primP )
|
||||||
|
m_primP = aOther.m_primP->Clone();
|
||||||
|
if( aOther.m_primN )
|
||||||
|
m_primN = aOther.m_primN->Clone();
|
||||||
|
|
||||||
|
m_anchorP = aOther.m_anchorP;
|
||||||
|
m_anchorN = aOther.m_anchorN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR& PNS_DP_PRIMITIVE_PAIR::operator=( const PNS_DP_PRIMITIVE_PAIR& aOther )
|
||||||
|
{
|
||||||
|
if( aOther.m_primP )
|
||||||
|
m_primP = aOther.m_primP->Clone();
|
||||||
|
if( aOther.m_primN )
|
||||||
|
m_primN = aOther.m_primN->Clone();
|
||||||
|
|
||||||
|
m_anchorP = aOther.m_anchorP;
|
||||||
|
m_anchorN = aOther.m_anchorN;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR::~PNS_DP_PRIMITIVE_PAIR()
|
||||||
|
{
|
||||||
|
delete m_primP;
|
||||||
|
delete m_primN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DP_PRIMITIVE_PAIR::Directional() const
|
||||||
|
{
|
||||||
|
if( !m_primP )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return m_primP->OfKind( PNS_ITEM::SEGMENT );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::anchorDirection( PNS_ITEM* aItem, const VECTOR2I& aP ) const
|
||||||
|
{
|
||||||
|
if( !aItem->OfKind ( PNS_ITEM::SEGMENT ) )
|
||||||
|
return DIRECTION_45();
|
||||||
|
|
||||||
|
PNS_SEGMENT* s = static_cast<PNS_SEGMENT*>( aItem );
|
||||||
|
|
||||||
|
if( s->Seg().A == aP )
|
||||||
|
return DIRECTION_45( s->Seg().A - s->Seg().B );
|
||||||
|
else
|
||||||
|
return DIRECTION_45( s->Seg().B - s->Seg().A );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirP() const
|
||||||
|
{
|
||||||
|
return anchorDirection( m_primP, m_anchorP );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirN() const
|
||||||
|
{
|
||||||
|
return anchorDirection( m_primN, m_anchorN );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void drawGw( VECTOR2I p, int color )
|
||||||
|
{
|
||||||
|
SHAPE_LINE_CHAIN l;
|
||||||
|
|
||||||
|
l.Append( p - VECTOR2I( -50000, -50000 ) );
|
||||||
|
l.Append( p + VECTOR2I( -50000, -50000 ) );
|
||||||
|
|
||||||
|
l.Clear();
|
||||||
|
l.Append( p - VECTOR2I( 50000, -50000 ) );
|
||||||
|
l.Append( p + VECTOR2I( 50000, -50000 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static DIRECTION_45::AngleType angle( const VECTOR2I &a, const VECTOR2I &b )
|
||||||
|
{
|
||||||
|
DIRECTION_45 dir_a( a );
|
||||||
|
DIRECTION_45 dir_b( b );
|
||||||
|
|
||||||
|
return dir_a.Angle( dir_b );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool checkGap( const SHAPE_LINE_CHAIN &p, const SHAPE_LINE_CHAIN &n, int gap )
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for( i = 0; i < p.SegmentCount(); i++ )
|
||||||
|
{
|
||||||
|
for( j = 0; j < n.SegmentCount() ; j++ )
|
||||||
|
{
|
||||||
|
int dist = p.CSegment( i ).Distance( n.CSegment( j ) );
|
||||||
|
|
||||||
|
if( dist < gap - 100 )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DP_GATEWAY::Reverse()
|
||||||
|
{
|
||||||
|
m_entryN = m_entryN.Reverse();
|
||||||
|
m_entryP = m_entryP.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR::BuildInitial( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY &aTarget, bool aPrefDiagonal )
|
||||||
|
{
|
||||||
|
SHAPE_LINE_CHAIN p = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorP(), aTarget.AnchorP(), aPrefDiagonal );
|
||||||
|
SHAPE_LINE_CHAIN n = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorN(), aTarget.AnchorN(), aPrefDiagonal );
|
||||||
|
|
||||||
|
int mask = aEntry.AllowedAngles() | DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_OBTUSE;
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN sum_n, sum_p;
|
||||||
|
m_p = p;
|
||||||
|
m_n = n;
|
||||||
|
|
||||||
|
if( aEntry.HasEntryLines() )
|
||||||
|
{
|
||||||
|
if( !aEntry.Entry().CheckConnectionAngle( *this, mask ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sum_p = aEntry.Entry().CP();
|
||||||
|
sum_n = aEntry.Entry().CN();
|
||||||
|
sum_p.Append( p );
|
||||||
|
sum_n.Append( n );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sum_p = p;
|
||||||
|
sum_n = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = aTarget.AllowedAngles() | DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_OBTUSE;
|
||||||
|
|
||||||
|
m_p = sum_p;
|
||||||
|
m_n = sum_n;
|
||||||
|
|
||||||
|
if( aTarget.HasEntryLines() )
|
||||||
|
{
|
||||||
|
PNS_DP_GATEWAY t(aTarget) ;
|
||||||
|
t.Reverse();
|
||||||
|
|
||||||
|
if( !CheckConnectionAngle( t.Entry(), mask ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sum_p.Append( t.Entry().CP() );
|
||||||
|
sum_n.Append( t.Entry().CN() );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_p = sum_p;
|
||||||
|
m_n = sum_n;
|
||||||
|
|
||||||
|
if( !checkGap ( p, n, m_gapConstraint ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( p.SelfIntersecting() || n.SelfIntersecting() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( p.Intersects( n ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR::CheckConnectionAngle( const PNS_DIFF_PAIR& aOther, int aAllowedAngles ) const
|
||||||
|
{
|
||||||
|
bool checkP, checkN;
|
||||||
|
|
||||||
|
if( m_p.SegmentCount() == 0 || aOther.m_p.SegmentCount() == 0 )
|
||||||
|
checkP = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DIRECTION_45 p0( m_p.CSegment( -1 ) );
|
||||||
|
DIRECTION_45 p1( aOther.m_p.CSegment( 0 ) );
|
||||||
|
|
||||||
|
checkP = ( p0.Angle( p1 ) & aAllowedAngles ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_n.SegmentCount() == 0 || aOther.m_n.SegmentCount() == 0 )
|
||||||
|
checkN = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DIRECTION_45 n0( m_n.CSegment( -1 ) );
|
||||||
|
DIRECTION_45 n1( aOther.m_n.CSegment( 0 ) );
|
||||||
|
|
||||||
|
checkN = ( n0.Angle( n1 ) & aAllowedAngles ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkP && checkN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const PNS_DIFF_PAIR PNS_DP_GATEWAY::Entry() const
|
||||||
|
{
|
||||||
|
return PNS_DIFF_PAIR( m_entryP, m_entryN, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DP_GATEWAYS::BuildOrthoProjections( PNS_DP_GATEWAYS& aEntries,
|
||||||
|
const VECTOR2I& aCursorPos, int aOrthoScore )
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( PNS_DP_GATEWAY g, aEntries.Gateways() )
|
||||||
|
{
|
||||||
|
VECTOR2I dir = ( g.AnchorP() - g.AnchorN() ).Perpendicular();
|
||||||
|
VECTOR2I midpoint( ( g.AnchorP() + g.AnchorN() ) / 2 );
|
||||||
|
SEG guide( midpoint, midpoint + dir );
|
||||||
|
VECTOR2I proj = guide.LineProject( aCursorPos );
|
||||||
|
|
||||||
|
PNS_DP_GATEWAYS targets( m_gap );
|
||||||
|
|
||||||
|
targets.m_viaGap = m_viaGap;
|
||||||
|
targets.m_viaDiameter = m_viaDiameter;
|
||||||
|
targets.m_fitVias = m_fitVias;
|
||||||
|
|
||||||
|
targets.BuildForCursor( proj );
|
||||||
|
|
||||||
|
BOOST_FOREACH( PNS_DP_GATEWAY t, targets.Gateways() )
|
||||||
|
{
|
||||||
|
t.SetPriority( aOrthoScore );
|
||||||
|
m_gateways.push_back( t );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DP_GATEWAYS::FitGateways( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& aTarget,
|
||||||
|
bool aPrefDiagonal, PNS_DIFF_PAIR& aDp )
|
||||||
|
{
|
||||||
|
std::vector<DP_CANDIDATE> candidates;
|
||||||
|
|
||||||
|
BOOST_FOREACH( PNS_DP_GATEWAY g_entry, aEntry.Gateways() )
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( PNS_DP_GATEWAY g_target, aTarget.Gateways() )
|
||||||
|
{
|
||||||
|
for( int attempt = 0; attempt < 2; attempt++ )
|
||||||
|
{
|
||||||
|
PNS_DIFF_PAIR l( m_gap );
|
||||||
|
|
||||||
|
if( l.BuildInitial( g_entry, g_target, aPrefDiagonal ^ ( attempt ? true : false ) ) )
|
||||||
|
{
|
||||||
|
int score = ( attempt == 1 ? -3 : 0 );
|
||||||
|
score +=g_entry.Priority();
|
||||||
|
score +=g_target.Priority();
|
||||||
|
|
||||||
|
DP_CANDIDATE c;
|
||||||
|
c.score = score;
|
||||||
|
c.p = l.CP();
|
||||||
|
c.n = l.CN();
|
||||||
|
candidates.push_back( c );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int bestScore = -1000;
|
||||||
|
DP_CANDIDATE best;
|
||||||
|
bool found;
|
||||||
|
|
||||||
|
BOOST_FOREACH( DP_CANDIDATE c, candidates )
|
||||||
|
{
|
||||||
|
if( c.score > bestScore )
|
||||||
|
{
|
||||||
|
bestScore = c.score;
|
||||||
|
best = c;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( found )
|
||||||
|
{
|
||||||
|
aDp.SetGap( m_gap );
|
||||||
|
aDp.SetShape( best.p, best.n );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DP_GATEWAYS::checkDiagonalAlignment( const VECTOR2I& a, const VECTOR2I& b ) const
|
||||||
|
{
|
||||||
|
VECTOR2I dir ( std::abs (a.x - b.x), std::abs ( a.y - b.y ));
|
||||||
|
|
||||||
|
return (dir.x == 0 && dir.y != 0) || (dir.x == dir.y) || (dir.y == 0 && dir.x != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DP_GATEWAYS::BuildFromPrimitivePair( PNS_DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal )
|
||||||
|
{
|
||||||
|
VECTOR2I majorDirection;
|
||||||
|
VECTOR2I p0_p, p0_n;
|
||||||
|
int orthoFanDistance;
|
||||||
|
int diagFanDistance;
|
||||||
|
const SHAPE* shP = NULL;
|
||||||
|
|
||||||
|
if( aPair.PrimP() == NULL )
|
||||||
|
{
|
||||||
|
BuildGeneric( aPair.AnchorP(), aPair.AnchorN(), true );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int pvMask = PNS_ITEM::SOLID | PNS_ITEM::VIA;
|
||||||
|
|
||||||
|
if( aPair.PrimP()->OfKind( pvMask ) && aPair.PrimN()->OfKind( pvMask ) )
|
||||||
|
{
|
||||||
|
p0_p = aPair.AnchorP();
|
||||||
|
p0_n = aPair.AnchorN();
|
||||||
|
|
||||||
|
shP = aPair.PrimP()->Shape();
|
||||||
|
|
||||||
|
}
|
||||||
|
else if( aPair.PrimP()->OfKind( PNS_ITEM::SEGMENT ) && aPair.PrimN()->OfKind( PNS_ITEM::SEGMENT ) )
|
||||||
|
{
|
||||||
|
buildDpContinuation( aPair, aPreferDiagonal );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
majorDirection = ( p0_p - p0_n ).Perpendicular();
|
||||||
|
|
||||||
|
switch( shP->Type() )
|
||||||
|
{
|
||||||
|
case SH_RECT:
|
||||||
|
{
|
||||||
|
int w = static_cast<const SHAPE_RECT*>( shP )->GetWidth();
|
||||||
|
int h = static_cast<const SHAPE_RECT*>( shP )->GetHeight();
|
||||||
|
|
||||||
|
if( w < h )
|
||||||
|
std::swap( w, h );
|
||||||
|
|
||||||
|
orthoFanDistance = w * 3/4;
|
||||||
|
diagFanDistance = ( w - h ) / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SH_SEGMENT:
|
||||||
|
{
|
||||||
|
int w = static_cast<const SHAPE_SEGMENT*>( shP )->GetWidth();
|
||||||
|
SEG s = static_cast<const SHAPE_SEGMENT*>( shP )->GetSeg();
|
||||||
|
|
||||||
|
orthoFanDistance = w + ( s.B - s.A ).EuclideanNorm() / 2;
|
||||||
|
diagFanDistance = ( s.B - s.A ).EuclideanNorm() / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
BuildGeneric ( p0_p, p0_n, true );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( checkDiagonalAlignment( p0_p, p0_n ) )
|
||||||
|
{
|
||||||
|
int padDist = ( p0_p - p0_n ).EuclideanNorm();
|
||||||
|
|
||||||
|
for( int k = 0; k < 2; k++ )
|
||||||
|
{
|
||||||
|
VECTOR2I dir, dp, dv;
|
||||||
|
|
||||||
|
if( k == 0 )
|
||||||
|
{
|
||||||
|
dir = majorDirection.Resize( orthoFanDistance );
|
||||||
|
int d = ( padDist - m_gap ) / 2;
|
||||||
|
|
||||||
|
dp = dir.Resize( d );
|
||||||
|
dv = ( p0_n - p0_p ).Resize( d );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dir = majorDirection.Resize( diagFanDistance );
|
||||||
|
int d = ( padDist - m_gap ) / 2;
|
||||||
|
dp = dir.Resize( d );
|
||||||
|
dv = ( p0_n - p0_p ).Resize( d );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i = 0; i < 2; i++ )
|
||||||
|
{
|
||||||
|
int sign = i ? -1 : 1;
|
||||||
|
|
||||||
|
VECTOR2I gw_p( p0_p + sign * ( dir + dp ) + dv );
|
||||||
|
VECTOR2I gw_n( p0_n + sign * ( dir + dp ) - dv );
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN entryP( p0_p, p0_p + sign * dir, gw_p );
|
||||||
|
SHAPE_LINE_CHAIN entryN( p0_n, p0_n + sign * dir, gw_n );
|
||||||
|
|
||||||
|
PNS_DP_GATEWAY gw( gw_p, gw_n, false );
|
||||||
|
|
||||||
|
gw.SetEntryLines( entryP, entryN );
|
||||||
|
gw.SetPriority( 100 - k );
|
||||||
|
m_gateways.push_back( gw );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildGeneric( p0_p, p0_n, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DP_GATEWAYS::BuildForCursor( const VECTOR2I& aCursorPos )
|
||||||
|
{
|
||||||
|
int gap = m_fitVias ? m_viaGap + m_viaDiameter : m_gap;
|
||||||
|
|
||||||
|
for( int attempt = 0; attempt < 2; attempt++ )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 4; i++ )
|
||||||
|
{
|
||||||
|
VECTOR2I dir;
|
||||||
|
|
||||||
|
if( !attempt )
|
||||||
|
{
|
||||||
|
dir = VECTOR2I( gap, gap ).Resize( gap / 2 );
|
||||||
|
|
||||||
|
if( i % 2 == 0 )
|
||||||
|
dir.x = -dir.x;
|
||||||
|
|
||||||
|
if( i / 2 == 0 )
|
||||||
|
dir.y = -dir.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( i /2 == 0 )
|
||||||
|
dir = VECTOR2I( gap / 2 * ( ( i % 2 ) ? -1 : 1 ), 0 );
|
||||||
|
else
|
||||||
|
dir = VECTOR2I( 0, gap / 2 * ( ( i % 2 ) ? -1 : 1) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_fitVias )
|
||||||
|
BuildGeneric( aCursorPos + dir, aCursorPos - dir, true, true );
|
||||||
|
else
|
||||||
|
m_gateways.push_back( PNS_DP_GATEWAY( aCursorPos + dir,
|
||||||
|
aCursorPos - dir, attempt ? true : false ) );
|
||||||
|
|
||||||
|
drawGw ( aCursorPos + dir, 2 );
|
||||||
|
drawGw ( aCursorPos - dir, 3 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DP_GATEWAYS::buildEntries( const VECTOR2I& p0_p, const VECTOR2I& p0_n )
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( PNS_DP_GATEWAY &g, m_gateways )
|
||||||
|
{
|
||||||
|
if( !g.HasEntryLines() )
|
||||||
|
{
|
||||||
|
SHAPE_LINE_CHAIN lead_p = DIRECTION_45().BuildInitialTrace ( g.AnchorP(), p0_p, g.IsDiagonal() ).Reverse();
|
||||||
|
SHAPE_LINE_CHAIN lead_n = DIRECTION_45().BuildInitialTrace ( g.AnchorN(), p0_n, g.IsDiagonal() ).Reverse();
|
||||||
|
g.SetEntryLines( lead_p, lead_n );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DP_GATEWAYS::buildDpContinuation( PNS_DP_PRIMITIVE_PAIR aPair, bool aIsDiagonal )
|
||||||
|
{
|
||||||
|
PNS_DP_GATEWAY gw( aPair.AnchorP(), aPair.AnchorN(), aIsDiagonal );
|
||||||
|
gw.SetPriority( 100 );
|
||||||
|
m_gateways.push_back( gw );
|
||||||
|
|
||||||
|
if( !aPair.Directional() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
DIRECTION_45 dP = aPair.DirP();
|
||||||
|
DIRECTION_45 dN = aPair.DirN();
|
||||||
|
|
||||||
|
int gap = ( aPair.AnchorP() - aPair.AnchorN() ).EuclideanNorm();
|
||||||
|
|
||||||
|
VECTOR2I vdP = aPair.AnchorP() + dP.Left().ToVector();
|
||||||
|
VECTOR2I vdN = aPair.AnchorN() + dN.Left().ToVector();
|
||||||
|
|
||||||
|
PNS_SEGMENT* sP = static_cast<PNS_SEGMENT*>( aPair.PrimP() );
|
||||||
|
|
||||||
|
VECTOR2I t1, t2;
|
||||||
|
|
||||||
|
if( sP->Seg().Side( vdP ) == sP->Seg().Side( vdN ) )
|
||||||
|
{
|
||||||
|
t1 = aPair.AnchorP() + dP.Left().ToVector().Resize( gap );
|
||||||
|
t2 = aPair.AnchorN() + dP.Right().ToVector().Resize( gap );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t1 = aPair.AnchorP() + dP.Right().ToVector().Resize( gap );
|
||||||
|
t2 = aPair.AnchorN() + dP.Left().ToVector().Resize( gap );
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_DP_GATEWAY gwL( t2, aPair.AnchorN(), !aIsDiagonal );
|
||||||
|
SHAPE_LINE_CHAIN ep = dP.BuildInitialTrace( aPair.AnchorP(), t2, !aIsDiagonal );
|
||||||
|
|
||||||
|
gwL.SetPriority( 10 );
|
||||||
|
gwL.SetEntryLines( ep , SHAPE_LINE_CHAIN() );
|
||||||
|
|
||||||
|
m_gateways.push_back( gwL );
|
||||||
|
|
||||||
|
PNS_DP_GATEWAY gwR( aPair.AnchorP(), t1, !aIsDiagonal );
|
||||||
|
SHAPE_LINE_CHAIN en = dP.BuildInitialTrace( aPair.AnchorN(), t1, !aIsDiagonal );
|
||||||
|
gwR.SetPriority( 10) ;
|
||||||
|
gwR.SetEntryLines( SHAPE_LINE_CHAIN(), en );
|
||||||
|
|
||||||
|
m_gateways.push_back( gwR );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DP_GATEWAYS::BuildGeneric( const VECTOR2I& p0_p, const VECTOR2I& p0_n, bool aBuildEntries, bool aViaMode )
|
||||||
|
{
|
||||||
|
SEG st_p[2], st_n[2];
|
||||||
|
SEG d_n[2], d_p[2];
|
||||||
|
|
||||||
|
const int padToGapThreshold = 3;
|
||||||
|
int padDist = ( p0_p - p0_p ).EuclideanNorm();
|
||||||
|
|
||||||
|
st_p[0] = SEG(p0_p + VECTOR2I( -100, 0 ), p0_p + VECTOR2I( 100, 0 ) );
|
||||||
|
st_n[0] = SEG(p0_n + VECTOR2I( -100, 0 ), p0_n + VECTOR2I( 100, 0 ) );
|
||||||
|
st_p[1] = SEG(p0_p + VECTOR2I( 0, -100 ), p0_p + VECTOR2I( 0, 100 ) );
|
||||||
|
st_n[1] = SEG(p0_n + VECTOR2I( 0, -100 ), p0_n + VECTOR2I( 0, 100 ) );
|
||||||
|
d_p[0] = SEG( p0_p + VECTOR2I( -100, -100 ), p0_p + VECTOR2I( 100, 100 ) );
|
||||||
|
d_p[1] = SEG( p0_p + VECTOR2I( 100, -100 ), p0_p + VECTOR2I( -100, 100 ) );
|
||||||
|
d_n[0] = SEG( p0_n + VECTOR2I( -100, -100 ), p0_n + VECTOR2I( 100, 100 ) );
|
||||||
|
d_n[1] = SEG( p0_n + VECTOR2I( 100, -100 ), p0_n + VECTOR2I( -100, 100 ) );
|
||||||
|
|
||||||
|
// midpoint exit & side-by exits
|
||||||
|
for( int i = 0; i < 2; i++ )
|
||||||
|
{
|
||||||
|
bool straightColl = st_p[i].Collinear( st_n[i] );
|
||||||
|
bool diagColl = d_p[i].Collinear( d_n[i] );
|
||||||
|
|
||||||
|
if( straightColl || diagColl )
|
||||||
|
{
|
||||||
|
VECTOR2I dir = ( p0_n - p0_p ).Resize( m_gap / 2 );
|
||||||
|
VECTOR2I m = ( p0_p + p0_n ) / 2;
|
||||||
|
int prio = ( padDist > padToGapThreshold * m_gap ? 2 : 1);
|
||||||
|
|
||||||
|
if( !aViaMode )
|
||||||
|
{
|
||||||
|
m_gateways.push_back( PNS_DP_GATEWAY( m - dir, m + dir, diagColl, DIRECTION_45::ANG_RIGHT, prio ) );
|
||||||
|
|
||||||
|
dir = ( p0_n - p0_p ).Resize( m_gap );
|
||||||
|
m_gateways.push_back( PNS_DP_GATEWAY( p0_p - dir, p0_p - dir + dir.Perpendicular(), diagColl ) );
|
||||||
|
m_gateways.push_back( PNS_DP_GATEWAY( p0_p - dir, p0_p - dir - dir.Perpendicular(), diagColl ) );
|
||||||
|
m_gateways.push_back( PNS_DP_GATEWAY( p0_n + dir + dir.Perpendicular(), p0_n + dir, diagColl ) );
|
||||||
|
m_gateways.push_back( PNS_DP_GATEWAY( p0_n + dir - dir.Perpendicular(), p0_n + dir, diagColl ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i = 0; i < 2; i++ )
|
||||||
|
{
|
||||||
|
for( int j = 0; j < 2; j++ )
|
||||||
|
{
|
||||||
|
OPT_VECTOR2I ips[2], m;
|
||||||
|
|
||||||
|
ips[0] = d_n[i].IntersectLines( d_p[j] );
|
||||||
|
ips[1] = st_p[i].IntersectLines( st_n[j] );
|
||||||
|
|
||||||
|
if( d_n[i].Collinear( d_p[j] ) )
|
||||||
|
ips [0] = OPT_VECTOR2I();
|
||||||
|
if( st_p[i].Collinear( st_p[j] ) )
|
||||||
|
ips [1] = OPT_VECTOR2I();
|
||||||
|
|
||||||
|
// diagonal-diagonal and straight-straight cases - the most typical case if the pads
|
||||||
|
// are on the same straight/diagonal line
|
||||||
|
for( int k = 0; k < 2; k++ )
|
||||||
|
{
|
||||||
|
m = ips[k];
|
||||||
|
if( m && *m != p0_p && *m != p0_n )
|
||||||
|
{
|
||||||
|
int prio = ( padDist > padToGapThreshold * m_gap ? 10 : 20 );
|
||||||
|
VECTOR2I g_p( ( p0_p - *m ).Resize( (double) m_gap * M_SQRT1_2 ) );
|
||||||
|
VECTOR2I g_n( ( p0_n - *m ).Resize( (double) m_gap * M_SQRT1_2 ) );
|
||||||
|
|
||||||
|
m_gateways.push_back( PNS_DP_GATEWAY( *m + g_p, *m + g_n, k == 0 ? true : false, DIRECTION_45::ANG_OBTUSE, prio ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ips[0] = st_n[i].IntersectLines( d_p[j] );
|
||||||
|
ips[1] = st_p[i].IntersectLines( d_n[j] );
|
||||||
|
|
||||||
|
// diagonal-straight cases: 8 possibilities of "weirder" exists
|
||||||
|
for( int k = 0; k < 2; k++ )
|
||||||
|
{
|
||||||
|
m = ips[k];
|
||||||
|
|
||||||
|
if( !aViaMode && m && *m != p0_p && *m != p0_n )
|
||||||
|
{
|
||||||
|
VECTOR2I g_p, g_n;
|
||||||
|
|
||||||
|
g_p = ( p0_p - *m ).Resize( (double) m_gap * M_SQRT2 );
|
||||||
|
g_n = ( p0_n - *m ).Resize( (double) m_gap );
|
||||||
|
|
||||||
|
if( angle( g_p, g_n ) != DIRECTION_45::ANG_ACUTE )
|
||||||
|
m_gateways.push_back( PNS_DP_GATEWAY( *m + g_p, *m + g_n, true ) );
|
||||||
|
|
||||||
|
g_p = ( p0_p - *m ).Resize( m_gap );
|
||||||
|
g_n = ( p0_n - *m ).Resize( (double) m_gap * M_SQRT2 );
|
||||||
|
|
||||||
|
if( angle( g_p, g_n ) != DIRECTION_45::ANG_ACUTE )
|
||||||
|
m_gateways.push_back( PNS_DP_GATEWAY( *m + g_p, *m + g_n, true ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aBuildEntries )
|
||||||
|
buildEntries( p0_p, p0_n );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR PNS_DIFF_PAIR::EndingPrimitives()
|
||||||
|
{
|
||||||
|
if( m_hasVias )
|
||||||
|
return PNS_DP_PRIMITIVE_PAIR( &m_via_p, &m_via_n );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const PNS_LINE lP( PLine() );
|
||||||
|
const PNS_LINE lN( NLine() );
|
||||||
|
|
||||||
|
PNS_SEGMENT sP( lP, lP.CSegment( -1 ) );
|
||||||
|
PNS_SEGMENT sN( lN, lN.CSegment( -1 ) );
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR dpair( &sP, &sN );
|
||||||
|
dpair.SetAnchors( sP.Seg().B, sN.Seg().B );
|
||||||
|
|
||||||
|
return dpair;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool commonParallelProjection( SEG n, SEG p, SEG &pClip, SEG& nClip )
|
||||||
|
{
|
||||||
|
SEG n_proj_p( p.LineProject( n.A ), p.LineProject( n.B ) );
|
||||||
|
|
||||||
|
int64_t t_a = 0;
|
||||||
|
int64_t t_b = p.TCoef( p.B );
|
||||||
|
|
||||||
|
int64_t tproj_a = p.TCoef( n_proj_p.A );
|
||||||
|
int64_t tproj_b = p.TCoef( n_proj_p.B );
|
||||||
|
|
||||||
|
if( t_b < t_a )
|
||||||
|
std::swap( t_b, t_a );
|
||||||
|
|
||||||
|
if( tproj_b < tproj_a )
|
||||||
|
std::swap( tproj_b, tproj_a );
|
||||||
|
|
||||||
|
if( t_b <= tproj_a )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( t_a >= tproj_b )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int64_t t[4] = { 0, p.TCoef( p.B ), p.TCoef( n_proj_p.A ), p.TCoef( n_proj_p.B ) };
|
||||||
|
std::vector<int64_t> tv( t, t + 4 );
|
||||||
|
std::sort( tv.begin(), tv.end() ); // fixme: awful and disgusting way of finding 2 midpoints
|
||||||
|
|
||||||
|
int64_t pLenSq = p.SquaredLength();
|
||||||
|
|
||||||
|
VECTOR2I dp = p.B - p.A;
|
||||||
|
pClip.A.x = p.A.x + rescale( (int64_t)dp.x, tv[1], pLenSq );
|
||||||
|
pClip.A.y = p.A.y + rescale( (int64_t)dp.y, tv[1], pLenSq );
|
||||||
|
|
||||||
|
pClip.B.x = p.A.x + rescale( (int64_t)dp.x, tv[2], pLenSq );
|
||||||
|
pClip.B.y = p.A.y + rescale( (int64_t)dp.y, tv[2], pLenSq );
|
||||||
|
|
||||||
|
nClip.A = n.LineProject( pClip.A );
|
||||||
|
nClip.B = n.LineProject( pClip.B );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double PNS_DIFF_PAIR::Skew() const
|
||||||
|
{
|
||||||
|
return m_p.Length() - m_n.Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DIFF_PAIR::CoupledSegmentPairs( COUPLED_SEGMENTS_VEC& aPairs ) const
|
||||||
|
{
|
||||||
|
SHAPE_LINE_CHAIN p( m_p );
|
||||||
|
SHAPE_LINE_CHAIN n( m_n );
|
||||||
|
|
||||||
|
p.Simplify();
|
||||||
|
n.Simplify();
|
||||||
|
|
||||||
|
for( int i = 0; i < p.SegmentCount(); i++ )
|
||||||
|
{
|
||||||
|
for( int j = 0; j < n.SegmentCount(); j++ )
|
||||||
|
{
|
||||||
|
SEG sp = p.CSegment( i );
|
||||||
|
SEG sn = n.CSegment( j );
|
||||||
|
|
||||||
|
SEG p_clip, n_clip;
|
||||||
|
|
||||||
|
int64_t dist = std::abs( sp.Distance( sn ) - m_width );
|
||||||
|
|
||||||
|
if( sp.ApproxParallel( sn ) && m_gapConstraint.Matches( dist ) && commonParallelProjection( sp, sn, p_clip, n_clip ) )
|
||||||
|
{
|
||||||
|
const COUPLED_SEGMENTS spair( p_clip, sp, i, n_clip, sn, j );
|
||||||
|
aPairs.push_back( spair );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int64_t PNS_DIFF_PAIR::CoupledLength( const SHAPE_LINE_CHAIN& aP, const SHAPE_LINE_CHAIN& aN ) const
|
||||||
|
{
|
||||||
|
int64_t total = 0;
|
||||||
|
|
||||||
|
for( int i = 0; i < aP.SegmentCount(); i++ )
|
||||||
|
{
|
||||||
|
for( int j = 0; j < aN.SegmentCount(); j++ )
|
||||||
|
{
|
||||||
|
SEG sp = aP.CSegment( i );
|
||||||
|
SEG sn = aN.CSegment( j );
|
||||||
|
|
||||||
|
SEG p_clip, n_clip;
|
||||||
|
|
||||||
|
int64_t dist = std::abs( sp.Distance(sn) - m_width );
|
||||||
|
|
||||||
|
if( sp.ApproxParallel( sn ) && m_gapConstraint.Matches( dist ) &&
|
||||||
|
commonParallelProjection( sp, sn, p_clip, n_clip ) )
|
||||||
|
total += p_clip.Length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double PNS_DIFF_PAIR::CoupledLength() const
|
||||||
|
{
|
||||||
|
COUPLED_SEGMENTS_VEC pairs;
|
||||||
|
|
||||||
|
CoupledSegmentPairs( pairs );
|
||||||
|
|
||||||
|
double l = 0.0;
|
||||||
|
for( unsigned int i = 0; i < pairs.size(); i++ )
|
||||||
|
l += pairs[i].coupledP.Length();
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double PNS_DIFF_PAIR::CoupledLengthFactor() const
|
||||||
|
{
|
||||||
|
double t = TotalLength();
|
||||||
|
|
||||||
|
if( t == 0.0 )
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
return CoupledLength() / t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double PNS_DIFF_PAIR::TotalLength() const
|
||||||
|
{
|
||||||
|
double lenP = m_p.Length();
|
||||||
|
double lenN = m_n.Length();
|
||||||
|
|
||||||
|
return (lenN + lenP ) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_DIFF_PAIR::CoupledLength ( const SEG& aP, const SEG& aN ) const
|
||||||
|
{
|
||||||
|
SEG p_clip, n_clip;
|
||||||
|
int64_t dist = std::abs( aP.Distance( aN ) - m_width );
|
||||||
|
|
||||||
|
if( aP.ApproxParallel( aN ) && m_gapConstraint.Matches( dist ) &&
|
||||||
|
commonParallelProjection ( aP, aN, p_clip, n_clip ) )
|
||||||
|
return p_clip.Length();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,454 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __PNS_DIFF_PAIR_H
|
||||||
|
#define __PNS_DIFF_PAIR_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <geometry/shape.h>
|
||||||
|
#include <geometry/shape_line_chain.h>
|
||||||
|
|
||||||
|
#include "pns_line.h"
|
||||||
|
#include "pns_via.h"
|
||||||
|
|
||||||
|
#include "ranged_num.h"
|
||||||
|
|
||||||
|
class PNS_DIFF_PAIR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_DP_GATEWAY
|
||||||
|
*
|
||||||
|
* Defines a "gateway" for routing a differential pair - e.g. a pair of points (anchors) with certain
|
||||||
|
* orientation, spacing and (optionally) predefined entry paths. The routing algorithm connects such
|
||||||
|
* gateways with parallel lines, thus creating a difrerential pair.
|
||||||
|
**/
|
||||||
|
class PNS_DP_GATEWAY {
|
||||||
|
public:
|
||||||
|
PNS_DP_GATEWAY( const VECTOR2I& aAnchorP,
|
||||||
|
const VECTOR2I& aAnchorN,
|
||||||
|
bool aIsDiagonal,
|
||||||
|
int aAllowedEntryAngles = DIRECTION_45::ANG_OBTUSE,
|
||||||
|
int aPriority = 0 )
|
||||||
|
: m_anchorP( aAnchorP ),
|
||||||
|
m_anchorN( aAnchorN ),
|
||||||
|
m_isDiagonal( aIsDiagonal ),
|
||||||
|
m_allowedEntryAngles( aAllowedEntryAngles ),
|
||||||
|
m_priority( aPriority )
|
||||||
|
{
|
||||||
|
m_hasEntryLines = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
~PNS_DP_GATEWAY()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function IsDiagonal()
|
||||||
|
*
|
||||||
|
* @return true, if the gateway anchors lie on a diagonal line
|
||||||
|
*/
|
||||||
|
bool IsDiagonal() const
|
||||||
|
{
|
||||||
|
return m_isDiagonal;
|
||||||
|
}
|
||||||
|
|
||||||
|
const VECTOR2I& AnchorP() const { return m_anchorP; }
|
||||||
|
|
||||||
|
const VECTOR2I& AnchorN() const { return m_anchorN; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function AllowedAngles()
|
||||||
|
*
|
||||||
|
* @return a mask of 45-degree entry directoins allowed for the
|
||||||
|
* gateway.
|
||||||
|
*/
|
||||||
|
int AllowedAngles () const { return m_allowedEntryAngles; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Priority()
|
||||||
|
*
|
||||||
|
* @return priority/score value for gateway matching
|
||||||
|
*/
|
||||||
|
int Priority() const
|
||||||
|
{
|
||||||
|
return m_priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPriority(int aPriority)
|
||||||
|
{
|
||||||
|
m_priority = aPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetEntryLines( const SHAPE_LINE_CHAIN& aEntryP, const SHAPE_LINE_CHAIN& aEntryN )
|
||||||
|
{
|
||||||
|
m_entryP = aEntryP;
|
||||||
|
m_entryN = aEntryN;
|
||||||
|
m_hasEntryLines = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHAPE_LINE_CHAIN& EntryP() const { return m_entryP; }
|
||||||
|
const SHAPE_LINE_CHAIN& EntryN() const { return m_entryN; }
|
||||||
|
const PNS_DIFF_PAIR Entry() const ;
|
||||||
|
|
||||||
|
void Reverse();
|
||||||
|
|
||||||
|
bool HasEntryLines () const
|
||||||
|
{
|
||||||
|
return m_hasEntryLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SHAPE_LINE_CHAIN m_entryP, m_entryN;
|
||||||
|
bool m_hasEntryLines;
|
||||||
|
VECTOR2I m_anchorP, m_anchorN;
|
||||||
|
bool m_isDiagonal;
|
||||||
|
int m_allowedEntryAngles;
|
||||||
|
int m_priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_DP_PRIMITIVE_PAIR
|
||||||
|
*
|
||||||
|
* Stores staring/ending primitives (pads, vias or segments) for a differential pair.
|
||||||
|
**/
|
||||||
|
class PNS_DP_PRIMITIVE_PAIR
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PNS_DP_PRIMITIVE_PAIR():
|
||||||
|
m_primP( NULL ), m_primN( NULL ) {};
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR( const PNS_DP_PRIMITIVE_PAIR& aOther );
|
||||||
|
PNS_DP_PRIMITIVE_PAIR( PNS_ITEM* aPrimP, PNS_ITEM* aPrimN );
|
||||||
|
PNS_DP_PRIMITIVE_PAIR( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
|
||||||
|
|
||||||
|
~PNS_DP_PRIMITIVE_PAIR();
|
||||||
|
|
||||||
|
void SetAnchors( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
|
||||||
|
|
||||||
|
const VECTOR2I& AnchorP() const { return m_anchorP; }
|
||||||
|
const VECTOR2I& AnchorN() const { return m_anchorN; }
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR& operator=( const PNS_DP_PRIMITIVE_PAIR& aOther );
|
||||||
|
|
||||||
|
PNS_ITEM* PrimP() const { return m_primP; }
|
||||||
|
PNS_ITEM* PrimN() const { return m_primN; }
|
||||||
|
|
||||||
|
bool Directional() const;
|
||||||
|
|
||||||
|
DIRECTION_45 DirP() const;
|
||||||
|
DIRECTION_45 DirN() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DIRECTION_45 anchorDirection( PNS_ITEM* aItem, const VECTOR2I& aP ) const;
|
||||||
|
|
||||||
|
PNS_ITEM* m_primP;
|
||||||
|
PNS_ITEM* m_primN;
|
||||||
|
VECTOR2I m_anchorP, m_anchorN;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_GATEWAYS
|
||||||
|
*
|
||||||
|
* A set of gateways calculated for the cursor or starting/ending primitive pair.
|
||||||
|
**/
|
||||||
|
|
||||||
|
class PNS_DP_GATEWAYS
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
PNS_DP_GATEWAYS ( int aGap ):
|
||||||
|
m_gap(aGap), m_viaGap( aGap ) {};
|
||||||
|
|
||||||
|
void SetGap ( int aGap ) {
|
||||||
|
m_gap = aGap;
|
||||||
|
m_viaGap = aGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
m_gateways.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetFitVias ( bool aEnable, int aDiameter = 0, int aViaGap = -1 )
|
||||||
|
{
|
||||||
|
m_fitVias = aEnable;
|
||||||
|
m_viaDiameter = aDiameter;
|
||||||
|
if(aViaGap < 0)
|
||||||
|
m_viaGap = m_gap;
|
||||||
|
else
|
||||||
|
m_viaGap = aViaGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BuildForCursor ( const VECTOR2I& aCursorPos );
|
||||||
|
void BuildOrthoProjections ( PNS_DP_GATEWAYS &aEntries, const VECTOR2I& aCursorPos, int aOrthoScore );
|
||||||
|
void BuildGeneric ( const VECTOR2I& p0_p, const VECTOR2I& p0_n, bool aBuildEntries = false, bool aViaMode = false );
|
||||||
|
void BuildFromPrimitivePair( PNS_DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal );
|
||||||
|
|
||||||
|
bool FitGateways ( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& aTarget, bool aPrefDiagonal, PNS_DIFF_PAIR& aDp );
|
||||||
|
|
||||||
|
std::vector<PNS_DP_GATEWAY>& Gateways()
|
||||||
|
{
|
||||||
|
return m_gateways;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct DP_CANDIDATE
|
||||||
|
{
|
||||||
|
SHAPE_LINE_CHAIN p, n;
|
||||||
|
VECTOR2I gw_p, gw_n;
|
||||||
|
int score;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool checkDiagonalAlignment ( const VECTOR2I& a, const VECTOR2I& b) const;
|
||||||
|
void buildDpContinuation ( PNS_DP_PRIMITIVE_PAIR aPair, bool aIsDiagonal );
|
||||||
|
void buildEntries ( const VECTOR2I& p0_p, const VECTOR2I& p0_n );
|
||||||
|
|
||||||
|
int m_gap;
|
||||||
|
int m_viaGap;
|
||||||
|
int m_viaDiameter;
|
||||||
|
bool m_fitVias;
|
||||||
|
|
||||||
|
std::vector<PNS_DP_GATEWAY> m_gateways;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_DIFF_PAIR
|
||||||
|
*
|
||||||
|
* Basic class for a differential pair. Stores two PNS_LINEs (for positive and negative nets, respectively),
|
||||||
|
* the gap and coupling constraints.
|
||||||
|
**/
|
||||||
|
class PNS_DIFF_PAIR : public PNS_ITEM {
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct COUPLED_SEGMENTS {
|
||||||
|
COUPLED_SEGMENTS ( const SEG& aCoupledP, const SEG& aParentP, int aIndexP,
|
||||||
|
const SEG& aCoupledN, const SEG& aParentN, int aIndexN ) :
|
||||||
|
coupledP ( aCoupledP ),
|
||||||
|
coupledN ( aCoupledN ),
|
||||||
|
parentP ( aParentP ),
|
||||||
|
parentN ( aParentN ),
|
||||||
|
indexP ( aIndexP ),
|
||||||
|
indexN ( aIndexN )
|
||||||
|
{}
|
||||||
|
|
||||||
|
SEG coupledP;
|
||||||
|
SEG coupledN;
|
||||||
|
SEG parentP;
|
||||||
|
SEG parentN;
|
||||||
|
int indexP;
|
||||||
|
int indexN;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<COUPLED_SEGMENTS> COUPLED_SEGMENTS_VEC;
|
||||||
|
|
||||||
|
PNS_DIFF_PAIR ( ) : PNS_ITEM ( DIFF_PAIR ), m_hasVias (false) {}
|
||||||
|
|
||||||
|
PNS_DIFF_PAIR ( int aGap ) :
|
||||||
|
PNS_ITEM ( DIFF_PAIR ),
|
||||||
|
m_hasVias (false)
|
||||||
|
{
|
||||||
|
m_gapConstraint = aGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_DIFF_PAIR ( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, int aGap = 0 ):
|
||||||
|
PNS_ITEM ( DIFF_PAIR ),
|
||||||
|
m_n (aN),
|
||||||
|
m_p (aP),
|
||||||
|
m_hasVias (false)
|
||||||
|
{
|
||||||
|
m_gapConstraint = aGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_DIFF_PAIR ( const PNS_LINE &aLineP, const PNS_LINE &aLineN, int aGap = 0 ):
|
||||||
|
PNS_ITEM ( DIFF_PAIR ),
|
||||||
|
m_line_p ( aLineP ),
|
||||||
|
m_line_n ( aLineN ),
|
||||||
|
m_hasVias (false)
|
||||||
|
{
|
||||||
|
m_gapConstraint = aGap;
|
||||||
|
m_net_p = aLineP.Net();
|
||||||
|
m_net_n = aLineN.Net();
|
||||||
|
m_p = aLineP.CLine();
|
||||||
|
m_n = aLineN.CLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool ClassOf( const PNS_ITEM* aItem )
|
||||||
|
{
|
||||||
|
return aItem && DIFF_PAIR == aItem->Kind();
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_DIFF_PAIR * Clone() const { assert(false); return NULL; }
|
||||||
|
|
||||||
|
static PNS_DIFF_PAIR* AssembleDp ( PNS_LINE *aLine );
|
||||||
|
|
||||||
|
void SetShape ( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, bool aSwapLanes = false)
|
||||||
|
{
|
||||||
|
if (aSwapLanes)
|
||||||
|
{
|
||||||
|
m_p = aN;
|
||||||
|
m_n = aP;
|
||||||
|
} else {
|
||||||
|
m_p = aP;
|
||||||
|
m_n = aN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetShape ( const PNS_DIFF_PAIR& aPair )
|
||||||
|
{
|
||||||
|
m_p = aPair.m_p;
|
||||||
|
m_n = aPair.m_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetNets ( int aP, int aN )
|
||||||
|
{
|
||||||
|
m_net_p = aP;
|
||||||
|
m_net_n = aN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetWidth ( int aWidth )
|
||||||
|
{
|
||||||
|
m_width = aWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Width() const { return m_width; }
|
||||||
|
|
||||||
|
void SetGap ( int aGap)
|
||||||
|
{
|
||||||
|
m_gap = aGap;
|
||||||
|
m_gapConstraint = RANGED_NUM<int> ( m_gap, 10000, 10000 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int Gap() const {
|
||||||
|
return m_gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppendVias ( const PNS_VIA &aViaP, const PNS_VIA& aViaN )
|
||||||
|
{
|
||||||
|
m_hasVias = true;
|
||||||
|
m_via_p = aViaP;
|
||||||
|
m_via_n = aViaN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveVias ()
|
||||||
|
{
|
||||||
|
m_hasVias = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EndsWithVias() const
|
||||||
|
{
|
||||||
|
return m_hasVias;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetP() const
|
||||||
|
{
|
||||||
|
return m_net_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetN() const
|
||||||
|
{
|
||||||
|
return m_net_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_LINE& PLine()
|
||||||
|
{
|
||||||
|
if ( !m_line_p.IsLinked ( ) )
|
||||||
|
updateLine(m_line_p, m_p, m_net_p, m_via_p );
|
||||||
|
return m_line_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_LINE& NLine()
|
||||||
|
{
|
||||||
|
if ( !m_line_n.IsLinked ( ) )
|
||||||
|
updateLine(m_line_n, m_n, m_net_n, m_via_n );
|
||||||
|
return m_line_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR EndingPrimitives();
|
||||||
|
|
||||||
|
double CoupledLength() const;
|
||||||
|
double TotalLength() const;
|
||||||
|
double CoupledLengthFactor () const;
|
||||||
|
double Skew () const;
|
||||||
|
|
||||||
|
void CoupledSegmentPairs ( COUPLED_SEGMENTS_VEC& aPairs ) const;
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
m_n.Clear();
|
||||||
|
m_p.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Append (const PNS_DIFF_PAIR& aOther )
|
||||||
|
{
|
||||||
|
m_n.Append ( aOther.m_n );
|
||||||
|
m_p.Append ( aOther.m_p );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Empty() const
|
||||||
|
{
|
||||||
|
return (m_n.SegmentCount() == 0) || (m_p.SegmentCount() == 0);
|
||||||
|
}
|
||||||
|
const SHAPE_LINE_CHAIN& CP() const { return m_p; }
|
||||||
|
const SHAPE_LINE_CHAIN& CN() const { return m_n; }
|
||||||
|
|
||||||
|
bool BuildInitial ( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY& aTarget, bool aPrefDiagonal );
|
||||||
|
bool CheckConnectionAngle ( const PNS_DIFF_PAIR &aOther, int allowedAngles ) const;
|
||||||
|
int CoupledLength ( const SEG& aP, const SEG& aN ) const;
|
||||||
|
|
||||||
|
int64_t CoupledLength ( const SHAPE_LINE_CHAIN& aP, const SHAPE_LINE_CHAIN& aN ) const;
|
||||||
|
|
||||||
|
const RANGED_NUM<int> GapConstraint() const {
|
||||||
|
return m_gapConstraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void updateLine( PNS_LINE &aLine, const SHAPE_LINE_CHAIN& aShape, int aNet, PNS_VIA& aVia )
|
||||||
|
{
|
||||||
|
aLine.SetShape( aShape );
|
||||||
|
aLine.SetWidth( m_width );
|
||||||
|
aLine.SetNet(aNet);
|
||||||
|
aLine.SetLayer (Layers().Start());
|
||||||
|
|
||||||
|
if(m_hasVias)
|
||||||
|
aLine.AppendVia ( aVia );
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN m_n, m_p;
|
||||||
|
PNS_LINE m_line_p, m_line_n;
|
||||||
|
PNS_VIA m_via_p, m_via_n;
|
||||||
|
|
||||||
|
bool m_hasVias;
|
||||||
|
int m_net_p, m_net_n;
|
||||||
|
int m_width;
|
||||||
|
int m_gap;
|
||||||
|
int m_viaGap;
|
||||||
|
int m_maxUncoupledLength;
|
||||||
|
int m_chamferLimit;
|
||||||
|
RANGED_NUM<int> m_gapConstraint;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,797 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#include <colors.h>
|
||||||
|
#include <class_board.h>
|
||||||
|
#include <class_board_item.h>
|
||||||
|
#include <class_netinfo.h>
|
||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#include "pns_node.h"
|
||||||
|
#include "pns_walkaround.h"
|
||||||
|
#include "pns_shove.h"
|
||||||
|
#include "pns_utils.h"
|
||||||
|
#include "pns_router.h"
|
||||||
|
#include "pns_diff_pair_placer.h"
|
||||||
|
#include "pns_solid.h"
|
||||||
|
#include "pns_topology.h"
|
||||||
|
|
||||||
|
using boost::optional;
|
||||||
|
|
||||||
|
PNS_DIFF_PAIR_PLACER::PNS_DIFF_PAIR_PLACER( PNS_ROUTER* aRouter ) :
|
||||||
|
PNS_PLACEMENT_ALGO ( aRouter )
|
||||||
|
{
|
||||||
|
m_initialDiagonal = false;
|
||||||
|
m_startDiagonal = false;
|
||||||
|
m_world = NULL;
|
||||||
|
m_shove = NULL;
|
||||||
|
m_currentNode = NULL;
|
||||||
|
m_idle = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_DIFF_PAIR_PLACER::~PNS_DIFF_PAIR_PLACER()
|
||||||
|
{
|
||||||
|
if( m_shove )
|
||||||
|
delete m_shove;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DIFF_PAIR_PLACER::setWorld( PNS_NODE* aWorld )
|
||||||
|
{
|
||||||
|
m_world = aWorld;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const PNS_VIA PNS_DIFF_PAIR_PLACER::makeVia( const VECTOR2I& aP, int aNet )
|
||||||
|
{
|
||||||
|
const PNS_LAYERSET layers( m_sizes.GetLayerTop(), m_sizes.GetLayerBottom() );
|
||||||
|
|
||||||
|
PNS_VIA v( aP, layers, m_sizes.ViaDiameter(), m_sizes.ViaDrill(), -1, m_sizes.ViaType() );
|
||||||
|
v.SetNet( aNet );
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DIFF_PAIR_PLACER::SetOrthoMode ( bool aOrthoMode )
|
||||||
|
{
|
||||||
|
m_orthoMode = aOrthoMode;
|
||||||
|
|
||||||
|
if( !m_idle )
|
||||||
|
Move( m_currentEnd, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::ToggleVia( bool aEnabled )
|
||||||
|
{
|
||||||
|
m_placingVia = aEnabled;
|
||||||
|
|
||||||
|
if( !m_idle )
|
||||||
|
Move( m_currentEnd, NULL );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::rhMarkObstacles( const VECTOR2I& aP )
|
||||||
|
{
|
||||||
|
if( !routeHead( aP ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool collP = m_currentNode->CheckColliding( &m_currentTrace.PLine() );
|
||||||
|
bool collN = m_currentNode->CheckColliding( &m_currentTrace.NLine() );
|
||||||
|
|
||||||
|
m_fitOk = !( collP || collN ) ;
|
||||||
|
return m_fitOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNewP )
|
||||||
|
{
|
||||||
|
PNS_VIA virtHead = makeVia( aP, -1 );
|
||||||
|
|
||||||
|
if( m_placingVia )
|
||||||
|
virtHead.SetDiameter( viaGap() + 2 * virtHead.Diameter() );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
virtHead.SetLayer( m_currentLayer );
|
||||||
|
virtHead.SetDiameter( m_sizes.DiffPairGap() + 2 * m_sizes.TrackWidth() );
|
||||||
|
}
|
||||||
|
|
||||||
|
VECTOR2I lead( 0, 0 );// = aP - m_currentStart ;
|
||||||
|
VECTOR2I force;
|
||||||
|
bool solidsOnly = true;
|
||||||
|
|
||||||
|
if( m_currentMode == RM_MarkObstacles )
|
||||||
|
{
|
||||||
|
aNewP = aP;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if( m_currentMode == RM_Walkaround )
|
||||||
|
{
|
||||||
|
solidsOnly = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixme: I'm too lazy to do it well. Circular approximaton will do for the moment.
|
||||||
|
if( virtHead.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
|
||||||
|
{
|
||||||
|
aNewP = aP + force;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::attemptWalk ( PNS_NODE* aNode, PNS_DIFF_PAIR* aCurrent, PNS_DIFF_PAIR& aWalk, bool aPFirst, bool aWindCw, bool aSolidsOnly )
|
||||||
|
{
|
||||||
|
PNS_WALKAROUND walkaround( aNode, Router() );
|
||||||
|
PNS_WALKAROUND::WALKAROUND_STATUS wf1;
|
||||||
|
|
||||||
|
Router()->GetClearanceFunc()->OverrideClearance( true, aCurrent->NetP(), aCurrent->NetN(), aCurrent->Gap() );
|
||||||
|
|
||||||
|
walkaround.SetSolidsOnly( aSolidsOnly );
|
||||||
|
walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
|
||||||
|
|
||||||
|
PNS_SHOVE shove( aNode, Router() );
|
||||||
|
PNS_LINE walkP, walkN;
|
||||||
|
|
||||||
|
aWalk = *aCurrent;
|
||||||
|
|
||||||
|
int iter = 0;
|
||||||
|
|
||||||
|
PNS_DIFF_PAIR cur( *aCurrent );
|
||||||
|
|
||||||
|
bool currentIsP = aPFirst;
|
||||||
|
|
||||||
|
int mask = aSolidsOnly ? PNS_ITEM::SOLID : PNS_ITEM::ANY;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
PNS_LINE preWalk = ( currentIsP ? cur.PLine() : cur.NLine() );
|
||||||
|
PNS_LINE preShove = ( currentIsP ? cur.NLine() : cur.PLine() );
|
||||||
|
PNS_LINE postWalk;
|
||||||
|
|
||||||
|
if( !aNode->CheckColliding ( &preWalk, mask ) )
|
||||||
|
{
|
||||||
|
currentIsP = !currentIsP;
|
||||||
|
|
||||||
|
if( !aNode->CheckColliding( &preShove, mask ) )
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
wf1 = walkaround.Route( preWalk, postWalk, false );
|
||||||
|
|
||||||
|
if( wf1 != PNS_WALKAROUND::DONE )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PNS_LINE postShove( preShove );
|
||||||
|
|
||||||
|
shove.ForceClearance( true, cur.Gap() - 2 * PNS_HULL_MARGIN );
|
||||||
|
|
||||||
|
PNS_SHOVE::SHOVE_STATUS sh1;
|
||||||
|
|
||||||
|
sh1 = shove.ProcessSingleLine( &postWalk, &preShove, &postShove );
|
||||||
|
|
||||||
|
if( sh1 != PNS_SHOVE::SH_OK )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
postWalk.Line().Simplify();
|
||||||
|
postShove.Line().Simplify();
|
||||||
|
|
||||||
|
cur.SetShape( postWalk.CLine(), postShove.CLine(), !currentIsP );
|
||||||
|
|
||||||
|
currentIsP = !currentIsP;
|
||||||
|
|
||||||
|
if( !aNode->CheckColliding( &postShove, mask ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
while( iter < 3 );
|
||||||
|
|
||||||
|
if( iter == 3 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
aWalk.SetShape( cur.CP(), cur.CN() );
|
||||||
|
Router()->GetClearanceFunc()->OverrideClearance( false );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::tryWalkDp( PNS_NODE* aNode, PNS_DIFF_PAIR &aPair, bool aSolidsOnly )
|
||||||
|
{
|
||||||
|
PNS_DIFF_PAIR best;
|
||||||
|
double bestScore = 100000000000000.0;
|
||||||
|
|
||||||
|
for( int attempt = 0; attempt <= 1; attempt++ )
|
||||||
|
{
|
||||||
|
PNS_DIFF_PAIR p;
|
||||||
|
PNS_NODE *tmp = m_currentNode->Branch();
|
||||||
|
|
||||||
|
bool pfirst = attempt % 2 ? true : false;
|
||||||
|
bool wind_cw = attempt / 2 ? true : false;
|
||||||
|
|
||||||
|
if( attemptWalk ( tmp, &aPair, p, pfirst, wind_cw, aSolidsOnly ) )
|
||||||
|
{
|
||||||
|
// double len = p.TotalLength();
|
||||||
|
double cl = p.CoupledLength();
|
||||||
|
double skew = p.Skew();
|
||||||
|
|
||||||
|
double score = cl + fabs(skew) * 3.0;
|
||||||
|
|
||||||
|
if( score < bestScore )
|
||||||
|
{
|
||||||
|
bestScore = score;
|
||||||
|
best = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( bestScore > 0.0 )
|
||||||
|
{
|
||||||
|
PNS_OPTIMIZER optimizer( m_currentNode );
|
||||||
|
|
||||||
|
aPair.SetShape( best );
|
||||||
|
optimizer.Optimize( &aPair );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::rhWalkOnly( const VECTOR2I& aP )
|
||||||
|
{
|
||||||
|
if( !routeHead ( aP ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_fitOk = tryWalkDp( m_currentNode, m_currentTrace, false );
|
||||||
|
|
||||||
|
return m_fitOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::route( const VECTOR2I& aP )
|
||||||
|
{
|
||||||
|
switch( m_currentMode )
|
||||||
|
{
|
||||||
|
case RM_MarkObstacles:
|
||||||
|
return rhMarkObstacles( aP );
|
||||||
|
case RM_Walkaround:
|
||||||
|
return rhWalkOnly ( aP );
|
||||||
|
case RM_Shove:
|
||||||
|
return rhShoveOnly ( aP );
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::rhShoveOnly( const VECTOR2I& aP )
|
||||||
|
{
|
||||||
|
m_currentNode = m_shove->CurrentNode();
|
||||||
|
|
||||||
|
bool ok = routeHead ( aP );
|
||||||
|
|
||||||
|
m_fitOk = false;
|
||||||
|
|
||||||
|
if( !ok )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( !tryWalkDp( m_currentNode, m_currentTrace, true ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PNS_LINE pLine( m_currentTrace.PLine() );
|
||||||
|
PNS_LINE nLine( m_currentTrace.NLine() );
|
||||||
|
PNS_ITEMSET head;
|
||||||
|
|
||||||
|
head.Add( &pLine );
|
||||||
|
head.Add( &nLine );
|
||||||
|
|
||||||
|
PNS_SHOVE::SHOVE_STATUS status = m_shove->ShoveMultiLines( head );
|
||||||
|
|
||||||
|
m_currentNode = m_shove->CurrentNode();
|
||||||
|
|
||||||
|
if( status == PNS_SHOVE::SH_OK )
|
||||||
|
{
|
||||||
|
m_currentNode = m_shove->CurrentNode();
|
||||||
|
|
||||||
|
if( !m_currentNode->CheckColliding( &m_currentTrace.PLine() ) &&
|
||||||
|
!m_currentNode->CheckColliding( &m_currentTrace.NLine() ) )
|
||||||
|
{
|
||||||
|
m_fitOk = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_fitOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const PNS_ITEMSET PNS_DIFF_PAIR_PLACER::Traces()
|
||||||
|
{
|
||||||
|
PNS_ITEMSET t;
|
||||||
|
|
||||||
|
t.Add( const_cast<PNS_LINE*>( &m_currentTrace.PLine() ) );
|
||||||
|
t.Add( const_cast<PNS_LINE*>( &m_currentTrace.NLine() ) );
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DIFF_PAIR_PLACER::FlipPosture()
|
||||||
|
{
|
||||||
|
m_startDiagonal = !m_startDiagonal;
|
||||||
|
|
||||||
|
if( !m_idle )
|
||||||
|
Move( m_currentEnd, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_NODE* PNS_DIFF_PAIR_PLACER::CurrentNode( bool aLoopsRemoved ) const
|
||||||
|
{
|
||||||
|
if( m_lastNode )
|
||||||
|
return m_lastNode;
|
||||||
|
|
||||||
|
return m_currentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::SetLayer( int aLayer )
|
||||||
|
{
|
||||||
|
if( m_idle )
|
||||||
|
{
|
||||||
|
m_currentLayer = aLayer;
|
||||||
|
return true;
|
||||||
|
} else if( m_chainedPlacement )
|
||||||
|
return false;
|
||||||
|
else if( !m_prevPair )
|
||||||
|
return false;
|
||||||
|
else if( m_prevPair->PrimP() || ( m_prevPair->PrimP()->OfKind( PNS_ITEM::VIA ) &&
|
||||||
|
m_prevPair->PrimP()->Layers().Overlaps( aLayer ) ) )
|
||||||
|
{
|
||||||
|
m_currentLayer = aLayer;
|
||||||
|
m_start = *m_prevPair;
|
||||||
|
initPlacement( false );
|
||||||
|
Move( m_currentEnd, NULL );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_DIFF_PAIR_PLACER::matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName )
|
||||||
|
{
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
if( aNetName.EndsWith( "+" ) )
|
||||||
|
{
|
||||||
|
aComplementNet = "-";
|
||||||
|
rv = 1;
|
||||||
|
}
|
||||||
|
else if( aNetName.EndsWith( "_P" ) )
|
||||||
|
{
|
||||||
|
aComplementNet = "_N";
|
||||||
|
rv = 1;
|
||||||
|
}
|
||||||
|
else if( aNetName.EndsWith( "-" ) )
|
||||||
|
{
|
||||||
|
aComplementNet = "+";
|
||||||
|
rv = -1;
|
||||||
|
}
|
||||||
|
else if( aNetName.EndsWith( "_N" ) )
|
||||||
|
{
|
||||||
|
aComplementNet = "_P";
|
||||||
|
rv = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rv != 0 )
|
||||||
|
{
|
||||||
|
aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OPT_VECTOR2I PNS_DIFF_PAIR_PLACER::getDanglingAnchor( PNS_NODE* aNode, PNS_ITEM* aItem )
|
||||||
|
{
|
||||||
|
switch( aItem->Kind() )
|
||||||
|
{
|
||||||
|
case PNS_ITEM::VIA:
|
||||||
|
case PNS_ITEM::SOLID:
|
||||||
|
return aItem->Anchor( 0 );
|
||||||
|
|
||||||
|
case PNS_ITEM::SEGMENT:
|
||||||
|
{
|
||||||
|
PNS_SEGMENT* s =static_cast<PNS_SEGMENT*>( aItem );
|
||||||
|
|
||||||
|
PNS_JOINT* jA = aNode->FindJoint( s->Seg().A, s );
|
||||||
|
PNS_JOINT* jB = aNode->FindJoint( s->Seg().B, s );
|
||||||
|
|
||||||
|
if( jA->LinkCount() == 1 )
|
||||||
|
return s->Seg().A;
|
||||||
|
else if( jB->LinkCount() == 1 )
|
||||||
|
return s->Seg().B;
|
||||||
|
else
|
||||||
|
return OPT_VECTOR2I();
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return OPT_VECTOR2I();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aItem, PNS_DP_PRIMITIVE_PAIR& aPair )
|
||||||
|
{
|
||||||
|
if( !aItem || !aItem->Parent() || !aItem->Parent()->GetNet() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxString netNameP = aItem->Parent()->GetNet()->GetNetname();
|
||||||
|
wxString netNameN, netNameBase;
|
||||||
|
|
||||||
|
BOARD* brd = Router()->GetBoard();
|
||||||
|
PNS_ITEM *primRef = NULL, *primP = NULL, *primN = NULL;
|
||||||
|
|
||||||
|
int refNet;
|
||||||
|
|
||||||
|
wxString suffix;
|
||||||
|
|
||||||
|
int r = matchDpSuffix ( netNameP, suffix, netNameBase );
|
||||||
|
|
||||||
|
if( r == 0 )
|
||||||
|
return false;
|
||||||
|
else if( r == 1 )
|
||||||
|
{
|
||||||
|
primRef = primP = static_cast<PNS_SOLID*>( aItem );
|
||||||
|
netNameN = netNameBase + suffix;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
primRef = primN = static_cast<PNS_SOLID*>( aItem );
|
||||||
|
netNameN = netNameP;
|
||||||
|
netNameP = netNameBase + suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
int netP = brd->FindNet( netNameP )->GetNet();
|
||||||
|
int netN = brd->FindNet( netNameN )->GetNet();
|
||||||
|
|
||||||
|
if( primP )
|
||||||
|
refNet = netN;
|
||||||
|
else
|
||||||
|
refNet = netP;
|
||||||
|
|
||||||
|
|
||||||
|
std::set<PNS_ITEM*> items;
|
||||||
|
|
||||||
|
OPT_VECTOR2I refAnchor = getDanglingAnchor( m_currentNode, primRef );
|
||||||
|
|
||||||
|
if( !refAnchor )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_currentNode->AllItemsInNet( refNet, items );
|
||||||
|
double bestDist = std::numeric_limits<double>::max();
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
BOOST_FOREACH(PNS_ITEM* item, items )
|
||||||
|
{
|
||||||
|
if( item->Kind() == aItem->Kind() )
|
||||||
|
{
|
||||||
|
OPT_VECTOR2I anchor = getDanglingAnchor( m_currentNode, item );
|
||||||
|
if( !anchor )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double dist = ( *anchor - *refAnchor ).EuclideanNorm();
|
||||||
|
|
||||||
|
if( dist < bestDist )
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
bestDist = dist;
|
||||||
|
|
||||||
|
if( refNet == netP )
|
||||||
|
{
|
||||||
|
aPair = PNS_DP_PRIMITIVE_PAIR ( item, primRef );
|
||||||
|
aPair.SetAnchors( *anchor, *refAnchor );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aPair = PNS_DP_PRIMITIVE_PAIR( primRef, item );
|
||||||
|
aPair.SetAnchors( *refAnchor, *anchor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_DIFF_PAIR_PLACER::viaGap() const
|
||||||
|
{
|
||||||
|
return m_sizes.DiffPairViaGap();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_DIFF_PAIR_PLACER::gap() const
|
||||||
|
{
|
||||||
|
return m_sizes.DiffPairGap() + m_sizes.DiffPairWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||||
|
{
|
||||||
|
VECTOR2I p( aP );
|
||||||
|
|
||||||
|
bool split;
|
||||||
|
|
||||||
|
if( Router()->SnappingEnabled() )
|
||||||
|
p = Router()->SnapToItem( aStartItem, aP, split );
|
||||||
|
|
||||||
|
if( !aStartItem )
|
||||||
|
{
|
||||||
|
Router()->SetFailureReason( _( "Can't start a differential pair "
|
||||||
|
" in the middle of nowhere." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR start;
|
||||||
|
|
||||||
|
m_currentNode = Router()->GetWorld();
|
||||||
|
|
||||||
|
if( !findDpPrimitivePair( aP, aStartItem, m_start ) )
|
||||||
|
{
|
||||||
|
Router()->SetFailureReason( _( "Unable to find complementary differential pair "
|
||||||
|
"net. Make sure the names of the nets belonging "
|
||||||
|
"to a differential pair end with either _N/_P or +/-." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_netP = m_start.PrimP()->Net();
|
||||||
|
m_netN = m_start.PrimN()->Net();
|
||||||
|
|
||||||
|
m_currentStart = p;
|
||||||
|
m_currentEnd = p;
|
||||||
|
m_placingVia = false;
|
||||||
|
m_chainedPlacement = false;
|
||||||
|
|
||||||
|
initPlacement( false );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DIFF_PAIR_PLACER::initPlacement( bool aSplitSeg )
|
||||||
|
{
|
||||||
|
m_idle = false;
|
||||||
|
m_orthoMode = false;
|
||||||
|
m_currentEndItem = NULL;
|
||||||
|
m_startDiagonal = m_initialDiagonal;
|
||||||
|
|
||||||
|
PNS_NODE* world = Router()->GetWorld();
|
||||||
|
|
||||||
|
world->KillChildren();
|
||||||
|
PNS_NODE* rootNode = world->Branch();
|
||||||
|
|
||||||
|
setWorld( rootNode );
|
||||||
|
|
||||||
|
m_lastNode = NULL;
|
||||||
|
m_currentNode = rootNode;
|
||||||
|
m_currentMode = Settings().Mode();
|
||||||
|
|
||||||
|
if( m_shove )
|
||||||
|
delete m_shove;
|
||||||
|
|
||||||
|
m_shove = NULL;
|
||||||
|
|
||||||
|
if( m_currentMode == RM_Shove || m_currentMode == RM_Smart )
|
||||||
|
{
|
||||||
|
m_shove = new PNS_SHOVE( m_currentNode, Router() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
|
||||||
|
{
|
||||||
|
m_fitOk = false;
|
||||||
|
|
||||||
|
PNS_DP_GATEWAYS gwsEntry( gap() );
|
||||||
|
PNS_DP_GATEWAYS gwsTarget( gap() );
|
||||||
|
|
||||||
|
if( !m_prevPair )
|
||||||
|
m_prevPair = m_start;
|
||||||
|
|
||||||
|
gwsEntry.BuildFromPrimitivePair( *m_prevPair, m_startDiagonal );
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR target;
|
||||||
|
|
||||||
|
if( findDpPrimitivePair ( aP, m_currentEndItem, target ) )
|
||||||
|
{
|
||||||
|
gwsTarget.BuildFromPrimitivePair( target, m_startDiagonal );
|
||||||
|
m_snapOnTarget = true;
|
||||||
|
} else {
|
||||||
|
VECTOR2I fp;
|
||||||
|
|
||||||
|
if( !propagateDpHeadForces( aP, fp ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
gwsTarget.SetFitVias( m_placingVia, m_sizes.ViaDiameter(), viaGap() );
|
||||||
|
gwsTarget.BuildForCursor( fp );
|
||||||
|
gwsTarget.BuildOrthoProjections( gwsEntry, fp, m_orthoMode ? 200 : -200 );
|
||||||
|
m_snapOnTarget = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentTrace = PNS_DIFF_PAIR();
|
||||||
|
m_currentTrace.SetGap( gap() );
|
||||||
|
m_currentTrace.SetLayer( m_currentLayer );
|
||||||
|
|
||||||
|
if ( gwsEntry.FitGateways( gwsEntry, gwsTarget, m_startDiagonal, m_currentTrace ) )
|
||||||
|
{
|
||||||
|
m_currentTrace.SetNets( m_netP, m_netN );
|
||||||
|
m_currentTrace.SetWidth( m_sizes.DiffPairWidth() );
|
||||||
|
m_currentTrace.SetGap( m_sizes.DiffPairGap() );
|
||||||
|
|
||||||
|
if( m_placingVia )
|
||||||
|
{
|
||||||
|
m_currentTrace.AppendVias ( makeVia ( m_currentTrace.CP().CPoint(-1), m_netP ),
|
||||||
|
makeVia ( m_currentTrace.CN().CPoint(-1), m_netN ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::Move( const VECTOR2I& aP , PNS_ITEM* aEndItem )
|
||||||
|
{
|
||||||
|
m_currentEndItem = aEndItem;
|
||||||
|
m_fitOk = false;
|
||||||
|
|
||||||
|
delete m_lastNode;
|
||||||
|
m_lastNode = NULL;
|
||||||
|
|
||||||
|
if( !route( aP ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PNS_NODE* latestNode = m_currentNode;
|
||||||
|
m_lastNode = latestNode->Branch();
|
||||||
|
|
||||||
|
assert( m_lastNode != NULL );
|
||||||
|
m_currentEnd = aP;
|
||||||
|
|
||||||
|
updateLeadingRatLine();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DIFF_PAIR_PLACER::UpdateSizes( const PNS_SIZES_SETTINGS& aSizes )
|
||||||
|
{
|
||||||
|
m_sizes = aSizes;
|
||||||
|
|
||||||
|
if( !m_idle )
|
||||||
|
{
|
||||||
|
initPlacement();
|
||||||
|
Move( m_currentEnd, NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DIFF_PAIR_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||||
|
{
|
||||||
|
if( !m_fitOk )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( m_currentTrace.CP().SegmentCount() < 1 ||
|
||||||
|
m_currentTrace.CN().SegmentCount() < 1 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( m_currentTrace.CP().SegmentCount() > 1 )
|
||||||
|
m_initialDiagonal = !DIRECTION_45( m_currentTrace.CP().CSegment( -2 ) ).IsDiagonal();
|
||||||
|
|
||||||
|
PNS_TOPOLOGY topo( m_lastNode );
|
||||||
|
|
||||||
|
if( !m_snapOnTarget && !m_currentTrace.EndsWithVias() )
|
||||||
|
{
|
||||||
|
SHAPE_LINE_CHAIN newP ( m_currentTrace.CP() );
|
||||||
|
SHAPE_LINE_CHAIN newN ( m_currentTrace.CN() );
|
||||||
|
|
||||||
|
if( newP.SegmentCount() > 1 && newN.SegmentCount() > 1 )
|
||||||
|
{
|
||||||
|
newP.Remove( -1, -1 );
|
||||||
|
newN.Remove( -1, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentTrace.SetShape( newP, newN );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_currentTrace.EndsWithVias() )
|
||||||
|
{
|
||||||
|
m_lastNode->Add( m_currentTrace.PLine().Via().Clone() );
|
||||||
|
m_lastNode->Add( m_currentTrace.NLine().Via().Clone() );
|
||||||
|
m_chainedPlacement = false;
|
||||||
|
} else
|
||||||
|
m_chainedPlacement = !m_snapOnTarget;
|
||||||
|
|
||||||
|
PNS_LINE lineP( m_currentTrace.PLine() );
|
||||||
|
PNS_LINE lineN( m_currentTrace.NLine() );
|
||||||
|
|
||||||
|
m_lastNode->Add( &lineP );
|
||||||
|
m_lastNode->Add( &lineN );
|
||||||
|
|
||||||
|
topo.SimplifyLine( &lineP );
|
||||||
|
topo.SimplifyLine( &lineN );
|
||||||
|
|
||||||
|
m_prevPair = m_currentTrace.EndingPrimitives();
|
||||||
|
|
||||||
|
Router()->CommitRouting( m_lastNode );
|
||||||
|
|
||||||
|
m_lastNode = NULL;
|
||||||
|
m_placingVia = false;
|
||||||
|
|
||||||
|
if( m_snapOnTarget )
|
||||||
|
{
|
||||||
|
m_idle = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initPlacement();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DIFF_PAIR_PLACER::GetModifiedNets( std::vector<int> &aNets ) const
|
||||||
|
{
|
||||||
|
aNets.push_back( m_netP );
|
||||||
|
aNets.push_back( m_netN );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DIFF_PAIR_PLACER::updateLeadingRatLine()
|
||||||
|
{
|
||||||
|
SHAPE_LINE_CHAIN ratLineN, ratLineP;
|
||||||
|
PNS_TOPOLOGY topo( m_lastNode );
|
||||||
|
|
||||||
|
if( topo.LeadingRatLine( &m_currentTrace.PLine(), ratLineP ) )
|
||||||
|
{
|
||||||
|
Router()->DisplayDebugLine( ratLineP, 1, 10000 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( topo.LeadingRatLine ( &m_currentTrace.NLine(), ratLineN ) )
|
||||||
|
{
|
||||||
|
Router()->DisplayDebugLine( ratLineN, 3, 10000 );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,302 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2014 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PNS_DIFF_PLACER_H
|
||||||
|
#define __PNS_DIFF_PLACER_H
|
||||||
|
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
|
||||||
|
#include <geometry/shape.h>
|
||||||
|
#include <geometry/shape_line_chain.h>
|
||||||
|
|
||||||
|
#include "pns_sizes_settings.h"
|
||||||
|
#include "pns_node.h"
|
||||||
|
#include "pns_via.h"
|
||||||
|
#include "pns_line.h"
|
||||||
|
#include "pns_algo_base.h"
|
||||||
|
#include "pns_diff_pair.h"
|
||||||
|
|
||||||
|
#include "pns_placement_algo.h"
|
||||||
|
|
||||||
|
class PNS_ROUTER;
|
||||||
|
class PNS_SHOVE;
|
||||||
|
class PNS_OPTIMIZER;
|
||||||
|
class PNS_ROUTER_BASE;
|
||||||
|
class PNS_VIA;
|
||||||
|
class PNS_SIZES_SETTINGS;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_LINE_PLACER
|
||||||
|
*
|
||||||
|
* Single track placement algorithm. Interactively routes a track.
|
||||||
|
* Applies shove and walkaround algorithms when needed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PNS_DIFF_PAIR_PLACER : public PNS_PLACEMENT_ALGO
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PNS_DIFF_PAIR_PLACER( PNS_ROUTER* aRouter );
|
||||||
|
~PNS_DIFF_PAIR_PLACER();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Start()
|
||||||
|
*
|
||||||
|
* Starts routing a single track at point aP, taking item aStartItem as anchor
|
||||||
|
* (unless NULL).
|
||||||
|
*/
|
||||||
|
bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Move()
|
||||||
|
*
|
||||||
|
* Moves the end of the currently routed trace to the point aP, taking
|
||||||
|
* aEndItem as anchor (if not NULL).
|
||||||
|
* (unless NULL).
|
||||||
|
*/
|
||||||
|
bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function FixRoute()
|
||||||
|
*
|
||||||
|
* Commits the currently routed track to the parent node, taking
|
||||||
|
* aP as the final end point and aEndItem as the final anchor (if provided).
|
||||||
|
* @return true, if route has been commited. May return false if the routing
|
||||||
|
* result is violating design rules - in such case, the track is only committed
|
||||||
|
* if Settings.CanViolateDRC() is on.
|
||||||
|
*/
|
||||||
|
bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function ToggleVia()
|
||||||
|
*
|
||||||
|
* Enables/disables a via at the end of currently routed trace.
|
||||||
|
*/
|
||||||
|
bool ToggleVia( bool aEnabled );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetLayer()
|
||||||
|
*
|
||||||
|
* Sets the current routing layer.
|
||||||
|
*/
|
||||||
|
bool SetLayer( int aLayer );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Traces()
|
||||||
|
*
|
||||||
|
* Returns the complete routed line, as a single-member PNS_ITEMSET.
|
||||||
|
*/
|
||||||
|
const PNS_ITEMSET Traces();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurrentEnd()
|
||||||
|
*
|
||||||
|
* Returns the current end of the line being placed. It may not be equal
|
||||||
|
* to the cursor position due to collisions.
|
||||||
|
*/
|
||||||
|
const VECTOR2I& CurrentEnd() const
|
||||||
|
{
|
||||||
|
return m_currentEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurrentNet()
|
||||||
|
*
|
||||||
|
* Returns the net code of currently routed track.
|
||||||
|
*/
|
||||||
|
int CurrentNet() const
|
||||||
|
{
|
||||||
|
return m_currentNet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurrentLayer()
|
||||||
|
*
|
||||||
|
* Returns the layer of currently routed track.
|
||||||
|
*/
|
||||||
|
int CurrentLayer() const
|
||||||
|
{
|
||||||
|
return m_currentLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurrentNode()
|
||||||
|
*
|
||||||
|
* Returns the most recent world state.
|
||||||
|
*/
|
||||||
|
PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function FlipPosture()
|
||||||
|
*
|
||||||
|
* Toggles the current posture (straight/diagonal) of the trace head.
|
||||||
|
*/
|
||||||
|
void FlipPosture();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function UpdateSizes()
|
||||||
|
*
|
||||||
|
* Performs on-the-fly update of the width, via diameter & drill size from
|
||||||
|
* a settings class. Used to dynamically change these parameters as
|
||||||
|
* the track is routed.
|
||||||
|
*/
|
||||||
|
void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes );
|
||||||
|
|
||||||
|
bool IsPlacingVia() const { return m_placingVia; }
|
||||||
|
|
||||||
|
void SetOrthoMode( bool aOrthoMode );
|
||||||
|
|
||||||
|
void GetModifiedNets( std::vector<int>& aNets ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int viaGap() const;
|
||||||
|
int gap() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function route()
|
||||||
|
*
|
||||||
|
* Re-routes the current track to point aP. Returns true, when routing has
|
||||||
|
* completed successfully (i.e. the trace end has reached point aP), and false
|
||||||
|
* if the trace was stuck somewhere on the way. May call routeStep()
|
||||||
|
* repetitively due to mouse smoothing.
|
||||||
|
* @param aP ending point of current route.
|
||||||
|
* @return true, if the routing is complete.
|
||||||
|
*/
|
||||||
|
bool route( const VECTOR2I& aP );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function updateLeadingRatLine()
|
||||||
|
*
|
||||||
|
* Draws the "leading" ratsnest line, which connects the end of currently
|
||||||
|
* routed track and the nearest yet unrouted item. If the routing for
|
||||||
|
* current net is complete, draws nothing.
|
||||||
|
*/
|
||||||
|
void updateLeadingRatLine();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function setWorld()
|
||||||
|
*
|
||||||
|
* Sets the board to route.
|
||||||
|
*/
|
||||||
|
void setWorld( PNS_NODE* aWorld );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function startPlacement()
|
||||||
|
*
|
||||||
|
* Initializes placement of a new line with given parameters.
|
||||||
|
*/
|
||||||
|
void initPlacement( bool aSplitSeg = false );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function setInitialDirection()
|
||||||
|
*
|
||||||
|
* Sets preferred direction of the very first track segment to be laid.
|
||||||
|
* Used by posture switching mechanism.
|
||||||
|
*/
|
||||||
|
void setInitialDirection( const DIRECTION_45& aDirection );
|
||||||
|
|
||||||
|
|
||||||
|
bool routeHead( const VECTOR2I& aP );
|
||||||
|
bool tryWalkDp( PNS_NODE* aNode, PNS_DIFF_PAIR& aPair, bool aSolidsOnly );
|
||||||
|
|
||||||
|
///> route step, walkaround mode
|
||||||
|
bool rhWalkOnly( const VECTOR2I& aP );
|
||||||
|
|
||||||
|
///> route step, shove mode
|
||||||
|
bool rhShoveOnly ( const VECTOR2I& aP );
|
||||||
|
|
||||||
|
///> route step, mark obstacles mode
|
||||||
|
bool rhMarkObstacles( const VECTOR2I& aP );
|
||||||
|
|
||||||
|
const PNS_VIA makeVia ( const VECTOR2I& aP, int aNet );
|
||||||
|
|
||||||
|
bool findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aItem, PNS_DP_PRIMITIVE_PAIR& aPair );
|
||||||
|
OPT_VECTOR2I getDanglingAnchor( PNS_NODE* aNode, PNS_ITEM* aItem );
|
||||||
|
int matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName );
|
||||||
|
bool attemptWalk( PNS_NODE* aNode, PNS_DIFF_PAIR* aCurrent, PNS_DIFF_PAIR& aWalk, bool aPFirst, bool aWindCw, bool aSolidsOnly );
|
||||||
|
bool propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNewP );
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
RT_START = 0,
|
||||||
|
RT_ROUTE = 1,
|
||||||
|
RT_FINISH = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
State m_state;
|
||||||
|
|
||||||
|
bool m_chainedPlacement;
|
||||||
|
bool m_initialDiagonal;
|
||||||
|
bool m_startDiagonal;
|
||||||
|
bool m_fitOk;
|
||||||
|
|
||||||
|
int m_netP, m_netN;
|
||||||
|
|
||||||
|
PNS_DP_PRIMITIVE_PAIR m_start;
|
||||||
|
boost::optional<PNS_DP_PRIMITIVE_PAIR> m_prevPair;
|
||||||
|
|
||||||
|
///> current algorithm iteration
|
||||||
|
int m_iteration;
|
||||||
|
|
||||||
|
///> pointer to world to search colliding items
|
||||||
|
PNS_NODE* m_world;
|
||||||
|
|
||||||
|
///> current routing start point (end of tail, beginning of head)
|
||||||
|
VECTOR2I m_p_start;
|
||||||
|
|
||||||
|
///> The shove engine
|
||||||
|
PNS_SHOVE* m_shove;
|
||||||
|
|
||||||
|
///> Current world state
|
||||||
|
PNS_NODE* m_currentNode;
|
||||||
|
|
||||||
|
///> Postprocessed world state (including marked collisions & removed loops)
|
||||||
|
PNS_NODE* m_lastNode;
|
||||||
|
|
||||||
|
PNS_SIZES_SETTINGS m_sizes;
|
||||||
|
|
||||||
|
///> Are we placing a via?
|
||||||
|
bool m_placingVia;
|
||||||
|
|
||||||
|
///> current via diameter
|
||||||
|
int m_viaDiameter;
|
||||||
|
|
||||||
|
///> current via drill
|
||||||
|
int m_viaDrill;
|
||||||
|
|
||||||
|
///> current track width
|
||||||
|
int m_currentWidth;
|
||||||
|
|
||||||
|
int m_currentNet;
|
||||||
|
int m_currentLayer;
|
||||||
|
|
||||||
|
bool m_startsOnVia;
|
||||||
|
bool m_orthoMode;
|
||||||
|
bool m_snapOnTarget;
|
||||||
|
|
||||||
|
VECTOR2I m_currentEnd, m_currentStart;
|
||||||
|
PNS_DIFF_PAIR m_currentTrace;
|
||||||
|
|
||||||
|
PNS_ITEM* m_currentEndItem;
|
||||||
|
PNS_MODE m_currentMode;
|
||||||
|
|
||||||
|
bool m_idle;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __PNS_LINE_PLACER_H
|
|
@ -0,0 +1,459 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2014 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#include <base_units.h> // God forgive me doing this...
|
||||||
|
#include <colors.h>
|
||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#include "pns_node.h"
|
||||||
|
#include "pns_itemset.h"
|
||||||
|
#include "pns_topology.h"
|
||||||
|
#include "pns_dp_meander_placer.h"
|
||||||
|
#include "pns_diff_pair.h"
|
||||||
|
#include "pns_router.h"
|
||||||
|
#include "pns_utils.h"
|
||||||
|
|
||||||
|
using boost::optional;
|
||||||
|
|
||||||
|
PNS_DP_MEANDER_PLACER::PNS_DP_MEANDER_PLACER( PNS_ROUTER* aRouter ) :
|
||||||
|
PNS_MEANDER_PLACER_BASE( aRouter )
|
||||||
|
{
|
||||||
|
m_world = NULL;
|
||||||
|
m_currentNode = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_DP_MEANDER_PLACER::~PNS_DP_MEANDER_PLACER()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const PNS_LINE PNS_DP_MEANDER_PLACER::Trace() const
|
||||||
|
{
|
||||||
|
return m_currentTraceP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_NODE* PNS_DP_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const
|
||||||
|
{
|
||||||
|
if( !m_currentNode )
|
||||||
|
return m_world;
|
||||||
|
|
||||||
|
return m_currentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DP_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||||
|
{
|
||||||
|
VECTOR2I p;
|
||||||
|
|
||||||
|
if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) )
|
||||||
|
{
|
||||||
|
Router()->SetFailureReason( _( "Please select a track whose length you want to tune." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_initialSegment = static_cast<PNS_SEGMENT*>( aStartItem );
|
||||||
|
|
||||||
|
p = m_initialSegment->Seg().NearestPoint( aP );
|
||||||
|
|
||||||
|
m_currentNode=NULL;
|
||||||
|
m_currentStart = p;
|
||||||
|
|
||||||
|
m_world = Router()->GetWorld()->Branch();
|
||||||
|
|
||||||
|
PNS_TOPOLOGY topo( m_world );
|
||||||
|
|
||||||
|
if( !topo.AssembleDiffPair( m_initialSegment, m_originPair ) )
|
||||||
|
{
|
||||||
|
Router()->SetFailureReason( _( "Unable to find complementary differential pair "
|
||||||
|
"net for length tuning. Make sure the names of the nets belonging "
|
||||||
|
"to a differential pair end with either _N/_P or +/-." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_originPair.SetGap( Router()->Sizes().DiffPairGap() );
|
||||||
|
|
||||||
|
if( !m_originPair.PLine().SegmentCount() ||
|
||||||
|
!m_originPair.NLine().SegmentCount() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_tunedPathP = topo.AssembleTrivialPath( m_originPair.PLine().GetLink( 0 ) );
|
||||||
|
m_tunedPathN = topo.AssembleTrivialPath( m_originPair.NLine().GetLink( 0 ) );
|
||||||
|
|
||||||
|
m_world->Remove( m_originPair.PLine() );
|
||||||
|
m_world->Remove( m_originPair.NLine() );
|
||||||
|
|
||||||
|
m_currentWidth = m_originPair.Width();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DP_MEANDER_PLACER::release()
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
BOOST_FOREACH(PNS_MEANDER *m, m_meanders)
|
||||||
|
{
|
||||||
|
delete m;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_meanders.clear();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_DP_MEANDER_PLACER::origPathLength() const
|
||||||
|
{
|
||||||
|
int totalP = 0;
|
||||||
|
int totalN = 0;
|
||||||
|
|
||||||
|
BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathP.CItems() )
|
||||||
|
{
|
||||||
|
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||||
|
totalP += l->CLine().Length();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathN.CItems() )
|
||||||
|
{
|
||||||
|
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||||
|
totalN += l->CLine().Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::max( totalP, totalN );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const SEG PNS_DP_MEANDER_PLACER::baselineSegment( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aCoupledSegs )
|
||||||
|
{
|
||||||
|
const VECTOR2I a( ( aCoupledSegs.coupledP.A + aCoupledSegs.coupledN.A ) / 2 );
|
||||||
|
const VECTOR2I b( ( aCoupledSegs.coupledP.B + aCoupledSegs.coupledN.B ) / 2 );
|
||||||
|
|
||||||
|
return SEG( a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
PNS_MEANDER_PLACER_BASE::TUNING_STATUS PNS_DP_MEANDER_PLACER::tuneLineLength ( PNS_MEANDERED_LINE& aTuned, int aElongation )
|
||||||
|
{
|
||||||
|
int remaining = aElongation;
|
||||||
|
bool finished = false;
|
||||||
|
|
||||||
|
BOOST_FOREACH(PNS_MEANDER_SHAPE *m, aTuned.Meanders())
|
||||||
|
{
|
||||||
|
|
||||||
|
if(m->Type() != MT_CORNER )
|
||||||
|
{
|
||||||
|
|
||||||
|
if(remaining >= 0)
|
||||||
|
remaining -= m->MaxTunableLength() - m->BaselineLength();
|
||||||
|
|
||||||
|
if(remaining < 0)
|
||||||
|
{
|
||||||
|
if(!finished)
|
||||||
|
{
|
||||||
|
PNS_MEANDER_TYPE newType;
|
||||||
|
|
||||||
|
if ( m->Type() == MT_START || m->Type() == MT_SINGLE)
|
||||||
|
newType = MT_SINGLE;
|
||||||
|
else
|
||||||
|
newType = MT_FINISH;
|
||||||
|
|
||||||
|
m->SetType ( newType );
|
||||||
|
m->Recalculate( );
|
||||||
|
|
||||||
|
finished = true;
|
||||||
|
} else {
|
||||||
|
m->MakeEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining = aElongation;
|
||||||
|
int meanderCount = 0;
|
||||||
|
|
||||||
|
BOOST_FOREACH(PNS_MEANDER_SHAPE *m, aTuned.Meanders())
|
||||||
|
{
|
||||||
|
if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY )
|
||||||
|
{
|
||||||
|
if(remaining >= 0)
|
||||||
|
{
|
||||||
|
remaining -= m->MaxTunableLength() - m->BaselineLength();
|
||||||
|
meanderCount ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int balance = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if( meanderCount )
|
||||||
|
balance = -remaining / meanderCount;
|
||||||
|
|
||||||
|
if (balance >= 0)
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(PNS_MEANDER_SHAPE *m, aTuned.Meanders())
|
||||||
|
{
|
||||||
|
if(m->Type() != MT_CORNER && m->Type() != MT_EMPTY)
|
||||||
|
{
|
||||||
|
// int pre = m->MaxTunableLength();
|
||||||
|
m->Resize ( std::max( m->Amplitude() - balance / 2, m_settings.m_minAmplitude ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return TUNED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool pairOrientation( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aPair )
|
||||||
|
{
|
||||||
|
VECTOR2I midp = ( aPair.coupledP.A + aPair.coupledN.A ) / 2;
|
||||||
|
|
||||||
|
//DrawDebugPoint (midp, 6);
|
||||||
|
|
||||||
|
return aPair.coupledP.Side( midp ) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DP_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||||
|
{
|
||||||
|
// return false;
|
||||||
|
|
||||||
|
if( m_currentNode )
|
||||||
|
delete m_currentNode;
|
||||||
|
|
||||||
|
m_currentNode = m_world->Branch();
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN preP, tunedP, postP;
|
||||||
|
SHAPE_LINE_CHAIN preN, tunedN, postN;
|
||||||
|
|
||||||
|
cutTunedLine( m_originPair.CP(), m_currentStart, aP, preP, tunedP, postP );
|
||||||
|
cutTunedLine( m_originPair.CN(), m_currentStart, aP, preN, tunedN, postN );
|
||||||
|
|
||||||
|
PNS_DIFF_PAIR tuned ( m_originPair );
|
||||||
|
|
||||||
|
tuned.SetShape( tunedP, tunedN );
|
||||||
|
|
||||||
|
m_coupledSegments.clear();
|
||||||
|
|
||||||
|
tuned.CoupledSegmentPairs( m_coupledSegments );
|
||||||
|
|
||||||
|
if( m_coupledSegments.size() == 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//Router()->DisplayDebugLine ( tuned.CP(), 5, 20000 );
|
||||||
|
//Router()->DisplayDebugLine ( tuned.CN(), 4, 20000 );
|
||||||
|
|
||||||
|
//Router()->DisplayDebugLine ( m_originPair.CP(), 5, 20000 );
|
||||||
|
//Router()->DisplayDebugLine ( m_originPair.CN(), 4, 20000 );
|
||||||
|
|
||||||
|
m_result = PNS_MEANDERED_LINE( this, true );
|
||||||
|
m_result.SetWidth( tuned.Width() );
|
||||||
|
|
||||||
|
int offset = ( tuned.Gap() + tuned.Width() ) / 2;
|
||||||
|
|
||||||
|
if( !pairOrientation( m_coupledSegments[0] ) )
|
||||||
|
offset *= -1;
|
||||||
|
|
||||||
|
m_result.SetBaselineOffset( offset );
|
||||||
|
|
||||||
|
BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathP.CItems() )
|
||||||
|
{
|
||||||
|
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||||
|
Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathN.CItems() )
|
||||||
|
{
|
||||||
|
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||||
|
Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& sp, m_coupledSegments )
|
||||||
|
{
|
||||||
|
SEG base = baselineSegment( sp );
|
||||||
|
|
||||||
|
// DrawDebugSeg ( base, 3 );
|
||||||
|
|
||||||
|
m_result.AddCorner( sp.parentP.A, sp.parentN.A );
|
||||||
|
m_result.MeanderSegment( base );
|
||||||
|
m_result.AddCorner( sp.parentP.B, sp.parentN.B );
|
||||||
|
}
|
||||||
|
|
||||||
|
int dpLen = origPathLength();
|
||||||
|
|
||||||
|
m_lastStatus = TUNED;
|
||||||
|
|
||||||
|
if( dpLen - m_settings.m_targetLength > m_settings.m_lengthTolerance )
|
||||||
|
{
|
||||||
|
m_lastStatus = TOO_LONG;
|
||||||
|
m_lastLength = dpLen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_lastLength = dpLen - std::max( tunedP.Length(), tunedN.Length() );
|
||||||
|
tuneLineLength( m_result, m_settings.m_targetLength - dpLen );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_lastStatus != TOO_LONG )
|
||||||
|
{
|
||||||
|
tunedP.Clear();
|
||||||
|
tunedN.Clear();
|
||||||
|
|
||||||
|
BOOST_FOREACH( PNS_MEANDER_SHAPE* m, m_result.Meanders() )
|
||||||
|
{
|
||||||
|
if( m->Type() != MT_EMPTY )
|
||||||
|
{
|
||||||
|
tunedP.Append ( m->CLine( 0 ) );
|
||||||
|
tunedN.Append ( m->CLine( 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lastLength += std::max( tunedP.Length(), tunedN.Length() );
|
||||||
|
|
||||||
|
int comp = compareWithTolerance( m_lastLength - m_settings.m_targetLength, 0, m_settings.m_lengthTolerance );
|
||||||
|
|
||||||
|
if( comp > 0 )
|
||||||
|
m_lastStatus = TOO_LONG;
|
||||||
|
else if( comp < 0 )
|
||||||
|
m_lastStatus = TOO_SHORT;
|
||||||
|
else
|
||||||
|
m_lastStatus = TUNED;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_finalShapeP.Clear();
|
||||||
|
m_finalShapeP.Append( preP );
|
||||||
|
m_finalShapeP.Append( tunedP );
|
||||||
|
m_finalShapeP.Append( postP );
|
||||||
|
m_finalShapeP.Simplify();
|
||||||
|
|
||||||
|
m_finalShapeN.Clear();
|
||||||
|
m_finalShapeN.Append( preN );
|
||||||
|
m_finalShapeN.Append( tunedN );
|
||||||
|
m_finalShapeN.Append( postN );
|
||||||
|
m_finalShapeN.Simplify();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DP_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||||
|
{
|
||||||
|
PNS_LINE lP( m_originPair.PLine(), m_finalShapeP );
|
||||||
|
PNS_LINE lN( m_originPair.NLine(), m_finalShapeN );
|
||||||
|
|
||||||
|
m_currentNode->Add( &lP );
|
||||||
|
m_currentNode->Add( &lN );
|
||||||
|
|
||||||
|
Router()->CommitRouting( m_currentNode );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_DP_MEANDER_PLACER::CheckFit( PNS_MEANDER_SHAPE* aShape )
|
||||||
|
{
|
||||||
|
PNS_LINE l1( m_originPair.PLine(), aShape->CLine( 0 ) );
|
||||||
|
PNS_LINE l2( m_originPair.NLine(), aShape->CLine( 1 ) );
|
||||||
|
|
||||||
|
if( m_currentNode->CheckColliding( &l1 ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( m_currentNode->CheckColliding( &l2 ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int w = aShape->Width();
|
||||||
|
int clearance = w + m_settings.m_spacing;
|
||||||
|
|
||||||
|
return m_result.CheckSelfIntersections( aShape, clearance );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const PNS_ITEMSET PNS_DP_MEANDER_PLACER::Traces()
|
||||||
|
{
|
||||||
|
m_currentTraceP = PNS_LINE( m_originPair.PLine(), m_finalShapeP );
|
||||||
|
m_currentTraceN = PNS_LINE( m_originPair.NLine(), m_finalShapeN );
|
||||||
|
|
||||||
|
PNS_ITEMSET traces;
|
||||||
|
|
||||||
|
traces.Add( &m_currentTraceP );
|
||||||
|
traces.Add( &m_currentTraceN );
|
||||||
|
|
||||||
|
return traces;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const VECTOR2I& PNS_DP_MEANDER_PLACER::CurrentEnd() const
|
||||||
|
{
|
||||||
|
return m_currentEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_DP_MEANDER_PLACER::CurrentNet() const
|
||||||
|
{
|
||||||
|
return m_initialSegment->Net();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_DP_MEANDER_PLACER::CurrentLayer() const
|
||||||
|
{
|
||||||
|
return m_initialSegment->Layers().Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const wxString PNS_DP_MEANDER_PLACER::TuningInfo() const
|
||||||
|
{
|
||||||
|
wxString status;
|
||||||
|
|
||||||
|
switch( m_lastStatus )
|
||||||
|
{
|
||||||
|
case TOO_LONG:
|
||||||
|
status = _( "Too long: " );
|
||||||
|
break;
|
||||||
|
case TOO_SHORT:
|
||||||
|
status = _("Too short: " );
|
||||||
|
break;
|
||||||
|
case TUNED:
|
||||||
|
status = _( "Tuned: " );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return _( "?" );
|
||||||
|
}
|
||||||
|
|
||||||
|
status += LengthDoubleToString( (double) m_lastLength, false );
|
||||||
|
status += "/";
|
||||||
|
status += LengthDoubleToString( (double) m_settings.m_targetLength, false );
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_DP_MEANDER_PLACER::TUNING_STATUS PNS_DP_MEANDER_PLACER::TuningStatus() const
|
||||||
|
{
|
||||||
|
return m_lastStatus;
|
||||||
|
}
|
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2014 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PNS_DP_MEANDER_PLACER_H
|
||||||
|
#define __PNS_DP_MEANDER_PLACER_H
|
||||||
|
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
|
||||||
|
#include <geometry/shape.h>
|
||||||
|
#include <geometry/shape_line_chain.h>
|
||||||
|
|
||||||
|
#include "pns_node.h"
|
||||||
|
#include "pns_via.h"
|
||||||
|
#include "pns_line.h"
|
||||||
|
#include "pns_placement_algo.h"
|
||||||
|
#include "pns_meander.h"
|
||||||
|
#include "pns_meander_placer_base.h"
|
||||||
|
#include "pns_diff_pair.h"
|
||||||
|
|
||||||
|
class PNS_ROUTER;
|
||||||
|
class PNS_SHOVE;
|
||||||
|
class PNS_OPTIMIZER;
|
||||||
|
class PNS_ROUTER_BASE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_DP_MEANDER_PLACER
|
||||||
|
*
|
||||||
|
* Differential Pair length-matching/meandering tool.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PNS_DP_MEANDER_PLACER : public PNS_MEANDER_PLACER_BASE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PNS_DP_MEANDER_PLACER( PNS_ROUTER* aRouter );
|
||||||
|
~PNS_DP_MEANDER_PLACER();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Start()
|
||||||
|
*
|
||||||
|
* Starts routing a single track at point aP, taking item aStartItem as anchor
|
||||||
|
* (unless NULL).
|
||||||
|
*/
|
||||||
|
bool Start ( const VECTOR2I& aP, PNS_ITEM* aStartItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Move()
|
||||||
|
*
|
||||||
|
* Moves the end of the currently routed trace to the point aP, taking
|
||||||
|
* aEndItem as anchor (if not NULL).
|
||||||
|
* (unless NULL).
|
||||||
|
*/
|
||||||
|
bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function FixRoute()
|
||||||
|
*
|
||||||
|
* Commits the currently routed track to the parent node, taking
|
||||||
|
* aP as the final end point and aEndItem as the final anchor (if provided).
|
||||||
|
* @return true, if route has been commited. May return false if the routing
|
||||||
|
* result is violating design rules - in such case, the track is only committed
|
||||||
|
* if Settings.CanViolateDRC() is on.
|
||||||
|
*/
|
||||||
|
bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem );
|
||||||
|
|
||||||
|
const PNS_LINE Trace() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurrentNode()
|
||||||
|
*
|
||||||
|
* Returns the most recent world state.
|
||||||
|
*/
|
||||||
|
PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const;
|
||||||
|
|
||||||
|
const PNS_ITEMSET Traces();
|
||||||
|
|
||||||
|
const VECTOR2I& CurrentEnd() const;
|
||||||
|
|
||||||
|
int CurrentNet() const;
|
||||||
|
int CurrentLayer() const;
|
||||||
|
|
||||||
|
int totalLength();
|
||||||
|
|
||||||
|
const wxString TuningInfo() const;
|
||||||
|
TUNING_STATUS TuningStatus() const;
|
||||||
|
|
||||||
|
bool CheckFit( PNS_MEANDER_SHAPE* aShape );
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class PNS_MEANDER_SHAPE;
|
||||||
|
|
||||||
|
void meanderSegment ( const SEG& aBase );
|
||||||
|
|
||||||
|
// void addMeander ( PNS_MEANDER *aM );
|
||||||
|
// void addCorner ( const VECTOR2I& aP );
|
||||||
|
|
||||||
|
const SEG baselineSegment( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aCoupledSegs );
|
||||||
|
|
||||||
|
void setWorld( PNS_NODE* aWorld );
|
||||||
|
void release();
|
||||||
|
|
||||||
|
int origPathLength() const;
|
||||||
|
|
||||||
|
///> pointer to world to search colliding items
|
||||||
|
PNS_NODE* m_world;
|
||||||
|
|
||||||
|
///> current routing start point (end of tail, beginning of head)
|
||||||
|
VECTOR2I m_currentStart;
|
||||||
|
|
||||||
|
///> Current world state
|
||||||
|
PNS_NODE* m_currentNode;
|
||||||
|
|
||||||
|
PNS_DIFF_PAIR m_originPair;
|
||||||
|
PNS_DIFF_PAIR::COUPLED_SEGMENTS_VEC m_coupledSegments;
|
||||||
|
|
||||||
|
PNS_LINE m_currentTraceN, m_currentTraceP;
|
||||||
|
PNS_ITEMSET m_tunedPath, m_tunedPathP, m_tunedPathN;
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN m_finalShapeP, m_finalShapeN;
|
||||||
|
PNS_MEANDERED_LINE m_result;
|
||||||
|
PNS_SEGMENT* m_initialSegment;
|
||||||
|
|
||||||
|
int m_lastLength;
|
||||||
|
TUNING_STATUS m_lastStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __PNS_DP_MEANDER_PLACER_H
|
|
@ -96,7 +96,7 @@ public:
|
||||||
virtual PNS_LOGGER* Logger();
|
virtual PNS_LOGGER* Logger();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::pair<PNS_LINE *, PNS_LINE *> LinePair;
|
typedef std::pair<PNS_LINE*, PNS_LINE*> LinePair;
|
||||||
typedef std::vector<LinePair> LinePairVec;
|
typedef std::vector<LinePair> LinePairVec;
|
||||||
|
|
||||||
enum DragMode {
|
enum DragMode {
|
||||||
|
|
|
@ -160,7 +160,6 @@ PNS_INDEX::PNS_INDEX()
|
||||||
memset( m_subIndices, 0, sizeof( m_subIndices ) );
|
memset( m_subIndices, 0, sizeof( m_subIndices ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_INDEX::ITEM_SHAPE_INDEX* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
|
PNS_INDEX::ITEM_SHAPE_INDEX* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
|
||||||
{
|
{
|
||||||
int idx_n = -1;
|
int idx_n = -1;
|
||||||
|
@ -201,7 +200,6 @@ PNS_INDEX::ITEM_SHAPE_INDEX* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
|
||||||
return m_subIndices[idx_n];
|
return m_subIndices[idx_n];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_INDEX::Add( PNS_ITEM* aItem )
|
void PNS_INDEX::Add( PNS_ITEM* aItem )
|
||||||
{
|
{
|
||||||
ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
|
ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
|
||||||
|
@ -216,7 +214,6 @@ void PNS_INDEX::Add( PNS_ITEM* aItem )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_INDEX::Remove( PNS_ITEM* aItem )
|
void PNS_INDEX::Remove( PNS_ITEM* aItem )
|
||||||
{
|
{
|
||||||
ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
|
ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
|
||||||
|
@ -230,14 +227,12 @@ void PNS_INDEX::Remove( PNS_ITEM* aItem )
|
||||||
m_netMap[net].remove( aItem );
|
m_netMap[net].remove( aItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem )
|
void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem )
|
||||||
{
|
{
|
||||||
Remove( aOldItem );
|
Remove( aOldItem );
|
||||||
Add( aNewItem );
|
Add( aNewItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Visitor>
|
template<class Visitor>
|
||||||
int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& aVisitor )
|
int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& aVisitor )
|
||||||
{
|
{
|
||||||
|
@ -247,7 +242,6 @@ int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Vi
|
||||||
return m_subIndices[index]->Query( aShape, aMinDistance, aVisitor, false );
|
return m_subIndices[index]->Query( aShape, aMinDistance, aVisitor, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Visitor>
|
template<class Visitor>
|
||||||
int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& aVisitor )
|
int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& aVisitor )
|
||||||
{
|
{
|
||||||
|
@ -281,7 +275,6 @@ int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& aVisitor
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Visitor>
|
template<class Visitor>
|
||||||
int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& aVisitor )
|
int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& aVisitor )
|
||||||
{
|
{
|
||||||
|
@ -293,7 +286,6 @@ int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& aVisitor )
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_INDEX::Clear()
|
void PNS_INDEX::Clear()
|
||||||
{
|
{
|
||||||
for( int i = 0; i < MaxSubIndices; ++i )
|
for( int i = 0; i < MaxSubIndices; ++i )
|
||||||
|
@ -307,13 +299,11 @@ void PNS_INDEX::Clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_INDEX::~PNS_INDEX()
|
PNS_INDEX::~PNS_INDEX()
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_INDEX::NET_ITEMS_LIST* PNS_INDEX::GetItemsForNet( int aNet )
|
PNS_INDEX::NET_ITEMS_LIST* PNS_INDEX::GetItemsForNet( int aNet )
|
||||||
{
|
{
|
||||||
if( m_netMap.find( aNet ) == m_netMap.end() )
|
if( m_netMap.find( aNet ) == m_netMap.end() )
|
||||||
|
|
|
@ -36,7 +36,8 @@ class PNS_NODE;
|
||||||
enum LineMarker {
|
enum LineMarker {
|
||||||
MK_HEAD = ( 1 << 0 ),
|
MK_HEAD = ( 1 << 0 ),
|
||||||
MK_VIOLATION = ( 1 << 3 ),
|
MK_VIOLATION = ( 1 << 3 ),
|
||||||
MK_LOCKED = ( 1 << 4 )
|
MK_LOCKED = ( 1 << 4 ),
|
||||||
|
MK_DP_COUPLED = ( 1 << 5 )
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,6 +59,7 @@ public:
|
||||||
JOINT = 4,
|
JOINT = 4,
|
||||||
SEGMENT = 8,
|
SEGMENT = 8,
|
||||||
VIA = 16,
|
VIA = 16,
|
||||||
|
DIFF_PAIR = 32,
|
||||||
ANY = 0xff
|
ANY = 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,24 @@
|
||||||
|
|
||||||
#include "pns_itemset.h"
|
#include "pns_itemset.h"
|
||||||
|
|
||||||
PNS_ITEMSET::PNS_ITEMSET( PNS_ITEM* aInitialItem )
|
PNS_ITEMSET::PNS_ITEMSET( PNS_ITEM* aInitialItem ) :
|
||||||
|
m_owner( false )
|
||||||
{
|
{
|
||||||
if( aInitialItem )
|
if( aInitialItem )
|
||||||
m_items.push_back( aInitialItem );
|
m_items.push_back( aInitialItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_ITEMSET::~PNS_ITEMSET()
|
||||||
|
{
|
||||||
|
if( m_owner )
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert )
|
PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert )
|
||||||
{
|
{
|
||||||
ITEMS newItems;
|
ITEMS newItems;
|
||||||
|
@ -65,6 +77,22 @@ PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask, bool aInvert )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_ITEMSET& PNS_ITEMSET::FilterMarker( int aMarker, bool aInvert )
|
||||||
|
{
|
||||||
|
ITEMS newItems;
|
||||||
|
|
||||||
|
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||||
|
{
|
||||||
|
if( item->Marker() & aMarker )
|
||||||
|
newItems.push_back( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_items = newItems;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet, bool aInvert )
|
PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet, bool aInvert )
|
||||||
{
|
{
|
||||||
ITEMS newItems;
|
ITEMS newItems;
|
||||||
|
@ -80,6 +108,7 @@ PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet, bool aInvert )
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_ITEMSET& PNS_ITEMSET::ExcludeItem( const PNS_ITEM* aItem )
|
PNS_ITEMSET& PNS_ITEMSET::ExcludeItem( const PNS_ITEM* aItem )
|
||||||
{
|
{
|
||||||
ITEMS newItems;
|
ITEMS newItems;
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#ifndef __PNS_ITEMSET_H
|
#ifndef __PNS_ITEMSET_H
|
||||||
#define __PNS_ITEMSET_H
|
#define __PNS_ITEMSET_H
|
||||||
|
|
||||||
#include <vector>
|
#include <deque>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
#include "pns_item.h"
|
#include "pns_item.h"
|
||||||
|
@ -36,15 +36,23 @@
|
||||||
class PNS_ITEMSET
|
class PNS_ITEMSET
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::vector<PNS_ITEM*> ITEMS;
|
typedef std::deque<PNS_ITEM*> ITEMS;
|
||||||
|
|
||||||
PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL );
|
PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL );
|
||||||
|
|
||||||
PNS_ITEMSET( const PNS_ITEMSET& aOther )
|
PNS_ITEMSET( const PNS_ITEMSET& aOther ):
|
||||||
|
m_owner( false )
|
||||||
{
|
{
|
||||||
m_items = aOther.m_items;
|
m_items = aOther.m_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~PNS_ITEMSET();
|
||||||
|
|
||||||
|
void MakeOwner()
|
||||||
|
{
|
||||||
|
m_owner = true;
|
||||||
|
}
|
||||||
|
|
||||||
const PNS_ITEMSET& operator=( const PNS_ITEMSET& aOther )
|
const PNS_ITEMSET& operator=( const PNS_ITEMSET& aOther )
|
||||||
{
|
{
|
||||||
m_items = aOther.m_items;
|
m_items = aOther.m_items;
|
||||||
|
@ -68,6 +76,7 @@ public:
|
||||||
PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1, bool aInvert = false );
|
PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1, bool aInvert = false );
|
||||||
PNS_ITEMSET& FilterKinds( int aKindMask, bool aInvert = false );
|
PNS_ITEMSET& FilterKinds( int aKindMask, bool aInvert = false );
|
||||||
PNS_ITEMSET& FilterNet( int aNet, bool aInvert = false );
|
PNS_ITEMSET& FilterNet( int aNet, bool aInvert = false );
|
||||||
|
PNS_ITEMSET& FilterMarker( int aMarker, bool aInvert = false );
|
||||||
|
|
||||||
PNS_ITEMSET& ExcludeLayers( int aStart, int aEnd = -1 )
|
PNS_ITEMSET& ExcludeLayers( int aStart, int aEnd = -1 )
|
||||||
{
|
{
|
||||||
|
@ -96,6 +105,11 @@ public:
|
||||||
m_items.push_back( aItem );
|
m_items.push_back( aItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Prepend( PNS_ITEM* aItem )
|
||||||
|
{
|
||||||
|
m_items.push_front( aItem );
|
||||||
|
}
|
||||||
|
|
||||||
PNS_ITEM* Get( int index ) const
|
PNS_ITEM* Get( int index ) const
|
||||||
{
|
{
|
||||||
return m_items[index];
|
return m_items[index];
|
||||||
|
@ -126,6 +140,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ITEMS m_items;
|
ITEMS m_items;
|
||||||
|
bool m_owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
class PNS_JOINT : public PNS_ITEM
|
class PNS_JOINT : public PNS_ITEM
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::vector<PNS_ITEM*> LINKED_ITEMS;
|
typedef std::deque<PNS_ITEM*> LINKED_ITEMS;
|
||||||
|
|
||||||
///> Joints are hashed by their position, layers and net.
|
///> Joints are hashed by their position, layers and net.
|
||||||
/// Linked items are, obviously, not hashed
|
/// Linked items are, obviously, not hashed
|
||||||
|
@ -95,6 +95,22 @@ public:
|
||||||
return seg1->Width() == seg2->Width();
|
return seg1->Width() == seg2->Width();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsNonFanoutVia() const
|
||||||
|
{
|
||||||
|
if( m_linkedItems.Size() != 3 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int vias = 0, segs = 0;
|
||||||
|
|
||||||
|
for( int i = 0; i < 3; i++ )
|
||||||
|
{
|
||||||
|
vias += m_linkedItems[i]->Kind() == VIA ? 1 : 0;
|
||||||
|
segs += m_linkedItems[i]->Kind() == SEGMENT ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( vias == 1 && segs == 2 );
|
||||||
|
}
|
||||||
|
|
||||||
///> Links the joint to a given board item (when it's added to the PNS_NODE)
|
///> Links the joint to a given board item (when it's added to the PNS_NODE)
|
||||||
void Link( PNS_ITEM* aItem )
|
void Link( PNS_ITEM* aItem )
|
||||||
{
|
{
|
||||||
|
@ -193,15 +209,11 @@ private:
|
||||||
PNS_ITEMSET m_linkedItems;
|
PNS_ITEMSET m_linkedItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool operator==( PNS_JOINT::HASH_TAG const& aP1, PNS_JOINT::HASH_TAG const& aP2 )
|
||||||
// hash function & comparison operator for boost::unordered_map<>
|
|
||||||
inline bool operator==( PNS_JOINT::HASH_TAG const& aP1,
|
|
||||||
PNS_JOINT::HASH_TAG const& aP2 )
|
|
||||||
{
|
{
|
||||||
return aP1.pos == aP2.pos && aP1.net == aP2.net;
|
return aP1.pos == aP2.pos && aP1.net == aP2.net;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline std::size_t hash_value( PNS_JOINT::HASH_TAG const& aP )
|
inline std::size_t hash_value( PNS_JOINT::HASH_TAG const& aP )
|
||||||
{
|
{
|
||||||
std::size_t seed = 0;
|
std::size_t seed = 0;
|
||||||
|
|
|
@ -348,7 +348,6 @@ SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECT
|
||||||
{
|
{
|
||||||
optional<SHAPE_LINE_CHAIN> picked;
|
optional<SHAPE_LINE_CHAIN> picked;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
int d = 2;
|
int d = 2;
|
||||||
|
|
||||||
if( aOrigin.CSegment( -1 ).Length() > 100000 * 30 ) // fixme: constant/parameter?
|
if( aOrigin.CSegment( -1 ).Length() > 100000 * 30 ) // fixme: constant/parameter?
|
||||||
|
@ -701,6 +700,9 @@ void PNS_LINE::Reverse()
|
||||||
|
|
||||||
void PNS_LINE::AppendVia( const PNS_VIA& aVia )
|
void PNS_LINE::AppendVia( const PNS_VIA& aVia )
|
||||||
{
|
{
|
||||||
|
if( m_line.PointCount() == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
if( aVia.Pos() == m_line.CPoint( 0 ) )
|
if( aVia.Pos() == m_line.CPoint( 0 ) )
|
||||||
{
|
{
|
||||||
Reverse();
|
Reverse();
|
||||||
|
@ -781,3 +783,93 @@ void PNS_LINE::ClearSegmentLinks()
|
||||||
|
|
||||||
m_segmentRefs = NULL;
|
m_segmentRefs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void extendBox( BOX2I& aBox, bool& aDefined, const VECTOR2I& aP )
|
||||||
|
{
|
||||||
|
if( aDefined )
|
||||||
|
aBox.Merge ( aP );
|
||||||
|
else {
|
||||||
|
aBox = BOX2I( aP, VECTOR2I( 0, 0 ) );
|
||||||
|
aDefined = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OPT_BOX2I PNS_LINE::ChangedArea( const PNS_LINE* aOther ) const
|
||||||
|
{
|
||||||
|
BOX2I area;
|
||||||
|
bool areaDefined = false;
|
||||||
|
|
||||||
|
int i_start = -1;
|
||||||
|
int i_end_self = -1, i_end_other = -1;
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN self( m_line );
|
||||||
|
self.Simplify();
|
||||||
|
SHAPE_LINE_CHAIN other( aOther->m_line );
|
||||||
|
other.Simplify();
|
||||||
|
|
||||||
|
int np_self = self.PointCount();
|
||||||
|
int np_other = other.PointCount();
|
||||||
|
|
||||||
|
int n = std::min( np_self, np_other );
|
||||||
|
|
||||||
|
for( int i = 0; i < n; i++ )
|
||||||
|
{
|
||||||
|
const VECTOR2I p1 = self.CPoint( i );
|
||||||
|
const VECTOR2I p2 = other.CPoint( i );
|
||||||
|
|
||||||
|
if( p1 != p2 )
|
||||||
|
{
|
||||||
|
if( i != n - 1 )
|
||||||
|
{
|
||||||
|
SEG s = self.CSegment( i );
|
||||||
|
|
||||||
|
if( !s.Contains( p2 ) )
|
||||||
|
{
|
||||||
|
i_start = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i_start = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i = 0; i < n; i++ )
|
||||||
|
{
|
||||||
|
const VECTOR2I p1 = self.CPoint( np_self - 1 - i );
|
||||||
|
const VECTOR2I p2 = other.CPoint( np_other - 1 - i );
|
||||||
|
|
||||||
|
if( p1 != p2 )
|
||||||
|
{
|
||||||
|
i_end_self = np_self - 1 - i;
|
||||||
|
i_end_other = np_other - 1 - i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( i_start < 0 )
|
||||||
|
i_start = n;
|
||||||
|
|
||||||
|
if( i_end_self < 0 )
|
||||||
|
i_end_self = np_self - 1;
|
||||||
|
|
||||||
|
if( i_end_other < 0 )
|
||||||
|
i_end_other = np_other - 1;
|
||||||
|
|
||||||
|
for( int i = i_start; i <= i_end_self; i++ )
|
||||||
|
extendBox( area, areaDefined, self.CPoint( i ) );
|
||||||
|
|
||||||
|
for( int i = i_start; i <= i_end_other; i++ )
|
||||||
|
extendBox( area, areaDefined, other.CPoint( i ) );
|
||||||
|
|
||||||
|
if( areaDefined )
|
||||||
|
{
|
||||||
|
area.Inflate( std::max( Width(), aOther->Width() ) );
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OPT_BOX2I();
|
||||||
|
}
|
||||||
|
|
|
@ -89,6 +89,11 @@ public:
|
||||||
|
|
||||||
~PNS_LINE();
|
~PNS_LINE();
|
||||||
|
|
||||||
|
static inline bool ClassOf( const PNS_ITEM* aItem )
|
||||||
|
{
|
||||||
|
return aItem && LINE == aItem->Kind();
|
||||||
|
}
|
||||||
|
|
||||||
/// @copydoc PNS_ITEM::Clone()
|
/// @copydoc PNS_ITEM::Clone()
|
||||||
virtual PNS_LINE* Clone() const;
|
virtual PNS_LINE* Clone() const;
|
||||||
|
|
||||||
|
@ -179,6 +184,11 @@ public:
|
||||||
return m_segmentRefs;
|
return m_segmentRefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsLinked() const
|
||||||
|
{
|
||||||
|
return m_segmentRefs != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
///> Checks if the segment aSeg is a part of the line.
|
///> Checks if the segment aSeg is a part of the line.
|
||||||
bool ContainsSegment( PNS_SEGMENT* aSeg ) const
|
bool ContainsSegment( PNS_SEGMENT* aSeg ) const
|
||||||
{
|
{
|
||||||
|
@ -189,6 +199,11 @@ public:
|
||||||
aSeg ) != m_segmentRefs->end();
|
aSeg ) != m_segmentRefs->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNS_SEGMENT* GetLink( int aIndex ) const
|
||||||
|
{
|
||||||
|
return (*m_segmentRefs) [ aIndex ];
|
||||||
|
}
|
||||||
|
|
||||||
///> Erases the linking information. Used to detach the line from the owning node.
|
///> Erases the linking information. Used to detach the line from the owning node.
|
||||||
void ClearSegmentLinks();
|
void ClearSegmentLinks();
|
||||||
|
|
||||||
|
@ -251,6 +266,8 @@ public:
|
||||||
|
|
||||||
bool HasLoops() const;
|
bool HasLoops() const;
|
||||||
|
|
||||||
|
OPT_BOX2I ChangedArea( const PNS_LINE* aOther ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VECTOR2I snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,
|
VECTOR2I snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,
|
||||||
int aIndex, int aThreshold) const;
|
int aIndex, int aThreshold) const;
|
||||||
|
|
|
@ -31,13 +31,14 @@
|
||||||
#include "pns_shove.h"
|
#include "pns_shove.h"
|
||||||
#include "pns_utils.h"
|
#include "pns_utils.h"
|
||||||
#include "pns_router.h"
|
#include "pns_router.h"
|
||||||
|
#include "pns_topology.h"
|
||||||
|
|
||||||
#include <class_board_item.h>
|
#include <class_board_item.h>
|
||||||
|
|
||||||
using boost::optional;
|
using boost::optional;
|
||||||
|
|
||||||
PNS_LINE_PLACER::PNS_LINE_PLACER( PNS_ROUTER* aRouter ) :
|
PNS_LINE_PLACER::PNS_LINE_PLACER( PNS_ROUTER* aRouter ) :
|
||||||
PNS_ALGO_BASE ( aRouter )
|
PNS_PLACEMENT_ALGO( aRouter )
|
||||||
{
|
{
|
||||||
m_initial_direction = DIRECTION_45::N;
|
m_initial_direction = DIRECTION_45::N;
|
||||||
m_world = NULL;
|
m_world = NULL;
|
||||||
|
@ -67,11 +68,13 @@ const PNS_VIA PNS_LINE_PLACER::makeVia ( const VECTOR2I& aP )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_LINE_PLACER::ToggleVia( bool aEnabled )
|
bool PNS_LINE_PLACER::ToggleVia( bool aEnabled )
|
||||||
{
|
{
|
||||||
m_placingVia = aEnabled;
|
m_placingVia = aEnabled;
|
||||||
if(!m_idle)
|
if( !m_idle )
|
||||||
Move ( m_currentEnd, NULL );
|
Move( m_currentEnd, NULL );
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -225,8 +228,6 @@ bool PNS_LINE_PLACER::reduceTail( const VECTOR2I& aEnd )
|
||||||
VECTOR2I new_start;
|
VECTOR2I new_start;
|
||||||
int reduce_index = -1;
|
int reduce_index = -1;
|
||||||
|
|
||||||
DIRECTION_45 head_dir( head.CSegment( 0 ) );
|
|
||||||
|
|
||||||
for( int i = tail.SegmentCount() - 1; i >= 0; i-- )
|
for( int i = tail.SegmentCount() - 1; i >= 0; i-- )
|
||||||
{
|
{
|
||||||
const SEG s = tail.CSegment( i );
|
const SEG s = tail.CSegment( i );
|
||||||
|
@ -376,7 +377,7 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead )
|
||||||
|
|
||||||
bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
||||||
{
|
{
|
||||||
SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP );
|
SHAPE_LINE_CHAIN line = buildInitialLine( aP );
|
||||||
PNS_LINE initTrack( m_head, line ), walkFull;
|
PNS_LINE initTrack( m_head, line ), walkFull;
|
||||||
int effort = 0;
|
int effort = 0;
|
||||||
bool viaOk = handleViaPlacement( initTrack );
|
bool viaOk = handleViaPlacement( initTrack );
|
||||||
|
@ -430,7 +431,7 @@ bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
||||||
|
|
||||||
bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
||||||
{
|
{
|
||||||
m_head.SetShape( m_direction.BuildInitialTrace( m_p_start, aP ) );
|
m_head.SetShape( buildInitialLine( aP ) );
|
||||||
|
|
||||||
if( m_placingVia )
|
if( m_placingVia )
|
||||||
{
|
{
|
||||||
|
@ -445,7 +446,7 @@ bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
||||||
|
|
||||||
bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
||||||
{
|
{
|
||||||
SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP );
|
SHAPE_LINE_CHAIN line = buildInitialLine( aP );
|
||||||
PNS_LINE initTrack( m_head, line );
|
PNS_LINE initTrack( m_head, line );
|
||||||
PNS_LINE walkSolids, l2;
|
PNS_LINE walkSolids, l2;
|
||||||
|
|
||||||
|
@ -530,9 +531,9 @@ bool PNS_LINE_PLACER::routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
||||||
case RM_MarkObstacles:
|
case RM_MarkObstacles:
|
||||||
return rhMarkObstacles( aP, aNewHead );
|
return rhMarkObstacles( aP, aNewHead );
|
||||||
case RM_Walkaround:
|
case RM_Walkaround:
|
||||||
return rhWalkOnly ( aP, aNewHead );
|
return rhWalkOnly( aP, aNewHead );
|
||||||
case RM_Shove:
|
case RM_Shove:
|
||||||
return rhShoveOnly ( aP, aNewHead );
|
return rhShoveOnly( aP, aNewHead );
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -731,9 +732,12 @@ bool PNS_LINE_PLACER::SetLayer( int aLayer )
|
||||||
{
|
{
|
||||||
m_currentLayer = aLayer;
|
m_currentLayer = aLayer;
|
||||||
return true;
|
return true;
|
||||||
} else if( m_chainedPlacement ) {
|
}
|
||||||
|
else if( m_chainedPlacement )
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
} else if( !m_startItem || ( m_startItem->OfKind( PNS_ITEM::VIA ) && m_startItem->Layers().Overlaps( aLayer ) ) ) {
|
}
|
||||||
|
else if( !m_startItem || ( m_startItem->OfKind( PNS_ITEM::VIA ) && m_startItem->Layers().Overlaps( aLayer ) ) ) {
|
||||||
m_currentLayer = aLayer;
|
m_currentLayer = aLayer;
|
||||||
m_splitSeg = false;
|
m_splitSeg = false;
|
||||||
initPlacement ( m_splitSeg );
|
initPlacement ( m_splitSeg );
|
||||||
|
@ -744,7 +748,8 @@ bool PNS_LINE_PLACER::SetLayer( int aLayer )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|
||||||
|
bool PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||||
{
|
{
|
||||||
VECTOR2I p( aP );
|
VECTOR2I p( aP );
|
||||||
|
|
||||||
|
@ -772,6 +777,7 @@ void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||||
setInitialDirection( Settings().InitialDirection() );
|
setInitialDirection( Settings().InitialDirection() );
|
||||||
|
|
||||||
initPlacement( m_splitSeg );
|
initPlacement( m_splitSeg );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PNS_LINE_PLACER::initPlacement( bool aSplitSeg )
|
void PNS_LINE_PLACER::initPlacement( bool aSplitSeg )
|
||||||
|
@ -819,7 +825,7 @@ void PNS_LINE_PLACER::initPlacement( bool aSplitSeg )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
bool PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||||
{
|
{
|
||||||
PNS_LINE current;
|
PNS_LINE current;
|
||||||
VECTOR2I p = aP;
|
VECTOR2I p = aP;
|
||||||
|
@ -856,6 +862,7 @@ void PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLeadingRatLine();
|
updateLeadingRatLine();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -962,11 +969,6 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest )
|
||||||
|
|
||||||
if( !( line->ContainsSegment( seg ) ) && line->SegmentCount() )
|
if( !( line->ContainsSegment( seg ) ) && line->SegmentCount() )
|
||||||
{
|
{
|
||||||
Router()->DisplayDebugLine ( line->CLine(), -1, 10000 );
|
|
||||||
|
|
||||||
for( int i = 0; i < line->PointCount(); i++ )
|
|
||||||
Router()->DisplayDebugPoint( line->CPoint( i ), -1 );
|
|
||||||
|
|
||||||
aNode->Remove( line );
|
aNode->Remove( line );
|
||||||
removedCount ++;
|
removedCount ++;
|
||||||
}
|
}
|
||||||
|
@ -1012,27 +1014,42 @@ void PNS_LINE_PLACER::UpdateSizes( const PNS_SIZES_SETTINGS& aSizes )
|
||||||
void PNS_LINE_PLACER::updateLeadingRatLine()
|
void PNS_LINE_PLACER::updateLeadingRatLine()
|
||||||
{
|
{
|
||||||
PNS_LINE current = Trace();
|
PNS_LINE current = Trace();
|
||||||
|
SHAPE_LINE_CHAIN ratLine;
|
||||||
|
PNS_TOPOLOGY topo ( m_lastNode );
|
||||||
|
|
||||||
if( !current.PointCount() )
|
if( topo.LeadingRatLine( ¤t, ratLine ) )
|
||||||
return;
|
Router()->DisplayDebugLine( ratLine, 5, 10000 );
|
||||||
|
}
|
||||||
std::auto_ptr<PNS_NODE> tmpNode ( m_lastNode->Branch() );
|
|
||||||
tmpNode->Add( ¤t );
|
|
||||||
|
void PNS_LINE_PLACER::SetOrthoMode( bool aOrthoMode )
|
||||||
PNS_JOINT* jt = tmpNode->FindJoint( current.CPoint( -1 ),
|
{
|
||||||
current.Layers().Start(), current.Net() );
|
m_orthoMode = aOrthoMode;
|
||||||
|
|
||||||
if( !jt )
|
if( !m_idle )
|
||||||
return;
|
Move( m_currentEnd, NULL );
|
||||||
|
}
|
||||||
int anchor;
|
|
||||||
PNS_ITEM* it = tmpNode->NearestUnconnectedItem( jt, &anchor );
|
const SHAPE_LINE_CHAIN PNS_LINE_PLACER::buildInitialLine( const VECTOR2I& aP )
|
||||||
|
{
|
||||||
if( it )
|
SHAPE_LINE_CHAIN l( m_direction.BuildInitialTrace( m_p_start, aP ) );
|
||||||
{
|
|
||||||
SHAPE_LINE_CHAIN lc;
|
if( l.SegmentCount() <= 1 )
|
||||||
lc.Append ( current.CPoint( -1 ) );
|
return l;
|
||||||
lc.Append ( it->Anchor( anchor ) );
|
|
||||||
Router()->DisplayDebugLine( lc, 5, 10000 );
|
if( m_orthoMode )
|
||||||
}
|
{
|
||||||
|
VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );
|
||||||
|
|
||||||
|
l.Remove( -1, -1 );
|
||||||
|
l.Point( 1 ) = newLast;
|
||||||
|
}
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_LINE_PLACER::GetModifiedNets( std::vector<int>& aNets ) const
|
||||||
|
{
|
||||||
|
aNets.push_back( m_currentNet );
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "pns_node.h"
|
#include "pns_node.h"
|
||||||
#include "pns_via.h"
|
#include "pns_via.h"
|
||||||
#include "pns_line.h"
|
#include "pns_line.h"
|
||||||
#include "pns_algo_base.h"
|
#include "pns_placement_algo.h"
|
||||||
|
|
||||||
class PNS_ROUTER;
|
class PNS_ROUTER;
|
||||||
class PNS_SHOVE;
|
class PNS_SHOVE;
|
||||||
|
@ -47,7 +47,7 @@ class PNS_SIZES_SETTINGS;
|
||||||
* Applies shove and walkaround algorithms when needed.
|
* Applies shove and walkaround algorithms when needed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PNS_LINE_PLACER : public PNS_ALGO_BASE
|
class PNS_LINE_PLACER : public PNS_PLACEMENT_ALGO
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PNS_LINE_PLACER( PNS_ROUTER* aRouter );
|
PNS_LINE_PLACER( PNS_ROUTER* aRouter );
|
||||||
|
@ -59,7 +59,7 @@ public:
|
||||||
* Starts routing a single track at point aP, taking item aStartItem as anchor
|
* Starts routing a single track at point aP, taking item aStartItem as anchor
|
||||||
* (unless NULL).
|
* (unless NULL).
|
||||||
*/
|
*/
|
||||||
void Start( const VECTOR2I& aP, PNS_ITEM* aStartItem );
|
bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Move()
|
* Function Move()
|
||||||
|
@ -68,7 +68,7 @@ public:
|
||||||
* aEndItem as anchor (if not NULL).
|
* aEndItem as anchor (if not NULL).
|
||||||
* (unless NULL).
|
* (unless NULL).
|
||||||
*/
|
*/
|
||||||
void Move( const VECTOR2I& aP, PNS_ITEM* aEndItem );
|
bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function FixRoute()
|
* Function FixRoute()
|
||||||
|
@ -86,7 +86,7 @@ public:
|
||||||
*
|
*
|
||||||
* Enables/disables a via at the end of currently routed trace.
|
* Enables/disables a via at the end of currently routed trace.
|
||||||
*/
|
*/
|
||||||
void ToggleVia( bool aEnabled );
|
bool ToggleVia( bool aEnabled );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function SetLayer()
|
* Function SetLayer()
|
||||||
|
@ -95,7 +95,6 @@ public:
|
||||||
*/
|
*/
|
||||||
bool SetLayer( int aLayer );
|
bool SetLayer( int aLayer );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Head()
|
* Function Head()
|
||||||
*
|
*
|
||||||
|
@ -180,7 +179,11 @@ public:
|
||||||
*/
|
*/
|
||||||
void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes );
|
void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes );
|
||||||
|
|
||||||
|
void SetOrthoMode( bool aOrthoMode );
|
||||||
|
|
||||||
bool IsPlacingVia() const { return m_placingVia; }
|
bool IsPlacingVia() const { return m_placingVia; }
|
||||||
|
|
||||||
|
void GetModifiedNets( std::vector<int>& aNets ) const;
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Function route()
|
* Function route()
|
||||||
|
@ -344,6 +347,8 @@ private:
|
||||||
|
|
||||||
const PNS_VIA makeVia ( const VECTOR2I& aP );
|
const PNS_VIA makeVia ( const VECTOR2I& aP );
|
||||||
|
|
||||||
|
const SHAPE_LINE_CHAIN buildInitialLine( const VECTOR2I& aP );
|
||||||
|
|
||||||
///> current routing direction
|
///> current routing direction
|
||||||
DIRECTION_45 m_direction;
|
DIRECTION_45 m_direction;
|
||||||
|
|
||||||
|
@ -403,6 +408,7 @@ private:
|
||||||
bool m_idle;
|
bool m_idle;
|
||||||
bool m_chainedPlacement;
|
bool m_chainedPlacement;
|
||||||
bool m_splitSeg;
|
bool m_splitSeg;
|
||||||
|
bool m_orthoMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __PNS_LINE_PLACER_H
|
#endif // __PNS_LINE_PLACER_H
|
||||||
|
|
|
@ -70,7 +70,7 @@ void PNS_LOGGER::EndGroup()
|
||||||
|
|
||||||
void PNS_LOGGER::Log ( const PNS_ITEM* aItem, int aKind, const std::string aName )
|
void PNS_LOGGER::Log ( const PNS_ITEM* aItem, int aKind, const std::string aName )
|
||||||
{
|
{
|
||||||
m_theLog << "aItem " << aKind << " " << aName << " ";
|
m_theLog << "item " << aKind << " " << aName << " ";
|
||||||
m_theLog << aItem->Net() << " " << aItem->Layers().Start() << " " <<
|
m_theLog << aItem->Net() << " " << aItem->Layers().Start() << " " <<
|
||||||
aItem->Layers().End() << " " << aItem->Marker() << " " << aItem->Rank();
|
aItem->Layers().End() << " " << aItem->Marker() << " " << aItem->Rank();
|
||||||
|
|
||||||
|
@ -178,6 +178,7 @@ void PNS_LOGGER::dumpShape( const SHAPE* aSh )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_LOGGER::Save( const std::string& aFilename )
|
void PNS_LOGGER::Save( const std::string& aFilename )
|
||||||
{
|
{
|
||||||
EndGroup();
|
EndGroup();
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
const std::string aName = std::string() );
|
const std::string aName = std::string() );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void dumpShape ( const SHAPE* aSh );
|
void dumpShape( const SHAPE* aSh );
|
||||||
|
|
||||||
bool m_groupOpened;
|
bool m_groupOpened;
|
||||||
std::stringstream m_theLog;
|
std::stringstream m_theLog;
|
||||||
|
|
|
@ -0,0 +1,594 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2014 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
#include <base_units.h> // God forgive me doing this...
|
||||||
|
#include <colors.h>
|
||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#include "pns_node.h"
|
||||||
|
#include "pns_itemset.h"
|
||||||
|
#include "pns_topology.h"
|
||||||
|
#include "pns_meander.h"
|
||||||
|
#include "pns_meander_placer_base.h"
|
||||||
|
#include "pns_router.h"
|
||||||
|
|
||||||
|
const PNS_MEANDER_SETTINGS& PNS_MEANDER_SHAPE::Settings() const
|
||||||
|
{
|
||||||
|
return m_placer->MeanderSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
const PNS_MEANDER_SETTINGS& PNS_MEANDERED_LINE::Settings() const
|
||||||
|
{
|
||||||
|
return m_placer->MeanderSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PNS_MEANDERED_LINE::MeanderSegment( const SEG& aBase, int aBaseIndex )
|
||||||
|
{
|
||||||
|
double base_len = aBase.Length();
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN lc;
|
||||||
|
|
||||||
|
bool side = true;
|
||||||
|
VECTOR2D dir( aBase.B - aBase.A );
|
||||||
|
|
||||||
|
if( !m_dual )
|
||||||
|
AddCorner( aBase.A );
|
||||||
|
|
||||||
|
bool turning = false;
|
||||||
|
bool started = false;
|
||||||
|
|
||||||
|
m_last = aBase.A;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
PNS_MEANDER_SHAPE* m = new PNS_MEANDER_SHAPE( m_placer, m_width, m_dual );
|
||||||
|
m->SetBaselineOffset( m_baselineOffset );
|
||||||
|
m->SetBaseIndex( aBaseIndex );
|
||||||
|
|
||||||
|
double thr = (double) m->spacing();
|
||||||
|
|
||||||
|
bool fail = false;
|
||||||
|
double remaining = base_len - ( m_last - aBase.A ).EuclideanNorm();
|
||||||
|
|
||||||
|
if( remaining < Settings( ).m_step )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( remaining > 3.0 * thr )
|
||||||
|
{
|
||||||
|
if( !turning )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 2; i++ )
|
||||||
|
{
|
||||||
|
if ( m->Fit( MT_CHECK_START, aBase, m_last, i ) )
|
||||||
|
{
|
||||||
|
turning = true;
|
||||||
|
AddMeander( m );
|
||||||
|
side = !i;
|
||||||
|
started = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !turning )
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
|
||||||
|
for( int i = 0; i < 2; i++ )
|
||||||
|
{
|
||||||
|
if ( m->Fit ( MT_SINGLE, aBase, m_last, i ) )
|
||||||
|
{
|
||||||
|
AddMeander( m );
|
||||||
|
fail = false;
|
||||||
|
started = false;
|
||||||
|
side = !i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bool rv = m->Fit( MT_CHECK_FINISH, aBase, m_last, side );
|
||||||
|
|
||||||
|
if( rv )
|
||||||
|
{
|
||||||
|
m->Fit( MT_TURN, aBase, m_last, side );
|
||||||
|
AddMeander( m );
|
||||||
|
started = true;
|
||||||
|
} else {
|
||||||
|
m->Fit( MT_FINISH, aBase, m_last, side );
|
||||||
|
started = false;
|
||||||
|
AddMeander( m );
|
||||||
|
turning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
side = !side;
|
||||||
|
}
|
||||||
|
} else if( started )
|
||||||
|
{
|
||||||
|
bool rv = m->Fit( MT_FINISH, aBase, m_last, side );
|
||||||
|
if( rv )
|
||||||
|
AddMeander( m );
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining = base_len - ( m_last - aBase.A ).EuclideanNorm( );
|
||||||
|
|
||||||
|
if( remaining < Settings( ).m_step )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( fail )
|
||||||
|
{
|
||||||
|
PNS_MEANDER_SHAPE tmp( m_placer, m_width, m_dual );
|
||||||
|
tmp.SetBaselineOffset( m_baselineOffset );
|
||||||
|
tmp.SetBaseIndex( aBaseIndex );
|
||||||
|
|
||||||
|
int nextP = tmp.spacing() - 2 * tmp.cornerRadius() + Settings().m_step;
|
||||||
|
VECTOR2I pn = m_last + dir.Resize( nextP );
|
||||||
|
|
||||||
|
if( aBase.Contains( pn ) && !m_dual )
|
||||||
|
{
|
||||||
|
AddCorner( pn );
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} while( true );
|
||||||
|
|
||||||
|
if( !m_dual )
|
||||||
|
AddCorner( aBase.B );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_MEANDER_SHAPE::cornerRadius() const
|
||||||
|
{
|
||||||
|
int cr = (int64_t) spacing() * Settings().m_cornerRadiusPercentage / 200;
|
||||||
|
|
||||||
|
return cr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_MEANDER_SHAPE::spacing( ) const
|
||||||
|
{
|
||||||
|
if ( !m_dual )
|
||||||
|
return std::max( 2 * m_width, Settings().m_spacing );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int sp = 2 * ( m_width + std::abs( m_baselineOffset ) );
|
||||||
|
return std::max ( sp, Settings().m_spacing );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::circleQuad( VECTOR2D aP, VECTOR2D aDir, bool aSide )
|
||||||
|
{
|
||||||
|
SHAPE_LINE_CHAIN lc;
|
||||||
|
|
||||||
|
if( aDir.EuclideanNorm( ) == 0.0f )
|
||||||
|
{
|
||||||
|
lc.Append( aP );
|
||||||
|
return lc;
|
||||||
|
}
|
||||||
|
|
||||||
|
VECTOR2D dir_u( aDir );
|
||||||
|
VECTOR2D dir_v( aDir.Perpendicular( ) );
|
||||||
|
|
||||||
|
const int ArcSegments = Settings().m_cornerArcSegments;
|
||||||
|
|
||||||
|
for( int i = ArcSegments - 1; i >= 0; i-- )
|
||||||
|
{
|
||||||
|
VECTOR2D p;
|
||||||
|
double alpha = (double) i / (double) ( ArcSegments - 1 ) * M_PI / 2.0;
|
||||||
|
p = aP + dir_u * cos( alpha ) + dir_v * ( aSide ? -1.0 : 1.0 ) * ( 1.0 - sin( alpha ) );
|
||||||
|
lc.Append( ( int ) p.x, ( int ) p.y );
|
||||||
|
}
|
||||||
|
|
||||||
|
return lc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VECTOR2I PNS_MEANDER_SHAPE::reflect( VECTOR2I p, const SEG& line )
|
||||||
|
{
|
||||||
|
typedef int64_t ecoord;
|
||||||
|
VECTOR2I d = line.B - line.A;
|
||||||
|
ecoord l_squared = d.Dot( d );
|
||||||
|
ecoord t = d.Dot( p - line.A );
|
||||||
|
VECTOR2I c, rv;
|
||||||
|
|
||||||
|
if( !l_squared )
|
||||||
|
c = p;
|
||||||
|
else {
|
||||||
|
c.x = line.A.x + rescale( t, (ecoord) d.x, l_squared );
|
||||||
|
c.y = line.A.y + rescale( t, (ecoord) d.y, l_squared );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2 * c - p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_SHAPE::start( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir )
|
||||||
|
{
|
||||||
|
m_currentTarget = aTarget;
|
||||||
|
m_currentTarget->Clear();
|
||||||
|
m_currentTarget->Append( aWhere );
|
||||||
|
m_currentDir = aDir;
|
||||||
|
m_currentPos = aWhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_SHAPE::forward( int aLength )
|
||||||
|
{
|
||||||
|
m_currentPos += m_currentDir.Resize( aLength );
|
||||||
|
m_currentTarget->Append( m_currentPos );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_SHAPE::turn( int aAngle )
|
||||||
|
{
|
||||||
|
m_currentDir = m_currentDir.Rotate( (double) aAngle * M_PI / 180.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_SHAPE::arc( int aRadius, bool aSide )
|
||||||
|
{
|
||||||
|
if( aRadius <= 0 )
|
||||||
|
{
|
||||||
|
turn( aSide ? -90 : 90 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VECTOR2D dir = m_currentDir.Resize( (double) aRadius );
|
||||||
|
SHAPE_LINE_CHAIN arc = circleQuad( m_currentPos, dir, aSide );
|
||||||
|
m_currentPos = arc.CPoint( -1 );
|
||||||
|
m_currentDir = dir.Rotate( aSide ? -M_PI / 2.0 : M_PI / 2.0 );
|
||||||
|
|
||||||
|
m_currentTarget->Append ( arc );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_SHAPE::uShape( int aSides, int aCorner, int aTop )
|
||||||
|
{
|
||||||
|
forward( aSides );
|
||||||
|
arc( aCorner, true );
|
||||||
|
forward( aTop );
|
||||||
|
arc( aCorner, true );
|
||||||
|
forward( aSides );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape( VECTOR2D aP, VECTOR2D aDir,
|
||||||
|
bool aSide, PNS_MEANDER_TYPE aType, int aAmpl, int aBaselineOffset )
|
||||||
|
{
|
||||||
|
const PNS_MEANDER_SETTINGS& st = Settings();
|
||||||
|
int cr = cornerRadius();
|
||||||
|
int offset = aBaselineOffset;
|
||||||
|
int spc = spacing();
|
||||||
|
|
||||||
|
if( aSide )
|
||||||
|
offset *= -1;
|
||||||
|
|
||||||
|
VECTOR2D dir_u_b( aDir.Resize( offset ) );
|
||||||
|
VECTOR2D dir_v_b( dir_u_b.Perpendicular() );
|
||||||
|
|
||||||
|
if( 2 * cr > aAmpl )
|
||||||
|
{
|
||||||
|
cr = aAmpl / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( 2 * cr > spc )
|
||||||
|
{
|
||||||
|
cr = spc / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN lc;
|
||||||
|
|
||||||
|
start( &lc, aP + dir_v_b, aDir );
|
||||||
|
|
||||||
|
switch( aType )
|
||||||
|
{
|
||||||
|
case MT_EMPTY:
|
||||||
|
{
|
||||||
|
lc.Append( aP + dir_v_b + aDir );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MT_START:
|
||||||
|
{
|
||||||
|
arc( cr - offset, false );
|
||||||
|
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
|
||||||
|
forward( std::min( cr - offset, cr + offset ) );
|
||||||
|
forward( std::abs( offset ) );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MT_FINISH:
|
||||||
|
{
|
||||||
|
start( &lc, aP - dir_u_b, aDir );
|
||||||
|
turn ( 90 );
|
||||||
|
forward( std::min( cr - offset, cr + offset ) );
|
||||||
|
forward( std::abs( offset ) );
|
||||||
|
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
|
||||||
|
arc( cr - offset, false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MT_TURN:
|
||||||
|
{
|
||||||
|
start( &lc, aP - dir_u_b, aDir );
|
||||||
|
turn( 90 );
|
||||||
|
forward( std::abs( offset ) );
|
||||||
|
uShape ( aAmpl - cr, cr + offset, spc - 2 * cr );
|
||||||
|
forward( std::abs( offset ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MT_SINGLE:
|
||||||
|
{
|
||||||
|
arc( cr - offset, false );
|
||||||
|
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
|
||||||
|
arc( cr - offset, false );
|
||||||
|
lc.Append( aP + dir_v_b + aDir.Resize ( 2 * st.m_spacing ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aSide )
|
||||||
|
{
|
||||||
|
SEG axis ( aP, aP + aDir );
|
||||||
|
|
||||||
|
for( int i = 0; i < lc.PointCount(); i++ )
|
||||||
|
lc.Point( i ) = reflect( lc.CPoint( i ), axis );
|
||||||
|
}
|
||||||
|
|
||||||
|
return lc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_MEANDERED_LINE::CheckSelfIntersections( PNS_MEANDER_SHAPE* aShape, int aClearance )
|
||||||
|
{
|
||||||
|
for( int i = m_meanders.size() - 1; i >= 0; i-- )
|
||||||
|
{
|
||||||
|
PNS_MEANDER_SHAPE* m = m_meanders[i];
|
||||||
|
|
||||||
|
if( m->Type() == MT_EMPTY || m->Type() == MT_CORNER )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const SEG& b1 = aShape->BaseSegment();
|
||||||
|
const SEG& b2 = m->BaseSegment();
|
||||||
|
|
||||||
|
if( b1.ApproxParallel( b2 ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int n = m->CLine( 0 ).SegmentCount();
|
||||||
|
|
||||||
|
for( int j = n - 1; j >= 0; j-- )
|
||||||
|
if( aShape->CLine( 0 ).Collide ( m->CLine( 0 ) .CSegment( j ), aClearance ) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_MEANDER_SHAPE::Fit( PNS_MEANDER_TYPE aType, const SEG& aSeg, const VECTOR2I& aP, bool aSide )
|
||||||
|
{
|
||||||
|
const PNS_MEANDER_SETTINGS& st = Settings();
|
||||||
|
|
||||||
|
bool checkMode = false;
|
||||||
|
PNS_MEANDER_TYPE prim1, prim2;
|
||||||
|
|
||||||
|
if( aType == MT_CHECK_START )
|
||||||
|
{
|
||||||
|
prim1 = MT_START;
|
||||||
|
prim2 = MT_TURN;
|
||||||
|
checkMode = true;
|
||||||
|
}
|
||||||
|
else if( aType == MT_CHECK_FINISH )
|
||||||
|
{
|
||||||
|
prim1 = MT_TURN;
|
||||||
|
prim2 = MT_FINISH;
|
||||||
|
checkMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( checkMode )
|
||||||
|
{
|
||||||
|
PNS_MEANDER_SHAPE m1( m_placer, m_width, m_dual );
|
||||||
|
PNS_MEANDER_SHAPE m2( m_placer, m_width, m_dual );
|
||||||
|
|
||||||
|
m1.SetBaselineOffset( m_baselineOffset );
|
||||||
|
m2.SetBaselineOffset( m_baselineOffset );
|
||||||
|
|
||||||
|
bool c1 = m1.Fit( prim1, aSeg, aP, aSide );
|
||||||
|
bool c2 = false;
|
||||||
|
|
||||||
|
if( c1 )
|
||||||
|
c2 = m2.Fit( prim2, aSeg, m1.End(), !aSide );
|
||||||
|
|
||||||
|
if( c1 && c2 )
|
||||||
|
{
|
||||||
|
m_type = prim1;
|
||||||
|
m_shapes[0] = m1.m_shapes[0];
|
||||||
|
m_shapes[1] = m1.m_shapes[1];
|
||||||
|
m_baseSeg =aSeg;
|
||||||
|
m_p0 = aP;
|
||||||
|
m_side = aSide;
|
||||||
|
m_amplitude = m1.Amplitude();
|
||||||
|
m_dual = m1.m_dual;
|
||||||
|
m_baseSeg = m1.m_baseSeg;
|
||||||
|
m_baseIndex = m1.m_baseIndex;
|
||||||
|
updateBaseSegment();
|
||||||
|
m_baselineOffset = m1.m_baselineOffset;
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int minAmpl = st.m_minAmplitude;
|
||||||
|
int maxAmpl = st.m_maxAmplitude;
|
||||||
|
|
||||||
|
if( m_dual )
|
||||||
|
{
|
||||||
|
minAmpl = std::max( minAmpl, 2 * std::abs( m_baselineOffset ) );
|
||||||
|
maxAmpl = std::max( maxAmpl, 2 * std::abs( m_baselineOffset ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int ampl = maxAmpl; ampl >= minAmpl; ampl -= st.m_step )
|
||||||
|
{
|
||||||
|
if( m_dual )
|
||||||
|
{
|
||||||
|
m_shapes[0] = genMeanderShape( aP, aSeg.B - aSeg.A, aSide, aType, ampl, m_baselineOffset );
|
||||||
|
m_shapes[1] = genMeanderShape( aP, aSeg.B - aSeg.A, aSide, aType, ampl, -m_baselineOffset );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_shapes[0] = genMeanderShape( aP, aSeg.B - aSeg.A, aSide, aType, ampl, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_type = aType;
|
||||||
|
m_baseSeg = aSeg;
|
||||||
|
m_p0 = aP;
|
||||||
|
m_side = aSide;
|
||||||
|
m_amplitude = ampl;
|
||||||
|
|
||||||
|
updateBaseSegment();
|
||||||
|
|
||||||
|
if( m_placer->CheckFit( this ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_SHAPE::Recalculate()
|
||||||
|
{
|
||||||
|
m_shapes[0] = genMeanderShape( m_p0, m_baseSeg.B - m_baseSeg.A, m_side, m_type, m_amplitude, m_dual ? m_baselineOffset : 0 );
|
||||||
|
|
||||||
|
if( m_dual )
|
||||||
|
m_shapes[1] = genMeanderShape( m_p0, m_baseSeg.B - m_baseSeg.A, m_side, m_type, m_amplitude, -m_baselineOffset );
|
||||||
|
|
||||||
|
updateBaseSegment();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_SHAPE::Resize( int aAmpl )
|
||||||
|
{
|
||||||
|
if( aAmpl < 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_amplitude = aAmpl;
|
||||||
|
|
||||||
|
Recalculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_SHAPE::MakeEmpty()
|
||||||
|
{
|
||||||
|
updateBaseSegment();
|
||||||
|
|
||||||
|
VECTOR2I dir = m_clippedBaseSeg.B - m_clippedBaseSeg.A;
|
||||||
|
|
||||||
|
m_type = MT_EMPTY;
|
||||||
|
|
||||||
|
m_shapes[0] = genMeanderShape ( m_p0, dir, m_side, m_type, 0, m_dual ? m_baselineOffset : 0 );
|
||||||
|
|
||||||
|
if( m_dual )
|
||||||
|
m_shapes[1] = genMeanderShape( m_p0, dir, m_side, m_type, 0, -m_baselineOffset );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDERED_LINE::AddCorner( const VECTOR2I& aA, const VECTOR2I& aB )
|
||||||
|
{
|
||||||
|
PNS_MEANDER_SHAPE* m = new PNS_MEANDER_SHAPE( m_placer, m_width, m_dual );
|
||||||
|
|
||||||
|
m->MakeCorner( aA, aB );
|
||||||
|
m_last = aA;
|
||||||
|
|
||||||
|
m_meanders.push_back( m );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_SHAPE::MakeCorner( VECTOR2I aP1, VECTOR2I aP2 )
|
||||||
|
{
|
||||||
|
SetType( MT_CORNER );
|
||||||
|
m_shapes[0].Clear();
|
||||||
|
m_shapes[1].Clear();
|
||||||
|
m_shapes[0].Append( aP1 );
|
||||||
|
m_shapes[1].Append( aP2 );
|
||||||
|
m_clippedBaseSeg.A = aP1;
|
||||||
|
m_clippedBaseSeg.B = aP1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDERED_LINE::AddMeander( PNS_MEANDER_SHAPE* aShape )
|
||||||
|
{
|
||||||
|
m_last = aShape->BaseSegment().B;
|
||||||
|
m_meanders.push_back( aShape );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDERED_LINE::Clear()
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( PNS_MEANDER_SHAPE* m, m_meanders )
|
||||||
|
{
|
||||||
|
delete m;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_meanders.clear( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_MEANDER_SHAPE::BaselineLength() const
|
||||||
|
{
|
||||||
|
return m_clippedBaseSeg.Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_MEANDER_SHAPE::MaxTunableLength() const
|
||||||
|
{
|
||||||
|
return CLine( 0 ).Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_SHAPE::updateBaseSegment( )
|
||||||
|
{
|
||||||
|
if( m_dual )
|
||||||
|
{
|
||||||
|
VECTOR2I midpA = ( CLine( 0 ).CPoint( 0 ) + CLine( 1 ).CPoint( 0 ) ) / 2;
|
||||||
|
VECTOR2I midpB = ( CLine( 0 ).CPoint( -1 ) + CLine( 1 ).CPoint( -1 ) ) / 2;
|
||||||
|
|
||||||
|
m_clippedBaseSeg.A = m_baseSeg.LineProject( midpA );
|
||||||
|
m_clippedBaseSeg.B = m_baseSeg.LineProject( midpB );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_clippedBaseSeg.A = m_baseSeg.LineProject( CLine( 0 ).CPoint( 0 ) );
|
||||||
|
m_clippedBaseSeg.B = m_baseSeg.LineProject( CLine( 0 ).CPoint( -1 ) );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,492 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PNS_MEANDER_H
|
||||||
|
#define __PNS_MEANDER_H
|
||||||
|
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
|
||||||
|
#include <geometry/shape.h>
|
||||||
|
#include <geometry/shape_line_chain.h>
|
||||||
|
|
||||||
|
class PNS_MEANDER_PLACER_BASE;
|
||||||
|
|
||||||
|
///< Shapes of available meanders
|
||||||
|
enum PNS_MEANDER_TYPE {
|
||||||
|
MT_SINGLE, // _|^|_, single-sided
|
||||||
|
MT_START, // _|^|
|
||||||
|
MT_FINISH, // |^|_
|
||||||
|
MT_TURN, // |^| or |_|
|
||||||
|
MT_CHECK_START, // try fitting a start type, but don't produce a line
|
||||||
|
MT_CHECK_FINISH, // try fitting a finish type, but don't produce a line
|
||||||
|
MT_CORNER, // line corner
|
||||||
|
MT_EMPTY // no meander (straight line)
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_MEANDER_SETTINGS
|
||||||
|
*
|
||||||
|
* Holds dimensions for the meandering algorithm.
|
||||||
|
*/
|
||||||
|
class PNS_MEANDER_SETTINGS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
///> meander corner shape
|
||||||
|
enum CornerType {
|
||||||
|
ROUND = 1, // rounded (90 degree arc)
|
||||||
|
CHAMFER // chamfered (45 degree segment)
|
||||||
|
};
|
||||||
|
|
||||||
|
PNS_MEANDER_SETTINGS()
|
||||||
|
{
|
||||||
|
m_minAmplitude = 100000;
|
||||||
|
m_maxAmplitude = 1000000;
|
||||||
|
m_step = 50000;
|
||||||
|
m_spacing = 600000;
|
||||||
|
m_targetLength = 100000000;
|
||||||
|
m_targetSkew = 0;
|
||||||
|
m_cornerType = ROUND;
|
||||||
|
m_cornerRadiusPercentage = 100;
|
||||||
|
m_lengthTolerance = 100000;
|
||||||
|
m_cornerArcSegments = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
///> minimum meandering amplitude
|
||||||
|
int m_minAmplitude;
|
||||||
|
///> maximum meandering amplitude
|
||||||
|
int m_maxAmplitude;
|
||||||
|
///> meandering period/spacing (see dialog picture for explanation)
|
||||||
|
int m_spacing;
|
||||||
|
///> amplitude/spacing adjustment step
|
||||||
|
int m_step;
|
||||||
|
///> desired length of the tuned line/diff pair
|
||||||
|
int m_targetLength;
|
||||||
|
///> type of corners for the meandered line
|
||||||
|
CornerType m_cornerType;
|
||||||
|
///> rounding percentage (0 - 100)
|
||||||
|
int m_cornerRadiusPercentage;
|
||||||
|
///> allowable tuning error
|
||||||
|
int m_lengthTolerance;
|
||||||
|
///> number of line segments for arc approximation
|
||||||
|
int m_cornerArcSegments;
|
||||||
|
///> target skew value for diff pair de-skewing
|
||||||
|
int m_targetSkew;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PNS_MEANDERED_LINE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_MEANDER_SETTINGS
|
||||||
|
*
|
||||||
|
* Holds the geometry of a single meander.
|
||||||
|
*/
|
||||||
|
class PNS_MEANDER_SHAPE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param aPlacer the meander placer instance
|
||||||
|
* @param aWidth width of the meandered line
|
||||||
|
* @param aIsDual when true, the shape contains two meandered
|
||||||
|
* lines at a given offset (diff pairs)
|
||||||
|
*/
|
||||||
|
PNS_MEANDER_SHAPE( PNS_MEANDER_PLACER_BASE *aPlacer, int aWidth, bool aIsDual = false ) :
|
||||||
|
m_placer( aPlacer ),
|
||||||
|
m_dual( aIsDual ),
|
||||||
|
m_width( aWidth ),
|
||||||
|
m_baselineOffset( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetType()
|
||||||
|
*
|
||||||
|
* Sets the type of the meander.
|
||||||
|
*/
|
||||||
|
void SetType( PNS_MEANDER_TYPE aType )
|
||||||
|
{
|
||||||
|
m_type = aType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Type()
|
||||||
|
*
|
||||||
|
* @return the type of the meander.
|
||||||
|
*/
|
||||||
|
PNS_MEANDER_TYPE Type() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetBaseIndex()
|
||||||
|
*
|
||||||
|
* Sets an auxillary index of the segment being meandered in its original PNS_LINE.
|
||||||
|
*/
|
||||||
|
void SetBaseIndex( int aIndex )
|
||||||
|
{
|
||||||
|
m_baseIndex = aIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function BaseIndex()
|
||||||
|
*
|
||||||
|
* @return auxillary index of the segment being meandered in its original PNS_LINE.
|
||||||
|
*/
|
||||||
|
int BaseIndex() const
|
||||||
|
{
|
||||||
|
return m_baseIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Amplitude()
|
||||||
|
*
|
||||||
|
* @return the amplitude of the meander shape.
|
||||||
|
*/
|
||||||
|
int Amplitude() const
|
||||||
|
{
|
||||||
|
return m_amplitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function MakeCorner()
|
||||||
|
*
|
||||||
|
* Creates a dummy meander shape representing a line corner. Used to define
|
||||||
|
* the starts/ends of meandered segments.
|
||||||
|
* @param aP1 corner point of the 1st line
|
||||||
|
* @param aP2 corner point of the 2nd line (if m_dual == true)
|
||||||
|
*/
|
||||||
|
void MakeCorner( VECTOR2I aP1, VECTOR2I aP2 = VECTOR2I( 0, 0 ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Resize()
|
||||||
|
*
|
||||||
|
* Changes the amplitude of the meander shape to aAmpl and recalculates
|
||||||
|
* the resulting line chain.
|
||||||
|
* @param aAmpl new amplitude.
|
||||||
|
*/
|
||||||
|
void Resize( int aAmpl );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Recalculate()
|
||||||
|
*
|
||||||
|
* Recalculates the line chain representing the meanders's shape.
|
||||||
|
*/
|
||||||
|
void Recalculate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function IsDual()
|
||||||
|
*
|
||||||
|
* @return true if the shape represents 2 parallel lines (diff pair).
|
||||||
|
*/
|
||||||
|
bool IsDual() const
|
||||||
|
{
|
||||||
|
return m_dual;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Side()
|
||||||
|
*
|
||||||
|
* @return true if the meander is to the right of its base segment.
|
||||||
|
*/
|
||||||
|
bool Side() const
|
||||||
|
{
|
||||||
|
return m_side;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function End()
|
||||||
|
*
|
||||||
|
* @return end vertex of the base segment of the meander shape.
|
||||||
|
*/
|
||||||
|
VECTOR2I End() const
|
||||||
|
{
|
||||||
|
return m_clippedBaseSeg.B;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CLine()
|
||||||
|
*
|
||||||
|
* @return the line chain representing the shape of the meander.
|
||||||
|
*/
|
||||||
|
const SHAPE_LINE_CHAIN& CLine( int aShape ) const
|
||||||
|
{
|
||||||
|
return m_shapes[aShape];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function MakeEmpty()
|
||||||
|
*
|
||||||
|
* Replaces the meander with straight bypass line(s), effectively
|
||||||
|
* clearing it.
|
||||||
|
*/
|
||||||
|
void MakeEmpty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Fit()
|
||||||
|
*
|
||||||
|
* Attempts to fit a meander of a given type onto a segment, avoiding
|
||||||
|
* collisions with other board features.
|
||||||
|
* @param aType type of meander shape
|
||||||
|
* @param aSeg base segment for meandering
|
||||||
|
* @param aP start point of the meander
|
||||||
|
* @param aSide side of aSeg to put the meander on (true = right)
|
||||||
|
* @return true on success.
|
||||||
|
*/
|
||||||
|
bool Fit( PNS_MEANDER_TYPE aType, const SEG& aSeg, const VECTOR2I& aP, bool aSide );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function BaseSegment()
|
||||||
|
*
|
||||||
|
* Returns the base segment the meadner was fitted to.
|
||||||
|
* @return the base segment.
|
||||||
|
*/
|
||||||
|
const SEG& BaseSegment() const
|
||||||
|
{
|
||||||
|
return m_clippedBaseSeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function BaselineLength()
|
||||||
|
*
|
||||||
|
* @return length of the base segment for the meander (i.e.
|
||||||
|
* the minimum tuned length.
|
||||||
|
*/
|
||||||
|
int BaselineLength() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function MaxTunableLength()
|
||||||
|
*
|
||||||
|
* @return the length of the fitted line chain.
|
||||||
|
*/
|
||||||
|
int MaxTunableLength() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Settings()
|
||||||
|
*
|
||||||
|
* @return the current meandering settings.
|
||||||
|
*/
|
||||||
|
const PNS_MEANDER_SETTINGS& Settings() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Width()
|
||||||
|
*
|
||||||
|
* @return width of the meandered line.
|
||||||
|
*/
|
||||||
|
int Width() const
|
||||||
|
{
|
||||||
|
return m_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetBaselineOffset()
|
||||||
|
*
|
||||||
|
* Sets the parallel offset between the base segment and the meandered
|
||||||
|
* line. Used for dual menaders (diff pair) only.
|
||||||
|
* @param aOffset the offset
|
||||||
|
*/
|
||||||
|
void SetBaselineOffset( int aOffset )
|
||||||
|
{
|
||||||
|
m_baselineOffset = aOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class PNS_MEANDERED_LINE;
|
||||||
|
|
||||||
|
///> starts turtle drawing
|
||||||
|
void start( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir );
|
||||||
|
///> moves turtle forward by aLength
|
||||||
|
void forward( int aLength );
|
||||||
|
///> turns the turtle by aAngle
|
||||||
|
void turn( int aAngle );
|
||||||
|
///> tells the turtle to draw an arc of given radius and turn direction
|
||||||
|
void arc( int aRadius, bool aSide );
|
||||||
|
///> tells the turtle to draw an U-like shape
|
||||||
|
void uShape( int aSides, int aCorner, int aTop );
|
||||||
|
|
||||||
|
///> generates a 90-degree circular arc
|
||||||
|
SHAPE_LINE_CHAIN circleQuad( VECTOR2D aP, VECTOR2D aDir, bool aSide );
|
||||||
|
|
||||||
|
///> reflects a point onto other side of a given segment
|
||||||
|
VECTOR2I reflect( VECTOR2I aP, const SEG& aLine );
|
||||||
|
|
||||||
|
///> produces a meander shape of given type
|
||||||
|
SHAPE_LINE_CHAIN genMeanderShape( VECTOR2D aP, VECTOR2D aDir, bool aSide, PNS_MEANDER_TYPE aType, int aAmpl, int aBaselineOffset = 0 );
|
||||||
|
|
||||||
|
///> recalculates the clipped baseline after the parameters of
|
||||||
|
///> the meander have been changed.
|
||||||
|
void updateBaseSegment();
|
||||||
|
|
||||||
|
///> returns sanitized corner radius value
|
||||||
|
int cornerRadius() const;
|
||||||
|
|
||||||
|
///> returns sanitized spacing value
|
||||||
|
int spacing() const;
|
||||||
|
|
||||||
|
///> the type
|
||||||
|
PNS_MEANDER_TYPE m_type;
|
||||||
|
///> the placer that placed this meander
|
||||||
|
PNS_MEANDER_PLACER_BASE* m_placer;
|
||||||
|
///> dual or single line
|
||||||
|
bool m_dual;
|
||||||
|
///> width of the line
|
||||||
|
int m_width;
|
||||||
|
///> amplitude of the meander
|
||||||
|
int m_amplitude;
|
||||||
|
///> offset wrs the base segment (dual only)
|
||||||
|
int m_baselineOffset;
|
||||||
|
///> first point of the meandered line
|
||||||
|
VECTOR2I m_p0;
|
||||||
|
///> base segment (unclipped)
|
||||||
|
SEG m_baseSeg;
|
||||||
|
///> base segment (clipped)
|
||||||
|
SEG m_clippedBaseSeg;
|
||||||
|
///> side (true = right)
|
||||||
|
bool m_side;
|
||||||
|
///> the actual shapes (0 used for single, both for dual)
|
||||||
|
SHAPE_LINE_CHAIN m_shapes[2];
|
||||||
|
///> index of the meandered segment in the base line
|
||||||
|
int m_baseIndex;
|
||||||
|
///> current turtle direction
|
||||||
|
VECTOR2D m_currentDir;
|
||||||
|
///> current turtle position
|
||||||
|
VECTOR2D m_currentPos;
|
||||||
|
///> the line the turtle is drawing on
|
||||||
|
SHAPE_LINE_CHAIN* m_currentTarget;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_MEANDERED_LINE
|
||||||
|
*
|
||||||
|
* Represents a set of meanders fitted over a single or two lines.
|
||||||
|
*/
|
||||||
|
class PNS_MEANDERED_LINE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PNS_MEANDERED_LINE()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param aPlacer the meander placer instance
|
||||||
|
* @param aIsDual when true, the meanders are generated for two coupled lines
|
||||||
|
*/
|
||||||
|
PNS_MEANDERED_LINE( PNS_MEANDER_PLACER_BASE* aPlacer, bool aIsDual = false ) :
|
||||||
|
m_placer( aPlacer ),
|
||||||
|
m_dual( aIsDual )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function AddCorner()
|
||||||
|
*
|
||||||
|
* Creates a dummy meander shape representing a line corner. Used to define
|
||||||
|
* the starts/ends of meandered segments.
|
||||||
|
* @param aA corner point of the 1st line
|
||||||
|
* @param aB corner point of the 2nd line (if m_dual == true)
|
||||||
|
*/
|
||||||
|
void AddCorner( const VECTOR2I& aA, const VECTOR2I& aB = VECTOR2I( 0, 0 ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function AddMeander()
|
||||||
|
*
|
||||||
|
* Adds a new meander shape the the meandered line.
|
||||||
|
* @param aShape the meander shape to add
|
||||||
|
*/
|
||||||
|
void AddMeander( PNS_MEANDER_SHAPE* aShape );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Clear()
|
||||||
|
*
|
||||||
|
* Clears the line geometry, removing all corners and meanders.
|
||||||
|
*/
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetWidth()
|
||||||
|
*
|
||||||
|
* Sets the line width.
|
||||||
|
*/
|
||||||
|
void SetWidth( int aWidth )
|
||||||
|
{
|
||||||
|
m_width = aWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function MeanderSegment()
|
||||||
|
*
|
||||||
|
* Fits maximum amplitude meanders on a given segment and adds to the
|
||||||
|
* current line.
|
||||||
|
* @param aSeg the base segment to meander
|
||||||
|
* @param aBaseIndex index of the base segment in the original line
|
||||||
|
*/
|
||||||
|
void MeanderSegment( const SEG& aSeg, int aBaseIndex = 0 );
|
||||||
|
|
||||||
|
/// @copydoc PNS_MEANDER_SHAPE::SetBaselineOffset()
|
||||||
|
void SetBaselineOffset( int aOffset )
|
||||||
|
{
|
||||||
|
m_baselineOffset = aOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Meanders()
|
||||||
|
*
|
||||||
|
* @return set of meander shapes for this line
|
||||||
|
*/
|
||||||
|
std::vector<PNS_MEANDER_SHAPE*>& Meanders()
|
||||||
|
{
|
||||||
|
return m_meanders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CheckSelfIntersections()
|
||||||
|
*
|
||||||
|
* Checks if the given shape is intersecting with any other meander in
|
||||||
|
* the current line.
|
||||||
|
* @param aShape the shape to check
|
||||||
|
* @param aClearance clearance value
|
||||||
|
* @return true, if the meander shape is not colliding
|
||||||
|
*/
|
||||||
|
bool CheckSelfIntersections ( PNS_MEANDER_SHAPE* aShape, int aClearance );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Settings()
|
||||||
|
*
|
||||||
|
* @return the current meandering settings.
|
||||||
|
*/
|
||||||
|
const PNS_MEANDER_SETTINGS& Settings() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VECTOR2I m_last;
|
||||||
|
|
||||||
|
PNS_MEANDER_PLACER_BASE* m_placer;
|
||||||
|
std::vector<PNS_MEANDER_SHAPE*> m_meanders;
|
||||||
|
|
||||||
|
bool m_dual;
|
||||||
|
int m_width;
|
||||||
|
int m_baselineOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __PNS_MEANDER_H
|
|
@ -0,0 +1,269 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
#include <base_units.h> // God forgive me doing this...
|
||||||
|
#include <colors.h>
|
||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#include "pns_node.h"
|
||||||
|
#include "pns_itemset.h"
|
||||||
|
#include "pns_topology.h"
|
||||||
|
#include "pns_meander_placer.h"
|
||||||
|
#include "pns_router.h"
|
||||||
|
|
||||||
|
|
||||||
|
PNS_MEANDER_PLACER::PNS_MEANDER_PLACER( PNS_ROUTER* aRouter ) :
|
||||||
|
PNS_MEANDER_PLACER_BASE( aRouter )
|
||||||
|
{
|
||||||
|
m_world = NULL;
|
||||||
|
m_currentNode = NULL;
|
||||||
|
m_originLine = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_MEANDER_PLACER::~PNS_MEANDER_PLACER()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_NODE* PNS_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const
|
||||||
|
{
|
||||||
|
if( !m_currentNode )
|
||||||
|
return m_world;
|
||||||
|
|
||||||
|
return m_currentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||||
|
{
|
||||||
|
VECTOR2I p;
|
||||||
|
|
||||||
|
if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) )
|
||||||
|
{
|
||||||
|
Router()->SetFailureReason( _( "Please select a track whose length you want to tune." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_initialSegment = static_cast<PNS_SEGMENT*>( aStartItem );
|
||||||
|
|
||||||
|
p = m_initialSegment->Seg().NearestPoint( aP );
|
||||||
|
|
||||||
|
m_originLine = NULL;
|
||||||
|
m_currentNode = NULL;
|
||||||
|
m_currentStart = p;
|
||||||
|
|
||||||
|
m_world = Router()->GetWorld()->Branch();
|
||||||
|
m_originLine = m_world->AssembleLine( m_initialSegment );
|
||||||
|
|
||||||
|
PNS_TOPOLOGY topo( m_world );
|
||||||
|
m_tunedPath = topo.AssembleTrivialPath( m_initialSegment );
|
||||||
|
|
||||||
|
m_world->Remove( m_originLine );
|
||||||
|
|
||||||
|
m_currentWidth = m_originLine->Width();
|
||||||
|
m_currentEnd = VECTOR2I( 0, 0 );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_MEANDER_PLACER::origPathLength() const
|
||||||
|
{
|
||||||
|
int total = 0;
|
||||||
|
BOOST_FOREACH( const PNS_ITEM* item, m_tunedPath.CItems() )
|
||||||
|
{
|
||||||
|
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||||
|
{
|
||||||
|
total += l->CLine().Length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||||
|
{
|
||||||
|
return doMove( aP, aEndItem, m_settings.m_targetLength );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_MEANDER_PLACER::doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTargetLength )
|
||||||
|
{
|
||||||
|
SHAPE_LINE_CHAIN pre, tuned, post;
|
||||||
|
|
||||||
|
if( m_currentNode )
|
||||||
|
delete m_currentNode;
|
||||||
|
|
||||||
|
m_currentNode = m_world->Branch();
|
||||||
|
|
||||||
|
cutTunedLine( m_originLine->CLine(), m_currentStart, aP, pre, tuned, post );
|
||||||
|
|
||||||
|
m_result = PNS_MEANDERED_LINE( this, false );
|
||||||
|
m_result.SetWidth( m_originLine->Width() );
|
||||||
|
m_result.SetBaselineOffset( 0 );
|
||||||
|
|
||||||
|
for( int i = 0; i < tuned.SegmentCount(); i++ )
|
||||||
|
{
|
||||||
|
const SEG s = tuned.CSegment( i );
|
||||||
|
m_result.AddCorner( s.A );
|
||||||
|
m_result.MeanderSegment( s );
|
||||||
|
m_result.AddCorner( s.B );
|
||||||
|
}
|
||||||
|
|
||||||
|
int lineLen = origPathLength();
|
||||||
|
|
||||||
|
m_lastLength = lineLen;
|
||||||
|
m_lastStatus = TUNED;
|
||||||
|
|
||||||
|
if( compareWithTolerance( lineLen, aTargetLength, m_settings.m_lengthTolerance ) > 0 )
|
||||||
|
{
|
||||||
|
m_lastStatus = TOO_LONG;
|
||||||
|
} else {
|
||||||
|
m_lastLength = lineLen - tuned.Length();
|
||||||
|
tuneLineLength( m_result, aTargetLength - lineLen );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH ( const PNS_ITEM* item, m_tunedPath.CItems() )
|
||||||
|
{
|
||||||
|
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||||
|
{
|
||||||
|
Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_lastStatus != TOO_LONG )
|
||||||
|
{
|
||||||
|
tuned.Clear();
|
||||||
|
|
||||||
|
BOOST_FOREACH( PNS_MEANDER_SHAPE* m, m_result.Meanders() )
|
||||||
|
{
|
||||||
|
if( m->Type() != MT_EMPTY )
|
||||||
|
{
|
||||||
|
tuned.Append ( m->CLine( 0 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lastLength += tuned.Length();
|
||||||
|
|
||||||
|
int comp = compareWithTolerance( m_lastLength - aTargetLength, 0, m_settings.m_lengthTolerance );
|
||||||
|
|
||||||
|
if( comp > 0 )
|
||||||
|
m_lastStatus = TOO_LONG;
|
||||||
|
else if( comp < 0 )
|
||||||
|
m_lastStatus = TOO_SHORT;
|
||||||
|
else
|
||||||
|
m_lastStatus = TUNED;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_finalShape.Clear();
|
||||||
|
m_finalShape.Append( pre );
|
||||||
|
m_finalShape.Append( tuned );
|
||||||
|
m_finalShape.Append( post );
|
||||||
|
m_finalShape.Simplify();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||||
|
{
|
||||||
|
m_currentTrace = PNS_LINE( *m_originLine, m_finalShape );
|
||||||
|
m_currentNode->Add( &m_currentTrace );
|
||||||
|
|
||||||
|
Router()->CommitRouting( m_currentNode );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_MEANDER_PLACER::CheckFit( PNS_MEANDER_SHAPE* aShape )
|
||||||
|
{
|
||||||
|
PNS_LINE l( *m_originLine, aShape->CLine( 0 ) );
|
||||||
|
|
||||||
|
if( m_currentNode->CheckColliding( &l ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int w = aShape->Width();
|
||||||
|
int clearance = w + m_settings.m_spacing;
|
||||||
|
|
||||||
|
return m_result.CheckSelfIntersections( aShape, clearance );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const PNS_ITEMSET PNS_MEANDER_PLACER::Traces()
|
||||||
|
{
|
||||||
|
m_currentTrace = PNS_LINE( *m_originLine, m_finalShape );
|
||||||
|
return PNS_ITEMSET( &m_currentTrace );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const VECTOR2I& PNS_MEANDER_PLACER::CurrentEnd() const
|
||||||
|
{
|
||||||
|
return m_currentEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_MEANDER_PLACER::CurrentNet() const
|
||||||
|
{
|
||||||
|
return m_initialSegment->Net();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_MEANDER_PLACER::CurrentLayer() const
|
||||||
|
{
|
||||||
|
return m_initialSegment->Layers().Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const wxString PNS_MEANDER_PLACER::TuningInfo() const
|
||||||
|
{
|
||||||
|
wxString status;
|
||||||
|
|
||||||
|
switch ( m_lastStatus )
|
||||||
|
{
|
||||||
|
case TOO_LONG:
|
||||||
|
status = _( "Too long: " );
|
||||||
|
break;
|
||||||
|
case TOO_SHORT:
|
||||||
|
status = _( "Too short: " );
|
||||||
|
break;
|
||||||
|
case TUNED:
|
||||||
|
status = _( "Tuned: " );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return _( "?" );
|
||||||
|
}
|
||||||
|
|
||||||
|
status += LengthDoubleToString( (double) m_lastLength, false );
|
||||||
|
status += "/";
|
||||||
|
status += LengthDoubleToString( (double) m_settings.m_targetLength, false );
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_MEANDER_PLACER::TUNING_STATUS PNS_MEANDER_PLACER::TuningStatus() const
|
||||||
|
{
|
||||||
|
return m_lastStatus;
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2014 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PNS_MEANDER_PLACER_H
|
||||||
|
#define __PNS_MEANDER_PLACER_H
|
||||||
|
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
|
||||||
|
#include <geometry/shape.h>
|
||||||
|
#include <geometry/shape_line_chain.h>
|
||||||
|
|
||||||
|
#include "pns_node.h"
|
||||||
|
#include "pns_via.h"
|
||||||
|
#include "pns_line.h"
|
||||||
|
#include "pns_placement_algo.h"
|
||||||
|
#include "pns_meander.h"
|
||||||
|
#include "pns_meander_placer_base.h"
|
||||||
|
|
||||||
|
class PNS_ROUTER;
|
||||||
|
class PNS_SHOVE;
|
||||||
|
class PNS_OPTIMIZER;
|
||||||
|
class PNS_ROUTER_BASE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_MEANDER_PLACER
|
||||||
|
*
|
||||||
|
* Single track length matching/meandering tool.
|
||||||
|
*/
|
||||||
|
class PNS_MEANDER_PLACER : public PNS_MEANDER_PLACER_BASE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
PNS_MEANDER_PLACER( PNS_ROUTER* aRouter );
|
||||||
|
virtual ~PNS_MEANDER_PLACER();
|
||||||
|
|
||||||
|
/// @copydoc PNS_PLACEMENT_ALGO::Start()
|
||||||
|
virtual bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem );
|
||||||
|
|
||||||
|
/// @copydoc PNS_PLACEMENT_ALGO::Move()
|
||||||
|
virtual bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem );
|
||||||
|
|
||||||
|
/// @copydoc PNS_PLACEMENT_ALGO::FixRoute()
|
||||||
|
virtual bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem );
|
||||||
|
|
||||||
|
/// @copydoc PNS_PLACEMENT_ALGO::CurrentNode()
|
||||||
|
PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const;
|
||||||
|
|
||||||
|
/// @copydoc PNS_PLACEMENT_ALGO::Traces()
|
||||||
|
const PNS_ITEMSET Traces();
|
||||||
|
|
||||||
|
/// @copydoc PNS_PLACEMENT_ALGO::CurrentEnd()
|
||||||
|
const VECTOR2I& CurrentEnd() const;
|
||||||
|
|
||||||
|
/// @copydoc PNS_PLACEMENT_ALGO::CurrentNet()
|
||||||
|
int CurrentNet() const;
|
||||||
|
|
||||||
|
/// @copydoc PNS_PLACEMENT_ALGO::CurrentLayer()
|
||||||
|
int CurrentLayer() const;
|
||||||
|
|
||||||
|
/// @copydoc PNS_MEANDER_PLACER_BASE::TuningInfo()
|
||||||
|
virtual const wxString TuningInfo() const;
|
||||||
|
|
||||||
|
/// @copydoc PNS_MEANDER_PLACER_BASE::TuningStatus()
|
||||||
|
virtual TUNING_STATUS TuningStatus() const;
|
||||||
|
|
||||||
|
/// @copydoc PNS_MEANDER_PLACER_BASE::CheckFit()
|
||||||
|
bool CheckFit ( PNS_MEANDER_SHAPE* aShape );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTargetLength );
|
||||||
|
|
||||||
|
void setWorld( PNS_NODE* aWorld );
|
||||||
|
|
||||||
|
virtual int origPathLength() const;
|
||||||
|
|
||||||
|
///> pointer to world to search colliding items
|
||||||
|
PNS_NODE* m_world;
|
||||||
|
|
||||||
|
///> current routing start point (end of tail, beginning of head)
|
||||||
|
VECTOR2I m_currentStart;
|
||||||
|
|
||||||
|
///> Current world state
|
||||||
|
PNS_NODE* m_currentNode;
|
||||||
|
|
||||||
|
PNS_LINE* m_originLine;
|
||||||
|
PNS_LINE m_currentTrace;
|
||||||
|
PNS_ITEMSET m_tunedPath;
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN m_finalShape;
|
||||||
|
PNS_MEANDERED_LINE m_result;
|
||||||
|
PNS_SEGMENT* m_initialSegment;
|
||||||
|
|
||||||
|
int m_lastLength;
|
||||||
|
TUNING_STATUS m_lastStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __PNS_MEANDER_PLACER_H
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pns_router.h"
|
||||||
|
#include "pns_meander.h"
|
||||||
|
#include "pns_meander_placer_base.h"
|
||||||
|
|
||||||
|
PNS_MEANDER_PLACER_BASE::PNS_MEANDER_PLACER_BASE( PNS_ROUTER* aRouter ) :
|
||||||
|
PNS_PLACEMENT_ALGO( aRouter )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_MEANDER_PLACER_BASE::~PNS_MEANDER_PLACER_BASE()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_PLACER_BASE::AmplitudeStep( int aSign )
|
||||||
|
{
|
||||||
|
int a = m_settings.m_maxAmplitude + aSign * m_settings.m_step;
|
||||||
|
a = std::max( a, m_settings.m_minAmplitude );
|
||||||
|
|
||||||
|
m_settings.m_maxAmplitude = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_PLACER_BASE::SpacingStep( int aSign )
|
||||||
|
{
|
||||||
|
int s = m_settings.m_spacing + aSign * m_settings.m_step;
|
||||||
|
s = std::max( s, 2 * m_currentWidth );
|
||||||
|
|
||||||
|
m_settings.m_spacing = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_PLACER_BASE::UpdateSettings( const PNS_MEANDER_SETTINGS& aSettings )
|
||||||
|
{
|
||||||
|
m_settings = aSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_PLACER_BASE::cutTunedLine( const SHAPE_LINE_CHAIN& aOrigin,
|
||||||
|
const VECTOR2I& aTuneStart,
|
||||||
|
const VECTOR2I& aCursorPos,
|
||||||
|
SHAPE_LINE_CHAIN& aPre,
|
||||||
|
SHAPE_LINE_CHAIN& aTuned,
|
||||||
|
SHAPE_LINE_CHAIN& aPost )
|
||||||
|
{
|
||||||
|
VECTOR2I n = aOrigin.NearestPoint( aCursorPos );
|
||||||
|
VECTOR2I m = aOrigin.NearestPoint( aTuneStart );
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN l( aOrigin );
|
||||||
|
l.Split( n );
|
||||||
|
l.Split( m );
|
||||||
|
|
||||||
|
int i_start = l.Find( m );
|
||||||
|
int i_end = l.Find( n );
|
||||||
|
|
||||||
|
if( i_start > i_end )
|
||||||
|
{
|
||||||
|
l = l.Reverse();
|
||||||
|
i_start = l.Find( m );
|
||||||
|
i_end = l.Find( n );
|
||||||
|
}
|
||||||
|
|
||||||
|
aPre = l.Slice( 0, i_start );
|
||||||
|
aPost = l.Slice( i_end, -1 );
|
||||||
|
aTuned = l.Slice( i_start, i_end );
|
||||||
|
aTuned.Simplify();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_MEANDER_PLACER_BASE::tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aElongation )
|
||||||
|
{
|
||||||
|
int remaining = aElongation;
|
||||||
|
bool finished = false;
|
||||||
|
|
||||||
|
BOOST_FOREACH( PNS_MEANDER_SHAPE* m, aTuned.Meanders() )
|
||||||
|
{
|
||||||
|
if( m->Type() != MT_CORNER )
|
||||||
|
{
|
||||||
|
if( remaining >= 0 )
|
||||||
|
remaining -= m->MaxTunableLength() - m->BaselineLength();
|
||||||
|
|
||||||
|
if( remaining < 0 )
|
||||||
|
{
|
||||||
|
if( !finished )
|
||||||
|
{
|
||||||
|
PNS_MEANDER_TYPE newType;
|
||||||
|
|
||||||
|
if( m->Type() == MT_START || m->Type() == MT_SINGLE )
|
||||||
|
newType = MT_SINGLE;
|
||||||
|
else
|
||||||
|
newType = MT_FINISH;
|
||||||
|
|
||||||
|
m->SetType( newType );
|
||||||
|
m->Recalculate();
|
||||||
|
|
||||||
|
finished = true;
|
||||||
|
} else {
|
||||||
|
m->MakeEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining = aElongation;
|
||||||
|
int meanderCount = 0;
|
||||||
|
|
||||||
|
BOOST_FOREACH(PNS_MEANDER_SHAPE* m, aTuned.Meanders())
|
||||||
|
{
|
||||||
|
if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY )
|
||||||
|
{
|
||||||
|
if(remaining >= 0)
|
||||||
|
{
|
||||||
|
remaining -= m->MaxTunableLength() - m->BaselineLength();
|
||||||
|
meanderCount ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int balance = 0;
|
||||||
|
|
||||||
|
if( meanderCount )
|
||||||
|
balance = -remaining / meanderCount;
|
||||||
|
|
||||||
|
if( balance >= 0 )
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( PNS_MEANDER_SHAPE* m, aTuned.Meanders() )
|
||||||
|
{
|
||||||
|
if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY )
|
||||||
|
{
|
||||||
|
m->Resize( std::max( m->Amplitude() - balance / 2, m_settings.m_minAmplitude ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const PNS_MEANDER_SETTINGS& PNS_MEANDER_PLACER_BASE::MeanderSettings() const
|
||||||
|
{
|
||||||
|
return m_settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_MEANDER_PLACER_BASE::compareWithTolerance( int aValue, int aExpected, int aTolerance ) const
|
||||||
|
{
|
||||||
|
if( aValue < aExpected - aTolerance )
|
||||||
|
return -1;
|
||||||
|
else if( aValue > aExpected + aTolerance )
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PNS_MEANDER_PLACER_BASE_H
|
||||||
|
#define __PNS_MEANDER_PLACER_BASE_H
|
||||||
|
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
|
||||||
|
#include <geometry/shape.h>
|
||||||
|
#include <geometry/shape_line_chain.h>
|
||||||
|
|
||||||
|
#include "pns_node.h"
|
||||||
|
#include "pns_via.h"
|
||||||
|
#include "pns_line.h"
|
||||||
|
#include "pns_placement_algo.h"
|
||||||
|
#include "pns_meander.h"
|
||||||
|
|
||||||
|
class PNS_ROUTER;
|
||||||
|
class PNS_SHOVE;
|
||||||
|
class PNS_OPTIMIZER;
|
||||||
|
class PNS_ROUTER_BASE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_MEANDER_PLACER_BASE
|
||||||
|
*
|
||||||
|
* Base class for Single trace & Differenial pair meandering tools, as
|
||||||
|
* both of them share a lot of code.
|
||||||
|
*/
|
||||||
|
class PNS_MEANDER_PLACER_BASE : public PNS_PLACEMENT_ALGO
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
///> Result of the length tuning operation
|
||||||
|
enum TUNING_STATUS {
|
||||||
|
TOO_SHORT = 0,
|
||||||
|
TOO_LONG,
|
||||||
|
TUNED
|
||||||
|
};
|
||||||
|
|
||||||
|
PNS_MEANDER_PLACER_BASE( PNS_ROUTER* aRouter );
|
||||||
|
virtual ~PNS_MEANDER_PLACER_BASE();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TuningInfo()
|
||||||
|
*
|
||||||
|
* Returns a string describing the status and length of the
|
||||||
|
* tuned traces.
|
||||||
|
*/
|
||||||
|
virtual const wxString TuningInfo() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TuningStatus()
|
||||||
|
*
|
||||||
|
* Returns the tuning status (too short, too long, etc.)
|
||||||
|
* of the trace(s) being tuned.
|
||||||
|
*/
|
||||||
|
virtual TUNING_STATUS TuningStatus() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function AmplitudeStep()
|
||||||
|
*
|
||||||
|
* Increases/decreases the current meandering amplitude by one step.
|
||||||
|
* @param aSign direction (negative = decrease, positive = increase).
|
||||||
|
*/
|
||||||
|
virtual void AmplitudeStep( int aSign );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SpacingStep()
|
||||||
|
*
|
||||||
|
* Increases/decreases the current meandering spcing by one step.
|
||||||
|
* @param aSign direction (negative = decrease, positive = increase).
|
||||||
|
*/
|
||||||
|
virtual void SpacingStep( int aSign );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function MeanderSettings()
|
||||||
|
*
|
||||||
|
* Returns the current meandering configuration.
|
||||||
|
* @return the settings
|
||||||
|
*/
|
||||||
|
virtual const PNS_MEANDER_SETTINGS& MeanderSettings() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function UpdateSettings()
|
||||||
|
*
|
||||||
|
* Sets the current meandering configuration.
|
||||||
|
* @param aSettings the settings
|
||||||
|
*/
|
||||||
|
virtual void UpdateSettings( const PNS_MEANDER_SETTINGS& aSettings);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CheckFit()
|
||||||
|
*
|
||||||
|
* Checks if it's ok to place the shape aShape (i.e.
|
||||||
|
* if it doesn't cause DRC violations or collide with
|
||||||
|
* other meanders).
|
||||||
|
* @param aShape the shape to check
|
||||||
|
* @return true if the shape fits
|
||||||
|
*/
|
||||||
|
virtual bool CheckFit( PNS_MEANDER_SHAPE* aShape )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function cutTunedLine()
|
||||||
|
*
|
||||||
|
* Extracts the part of a track to be meandered, depending on the
|
||||||
|
* starting point and the cursor position.
|
||||||
|
* @param aOrigin the original line
|
||||||
|
* @param aTuneStart point where we start meandering (start click coorinates)
|
||||||
|
* @param aCursorPos current cursor position
|
||||||
|
* @param aPre part before the beginning of meanders
|
||||||
|
* @param aTuned part to be meandered
|
||||||
|
* @param aPost part after the end of meanders
|
||||||
|
*/
|
||||||
|
void cutTunedLine( const SHAPE_LINE_CHAIN& aOrigin,
|
||||||
|
const VECTOR2I& aTuneStart,
|
||||||
|
const VECTOR2I& aCursorPos,
|
||||||
|
SHAPE_LINE_CHAIN& aPre,
|
||||||
|
SHAPE_LINE_CHAIN& aTuned,
|
||||||
|
SHAPE_LINE_CHAIN& aPost );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function tuneLineLength()
|
||||||
|
*
|
||||||
|
* Takes a set of meanders in aTuned and tunes their length to
|
||||||
|
* extend the original line length by aElongation.
|
||||||
|
*/
|
||||||
|
void tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aElongation );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function compareWithTolerance()
|
||||||
|
*
|
||||||
|
* Compares aValue against aExpected with given tolerance.
|
||||||
|
*/
|
||||||
|
int compareWithTolerance ( int aValue, int aExpected, int aTolerance = 0 ) const;
|
||||||
|
|
||||||
|
///> width of the meandered trace(s)
|
||||||
|
int m_currentWidth;
|
||||||
|
///> meandering settings
|
||||||
|
PNS_MEANDER_SETTINGS m_settings;
|
||||||
|
///> current end point
|
||||||
|
VECTOR2I m_currentEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __PNS_MEANDER_PLACER_BASE_H
|
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
#include <base_units.h> // God forgive me doing this...
|
||||||
|
#include <colors.h>
|
||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#include "pns_node.h"
|
||||||
|
#include "pns_itemset.h"
|
||||||
|
#include "pns_topology.h"
|
||||||
|
#include "pns_meander_skew_placer.h"
|
||||||
|
|
||||||
|
#include "pns_router.h"
|
||||||
|
|
||||||
|
|
||||||
|
PNS_MEANDER_SKEW_PLACER::PNS_MEANDER_SKEW_PLACER ( PNS_ROUTER* aRouter ) :
|
||||||
|
PNS_MEANDER_PLACER ( aRouter )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_MEANDER_SKEW_PLACER::~PNS_MEANDER_SKEW_PLACER( )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||||
|
{
|
||||||
|
VECTOR2I p;
|
||||||
|
|
||||||
|
if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) )
|
||||||
|
{
|
||||||
|
Router()->SetFailureReason( _( "Please select a differential pair trace you want to tune." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_initialSegment = static_cast<PNS_SEGMENT*>( aStartItem );
|
||||||
|
|
||||||
|
p = m_initialSegment->Seg().NearestPoint( aP );
|
||||||
|
|
||||||
|
m_originLine = NULL;
|
||||||
|
m_currentNode = NULL;
|
||||||
|
m_currentStart = p;
|
||||||
|
|
||||||
|
m_world = Router()->GetWorld( )->Branch();
|
||||||
|
m_originLine = m_world->AssembleLine( m_initialSegment );
|
||||||
|
|
||||||
|
PNS_TOPOLOGY topo( m_world );
|
||||||
|
m_tunedPath = topo.AssembleTrivialPath( m_initialSegment );
|
||||||
|
|
||||||
|
if( !topo.AssembleDiffPair ( m_initialSegment, m_originPair ) )
|
||||||
|
{
|
||||||
|
Router()->SetFailureReason( _( "Unable to find complementary differential pair "
|
||||||
|
"net for skew tuning. Make sure the names of the nets belonging "
|
||||||
|
"to a differential pair end with either _N/_P or +/-." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_originPair.SetGap ( Router()->Sizes().DiffPairGap() );
|
||||||
|
|
||||||
|
if( !m_originPair.PLine().SegmentCount() ||
|
||||||
|
!m_originPair.NLine().SegmentCount() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_tunedPathP = topo.AssembleTrivialPath ( m_originPair.PLine().GetLink( 0 ) );
|
||||||
|
m_tunedPathN = topo.AssembleTrivialPath ( m_originPair.NLine().GetLink( 0 ) );
|
||||||
|
|
||||||
|
m_world->Remove( m_originLine );
|
||||||
|
|
||||||
|
m_currentWidth = m_originLine->Width( );
|
||||||
|
m_currentEnd = VECTOR2I( 0, 0 );
|
||||||
|
|
||||||
|
if ( m_originPair.PLine().Net () == m_originLine->Net() )
|
||||||
|
m_coupledLength = itemsetLength ( m_tunedPathN );
|
||||||
|
else
|
||||||
|
m_coupledLength = itemsetLength ( m_tunedPathP );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_MEANDER_SKEW_PLACER::origPathLength( ) const
|
||||||
|
{
|
||||||
|
return itemsetLength ( m_tunedPath );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_MEANDER_SKEW_PLACER::itemsetLength( const PNS_ITEMSET& aSet ) const
|
||||||
|
{
|
||||||
|
int total = 0;
|
||||||
|
BOOST_FOREACH( const PNS_ITEM* item, aSet.CItems() )
|
||||||
|
{
|
||||||
|
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||||
|
{
|
||||||
|
total += l->CLine().Length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_MEANDER_SKEW_PLACER::currentSkew() const
|
||||||
|
{
|
||||||
|
return m_lastLength - m_coupledLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_MEANDER_SKEW_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||||
|
{
|
||||||
|
return doMove( aP, aEndItem, m_coupledLength + m_settings.m_targetSkew );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const wxString PNS_MEANDER_SKEW_PLACER::TuningInfo() const
|
||||||
|
{
|
||||||
|
wxString status;
|
||||||
|
|
||||||
|
switch( m_lastStatus )
|
||||||
|
{
|
||||||
|
case TOO_LONG:
|
||||||
|
status = _( "Too long: skew " );
|
||||||
|
break;
|
||||||
|
case TOO_SHORT:
|
||||||
|
status = _( "Too short: skew " );
|
||||||
|
break;
|
||||||
|
case TUNED:
|
||||||
|
status = _( "Tuned: skew " );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return _( "?" );
|
||||||
|
}
|
||||||
|
|
||||||
|
status += LengthDoubleToString( (double) m_lastLength - m_coupledLength, false );
|
||||||
|
status += "/";
|
||||||
|
status += LengthDoubleToString( (double) m_settings.m_targetSkew, false );
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PNS_MEANDER_SKEW_PLACER_H
|
||||||
|
#define __PNS_MEANDER_SKEW_PLACER_H
|
||||||
|
|
||||||
|
#include "pns_meander_placer.h"
|
||||||
|
#include "pns_diff_pair.h"
|
||||||
|
|
||||||
|
class PNS_ROUTER;
|
||||||
|
class PNS_SHOVE;
|
||||||
|
class PNS_OPTIMIZER;
|
||||||
|
class PNS_ROUTER_BASE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_MEANDER_SKEW_PLACER
|
||||||
|
*
|
||||||
|
* Differential pair skew adjustment algorithm.
|
||||||
|
*/
|
||||||
|
class PNS_MEANDER_SKEW_PLACER : public PNS_MEANDER_PLACER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PNS_MEANDER_SKEW_PLACER( PNS_ROUTER* aRouter );
|
||||||
|
~PNS_MEANDER_SKEW_PLACER();
|
||||||
|
|
||||||
|
/// @copydoc PNS_PLACEMENT_ALGO::Start()
|
||||||
|
bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem );
|
||||||
|
|
||||||
|
/// @copydoc PNS_PLACEMENT_ALGO::Move()
|
||||||
|
bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem );
|
||||||
|
|
||||||
|
/// @copydoc PNS_MEANDER_PLACER_BASE::TuningInfo()
|
||||||
|
const wxString TuningInfo() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int currentSkew( ) const;
|
||||||
|
int itemsetLength( const PNS_ITEMSET& aSet ) const;
|
||||||
|
|
||||||
|
int origPathLength () const;
|
||||||
|
|
||||||
|
PNS_DIFF_PAIR m_originPair;
|
||||||
|
PNS_ITEMSET m_tunedPath, m_tunedPathP, m_tunedPathN;
|
||||||
|
|
||||||
|
int m_coupledLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __PNS_MEANDER_SKEW_PLACER_H
|
|
@ -53,6 +53,7 @@ PNS_NODE::PNS_NODE()
|
||||||
m_parent = NULL;
|
m_parent = NULL;
|
||||||
m_maxClearance = 800000; // fixme: depends on how thick traces are.
|
m_maxClearance = 800000; // fixme: depends on how thick traces are.
|
||||||
m_index = new PNS_INDEX;
|
m_index = new PNS_INDEX;
|
||||||
|
m_collisionFilter = NULL;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
allocNodes.insert( this );
|
allocNodes.insert( this );
|
||||||
|
@ -109,6 +110,7 @@ PNS_NODE* PNS_NODE::Branch()
|
||||||
child->m_parent = this;
|
child->m_parent = this;
|
||||||
child->m_clearanceFunctor = m_clearanceFunctor;
|
child->m_clearanceFunctor = m_clearanceFunctor;
|
||||||
child->m_root = isRoot() ? this : m_root;
|
child->m_root = isRoot() ? this : m_root;
|
||||||
|
child->m_collisionFilter = m_collisionFilter;
|
||||||
|
|
||||||
// immmediate offspring of the root branch needs not copy anything.
|
// immmediate offspring of the root branch needs not copy anything.
|
||||||
// For the rest, deep-copy joints, overridden item map and pointers
|
// For the rest, deep-copy joints, overridden item map and pointers
|
||||||
|
@ -211,6 +213,9 @@ struct PNS_NODE::OBSTACLE_VISITOR
|
||||||
|
|
||||||
int clearance = m_extraClearance + m_node->GetClearance( aItem, m_item );
|
int clearance = m_extraClearance + m_node->GetClearance( aItem, m_item );
|
||||||
|
|
||||||
|
if( m_node->m_collisionFilter && (*m_node->m_collisionFilter)(aItem, m_item))
|
||||||
|
return true;
|
||||||
|
|
||||||
if( aItem->Kind() == PNS_ITEM::LINE )
|
if( aItem->Kind() == PNS_ITEM::LINE )
|
||||||
clearance += static_cast<PNS_LINE *>(aItem)->Width() / 2;
|
clearance += static_cast<PNS_LINE *>(aItem)->Width() / 2;
|
||||||
|
|
||||||
|
@ -220,6 +225,7 @@ struct PNS_NODE::OBSTACLE_VISITOR
|
||||||
PNS_OBSTACLE obs;
|
PNS_OBSTACLE obs;
|
||||||
|
|
||||||
obs.m_item = aItem;
|
obs.m_item = aItem;
|
||||||
|
obs.m_head = m_item;
|
||||||
m_tab.push_back( obs );
|
m_tab.push_back( obs );
|
||||||
|
|
||||||
m_matchCount++;
|
m_matchCount++;
|
||||||
|
@ -414,10 +420,14 @@ PNS_NODE::OPT_OBSTACLE PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB, int aKindMask )
|
bool PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB, int aKindMask, int aForceClearance )
|
||||||
{
|
{
|
||||||
assert( aItemB );
|
assert( aItemB );
|
||||||
int clearance = GetClearance( aItemA, aItemB );
|
int clearance;
|
||||||
|
if( aForceClearance >= 0 )
|
||||||
|
clearance = aForceClearance;
|
||||||
|
else
|
||||||
|
clearance = GetClearance( aItemA, aItemB );
|
||||||
|
|
||||||
// fixme: refactor
|
// fixme: refactor
|
||||||
if( aItemA->Kind() == PNS_ITEM::LINE )
|
if( aItemA->Kind() == PNS_ITEM::LINE )
|
||||||
|
@ -609,13 +619,13 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
|
||||||
{
|
{
|
||||||
std::vector<PNS_SEGMENT*>* segRefs = aLine->LinkedSegments();
|
std::vector<PNS_SEGMENT*>* segRefs = aLine->LinkedSegments();
|
||||||
|
|
||||||
if(! aLine->SegmentCount() )
|
if( !aLine->SegmentCount() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
assert (segRefs != NULL);
|
assert( segRefs != NULL );
|
||||||
assert (aLine->Owner());
|
assert( aLine->Owner() );
|
||||||
|
|
||||||
if ( (int) segRefs->size() != aLine->SegmentCount() )
|
if( (int) segRefs->size() != aLine->SegmentCount() )
|
||||||
{
|
{
|
||||||
//printf("******weird deletion: segrefs %d segcount %d hasloops %d\n", segRefs->size(), aLine->SegmentCount(), aLine->HasLoops());
|
//printf("******weird deletion: segrefs %d segcount %d hasloops %d\n", segRefs->size(), aLine->SegmentCount(), aLine->HasLoops());
|
||||||
}
|
}
|
||||||
|
@ -714,6 +724,12 @@ void PNS_NODE::Remove( PNS_ITEM* aItem )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_NODE::Remove( PNS_LINE& aLine )
|
||||||
|
{
|
||||||
|
removeLine( &aLine );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_NODE::followLine( PNS_SEGMENT* aCurrent, bool aScanDirection, int& aPos,
|
void PNS_NODE::followLine( PNS_SEGMENT* aCurrent, bool aScanDirection, int& aPos,
|
||||||
int aLimit, VECTOR2I* aCorners, PNS_SEGMENT** aSegments, bool& aGuardHit )
|
int aLimit, VECTOR2I* aCorners, PNS_SEGMENT** aSegments, bool& aGuardHit )
|
||||||
{
|
{
|
||||||
|
@ -748,14 +764,14 @@ void PNS_NODE::followLine( PNS_SEGMENT* aCurrent, bool aScanDirection, int& aPos
|
||||||
aCurrent = jt->NextSegment( aCurrent );
|
aCurrent = jt->NextSegment( aCurrent );
|
||||||
|
|
||||||
prevReversed =
|
prevReversed =
|
||||||
( jt->Pos() == (aScanDirection ? aCurrent->Seg().B : aCurrent->Seg().A ) );
|
( jt->Pos() == ( aScanDirection ? aCurrent->Seg().B : aCurrent->Seg().A ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex)
|
PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex)
|
||||||
{
|
{
|
||||||
const int MaxVerts = 1024;
|
const int MaxVerts = 1024 * 16;
|
||||||
|
|
||||||
VECTOR2I corners[MaxVerts + 1];
|
VECTOR2I corners[MaxVerts + 1];
|
||||||
PNS_SEGMENT* segs[MaxVerts + 1];
|
PNS_SEGMENT* segs[MaxVerts + 1];
|
||||||
|
@ -812,6 +828,7 @@ void PNS_NODE::FindLineEnds( PNS_LINE* aLine, PNS_JOINT& aA, PNS_JOINT& aB )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*>& aFoundJoints )
|
void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*>& aFoundJoints )
|
||||||
{
|
{
|
||||||
std::deque<PNS_JOINT*> searchQueue;
|
std::deque<PNS_JOINT*> searchQueue;
|
||||||
|
@ -846,51 +863,7 @@ void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*>& aFo
|
||||||
BOOST_FOREACH(PNS_JOINT* jt, processed)
|
BOOST_FOREACH(PNS_JOINT* jt, processed)
|
||||||
aFoundJoints.push_back( jt );
|
aFoundJoints.push_back( jt );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
PNS_ITEM* PNS_NODE::NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor, int aKindMask )
|
|
||||||
{
|
|
||||||
std::set<PNS_ITEM*> disconnected;
|
|
||||||
std::vector<PNS_JOINT*> joints;
|
|
||||||
|
|
||||||
AllItemsInNet( aStart->Net(), disconnected );
|
|
||||||
MapConnectivity ( aStart, joints );
|
|
||||||
|
|
||||||
BOOST_FOREACH( PNS_JOINT *jt, joints )
|
|
||||||
{
|
|
||||||
BOOST_FOREACH( PNS_ITEM* link, jt->LinkList() )
|
|
||||||
{
|
|
||||||
if( disconnected.find( link ) != disconnected.end() )
|
|
||||||
disconnected.erase( link );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int best_dist = INT_MAX;
|
|
||||||
PNS_ITEM* best = NULL;
|
|
||||||
|
|
||||||
BOOST_FOREACH( PNS_ITEM* item, disconnected )
|
|
||||||
{
|
|
||||||
if( item->OfKind( aKindMask ) )
|
|
||||||
{
|
|
||||||
for(int i = 0; i < item->AnchorCount(); i++)
|
|
||||||
{
|
|
||||||
VECTOR2I p = item->Anchor( i );
|
|
||||||
int d = ( p - aStart->Pos() ).EuclideanNorm();
|
|
||||||
|
|
||||||
if( d < best_dist )
|
|
||||||
{
|
|
||||||
best_dist = d;
|
|
||||||
best = item;
|
|
||||||
|
|
||||||
if( aAnchor )
|
|
||||||
*aAnchor = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return best;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& aA, PNS_JOINT& aB, std::vector<PNS_LINE*>& aLines )
|
int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& aA, PNS_JOINT& aB, std::vector<PNS_LINE*>& aLines )
|
||||||
|
@ -1192,12 +1165,12 @@ void PNS_NODE::AllItemsInNet( int aNet, std::set<PNS_ITEM*>& aItems )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_NODE::ClearRanks()
|
void PNS_NODE::ClearRanks( int aMarkerMask )
|
||||||
{
|
{
|
||||||
for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
|
for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
|
||||||
{
|
{
|
||||||
(*i)->SetRank( -1 );
|
(*i)->SetRank( -1 );
|
||||||
(*i)->Mark( 0 );
|
(*i)->Mark( (*i)->Marker() & (~aMarkerMask) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1235,7 +1208,7 @@ int PNS_NODE::RemoveByMarker( int aMarker )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_SEGMENT* PNS_NODE::findRedundantSegment ( PNS_SEGMENT *aSeg )
|
PNS_SEGMENT* PNS_NODE::findRedundantSegment( PNS_SEGMENT* aSeg )
|
||||||
{
|
{
|
||||||
PNS_JOINT* jtStart = FindJoint ( aSeg->Seg().A, aSeg );
|
PNS_JOINT* jtStart = FindJoint ( aSeg->Seg().A, aSeg );
|
||||||
|
|
||||||
|
@ -1262,3 +1235,8 @@ PNS_SEGMENT* PNS_NODE::findRedundantSegment ( PNS_SEGMENT *aSeg )
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PNS_NODE::SetCollisionFilter( PNS_COLLISION_FILTER* aFilter )
|
||||||
|
{
|
||||||
|
m_collisionFilter = aFilter;
|
||||||
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ class PNS_SOLID;
|
||||||
class PNS_VIA;
|
class PNS_VIA;
|
||||||
class PNS_RATSNEST;
|
class PNS_RATSNEST;
|
||||||
class PNS_INDEX;
|
class PNS_INDEX;
|
||||||
|
class PNS_ROUTER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PNS_CLEARANCE_FUNC
|
* Class PNS_CLEARANCE_FUNC
|
||||||
|
@ -52,8 +52,34 @@ class PNS_INDEX;
|
||||||
class PNS_CLEARANCE_FUNC
|
class PNS_CLEARANCE_FUNC
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual int operator()( const PNS_ITEM* aA, const PNS_ITEM* aB ) = 0;
|
|
||||||
virtual ~PNS_CLEARANCE_FUNC() {}
|
virtual ~PNS_CLEARANCE_FUNC() {}
|
||||||
|
virtual int operator()( const PNS_ITEM* aA, const PNS_ITEM* aB ) = 0;
|
||||||
|
virtual void OverrideClearance (bool aEnable, int aNetA = 0, int aNetB = 0, int aClearance = 0) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PNS_PCBNEW_CLEARANCE_FUNC : public PNS_CLEARANCE_FUNC
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PNS_PCBNEW_CLEARANCE_FUNC( PNS_ROUTER *aRouter );
|
||||||
|
virtual ~PNS_PCBNEW_CLEARANCE_FUNC();
|
||||||
|
|
||||||
|
virtual int operator()( const PNS_ITEM* aA, const PNS_ITEM* aB );
|
||||||
|
virtual void OverrideClearance (bool aEnable, int aNetA = 0, int aNetB = 0, int aClearance = 0);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct CLEARANCE_ENT {
|
||||||
|
int coupledNet;
|
||||||
|
int clearance;
|
||||||
|
};
|
||||||
|
|
||||||
|
PNS_ROUTER *m_router;
|
||||||
|
|
||||||
|
int localPadClearance( const PNS_ITEM* aItem ) const;
|
||||||
|
std::vector<CLEARANCE_ENT> m_clearanceCache;
|
||||||
|
int m_defaultClearance;
|
||||||
|
bool m_overrideEnabled;
|
||||||
|
int m_overrideNetA, m_overrideNetB;
|
||||||
|
int m_overrideClearance;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,7 +91,7 @@ public:
|
||||||
struct PNS_OBSTACLE
|
struct PNS_OBSTACLE
|
||||||
{
|
{
|
||||||
///> Item we search collisions with
|
///> Item we search collisions with
|
||||||
PNS_ITEM* m_head;
|
const PNS_ITEM* m_head;
|
||||||
|
|
||||||
///> Item found to be colliding with m_head
|
///> Item found to be colliding with m_head
|
||||||
PNS_ITEM* m_item;
|
PNS_ITEM* m_item;
|
||||||
|
@ -81,6 +107,15 @@ struct PNS_OBSTACLE
|
||||||
int m_distFirst, m_distLast;
|
int m_distFirst, m_distLast;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Struct PNS_COLLISION_FILTER
|
||||||
|
* Used to override the decision of the collision search algorithm whether two
|
||||||
|
* items collide.
|
||||||
|
**/
|
||||||
|
struct PNS_COLLISION_FILTER {
|
||||||
|
virtual bool operator()( const PNS_ITEM *aItemA, const PNS_ITEM *aItemB ) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PNS_NODE
|
* Class PNS_NODE
|
||||||
*
|
*
|
||||||
|
@ -201,7 +236,8 @@ public:
|
||||||
*/
|
*/
|
||||||
bool CheckColliding( const PNS_ITEM* aItemA,
|
bool CheckColliding( const PNS_ITEM* aItemA,
|
||||||
const PNS_ITEM* aItemB,
|
const PNS_ITEM* aItemB,
|
||||||
int aKindMask = PNS_ITEM::ANY );
|
int aKindMask = PNS_ITEM::ANY,
|
||||||
|
int aForceClearance = -1 );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function HitTest()
|
* Function HitTest()
|
||||||
|
@ -230,6 +266,15 @@ public:
|
||||||
*/
|
*/
|
||||||
void Remove( PNS_ITEM* aItem );
|
void Remove( PNS_ITEM* aItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Remove()
|
||||||
|
*
|
||||||
|
* Just as the name says, removes a line from this branch.
|
||||||
|
* @param aItem item to remove
|
||||||
|
*/
|
||||||
|
void Remove( PNS_LINE& aLine );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Replace()
|
* Function Replace()
|
||||||
*
|
*
|
||||||
|
@ -258,7 +303,7 @@ public:
|
||||||
* @param aOriginSegmentIndex index of aSeg in the resulting line
|
* @param aOriginSegmentIndex index of aSeg in the resulting line
|
||||||
* @return the line
|
* @return the line
|
||||||
*/
|
*/
|
||||||
PNS_LINE* AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex = NULL );
|
PNS_LINE* AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex = NULL );
|
||||||
|
|
||||||
///> Prints the contents and joints structure
|
///> Prints the contents and joints structure
|
||||||
void Dump( bool aLong = false );
|
void Dump( bool aLong = false );
|
||||||
|
@ -296,16 +341,18 @@ public:
|
||||||
* Searches for a joint at a given position, linked to given item.
|
* Searches for a joint at a given position, linked to given item.
|
||||||
* @return the joint, if found, otherwise empty
|
* @return the joint, if found, otherwise empty
|
||||||
*/
|
*/
|
||||||
PNS_JOINT* FindJoint( const VECTOR2I& aPos, PNS_ITEM* aItem )
|
PNS_JOINT* FindJoint( const VECTOR2I& aPos, const PNS_ITEM* aItem )
|
||||||
{
|
{
|
||||||
return FindJoint( aPos, aItem->Layers().Start(), aItem->Net() );
|
return FindJoint( aPos, aItem->Layers().Start(), aItem->Net() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
void MapConnectivity( PNS_JOINT* aStart, std::vector<PNS_JOINT*> & aFoundJoints );
|
void MapConnectivity( PNS_JOINT* aStart, std::vector<PNS_JOINT*> & aFoundJoints );
|
||||||
|
|
||||||
PNS_ITEM* NearestUnconnectedItem( PNS_JOINT* aStart, int *aAnchor = NULL,
|
PNS_ITEM* NearestUnconnectedItem( PNS_JOINT* aStart, int *aAnchor = NULL,
|
||||||
int aKindMask = PNS_ITEM::ANY);
|
int aKindMask = PNS_ITEM::ANY);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
///> finds all lines between a pair of joints. Used by the loop removal procedure.
|
///> finds all lines between a pair of joints. Used by the loop removal procedure.
|
||||||
int FindLinesBetweenJoints( PNS_JOINT& aA,
|
int FindLinesBetweenJoints( PNS_JOINT& aA,
|
||||||
|
@ -320,10 +367,11 @@ public:
|
||||||
|
|
||||||
void AllItemsInNet( int aNet, std::set<PNS_ITEM*>& aItems );
|
void AllItemsInNet( int aNet, std::set<PNS_ITEM*>& aItems );
|
||||||
|
|
||||||
void ClearRanks();
|
void ClearRanks( int aMarkerMask = MK_HEAD | MK_VIOLATION );
|
||||||
|
|
||||||
int FindByMarker( int aMarker, PNS_ITEMSET& aItems );
|
int FindByMarker( int aMarker, PNS_ITEMSET& aItems );
|
||||||
int RemoveByMarker( int aMarker );
|
int RemoveByMarker( int aMarker );
|
||||||
|
void SetCollisionFilter( PNS_COLLISION_FILTER* aFilter );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct OBSTACLE_VISITOR;
|
struct OBSTACLE_VISITOR;
|
||||||
|
@ -411,6 +459,9 @@ private:
|
||||||
|
|
||||||
///> depth of the node (number of parent nodes in the inheritance chain)
|
///> depth of the node (number of parent nodes in the inheritance chain)
|
||||||
int m_depth;
|
int m_depth;
|
||||||
|
|
||||||
|
///> optional collision filtering object
|
||||||
|
PNS_COLLISION_FILTER *m_collisionFilter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <geometry/shape_rect.h>
|
#include <geometry/shape_rect.h>
|
||||||
|
|
||||||
#include "pns_line.h"
|
#include "pns_line.h"
|
||||||
|
#include "pns_diff_pair.h"
|
||||||
#include "pns_node.h"
|
#include "pns_node.h"
|
||||||
#include "pns_optimizer.h"
|
#include "pns_optimizer.h"
|
||||||
#include "pns_utils.h"
|
#include "pns_utils.h"
|
||||||
|
@ -100,14 +101,14 @@ void PNS_COST_ESTIMATOR::Replace( PNS_LINE& aOldLine, PNS_LINE& aNewLine )
|
||||||
|
|
||||||
|
|
||||||
bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
|
bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
|
||||||
double aLengthTollerance,
|
double aLengthTolerance,
|
||||||
double aCornerTollerance ) const
|
double aCornerTolerance ) const
|
||||||
{
|
{
|
||||||
if( aOther.m_cornerCost < m_cornerCost && aOther.m_lengthCost < m_lengthCost )
|
if( aOther.m_cornerCost < m_cornerCost && aOther.m_lengthCost < m_lengthCost )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
else if( aOther.m_cornerCost < m_cornerCost * aCornerTollerance &&
|
else if( aOther.m_cornerCost < m_cornerCost * aCornerTolerance &&
|
||||||
aOther.m_lengthCost < m_lengthCost * aLengthTollerance )
|
aOther.m_lengthCost < m_lengthCost * aLengthTolerance )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -121,6 +122,7 @@ PNS_OPTIMIZER::PNS_OPTIMIZER( PNS_NODE* aWorld ) :
|
||||||
m_world( aWorld ), m_collisionKindMask( PNS_ITEM::ANY ), m_effortLevel( MERGE_SEGMENTS )
|
m_world( aWorld ), m_collisionKindMask( PNS_ITEM::ANY ), m_effortLevel( MERGE_SEGMENTS )
|
||||||
{
|
{
|
||||||
// m_cache = new SHAPE_INDEX_LIST<PNS_ITEM*>();
|
// m_cache = new SHAPE_INDEX_LIST<PNS_ITEM*>();
|
||||||
|
m_restrictAreaActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -223,6 +225,158 @@ void PNS_OPTIMIZER::ClearCache( bool aStaticOnly )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class LINE_RESTRICTIONS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LINE_RESTRICTIONS() {};
|
||||||
|
~LINE_RESTRICTIONS() {};
|
||||||
|
|
||||||
|
void Build( PNS_NODE* aWorld, PNS_LINE* aOriginLine, const SHAPE_LINE_CHAIN& aLine, const BOX2I& aRestrictedArea, bool aRestrictedAreaEnable );
|
||||||
|
bool Check ( int aVertex1, int aVertex2, const SHAPE_LINE_CHAIN& aReplacement );
|
||||||
|
void Dump();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int allowedAngles( PNS_NODE* aWorld, const PNS_LINE* aLine, const VECTOR2I& aP, bool aFirst );
|
||||||
|
|
||||||
|
struct RVERTEX
|
||||||
|
{
|
||||||
|
RVERTEX ( bool aRestricted, int aAllowedAngles ) :
|
||||||
|
restricted( aRestricted ),
|
||||||
|
allowedAngles( aAllowedAngles )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool restricted;
|
||||||
|
int allowedAngles;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<RVERTEX> m_rs;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// fixme: use later
|
||||||
|
int LINE_RESTRICTIONS::allowedAngles( PNS_NODE* aWorld, const PNS_LINE* aLine, const VECTOR2I& aP, bool aFirst )
|
||||||
|
{
|
||||||
|
PNS_JOINT* jt = aWorld->FindJoint( aP , aLine );
|
||||||
|
|
||||||
|
if( !jt )
|
||||||
|
return 0xff;
|
||||||
|
|
||||||
|
DIRECTION_45 dirs [8];
|
||||||
|
|
||||||
|
int n_dirs = 0;
|
||||||
|
|
||||||
|
BOOST_FOREACH( const PNS_ITEM* item, jt->Links().CItems() )
|
||||||
|
{
|
||||||
|
if( item->OfKind( PNS_ITEM::VIA ) || item->OfKind( PNS_ITEM::SOLID ) )
|
||||||
|
return 0xff;
|
||||||
|
else if( const PNS_SEGMENT* seg = dyn_cast<const PNS_SEGMENT*>( item ) )
|
||||||
|
{
|
||||||
|
SEG s = seg->Seg();
|
||||||
|
if( s.A != aP )
|
||||||
|
s.Reverse();
|
||||||
|
|
||||||
|
if( n_dirs < 8 )
|
||||||
|
dirs[n_dirs++] = aFirst ? DIRECTION_45( s ) : DIRECTION_45( s ).Opposite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int angleMask = DIRECTION_45::ANG_OBTUSE | DIRECTION_45::ANG_HALF_FULL | DIRECTION_45::ANG_STRAIGHT;
|
||||||
|
int outputMask = 0xff;
|
||||||
|
|
||||||
|
for( int d = 0; d < 8; d++ )
|
||||||
|
{
|
||||||
|
DIRECTION_45 refDir( ( DIRECTION_45::Directions ) d );
|
||||||
|
|
||||||
|
for( int i = 0; i < n_dirs; i++ )
|
||||||
|
{
|
||||||
|
if( !(refDir.Angle( dirs[i] ) & angleMask ) )
|
||||||
|
outputMask &= ~refDir.Mask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawDebugDirs( aP, outputMask, 3 );
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LINE_RESTRICTIONS::Build( PNS_NODE* aWorld, PNS_LINE* aOriginLine, const SHAPE_LINE_CHAIN& aLine, const BOX2I& aRestrictedArea, bool aRestrictedAreaEnable )
|
||||||
|
{
|
||||||
|
const SHAPE_LINE_CHAIN& l = aLine;
|
||||||
|
VECTOR2I v_prev;
|
||||||
|
int n = l.PointCount( );
|
||||||
|
|
||||||
|
m_rs.reserve( n );
|
||||||
|
|
||||||
|
for( int i = 0; i < n; i++ )
|
||||||
|
{
|
||||||
|
const VECTOR2I &v = l.CPoint( i ), v_next;
|
||||||
|
RVERTEX r( false, 0xff );
|
||||||
|
|
||||||
|
if( aRestrictedAreaEnable )
|
||||||
|
{
|
||||||
|
bool exiting = ( i > 0 && aRestrictedArea.Contains( v_prev ) && !aRestrictedArea.Contains( v ) );
|
||||||
|
bool entering = false;
|
||||||
|
|
||||||
|
if( i != l.PointCount() - 1 )
|
||||||
|
{
|
||||||
|
const VECTOR2I& v_next = l.CPoint( i + 1 );
|
||||||
|
entering = ( !aRestrictedArea.Contains( v ) && aRestrictedArea.Contains( v_next ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( entering )
|
||||||
|
{
|
||||||
|
const SEG& sp = l.CSegment( i );
|
||||||
|
r.allowedAngles = DIRECTION_45( sp ).Mask();
|
||||||
|
}
|
||||||
|
else if( exiting )
|
||||||
|
{
|
||||||
|
const SEG& sp = l.CSegment( i - 1 );
|
||||||
|
r.allowedAngles = DIRECTION_45( sp ).Mask();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r.allowedAngles = ( !aRestrictedArea.Contains( v ) ) ? 0 : 0xff;
|
||||||
|
r.restricted = r.allowedAngles ? false : true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v_prev = v;
|
||||||
|
m_rs.push_back( r );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LINE_RESTRICTIONS::Dump()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LINE_RESTRICTIONS::Check( int aVertex1, int aVertex2, const SHAPE_LINE_CHAIN& aReplacement )
|
||||||
|
{
|
||||||
|
if( m_rs.empty( ) )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for( int i = aVertex1; i <= aVertex2; i++ )
|
||||||
|
if ( m_rs[i].restricted )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const RVERTEX& v1 = m_rs[ aVertex1 ];
|
||||||
|
const RVERTEX& v2 = m_rs[ aVertex2 ];
|
||||||
|
|
||||||
|
int m1 = DIRECTION_45( aReplacement.CSegment( 0 ) ).Mask();
|
||||||
|
int m2;
|
||||||
|
|
||||||
|
if( aReplacement.SegmentCount() == 1 )
|
||||||
|
m2 = m1;
|
||||||
|
else
|
||||||
|
m2 = DIRECTION_45( aReplacement.CSegment( 1 ) ).Mask();
|
||||||
|
|
||||||
|
return ( ( v1.allowedAngles & m1 ) != 0 ) &&
|
||||||
|
( ( v2.allowedAngles & m2 ) != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache )
|
bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache )
|
||||||
{
|
{
|
||||||
CACHE_VISITOR v( aItem, m_world, m_collisionKindMask );
|
CACHE_VISITOR v( aItem, m_world, m_collisionKindMask );
|
||||||
|
@ -314,7 +468,6 @@ bool PNS_OPTIMIZER::mergeObtuse( PNS_LINE* aLine )
|
||||||
s2opt = SEG( ip, s2.B );
|
s2opt = SEG( ip, s2.B );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if( DIRECTION_45( s1opt ).IsObtuse( DIRECTION_45( s2opt ) ) )
|
if( DIRECTION_45( s1opt ).IsObtuse( DIRECTION_45( s2opt ) ) )
|
||||||
{
|
{
|
||||||
SHAPE_LINE_CHAIN opt_path;
|
SHAPE_LINE_CHAIN opt_path;
|
||||||
|
@ -391,7 +544,7 @@ bool PNS_OPTIMIZER::mergeFull( PNS_LINE* aLine )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PNS_OPTIMIZER::Optimize( PNS_LINE* aLine, PNS_LINE* aResult )//, int aStartVertex, int aEndVertex )
|
bool PNS_OPTIMIZER::Optimize( PNS_LINE* aLine, PNS_LINE* aResult )
|
||||||
{
|
{
|
||||||
if( !aResult )
|
if( !aResult )
|
||||||
aResult = aLine;
|
aResult = aLine;
|
||||||
|
@ -425,12 +578,16 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath,
|
||||||
|
|
||||||
int cost_orig = PNS_COST_ESTIMATOR::CornerCost( aCurrentPath );
|
int cost_orig = PNS_COST_ESTIMATOR::CornerCost( aCurrentPath );
|
||||||
|
|
||||||
|
LINE_RESTRICTIONS restr;
|
||||||
|
|
||||||
if( aLine->SegmentCount() < 4 )
|
if( aLine->SegmentCount() < 4 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
DIRECTION_45 orig_start( aLine->CSegment( 0 ) );
|
DIRECTION_45 orig_start( aLine->CSegment( 0 ) );
|
||||||
DIRECTION_45 orig_end( aLine->CSegment( -1 ) );
|
DIRECTION_45 orig_end( aLine->CSegment( -1 ) );
|
||||||
|
|
||||||
|
restr.Build( m_world, aLine, aCurrentPath, m_restrictArea, m_restrictAreaActive );
|
||||||
|
|
||||||
while( n < n_segs - step )
|
while( n < n_segs - step )
|
||||||
{
|
{
|
||||||
const SEG s1 = aCurrentPath.CSegment( n );
|
const SEG s1 = aCurrentPath.CSegment( n );
|
||||||
|
@ -446,13 +603,14 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath,
|
||||||
SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, i );
|
SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, i );
|
||||||
cost[i] = INT_MAX;
|
cost[i] = INT_MAX;
|
||||||
|
|
||||||
|
bool restrictionsOK = restr.Check ( n, n + step + 1, bypass );
|
||||||
|
|
||||||
if( n == 0 && orig_start != DIRECTION_45( bypass.CSegment( 0 ) ) )
|
if( n == 0 && orig_start != DIRECTION_45( bypass.CSegment( 0 ) ) )
|
||||||
postureMatch = false;
|
postureMatch = false;
|
||||||
else if( n == n_segs - step && orig_end != DIRECTION_45( bypass.CSegment( -1 ) ) )
|
else if( n == n_segs - step && orig_end != DIRECTION_45( bypass.CSegment( -1 ) ) )
|
||||||
postureMatch = false;
|
postureMatch = false;
|
||||||
|
|
||||||
if( (postureMatch || !m_keepPostures) && !checkColliding( aLine, bypass ) )
|
if( restrictionsOK && (postureMatch || !m_keepPostures) && !checkColliding( aLine, bypass ) )
|
||||||
{
|
{
|
||||||
path[i] = aCurrentPath;
|
path[i] = aCurrentPath;
|
||||||
path[i].Replace( s1.Index(), s2.Index(), bypass );
|
path[i].Replace( s1.Index(), s2.Index(), bypass );
|
||||||
|
@ -773,16 +931,17 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE* aLine )
|
||||||
if(endPad)
|
if(endPad)
|
||||||
{
|
{
|
||||||
endMatch = endPad->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID );
|
endMatch = endPad->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
endMatch = aLine->EndsWithVia();
|
endMatch = aLine->EndsWithVia();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( startMatch && endMatch && len < thr )
|
if( startMatch && endMatch && len < thr )
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 2; i++ )
|
for( int i = 0; i < 2; i++ )
|
||||||
{
|
{
|
||||||
SHAPE_LINE_CHAIN l2 = DIRECTION_45().BuildInitialTrace( p_start, p_end, i );
|
SHAPE_LINE_CHAIN l2 = DIRECTION_45().BuildInitialTrace( p_start, p_end, i );
|
||||||
PNS_ROUTER::GetInstance()->DisplayDebugLine( l2, 4, 10000 );
|
|
||||||
PNS_LINE repl;
|
PNS_LINE repl;
|
||||||
repl = PNS_LINE( *aLine, l2 );
|
repl = PNS_LINE( *aLine, l2 );
|
||||||
|
|
||||||
|
@ -796,3 +955,215 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE* aLine )
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int findCoupledVertices( const VECTOR2I& aVertex, const SEG& aOrigSeg, const SHAPE_LINE_CHAIN& aCoupled, PNS_DIFF_PAIR* aPair, int* aIndices )
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
for ( int i = 0; i < aCoupled.SegmentCount(); i++ )
|
||||||
|
{
|
||||||
|
SEG s = aCoupled.CSegment( i );
|
||||||
|
VECTOR2I projOverCoupled = s.LineProject ( aVertex );
|
||||||
|
|
||||||
|
if( s.ApproxParallel ( aOrigSeg ) )
|
||||||
|
{
|
||||||
|
int64_t dist = ( projOverCoupled - aVertex ).EuclideanNorm() - aPair->Width();
|
||||||
|
|
||||||
|
if( aPair->GapConstraint().Matches( dist ) )
|
||||||
|
{
|
||||||
|
*aIndices++ = i;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool verifyDpBypass( PNS_NODE* aNode, PNS_DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aNewRef, const SHAPE_LINE_CHAIN& aNewCoupled )
|
||||||
|
{
|
||||||
|
PNS_LINE refLine ( aRefIsP ? aPair->PLine() : aPair->NLine(), aNewRef );
|
||||||
|
PNS_LINE coupledLine ( aRefIsP ? aPair->NLine() : aPair->PLine(), aNewCoupled );
|
||||||
|
|
||||||
|
if( aNode->CheckColliding( &refLine, &coupledLine, PNS_ITEM::ANY, aPair->Gap() - 10 ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( aNode->CheckColliding ( &refLine ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( aNode->CheckColliding ( &coupledLine ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool coupledBypass( PNS_NODE* aNode, PNS_DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aRef, const SHAPE_LINE_CHAIN& aRefBypass, const SHAPE_LINE_CHAIN& aCoupled, SHAPE_LINE_CHAIN& aNewCoupled )
|
||||||
|
{
|
||||||
|
int vStartIdx[1024]; // fixme: possible overflow
|
||||||
|
|
||||||
|
int nStarts = findCoupledVertices( aRefBypass.CPoint( 0 ), aRefBypass.CSegment( 0 ), aCoupled, aPair, vStartIdx );
|
||||||
|
DIRECTION_45 dir( aRefBypass.CSegment( 0 ) );
|
||||||
|
|
||||||
|
int64_t bestLength = -1;
|
||||||
|
bool found = false;
|
||||||
|
SHAPE_LINE_CHAIN bestBypass;
|
||||||
|
int si, ei;
|
||||||
|
|
||||||
|
for( int i=0; i< nStarts; i++ )
|
||||||
|
{
|
||||||
|
for( int j = 1; j < aCoupled.PointCount() - 1; j++ )
|
||||||
|
{
|
||||||
|
int delta = std::abs ( vStartIdx[i] - j );
|
||||||
|
|
||||||
|
if( delta > 1 )
|
||||||
|
{
|
||||||
|
const VECTOR2I& vs = aCoupled.CPoint( vStartIdx[i] );
|
||||||
|
SHAPE_LINE_CHAIN bypass = dir.BuildInitialTrace( vs, aCoupled.CPoint(j), dir.IsDiagonal() );
|
||||||
|
|
||||||
|
int64_t coupledLength = aPair->CoupledLength( aRef, bypass );
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN newCoupled = aCoupled;
|
||||||
|
|
||||||
|
si = vStartIdx[i];
|
||||||
|
ei = j;
|
||||||
|
|
||||||
|
if(si < ei)
|
||||||
|
newCoupled.Replace( si, ei, bypass );
|
||||||
|
else
|
||||||
|
newCoupled.Replace( ei, si, bypass.Reverse() );
|
||||||
|
|
||||||
|
if(coupledLength > bestLength && verifyDpBypass( aNode, aPair, aRefIsP, aRef, newCoupled) )
|
||||||
|
{
|
||||||
|
bestBypass = newCoupled;
|
||||||
|
bestLength = coupledLength;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( found )
|
||||||
|
aNewCoupled = bestBypass;
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool checkDpColliding( PNS_NODE* aNode, PNS_DIFF_PAIR* aPair, bool aIsP, const SHAPE_LINE_CHAIN& aPath )
|
||||||
|
{
|
||||||
|
PNS_LINE tmp ( aIsP ? aPair->PLine() : aPair->NLine(), aPath );
|
||||||
|
|
||||||
|
return aNode->CheckColliding( &tmp );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_OPTIMIZER::mergeDpStep( PNS_DIFF_PAIR* aPair, bool aTryP, int step )
|
||||||
|
{
|
||||||
|
int n = 1;
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN currentPath = aTryP ? aPair->CP() : aPair->CN();
|
||||||
|
SHAPE_LINE_CHAIN coupledPath = aTryP ? aPair->CN() : aPair->CP();
|
||||||
|
|
||||||
|
int n_segs = currentPath.SegmentCount() - 1;
|
||||||
|
|
||||||
|
int64_t clenPre = aPair->CoupledLength( currentPath, coupledPath );
|
||||||
|
int64_t budget = clenPre / 10; // fixme: come up with somethig more intelligent here...
|
||||||
|
|
||||||
|
while( n < n_segs - step )
|
||||||
|
{
|
||||||
|
const SEG s1 = currentPath.CSegment( n );
|
||||||
|
const SEG s2 = currentPath.CSegment( n + step );
|
||||||
|
|
||||||
|
DIRECTION_45 dir1( s1 );
|
||||||
|
DIRECTION_45 dir2( s2 );
|
||||||
|
|
||||||
|
if( dir1.IsObtuse( dir2 ) )
|
||||||
|
{
|
||||||
|
SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, dir1.IsDiagonal() );
|
||||||
|
SHAPE_LINE_CHAIN newRef;
|
||||||
|
SHAPE_LINE_CHAIN newCoup;
|
||||||
|
int64_t deltaCoupled = -1, deltaUni = -1;
|
||||||
|
|
||||||
|
newRef = currentPath;
|
||||||
|
newRef.Replace( s1.Index(), s2.Index(), bypass );
|
||||||
|
|
||||||
|
deltaUni = aPair->CoupledLength ( newRef, coupledPath ) - clenPre + budget;
|
||||||
|
|
||||||
|
if ( coupledBypass( m_world, aPair, aTryP, newRef, bypass, coupledPath, newCoup ) )
|
||||||
|
{
|
||||||
|
deltaCoupled = aPair->CoupledLength( newRef, newCoup ) - clenPre + budget;
|
||||||
|
|
||||||
|
if( deltaCoupled >= 0 )
|
||||||
|
{
|
||||||
|
newRef.Simplify();
|
||||||
|
newCoup.Simplify();
|
||||||
|
|
||||||
|
aPair->SetShape( newRef, newCoup, !aTryP );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( deltaUni >= 0 && verifyDpBypass ( m_world, aPair, aTryP, newRef, coupledPath ) )
|
||||||
|
{
|
||||||
|
newRef.Simplify();
|
||||||
|
coupledPath.Simplify();
|
||||||
|
|
||||||
|
aPair->SetShape( newRef, coupledPath, !aTryP );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_OPTIMIZER::mergeDpSegments( PNS_DIFF_PAIR* aPair )
|
||||||
|
{
|
||||||
|
int step_p = aPair->CP().SegmentCount() - 2;
|
||||||
|
int step_n = aPair->CN().SegmentCount() - 2;
|
||||||
|
|
||||||
|
while( 1 )
|
||||||
|
{
|
||||||
|
int n_segs_p = aPair->CP().SegmentCount();
|
||||||
|
int n_segs_n = aPair->CN().SegmentCount();
|
||||||
|
|
||||||
|
int max_step_p = n_segs_p - 2;
|
||||||
|
int max_step_n = n_segs_n - 2;
|
||||||
|
|
||||||
|
if( step_p > max_step_p )
|
||||||
|
step_p = max_step_p;
|
||||||
|
|
||||||
|
if( step_n > max_step_n )
|
||||||
|
step_n = max_step_n;
|
||||||
|
|
||||||
|
if( step_p < 1 && step_n < 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bool found_anything_p = false;
|
||||||
|
bool found_anything_n = false;
|
||||||
|
|
||||||
|
if( step_p > 1 )
|
||||||
|
found_anything_p = mergeDpStep( aPair, true, step_p );
|
||||||
|
|
||||||
|
if( step_n > 1 )
|
||||||
|
found_anything_n = mergeDpStep( aPair, false, step_n );
|
||||||
|
|
||||||
|
if( !found_anything_n && !found_anything_p )
|
||||||
|
{
|
||||||
|
step_n--;
|
||||||
|
step_p--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PNS_OPTIMIZER::Optimize( PNS_DIFF_PAIR* aPair )
|
||||||
|
{
|
||||||
|
return mergeDpSegments( aPair );
|
||||||
|
}
|
||||||
|
|
|
@ -30,8 +30,9 @@
|
||||||
#include "range.h"
|
#include "range.h"
|
||||||
|
|
||||||
class PNS_NODE;
|
class PNS_NODE;
|
||||||
class PNS_LINE;
|
|
||||||
class PNS_ROUTER;
|
class PNS_ROUTER;
|
||||||
|
class PNS_LINE;
|
||||||
|
class PNS_DIFF_PAIR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PNS_COST_ESTIMATOR
|
* Class PNS_COST_ESTIMATOR
|
||||||
|
@ -61,7 +62,7 @@ public:
|
||||||
void Remove( PNS_LINE& aLine );
|
void Remove( PNS_LINE& aLine );
|
||||||
void Replace( PNS_LINE& aOldLine, PNS_LINE& aNewLine );
|
void Replace( PNS_LINE& aOldLine, PNS_LINE& aNewLine );
|
||||||
|
|
||||||
bool IsBetter( PNS_COST_ESTIMATOR& aOther, double aLengthTollerance,
|
bool IsBetter( PNS_COST_ESTIMATOR& aOther, double aLengthTolerance,
|
||||||
double aCornerTollerace ) const;
|
double aCornerTollerace ) const;
|
||||||
|
|
||||||
double GetLengthCost() const { return m_lengthCost; }
|
double GetLengthCost() const { return m_lengthCost; }
|
||||||
|
@ -101,6 +102,8 @@ public:
|
||||||
static bool Optimize( PNS_LINE* aLine, int aEffortLevel, PNS_NODE* aWorld);
|
static bool Optimize( PNS_LINE* aLine, int aEffortLevel, PNS_NODE* aWorld);
|
||||||
|
|
||||||
bool Optimize( PNS_LINE* aLine, PNS_LINE* aResult = NULL );
|
bool Optimize( PNS_LINE* aLine, PNS_LINE* aResult = NULL );
|
||||||
|
bool Optimize( PNS_DIFF_PAIR* aPair );
|
||||||
|
|
||||||
|
|
||||||
void SetWorld( PNS_NODE* aNode ) { m_world = aNode; }
|
void SetWorld( PNS_NODE* aNode ) { m_world = aNode; }
|
||||||
void CacheStaticItem( PNS_ITEM* aItem );
|
void CacheStaticItem( PNS_ITEM* aItem );
|
||||||
|
@ -117,6 +120,13 @@ public:
|
||||||
m_effortLevel = aEffort;
|
m_effortLevel = aEffort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetRestrictArea( const BOX2I& aArea )
|
||||||
|
{
|
||||||
|
m_restrictArea = aArea;
|
||||||
|
m_restrictAreaActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int MaxCachedItems = 256;
|
static const int MaxCachedItems = 256;
|
||||||
|
|
||||||
|
@ -136,6 +146,8 @@ private:
|
||||||
bool runSmartPads( PNS_LINE* aLine );
|
bool runSmartPads( PNS_LINE* aLine );
|
||||||
bool mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentLine, int step );
|
bool mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentLine, int step );
|
||||||
bool fanoutCleanup( PNS_LINE * aLine );
|
bool fanoutCleanup( PNS_LINE * aLine );
|
||||||
|
bool mergeDpSegments( PNS_DIFF_PAIR *aPair );
|
||||||
|
bool mergeDpStep( PNS_DIFF_PAIR *aPair, bool aTryP, int step );
|
||||||
|
|
||||||
bool checkColliding( PNS_ITEM* aItem, bool aUpdateCache = true );
|
bool checkColliding( PNS_ITEM* aItem, bool aUpdateCache = true );
|
||||||
bool checkColliding( PNS_LINE* aLine, const SHAPE_LINE_CHAIN& aOptPath );
|
bool checkColliding( PNS_LINE* aLine, const SHAPE_LINE_CHAIN& aOptPath );
|
||||||
|
@ -160,6 +172,9 @@ private:
|
||||||
int m_collisionKindMask;
|
int m_collisionKindMask;
|
||||||
int m_effortLevel;
|
int m_effortLevel;
|
||||||
bool m_keepPostures;
|
bool m_keepPostures;
|
||||||
|
|
||||||
|
BOX2I m_restrictArea;
|
||||||
|
bool m_restrictAreaActive;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2014 CERN
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PNS_PLACEMENT_ALGO_H
|
||||||
|
#define __PNS_PLACEMENT_ALGO_H
|
||||||
|
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
|
||||||
|
#include "pns_algo_base.h"
|
||||||
|
#include "pns_sizes_settings.h"
|
||||||
|
#include "pns_itemset.h"
|
||||||
|
|
||||||
|
class PNS_ROUTER;
|
||||||
|
class PNS_ITEM;
|
||||||
|
class PNS_NODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PNS_PLACEMENT_ALGO
|
||||||
|
*
|
||||||
|
* Abstract class for a P&S placement/dragging algorithm.
|
||||||
|
* All subtools (drag, single/diff pair routing and meandering)
|
||||||
|
* are derived from it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PNS_PLACEMENT_ALGO : public PNS_ALGO_BASE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PNS_PLACEMENT_ALGO( PNS_ROUTER* aRouter ) :
|
||||||
|
PNS_ALGO_BASE( aRouter ) {};
|
||||||
|
|
||||||
|
virtual ~PNS_PLACEMENT_ALGO () {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Start()
|
||||||
|
*
|
||||||
|
* Starts placement/drag operation at point aP, taking item aStartItem as anchor
|
||||||
|
* (unless NULL).
|
||||||
|
*/
|
||||||
|
virtual bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Move()
|
||||||
|
*
|
||||||
|
* Moves the end of the currently routed primtive(s) to the point aP, taking
|
||||||
|
* aEndItem as the anchor (if not NULL).
|
||||||
|
* (unless NULL).
|
||||||
|
*/
|
||||||
|
virtual bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem ) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function FixRoute()
|
||||||
|
*
|
||||||
|
* Commits the currently routed items to the parent node, taking
|
||||||
|
* aP as the final end point and aEndItem as the final anchor (if provided).
|
||||||
|
* @return true, if route has been commited. May return false if the routing
|
||||||
|
* result is violating design rules - in such case, the track is only committed
|
||||||
|
* if Settings.CanViolateDRC() is on.
|
||||||
|
*/
|
||||||
|
virtual bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function ToggleVia()
|
||||||
|
*
|
||||||
|
* Enables/disables a via at the end of currently routed trace.
|
||||||
|
*/
|
||||||
|
virtual bool ToggleVia( bool aEnabled )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function IsPlacingVia()
|
||||||
|
*
|
||||||
|
* Returns true if the placer is placing a via (or more vias).
|
||||||
|
*/
|
||||||
|
virtual bool IsPlacingVia() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetLayer()
|
||||||
|
*
|
||||||
|
* Sets the current routing layer.
|
||||||
|
*/
|
||||||
|
virtual bool SetLayer( int aLayer )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Traces()
|
||||||
|
*
|
||||||
|
* Returns all routed/tuned traces.
|
||||||
|
*/
|
||||||
|
virtual const PNS_ITEMSET Traces() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurrentEnd()
|
||||||
|
*
|
||||||
|
* Returns the current end of the line being placed/tuned. It may not be equal
|
||||||
|
* to the cursor position due to collisions.
|
||||||
|
*/
|
||||||
|
virtual const VECTOR2I& CurrentEnd() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurrentNet()
|
||||||
|
*
|
||||||
|
* Returns the net code of currently routed track.
|
||||||
|
*/
|
||||||
|
virtual int CurrentNet() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurrentLayer()
|
||||||
|
*
|
||||||
|
* Returns the layer of currently routed track.
|
||||||
|
*/
|
||||||
|
virtual int CurrentLayer() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurrentNode()
|
||||||
|
*
|
||||||
|
* Returns the most recent board state.
|
||||||
|
*/
|
||||||
|
virtual PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function FlipPosture()
|
||||||
|
*
|
||||||
|
* Toggles the current posture (straight/diagonal) of the trace head.
|
||||||
|
*/
|
||||||
|
virtual void FlipPosture()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function UpdateSizes()
|
||||||
|
*
|
||||||
|
* Performs on-the-fly update of the width, via diameter & drill size from
|
||||||
|
* a settings class. Used to dynamically change these parameters as
|
||||||
|
* the track is routed.
|
||||||
|
*/
|
||||||
|
virtual void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetOrthoMode()
|
||||||
|
*
|
||||||
|
* Forces the router to place a straight 90/45 degree trace (with the end
|
||||||
|
* as near to the cursor as possible) instead of a standard 135 degree
|
||||||
|
* two-segment bend.
|
||||||
|
*/
|
||||||
|
virtual void SetOrthoMode ( bool aOrthoMode )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetModifiedNets
|
||||||
|
*
|
||||||
|
* Returns the net codes of all currently routed trace(s)
|
||||||
|
*/
|
||||||
|
virtual void GetModifiedNets( std::vector<int> &aNets ) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -44,6 +44,11 @@
|
||||||
#include "pns_router.h"
|
#include "pns_router.h"
|
||||||
#include "pns_shove.h"
|
#include "pns_shove.h"
|
||||||
#include "pns_dragger.h"
|
#include "pns_dragger.h"
|
||||||
|
#include "pns_topology.h"
|
||||||
|
#include "pns_diff_pair_placer.h"
|
||||||
|
#include "pns_meander_placer.h"
|
||||||
|
#include "pns_meander_skew_placer.h"
|
||||||
|
#include "pns_dp_meander_placer.h"
|
||||||
|
|
||||||
#include <router/router_preview_item.h>
|
#include <router/router_preview_item.h>
|
||||||
|
|
||||||
|
@ -58,46 +63,69 @@
|
||||||
// To be fixed sometime in the future.
|
// To be fixed sometime in the future.
|
||||||
static PNS_ROUTER* theRouter;
|
static PNS_ROUTER* theRouter;
|
||||||
|
|
||||||
class PCBNEW_CLEARANCE_FUNC : public PNS_CLEARANCE_FUNC
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PCBNEW_CLEARANCE_FUNC( BOARD* aBoard )
|
|
||||||
{
|
|
||||||
m_clearanceCache.resize( aBoard->GetNetCount() );
|
|
||||||
|
|
||||||
for( unsigned int i = 0; i < aBoard->GetNetCount(); i++ )
|
PNS_PCBNEW_CLEARANCE_FUNC::PNS_PCBNEW_CLEARANCE_FUNC( PNS_ROUTER *aRouter ) :
|
||||||
|
m_router( aRouter )
|
||||||
|
{
|
||||||
|
BOARD *brd = m_router->GetBoard();
|
||||||
|
PNS_NODE *world = m_router->GetWorld();
|
||||||
|
|
||||||
|
PNS_TOPOLOGY topo( world );
|
||||||
|
m_clearanceCache.resize( brd->GetNetCount() );
|
||||||
|
|
||||||
|
for( unsigned int i = 0; i < brd->GetNetCount(); i++ )
|
||||||
{
|
{
|
||||||
NETINFO_ITEM* ni = aBoard->FindNet( i );
|
NETINFO_ITEM* ni = brd->FindNet( i );
|
||||||
if( ni == NULL )
|
if( ni == NULL )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
CLEARANCE_ENT ent;
|
||||||
|
ent.coupledNet = topo.DpCoupledNet( i );
|
||||||
|
|
||||||
wxString netClassName = ni->GetClassName();
|
wxString netClassName = ni->GetClassName();
|
||||||
NETCLASSPTR nc = aBoard->GetDesignSettings().m_NetClasses.Find( netClassName );
|
NETCLASSPTR nc = brd->GetDesignSettings().m_NetClasses.Find( netClassName );
|
||||||
|
|
||||||
int clearance = nc->GetClearance();
|
int clearance = nc->GetClearance();
|
||||||
m_clearanceCache[i] = clearance;
|
ent.clearance = clearance;
|
||||||
|
m_clearanceCache[i] = ent;
|
||||||
|
|
||||||
TRACE( 1, "Add net %d netclass %s clearance %d", i % netClassName.mb_str() %
|
TRACE( 1, "Add net %d netclass %s clearance %d", i % netClassName.mb_str() %
|
||||||
clearance );
|
clearance );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_overrideEnabled = false;
|
||||||
m_defaultClearance = 254000; // aBoard->m_NetClasses.Find ("Default clearance")->GetClearance();
|
m_defaultClearance = 254000; // aBoard->m_NetClasses.Find ("Default clearance")->GetClearance();
|
||||||
}
|
}
|
||||||
|
|
||||||
int localPadClearance( const PNS_ITEM* aItem ) const
|
|
||||||
{
|
PNS_PCBNEW_CLEARANCE_FUNC::~PNS_PCBNEW_CLEARANCE_FUNC()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_PCBNEW_CLEARANCE_FUNC::localPadClearance( const PNS_ITEM* aItem ) const
|
||||||
|
{
|
||||||
if( !aItem->Parent() || aItem->Parent()->Type() != PCB_PAD_T )
|
if( !aItem->Parent() || aItem->Parent()->Type() != PCB_PAD_T )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const D_PAD* pad = static_cast<D_PAD*>( aItem->Parent() );
|
const D_PAD* pad = static_cast<D_PAD*>( aItem->Parent() );
|
||||||
|
|
||||||
return pad->GetLocalClearance();
|
return pad->GetLocalClearance();
|
||||||
}
|
}
|
||||||
|
|
||||||
int operator()( const PNS_ITEM* aA, const PNS_ITEM* aB )
|
|
||||||
{
|
int PNS_PCBNEW_CLEARANCE_FUNC::operator()( const PNS_ITEM* aA, const PNS_ITEM* aB )
|
||||||
|
{
|
||||||
int net_a = aA->Net();
|
int net_a = aA->Net();
|
||||||
int cl_a = ( net_a >= 0 ? m_clearanceCache[net_a] : m_defaultClearance );
|
int cl_a = ( net_a >= 0 ? m_clearanceCache[net_a].clearance : m_defaultClearance );
|
||||||
int net_b = aB->Net();
|
int net_b = aB->Net();
|
||||||
int cl_b = ( net_b >= 0 ? m_clearanceCache[net_b] : m_defaultClearance );
|
int cl_b = ( net_b >= 0 ? m_clearanceCache[net_b].clearance : m_defaultClearance );
|
||||||
|
|
||||||
|
bool linesOnly = aA->OfKind( PNS_ITEM::SEGMENT | PNS_ITEM::LINE ) && aB->OfKind( PNS_ITEM::SEGMENT | PNS_ITEM::LINE );
|
||||||
|
|
||||||
|
if( linesOnly && net_a >= 0 && net_b >= 0 && m_clearanceCache[net_a].coupledNet == net_b )
|
||||||
|
{
|
||||||
|
cl_a = cl_b = m_router->Sizes().DiffPairGap() - 2 * PNS_HULL_MARGIN;
|
||||||
|
}
|
||||||
|
|
||||||
int pad_a = localPadClearance( aA );
|
int pad_a = localPadClearance( aA );
|
||||||
int pad_b = localPadClearance( aB );
|
int pad_b = localPadClearance( aB );
|
||||||
|
@ -106,18 +134,27 @@ public:
|
||||||
cl_b = std::max( cl_b, pad_b );
|
cl_b = std::max( cl_b, pad_b );
|
||||||
|
|
||||||
return std::max( cl_a, cl_b );
|
return std::max( cl_a, cl_b );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<int> m_clearanceCache;
|
// fixme: ugly hack to make the optimizer respect gap width for currently routed differential pair.
|
||||||
int m_defaultClearance;
|
void PNS_PCBNEW_CLEARANCE_FUNC::OverrideClearance( bool aEnable, int aNetA, int aNetB , int aClearance )
|
||||||
};
|
{
|
||||||
|
m_overrideEnabled = aEnable;
|
||||||
|
m_overrideNetA = aNetA;
|
||||||
|
m_overrideNetB = aNetB;
|
||||||
|
m_overrideClearance = aClearance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
|
PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
|
||||||
{
|
{
|
||||||
PNS_LAYERSET layers( 0, MAX_CU_LAYERS - 1 );
|
PNS_LAYERSET layers( 0, MAX_CU_LAYERS - 1 );
|
||||||
|
|
||||||
|
// ignore non-copper pads
|
||||||
|
if ( (aPad->GetLayerSet() & LSET::AllCuMask()).none() )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
switch( aPad->GetAttribute() )
|
switch( aPad->GetAttribute() )
|
||||||
{
|
{
|
||||||
case PAD_STANDARD:
|
case PAD_STANDARD:
|
||||||
|
@ -253,6 +290,7 @@ void PNS_ROUTER::SetBoard( BOARD* aBoard )
|
||||||
TRACE( 1, "m_board = %p\n", m_board );
|
TRACE( 1, "m_board = %p\n", m_board );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_ROUTER::SyncWorld()
|
void PNS_ROUTER::SyncWorld()
|
||||||
{
|
{
|
||||||
if( !m_board )
|
if( !m_board )
|
||||||
|
@ -263,12 +301,7 @@ void PNS_ROUTER::SyncWorld()
|
||||||
|
|
||||||
ClearWorld();
|
ClearWorld();
|
||||||
|
|
||||||
int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue();
|
|
||||||
|
|
||||||
m_clearanceFunc = new PCBNEW_CLEARANCE_FUNC( m_board );
|
|
||||||
m_world = new PNS_NODE();
|
m_world = new PNS_NODE();
|
||||||
m_world->SetClearanceFunctor( m_clearanceFunc );
|
|
||||||
m_world->SetMaxClearance( 4 * worstClearance );
|
|
||||||
|
|
||||||
for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
|
for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
|
||||||
{
|
{
|
||||||
|
@ -294,9 +327,15 @@ void PNS_ROUTER::SyncWorld()
|
||||||
if( item )
|
if( item )
|
||||||
m_world->Add( item );
|
m_world->Add( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue();
|
||||||
|
m_clearanceFunc = new PNS_PCBNEW_CLEARANCE_FUNC( this );
|
||||||
|
m_world->SetClearanceFunctor( m_clearanceFunc );
|
||||||
|
m_world->SetMaxClearance( 4 * worstClearance );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PNS_ROUTER::PNS_ROUTER()
|
PNS_ROUTER::PNS_ROUTER()
|
||||||
{
|
{
|
||||||
theRouter = this;
|
theRouter = this;
|
||||||
|
@ -309,6 +348,7 @@ PNS_ROUTER::PNS_ROUTER()
|
||||||
m_previewItems = NULL;
|
m_previewItems = NULL;
|
||||||
m_board = NULL;
|
m_board = NULL;
|
||||||
m_dragger = NULL;
|
m_dragger = NULL;
|
||||||
|
m_mode = PNS_MODE_ROUTE_SINGLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -460,19 +500,49 @@ bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||||
|
|
||||||
bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem, int aLayer )
|
bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem, int aLayer )
|
||||||
{
|
{
|
||||||
|
switch( m_mode )
|
||||||
|
{
|
||||||
|
case PNS_MODE_ROUTE_SINGLE:
|
||||||
m_placer = new PNS_LINE_PLACER( this );
|
m_placer = new PNS_LINE_PLACER( this );
|
||||||
|
break;
|
||||||
|
case PNS_MODE_ROUTE_DIFF_PAIR:
|
||||||
|
m_placer = new PNS_DIFF_PAIR_PLACER( this );
|
||||||
|
break;
|
||||||
|
case PNS_MODE_TUNE_SINGLE:
|
||||||
|
m_placer = new PNS_MEANDER_PLACER( this );
|
||||||
|
break;
|
||||||
|
case PNS_MODE_TUNE_DIFF_PAIR:
|
||||||
|
m_placer = new PNS_DP_MEANDER_PLACER( this );
|
||||||
|
break;
|
||||||
|
case PNS_MODE_TUNE_DIFF_PAIR_SKEW:
|
||||||
|
m_placer = new PNS_MEANDER_SKEW_PLACER( this );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_placer->UpdateSizes ( m_sizes );
|
m_placer->UpdateSizes ( m_sizes );
|
||||||
m_placer->SetLayer( aLayer );
|
m_placer->SetLayer( aLayer );
|
||||||
m_placer->Start( aP, aStartItem );
|
|
||||||
|
bool rv = m_placer->Start( aP, aStartItem );
|
||||||
|
|
||||||
|
if( !rv )
|
||||||
|
return false;
|
||||||
|
|
||||||
m_currentEnd = aP;
|
m_currentEnd = aP;
|
||||||
m_currentEndItem = NULL;
|
m_currentEndItem = NULL;
|
||||||
m_state = ROUTE_TRACK;
|
m_state = ROUTE_TRACK;
|
||||||
|
return rv;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOARD* PNS_ROUTER::GetBoard()
|
||||||
|
{
|
||||||
|
return m_board;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_ROUTER::eraseView()
|
void PNS_ROUTER::eraseView()
|
||||||
{
|
{
|
||||||
BOOST_FOREACH( BOARD_ITEM* item, m_hiddenItems )
|
BOOST_FOREACH( BOARD_ITEM* item, m_hiddenItems )
|
||||||
|
@ -652,15 +722,23 @@ void PNS_ROUTER::movePlacing( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||||
eraseView();
|
eraseView();
|
||||||
|
|
||||||
m_placer->Move( aP, aEndItem );
|
m_placer->Move( aP, aEndItem );
|
||||||
PNS_LINE current = m_placer->Trace();
|
PNS_ITEMSET current = m_placer->Traces();
|
||||||
|
|
||||||
DisplayItem( ¤t );
|
BOOST_FOREACH( const PNS_ITEM* item, current.CItems() )
|
||||||
|
{
|
||||||
|
if( !item->OfKind( PNS_ITEM::LINE ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
if( current.EndsWithVia() )
|
const PNS_LINE* l = static_cast <const PNS_LINE*> (item);
|
||||||
DisplayItem( ¤t.Via() );
|
DisplayItem( l );
|
||||||
|
|
||||||
PNS_ITEMSET tmp( ¤t );
|
if( l->EndsWithVia() )
|
||||||
updateView( m_placer->CurrentNode( true ), tmp );
|
DisplayItem( &l->Via() );
|
||||||
|
}
|
||||||
|
|
||||||
|
//PNS_ITEMSET tmp( ¤t );
|
||||||
|
|
||||||
|
updateView( m_placer->CurrentNode( true ), current );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -765,18 +843,19 @@ bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||||
void PNS_ROUTER::StopRouting()
|
void PNS_ROUTER::StopRouting()
|
||||||
{
|
{
|
||||||
// Update the ratsnest with new changes
|
// Update the ratsnest with new changes
|
||||||
|
|
||||||
if( m_placer )
|
if( m_placer )
|
||||||
{
|
{
|
||||||
int n = m_placer->CurrentNet();
|
std::vector<int> nets;
|
||||||
|
m_placer->GetModifiedNets( nets );
|
||||||
|
|
||||||
if( n >= 0)
|
BOOST_FOREACH ( int n, nets )
|
||||||
{
|
{
|
||||||
// Update the ratsnest with new changes
|
// Update the ratsnest with new changes
|
||||||
m_board->GetRatsnest()->Recalculate( n );
|
m_board->GetRatsnest()->Recalculate( n );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if( !RoutingInProgress() )
|
if( !RoutingInProgress() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -864,10 +943,26 @@ void PNS_ROUTER::DumpLog()
|
||||||
logger->Save( "/tmp/shove.log" );
|
logger->Save( "/tmp/shove.log" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PNS_ROUTER::IsPlacingVia() const
|
bool PNS_ROUTER::IsPlacingVia() const
|
||||||
{
|
{
|
||||||
if(!m_placer)
|
if( !m_placer )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return m_placer->IsPlacingVia();
|
return m_placer->IsPlacingVia();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_ROUTER::SetOrthoMode( bool aEnable )
|
||||||
|
{
|
||||||
|
if( !m_placer )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_placer->SetOrthoMode( aEnable );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_ROUTER::SetMode( PNS_ROUTER_MODE aMode )
|
||||||
|
{
|
||||||
|
m_mode = aMode;
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ class D_PAD;
|
||||||
class TRACK;
|
class TRACK;
|
||||||
class VIA;
|
class VIA;
|
||||||
class PNS_NODE;
|
class PNS_NODE;
|
||||||
|
class PNS_DIFF_PAIR_PLACER;
|
||||||
|
class PNS_PLACEMENT_ALGO;
|
||||||
class PNS_LINE_PLACER;
|
class PNS_LINE_PLACER;
|
||||||
class PNS_ITEM;
|
class PNS_ITEM;
|
||||||
class PNS_LINE;
|
class PNS_LINE;
|
||||||
|
@ -59,6 +61,14 @@ namespace KIGFX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum PNS_ROUTER_MODE {
|
||||||
|
PNS_MODE_ROUTE_SINGLE = 1,
|
||||||
|
PNS_MODE_ROUTE_DIFF_PAIR,
|
||||||
|
PNS_MODE_TUNE_SINGLE,
|
||||||
|
PNS_MODE_TUNE_DIFF_PAIR,
|
||||||
|
PNS_MODE_TUNE_DIFF_PAIR_SKEW
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PNS_ROUTER
|
* Class PNS_ROUTER
|
||||||
*
|
*
|
||||||
|
@ -78,6 +88,9 @@ public:
|
||||||
PNS_ROUTER();
|
PNS_ROUTER();
|
||||||
~PNS_ROUTER();
|
~PNS_ROUTER();
|
||||||
|
|
||||||
|
void SetMode ( PNS_ROUTER_MODE aMode );
|
||||||
|
PNS_ROUTER_MODE Mode() const { return m_mode; }
|
||||||
|
|
||||||
static PNS_ROUTER* GetInstance();
|
static PNS_ROUTER* GetInstance();
|
||||||
|
|
||||||
void ClearWorld();
|
void ClearWorld();
|
||||||
|
@ -113,6 +126,7 @@ public:
|
||||||
void SwitchLayer( int layer );
|
void SwitchLayer( int layer );
|
||||||
|
|
||||||
void ToggleViaPlacement();
|
void ToggleViaPlacement();
|
||||||
|
void SetOrthoMode ( bool aEnable );
|
||||||
|
|
||||||
int GetCurrentLayer() const;
|
int GetCurrentLayer() const;
|
||||||
int GetCurrentNet() const;
|
int GetCurrentNet() const;
|
||||||
|
@ -193,6 +207,15 @@ public:
|
||||||
return m_sizes;
|
return m_sizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNS_ITEM *QueryItemByParent ( const BOARD_ITEM *aItem ) const;
|
||||||
|
|
||||||
|
BOARD *GetBoard();
|
||||||
|
|
||||||
|
void SetFailureReason ( const wxString& aReason ) { m_failureReason = aReason; }
|
||||||
|
const wxString& FailureReason() const { return m_failureReason; }
|
||||||
|
|
||||||
|
PNS_PLACEMENT_ALGO *Placer() { return m_placer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void movePlacing( const VECTOR2I& aP, PNS_ITEM* aItem );
|
void movePlacing( const VECTOR2I& aP, PNS_ITEM* aItem );
|
||||||
void moveDragging( const VECTOR2I& aP, PNS_ITEM* aItem );
|
void moveDragging( const VECTOR2I& aP, PNS_ITEM* aItem );
|
||||||
|
@ -225,7 +248,7 @@ private:
|
||||||
BOARD* m_board;
|
BOARD* m_board;
|
||||||
PNS_NODE* m_world;
|
PNS_NODE* m_world;
|
||||||
PNS_NODE* m_lastNode;
|
PNS_NODE* m_lastNode;
|
||||||
PNS_LINE_PLACER* m_placer;
|
PNS_PLACEMENT_ALGO * m_placer;
|
||||||
PNS_DRAGGER* m_dragger;
|
PNS_DRAGGER* m_dragger;
|
||||||
PNS_SHOVE* m_shove;
|
PNS_SHOVE* m_shove;
|
||||||
int m_iterLimit;
|
int m_iterLimit;
|
||||||
|
@ -250,6 +273,10 @@ private:
|
||||||
///> Stores list of modified items in the current operation
|
///> Stores list of modified items in the current operation
|
||||||
PICKED_ITEMS_LIST m_undoBuffer;
|
PICKED_ITEMS_LIST m_undoBuffer;
|
||||||
PNS_SIZES_SETTINGS m_sizes;
|
PNS_SIZES_SETTINGS m_sizes;
|
||||||
|
PNS_ROUTER_MODE m_mode;
|
||||||
|
|
||||||
|
wxString m_toolStatusbarName;
|
||||||
|
wxString m_failureReason;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS()
|
PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS()
|
||||||
{
|
{
|
||||||
m_routingMode = RM_Walkaround;
|
m_routingMode = RM_Walkaround;
|
||||||
m_optimizerEffort = OE_FULL;
|
m_optimizerEffort = OE_MEDIUM;
|
||||||
m_removeLoops = true;
|
m_removeLoops = true;
|
||||||
m_smartPads = true;
|
m_smartPads = true;
|
||||||
m_shoveVias = true;
|
m_shoveVias = true;
|
||||||
|
|
|
@ -137,7 +137,6 @@ private:
|
||||||
PNS_MODE m_routingMode;
|
PNS_MODE m_routingMode;
|
||||||
PNS_OPTIMIZATION_EFFORT m_optimizerEffort;
|
PNS_OPTIMIZATION_EFFORT m_optimizerEffort;
|
||||||
|
|
||||||
|
|
||||||
int m_walkaroundIterationLimit;
|
int m_walkaroundIterationLimit;
|
||||||
int m_shoveIterationLimit;
|
int m_shoveIterationLimit;
|
||||||
TIME_LIMIT m_shoveTimeLimit;
|
TIME_LIMIT m_shoveTimeLimit;
|
||||||
|
|
|
@ -55,6 +55,11 @@ public:
|
||||||
m_rank = aParentLine.Rank();
|
m_rank = aParentLine.Rank();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline bool ClassOf( const PNS_ITEM* aItem )
|
||||||
|
{
|
||||||
|
return aItem && SEGMENT == aItem->Kind();
|
||||||
|
}
|
||||||
|
|
||||||
PNS_SEGMENT* Clone( ) const;
|
PNS_SEGMENT* Clone( ) const;
|
||||||
|
|
||||||
const SHAPE* Shape() const
|
const SHAPE* Shape() const
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define PNS_DEBUG
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
@ -36,11 +38,36 @@
|
||||||
#include "pns_utils.h"
|
#include "pns_utils.h"
|
||||||
#include "pns_router.h"
|
#include "pns_router.h"
|
||||||
#include "pns_shove.h"
|
#include "pns_shove.h"
|
||||||
|
#include "pns_utils.h"
|
||||||
|
|
||||||
#include "time_limit.h"
|
#include "time_limit.h"
|
||||||
|
|
||||||
#include <profile.h>
|
#include <profile.h>
|
||||||
|
|
||||||
|
void PNS_SHOVE::replaceItems( PNS_ITEM* aOld, PNS_ITEM* aNew )
|
||||||
|
{
|
||||||
|
OPT_BOX2I changed_area = ChangedArea( aOld, aNew );
|
||||||
|
|
||||||
|
if( changed_area )
|
||||||
|
{
|
||||||
|
assert( !changed_area->Contains( VECTOR2I( 0, 0 ) ) );
|
||||||
|
|
||||||
|
m_affectedAreaSum = m_affectedAreaSum ? m_affectedAreaSum->Merge ( *changed_area ) : *changed_area;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentNode->Replace( aOld, aNew );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PNS_SHOVE::getClearance( PNS_ITEM *aA, PNS_ITEM *aB ) const
|
||||||
|
{
|
||||||
|
if( m_forceClearance >= 0 )
|
||||||
|
return m_forceClearance;
|
||||||
|
|
||||||
|
return m_currentNode->GetClearance( aA, aB );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void sanityCheck( PNS_LINE* aOld, PNS_LINE* aNew )
|
static void sanityCheck( PNS_LINE* aOld, PNS_LINE* aNew )
|
||||||
{
|
{
|
||||||
assert( aOld->CPoint( 0 ) == aNew->CPoint( 0 ) );
|
assert( aOld->CPoint( 0 ) == aNew->CPoint( 0 ) );
|
||||||
|
@ -51,6 +78,7 @@ static void sanityCheck( PNS_LINE* aOld, PNS_LINE* aNew )
|
||||||
PNS_SHOVE::PNS_SHOVE( PNS_NODE* aWorld, PNS_ROUTER* aRouter ) :
|
PNS_SHOVE::PNS_SHOVE( PNS_NODE* aWorld, PNS_ROUTER* aRouter ) :
|
||||||
PNS_ALGO_BASE ( aRouter )
|
PNS_ALGO_BASE ( aRouter )
|
||||||
{
|
{
|
||||||
|
m_forceClearance = -1;
|
||||||
m_root = aWorld;
|
m_root = aWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,16 +102,6 @@ PNS_LINE* PNS_SHOVE::assembleLine( const PNS_SEGMENT* aSeg, int* aIndex )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// garbage-collected line cloning
|
|
||||||
PNS_LINE* PNS_SHOVE::cloneLine ( const PNS_LINE* aLine )
|
|
||||||
{
|
|
||||||
PNS_LINE* l = aLine->Clone();
|
|
||||||
|
|
||||||
m_gcItems.push_back( l );
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// A dumb function that checks if the shoved line is shoved the right way, e.g.
|
// A dumb function that checks if the shoved line is shoved the right way, e.g.
|
||||||
// visually "outwards" of the line/via applying pressure on it. Unfortunately there's no
|
// visually "outwards" of the line/via applying pressure on it. Unfortunately there's no
|
||||||
// mathematical concept of orientation of an open curve, so we use some primitive heuristics:
|
// mathematical concept of orientation of an open curve, so we use some primitive heuristics:
|
||||||
|
@ -92,7 +110,7 @@ bool PNS_SHOVE::checkBumpDirection( PNS_LINE* aCurrent, PNS_LINE* aShoved ) cons
|
||||||
{
|
{
|
||||||
const SEG ss = aCurrent->CSegment( 0 );
|
const SEG ss = aCurrent->CSegment( 0 );
|
||||||
|
|
||||||
int dist = m_currentNode->GetClearance( aCurrent, aShoved ) + PNS_HULL_MARGIN;
|
int dist = getClearance( aCurrent, aShoved ) + PNS_HULL_MARGIN;
|
||||||
|
|
||||||
dist += aCurrent->Width() / 2;
|
dist += aCurrent->Width() / 2;
|
||||||
dist += aShoved->Width() / 2;
|
dist += aShoved->Width() / 2;
|
||||||
|
@ -106,7 +124,7 @@ bool PNS_SHOVE::checkBumpDirection( PNS_LINE* aCurrent, PNS_LINE* aShoved ) cons
|
||||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::walkaroundLoneVia( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::walkaroundLoneVia( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
||||||
PNS_LINE* aShoved )
|
PNS_LINE* aShoved )
|
||||||
{
|
{
|
||||||
int clearance = m_currentNode->GetClearance( aCurrent, aObstacle );
|
int clearance = getClearance( aCurrent, aObstacle );
|
||||||
const SHAPE_LINE_CHAIN hull = aCurrent->Via().Hull( clearance, aObstacle->Width() );
|
const SHAPE_LINE_CHAIN hull = aCurrent->Via().Hull( clearance, aObstacle->Width() );
|
||||||
SHAPE_LINE_CHAIN path_cw, path_ccw;
|
SHAPE_LINE_CHAIN path_cw, path_ccw;
|
||||||
|
|
||||||
|
@ -204,7 +222,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processHullSet( PNS_LINE* aCurrent, PNS_LINE*
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool colliding = m_currentNode->CheckColliding( &l, aCurrent );
|
bool colliding = m_currentNode->CheckColliding( &l, aCurrent, PNS_ITEM::ANY, m_forceClearance );
|
||||||
|
|
||||||
if( ( aCurrent->Marker() & MK_HEAD ) && !colliding )
|
if( ( aCurrent->Marker() & MK_HEAD ) && !colliding )
|
||||||
{
|
{
|
||||||
|
@ -232,7 +250,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processHullSet( PNS_LINE* aCurrent, PNS_LINE*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processSingleLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ProcessSingleLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
||||||
PNS_LINE* aShoved )
|
PNS_LINE* aShoved )
|
||||||
{
|
{
|
||||||
aShoved->ClearSegmentLinks();
|
aShoved->ClearSegmentLinks();
|
||||||
|
@ -262,7 +280,8 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processSingleLine( PNS_LINE* aCurrent, PNS_LI
|
||||||
{
|
{
|
||||||
int w = aObstacle->Width();
|
int w = aObstacle->Width();
|
||||||
int n_segs = aCurrent->SegmentCount();
|
int n_segs = aCurrent->SegmentCount();
|
||||||
int clearance = m_currentNode->GetClearance( aCurrent, aObstacle );
|
|
||||||
|
int clearance = getClearance( aCurrent, aObstacle );
|
||||||
|
|
||||||
HULL_SET hulls;
|
HULL_SET hulls;
|
||||||
|
|
||||||
|
@ -291,19 +310,24 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSegment( PNS_LINE* aCurrent, PNS_S
|
||||||
{
|
{
|
||||||
int segIndex;
|
int segIndex;
|
||||||
PNS_LINE* obstacleLine = assembleLine( aObstacleSeg, &segIndex );
|
PNS_LINE* obstacleLine = assembleLine( aObstacleSeg, &segIndex );
|
||||||
PNS_LINE* shovedLine = cloneLine( obstacleLine );
|
PNS_LINE* shovedLine = clone( obstacleLine );
|
||||||
|
|
||||||
SHOVE_STATUS rv = processSingleLine( aCurrent, obstacleLine, shovedLine );
|
SHOVE_STATUS rv = ProcessSingleLine( aCurrent, obstacleLine, shovedLine );
|
||||||
|
|
||||||
assert ( obstacleLine->LayersOverlap( shovedLine ) );
|
assert( obstacleLine->LayersOverlap( shovedLine ) );
|
||||||
|
|
||||||
if( rv == SH_OK )
|
if( rv == SH_OK )
|
||||||
{
|
{
|
||||||
if( shovedLine->Marker() & MK_HEAD )
|
if( shovedLine->Marker() & MK_HEAD )
|
||||||
|
{
|
||||||
|
if( m_multiLineMode )
|
||||||
|
return SH_INCOMPLETE;
|
||||||
|
|
||||||
m_newHead = *shovedLine;
|
m_newHead = *shovedLine;
|
||||||
|
}
|
||||||
|
|
||||||
sanityCheck( obstacleLine, shovedLine );
|
sanityCheck( obstacleLine, shovedLine );
|
||||||
m_currentNode->Replace( obstacleLine, shovedLine );
|
replaceItems ( obstacleLine, shovedLine );
|
||||||
sanityCheck( obstacleLine, shovedLine );
|
sanityCheck( obstacleLine, shovedLine );
|
||||||
|
|
||||||
int rank = aCurrent->Rank();
|
int rank = aCurrent->Rank();
|
||||||
|
@ -326,17 +350,22 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSegment( PNS_LINE* aCurrent, PNS_S
|
||||||
|
|
||||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle )
|
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle )
|
||||||
{
|
{
|
||||||
PNS_LINE* shovedLine = cloneLine( aObstacle );
|
PNS_LINE* shovedLine = clone( aObstacle );
|
||||||
|
|
||||||
SHOVE_STATUS rv = processSingleLine( aCurrent, aObstacle, shovedLine );
|
SHOVE_STATUS rv = ProcessSingleLine( aCurrent, aObstacle, shovedLine );
|
||||||
|
|
||||||
if( rv == SH_OK )
|
if( rv == SH_OK )
|
||||||
{
|
{
|
||||||
if( shovedLine->Marker() & MK_HEAD )
|
if( shovedLine->Marker() & MK_HEAD )
|
||||||
|
{
|
||||||
|
if( m_multiLineMode )
|
||||||
|
return SH_INCOMPLETE;
|
||||||
|
|
||||||
m_newHead = *shovedLine;
|
m_newHead = *shovedLine;
|
||||||
|
}
|
||||||
|
|
||||||
sanityCheck( aObstacle, shovedLine );
|
sanityCheck( aObstacle, shovedLine );
|
||||||
m_currentNode->Replace( aObstacle, shovedLine );
|
replaceItems( aObstacle, shovedLine );
|
||||||
sanityCheck( aObstacle, shovedLine );
|
sanityCheck( aObstacle, shovedLine );
|
||||||
|
|
||||||
int rank = aObstacle->Rank();
|
int rank = aObstacle->Rank();
|
||||||
|
@ -359,7 +388,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingLine( PNS_LINE* aCurrent, PNS_LINE
|
||||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSolid( PNS_LINE* aCurrent, PNS_SOLID* aObstacleSolid )
|
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSolid( PNS_LINE* aCurrent, PNS_SOLID* aObstacleSolid )
|
||||||
{
|
{
|
||||||
PNS_WALKAROUND walkaround( m_currentNode, Router() );
|
PNS_WALKAROUND walkaround( m_currentNode, Router() );
|
||||||
PNS_LINE* walkaroundLine = cloneLine( aCurrent );
|
PNS_LINE* walkaroundLine = clone( aCurrent );
|
||||||
|
|
||||||
if( aCurrent->EndsWithVia() )
|
if( aCurrent->EndsWithVia() )
|
||||||
{
|
{
|
||||||
|
@ -413,10 +442,14 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSolid( PNS_LINE* aCurrent, PNS_SOL
|
||||||
if( aCurrent->Marker() & MK_HEAD )
|
if( aCurrent->Marker() & MK_HEAD )
|
||||||
{
|
{
|
||||||
walkaroundLine->Mark( MK_HEAD );
|
walkaroundLine->Mark( MK_HEAD );
|
||||||
|
|
||||||
|
if(m_multiLineMode)
|
||||||
|
return SH_INCOMPLETE;
|
||||||
|
|
||||||
m_newHead = *walkaroundLine;
|
m_newHead = *walkaroundLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentNode->Replace( aCurrent, walkaroundLine );
|
replaceItems ( aCurrent, walkaroundLine );
|
||||||
walkaroundLine->SetRank( nextRank );
|
walkaroundLine->SetRank( nextRank );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -457,32 +490,58 @@ bool PNS_SHOVE::reduceSpringback( const PNS_ITEMSET& aHeadSet )
|
||||||
|
|
||||||
|
|
||||||
bool PNS_SHOVE::pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems,
|
bool PNS_SHOVE::pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems,
|
||||||
const PNS_COST_ESTIMATOR& aCost )
|
const PNS_COST_ESTIMATOR& aCost, const OPT_BOX2I& aAffectedArea )
|
||||||
{
|
{
|
||||||
SPRINGBACK_TAG st;
|
SPRINGBACK_TAG st;
|
||||||
|
OPT_BOX2I prev_area;
|
||||||
|
|
||||||
|
if( !m_nodeStack.empty() )
|
||||||
|
prev_area = m_nodeStack.back().m_affectedArea;
|
||||||
|
|
||||||
st.m_node = aNode;
|
st.m_node = aNode;
|
||||||
st.m_cost = aCost;
|
st.m_cost = aCost;
|
||||||
st.m_headItems = aHeadItems;
|
st.m_headItems = aHeadItems;
|
||||||
|
|
||||||
|
if( aAffectedArea )
|
||||||
|
{
|
||||||
|
if( prev_area )
|
||||||
|
st.m_affectedArea = prev_area->Merge ( *aAffectedArea );
|
||||||
|
else
|
||||||
|
st.m_affectedArea = aAffectedArea;
|
||||||
|
} else
|
||||||
|
st.m_affectedArea = prev_area;
|
||||||
|
|
||||||
m_nodeStack.push_back( st );
|
m_nodeStack.push_back( st );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank )
|
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank, bool aDryRun )
|
||||||
{
|
{
|
||||||
LINE_PAIR_VEC draggedLines;
|
LINE_PAIR_VEC draggedLines;
|
||||||
VECTOR2I p0 ( aVia->Pos() );
|
VECTOR2I p0( aVia->Pos() );
|
||||||
PNS_JOINT* jt = m_currentNode->FindJoint( p0, 1, aVia->Net() );
|
PNS_JOINT* jt = m_currentNode->FindJoint( p0, aVia );
|
||||||
PNS_VIA* pushedVia = aVia -> Clone();
|
VECTOR2I p0_pushed( p0 + aForce );
|
||||||
|
|
||||||
pushedVia->SetPos( p0 + aForce );
|
while( aForce.x != 0 || aForce.y != 0 )
|
||||||
|
{
|
||||||
|
PNS_JOINT* jt_next = m_currentNode->FindJoint( p0_pushed, aVia );
|
||||||
|
|
||||||
|
if( !jt_next )
|
||||||
|
break;
|
||||||
|
|
||||||
|
p0_pushed += aForce.Resize( 2 ); // make sure pushed via does not overlap with any existing joint
|
||||||
|
}
|
||||||
|
|
||||||
|
PNS_VIA* pushedVia = aVia->Clone();
|
||||||
|
pushedVia->SetPos( p0_pushed );
|
||||||
pushedVia->Mark( aVia->Marker() );
|
pushedVia->Mark( aVia->Marker() );
|
||||||
|
|
||||||
if( aVia->Marker() & MK_HEAD )
|
if( aVia->Marker() & MK_HEAD )
|
||||||
{
|
{
|
||||||
m_draggedVia = pushedVia;
|
m_draggedVia = pushedVia;
|
||||||
|
m_draggedViaHeadSet.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !jt )
|
if( !jt )
|
||||||
|
@ -493,9 +552,8 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
||||||
|
|
||||||
BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
|
BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
|
||||||
{
|
{
|
||||||
if( item->OfKind( PNS_ITEM::SEGMENT ) )
|
if( PNS_SEGMENT* seg = dyn_cast<PNS_SEGMENT*>( item ) )
|
||||||
{
|
{
|
||||||
PNS_SEGMENT* seg = (PNS_SEGMENT*) item;
|
|
||||||
LINE_PAIR lp;
|
LINE_PAIR lp;
|
||||||
int segIndex;
|
int segIndex;
|
||||||
|
|
||||||
|
@ -506,16 +564,23 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
||||||
if( segIndex == 0 )
|
if( segIndex == 0 )
|
||||||
lp.first->Reverse();
|
lp.first->Reverse();
|
||||||
|
|
||||||
lp.second = cloneLine( lp.first );
|
lp.second = clone( lp.first );
|
||||||
lp.second->ClearSegmentLinks();
|
lp.second->ClearSegmentLinks();
|
||||||
lp.second->DragCorner( p0 + aForce, lp.second->CLine().Find( p0 ) );
|
lp.second->DragCorner( p0_pushed, lp.second->CLine().Find( p0 ) );
|
||||||
lp.second->AppendVia ( *pushedVia );
|
lp.second->AppendVia( *pushedVia );
|
||||||
draggedLines.push_back( lp );
|
draggedLines.push_back( lp );
|
||||||
|
|
||||||
|
if( aVia->Marker() & MK_HEAD )
|
||||||
|
m_draggedViaHeadSet.Add( clone ( lp.second ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentNode->Remove( aVia );
|
m_draggedViaHeadSet.Add ( pushedVia );
|
||||||
m_currentNode->Add ( pushedVia );
|
|
||||||
|
if ( aDryRun )
|
||||||
|
return SH_OK;
|
||||||
|
|
||||||
|
replaceItems ( aVia, pushedVia );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
m_logger.Log( aVia, 0, "obstacle-via" );
|
m_logger.Log( aVia, 0, "obstacle-via" );
|
||||||
|
@ -535,6 +600,10 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
||||||
if( lp.first->Marker() & MK_HEAD )
|
if( lp.first->Marker() & MK_HEAD )
|
||||||
{
|
{
|
||||||
lp.second->Mark( MK_HEAD );
|
lp.second->Mark( MK_HEAD );
|
||||||
|
|
||||||
|
if ( m_multiLineMode )
|
||||||
|
return SH_INCOMPLETE;
|
||||||
|
|
||||||
m_newHead = *lp.second;
|
m_newHead = *lp.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,7 +611,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
||||||
|
|
||||||
if( lp.second->SegmentCount() )
|
if( lp.second->SegmentCount() )
|
||||||
{
|
{
|
||||||
m_currentNode->Replace( lp.first, lp.second );
|
replaceItems( lp.first, lp.second );
|
||||||
lp.second->SetRank( aCurrentRank - 1 );
|
lp.second->SetRank( aCurrentRank - 1 );
|
||||||
pushLine( lp.second );
|
pushLine( lp.second );
|
||||||
}
|
}
|
||||||
|
@ -561,7 +630,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
||||||
|
|
||||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingVia( PNS_ITEM* aCurrent, PNS_VIA* aObstacleVia )
|
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingVia( PNS_ITEM* aCurrent, PNS_VIA* aObstacleVia )
|
||||||
{
|
{
|
||||||
int clearance = m_currentNode->GetClearance( aCurrent, aObstacleVia ) ;
|
int clearance = getClearance( aCurrent, aObstacleVia ) ;
|
||||||
LINE_PAIR_VEC draggedLines;
|
LINE_PAIR_VEC draggedLines;
|
||||||
bool colLine = false, colVia = false;
|
bool colLine = false, colVia = false;
|
||||||
PNS_LINE* currentLine = NULL;
|
PNS_LINE* currentLine = NULL;
|
||||||
|
@ -612,11 +681,11 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE* aCurrent, PN
|
||||||
{
|
{
|
||||||
std::vector<PNS_LINE*> steps;
|
std::vector<PNS_LINE*> steps;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
PNS_LINE* cur = cloneLine( aCurrent );
|
PNS_LINE* cur = clone( aCurrent );
|
||||||
cur->ClearSegmentLinks();
|
cur->ClearSegmentLinks();
|
||||||
|
|
||||||
PNS_JOINT* jt = m_currentNode->FindJoint( aObstacleVia->Pos(), aObstacleVia );
|
PNS_JOINT* jt = m_currentNode->FindJoint( aObstacleVia->Pos(), aObstacleVia );
|
||||||
PNS_LINE* shoved = cloneLine( aCurrent );
|
PNS_LINE* shoved = clone( aCurrent );
|
||||||
shoved->ClearSegmentLinks();
|
shoved->ClearSegmentLinks();
|
||||||
|
|
||||||
cur->RemoveVia();
|
cur->RemoveVia();
|
||||||
|
@ -631,7 +700,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE* aCurrent, PN
|
||||||
|
|
||||||
head->AppendVia( *aObstacleVia );
|
head->AppendVia( *aObstacleVia );
|
||||||
|
|
||||||
SHOVE_STATUS st = processSingleLine( head, cur, shoved );
|
SHOVE_STATUS st = ProcessSingleLine( head, cur, shoved );
|
||||||
|
|
||||||
if( st != SH_OK )
|
if( st != SH_OK )
|
||||||
{
|
{
|
||||||
|
@ -663,7 +732,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE* aCurrent, PN
|
||||||
head.AppendVia( *aObstacleVia );
|
head.AppendVia( *aObstacleVia );
|
||||||
head.ClearSegmentLinks();
|
head.ClearSegmentLinks();
|
||||||
|
|
||||||
SHOVE_STATUS st = processSingleLine( &head, aCurrent, shoved );
|
SHOVE_STATUS st = ProcessSingleLine( &head, aCurrent, shoved );
|
||||||
|
|
||||||
if( st != SH_OK )
|
if( st != SH_OK )
|
||||||
return st;
|
return st;
|
||||||
|
@ -681,7 +750,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE* aCurrent, PN
|
||||||
m_logger.Log( shoved, 3, "shoved-line" );
|
m_logger.Log( shoved, 3, "shoved-line" );
|
||||||
#endif
|
#endif
|
||||||
int currentRank = aCurrent->Rank();
|
int currentRank = aCurrent->Rank();
|
||||||
m_currentNode->Replace( aCurrent, shoved );
|
replaceItems( aCurrent, shoved );
|
||||||
|
|
||||||
pushLine( shoved );
|
pushLine( shoved );
|
||||||
shoved->SetRank( currentRank );
|
shoved->SetRank( currentRank );
|
||||||
|
@ -730,7 +799,15 @@ void PNS_SHOVE::unwindStack( PNS_ITEM* aItem )
|
||||||
void PNS_SHOVE::pushLine( PNS_LINE* aL )
|
void PNS_SHOVE::pushLine( PNS_LINE* aL )
|
||||||
{
|
{
|
||||||
if( aL->LinkCount() >= 0 && ( aL->LinkCount() != aL->SegmentCount() ) )
|
if( aL->LinkCount() >= 0 && ( aL->LinkCount() != aL->SegmentCount() ) )
|
||||||
|
{
|
||||||
|
printf("LC: %d SC %d\n", aL->LinkCount(), aL->SegmentCount() );
|
||||||
|
for(int i=0;i<aL->SegmentCount();i++)
|
||||||
|
{
|
||||||
|
SEG s = aL->CLine().CSegment(i);
|
||||||
|
printf("s %d: %d %d %d %d\n", i, s.A.x, s.A.y, s.B.x, s.B.y );
|
||||||
|
}
|
||||||
assert( false );
|
assert( false );
|
||||||
|
}
|
||||||
|
|
||||||
m_lineStack.push_back( aL );
|
m_lineStack.push_back( aL );
|
||||||
m_optimizerQueue.push_back( aL );
|
m_optimizerQueue.push_back( aL );
|
||||||
|
@ -850,6 +927,8 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveMainLoop()
|
||||||
{
|
{
|
||||||
SHOVE_STATUS st = SH_OK;
|
SHOVE_STATUS st = SH_OK;
|
||||||
|
|
||||||
|
m_affectedAreaSum = OPT_BOX2I();
|
||||||
|
|
||||||
TRACE( 1, "ShoveStart [root: %d jts, current: %d jts]", m_root->JointCount() %
|
TRACE( 1, "ShoveStart [root: %d jts, current: %d jts]", m_root->JointCount() %
|
||||||
m_currentNode->JointCount() );
|
m_currentNode->JointCount() );
|
||||||
|
|
||||||
|
@ -877,15 +956,34 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveMainLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OPT_BOX2I PNS_SHOVE::totalAffectedArea() const
|
||||||
|
{
|
||||||
|
OPT_BOX2I area;
|
||||||
|
if( !m_nodeStack.empty() )
|
||||||
|
area = m_nodeStack.back().m_affectedArea;
|
||||||
|
|
||||||
|
if( area )
|
||||||
|
{
|
||||||
|
if ( m_affectedAreaSum )
|
||||||
|
area->Merge ( *m_affectedAreaSum );
|
||||||
|
} else
|
||||||
|
area = m_affectedAreaSum;
|
||||||
|
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
||||||
{
|
{
|
||||||
SHOVE_STATUS st = SH_OK;
|
SHOVE_STATUS st = SH_OK;
|
||||||
|
|
||||||
|
m_multiLineMode = false;
|
||||||
|
|
||||||
// empty head? nothing to shove...
|
// empty head? nothing to shove...
|
||||||
if( !aCurrentHead.SegmentCount() )
|
if( !aCurrentHead.SegmentCount() )
|
||||||
return SH_INCOMPLETE;
|
return SH_INCOMPLETE;
|
||||||
|
|
||||||
PNS_LINE* head = cloneLine( &aCurrentHead );
|
PNS_LINE* head = clone( &aCurrentHead );
|
||||||
head->ClearSegmentLinks();
|
head->ClearSegmentLinks();
|
||||||
|
|
||||||
m_lineStack.clear();
|
m_lineStack.clear();
|
||||||
|
@ -893,7 +991,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
||||||
m_newHead = OPT_LINE();
|
m_newHead = OPT_LINE();
|
||||||
m_logger.Clear();
|
m_logger.Clear();
|
||||||
|
|
||||||
PNS_ITEMSET headSet( cloneLine( &aCurrentHead ) );
|
PNS_ITEMSET headSet( clone( &aCurrentHead ) );
|
||||||
|
|
||||||
reduceSpringback( headSet );
|
reduceSpringback( headSet );
|
||||||
|
|
||||||
|
@ -927,7 +1025,6 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
||||||
if( m_newHead && st == SH_OK )
|
if( m_newHead && st == SH_OK )
|
||||||
{
|
{
|
||||||
st = SH_HEAD_MODIFIED;
|
st = SH_HEAD_MODIFIED;
|
||||||
//Router()->DisplayDebugLine( m_newHead->CLine(), 3, 20000 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentNode->RemoveByMarker( MK_HEAD );
|
m_currentNode->RemoveByMarker( MK_HEAD );
|
||||||
|
@ -937,7 +1034,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
||||||
|
|
||||||
if( st == SH_OK || st == SH_HEAD_MODIFIED )
|
if( st == SH_OK || st == SH_HEAD_MODIFIED )
|
||||||
{
|
{
|
||||||
pushSpringback( m_currentNode, headSet, PNS_COST_ESTIMATOR() );
|
pushSpringback( m_currentNode, headSet, PNS_COST_ESTIMATOR(), m_affectedAreaSum);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -951,6 +1048,86 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet )
|
||||||
|
{
|
||||||
|
SHOVE_STATUS st = SH_OK;
|
||||||
|
|
||||||
|
m_multiLineMode = true;
|
||||||
|
|
||||||
|
PNS_ITEMSET headSet;
|
||||||
|
|
||||||
|
BOOST_FOREACH ( const PNS_ITEM* item, aHeadSet.CItems() )
|
||||||
|
{
|
||||||
|
const PNS_LINE* headOrig = static_cast<const PNS_LINE*>( item );
|
||||||
|
|
||||||
|
// empty head? nothing to shove...
|
||||||
|
if( !headOrig->SegmentCount() )
|
||||||
|
return SH_INCOMPLETE;
|
||||||
|
|
||||||
|
headSet.Add( clone( headOrig ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lineStack.clear();
|
||||||
|
m_optimizerQueue.clear();
|
||||||
|
m_logger.Clear();
|
||||||
|
|
||||||
|
reduceSpringback( headSet );
|
||||||
|
|
||||||
|
PNS_NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||||
|
|
||||||
|
m_currentNode = parent->Branch();
|
||||||
|
m_currentNode->ClearRanks();
|
||||||
|
int n = 0;
|
||||||
|
BOOST_FOREACH ( const PNS_ITEM* item, aHeadSet.CItems() )
|
||||||
|
{
|
||||||
|
const PNS_LINE* headOrig = static_cast<const PNS_LINE*>( item );
|
||||||
|
PNS_LINE* head = clone( headOrig );
|
||||||
|
head->ClearSegmentLinks();
|
||||||
|
|
||||||
|
m_currentNode->Add( head );
|
||||||
|
|
||||||
|
head->Mark( MK_HEAD );
|
||||||
|
head->SetRank( 100000 );
|
||||||
|
n++;
|
||||||
|
pushLine( head );
|
||||||
|
|
||||||
|
PNS_VIA* headVia = NULL;
|
||||||
|
|
||||||
|
if( head->EndsWithVia() )
|
||||||
|
{
|
||||||
|
headVia = head->Via().Clone(); // fixme: leak
|
||||||
|
m_currentNode->Add( headVia );
|
||||||
|
headVia->Mark( MK_HEAD );
|
||||||
|
headVia->SetRank( 100000 );
|
||||||
|
m_logger.Log( headVia, 0, "head-via" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_logger.NewGroup( "initial", 0 );
|
||||||
|
//m_logger.Log( head, 0, "head" );
|
||||||
|
|
||||||
|
st = shoveMainLoop();
|
||||||
|
runOptimizer( m_currentNode, NULL );
|
||||||
|
|
||||||
|
m_currentNode->RemoveByMarker( MK_HEAD );
|
||||||
|
|
||||||
|
TRACE( 1, "Shove status : %s after %d iterations",
|
||||||
|
( st == SH_OK ? "OK" : "FAILURE") % m_iter );
|
||||||
|
|
||||||
|
if( st == SH_OK )
|
||||||
|
{
|
||||||
|
pushSpringback( m_currentNode, PNS_ITEMSET(), PNS_COST_ESTIMATOR(), m_affectedAreaSum );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete m_currentNode;
|
||||||
|
m_currentNode = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR2I& aWhere,
|
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR2I& aWhere,
|
||||||
PNS_VIA** aNewVia )
|
PNS_VIA** aNewVia )
|
||||||
{
|
{
|
||||||
|
@ -960,10 +1137,16 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR
|
||||||
m_optimizerQueue.clear();
|
m_optimizerQueue.clear();
|
||||||
m_newHead = OPT_LINE();
|
m_newHead = OPT_LINE();
|
||||||
m_draggedVia = NULL;
|
m_draggedVia = NULL;
|
||||||
|
m_draggedViaHeadSet.Clear();
|
||||||
//reduceSpringback( aCurrentHead );
|
|
||||||
|
|
||||||
PNS_NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
PNS_NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||||
|
|
||||||
|
m_currentNode = parent;
|
||||||
|
//st = pushVia( aVia, ( aWhere - aVia->Pos() ), 0, true );
|
||||||
|
//reduceSpringback( m_draggedViaHeadSet );
|
||||||
|
|
||||||
|
parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||||
|
|
||||||
m_currentNode = parent->Branch();
|
m_currentNode = parent->Branch();
|
||||||
m_currentNode->ClearRanks();
|
m_currentNode->ClearRanks();
|
||||||
|
|
||||||
|
@ -972,10 +1155,11 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR
|
||||||
st = pushVia( aVia, ( aWhere - aVia->Pos() ), 0 );
|
st = pushVia( aVia, ( aWhere - aVia->Pos() ), 0 );
|
||||||
st = shoveMainLoop();
|
st = shoveMainLoop();
|
||||||
runOptimizer( m_currentNode, NULL );
|
runOptimizer( m_currentNode, NULL );
|
||||||
|
//m_currentNode->RemoveByMarker( MK_HEAD );
|
||||||
|
|
||||||
if( st == SH_OK || st == SH_HEAD_MODIFIED )
|
if( st == SH_OK || st == SH_HEAD_MODIFIED )
|
||||||
{
|
{
|
||||||
pushSpringback( m_currentNode, PNS_ITEMSET(), PNS_COST_ESTIMATOR() );
|
pushSpringback( m_currentNode, m_draggedViaHeadSet, PNS_COST_ESTIMATOR(), m_affectedAreaSum );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -984,8 +1168,9 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aNewVia )
|
if( aNewVia )
|
||||||
|
{
|
||||||
*aNewVia = m_draggedVia;
|
*aNewVia = m_draggedVia;
|
||||||
|
}
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,22 +1178,39 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR
|
||||||
void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
||||||
{
|
{
|
||||||
PNS_OPTIMIZER optimizer( aNode );
|
PNS_OPTIMIZER optimizer( aNode );
|
||||||
int optFlags = 0, n_passes = 0, extend = 0;
|
int optFlags = 0, n_passes = 0;
|
||||||
|
|
||||||
PNS_OPTIMIZATION_EFFORT effort = Settings().OptimizerEffort();
|
PNS_OPTIMIZATION_EFFORT effort = Settings().OptimizerEffort();
|
||||||
|
|
||||||
|
OPT_BOX2I area = totalAffectedArea();
|
||||||
|
|
||||||
|
int maxWidth = 0;
|
||||||
|
|
||||||
|
for( std::vector<PNS_LINE*>::iterator i = m_optimizerQueue.begin();
|
||||||
|
i != m_optimizerQueue.end(); ++i )
|
||||||
|
{
|
||||||
|
maxWidth = std::max ( (*i)->Width(), maxWidth );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( area )
|
||||||
|
{
|
||||||
|
area->Inflate( 10 * maxWidth );
|
||||||
|
}
|
||||||
|
|
||||||
switch( effort )
|
switch( effort )
|
||||||
{
|
{
|
||||||
case OE_LOW:
|
case OE_LOW:
|
||||||
optFlags = PNS_OPTIMIZER::MERGE_OBTUSE;
|
optFlags = PNS_OPTIMIZER::MERGE_OBTUSE;
|
||||||
n_passes = 1;
|
n_passes = 1;
|
||||||
extend = 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OE_MEDIUM:
|
case OE_MEDIUM:
|
||||||
optFlags = PNS_OPTIMIZER::MERGE_OBTUSE;
|
optFlags = PNS_OPTIMIZER::MERGE_SEGMENTS;
|
||||||
|
|
||||||
|
if( area )
|
||||||
|
optimizer.SetRestrictArea( *area );
|
||||||
|
|
||||||
n_passes = 2;
|
n_passes = 2;
|
||||||
extend = 1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OE_FULL:
|
case OE_FULL:
|
||||||
|
@ -1037,18 +1239,6 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
||||||
|
|
||||||
if( !( line -> Marker() & MK_HEAD ) )
|
if( !( line -> Marker() & MK_HEAD ) )
|
||||||
{
|
{
|
||||||
if( effort == OE_MEDIUM || effort == OE_LOW )
|
|
||||||
{
|
|
||||||
RANGE<int> r = findShovedVertexRange( line );
|
|
||||||
|
|
||||||
if( r.Defined() )
|
|
||||||
{
|
|
||||||
int start_v = std::max( 0, r.MinV() - extend );
|
|
||||||
int end_v = std::min( line->PointCount() - 1 , r.MaxV() + extend );
|
|
||||||
line->ClipVertexRange( start_v, end_v );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PNS_LINE optimized;
|
PNS_LINE optimized;
|
||||||
|
|
||||||
if( optimizer.Optimize( line, &optimized ) )
|
if( optimizer.Optimize( line, &optimized ) )
|
||||||
|
@ -1063,47 +1253,6 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const RANGE<int> PNS_SHOVE::findShovedVertexRange( PNS_LINE* aL )
|
|
||||||
{
|
|
||||||
RANGE<int> r;
|
|
||||||
|
|
||||||
for( int i = 0; i < aL->SegmentCount(); i++ )
|
|
||||||
{
|
|
||||||
PNS_SEGMENT* s = (*aL->LinkedSegments())[i];
|
|
||||||
PNS_JOINT* jt = m_root->FindJoint( s->Seg().A, s->Layer(), s->Net() );
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
if( jt )
|
|
||||||
{
|
|
||||||
BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
|
|
||||||
{
|
|
||||||
if( item->OfKind( PNS_ITEM::SEGMENT ) )
|
|
||||||
{
|
|
||||||
PNS_SEGMENT* s_old = (PNS_SEGMENT*) item;
|
|
||||||
|
|
||||||
if( s_old->Net() == s->Net() &&
|
|
||||||
s_old->Layer() == s->Layer() &&
|
|
||||||
s_old->Seg().A == s->Seg().A &&
|
|
||||||
s_old->Seg().B == s->Seg().B )
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !found )
|
|
||||||
{
|
|
||||||
r.Grow( i );
|
|
||||||
r.Grow( i + 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PNS_NODE* PNS_SHOVE::CurrentNode()
|
PNS_NODE* PNS_SHOVE::CurrentNode()
|
||||||
{
|
{
|
||||||
return m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
return m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||||
|
|
|
@ -61,7 +61,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
SHOVE_STATUS ShoveLines( const PNS_LINE& aCurrentHead );
|
SHOVE_STATUS ShoveLines( const PNS_LINE& aCurrentHead );
|
||||||
|
SHOVE_STATUS ShoveMultiLines( const PNS_ITEMSET& aHeadSet );
|
||||||
|
|
||||||
SHOVE_STATUS ShoveDraggingVia( PNS_VIA*aVia, const VECTOR2I& aWhere, PNS_VIA** aNewVia );
|
SHOVE_STATUS ShoveDraggingVia( PNS_VIA*aVia, const VECTOR2I& aWhere, PNS_VIA** aNewVia );
|
||||||
|
SHOVE_STATUS ProcessSingleLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
||||||
|
PNS_LINE* aShoved );
|
||||||
|
|
||||||
|
void ForceClearance ( bool aEnabled, int aClearance )
|
||||||
|
{
|
||||||
|
if( aEnabled )
|
||||||
|
m_forceClearance = aClearance;
|
||||||
|
else
|
||||||
|
m_forceClearance = -1;
|
||||||
|
}
|
||||||
|
|
||||||
PNS_NODE* CurrentNode();
|
PNS_NODE* CurrentNode();
|
||||||
|
|
||||||
|
@ -83,15 +95,15 @@ private:
|
||||||
PNS_NODE* m_node;
|
PNS_NODE* m_node;
|
||||||
PNS_ITEMSET m_headItems;
|
PNS_ITEMSET m_headItems;
|
||||||
PNS_COST_ESTIMATOR m_cost;
|
PNS_COST_ESTIMATOR m_cost;
|
||||||
|
OPT_BOX2I m_affectedArea;
|
||||||
};
|
};
|
||||||
|
|
||||||
SHOVE_STATUS processSingleLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle, PNS_LINE* aShoved );
|
|
||||||
SHOVE_STATUS processHullSet( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
SHOVE_STATUS processHullSet( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
||||||
PNS_LINE* aShoved, const HULL_SET& hulls );
|
PNS_LINE* aShoved, const HULL_SET& hulls );
|
||||||
|
|
||||||
bool reduceSpringback( const PNS_ITEMSET& aHeadItems );
|
bool reduceSpringback( const PNS_ITEMSET& aHeadItems );
|
||||||
bool pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET &aHeadItems,
|
bool pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems,
|
||||||
const PNS_COST_ESTIMATOR& aCost );
|
const PNS_COST_ESTIMATOR& aCost, const OPT_BOX2I& aAffectedArea );
|
||||||
|
|
||||||
SHOVE_STATUS walkaroundLoneVia( PNS_LINE* aCurrent, PNS_LINE* aObstacle, PNS_LINE* aShoved );
|
SHOVE_STATUS walkaroundLoneVia( PNS_LINE* aCurrent, PNS_LINE* aObstacle, PNS_LINE* aShoved );
|
||||||
bool checkBumpDirection( PNS_LINE* aCurrent, PNS_LINE* aShoved ) const;
|
bool checkBumpDirection( PNS_LINE* aCurrent, PNS_LINE* aShoved ) const;
|
||||||
|
@ -101,7 +113,9 @@ private:
|
||||||
SHOVE_STATUS onCollidingSolid( PNS_LINE* aCurrent, PNS_SOLID* aObstacleSolid );
|
SHOVE_STATUS onCollidingSolid( PNS_LINE* aCurrent, PNS_SOLID* aObstacleSolid );
|
||||||
SHOVE_STATUS onCollidingVia( PNS_ITEM* aCurrent, PNS_VIA* aObstacleVia );
|
SHOVE_STATUS onCollidingVia( PNS_ITEM* aCurrent, PNS_VIA* aObstacleVia );
|
||||||
SHOVE_STATUS onReverseCollidingVia( PNS_LINE* aCurrent, PNS_VIA* aObstacleVia );
|
SHOVE_STATUS onReverseCollidingVia( PNS_LINE* aCurrent, PNS_VIA* aObstacleVia );
|
||||||
SHOVE_STATUS pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank );
|
SHOVE_STATUS pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank, bool aDryRun = false );
|
||||||
|
|
||||||
|
OPT_BOX2I totalAffectedArea() const;
|
||||||
|
|
||||||
void unwindStack( PNS_SEGMENT* aSeg );
|
void unwindStack( PNS_SEGMENT* aSeg );
|
||||||
void unwindStack( PNS_ITEM* aItem );
|
void unwindStack( PNS_ITEM* aItem );
|
||||||
|
@ -111,14 +125,25 @@ private:
|
||||||
void pushLine( PNS_LINE* aL );
|
void pushLine( PNS_LINE* aL );
|
||||||
void popLine();
|
void popLine();
|
||||||
|
|
||||||
const RANGE<int> findShovedVertexRange( PNS_LINE* aL );
|
|
||||||
|
|
||||||
PNS_LINE* assembleLine( const PNS_SEGMENT* aSeg, int* aIndex = NULL );
|
PNS_LINE* assembleLine( const PNS_SEGMENT* aSeg, int* aIndex = NULL );
|
||||||
PNS_LINE* cloneLine( const PNS_LINE* aLine );
|
|
||||||
|
void replaceItems( PNS_ITEM *aOld, PNS_ITEM *aNew );
|
||||||
|
|
||||||
|
template<class T> T* clone ( const T* aItem )
|
||||||
|
{
|
||||||
|
T *cloned = aItem->Clone();
|
||||||
|
|
||||||
|
m_gcItems.push_back( cloned );
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
OPT_BOX2I m_affectedAreaSum;
|
||||||
|
|
||||||
SHOVE_STATUS shoveIteration( int aIter );
|
SHOVE_STATUS shoveIteration( int aIter );
|
||||||
SHOVE_STATUS shoveMainLoop();
|
SHOVE_STATUS shoveMainLoop();
|
||||||
|
|
||||||
|
int getClearance( PNS_ITEM *aA, PNS_ITEM *aB ) const;
|
||||||
|
|
||||||
std::vector<SPRINGBACK_TAG> m_nodeStack;
|
std::vector<SPRINGBACK_TAG> m_nodeStack;
|
||||||
std::vector<PNS_LINE*> m_lineStack;
|
std::vector<PNS_LINE*> m_lineStack;
|
||||||
std::vector<PNS_LINE*> m_optimizerQueue;
|
std::vector<PNS_LINE*> m_optimizerQueue;
|
||||||
|
@ -131,8 +156,12 @@ private:
|
||||||
|
|
||||||
PNS_LOGGER m_logger;
|
PNS_LOGGER m_logger;
|
||||||
PNS_VIA* m_draggedVia;
|
PNS_VIA* m_draggedVia;
|
||||||
|
PNS_ITEMSET m_draggedViaHeadSet;
|
||||||
|
|
||||||
int m_iter;
|
int m_iter;
|
||||||
|
int m_forceClearance;
|
||||||
|
bool m_multiLineMode;
|
||||||
|
bool m_headModified;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __PNS_SHOVE_H
|
#endif // __PNS_SHOVE_H
|
||||||
|
|
|
@ -66,6 +66,7 @@ int PNS_SIZES_SETTINGS::inheritTrackWidth( PNS_ITEM* aItem )
|
||||||
return ( mval == INT_MAX ? 0 : mval );
|
return ( mval == INT_MAX ? 0 : mval );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_SIZES_SETTINGS::Init( BOARD* aBoard, PNS_ITEM* aStartItem, int aNet )
|
void PNS_SIZES_SETTINGS::Init( BOARD* aBoard, PNS_ITEM* aStartItem, int aNet )
|
||||||
{
|
{
|
||||||
BOARD_DESIGN_SETTINGS &bds = aBoard->GetDesignSettings();
|
BOARD_DESIGN_SETTINGS &bds = aBoard->GetDesignSettings();
|
||||||
|
@ -121,11 +122,13 @@ void PNS_SIZES_SETTINGS::Init( BOARD* aBoard, PNS_ITEM* aStartItem, int aNet )
|
||||||
m_layerPairs.clear();
|
m_layerPairs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_SIZES_SETTINGS::ClearLayerPairs()
|
void PNS_SIZES_SETTINGS::ClearLayerPairs()
|
||||||
{
|
{
|
||||||
m_layerPairs.clear();
|
m_layerPairs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_SIZES_SETTINGS::AddLayerPair( int aL1, int aL2 )
|
void PNS_SIZES_SETTINGS::AddLayerPair( int aL1, int aL2 )
|
||||||
{
|
{
|
||||||
int top = std::min( aL1, aL2 );
|
int top = std::min( aL1, aL2 );
|
||||||
|
@ -135,6 +138,7 @@ void PNS_SIZES_SETTINGS::AddLayerPair( int aL1, int aL2 )
|
||||||
m_layerPairs[top] = bottom;
|
m_layerPairs[top] = bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings )
|
void PNS_SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings )
|
||||||
{
|
{
|
||||||
m_trackWidth = aSettings.GetCurrentTrackWidth();
|
m_trackWidth = aSettings.GetCurrentTrackWidth();
|
||||||
|
@ -142,6 +146,7 @@ void PNS_SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings )
|
||||||
m_viaDrill = aSettings.GetCurrentViaDrill();
|
m_viaDrill = aSettings.GetCurrentViaDrill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PNS_SIZES_SETTINGS::GetLayerTop() const
|
int PNS_SIZES_SETTINGS::GetLayerTop() const
|
||||||
{
|
{
|
||||||
if( m_layerPairs.empty() )
|
if( m_layerPairs.empty() )
|
||||||
|
@ -150,6 +155,7 @@ int PNS_SIZES_SETTINGS::GetLayerTop() const
|
||||||
return m_layerPairs.begin()->first;
|
return m_layerPairs.begin()->first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PNS_SIZES_SETTINGS::GetLayerBottom() const
|
int PNS_SIZES_SETTINGS::GetLayerBottom() const
|
||||||
{
|
{
|
||||||
if( m_layerPairs.empty() )
|
if( m_layerPairs.empty() )
|
||||||
|
|
|
@ -34,18 +34,20 @@ class PNS_SIZES_SETTINGS {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PNS_SIZES_SETTINGS() :
|
PNS_SIZES_SETTINGS() :
|
||||||
m_trackWidth( 100000 ),
|
m_trackWidth( 155000 ),
|
||||||
m_diffPairWidth( 100000 ),
|
m_diffPairWidth( 125000 ),
|
||||||
m_diffPairGap( 125000 ),
|
m_diffPairGap( 180000 ),
|
||||||
m_viaDiameter( 500000 ),
|
m_diffPairViaGap ( 180000 ),
|
||||||
m_viaDrill( 200000 ),
|
m_viaDiameter( 600000 ),
|
||||||
|
m_viaDrill( 250000 ),
|
||||||
|
m_diffPairViaGapSameAsTraceGap ( true ),
|
||||||
m_viaType( VIA_THROUGH )
|
m_viaType( VIA_THROUGH )
|
||||||
{};
|
{};
|
||||||
|
|
||||||
~PNS_SIZES_SETTINGS() {};
|
~PNS_SIZES_SETTINGS() {};
|
||||||
|
|
||||||
void Init( BOARD* aBoard, PNS_ITEM* aStartItem = NULL, int aNet = -1 );
|
void Init( BOARD* aBoard, PNS_ITEM* aStartItem = NULL, int aNet = -1 );
|
||||||
void ImportCurrent ( BOARD_DESIGN_SETTINGS& aSettings );
|
void ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings );
|
||||||
|
|
||||||
void ClearLayerPairs();
|
void ClearLayerPairs();
|
||||||
void AddLayerPair( int aL1, int aL2 );
|
void AddLayerPair( int aL1, int aL2 );
|
||||||
|
@ -54,9 +56,22 @@ public:
|
||||||
void SetTrackWidth( int aWidth ) { m_trackWidth = aWidth; }
|
void SetTrackWidth( int aWidth ) { m_trackWidth = aWidth; }
|
||||||
|
|
||||||
int DiffPairWidth() const { return m_diffPairWidth; }
|
int DiffPairWidth() const { return m_diffPairWidth; }
|
||||||
|
|
||||||
int DiffPairGap() const { return m_diffPairGap; }
|
int DiffPairGap() const { return m_diffPairGap; }
|
||||||
|
|
||||||
|
int DiffPairViaGap() const {
|
||||||
|
if(m_diffPairViaGapSameAsTraceGap)
|
||||||
|
return m_diffPairGap;
|
||||||
|
else
|
||||||
|
return m_diffPairViaGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DiffPairViaGapSameAsTraceGap() const { return m_diffPairViaGapSameAsTraceGap; }
|
||||||
|
|
||||||
|
void SetDiffPairWidth( int aWidth ) { m_diffPairWidth = aWidth; }
|
||||||
|
void SetDiffPairGap( int aGap ) { m_diffPairGap = aGap; }
|
||||||
|
void SetDiffPairViaGapSameAsTraceGap ( bool aEnable ) { m_diffPairViaGapSameAsTraceGap = aEnable; }
|
||||||
|
void SetDiffPairViaGap( int aGap ) { m_diffPairViaGap = aGap; }
|
||||||
|
|
||||||
int ViaDiameter() const { return m_viaDiameter; }
|
int ViaDiameter() const { return m_viaDiameter; }
|
||||||
void SetViaDiameter( int aDiameter) { m_viaDiameter = aDiameter; }
|
void SetViaDiameter( int aDiameter) { m_viaDiameter = aDiameter; }
|
||||||
|
|
||||||
|
@ -68,7 +83,7 @@ public:
|
||||||
if( m_layerPairs.find(aLayerId) == m_layerPairs.end() )
|
if( m_layerPairs.find(aLayerId) == m_layerPairs.end() )
|
||||||
return boost::optional<int>();
|
return boost::optional<int>();
|
||||||
|
|
||||||
return m_layerPairs [ aLayerId ];
|
return m_layerPairs[aLayerId];
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetLayerTop() const;
|
int GetLayerTop() const;
|
||||||
|
@ -84,9 +99,12 @@ private:
|
||||||
int m_trackWidth;
|
int m_trackWidth;
|
||||||
int m_diffPairWidth;
|
int m_diffPairWidth;
|
||||||
int m_diffPairGap;
|
int m_diffPairGap;
|
||||||
|
int m_diffPairViaGap;
|
||||||
int m_viaDiameter;
|
int m_viaDiameter;
|
||||||
int m_viaDrill;
|
int m_viaDrill;
|
||||||
|
|
||||||
|
bool m_diffPairViaGapSameAsTraceGap;
|
||||||
|
|
||||||
VIATYPE_T m_viaType;
|
VIATYPE_T m_viaType;
|
||||||
|
|
||||||
std::map<int, int> m_layerPairs;
|
std::map<int, int> m_layerPairs;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue