From 5f37c2b2474b08dc67d17c5506a85b9667c5b30e Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 5 Sep 2021 16:06:12 +0100 Subject: [PATCH] Custom rule severities. ADDED severity token to custom rule syntax. Each rule can now define its own severity. Fixes https://gitlab.com/kicad/code/kicad/issues/6148 --- common/drc_rules.keywords | 5 + common/rc_item.cpp | 46 +- include/marker_base.h | 2 + include/widgets/report_severity.h | 8 +- pcbnew/board.cpp | 4 +- pcbnew/dialogs/dialog_drc.cpp | 7 +- pcbnew/dialogs/dialog_plot.cpp | 2 +- pcbnew/dialogs/panel_setup_rules.cpp | 10 +- pcbnew/dialogs/panel_setup_rules_help.md | 11 + pcbnew/drc/drc_engine.cpp | 72 +- pcbnew/drc/drc_engine.h | 3 +- pcbnew/drc/drc_results_provider.cpp | 22 +- pcbnew/drc/drc_rule.cpp | 6 +- pcbnew/drc/drc_rule.h | 10 + pcbnew/drc/drc_rule_parser.cpp | 39 + pcbnew/drc/drc_rule_parser.h | 1 + pcbnew/drc/drc_test_provider.h | 2 - .../drc/drc_test_provider_annular_width.cpp | 11 +- pcbnew/drc/drc_test_provider_connectivity.cpp | 8 - .../drc_test_provider_copper_clearance.cpp | 330 +- .../drc_test_provider_courtyard_clearance.cpp | 72 +- .../drc_test_provider_diff_pair_coupling.cpp | 18 +- pcbnew/drc/drc_test_provider_disallow.cpp | 10 +- .../drc/drc_test_provider_edge_clearance.cpp | 43 +- pcbnew/drc/drc_test_provider_hole_size.cpp | 14 +- pcbnew/drc/drc_test_provider_hole_to_hole.cpp | 12 +- .../drc/drc_test_provider_library_parity.cpp | 8 - .../drc/drc_test_provider_matched_length.cpp | 14 +- ...drc_test_provider_mechanical_clearance.cpp | 72 +- pcbnew/drc/drc_test_provider_misc.cpp | 8 - .../drc_test_provider_schematic_parity.cpp | 8 - .../drc/drc_test_provider_silk_clearance.cpp | 10 +- .../drc/drc_test_provider_sliver_checker.cpp | 5 - pcbnew/drc/drc_test_provider_solder_mask.cpp | 10 +- pcbnew/drc/drc_test_provider_text_dims.cpp | 46 +- pcbnew/drc/drc_test_provider_track_width.cpp | 27 +- pcbnew/drc/drc_test_provider_via_diameter.cpp | 27 +- .../drc_test_provider_zone_connections.cpp | 8 +- pcbnew/pcb_display_options.cpp | 5 - pcbnew/pcb_edit_frame.cpp | 4 +- pcbnew/pcb_marker.cpp | 54 +- pcbnew/pcb_marker.h | 2 + .../scripting/pcbnew_scripting_helpers.cpp | 2 +- qa/data/custom_pads.kicad_pro | 128 +- qa/data/issue1358.kicad_pro | 14 +- qa/data/severities.kicad_dru | 5 + qa/data/severities.kicad_pcb | 3482 +++++++++++++++++ qa/data/severities.kicad_pro | 417 ++ qa/pcbnew/CMakeLists.txt | 1 + qa/pcbnew/drc/test_custom_rule_severities.cpp | 84 + qa/pcbnew/drc/test_solder_mask_bridging.cpp | 5 +- 51 files changed, 4624 insertions(+), 590 deletions(-) create mode 100644 qa/data/severities.kicad_dru create mode 100644 qa/data/severities.kicad_pcb create mode 100644 qa/data/severities.kicad_pro create mode 100644 qa/pcbnew/drc/test_custom_rule_severities.cpp diff --git a/common/drc_rules.keywords b/common/drc_rules.keywords index c490def6d6..4f5c24059a 100644 --- a/common/drc_rules.keywords +++ b/common/drc_rules.keywords @@ -9,12 +9,15 @@ diff_pair_gap diff_pair_uncoupled disallow edge_clearance +error +exclusion footprint graphic hole hole_clearance hole_size hole_to_hole +ignore inner layer length @@ -31,6 +34,7 @@ outer pad pth rule +severity silk_clearance skew solid @@ -46,5 +50,6 @@ version via via_count via_diameter +warning zone zone_connection diff --git a/common/rc_item.cpp b/common/rc_item.cpp index 4edc851ed4..0249b0d385 100644 --- a/common/rc_item.cpp +++ b/common/rc_item.cpp @@ -83,10 +83,11 @@ wxString RC_ITEM::ShowReport( EDA_UNITS aUnits, SEVERITY aSeverity, switch( aSeverity ) { - case RPT_SEVERITY_ERROR: severity = wxT( "Severity: error" ); break; - case RPT_SEVERITY_WARNING: severity = wxT( "Severity: warning" ); break; - case RPT_SEVERITY_ACTION: severity = wxT( "Severity: action" ); break; - case RPT_SEVERITY_INFO: severity = wxT( "Severity: info" ); break; + case RPT_SEVERITY_ERROR: severity = wxT( "Severity: error" ); break; + case RPT_SEVERITY_WARNING: severity = wxT( "Severity: warning" ); break; + case RPT_SEVERITY_ACTION: severity = wxT( "Severity: action" ); break; + case RPT_SEVERITY_INFO: severity = wxT( "Severity: info" ); break; + case RPT_SEVERITY_EXCLUSION: severity = wxT( "Severity: exclusion" ); break; default: ; }; @@ -349,20 +350,25 @@ void RC_TREE_MODEL::GetValue( wxVariant& aVariant, { wxString prefix; - if( rcItem->GetParent() && rcItem->GetParent()->IsExcluded() ) - prefix = _( "Excluded " ); - - switch( m_editFrame->GetSeverity( rcItem->GetErrorCode() ) ) + if( rcItem->GetParent() ) { - case RPT_SEVERITY_ERROR: prefix += _( "Error: " ); break; - case RPT_SEVERITY_WARNING: prefix += _( "Warning: " ); break; + SEVERITY severity = rcItem->GetParent()->GetSeverity(); - case RPT_SEVERITY_EXCLUSION: - case RPT_SEVERITY_UNDEFINED: - case RPT_SEVERITY_INFO: - case RPT_SEVERITY_ACTION: - case RPT_SEVERITY_IGNORE: - break; + if( severity == RPT_SEVERITY_EXCLUSION ) + { + if( m_editFrame->GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING ) + prefix = _( "Excluded warning: " ); + else + prefix = _( "Excluded error: " ); + } + else if( severity == RPT_SEVERITY_WARNING ) + { + prefix = _( "Warning: " ); + } + else + { + prefix = _( "Error: " ); + } } aVariant = prefix + rcItem->GetErrorMessage(); @@ -416,7 +422,8 @@ bool RC_TREE_MODEL::GetAttr( wxDataViewItem const& aItem, ret = true; } - if( node->m_RcItem->GetParent() && node->m_RcItem->GetParent()->IsExcluded() ) + if( node->m_RcItem->GetParent() + && node->m_RcItem->GetParent()->GetSeverity() == RPT_SEVERITY_EXCLUSION ) { wxColour textColour = wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXTEXT ); double brightness = KIGFX::COLOR4D( textColour ).GetBrightness(); @@ -493,7 +500,10 @@ void RC_TREE_MODEL::DeleteItems( bool aCurrentOnly, bool aIncludeExclusions, boo { std::shared_ptr rcItem = m_rcItemsProvider->GetItem( i ); MARKER_BASE* marker = rcItem->GetParent(); - bool excluded = marker ? marker->IsExcluded() : false; + bool excluded = false; + + if( marker && marker->GetSeverity() == RPT_SEVERITY_EXCLUSION ) + excluded = true; if( aCurrentOnly && itemDeleted && lastGood >= 0 ) break; diff --git a/include/marker_base.h b/include/marker_base.h index fe64c5a742..7000082115 100644 --- a/include/marker_base.h +++ b/include/marker_base.h @@ -95,6 +95,8 @@ public: bool IsExcluded() const { return m_excluded; } void SetExcluded( bool aExcluded ) { m_excluded = aExcluded; } + virtual SEVERITY GetSeverity() const { return RPT_SEVERITY_UNDEFINED; } + /** * @return the #RC_ITEM held within this marker so that its interface may be used. */ diff --git a/include/widgets/report_severity.h b/include/widgets/report_severity.h index 5329689485..1433d35b8a 100644 --- a/include/widgets/report_severity.h +++ b/include/widgets/report_severity.h @@ -18,11 +18,11 @@ */ -#ifndef _REPORT_SEVERITY_H_ -#define _REPORT_SEVERITY_H_ +#ifndef REPORT_SEVERITY_H +#define REPORT_SEVERITY_H // Note: On windows, SEVERITY_ERROR collides with a system declaration, -// so we used RPT_SEVERITY _xxx instead of SEVERITY _xxx +// so we used RPT_SEVERITY_xxx instead of SEVERITY_xxx enum SEVERITY { RPT_SEVERITY_UNDEFINED = 0x00, RPT_SEVERITY_INFO = 0x01, @@ -33,4 +33,4 @@ enum SEVERITY { RPT_SEVERITY_IGNORE = 0x20 }; -#endif // _REPORT_SEVERITY_H_ +#endif // REPORT_SEVERITY_H diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp index 193c714ec8..df501d7e38 100644 --- a/pcbnew/board.cpp +++ b/pcbnew/board.cpp @@ -823,8 +823,8 @@ void BOARD::DeleteMARKERs( bool aWarningsAndErrors, bool aExclusions ) for( PCB_MARKER* marker : m_markers ) { - if( ( marker->IsExcluded() && aExclusions ) - || ( !marker->IsExcluded() && aWarningsAndErrors ) ) + if( ( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION && aExclusions ) + || ( marker->GetSeverity() != RPT_SEVERITY_EXCLUSION && aWarningsAndErrors ) ) { delete marker; } diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp index 3b09eec205..52f2efdb77 100644 --- a/pcbnew/dialogs/dialog_drc.cpp +++ b/pcbnew/dialogs/dialog_drc.cpp @@ -822,7 +822,7 @@ void DIALOG_DRC::ExcludeMarker() RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( m_markerDataView->GetCurrentItem() ); PCB_MARKER* marker = dynamic_cast( node->m_RcItem->GetParent() ); - if( marker && !marker->IsExcluded() ) + if( marker && !marker->GetSeverity() == RPT_SEVERITY_EXCLUSION ) { marker->SetExcluded( true ); m_frame->GetCanvas()->GetView()->Update( marker ); @@ -876,7 +876,10 @@ bool DIALOG_DRC::writeReport( const wxString& aFullFileName ) for( int i = 0; i < count; ++i ) { const std::shared_ptr& item = m_markersProvider->GetItem( i ); - SEVERITY severity = bds.GetSeverity( item->GetErrorCode() ); + SEVERITY severity = item->GetParent()->GetSeverity(); + + if( severity == RPT_SEVERITY_EXCLUSION ) + severity = bds.GetSeverity( item->GetErrorCode() ); fprintf( fp, "%s", TO_UTF8( item->ShowReport( units, severity, itemMap ) ) ); } diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp index 262c6b7f54..ebabc822d0 100644 --- a/pcbnew/dialogs/dialog_plot.cpp +++ b/pcbnew/dialogs/dialog_plot.cpp @@ -240,7 +240,7 @@ void DIALOG_PLOT::reInitDialog() for( PCB_MARKER* marker : m_parent->GetBoard()->Markers() ) { - if( marker->IsExcluded() ) + if( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION ) exclusions++; else knownViolations++; diff --git a/pcbnew/dialogs/panel_setup_rules.cpp b/pcbnew/dialogs/panel_setup_rules.cpp index 2d7f94aec5..3af1678b45 100644 --- a/pcbnew/dialogs/panel_setup_rules.cpp +++ b/pcbnew/dialogs/panel_setup_rules.cpp @@ -275,7 +275,8 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent ) { tokens = "condition|" "constraint|" - "layer"; + "layer|" + "severity"; } else if( sexprs.top() == "constraint" ) { @@ -345,6 +346,13 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent ) { tokens = "warning|error|ignore|exclusion"; } + else if( sexprs.top() == "severity" ) + { + tokens = "error " + "exclusion " + "ignore " + "warning"; + } } else if( context == STRING && !sexprs.empty() && sexprs.top() == "condition" ) { diff --git a/pcbnew/dialogs/panel_setup_rules_help.md b/pcbnew/dialogs/panel_setup_rules_help.md index 30d598e237..5a5abab155 100644 --- a/pcbnew/dialogs/panel_setup_rules_help.md +++ b/pcbnew/dialogs/panel_setup_rules_help.md @@ -15,6 +15,8 @@ (layer "") + (severity ) +
@@ -69,6 +71,15 @@ Note: `clearance` and `hole_clearance` rules are not run against items of the sa
+### Severity Names + + * warning + * error + * exclusion + * ignore + +
+ ### Examples (version 1) diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index e94b1949fa..636c6f0f8b 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -42,6 +42,11 @@ #include +// wxListBox's performance degrades horrifically with very large datasets. It's not clear +// they're useful to the user anyway. +#define ERROR_LIMIT_MAX 199 + + void drcPrintDebugMessage( int level, const wxString& msg, const char *function, int line ) { wxString valueStr; @@ -73,7 +78,7 @@ DRC_ENGINE::DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS *aSettings ) : m_errorLimits.resize( DRCE_LAST + 1 ); for( int ii = DRCE_FIRST; ii <= DRCE_LAST; ++ii ) - m_errorLimits[ ii ] = INT_MAX; + m_errorLimits[ ii ] = ERROR_LIMIT_MAX; } @@ -502,43 +507,28 @@ void DRC_ENGINE::compileRules() { ReportAux( wxString::Format( "Compiling Rules (%d rules): ", (int) m_rules.size() ) ); - std::set constraintTypes; - - for( DRC_TEST_PROVIDER* provider : m_testProviders ) + for( DRC_RULE* rule : m_rules ) { - for( DRC_CONSTRAINT_T constraintType : provider->GetConstraintTypes() ) - constraintTypes.insert( constraintType ); - } + DRC_RULE_CONDITION* condition = nullptr; - for( DRC_CONSTRAINT_T constraintType : constraintTypes ) - { - if( m_constraintMap.find( constraintType ) == m_constraintMap.end() ) - m_constraintMap[ constraintType ] = new std::vector(); - - for( DRC_RULE* rule : m_rules ) + if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() ) { - DRC_RULE_CONDITION* condition = nullptr; + condition = rule->m_Condition; + condition->Compile( nullptr ); + } - if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() ) - { - condition = rule->m_Condition; - condition->Compile( nullptr, 0, 0 ); // fixme - } + for( const DRC_CONSTRAINT& constraint : rule->m_Constraints ) + { + if( !m_constraintMap.count( constraint.m_Type ) ) + m_constraintMap[ constraint.m_Type ] = new std::vector(); - for( const DRC_CONSTRAINT& constraint : rule->m_Constraints ) - { - if( constraint.m_Type == constraintType ) - { - DRC_ENGINE_CONSTRAINT* engineConstraint = new DRC_ENGINE_CONSTRAINT; + DRC_ENGINE_CONSTRAINT* engineConstraint = new DRC_ENGINE_CONSTRAINT; - engineConstraint->layerTest = rule->m_LayerCondition; - engineConstraint->condition = condition; - - engineConstraint->constraint = constraint; - engineConstraint->parentRule = rule; - m_constraintMap[ constraintType ]->push_back( engineConstraint ); - } - } + engineConstraint->layerTest = rule->m_LayerCondition; + engineConstraint->condition = condition; + engineConstraint->constraint = constraint; + engineConstraint->parentRule = rule; + m_constraintMap[ constraint.m_Type ]->push_back( engineConstraint ); } } } @@ -594,7 +584,7 @@ void DRC_ENGINE::InitEngine( const wxFileName& aRulePath ) } for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii ) - m_errorLimits[ ii ] = INT_MAX; + m_errorLimits[ ii ] = ERROR_LIMIT_MAX; m_rulesValid = true; } @@ -612,7 +602,7 @@ void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aT if( m_designSettings->Ignore( ii ) ) m_errorLimits[ ii ] = 0; else - m_errorLimits[ ii ] = INT_MAX; + m_errorLimits[ ii ] = ERROR_LIMIT_MAX; } m_board->IncrementTimeStamp(); // Invalidate all caches @@ -670,15 +660,13 @@ void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aT for( DRC_TEST_PROVIDER* provider : m_testProviders ) { - if( !provider->IsEnabled() ) - continue; + if( provider->IsEnabled() ) + { + ReportAux( wxString::Format( "Run DRC provider: '%s'", provider->GetName() ) ); - drc_dbg( 0, "Running test provider: '%s'\n", provider->GetName() ); - - ReportAux( wxString::Format( "Run DRC provider: '%s'", provider->GetName() ) ); - - if( !provider->Run() ) - break; + if( !provider->Run() ) + break; + } } } diff --git a/pcbnew/drc/drc_engine.h b/pcbnew/drc/drc_engine.h index db4ce88696..3e2290cc84 100644 --- a/pcbnew/drc/drc_engine.h +++ b/pcbnew/drc/drc_engine.h @@ -143,7 +143,6 @@ public: */ void RunTests( EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints ); - bool IsErrorLimitExceeded( int error_code ); DRC_CONSTRAINT EvalRules( DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM* a, @@ -168,7 +167,7 @@ public: bool QueryWorstConstraint( DRC_CONSTRAINT_T aRuleId, DRC_CONSTRAINT& aConstraint ); - std::vector GetTestProviders() const { return m_testProviders; }; + std::vector GetTestProviders() const { return m_testProviders; }; DRC_TEST_PROVIDER* GetTestProvider( const wxString& name ) const; diff --git a/pcbnew/drc/drc_results_provider.cpp b/pcbnew/drc/drc_results_provider.cpp index 9a9d27f0bc..128d21ee44 100644 --- a/pcbnew/drc/drc_results_provider.cpp +++ b/pcbnew/drc/drc_results_provider.cpp @@ -28,20 +28,11 @@ void BOARD_DRC_ITEMS_PROVIDER::SetSeverities( int aSeverities ) { m_severities = aSeverities; - BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); - m_filteredMarkers.clear(); for( PCB_MARKER* marker : m_board->Markers() ) { - SEVERITY markerSeverity; - - if( marker->IsExcluded() ) - markerSeverity = RPT_SEVERITY_EXCLUSION; - else - markerSeverity = bds.GetSeverity( marker->GetRCItem()->GetErrorCode() ); - - if( markerSeverity & m_severities ) + if( marker->GetSeverity() & m_severities ) m_filteredMarkers.push_back( marker ); } } @@ -52,20 +43,11 @@ int BOARD_DRC_ITEMS_PROVIDER::GetCount( int aSeverity ) const if( aSeverity < 0 ) return m_filteredMarkers.size(); - BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); - int count = 0; for( PCB_MARKER* marker : m_board->Markers() ) { - SEVERITY markerSeverity; - - if( marker->IsExcluded() ) - markerSeverity = RPT_SEVERITY_EXCLUSION; - else - markerSeverity = bds.GetSeverity( marker->GetRCItem()->GetErrorCode() ); - - if( markerSeverity == aSeverity ) + if( marker->GetSeverity() == aSeverity ) count++; } diff --git a/pcbnew/drc/drc_rule.cpp b/pcbnew/drc/drc_rule.cpp index da0cc87c52..abbc5c4446 100644 --- a/pcbnew/drc/drc_rule.cpp +++ b/pcbnew/drc/drc_rule.cpp @@ -32,7 +32,8 @@ DRC_RULE::DRC_RULE() : m_Unary( false ), m_Implicit( false ), m_LayerCondition( LSET::AllLayersMask() ), - m_Condition( nullptr ) + m_Condition( nullptr ), + m_Severity( RPT_SEVERITY_UNDEFINED ) { } @@ -42,7 +43,8 @@ DRC_RULE::DRC_RULE( const wxString& aName ) : m_Implicit( false ), m_Name( aName ), m_LayerCondition( LSET::AllLayersMask() ), - m_Condition( nullptr ) + m_Condition( nullptr ), + m_Severity( RPT_SEVERITY_UNDEFINED ) { } diff --git a/pcbnew/drc/drc_rule.h b/pcbnew/drc/drc_rule.h index 4a0042f57f..95f5b2bf07 100644 --- a/pcbnew/drc/drc_rule.h +++ b/pcbnew/drc/drc_rule.h @@ -32,6 +32,7 @@ #include #include #include +#include class BOARD_ITEM; class PCB_EXPR_UCODE; @@ -109,6 +110,7 @@ public: LSET m_LayerCondition; DRC_RULE_CONDITION* m_Condition; std::vector m_Constraints; + SEVERITY m_Severity; }; @@ -152,6 +154,14 @@ class DRC_CONSTRAINT return m_name; } + SEVERITY GetSeverity() const + { + if( m_parentRule ) + return m_parentRule->m_Severity; + else + return RPT_SEVERITY_UNDEFINED; + } + public: DRC_CONSTRAINT_T m_Type; MINOPTMAX m_Value; diff --git a/pcbnew/drc/drc_rule_parser.cpp b/pcbnew/drc/drc_rule_parser.cpp index d829d9ff1b..52cc36e879 100644 --- a/pcbnew/drc/drc_rule_parser.cpp +++ b/pcbnew/drc/drc_rule_parser.cpp @@ -226,6 +226,10 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE() rule->m_LayerCondition = parseLayer(); break; + case T_severity: + rule->m_Severity = parseSeverity(); + break; + case T_EOF: reportError( _( "Incomplete statement." ) ); return rule; @@ -575,3 +579,38 @@ LSET DRC_RULES_PARSER::parseLayer() return retVal; } + + +SEVERITY DRC_RULES_PARSER::parseSeverity() +{ + SEVERITY retVal = RPT_SEVERITY_UNDEFINED; + wxString msg; + + T token = NextTok(); + + if( (int) token == DSN_RIGHT || token == T_EOF ) + { + reportError( _( "Missing severity name." ) ); + return RPT_SEVERITY_UNDEFINED; + } + + switch( token ) + { + case T_ignore: retVal = RPT_SEVERITY_IGNORE; break; + case T_warning: retVal = RPT_SEVERITY_WARNING; break; + case T_error: retVal = RPT_SEVERITY_ERROR; break; + case T_exclusion: retVal = RPT_SEVERITY_EXCLUSION; break; + + default: + msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), + FromUTF8(), + "ignore, warning, error or exclusion" ); + reportError( msg ); + parseUnknown(); + } + + if( (int) NextTok() != DSN_RIGHT ) + reportError( _( "Missing ')'." ) ); + + return retVal; +} \ No newline at end of file diff --git a/pcbnew/drc/drc_rule_parser.h b/pcbnew/drc/drc_rule_parser.h index 19dfa2abde..bd584503b4 100644 --- a/pcbnew/drc/drc_rule_parser.h +++ b/pcbnew/drc/drc_rule_parser.h @@ -51,6 +51,7 @@ private: void parseConstraint( DRC_RULE* aRule ); void parseValueWithUnits( const wxString& aExpr, int& aResult ); LSET parseLayer(); + SEVERITY parseSeverity(); void parseUnknown(); void reportError( const wxString& aMessage ); diff --git a/pcbnew/drc/drc_test_provider.h b/pcbnew/drc/drc_test_provider.h index ef2ecdaf60..2c0aa2173e 100644 --- a/pcbnew/drc/drc_test_provider.h +++ b/pcbnew/drc/drc_test_provider.h @@ -89,8 +89,6 @@ public: virtual const wxString GetName() const; virtual const wxString GetDescription() const; - virtual std::set GetConstraintTypes() const = 0; - bool IsEnabled() const { return m_enabled; diff --git a/pcbnew/drc/drc_test_provider_annular_width.cpp b/pcbnew/drc/drc_test_provider_annular_width.cpp index 38ad04faf8..e96adba124 100644 --- a/pcbnew/drc/drc_test_provider_annular_width.cpp +++ b/pcbnew/drc/drc_test_provider_annular_width.cpp @@ -61,8 +61,6 @@ public: { return "Tests pad/via annular rings"; } - - virtual std::set GetConstraintTypes() const override; }; @@ -106,6 +104,9 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run() bool fail_min = false; bool fail_max = false; + if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE ) + return true; + if( constraint.Value().HasMin() ) { v_min = constraint.Value().Min(); @@ -162,12 +163,6 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run() } -std::set DRC_TEST_PROVIDER_ANNULAR_WIDTH::GetConstraintTypes() const -{ - return { ANNULAR_WIDTH_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_connectivity.cpp b/pcbnew/drc/drc_test_provider_connectivity.cpp index 6be0b52e8a..1409570897 100644 --- a/pcbnew/drc/drc_test_provider_connectivity.cpp +++ b/pcbnew/drc/drc_test_provider_connectivity.cpp @@ -63,8 +63,6 @@ public: { return "Tests board connectivity"; } - - virtual std::set GetConstraintTypes() const override; }; @@ -173,12 +171,6 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run() } -std::set DRC_TEST_PROVIDER_CONNECTIVITY::GetConstraintTypes() const -{ - return {}; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_copper_clearance.cpp b/pcbnew/drc/drc_test_provider_copper_clearance.cpp index 7505e65e86..285065cf79 100644 --- a/pcbnew/drc/drc_test_provider_copper_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_copper_clearance.cpp @@ -78,8 +78,6 @@ public: return "Tests copper item clearance"; } - virtual std::set GetConstraintTypes() const override; - private: bool testTrackAgainstItem( PCB_TRACK* track, SHAPE* trackShape, PCB_LAYER_ID layer, BOARD_ITEM* other ); @@ -92,7 +90,7 @@ private: void testZonesToZones(); - void testItemAgainstZones( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer ); + void testItemAgainstZone( BOARD_ITEM* aItem, ZONE* aZone, PCB_LAYER_ID aLayer ); private: DRC_RTREE m_copperTree; @@ -280,7 +278,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track, clearance = constraint.GetValue().Min(); } - if( clearance >= 0 ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance >= 0 ) { // Special processing for track:track intersections if( track->Type() == PCB_TRACE_T && other->Type() == PCB_TRACE_T ) @@ -347,25 +345,27 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track, constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, other, track, layer ); clearance = constraint.GetValue().Min(); - if( clearance > 0 && trackShape->Collide( holeShape.get(), - std::max( 0, clearance - m_drcEpsilon ), - &actual, &pos ) ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance > 0 ) { - std::shared_ptr drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE ); + if( trackShape->Collide( holeShape.get(), std::max( 0, clearance - m_drcEpsilon ), + &actual, &pos ) ) + { + std::shared_ptr drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE ); - m_msg.Printf( _( "(%s clearance %s; actual %s)" ), - constraint.GetName(), - MessageTextFromValue( userUnits(), clearance ), - MessageTextFromValue( userUnits(), actual ) ); + m_msg.Printf( _( "(%s clearance %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), clearance ), + MessageTextFromValue( userUnits(), actual ) ); - drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); - drce->SetItems( track, other ); - drce->SetViolatingRule( constraint.GetParentRule() ); + drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); + drce->SetItems( track, other ); + drce->SetViolatingRule( constraint.GetParentRule() ); - reportViolation( drce, (wxPoint) pos ); + reportViolation( drce, (wxPoint) pos ); - if( !m_drcEngine->GetReportAllTrackErrors() ) - return false; + if( !m_drcEngine->GetReportAllTrackErrors() ) + return false; + } } } } @@ -374,71 +374,115 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track, } -void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem, +void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZone( BOARD_ITEM* aItem, ZONE* aZone, PCB_LAYER_ID aLayer ) { - for( ZONE* zone : m_copperZones ) - { - if( !zone->GetLayerSet().test( aLayer ) ) - continue; + if( !aZone->GetLayerSet().test( aLayer ) ) + return; - if( zone->GetNetCode() && aItem->IsConnected() ) + if( aZone->GetNetCode() && aItem->IsConnected() ) + { + if( aZone->GetNetCode() == static_cast( aItem )->GetNetCode() ) + return; + } + + if( !aItem->GetBoundingBox().Intersects( aZone->GetCachedBoundingBox() ) ) + return; + + bool testClearance = !m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ); + bool testHoles = !m_drcEngine->IsErrorLimitExceeded( DRCE_HOLE_CLEARANCE ); + + if( !testClearance && !testHoles ) + return; + + DRC_RTREE* zoneTree = m_board->m_CopperZoneRTrees[ aZone ].get(); + EDA_RECT itemBBox = aItem->GetBoundingBox(); + DRC_CONSTRAINT constraint; + int clearance = -1; + int actual; + VECTOR2I pos; + + if( zoneTree && testClearance ) + { + constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, aItem, aZone, aLayer ); + clearance = constraint.GetValue().Min(); + } + + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance >= 0 ) + { + std::shared_ptr itemShape = aItem->GetEffectiveShape( aLayer ); + + if( aItem->Type() == PCB_PAD_T ) { - if( zone->GetNetCode() == static_cast( aItem )->GetNetCode() ) - continue; + PAD* pad = static_cast( aItem ); + + if( !pad->FlashLayer( aLayer ) ) + { + if( pad->GetDrillSize().x == 0 && pad->GetDrillSize().y == 0 ) + return; + + const SHAPE_SEGMENT* hole = pad->GetEffectiveHoleShape(); + int size = hole->GetWidth(); + + // Note: drill size represents finish size, which means the actual hole + // size is the plating thickness larger. + if( pad->GetAttribute() == PAD_ATTRIB::PTH ) + size += m_board->GetDesignSettings().GetHolePlatingThickness(); + + itemShape = std::make_shared( hole->GetSeg(), size ); + } } - if( aItem->GetBoundingBox().Intersects( zone->GetCachedBoundingBox() ) ) + if( zoneTree->QueryColliding( itemBBox, itemShape.get(), aLayer, + std::max( 0, clearance - m_drcEpsilon ), &actual, &pos ) ) { - bool testClearance = !m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ); - bool testHoles = !m_drcEngine->IsErrorLimitExceeded( DRCE_HOLE_CLEARANCE ); + std::shared_ptr drce = DRC_ITEM::Create( DRCE_CLEARANCE ); - if( !testClearance && !testHoles ) - return; + m_msg.Printf( _( "(%s clearance %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), clearance ), + MessageTextFromValue( userUnits(), actual ) ); - DRC_RTREE* zoneTree = m_board->m_CopperZoneRTrees[ zone ].get(); - EDA_RECT itemBBox = aItem->GetBoundingBox(); - DRC_CONSTRAINT constraint; - int clearance = -1; - int actual; - VECTOR2I pos; + drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); + drce->SetItems( aItem, aZone ); + drce->SetViolatingRule( constraint.GetParentRule() ); - if( zoneTree && testClearance ) + reportViolation( drce, (wxPoint) pos ); + } + } + + if( zoneTree && testHoles && ( aItem->Type() == PCB_VIA_T || aItem->Type() == PCB_PAD_T ) ) + { + std::unique_ptr holeShape; + + if( aItem->Type() == PCB_VIA_T ) + { + PCB_VIA* via = static_cast( aItem ); + pos = via->GetPosition(); + + if( via->GetLayerSet().Contains( aLayer ) ) + holeShape.reset( new SHAPE_SEGMENT( pos, pos, via->GetDrill() ) ); + } + else if( aItem->Type() == PCB_PAD_T ) + { + PAD* pad = static_cast( aItem ); + + if( pad->GetDrillSize().x ) + holeShape.reset( new SHAPE_SEGMENT( *pad->GetEffectiveHoleShape() ) ); + } + + if( holeShape ) + { + constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, aItem, aZone, aLayer ); + clearance = constraint.GetValue().Min(); + + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance >= 0 ) { - constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, aItem, zone, aLayer ); - clearance = constraint.GetValue().Min(); - } - - if( clearance >= 0 ) - { - std::shared_ptr itemShape = aItem->GetEffectiveShape( aLayer ); - - if( aItem->Type() == PCB_PAD_T ) + if( zoneTree->QueryColliding( itemBBox, holeShape.get(), aLayer, + std::max( 0, clearance - m_drcEpsilon ), + &actual, &pos ) ) { - PAD* pad = static_cast( aItem ); - - if( !pad->FlashLayer( aLayer ) ) - { - if( pad->GetDrillSize().x == 0 && pad->GetDrillSize().y == 0 ) - continue; - - const SHAPE_SEGMENT* hole = pad->GetEffectiveHoleShape(); - int size = hole->GetWidth(); - - // Note: drill size represents finish size, which means the actual hole - // size is the plating thickness larger. - if( pad->GetAttribute() == PAD_ATTRIB::PTH ) - size += m_board->GetDesignSettings().GetHolePlatingThickness(); - - itemShape = std::make_shared( hole->GetSeg(), size ); - } - } - - if( zoneTree && zoneTree->QueryColliding( itemBBox, itemShape.get(), aLayer, - std::max( 0, clearance - m_drcEpsilon ), - &actual, &pos ) ) - { - std::shared_ptr drce = DRC_ITEM::Create( DRCE_CLEARANCE ); + std::shared_ptr drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE ); m_msg.Printf( _( "(%s clearance %s; actual %s)" ), constraint.GetName(), @@ -446,58 +490,12 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem MessageTextFromValue( userUnits(), actual ) ); drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); - drce->SetItems( aItem, zone ); + drce->SetItems( aItem, aZone ); drce->SetViolatingRule( constraint.GetParentRule() ); reportViolation( drce, (wxPoint) pos ); } } - - if( testHoles && ( aItem->Type() == PCB_VIA_T || aItem->Type() == PCB_PAD_T ) ) - { - std::unique_ptr holeShape; - - if( aItem->Type() == PCB_VIA_T ) - { - PCB_VIA* via = static_cast( aItem ); - pos = via->GetPosition(); - - if( via->GetLayerSet().Contains( aLayer ) ) - holeShape.reset( new SHAPE_SEGMENT( pos, pos, via->GetDrill() ) ); - } - else if( aItem->Type() == PCB_PAD_T ) - { - PAD* pad = static_cast( aItem ); - - if( pad->GetDrillSize().x ) - holeShape.reset( new SHAPE_SEGMENT( *pad->GetEffectiveHoleShape() ) ); - } - - if( holeShape ) - { - constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, aItem, zone, - aLayer ); - clearance = constraint.GetValue().Min(); - - if( zoneTree && zoneTree->QueryColliding( itemBBox, holeShape.get(), aLayer, - std::max( 0, clearance - m_drcEpsilon ), - &actual, &pos ) ) - { - std::shared_ptr drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE ); - - m_msg.Printf( _( "(%s clearance %s; actual %s)" ), - constraint.GetName(), - MessageTextFromValue( userUnits(), clearance ), - MessageTextFromValue( userUnits(), actual ) ); - - drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); - drce->SetItems( aItem, zone ); - drce->SetViolatingRule( constraint.GetParentRule() ); - - reportViolation( drce, (wxPoint) pos ); - } - } - } } } } @@ -561,7 +559,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances() }, m_largestClearance ); - testItemAgainstZones( track, layer ); + for( ZONE* zone : m_copperZones ) + testItemAgainstZone( track, zone, layer ); } } } @@ -667,23 +666,25 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, pad, other, layer ); clearance = constraint.GetValue().Min(); - if( clearance > 0 && padShape->Collide( otherShape.get(), - std::max( 0, clearance - m_drcEpsilon ), - &actual, &pos ) ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance > 0 ) { - std::shared_ptr drce = DRC_ITEM::Create( DRCE_CLEARANCE ); + if( padShape->Collide( otherShape.get(), std::max( 0, clearance - m_drcEpsilon ), + &actual, &pos ) ) + { + std::shared_ptr drce = DRC_ITEM::Create( DRCE_CLEARANCE ); - m_msg.Printf( _( "(%s clearance %s; actual %s)" ), - constraint.GetName(), - MessageTextFromValue( userUnits(), clearance ), - MessageTextFromValue( userUnits(), actual ) ); + m_msg.Printf( _( "(%s clearance %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), clearance ), + MessageTextFromValue( userUnits(), actual ) ); - drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); - drce->SetItems( pad, other ); - drce->SetViolatingRule( constraint.GetParentRule() ); + drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); + drce->SetItems( pad, other ); + drce->SetViolatingRule( constraint.GetParentRule() ); - reportViolation( drce, (wxPoint) pos ); - testHoles = false; // No need for multiple violations + reportViolation( drce, (wxPoint) pos ); + testHoles = false; // No need for multiple violations + } } } @@ -691,6 +692,9 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa { constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, pad, other, layer ); clearance = constraint.GetValue().Min(); + + if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE ) + testHoles = false; } if( testHoles && otherPad && pad->FlashLayer( layer ) && otherPad->GetDrillSize().x ) @@ -819,7 +823,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( ) }, m_largestClearance ); - testItemAgainstZones( pad, layer ); + for( ZONE* zone : m_copperZones ) + testItemAgainstZone( pad, zone, layer ); } } } @@ -832,6 +837,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() SHAPE_POLY_SET buffer; SHAPE_POLY_SET* boardOutline = nullptr; + DRC_CONSTRAINT constraint; + int zone2zoneClearance; if( m_board->GetBoardPolygonOutlines( buffer ) ) boardOutline = &buffer; @@ -858,45 +865,41 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() if( !reportProgress( layer_id * m_copperZones.size() + ia, B_Cu * m_copperZones.size(), delta ) ) break; - ZONE* zoneRef = m_copperZones[ia]; + ZONE* zoneA = m_copperZones[ia]; - if( !zoneRef->IsOnLayer( layer ) ) + if( !zoneA->IsOnLayer( layer ) ) continue; - // If we are testing a single zone, then iterate through all other zones - // Otherwise, we have already tested the zone combination for( size_t ia2 = ia + 1; ia2 < m_copperZones.size(); ia2++ ) { - ZONE* zoneToTest = m_copperZones[ia2]; - - if( zoneRef == zoneToTest ) - continue; + ZONE* zoneB = m_copperZones[ia2]; // test for same layer - if( !zoneToTest->IsOnLayer( layer ) ) + if( !zoneB->IsOnLayer( layer ) ) continue; // Test for same net - if( zoneRef->GetNetCode() == zoneToTest->GetNetCode() - && zoneRef->GetNetCode() >= 0 ) + if( zoneA->GetNetCode() == zoneB->GetNetCode() && zoneA->GetNetCode() >= 0 ) continue; // test for different priorities - if( zoneRef->GetPriority() != zoneToTest->GetPriority() ) + if( zoneA->GetPriority() != zoneB->GetPriority() ) continue; // rule areas may overlap at will - if( zoneRef->GetIsRuleArea() || zoneToTest->GetIsRuleArea() ) + if( zoneA->GetIsRuleArea() || zoneB->GetIsRuleArea() ) continue; - // Examine a candidate zone: compare zoneToTest to zoneRef + // Examine a candidate zone: compare zoneB to zoneA // Get clearance used in zone to zone test. - auto constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, zoneRef, zoneToTest, - layer ); - int zone2zoneClearance = constraint.GetValue().Min(); + constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, zoneA, zoneB, layer ); + zone2zoneClearance = constraint.GetValue().Min(); - // test for some corners of zoneRef inside zoneToTest + if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE ) + continue; + + // test for some corners of zoneA inside zoneB for( auto iterator = smoothed_polys[ia].IterateWithHoles(); iterator; iterator++ ) { VECTOR2I currentVertex = *iterator; @@ -905,14 +908,14 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() if( smoothed_polys[ia2].Contains( currentVertex ) ) { std::shared_ptr drce = DRC_ITEM::Create( DRCE_ZONES_INTERSECT ); - drce->SetItems( zoneRef, zoneToTest ); + drce->SetItems( zoneA, zoneB ); drce->SetViolatingRule( constraint.GetParentRule() ); reportViolation( drce, pt ); } } - // test for some corners of zoneToTest inside zoneRef + // test for some corners of zoneB inside zoneA for( auto iterator = smoothed_polys[ia2].IterateWithHoles(); iterator; iterator++ ) { VECTOR2I currentVertex = *iterator; @@ -921,7 +924,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() if( smoothed_polys[ia].Contains( currentVertex ) ) { std::shared_ptr drce = DRC_ITEM::Create( DRCE_ZONES_INTERSECT ); - drce->SetItems( zoneToTest, zoneRef ); + drce->SetItems( zoneB, zoneA ); drce->SetViolatingRule( constraint.GetParentRule() ); reportViolation( drce, pt ); @@ -955,12 +958,9 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() bx2 = testSegment.B.x; by2 = testSegment.B.y; - int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, - 0, - ax1, ay1, ax2, ay2, - 0, - zone2zoneClearance, - &pt.x, &pt.y ); + int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, 0, + ax1, ay1, ax2, ay2, 0, + zone2zoneClearance, &pt.x, &pt.y ); if( d < zone2zoneClearance ) { @@ -974,7 +974,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() for( const std::pair& conflict : conflictPoints ) { - int actual = conflict.second; + int actual = conflict.second; std::shared_ptr drce; if( actual <= 0 ) @@ -993,7 +993,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); } - drce->SetItems( zoneRef, zoneToTest ); + drce->SetItems( zoneA, zoneB ); drce->SetViolatingRule( constraint.GetParentRule() ); reportViolation( drce, conflict.first ); @@ -1004,12 +1004,6 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() } -std::set DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetConstraintTypes() const -{ - return { CLEARANCE_CONSTRAINT, HOLE_CLEARANCE_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_courtyard_clearance.cpp b/pcbnew/drc/drc_test_provider_courtyard_clearance.cpp index 677fed73da..2e1a142c62 100644 --- a/pcbnew/drc/drc_test_provider_courtyard_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_courtyard_clearance.cpp @@ -67,8 +67,6 @@ public: return "Tests footprints' courtyard clearance"; } - virtual std::set GetConstraintTypes() const override; - private: bool testFootprintCourtyardDefinitions(); @@ -198,54 +196,58 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances() if( frontA.OutlineCount() > 0 && frontB.OutlineCount() > 0 && frontBBox.Intersects( frontB.BBoxFromCaches() ) ) { - constraint = m_drcEngine->EvalRules( COURTYARD_CLEARANCE_CONSTRAINT, fpA, fpB, - F_Cu ); + constraint = m_drcEngine->EvalRules( COURTYARD_CLEARANCE_CONSTRAINT, fpA, fpB, F_Cu ); clearance = constraint.GetValue().Min(); - if( clearance >= 0 && frontA.Collide( &frontB, clearance, &actual, &pos ) ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance >= 0 ) { - auto drce = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS ); - - if( clearance > 0 ) + if( frontA.Collide( &frontB, clearance, &actual, &pos ) ) { - m_msg.Printf( _( "(%s clearance %s; actual %s)" ), - constraint.GetName(), - MessageTextFromValue( userUnits(), clearance ), - MessageTextFromValue( userUnits(), actual ) ); + auto drce = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS ); - drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); - drce->SetViolatingRule( constraint.GetParentRule() ); + if( clearance > 0 ) + { + m_msg.Printf( _( "(%s clearance %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), clearance ), + MessageTextFromValue( userUnits(), actual ) ); + + drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); + drce->SetViolatingRule( constraint.GetParentRule() ); + } + + drce->SetItems( fpA, fpB ); + reportViolation( drce, (wxPoint) pos ); } - - drce->SetItems( fpA, fpB ); - reportViolation( drce, (wxPoint) pos ); } } if( backA.OutlineCount() > 0 && backB.OutlineCount() > 0 && backBBox.Intersects( backB.BBoxFromCaches() ) ) { - constraint = m_drcEngine->EvalRules( COURTYARD_CLEARANCE_CONSTRAINT, fpA, fpB, - B_Cu ); + constraint = m_drcEngine->EvalRules( COURTYARD_CLEARANCE_CONSTRAINT, fpA, fpB, B_Cu ); clearance = constraint.GetValue().Min(); - if( clearance >= 0 && backA.Collide( &backB, clearance, &actual, &pos ) ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance >= 0 ) { - auto drce = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS ); - - if( clearance > 0 ) + if( backA.Collide( &backB, clearance, &actual, &pos ) ) { - m_msg.Printf( _( "(%s clearance %s; actual %s)" ), - constraint.GetName(), - MessageTextFromValue( userUnits(), clearance ), - MessageTextFromValue( userUnits(), actual ) ); + auto drce = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS ); - drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); - drce->SetViolatingRule( constraint.GetParentRule() ); + if( clearance > 0 ) + { + m_msg.Printf( _( "(%s clearance %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), clearance ), + MessageTextFromValue( userUnits(), actual ) ); + + drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); + drce->SetViolatingRule( constraint.GetParentRule() ); + } + + drce->SetItems( fpA, fpB ); + reportViolation( drce, (wxPoint) pos ); } - - drce->SetItems( fpA, fpB ); - reportViolation( drce, (wxPoint) pos ); } } @@ -317,12 +319,6 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::Run() } -std::set DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::GetConstraintTypes() const -{ - return { COURTYARD_CLEARANCE_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_diff_pair_coupling.cpp b/pcbnew/drc/drc_test_provider_diff_pair_coupling.cpp index bd03165d83..8c04eff4b8 100644 --- a/pcbnew/drc/drc_test_provider_diff_pair_coupling.cpp +++ b/pcbnew/drc/drc_test_provider_diff_pair_coupling.cpp @@ -74,10 +74,7 @@ public: return "Tests differential pair coupling"; } - virtual std::set GetConstraintTypes() const override; - private: - BOARD* m_board; }; @@ -297,7 +294,7 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run() auto constraint = m_drcEngine->EvalRules( constraintsToCheck[ i ], item, nullptr, item->GetLayer() ); - if( constraint.IsNull() ) + if( constraint.IsNull() || constraint.GetSeverity() == RPT_SEVERITY_IGNORE ) continue; drc_dbg( 10, "cns %d item %p\n", constraintsToCheck[i], item ); @@ -316,8 +313,8 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run() m_board->GetConnectivity()->GetFromToCache()->Rebuild( m_board ); - forEachGeometryItem( { PCB_TRACE_T, PCB_VIA_T, PCB_ARC_T }, - LSET::AllCuMask(), evaluateDpConstraints ); + forEachGeometryItem( { PCB_TRACE_T, PCB_VIA_T, PCB_ARC_T }, LSET::AllCuMask(), + evaluateDpConstraints ); drc_dbg( 10, "dp rule matches %d\n", (int) dpRuleMatches.size() ); @@ -420,9 +417,6 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run() if( val.HasMax() && gap > val.Max() ) insideRange = false; -// if(val.HasMin() && val.HasMax() ) - // drc_dbg(10, "Vmin %d vmax %d\n", val.Min(), val.Max() ); - cpair.couplingOK = insideRange; } else @@ -515,12 +509,6 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run() } -std::set test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::GetConstraintTypes() const -{ - return { DIFF_PAIR_GAP_CONSTRAINT, DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_disallow.cpp b/pcbnew/drc/drc_test_provider_disallow.cpp index 9437e5b9b4..f7052a26dd 100644 --- a/pcbnew/drc/drc_test_provider_disallow.cpp +++ b/pcbnew/drc/drc_test_provider_disallow.cpp @@ -58,8 +58,6 @@ public: { return "Tests for disallowed items (e.g. keepouts)"; } - - virtual std::set GetConstraintTypes() const override; }; @@ -80,7 +78,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run() auto constraint = m_drcEngine->EvalRules( DISALLOW_CONSTRAINT, item, nullptr, UNDEFINED_LAYER ); - if( constraint.m_DisallowFlags ) + if( constraint.m_DisallowFlags && constraint.GetSeverity() != RPT_SEVERITY_IGNORE ) { std::shared_ptr drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS ); @@ -168,12 +166,6 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run() } -std::set DRC_TEST_PROVIDER_DISALLOW::GetConstraintTypes() const -{ - return { DISALLOW_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_edge_clearance.cpp b/pcbnew/drc/drc_test_provider_edge_clearance.cpp index 6a5c92f398..f61beea459 100644 --- a/pcbnew/drc/drc_test_provider_edge_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_edge_clearance.cpp @@ -68,8 +68,6 @@ public: return "Tests items vs board edge clearance"; } - virtual std::set GetConstraintTypes() const override; - private: bool testAgainstEdge( BOARD_ITEM* item, SHAPE* itemShape, BOARD_ITEM* other, DRC_CONSTRAINT_T aConstraintType, PCB_DRC_CODE aErrorCode ); @@ -88,26 +86,29 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::testAgainstEdge( BOARD_ITEM* item, SHAPE* int actual; VECTOR2I pos; - if( minClearance >= 0 && itemShape->Collide( edgeShape.get(), minClearance, &actual, &pos ) ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && minClearance >= 0 ) { - std::shared_ptr drce = DRC_ITEM::Create( aErrorCode ); - - // Only report clearance info if there is any; otherwise it's just a straight collision - if( minClearance > 0 ) + if( itemShape->Collide( edgeShape.get(), minClearance, &actual, &pos ) ) { - m_msg.Printf( _( "(%s clearance %s; actual %s)" ), - constraint.GetName(), - MessageTextFromValue( userUnits(), minClearance ), - MessageTextFromValue( userUnits(), actual ) ); + std::shared_ptr drce = DRC_ITEM::Create( aErrorCode ); - drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); + // Only report clearance info if there is any; otherwise it's just a straight collision + if( minClearance > 0 ) + { + m_msg.Printf( _( "(%s clearance %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), minClearance ), + MessageTextFromValue( userUnits(), actual ) ); + + drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); + } + + drce->SetItems( edge->m_Uuid, item->m_Uuid ); + drce->SetViolatingRule( constraint.GetParentRule() ); + + reportViolation( drce, (wxPoint) pos ); + return false; // don't report violations with multiple edges; one is enough } - - drce->SetItems( edge->m_Uuid, item->m_Uuid ); - drce->SetViolatingRule( constraint.GetParentRule() ); - - reportViolation( drce, (wxPoint) pos ); - return false; // don't report violations with multiple edges; one is enough } return true; @@ -281,12 +282,6 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run() } -std::set DRC_TEST_PROVIDER_EDGE_CLEARANCE::GetConstraintTypes() const -{ - return { EDGE_CLEARANCE_CONSTRAINT, SILK_CLEARANCE_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_hole_size.cpp b/pcbnew/drc/drc_test_provider_hole_size.cpp index 707f27868e..c98008ab8b 100644 --- a/pcbnew/drc/drc_test_provider_hole_size.cpp +++ b/pcbnew/drc/drc_test_provider_hole_size.cpp @@ -60,8 +60,6 @@ public: return "Tests sizes of drilled holes (via/pad drills)"; } - virtual std::set GetConstraintTypes() const override; - private: void checkVia( PCB_VIA* via, bool aExceedMicro, bool aExceedStd ); void checkPad( PAD* aPad ); @@ -144,6 +142,9 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( PAD* aPad ) bool fail_max = false; int constraintValue; + if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE ) + return; + if( constraint.Value().HasMin() && holeMinor < constraint.Value().Min() ) { fail_min = true; @@ -209,6 +210,9 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( PCB_VIA* via, bool aExceedMicro, boo bool fail_max = false; int constraintValue; + if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE ) + return; + if( constraint.Value().HasMin() && via->GetDrillValue() < constraint.Value().Min() ) { fail_min = true; @@ -249,12 +253,6 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( PCB_VIA* via, bool aExceedMicro, boo } -std::set DRC_TEST_PROVIDER_HOLE_SIZE::GetConstraintTypes() const -{ - return { HOLE_SIZE_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_hole_to_hole.cpp b/pcbnew/drc/drc_test_provider_hole_to_hole.cpp index e357052f26..5bbfe8e4d9 100644 --- a/pcbnew/drc/drc_test_provider_hole_to_hole.cpp +++ b/pcbnew/drc/drc_test_provider_hole_to_hole.cpp @@ -68,8 +68,6 @@ public: return "Tests hole to hole spacing"; } - virtual std::set GetConstraintTypes() const override; - private: bool testHoleAgainstHole( BOARD_ITEM* aItem, SHAPE_CIRCLE* aHole, BOARD_ITEM* aOther ); @@ -304,7 +302,9 @@ bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::testHoleAgainstHole( BOARD_ITEM* aItem, SHA UNDEFINED_LAYER /* holes pierce all layers */ ); int minClearance = constraint.GetValue().Min() - epsilon; - if( minClearance >= 0 && actual < minClearance ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE + && minClearance >= 0 + && actual < minClearance ) { std::shared_ptr drce = DRC_ITEM::Create( DRCE_DRILLED_HOLES_TOO_CLOSE ); @@ -325,12 +325,6 @@ bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::testHoleAgainstHole( BOARD_ITEM* aItem, SHA } -std::set DRC_TEST_PROVIDER_HOLE_TO_HOLE::GetConstraintTypes() const -{ - return { HOLE_TO_HOLE_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_library_parity.cpp b/pcbnew/drc/drc_test_provider_library_parity.cpp index abf767356a..1f9636552d 100644 --- a/pcbnew/drc/drc_test_provider_library_parity.cpp +++ b/pcbnew/drc/drc_test_provider_library_parity.cpp @@ -65,8 +65,6 @@ public: { return "Performs board footprint vs library integity checks"; } - - virtual std::set GetConstraintTypes() const override; }; @@ -508,12 +506,6 @@ bool DRC_TEST_PROVIDER_LIBRARY_PARITY::Run() } -std::set DRC_TEST_PROVIDER_LIBRARY_PARITY::GetConstraintTypes() const -{ - return {}; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_matched_length.cpp b/pcbnew/drc/drc_test_provider_matched_length.cpp index 951cb63bb3..7869ee9297 100644 --- a/pcbnew/drc/drc_test_provider_matched_length.cpp +++ b/pcbnew/drc/drc_test_provider_matched_length.cpp @@ -66,8 +66,6 @@ public: return "Tests matched track lengths."; } - virtual std::set GetConstraintTypes() const override; - DRC_LENGTH_REPORT BuildLengthReport() const; private: @@ -361,17 +359,17 @@ bool DRC_TEST_PROVIDER_MATCHED_LENGTH::runInternal( bool aDelayReportMode ) OPT lengthConstraint = rule->FindConstraint( LENGTH_CONSTRAINT ); - if( lengthConstraint ) + if( lengthConstraint && lengthConstraint->GetSeverity() != RPT_SEVERITY_IGNORE ) checkLengths( *lengthConstraint, matchedConnections ); OPT skewConstraint = rule->FindConstraint( SKEW_CONSTRAINT ); - if( skewConstraint ) + if( skewConstraint && skewConstraint->GetSeverity() != RPT_SEVERITY_IGNORE ) checkSkews( *skewConstraint, matchedConnections ); OPT viaCountConstraint = rule->FindConstraint( VIA_COUNT_CONSTRAINT ); - if( viaCountConstraint ) + if( viaCountConstraint && viaCountConstraint->GetSeverity() != RPT_SEVERITY_IGNORE ) checkViaCounts( *viaCountConstraint, matchedConnections ); } @@ -382,12 +380,6 @@ bool DRC_TEST_PROVIDER_MATCHED_LENGTH::runInternal( bool aDelayReportMode ) } -std::set DRC_TEST_PROVIDER_MATCHED_LENGTH::GetConstraintTypes() const -{ - return { LENGTH_CONSTRAINT, SKEW_CONSTRAINT, VIA_COUNT_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_mechanical_clearance.cpp b/pcbnew/drc/drc_test_provider_mechanical_clearance.cpp index b3d17253af..69421f8ba7 100644 --- a/pcbnew/drc/drc_test_provider_mechanical_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_mechanical_clearance.cpp @@ -70,8 +70,6 @@ public: return "Tests item clearances irrespective of nets"; } - virtual std::set GetConstraintTypes() const override; - private: bool testItemAgainstItem( BOARD_ITEM* item, SHAPE* itemShape, PCB_LAYER_ID layer, BOARD_ITEM* other ); @@ -510,7 +508,7 @@ void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testZoneLayer( ZONE* aZone, PCB_LAY int clearance = aConstraint.GetValue().Min(); SHAPE_POLY_SET fill = aZone->GetFilledPolysList( aLayer ); - if( clearance - epsilon <= 0 ) + if( aConstraint.GetSeverity() == RPT_SEVERITY_IGNORE || clearance - epsilon <= 0 ) return; // Turn fractured fill into outlines and holes @@ -580,7 +578,7 @@ bool DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testItemAgainstItem( BOARD_ITEM* it clearance = constraint.GetValue().Min(); } - if( clearance > 0 ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance > 0 ) { if( itemShape->Collide( otherShape.get(), clearance, &actual, &pos ) ) { @@ -644,38 +642,39 @@ bool DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testItemAgainstItem( BOARD_ITEM* it clearance = constraint.GetValue().Min(); } - if( clearance > 0 && itemHoleShape && itemHoleShape->Collide( otherShape.get(), clearance, - &actual, &pos ) ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance > 0 ) { - std::shared_ptr drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE ); + if( itemHoleShape && itemHoleShape->Collide( otherShape.get(), clearance, &actual, &pos ) ) + { + std::shared_ptr drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE ); - m_msg.Printf( _( "(%s clearance %s; actual %s)" ), - constraint.GetName(), - MessageTextFromValue( userUnits(), clearance ), - MessageTextFromValue( userUnits(), actual ) ); + m_msg.Printf( _( "(%s clearance %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), clearance ), + MessageTextFromValue( userUnits(), actual ) ); - drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); - drce->SetItems( item, other ); - drce->SetViolatingRule( constraint.GetParentRule() ); + drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); + drce->SetItems( item, other ); + drce->SetViolatingRule( constraint.GetParentRule() ); - reportViolation( drce, (wxPoint) pos ); - } + reportViolation( drce, (wxPoint) pos ); + } - if( clearance > 0 && otherHoleShape && otherHoleShape->Collide( itemShape, clearance, - &actual, &pos ) ) - { - std::shared_ptr drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE ); + if( otherHoleShape && otherHoleShape->Collide( itemShape, clearance, &actual, &pos ) ) + { + std::shared_ptr drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE ); - m_msg.Printf( _( "(%s clearance %s; actual %s)" ), - constraint.GetName(), - MessageTextFromValue( userUnits(), clearance ), - MessageTextFromValue( userUnits(), actual ) ); + m_msg.Printf( _( "(%s clearance %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), clearance ), + MessageTextFromValue( userUnits(), actual ) ); - drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); - drce->SetItems( item, other ); - drce->SetViolatingRule( constraint.GetParentRule() ); + drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); + drce->SetItems( item, other ); + drce->SetViolatingRule( constraint.GetParentRule() ); - reportViolation( drce, (wxPoint) pos ); + reportViolation( drce, (wxPoint) pos ); + } } } @@ -714,7 +713,7 @@ void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testItemAgainstZones( BOARD_ITEM* a clearance = constraint.GetValue().Min(); } - if( clearance > 0 ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance > 0 ) { std::shared_ptr itemShape = aItem->GetEffectiveShape( aLayer ); @@ -793,9 +792,10 @@ void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testItemAgainstZones( BOARD_ITEM* a aItem, zone, aLayer ); clearance = constraint.GetValue().Min(); - if( clearance > 0 && zoneTree->QueryColliding( itemBBox, holeShape.get(), - aLayer, clearance, &actual, - &pos ) ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE + && clearance > 0 + && zoneTree->QueryColliding( itemBBox, holeShape.get(), aLayer, + clearance, &actual, &pos ) ) { std::shared_ptr drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE ); @@ -817,14 +817,6 @@ void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testItemAgainstZones( BOARD_ITEM* a } - - -std::set DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::GetConstraintTypes() const -{ - return { MECHANICAL_CLEARANCE_CONSTRAINT, MECHANICAL_HOLE_CLEARANCE_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_misc.cpp b/pcbnew/drc/drc_test_provider_misc.cpp index 078242c519..f9e94bdf4c 100644 --- a/pcbnew/drc/drc_test_provider_misc.cpp +++ b/pcbnew/drc/drc_test_provider_misc.cpp @@ -68,8 +68,6 @@ public: return "Misc checks (board outline, missing textvars)"; } - virtual std::set GetConstraintTypes() const override; - private: void testOutline(); void testDisabledLayers(); @@ -282,12 +280,6 @@ bool DRC_TEST_PROVIDER_MISC::Run() } -std::set DRC_TEST_PROVIDER_MISC::GetConstraintTypes() const -{ - return {}; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_schematic_parity.cpp b/pcbnew/drc/drc_test_provider_schematic_parity.cpp index c1368e5b07..fa21057422 100644 --- a/pcbnew/drc/drc_test_provider_schematic_parity.cpp +++ b/pcbnew/drc/drc_test_provider_schematic_parity.cpp @@ -68,8 +68,6 @@ public: return "Performs layout-vs-schematics integity check"; } - virtual std::set GetConstraintTypes() const override; - private: void testNetlist( NETLIST& aNetlist ); }; @@ -233,12 +231,6 @@ bool DRC_TEST_PROVIDER_SCHEMATIC_PARITY::Run() } -std::set DRC_TEST_PROVIDER_SCHEMATIC_PARITY::GetConstraintTypes() const -{ - return {}; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_silk_clearance.cpp b/pcbnew/drc/drc_test_provider_silk_clearance.cpp index 60529e82e4..8393093fa7 100644 --- a/pcbnew/drc/drc_test_provider_silk_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_silk_clearance.cpp @@ -68,8 +68,6 @@ public: return "Tests for overlapping silkscreen features."; } - virtual std::set GetConstraintTypes() const override; - private: BOARD* m_board; @@ -193,7 +191,7 @@ bool DRC_TEST_PROVIDER_SILK_CLEARANCE::Run() aTestItem->parent, aLayers.second ); - if( constraint.IsNull() ) + if( constraint.IsNull() || constraint.GetSeverity() == RPT_SEVERITY_IGNORE ) return true; int minClearance = constraint.GetValue().Min(); @@ -254,12 +252,6 @@ bool DRC_TEST_PROVIDER_SILK_CLEARANCE::Run() } -std::set DRC_TEST_PROVIDER_SILK_CLEARANCE::GetConstraintTypes() const -{ - return { SILK_CLEARANCE_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_sliver_checker.cpp b/pcbnew/drc/drc_test_provider_sliver_checker.cpp index 8a6acc8c7e..23272d4c3c 100644 --- a/pcbnew/drc/drc_test_provider_sliver_checker.cpp +++ b/pcbnew/drc/drc_test_provider_sliver_checker.cpp @@ -61,11 +61,6 @@ public: return "Checks copper layers for slivers"; } - virtual std::set GetConstraintTypes() const override - { - return {}; - } - private: wxString layerDesc( PCB_LAYER_ID aLayer ); }; diff --git a/pcbnew/drc/drc_test_provider_solder_mask.cpp b/pcbnew/drc/drc_test_provider_solder_mask.cpp index 7bdc3269fc..5403004f71 100644 --- a/pcbnew/drc/drc_test_provider_solder_mask.cpp +++ b/pcbnew/drc/drc_test_provider_solder_mask.cpp @@ -69,8 +69,6 @@ public: "mask apertures of other nets"; } - virtual std::set GetConstraintTypes() const override; - private: void addItemToRTrees( BOARD_ITEM* item ); void buildRTrees(); @@ -261,7 +259,7 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testSilkToMaskClearance() int actual; VECTOR2I pos; - if( clearance <= 0 ) + if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE || clearance <= 0 ) return true; std::shared_ptr itemShape = item->GetEffectiveShape( layer ); @@ -573,12 +571,6 @@ bool DRC_TEST_PROVIDER_SOLDER_MASK::Run() } -std::set DRC_TEST_PROVIDER_SOLDER_MASK::GetConstraintTypes() const -{ - return { SILK_CLEARANCE_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_text_dims.cpp b/pcbnew/drc/drc_test_provider_text_dims.cpp index d8236ba7f9..a8cbb0370e 100644 --- a/pcbnew/drc/drc_test_provider_text_dims.cpp +++ b/pcbnew/drc/drc_test_provider_text_dims.cpp @@ -58,8 +58,6 @@ public: { return "Tests text height and thickness"; } - - virtual std::set GetConstraintTypes() const override; }; @@ -120,16 +118,19 @@ bool DRC_TEST_PROVIDER_TEXT_DIMS::Run() int constraintHeight; int actual = textItem->GetTextHeight(); - if( constraint.Value().HasMin() && actual < constraint.Value().Min() ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE ) { - fail_min = true; - constraintHeight = constraint.Value().Min(); - } + if( constraint.Value().HasMin() && actual < constraint.Value().Min() ) + { + fail_min = true; + constraintHeight = constraint.Value().Min(); + } - if( constraint.Value().HasMax() && actual > constraint.Value().Max() ) - { - fail_max = true; - constraintHeight = constraint.Value().Max(); + if( constraint.Value().HasMax() && actual > constraint.Value().Max() ) + { + fail_max = true; + constraintHeight = constraint.Value().Max(); + } } if( fail_min || fail_max ) @@ -168,16 +169,19 @@ bool DRC_TEST_PROVIDER_TEXT_DIMS::Run() int constraintThickness; int actual = textItem->GetTextThickness(); - if( constraint.Value().HasMin() && actual < constraint.Value().Min() ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE ) { - fail_min = true; - constraintThickness = constraint.Value().Min(); - } + if( constraint.Value().HasMin() && actual < constraint.Value().Min() ) + { + fail_min = true; + constraintThickness = constraint.Value().Min(); + } - if( constraint.Value().HasMax() && actual > constraint.Value().Max() ) - { - fail_max = true; - constraintThickness = constraint.Value().Max(); + if( constraint.Value().HasMax() && actual > constraint.Value().Max() ) + { + fail_max = true; + constraintThickness = constraint.Value().Max(); + } } if( fail_min || fail_max ) @@ -221,12 +225,6 @@ bool DRC_TEST_PROVIDER_TEXT_DIMS::Run() } -std::set DRC_TEST_PROVIDER_TEXT_DIMS::GetConstraintTypes() const -{ - return { TEXT_HEIGHT_CONSTRAINT, TEXT_THICKNESS_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_track_width.cpp b/pcbnew/drc/drc_test_provider_track_width.cpp index b659af8a88..7018e0334b 100644 --- a/pcbnew/drc/drc_test_provider_track_width.cpp +++ b/pcbnew/drc/drc_test_provider_track_width.cpp @@ -56,8 +56,6 @@ public: { return "Tests track widths"; } - - virtual std::set GetConstraintTypes() const override; }; @@ -110,16 +108,19 @@ bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run() bool fail_max = false; int constraintWidth; - if( constraint.Value().HasMin() && actual < constraint.Value().Min() ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE ) { - fail_min = true; - constraintWidth = constraint.Value().Min(); - } + if( constraint.Value().HasMin() && actual < constraint.Value().Min() ) + { + fail_min = true; + constraintWidth = constraint.Value().Min(); + } - if( constraint.Value().HasMax() && actual > constraint.Value().Max() ) - { - fail_max = true; - constraintWidth = constraint.Value().Max(); + if( constraint.Value().HasMax() && actual > constraint.Value().Max() ) + { + fail_max = true; + constraintWidth = constraint.Value().Max(); + } } if( fail_min || fail_max ) @@ -168,12 +169,6 @@ bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run() } -std::set DRC_TEST_PROVIDER_TRACK_WIDTH::GetConstraintTypes() const -{ - return { TRACK_WIDTH_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_via_diameter.cpp b/pcbnew/drc/drc_test_provider_via_diameter.cpp index 8286961e2f..a50e68b5d3 100644 --- a/pcbnew/drc/drc_test_provider_via_diameter.cpp +++ b/pcbnew/drc/drc_test_provider_via_diameter.cpp @@ -56,8 +56,6 @@ public: { return "Tests via diameters"; } - - virtual std::set GetConstraintTypes() const override; }; @@ -100,16 +98,19 @@ bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run() int constraintDiameter = 0; int actual = via->GetWidth(); - if( constraint.Value().HasMin() && actual < constraint.Value().Min() ) + if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE ) { - fail_min = true; - constraintDiameter = constraint.Value().Min(); - } + if( constraint.Value().HasMin() && actual < constraint.Value().Min() ) + { + fail_min = true; + constraintDiameter = constraint.Value().Min(); + } - if( constraint.Value().HasMax() && actual > constraint.Value().Max() ) - { - fail_max = true; - constraintDiameter = constraint.Value().Max(); + if( constraint.Value().HasMax() && actual > constraint.Value().Max() ) + { + fail_max = true; + constraintDiameter = constraint.Value().Max(); + } } if( fail_min ) @@ -158,12 +159,6 @@ bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run() } -std::set DRC_TEST_PROVIDER_VIA_DIAMETER::GetConstraintTypes() const -{ - return { VIA_DIAMETER_CONSTRAINT }; -} - - namespace detail { static DRC_REGISTER_TEST_PROVIDER dummy; diff --git a/pcbnew/drc/drc_test_provider_zone_connections.cpp b/pcbnew/drc/drc_test_provider_zone_connections.cpp index 4735fcbadf..a84c4b155e 100644 --- a/pcbnew/drc/drc_test_provider_zone_connections.cpp +++ b/pcbnew/drc/drc_test_provider_zone_connections.cpp @@ -64,12 +64,6 @@ public: { return "Checks thermal reliefs for a sufficient number of connecting spokes"; } - - virtual std::set GetConstraintTypes() const override - { - return { ZONE_CONNECTION_CONSTRAINT, THERMAL_RELIEF_GAP_CONSTRAINT, - THERMAL_SPOKE_WIDTH_CONSTRAINT, MIN_RESOLVED_SPOKES_CONSTRAINT }; - } }; bool DRC_TEST_PROVIDER_ZONE_CONNECTIONS::Run() @@ -132,7 +126,7 @@ bool DRC_TEST_PROVIDER_ZONE_CONNECTIONS::Run() pad, zone, layer ); int minCount = constraint.m_Value.Min(); - if( minCount <= 0 ) + if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE || minCount <= 0 ) continue; SHAPE_POLY_SET padPoly; diff --git a/pcbnew/pcb_display_options.cpp b/pcbnew/pcb_display_options.cpp index 3ed14d4f73..2ecdab4987 100644 --- a/pcbnew/pcb_display_options.cpp +++ b/pcbnew/pcb_display_options.cpp @@ -24,11 +24,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include -#include -#include -#include -#include #include #include diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 8aae8a4db4..db419d6d4d 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -809,7 +809,7 @@ void PCB_EDIT_FRAME::RecordDRCExclusions() for( PCB_MARKER* marker : GetBoard()->Markers() ) { - if( marker->IsExcluded() ) + if( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION ) bds.m_DrcExclusions.insert( marker->Serialize() ); } } @@ -826,7 +826,7 @@ void PCB_EDIT_FRAME::ResolveDRCExclusions() for( PCB_MARKER* marker : GetBoard()->Markers() ) { - if( marker->IsExcluded() ) + if( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION ) { GetCanvas()->GetView()->Remove( marker ); GetCanvas()->GetView()->Add( marker ); diff --git a/pcbnew/pcb_marker.cpp b/pcbnew/pcb_marker.cpp index 9c798e74db..3e97a84ce5 100644 --- a/pcbnew/pcb_marker.cpp +++ b/pcbnew/pcb_marker.cpp @@ -93,6 +93,8 @@ void PCB_MARKER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vectorGetErrorMessage() ); + aList.emplace_back( _( "Severity" ), GetSeverity() == RPT_SEVERITY_ERROR ? _( "Error" ) + : _( "Warning" ) ); wxString mainText; wxString auxText; @@ -149,51 +151,45 @@ BITMAPS PCB_MARKER::GetMenuImage() const } +SEVERITY PCB_MARKER::GetSeverity() const +{ + if( IsExcluded() ) + return RPT_SEVERITY_EXCLUSION; + + DRC_ITEM* item = static_cast( m_rcItem.get() ); + DRC_RULE* rule = item->GetViolatingRule(); + + if( rule && rule->m_Severity != RPT_SEVERITY_UNDEFINED ) + return rule->m_Severity; + + return GetBoard()->GetDesignSettings().GetSeverity( item->GetErrorCode() ); +} + + void PCB_MARKER::ViewGetLayers( int aLayers[], int& aCount ) const { aCount = 2; aLayers[1] = LAYER_MARKER_SHADOWS; - if( IsExcluded() ) - { - aLayers[0] = LAYER_DRC_EXCLUSION; - return; - } - - BOARD_ITEM_CONTAINER* ancestor = GetParent(); - - while( ancestor->GetParent() ) - ancestor = ancestor->GetParent(); - - BOARD* board = static_cast( ancestor ); - - switch( board->GetDesignSettings().GetSeverity( m_rcItem->GetErrorCode() ) ) + switch( GetSeverity() ) { default: - case SEVERITY::RPT_SEVERITY_ERROR: aLayers[0] = LAYER_DRC_ERROR; break; - case SEVERITY::RPT_SEVERITY_WARNING: aLayers[0] = LAYER_DRC_WARNING; break; + case SEVERITY::RPT_SEVERITY_ERROR: aLayers[0] = LAYER_DRC_ERROR; break; + case SEVERITY::RPT_SEVERITY_WARNING: aLayers[0] = LAYER_DRC_WARNING; break; + case SEVERITY::RPT_SEVERITY_EXCLUSION: aLayers[0] = LAYER_DRC_EXCLUSION; break; } } GAL_LAYER_ID PCB_MARKER::GetColorLayer() const { - if( IsExcluded() ) - return LAYER_DRC_EXCLUSION; - - BOARD_ITEM_CONTAINER* ancestor = GetParent(); - - while( ancestor->GetParent() ) - ancestor = ancestor->GetParent(); - - BOARD* board = static_cast( ancestor ); - - switch( board->GetDesignSettings().GetSeverity( m_rcItem->GetErrorCode() ) ) + switch( GetSeverity() ) { default: - case SEVERITY::RPT_SEVERITY_ERROR: return LAYER_DRC_ERROR; - case SEVERITY::RPT_SEVERITY_WARNING: return LAYER_DRC_WARNING; + case SEVERITY::RPT_SEVERITY_ERROR: return LAYER_DRC_ERROR; + case SEVERITY::RPT_SEVERITY_WARNING: return LAYER_DRC_WARNING; + case SEVERITY::RPT_SEVERITY_EXCLUSION: return LAYER_DRC_EXCLUSION; } } diff --git a/pcbnew/pcb_marker.h b/pcbnew/pcb_marker.h index 1398f6f41d..06d7f90c35 100644 --- a/pcbnew/pcb_marker.h +++ b/pcbnew/pcb_marker.h @@ -105,6 +105,8 @@ public: void ViewGetLayers( int aLayers[], int& aCount ) const override; + SEVERITY GetSeverity() const override; + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif diff --git a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp index f18cc58cda..e640c92e41 100644 --- a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp +++ b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp @@ -517,7 +517,7 @@ bool WriteDRCReport( BOARD* aBoard, const wxString& aFileName, EDA_UNITS aUnits, for( const std::shared_ptr& item : violations ) { - SEVERITY severity = bds.GetSeverity( item->GetErrorCode() ); + SEVERITY severity = item->GetParent()->GetSeverity(); fprintf( fp, "%s", TO_UTF8( item->ShowReport( aUnits, severity, itemMap ) ) ); } diff --git a/qa/data/custom_pads.kicad_pro b/qa/data/custom_pads.kicad_pro index 464bea79ad..40df837856 100644 --- a/qa/data/custom_pads.kicad_pro +++ b/qa/data/custom_pads.kicad_pro @@ -1,5 +1,128 @@ { "board": { + "design_settings": { + "defaults": { + "board_outline_line_width": 0.049999999999999996, + "copper_line_width": 0.19999999999999998, + "copper_text_italic": false, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "copper_text_upright": false, + "courtyard_line_width": 0.049999999999999996, + "dimension_precision": 4, + "dimension_units": 3, + "dimensions": { + "arrow_length": 1270000, + "extension_offset": 500000, + "keep_text_aligned": true, + "suppress_zeroes": false, + "text_position": 0, + "units_format": 1 + }, + "fab_line_width": 0.09999999999999999, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, + "other_line_width": 0.09999999999999999, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 0.762, + "height": 1.524, + "width": 1.524 + }, + "silk_line_width": 0.12, + "silk_text_italic": false, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.15, + "silk_text_upright": false, + "zones": { + "45_degree_only": false, + "min_clearance": 0.508 + } + }, + "diff_pair_dimensions": [], + "drc_exclusions": [], + "meta": { + "version": 2 + }, + "rule_severities": { + "annular_width": "error", + "clearance": "error", + "copper_edge_clearance": "error", + "copper_sliver": "warning", + "courtyards_overlap": "error", + "diff_pair_gap_out_of_range": "error", + "diff_pair_uncoupled_length_too_long": "error", + "drill_out_of_range": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "hole_clearance": "error", + "hole_near_hole": "error", + "invalid_outline": "error", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "length_out_of_range": "error", + "lib_footprint_issues": "error", + "malformed_courtyard": "error", + "microvia_drill_out_of_range": "error", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "net_conflict": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "error", + "pth_inside_courtyard": "ignore", + "shorting_items": "error", + "silk_over_copper": "warning", + "silk_overlap": "warning", + "skew_out_of_range": "error", + "solder_mask_bridge": "error", + "starved_thermal": "error", + "text_height": "warning", + "text_thickness": "warning", + "too_many_vias": "error", + "track_dangling": "warning", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_dangling": "warning", + "zone_has_empty_net": "error", + "zones_intersect": "error" + }, + "rules": { + "allow_blind_buried_vias": false, + "allow_microvias": false, + "max_error": 0.005, + "min_clearance": 0.0, + "min_copper_edge_clearance": 0.01, + "min_hole_clearance": 0.0, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.19999999999999998, + "min_microvia_drill": 0.09999999999999999, + "min_resolved_spokes": 2, + "min_silk_clearance": 0.0, + "min_text_height": 0.7999999999999999, + "min_text_thickness": 0.12, + "min_through_hole_diameter": 0.3, + "min_track_width": 0.19999999999999998, + "min_via_annular_width": 0.049999999999999996, + "min_via_diameter": 0.39999999999999997, + "solder_mask_to_copper_clearance": 0.0, + "use_height_for_length_calcs": true + }, + "track_widths": [], + "via_dimensions": [], + "zones_allow_external_fillets": false, + "zones_use_no_outline": true + }, "layer_presets": [] }, "boards": [], @@ -35,7 +158,7 @@ } ], "meta": { - "version": 0 + "version": 1 }, "net_colors": null }, @@ -46,7 +169,8 @@ "netlist": "", "specctra_dsn": "", "step": "", - "vmrl": "" + "vmrl": "", + "vrml": "" }, "page_layout_descr_file": "" }, diff --git a/qa/data/issue1358.kicad_pro b/qa/data/issue1358.kicad_pro index 87584b29b3..2e29c1f73f 100755 --- a/qa/data/issue1358.kicad_pro +++ b/qa/data/issue1358.kicad_pro @@ -48,7 +48,13 @@ "min_clearance": 0.254 } }, - "diff_pair_dimensions": [], + "diff_pair_dimensions": [ + { + "gap": 0.0, + "via_gap": 0.0, + "width": 0.0 + } + ], "drc_exclusions": [], "meta": { "filename": "board_design_settings.json", @@ -56,9 +62,9 @@ }, "rule_severities": { "annular_width": "error", - "aperture_clearance": "error", "clearance": "error", "copper_edge_clearance": "error", + "copper_sliver": "warning", "courtyards_overlap": "error", "diff_pair_gap_out_of_range": "error", "diff_pair_uncoupled_length_too_long": "error", @@ -84,6 +90,7 @@ "silk_over_copper": "ignore", "silk_overlap": "warning", "skew_out_of_range": "error", + "solder_mask_bridge": "error", "starved_thermal": "error", "text_height": "warning", "text_thickness": "warning", @@ -103,7 +110,7 @@ "max_error": 0.005, "min_aperture_clearance": 0.049999999999999996, "min_clearance": 0.0, - "min_copper_edge_clearance": 0.024999999999999998, + "min_copper_edge_clearance": 0.25, "min_hole_clearance": 0.0, "min_hole_to_hole": 0.25, "min_microvia_diameter": 0.19999999999999998, @@ -116,6 +123,7 @@ "min_track_width": 0.19999999999999998, "min_via_annular_width": 0.049999999999999996, "min_via_diameter": 0.39999999999999997, + "solder_mask_to_copper_clearance": 0.0, "use_height_for_length_calcs": true }, "track_widths": [ diff --git a/qa/data/severities.kicad_dru b/qa/data/severities.kicad_dru new file mode 100644 index 0000000000..f419b224f1 --- /dev/null +++ b/qa/data/severities.kicad_dru @@ -0,0 +1,5 @@ +(version 1) +(rule board_edge + (constraint edge_clearance (min 1mm)) + (condition "A.memberOf('board_edge')") + (severity ignore)) \ No newline at end of file diff --git a/qa/data/severities.kicad_pcb b/qa/data/severities.kicad_pcb new file mode 100644 index 0000000000..b0d623510a --- /dev/null +++ b/qa/data/severities.kicad_pcb @@ -0,0 +1,3482 @@ +(kicad_pcb (version 20210904) (generator pcbnew) + + (general + (thickness 1.6) + ) + + (paper "A4") + (layers + (0 "F.Cu" signal) + (31 "B.Cu" signal) + (32 "B.Adhes" user "B.Adhesive") + (33 "F.Adhes" user "F.Adhesive") + (34 "B.Paste" user) + (35 "F.Paste" user) + (36 "B.SilkS" user "B.Silkscreen") + (37 "F.SilkS" user "F.Silkscreen") + (38 "B.Mask" user) + (39 "F.Mask" user) + (40 "Dwgs.User" user "User.Drawings") + (41 "Cmts.User" user "User.Comments") + (42 "Eco1.User" user "User.Eco1") + (43 "Eco2.User" user "User.Eco2") + (44 "Edge.Cuts" user) + (45 "Margin" user) + (46 "B.CrtYd" user "B.Courtyard") + (47 "F.CrtYd" user "F.Courtyard") + (48 "B.Fab" user) + (49 "F.Fab" user) + ) + + (setup + (stackup + (layer "F.SilkS" (type "Top Silk Screen")) + (layer "F.Paste" (type "Top Solder Paste")) + (layer "F.Mask" (type "Top Solder Mask") (color "Green") (thickness 0.01)) + (layer "F.Cu" (type "copper") (thickness 0.035)) + (layer "dielectric 1" (type "core") (thickness 1.51) (material "FR4") (epsilon_r 4.5) (loss_tangent 0.02)) + (layer "B.Cu" (type "copper") (thickness 0.035)) + (layer "B.Mask" (type "Bottom Solder Mask") (color "Green") (thickness 0.01)) + (layer "B.Paste" (type "Bottom Solder Paste")) + (layer "B.SilkS" (type "Bottom Silk Screen")) + (copper_finish "None") + (dielectric_constraints no) + ) + (pad_to_mask_clearance 0.051) + (solder_mask_min_width 0.25) + (pcbplotparams + (layerselection 0x00010fc_ffffffff) + (disableapertmacros false) + (usegerberextensions false) + (usegerberattributes false) + (usegerberadvancedattributes false) + (creategerberjobfile false) + (dashed_line_dash_ratio 5.000000) + (dashed_line_gap_ratio 3.000000) + (svguseinch false) + (svgprecision 6) + (excludeedgelayer true) + (plotframeref false) + (viasonmask false) + (mode 1) + (useauxorigin false) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15.000000) + (dxfpolygonmode true) + (dxfimperialunits true) + (dxfusepcbnewfont true) + (psnegative false) + (psa4output false) + (plotreference true) + (plotvalue true) + (plotinvisibletext false) + (sketchpadsonfab false) + (subtractmaskfromsilk false) + (outputformat 1) + (mirror false) + (drillshape 1) + (scaleselection 1) + (outputdirectory "") + ) + ) + + (net 0 "") + (net 1 "GND") + (net 2 "+5V") + (net 3 "Net-(J1-Pad4)") + (net 4 "/USB_D+") + (net 5 "/USB_D-") + + (footprint "misc:USB_Micro-B" (layer "F.Cu") + (tedit 61126B8C) (tstamp 00000000-0000-0000-0000-00005bc6c671) + (at 119.6 114 -90) + (descr "Micro USB Type B Receptacle") + (tags "USB USB_B USB_micro USB_OTG") + (path "/00000000-0000-0000-0000-00005bc9014b") + (attr smd allow_soldermask_bridges) + (fp_text reference "J1" (at 0 -3.45 -90) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 19142c96-cd97-45b3-8b34-185d93a736d4) + ) + (fp_text value "USB_B_Mini" (at 0 4.8 -90) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 591f07f5-9372-4cf1-aaf7-35a6c3e2f845) + ) + (fp_line (start -4.3509 -2.58754) (end 4.3491 -2.58754) + (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp ce1d4461-bc7e-48f0-84a4-687a64887837)) + (fp_line (start -4.3509 3.81746) (end -4.3509 -2.58754) + (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp 30f49c3c-8dec-4a0d-ad60-118ffde39a76)) + (fp_line (start -4.3509 3.81746) (end 4.3491 3.81746) + (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp 82b7cd4d-7e2d-4496-acd4-d923e3c8b93c)) + (fp_line (start 4.3491 -2.58754) (end 4.3491 3.81746) + (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp 7bad1388-06a8-492b-92c7-dd05fc82eb98)) + (fp_line (start 4.3491 2.58746) (end -4.3509 2.58746) + (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp b5138935-f4d8-4328-917a-9995721fc667)) + (fp_line (start -4.6 -2.8) (end 4.6 -2.8) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 4796a32f-002e-449b-8fb2-c4108a118d80)) + (fp_line (start -4.6 4.05) (end -4.6 -2.8) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e0959a58-2b7c-4a71-9f65-decd095bb440)) + (fp_line (start 4.6 -2.8) (end 4.6 4.05) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 17532c3f-7bcc-4906-bd41-ebf5e0831077)) + (fp_line (start 4.6 4.05) (end -4.6 4.05) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 783794ef-83f0-47ba-b2e9-66f7d9378127)) + (pad "1" smd rect locked (at -1.3009 -1.56254) (size 1.35 0.4) (layers "F.Cu" "F.Paste" "F.Mask") + (net 2 "+5V") (tstamp 285f0e15-1598-43cc-9694-ef95b7f1c5a2)) + (pad "2" smd rect locked (at -0.6509 -1.56254) (size 1.35 0.4) (layers "F.Cu" "F.Paste" "F.Mask") + (net 5 "/USB_D-") (tstamp 7934933f-6225-44c2-a670-7b29f03e51fb)) + (pad "3" smd rect locked (at -0.0009 -1.56254) (size 1.35 0.4) (layers "F.Cu" "F.Paste" "F.Mask") + (net 4 "/USB_D+") (tstamp f0a66f8b-9c70-4c95-8f9e-68aff291bef7)) + (pad "4" smd rect locked (at 0.6491 -1.56254) (size 1.35 0.4) (layers "F.Cu" "F.Paste" "F.Mask") + (net 3 "Net-(J1-Pad4)") (zone_connect 1) (thermal_bridge_width 1) (thermal_gap 0.2) (tstamp 0045807b-9040-4aa2-8c99-82784cd811b8)) + (pad "5" smd rect locked (at 1.2991 -1.56254) (size 1.35 0.4) (layers "F.Cu" "F.Paste" "F.Mask") + (net 1 "GND") (zone_connect 2) (tstamp c41b9a9d-6938-47b3-a6fe-2ed346c27eef)) + (pad "6" smd rect locked (at -3.75 1.15 270) (size 1.524 1.524) (layers "F.Cu" "F.Paste" "F.Mask") + (net 1 "GND") (tstamp d5d8c1e4-327b-42fc-bcef-3d0fa9018029)) + (pad "6" smd rect locked (at 3.75 1.15 270) (size 1.524 1.524) (layers "F.Cu" "F.Paste" "F.Mask") + (net 1 "GND") (tstamp 4347d612-d8f6-4214-94e2-8d259f248c3c)) + ) + + (footprint "Connectors_Samtec:MECF-30-0_-L-DV_Edge" (layer "F.Cu") + (tedit 61350C5C) (tstamp 103f6d42-92f5-4124-8bee-144c92aca775) + (at 137.0584 131.4704) + (descr "Highspeed card edge connector for PCB's with 30 contacts (polarized)") + (tags "conn samtec card-edge high-speed") + (attr exclude_from_pos_files exclude_from_bom) + (fp_text reference "J1" (at 0 -2.3368) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 90471db3-f00b-446a-8d70-567bb8cce2f8) + ) + (fp_text value "MECF-30-0_-L-DV_Edge" (at 0 -3.81) (layer "F.Fab") hide + (effects (font (size 1 1) (thickness 0.15))) + (tstamp f43bf272-af03-4d87-9632-c4b252859aea) + ) + (fp_text user "${REFERENCE}" (at 0 -2.54) (layer "F.Fab") hide + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 00a6fec1-7d77-4933-bd18-bafcacb18f00) + ) + (pad "1" smd rect (at -18.405 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 11d937ea-a27c-4c65-8a36-8562d6961c24)) + (pad "2" smd rect (at -18.405 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp a11475dc-e53c-42d3-b71e-0fa739a0a833)) + (pad "3" smd rect (at -17.135 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp c130793a-a43b-4150-85f5-91f6d2355b8e)) + (pad "4" smd rect (at -17.135 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp e923d763-055b-458c-adf3-df14914c6e55)) + (pad "5" smd rect (at -15.865 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp bac3cb40-b68c-49ce-9d27-154b83f70f69)) + (pad "6" smd rect (at -15.865 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 8b667a1d-48d4-447e-81dd-2d2a69cd75e9)) + (pad "7" smd rect (at -14.595 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp bc8a74f2-547d-4f8d-8443-83738af543e4)) + (pad "8" smd rect (at -14.595 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 7b0dc20c-e247-4016-8481-aca5c2186a70)) + (pad "9" smd rect (at -13.325 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp d7f3f291-9056-416c-bc17-3b58c50ac016)) + (pad "10" smd rect (at -13.325 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp c4d6c4c8-ea23-4fc7-a835-477a81089d22)) + (pad "11" smd rect (at -12.055 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 8978bdb6-c7f5-4479-a31a-601d518c4446)) + (pad "12" smd rect (at -12.055 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp f4790ac3-23f1-40e3-8a14-128482f3ee52)) + (pad "13" smd rect (at -10.785 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 12cd4dae-f9f4-4c46-aa0f-5c59b2107262)) + (pad "14" smd rect (at -10.785 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 7e42e9c2-5be7-4386-a7b0-eaf52bb287c5)) + (pad "15" smd rect (at -9.515 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp c3436ee2-41b0-4344-aa97-eed407177972)) + (pad "16" smd rect (at -9.515 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp b19df688-ee0d-4de9-935d-30937011ad03)) + (pad "17" smd rect (at -8.245 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 159b812b-8540-4774-bc5b-8ad33dfd0593)) + (pad "18" smd rect (at -8.245 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 8d405355-05fc-4f8c-89ff-9d1b6cd81fea)) + (pad "19" smd rect (at -6.975 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 2e855421-9cb9-444e-a061-1ee2b722479b)) + (pad "20" smd rect (at -6.975 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 395c0b20-68d0-4e1c-9301-eedb2a470b56)) + (pad "23" smd rect (at -4.435 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 14c540f9-3397-40b3-aec0-bc23ac0dcfe2)) + (pad "24" smd rect (at -4.435 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 4ad959a5-ea16-4f15-b85e-a5662f19b20e)) + (pad "25" smd rect (at -3.165 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp a5f9c367-677d-443c-8962-752191fe9ada)) + (pad "26" smd rect (at -3.165 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp a7998cef-7172-4140-864b-20039270e66d)) + (pad "27" smd rect (at -1.895 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 7656fc9f-315d-46df-a2e4-4c70042f287e)) + (pad "28" smd rect (at -1.895 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 676fbf4b-da22-4ab4-bb87-eb49e837df67)) + (pad "29" smd rect (at -0.625 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp fe9ebc39-ff5a-409c-a09d-189f8b56c772)) + (pad "30" smd rect (at -0.625 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 9d6a2dd0-cc03-4c28-be84-7e47c129b4cd)) + (pad "31" smd rect (at 0.645 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 990e2795-2354-4d92-938a-205cd69b83af)) + (pad "32" smd rect (at 0.645 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 7c9526da-4908-4b86-ad1a-dd25034b3fae)) + (pad "33" smd rect (at 1.915 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp f0bc68e1-7874-4fff-82fe-27789ca527e5)) + (pad "34" smd rect (at 1.915 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp d6d2a82f-a1bf-4799-bad4-e66a5be475d2)) + (pad "35" smd rect (at 3.185 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp a7a514e1-c7f0-40c8-93b5-cbe2fd739198)) + (pad "36" smd rect (at 3.185 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 71433ec0-c0d9-451a-8def-5898619def13)) + (pad "37" smd rect (at 4.455 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 20b46255-56b4-48f9-887c-0b6b64e15a88)) + (pad "38" smd rect (at 4.455 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp e65b08f2-33d8-4436-b4f6-592645b5501a)) + (pad "39" smd rect (at 5.725 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp ffcaa8be-0f85-4820-9e6e-df2448650787)) + (pad "40" smd rect (at 5.725 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp d17bd7dd-ddae-494d-8601-c53d37c802c4)) + (pad "41" smd rect (at 6.995 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 626aea62-5a4c-4e0c-be87-da2e4e7202b0)) + (pad "42" smd rect (at 6.995 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 16d8dbd3-baff-4f86-9b74-e30489d34bc9)) + (pad "43" smd rect (at 8.265 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 11d3dc49-815c-496a-bb57-4b8241a28450)) + (pad "44" smd rect (at 8.265 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp c8664550-7a66-44a9-aa08-bb3ef591c150)) + (pad "45" smd rect (at 9.535 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 170d8112-4763-479b-bc57-8b577a450c31)) + (pad "46" smd rect (at 9.535 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 55a78016-dd58-4ff2-a8d0-1527b0c32bd6)) + (pad "47" smd rect (at 10.805 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 438e6a23-d2b6-4eee-ab85-236e836b763a)) + (pad "48" smd rect (at 10.805 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp ad7b3a41-3e54-4616-a2fa-5d52895d9b10)) + (pad "49" smd rect (at 12.075 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 5b70f5e6-a1e5-4019-a9f9-ea3d0ebca6af)) + (pad "50" smd rect (at 12.075 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 78147562-6b7c-48d7-b14b-a745b4b04bf9)) + (pad "51" smd rect (at 13.345 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 7aeac291-9967-4572-b19c-b9a817d2a5a4)) + (pad "52" smd rect (at 13.345 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 8cca3d0b-feab-4bc6-83c7-a77a2afaf37c)) + (pad "53" smd rect (at 14.615 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 562d9dd2-baa2-4746-b30a-b2762aa2c404)) + (pad "54" smd rect (at 14.615 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp f3ba32ca-8fcb-4bfc-93bf-53260c31d6ba)) + (pad "55" smd rect (at 15.885 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp da0df920-6151-41b0-a0a7-79a503b10687)) + (pad "56" smd rect (at 15.885 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp efb417da-af07-4650-b62b-6170631e8e38)) + (pad "57" smd rect (at 17.155 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp c17ea107-7f9d-4ac8-8934-47421ee3fe69)) + (pad "58" smd rect (at 17.155 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 44c5be1c-9f1b-486f-a302-2b9c82baacdd)) + (pad "59" smd rect (at 18.425 2.5) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 40271b7a-541b-4a55-84f0-f2f8380c554e)) + (pad "60" smd rect (at 18.425 2.5) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 69cb44cd-1d98-4f6b-a546-991c02c6c40a)) + ) + + (footprint "Connectors_Samtec:MECF-05-0_-L-DV_Edge" (layer "F.Cu") + (tedit 61350FA5) (tstamp 62b4aee2-acbe-45e4-8b57-4eaf686fdc14) + (at 152.4 106.0196 90) + (descr "Highspeed card edge connector for PCB's with 05 contacts (polarized)") + (tags "conn samtec card-edge high-speed") + (attr exclude_from_pos_files exclude_from_bom allow_soldermask_bridges) + (fp_text reference "J2" (at 0 -1.7272 90) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 7bffa857-60bf-40aa-a1e6-5d77083f2122) + ) + (fp_text value "MECF-05-0_-L-DV_Edge" (at 0 -3.81 90) (layer "F.Fab") hide + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 712d6211-4adc-4877-adc0-6ec98f1de534) + ) + (pad "1" smd rect (at -2.53 2.5 90) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 30aae736-d979-4e97-b02c-8560d0eb585e)) + (pad "2" smd rect (at -2.53 2.5 90) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 6a2c0066-d6c4-4250-9327-6d75258edab0)) + (pad "5" smd rect (at 0.01 2.5 90) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp ad360258-fe83-4451-b9fa-39b3c318bd4c)) + (pad "6" smd rect (at 0.01 2.5 90) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 8daff011-a427-4928-9e89-a1e07536ed6a)) + (pad "7" smd rect (at 1.28 2.5 90) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp ee8c01a3-b33c-4b83-862d-45b8618f8477)) + (pad "8" smd rect (at 1.28 2.5 90) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp 2068dd33-7982-43be-96be-a6e6c0a35974)) + (pad "9" smd rect (at 2.55 2.5 90) (size 0.56 4) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp e21e3e2c-4508-4004-b163-ea499b0e0de3)) + (pad "10" smd rect (at 2.55 2.5 90) (size 0.56 4) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp b95972b0-79e5-49ca-88cd-6972e95d9e68)) + ) + + (gr_rect (start 117.602 131.318) (end 118.0084 131.7244) + (stroke (width 0.2) (type default)) (fill none) (layer "F.Cu") (tstamp d9c93f10-1129-47c3-bf26-abbdba86ec6f)) + (gr_line (start 157 98) (end 117 98) + (stroke (width 0.05) (type solid)) (layer "Edge.Cuts") (tstamp 6fdc229b-84d7-4e10-8fa1-783efbb32453)) + (gr_line (start 117 136) (end 157 136) + (stroke (width 0.05) (type solid)) (layer "Edge.Cuts") (tstamp a2245f46-0acd-42a9-8797-cb02bed5437a)) + (gr_line (start 117 98) (end 117 136) + (stroke (width 0.05) (type solid)) (layer "Edge.Cuts") (tstamp a9e9a585-8709-4509-9010-bd37c04721c5)) + (gr_line (start 157 136) (end 157 98) + (stroke (width 0.05) (type solid)) (layer "Edge.Cuts") (tstamp b1fe2711-1faa-4274-a6c0-1d84db072506)) + (dimension (type aligned) (layer "Dwgs.User") (tstamp a71fc2a9-34ff-41df-ae25-dbd047977aec) + (pts (xy 157 98) (xy 157 136)) + (height -1.9) + (gr_text "38.0000 mm" (at 157.75 117 90) (layer "Dwgs.User") (tstamp a71fc2a9-34ff-41df-ae25-dbd047977aec) + (effects (font (size 1 1) (thickness 0.15))) + ) + (format (units 2) (units_format 1) (precision 4)) + (style (thickness 0.15) (arrow_length 1.27) (text_position_mode 0) (extension_height 0.58642) (extension_offset 0) keep_text_aligned) + ) + (dimension (type aligned) (layer "Dwgs.User") (tstamp a815db39-5a92-4934-b9d3-05c47a6ae3e3) + (pts (xy 157 136) (xy 117 136)) + (height -1.3) + (gr_text "40.0000 mm" (at 137 136.15) (layer "Dwgs.User") (tstamp a815db39-5a92-4934-b9d3-05c47a6ae3e3) + (effects (font (size 1 1) (thickness 0.15))) + ) + (format (units 2) (units_format 1) (precision 4)) + (style (thickness 0.15) (arrow_length 1.27) (text_position_mode 0) (extension_height 0.58642) (extension_offset 0) keep_text_aligned) + ) + + (via (at 118.8 120.5) (size 0.8) (drill 0.4) (layers "F.Cu" "B.Cu") (net 1) (tstamp aa14b4af-301c-42f7-82a0-57f19e0744b4)) + (segment (start 123.8009 112.6991) (end 121.16254 112.6991) (width 0.3) (layer "F.Cu") (net 2) (tstamp 3260e08f-6413-41b8-a04d-fbebf9360be5)) + (segment (start 122.275041 113.8991) (end 123.9809 113.8991) (width 0.2) (layer "F.Cu") (net 4) (tstamp 3fc7f791-7488-4f04-a042-487eae1be88a)) + (segment (start 121.16254 113.9991) (end 122.175041 113.9991) (width 0.2) (layer "F.Cu") (net 4) (tstamp e6baa44c-fd43-445d-a5af-74691ba315af)) + (segment (start 122.175041 113.9991) (end 122.275041 113.8991) (width 0.2) (layer "F.Cu") (net 4) (tstamp f9041409-1e9d-4cf2-9f39-a564a9d3629a)) + (segment (start 121.16254 113.3491) (end 122.175041 113.3491) (width 0.2) (layer "F.Cu") (net 5) (tstamp 369c3e9e-2175-4135-acc9-72726fa30fc3)) + (segment (start 122.275041 113.4491) (end 124.1673 113.4491) (width 0.2) (layer "F.Cu") (net 5) (tstamp b850fd40-eaae-43c7-b6d2-e38df7b0e231)) + (segment (start 122.175041 113.3491) (end 122.275041 113.4491) (width 0.2) (layer "F.Cu") (net 5) (tstamp fe13bca2-0ab7-4f21-beb0-d492235819a7)) + + (zone (net 1) (net_name "GND") (layer "F.Cu") (tstamp de1fc50a-44a7-4297-8b87-e0bfaa683c57) (hatch edge 0.508) + (connect_pads (clearance 0.254)) + (min_thickness 0.254) (filled_areas_thickness no) + (fill yes (thermal_gap 0.254) (thermal_bridge_width 0.3)) + (polygon + (pts + (xy 117 98) + (xy 157 98) + (xy 157 136) + (xy 117 136) + ) + ) + (filled_polygon + (layer "F.Cu") + (pts + (xy 156.688121 98.274002) + (xy 156.734614 98.327658) + (xy 156.746 98.38) + (xy 156.746 102.8076) + (xy 156.725998 102.875721) + (xy 156.672342 102.922214) + (xy 156.62 102.9336) + (xy 152.874788 102.9336) + (xy 152.851247 102.938283) + (xy 152.812283 102.946033) + (xy 152.812281 102.946034) + (xy 152.800114 102.948454) + (xy 152.7898 102.955346) + (xy 152.789797 102.955347) + (xy 152.725751 102.998142) + (xy 152.715435 103.005035) + (xy 152.708542 103.015351) + (xy 152.665747 103.079397) + (xy 152.665746 103.0794) + (xy 152.658854 103.089714) + (xy 152.644 103.164388) + (xy 152.644 103.774812) + (xy 152.658854 103.849486) + (xy 152.665746 103.8598) + (xy 152.665747 103.859803) + (xy 152.708542 103.923849) + (xy 152.715435 103.934165) + (xy 152.800114 103.990746) + (xy 152.804534 103.991625) + (xy 152.855554 104.032741) + (xy 152.877974 104.100104) + (xy 152.860415 104.168895) + (xy 152.809104 104.216666) + (xy 152.800114 104.218454) + (xy 152.715435 104.275035) + (xy 152.708542 104.285351) + (xy 152.665747 104.349397) + (xy 152.665746 104.3494) + (xy 152.658854 104.359714) + (xy 152.644 104.434388) + (xy 152.644 105.044812) + (xy 152.658854 105.119486) + (xy 152.665746 105.1298) + (xy 152.665747 105.129803) + (xy 152.708542 105.193849) + (xy 152.715435 105.204165) + (xy 152.800114 105.260746) + (xy 152.804534 105.261625) + (xy 152.855554 105.302741) + (xy 152.877974 105.370104) + (xy 152.860415 105.438895) + (xy 152.809104 105.486666) + (xy 152.800114 105.488454) + (xy 152.715435 105.545035) + (xy 152.708542 105.555351) + (xy 152.665747 105.619397) + (xy 152.665746 105.6194) + (xy 152.658854 105.629714) + (xy 152.644 105.704388) + (xy 152.644 106.314812) + (xy 152.658854 106.389486) + (xy 152.665746 106.3998) + (xy 152.665747 106.399803) + (xy 152.708542 106.463849) + (xy 152.715435 106.474165) + (xy 152.725751 106.481058) + (xy 152.789797 106.523853) + (xy 152.7898 106.523854) + (xy 152.800114 106.530746) + (xy 152.812281 106.533166) + (xy 152.812283 106.533167) + (xy 152.851247 106.540917) + (xy 152.874788 106.5456) + (xy 156.62 106.5456) + (xy 156.688121 106.565602) + (xy 156.734614 106.619258) + (xy 156.746 106.6716) + (xy 156.746 107.8876) + (xy 156.725998 107.955721) + (xy 156.672342 108.002214) + (xy 156.62 108.0136) + (xy 152.874788 108.0136) + (xy 152.851247 108.018283) + (xy 152.812283 108.026033) + (xy 152.812281 108.026034) + (xy 152.800114 108.028454) + (xy 152.7898 108.035346) + (xy 152.789797 108.035347) + (xy 152.725751 108.078142) + (xy 152.715435 108.085035) + (xy 152.708542 108.095351) + (xy 152.665747 108.159397) + (xy 152.665746 108.1594) + (xy 152.658854 108.169714) + (xy 152.644 108.244388) + (xy 152.644 108.854812) + (xy 152.658854 108.929486) + (xy 152.665746 108.9398) + (xy 152.665747 108.939803) + (xy 152.708542 109.003849) + (xy 152.715435 109.014165) + (xy 152.725751 109.021058) + (xy 152.789797 109.063853) + (xy 152.7898 109.063854) + (xy 152.800114 109.070746) + (xy 152.812281 109.073166) + (xy 152.812283 109.073167) + (xy 152.851247 109.080917) + (xy 152.874788 109.0856) + (xy 156.62 109.0856) + (xy 156.688121 109.105602) + (xy 156.734614 109.159258) + (xy 156.746 109.2116) + (xy 156.746 135.62) + (xy 156.725998 135.688121) + (xy 156.672342 135.734614) + (xy 156.62 135.746) + (xy 156.1454 135.746) + (xy 156.077279 135.725998) + (xy 156.030786 135.672342) + (xy 156.0194 135.62) + (xy 156.0194 131.945188) + (xy 156.004546 131.870514) + (xy 155.997654 131.8602) + (xy 155.997653 131.860197) + (xy 155.954858 131.796151) + (xy 155.947965 131.785835) + (xy 155.937649 131.778942) + (xy 155.873603 131.736147) + (xy 155.8736 131.736146) + (xy 155.863286 131.729254) + (xy 155.851119 131.726834) + (xy 155.851117 131.726833) + (xy 155.812153 131.719083) + (xy 155.788612 131.7144) + (xy 155.178188 131.7144) + (xy 155.154647 131.719083) + (xy 155.115683 131.726833) + (xy 155.115681 131.726834) + (xy 155.103514 131.729254) + (xy 155.0932 131.736146) + (xy 155.093197 131.736147) + (xy 155.029151 131.778942) + (xy 155.018835 131.785835) + (xy 155.011942 131.796151) + (xy 154.973858 131.853148) + (xy 154.962254 131.870514) + (xy 154.961375 131.874934) + (xy 154.920259 131.925954) + (xy 154.852896 131.948374) + (xy 154.784105 131.930815) + (xy 154.736334 131.879504) + (xy 154.734546 131.870514) + (xy 154.722943 131.853148) + (xy 154.684858 131.796151) + (xy 154.677965 131.785835) + (xy 154.667649 131.778942) + (xy 154.603603 131.736147) + (xy 154.6036 131.736146) + (xy 154.593286 131.729254) + (xy 154.581119 131.726834) + (xy 154.581117 131.726833) + (xy 154.542153 131.719083) + (xy 154.518612 131.7144) + (xy 153.908188 131.7144) + (xy 153.884647 131.719083) + (xy 153.845683 131.726833) + (xy 153.845681 131.726834) + (xy 153.833514 131.729254) + (xy 153.8232 131.736146) + (xy 153.823197 131.736147) + (xy 153.759151 131.778942) + (xy 153.748835 131.785835) + (xy 153.741942 131.796151) + (xy 153.703858 131.853148) + (xy 153.692254 131.870514) + (xy 153.691375 131.874934) + (xy 153.650259 131.925954) + (xy 153.582896 131.948374) + (xy 153.514105 131.930815) + (xy 153.466334 131.879504) + (xy 153.464546 131.870514) + (xy 153.452943 131.853148) + (xy 153.414858 131.796151) + (xy 153.407965 131.785835) + (xy 153.397649 131.778942) + (xy 153.333603 131.736147) + (xy 153.3336 131.736146) + (xy 153.323286 131.729254) + (xy 153.311119 131.726834) + (xy 153.311117 131.726833) + (xy 153.272153 131.719083) + (xy 153.248612 131.7144) + (xy 152.638188 131.7144) + (xy 152.614647 131.719083) + (xy 152.575683 131.726833) + (xy 152.575681 131.726834) + (xy 152.563514 131.729254) + (xy 152.5532 131.736146) + (xy 152.553197 131.736147) + (xy 152.489151 131.778942) + (xy 152.478835 131.785835) + (xy 152.471942 131.796151) + (xy 152.433858 131.853148) + (xy 152.422254 131.870514) + (xy 152.421375 131.874934) + (xy 152.380259 131.925954) + (xy 152.312896 131.948374) + (xy 152.244105 131.930815) + (xy 152.196334 131.879504) + (xy 152.194546 131.870514) + (xy 152.182943 131.853148) + (xy 152.144858 131.796151) + (xy 152.137965 131.785835) + (xy 152.127649 131.778942) + (xy 152.063603 131.736147) + (xy 152.0636 131.736146) + (xy 152.053286 131.729254) + (xy 152.041119 131.726834) + (xy 152.041117 131.726833) + (xy 152.002153 131.719083) + (xy 151.978612 131.7144) + (xy 151.368188 131.7144) + (xy 151.344647 131.719083) + (xy 151.305683 131.726833) + (xy 151.305681 131.726834) + (xy 151.293514 131.729254) + (xy 151.2832 131.736146) + (xy 151.283197 131.736147) + (xy 151.219151 131.778942) + (xy 151.208835 131.785835) + (xy 151.201942 131.796151) + (xy 151.163858 131.853148) + (xy 151.152254 131.870514) + (xy 151.151375 131.874934) + (xy 151.110259 131.925954) + (xy 151.042896 131.948374) + (xy 150.974105 131.930815) + (xy 150.926334 131.879504) + (xy 150.924546 131.870514) + (xy 150.912943 131.853148) + (xy 150.874858 131.796151) + (xy 150.867965 131.785835) + (xy 150.857649 131.778942) + (xy 150.793603 131.736147) + (xy 150.7936 131.736146) + (xy 150.783286 131.729254) + (xy 150.771119 131.726834) + (xy 150.771117 131.726833) + (xy 150.732153 131.719083) + (xy 150.708612 131.7144) + (xy 150.098188 131.7144) + (xy 150.074647 131.719083) + (xy 150.035683 131.726833) + (xy 150.035681 131.726834) + (xy 150.023514 131.729254) + (xy 150.0132 131.736146) + (xy 150.013197 131.736147) + (xy 149.949151 131.778942) + (xy 149.938835 131.785835) + (xy 149.931942 131.796151) + (xy 149.893858 131.853148) + (xy 149.882254 131.870514) + (xy 149.881375 131.874934) + (xy 149.840259 131.925954) + (xy 149.772896 131.948374) + (xy 149.704105 131.930815) + (xy 149.656334 131.879504) + (xy 149.654546 131.870514) + (xy 149.642943 131.853148) + (xy 149.604858 131.796151) + (xy 149.597965 131.785835) + (xy 149.587649 131.778942) + (xy 149.523603 131.736147) + (xy 149.5236 131.736146) + (xy 149.513286 131.729254) + (xy 149.501119 131.726834) + (xy 149.501117 131.726833) + (xy 149.462153 131.719083) + (xy 149.438612 131.7144) + (xy 148.828188 131.7144) + (xy 148.804647 131.719083) + (xy 148.765683 131.726833) + (xy 148.765681 131.726834) + (xy 148.753514 131.729254) + (xy 148.7432 131.736146) + (xy 148.743197 131.736147) + (xy 148.679151 131.778942) + (xy 148.668835 131.785835) + (xy 148.661942 131.796151) + (xy 148.623858 131.853148) + (xy 148.612254 131.870514) + (xy 148.611375 131.874934) + (xy 148.570259 131.925954) + (xy 148.502896 131.948374) + (xy 148.434105 131.930815) + (xy 148.386334 131.879504) + (xy 148.384546 131.870514) + (xy 148.372943 131.853148) + (xy 148.334858 131.796151) + (xy 148.327965 131.785835) + (xy 148.317649 131.778942) + (xy 148.253603 131.736147) + (xy 148.2536 131.736146) + (xy 148.243286 131.729254) + (xy 148.231119 131.726834) + (xy 148.231117 131.726833) + (xy 148.192153 131.719083) + (xy 148.168612 131.7144) + (xy 147.558188 131.7144) + (xy 147.534647 131.719083) + (xy 147.495683 131.726833) + (xy 147.495681 131.726834) + (xy 147.483514 131.729254) + (xy 147.4732 131.736146) + (xy 147.473197 131.736147) + (xy 147.409151 131.778942) + (xy 147.398835 131.785835) + (xy 147.391942 131.796151) + (xy 147.353858 131.853148) + (xy 147.342254 131.870514) + (xy 147.341375 131.874934) + (xy 147.300259 131.925954) + (xy 147.232896 131.948374) + (xy 147.164105 131.930815) + (xy 147.116334 131.879504) + (xy 147.114546 131.870514) + (xy 147.102943 131.853148) + (xy 147.064858 131.796151) + (xy 147.057965 131.785835) + (xy 147.047649 131.778942) + (xy 146.983603 131.736147) + (xy 146.9836 131.736146) + (xy 146.973286 131.729254) + (xy 146.961119 131.726834) + (xy 146.961117 131.726833) + (xy 146.922153 131.719083) + (xy 146.898612 131.7144) + (xy 146.288188 131.7144) + (xy 146.264647 131.719083) + (xy 146.225683 131.726833) + (xy 146.225681 131.726834) + (xy 146.213514 131.729254) + (xy 146.2032 131.736146) + (xy 146.203197 131.736147) + (xy 146.139151 131.778942) + (xy 146.128835 131.785835) + (xy 146.121942 131.796151) + (xy 146.083858 131.853148) + (xy 146.072254 131.870514) + (xy 146.071375 131.874934) + (xy 146.030259 131.925954) + (xy 145.962896 131.948374) + (xy 145.894105 131.930815) + (xy 145.846334 131.879504) + (xy 145.844546 131.870514) + (xy 145.832943 131.853148) + (xy 145.794858 131.796151) + (xy 145.787965 131.785835) + (xy 145.777649 131.778942) + (xy 145.713603 131.736147) + (xy 145.7136 131.736146) + (xy 145.703286 131.729254) + (xy 145.691119 131.726834) + (xy 145.691117 131.726833) + (xy 145.652153 131.719083) + (xy 145.628612 131.7144) + (xy 145.018188 131.7144) + (xy 144.994647 131.719083) + (xy 144.955683 131.726833) + (xy 144.955681 131.726834) + (xy 144.943514 131.729254) + (xy 144.9332 131.736146) + (xy 144.933197 131.736147) + (xy 144.869151 131.778942) + (xy 144.858835 131.785835) + (xy 144.851942 131.796151) + (xy 144.813858 131.853148) + (xy 144.802254 131.870514) + (xy 144.801375 131.874934) + (xy 144.760259 131.925954) + (xy 144.692896 131.948374) + (xy 144.624105 131.930815) + (xy 144.576334 131.879504) + (xy 144.574546 131.870514) + (xy 144.562943 131.853148) + (xy 144.524858 131.796151) + (xy 144.517965 131.785835) + (xy 144.507649 131.778942) + (xy 144.443603 131.736147) + (xy 144.4436 131.736146) + (xy 144.433286 131.729254) + (xy 144.421119 131.726834) + (xy 144.421117 131.726833) + (xy 144.382153 131.719083) + (xy 144.358612 131.7144) + (xy 143.748188 131.7144) + (xy 143.724647 131.719083) + (xy 143.685683 131.726833) + (xy 143.685681 131.726834) + (xy 143.673514 131.729254) + (xy 143.6632 131.736146) + (xy 143.663197 131.736147) + (xy 143.599151 131.778942) + (xy 143.588835 131.785835) + (xy 143.581942 131.796151) + (xy 143.543858 131.853148) + (xy 143.532254 131.870514) + (xy 143.531375 131.874934) + (xy 143.490259 131.925954) + (xy 143.422896 131.948374) + (xy 143.354105 131.930815) + (xy 143.306334 131.879504) + (xy 143.304546 131.870514) + (xy 143.292943 131.853148) + (xy 143.254858 131.796151) + (xy 143.247965 131.785835) + (xy 143.237649 131.778942) + (xy 143.173603 131.736147) + (xy 143.1736 131.736146) + (xy 143.163286 131.729254) + (xy 143.151119 131.726834) + (xy 143.151117 131.726833) + (xy 143.112153 131.719083) + (xy 143.088612 131.7144) + (xy 142.478188 131.7144) + (xy 142.454647 131.719083) + (xy 142.415683 131.726833) + (xy 142.415681 131.726834) + (xy 142.403514 131.729254) + (xy 142.3932 131.736146) + (xy 142.393197 131.736147) + (xy 142.329151 131.778942) + (xy 142.318835 131.785835) + (xy 142.311942 131.796151) + (xy 142.273858 131.853148) + (xy 142.262254 131.870514) + (xy 142.261375 131.874934) + (xy 142.220259 131.925954) + (xy 142.152896 131.948374) + (xy 142.084105 131.930815) + (xy 142.036334 131.879504) + (xy 142.034546 131.870514) + (xy 142.022943 131.853148) + (xy 141.984858 131.796151) + (xy 141.977965 131.785835) + (xy 141.967649 131.778942) + (xy 141.903603 131.736147) + (xy 141.9036 131.736146) + (xy 141.893286 131.729254) + (xy 141.881119 131.726834) + (xy 141.881117 131.726833) + (xy 141.842153 131.719083) + (xy 141.818612 131.7144) + (xy 141.208188 131.7144) + (xy 141.184647 131.719083) + (xy 141.145683 131.726833) + (xy 141.145681 131.726834) + (xy 141.133514 131.729254) + (xy 141.1232 131.736146) + (xy 141.123197 131.736147) + (xy 141.059151 131.778942) + (xy 141.048835 131.785835) + (xy 141.041942 131.796151) + (xy 141.003858 131.853148) + (xy 140.992254 131.870514) + (xy 140.991375 131.874934) + (xy 140.950259 131.925954) + (xy 140.882896 131.948374) + (xy 140.814105 131.930815) + (xy 140.766334 131.879504) + (xy 140.764546 131.870514) + (xy 140.752943 131.853148) + (xy 140.714858 131.796151) + (xy 140.707965 131.785835) + (xy 140.697649 131.778942) + (xy 140.633603 131.736147) + (xy 140.6336 131.736146) + (xy 140.623286 131.729254) + (xy 140.611119 131.726834) + (xy 140.611117 131.726833) + (xy 140.572153 131.719083) + (xy 140.548612 131.7144) + (xy 139.938188 131.7144) + (xy 139.914647 131.719083) + (xy 139.875683 131.726833) + (xy 139.875681 131.726834) + (xy 139.863514 131.729254) + (xy 139.8532 131.736146) + (xy 139.853197 131.736147) + (xy 139.789151 131.778942) + (xy 139.778835 131.785835) + (xy 139.771942 131.796151) + (xy 139.733858 131.853148) + (xy 139.722254 131.870514) + (xy 139.721375 131.874934) + (xy 139.680259 131.925954) + (xy 139.612896 131.948374) + (xy 139.544105 131.930815) + (xy 139.496334 131.879504) + (xy 139.494546 131.870514) + (xy 139.482943 131.853148) + (xy 139.444858 131.796151) + (xy 139.437965 131.785835) + (xy 139.427649 131.778942) + (xy 139.363603 131.736147) + (xy 139.3636 131.736146) + (xy 139.353286 131.729254) + (xy 139.341119 131.726834) + (xy 139.341117 131.726833) + (xy 139.302153 131.719083) + (xy 139.278612 131.7144) + (xy 138.668188 131.7144) + (xy 138.644647 131.719083) + (xy 138.605683 131.726833) + (xy 138.605681 131.726834) + (xy 138.593514 131.729254) + (xy 138.5832 131.736146) + (xy 138.583197 131.736147) + (xy 138.519151 131.778942) + (xy 138.508835 131.785835) + (xy 138.501942 131.796151) + (xy 138.463858 131.853148) + (xy 138.452254 131.870514) + (xy 138.451375 131.874934) + (xy 138.410259 131.925954) + (xy 138.342896 131.948374) + (xy 138.274105 131.930815) + (xy 138.226334 131.879504) + (xy 138.224546 131.870514) + (xy 138.212943 131.853148) + (xy 138.174858 131.796151) + (xy 138.167965 131.785835) + (xy 138.157649 131.778942) + (xy 138.093603 131.736147) + (xy 138.0936 131.736146) + (xy 138.083286 131.729254) + (xy 138.071119 131.726834) + (xy 138.071117 131.726833) + (xy 138.032153 131.719083) + (xy 138.008612 131.7144) + (xy 137.398188 131.7144) + (xy 137.374647 131.719083) + (xy 137.335683 131.726833) + (xy 137.335681 131.726834) + (xy 137.323514 131.729254) + (xy 137.3132 131.736146) + (xy 137.313197 131.736147) + (xy 137.249151 131.778942) + (xy 137.238835 131.785835) + (xy 137.231942 131.796151) + (xy 137.193858 131.853148) + (xy 137.182254 131.870514) + (xy 137.181375 131.874934) + (xy 137.140259 131.925954) + (xy 137.072896 131.948374) + (xy 137.004105 131.930815) + (xy 136.956334 131.879504) + (xy 136.954546 131.870514) + (xy 136.942943 131.853148) + (xy 136.904858 131.796151) + (xy 136.897965 131.785835) + (xy 136.887649 131.778942) + (xy 136.823603 131.736147) + (xy 136.8236 131.736146) + (xy 136.813286 131.729254) + (xy 136.801119 131.726834) + (xy 136.801117 131.726833) + (xy 136.762153 131.719083) + (xy 136.738612 131.7144) + (xy 136.128188 131.7144) + (xy 136.104647 131.719083) + (xy 136.065683 131.726833) + (xy 136.065681 131.726834) + (xy 136.053514 131.729254) + (xy 136.0432 131.736146) + (xy 136.043197 131.736147) + (xy 135.979151 131.778942) + (xy 135.968835 131.785835) + (xy 135.961942 131.796151) + (xy 135.923858 131.853148) + (xy 135.912254 131.870514) + (xy 135.911375 131.874934) + (xy 135.870259 131.925954) + (xy 135.802896 131.948374) + (xy 135.734105 131.930815) + (xy 135.686334 131.879504) + (xy 135.684546 131.870514) + (xy 135.672943 131.853148) + (xy 135.634858 131.796151) + (xy 135.627965 131.785835) + (xy 135.617649 131.778942) + (xy 135.553603 131.736147) + (xy 135.5536 131.736146) + (xy 135.543286 131.729254) + (xy 135.531119 131.726834) + (xy 135.531117 131.726833) + (xy 135.492153 131.719083) + (xy 135.468612 131.7144) + (xy 134.858188 131.7144) + (xy 134.834647 131.719083) + (xy 134.795683 131.726833) + (xy 134.795681 131.726834) + (xy 134.783514 131.729254) + (xy 134.7732 131.736146) + (xy 134.773197 131.736147) + (xy 134.709151 131.778942) + (xy 134.698835 131.785835) + (xy 134.691942 131.796151) + (xy 134.653858 131.853148) + (xy 134.642254 131.870514) + (xy 134.641375 131.874934) + (xy 134.600259 131.925954) + (xy 134.532896 131.948374) + (xy 134.464105 131.930815) + (xy 134.416334 131.879504) + (xy 134.414546 131.870514) + (xy 134.402943 131.853148) + (xy 134.364858 131.796151) + (xy 134.357965 131.785835) + (xy 134.347649 131.778942) + (xy 134.283603 131.736147) + (xy 134.2836 131.736146) + (xy 134.273286 131.729254) + (xy 134.261119 131.726834) + (xy 134.261117 131.726833) + (xy 134.222153 131.719083) + (xy 134.198612 131.7144) + (xy 133.588188 131.7144) + (xy 133.564647 131.719083) + (xy 133.525683 131.726833) + (xy 133.525681 131.726834) + (xy 133.513514 131.729254) + (xy 133.5032 131.736146) + (xy 133.503197 131.736147) + (xy 133.439151 131.778942) + (xy 133.428835 131.785835) + (xy 133.421942 131.796151) + (xy 133.383858 131.853148) + (xy 133.372254 131.870514) + (xy 133.371375 131.874934) + (xy 133.330259 131.925954) + (xy 133.262896 131.948374) + (xy 133.194105 131.930815) + (xy 133.146334 131.879504) + (xy 133.144546 131.870514) + (xy 133.132943 131.853148) + (xy 133.094858 131.796151) + (xy 133.087965 131.785835) + (xy 133.077649 131.778942) + (xy 133.013603 131.736147) + (xy 133.0136 131.736146) + (xy 133.003286 131.729254) + (xy 132.991119 131.726834) + (xy 132.991117 131.726833) + (xy 132.952153 131.719083) + (xy 132.928612 131.7144) + (xy 132.318188 131.7144) + (xy 132.294647 131.719083) + (xy 132.255683 131.726833) + (xy 132.255681 131.726834) + (xy 132.243514 131.729254) + (xy 132.2332 131.736146) + (xy 132.233197 131.736147) + (xy 132.169151 131.778942) + (xy 132.158835 131.785835) + (xy 132.151942 131.796151) + (xy 132.109147 131.860197) + (xy 132.109146 131.8602) + (xy 132.102254 131.870514) + (xy 132.0874 131.945188) + (xy 132.0874 135.62) + (xy 132.067398 135.688121) + (xy 132.013742 135.734614) + (xy 131.9614 135.746) + (xy 130.7454 135.746) + (xy 130.677279 135.725998) + (xy 130.630786 135.672342) + (xy 130.6194 135.62) + (xy 130.6194 131.945188) + (xy 130.604546 131.870514) + (xy 130.597654 131.8602) + (xy 130.597653 131.860197) + (xy 130.554858 131.796151) + (xy 130.547965 131.785835) + (xy 130.537649 131.778942) + (xy 130.473603 131.736147) + (xy 130.4736 131.736146) + (xy 130.463286 131.729254) + (xy 130.451119 131.726834) + (xy 130.451117 131.726833) + (xy 130.412153 131.719083) + (xy 130.388612 131.7144) + (xy 129.778188 131.7144) + (xy 129.754647 131.719083) + (xy 129.715683 131.726833) + (xy 129.715681 131.726834) + (xy 129.703514 131.729254) + (xy 129.6932 131.736146) + (xy 129.693197 131.736147) + (xy 129.629151 131.778942) + (xy 129.618835 131.785835) + (xy 129.611942 131.796151) + (xy 129.573858 131.853148) + (xy 129.562254 131.870514) + (xy 129.561375 131.874934) + (xy 129.520259 131.925954) + (xy 129.452896 131.948374) + (xy 129.384105 131.930815) + (xy 129.336334 131.879504) + (xy 129.334546 131.870514) + (xy 129.322943 131.853148) + (xy 129.284858 131.796151) + (xy 129.277965 131.785835) + (xy 129.267649 131.778942) + (xy 129.203603 131.736147) + (xy 129.2036 131.736146) + (xy 129.193286 131.729254) + (xy 129.181119 131.726834) + (xy 129.181117 131.726833) + (xy 129.142153 131.719083) + (xy 129.118612 131.7144) + (xy 128.508188 131.7144) + (xy 128.484647 131.719083) + (xy 128.445683 131.726833) + (xy 128.445681 131.726834) + (xy 128.433514 131.729254) + (xy 128.4232 131.736146) + (xy 128.423197 131.736147) + (xy 128.359151 131.778942) + (xy 128.348835 131.785835) + (xy 128.341942 131.796151) + (xy 128.303858 131.853148) + (xy 128.292254 131.870514) + (xy 128.291375 131.874934) + (xy 128.250259 131.925954) + (xy 128.182896 131.948374) + (xy 128.114105 131.930815) + (xy 128.066334 131.879504) + (xy 128.064546 131.870514) + (xy 128.052943 131.853148) + (xy 128.014858 131.796151) + (xy 128.007965 131.785835) + (xy 127.997649 131.778942) + (xy 127.933603 131.736147) + (xy 127.9336 131.736146) + (xy 127.923286 131.729254) + (xy 127.911119 131.726834) + (xy 127.911117 131.726833) + (xy 127.872153 131.719083) + (xy 127.848612 131.7144) + (xy 127.238188 131.7144) + (xy 127.214647 131.719083) + (xy 127.175683 131.726833) + (xy 127.175681 131.726834) + (xy 127.163514 131.729254) + (xy 127.1532 131.736146) + (xy 127.153197 131.736147) + (xy 127.089151 131.778942) + (xy 127.078835 131.785835) + (xy 127.071942 131.796151) + (xy 127.033858 131.853148) + (xy 127.022254 131.870514) + (xy 127.021375 131.874934) + (xy 126.980259 131.925954) + (xy 126.912896 131.948374) + (xy 126.844105 131.930815) + (xy 126.796334 131.879504) + (xy 126.794546 131.870514) + (xy 126.782943 131.853148) + (xy 126.744858 131.796151) + (xy 126.737965 131.785835) + (xy 126.727649 131.778942) + (xy 126.663603 131.736147) + (xy 126.6636 131.736146) + (xy 126.653286 131.729254) + (xy 126.641119 131.726834) + (xy 126.641117 131.726833) + (xy 126.602153 131.719083) + (xy 126.578612 131.7144) + (xy 125.968188 131.7144) + (xy 125.944647 131.719083) + (xy 125.905683 131.726833) + (xy 125.905681 131.726834) + (xy 125.893514 131.729254) + (xy 125.8832 131.736146) + (xy 125.883197 131.736147) + (xy 125.819151 131.778942) + (xy 125.808835 131.785835) + (xy 125.801942 131.796151) + (xy 125.763858 131.853148) + (xy 125.752254 131.870514) + (xy 125.751375 131.874934) + (xy 125.710259 131.925954) + (xy 125.642896 131.948374) + (xy 125.574105 131.930815) + (xy 125.526334 131.879504) + (xy 125.524546 131.870514) + (xy 125.512943 131.853148) + (xy 125.474858 131.796151) + (xy 125.467965 131.785835) + (xy 125.457649 131.778942) + (xy 125.393603 131.736147) + (xy 125.3936 131.736146) + (xy 125.383286 131.729254) + (xy 125.371119 131.726834) + (xy 125.371117 131.726833) + (xy 125.332153 131.719083) + (xy 125.308612 131.7144) + (xy 124.698188 131.7144) + (xy 124.674647 131.719083) + (xy 124.635683 131.726833) + (xy 124.635681 131.726834) + (xy 124.623514 131.729254) + (xy 124.6132 131.736146) + (xy 124.613197 131.736147) + (xy 124.549151 131.778942) + (xy 124.538835 131.785835) + (xy 124.531942 131.796151) + (xy 124.493858 131.853148) + (xy 124.482254 131.870514) + (xy 124.481375 131.874934) + (xy 124.440259 131.925954) + (xy 124.372896 131.948374) + (xy 124.304105 131.930815) + (xy 124.256334 131.879504) + (xy 124.254546 131.870514) + (xy 124.242943 131.853148) + (xy 124.204858 131.796151) + (xy 124.197965 131.785835) + (xy 124.187649 131.778942) + (xy 124.123603 131.736147) + (xy 124.1236 131.736146) + (xy 124.113286 131.729254) + (xy 124.101119 131.726834) + (xy 124.101117 131.726833) + (xy 124.062153 131.719083) + (xy 124.038612 131.7144) + (xy 123.428188 131.7144) + (xy 123.404647 131.719083) + (xy 123.365683 131.726833) + (xy 123.365681 131.726834) + (xy 123.353514 131.729254) + (xy 123.3432 131.736146) + (xy 123.343197 131.736147) + (xy 123.279151 131.778942) + (xy 123.268835 131.785835) + (xy 123.261942 131.796151) + (xy 123.223858 131.853148) + (xy 123.212254 131.870514) + (xy 123.211375 131.874934) + (xy 123.170259 131.925954) + (xy 123.102896 131.948374) + (xy 123.034105 131.930815) + (xy 122.986334 131.879504) + (xy 122.984546 131.870514) + (xy 122.972943 131.853148) + (xy 122.934858 131.796151) + (xy 122.927965 131.785835) + (xy 122.917649 131.778942) + (xy 122.853603 131.736147) + (xy 122.8536 131.736146) + (xy 122.843286 131.729254) + (xy 122.831119 131.726834) + (xy 122.831117 131.726833) + (xy 122.792153 131.719083) + (xy 122.768612 131.7144) + (xy 122.158188 131.7144) + (xy 122.134647 131.719083) + (xy 122.095683 131.726833) + (xy 122.095681 131.726834) + (xy 122.083514 131.729254) + (xy 122.0732 131.736146) + (xy 122.073197 131.736147) + (xy 122.009151 131.778942) + (xy 121.998835 131.785835) + (xy 121.991942 131.796151) + (xy 121.953858 131.853148) + (xy 121.942254 131.870514) + (xy 121.941375 131.874934) + (xy 121.900259 131.925954) + (xy 121.832896 131.948374) + (xy 121.764105 131.930815) + (xy 121.716334 131.879504) + (xy 121.714546 131.870514) + (xy 121.702943 131.853148) + (xy 121.664858 131.796151) + (xy 121.657965 131.785835) + (xy 121.647649 131.778942) + (xy 121.583603 131.736147) + (xy 121.5836 131.736146) + (xy 121.573286 131.729254) + (xy 121.561119 131.726834) + (xy 121.561117 131.726833) + (xy 121.522153 131.719083) + (xy 121.498612 131.7144) + (xy 120.888188 131.7144) + (xy 120.864647 131.719083) + (xy 120.825683 131.726833) + (xy 120.825681 131.726834) + (xy 120.813514 131.729254) + (xy 120.8032 131.736146) + (xy 120.803197 131.736147) + (xy 120.739151 131.778942) + (xy 120.728835 131.785835) + (xy 120.721942 131.796151) + (xy 120.683858 131.853148) + (xy 120.672254 131.870514) + (xy 120.671375 131.874934) + (xy 120.630259 131.925954) + (xy 120.562896 131.948374) + (xy 120.494105 131.930815) + (xy 120.446334 131.879504) + (xy 120.444546 131.870514) + (xy 120.432943 131.853148) + (xy 120.394858 131.796151) + (xy 120.387965 131.785835) + (xy 120.377649 131.778942) + (xy 120.313603 131.736147) + (xy 120.3136 131.736146) + (xy 120.303286 131.729254) + (xy 120.291119 131.726834) + (xy 120.291117 131.726833) + (xy 120.252153 131.719083) + (xy 120.228612 131.7144) + (xy 119.618188 131.7144) + (xy 119.594647 131.719083) + (xy 119.555683 131.726833) + (xy 119.555681 131.726834) + (xy 119.543514 131.729254) + (xy 119.5332 131.736146) + (xy 119.533197 131.736147) + (xy 119.469151 131.778942) + (xy 119.458835 131.785835) + (xy 119.451942 131.796151) + (xy 119.413858 131.853148) + (xy 119.402254 131.870514) + (xy 119.401375 131.874934) + (xy 119.360259 131.925954) + (xy 119.292896 131.948374) + (xy 119.224105 131.930815) + (xy 119.176334 131.879504) + (xy 119.174546 131.870514) + (xy 119.162943 131.853148) + (xy 119.124858 131.796151) + (xy 119.117965 131.785835) + (xy 119.107649 131.778942) + (xy 119.043603 131.736147) + (xy 119.0436 131.736146) + (xy 119.033286 131.729254) + (xy 119.021119 131.726834) + (xy 119.021117 131.726833) + (xy 118.982153 131.719083) + (xy 118.958612 131.7144) + (xy 118.4884 131.7144) + (xy 118.420279 131.694398) + (xy 118.373786 131.640742) + (xy 118.3624 131.5884) + (xy 118.3624 131.339034) + (xy 118.36287 131.328162) + (xy 118.36529 131.300219) + (xy 118.366189 131.289841) + (xy 118.356528 131.250947) + (xy 118.354522 131.241261) + (xy 118.349656 131.212025) + (xy 118.349655 131.212023) + (xy 118.347945 131.201748) + (xy 118.342998 131.19258) + (xy 118.341771 131.188997) + (xy 118.340287 131.185568) + (xy 118.337778 131.175466) + (xy 118.316036 131.141794) + (xy 118.311011 131.133296) + (xy 118.296931 131.107199) + (xy 118.296927 131.107193) + (xy 118.291983 131.098031) + (xy 118.284336 131.090963) + (xy 118.282038 131.088) + (xy 118.279502 131.085213) + (xy 118.27385 131.076459) + (xy 118.242382 131.051651) + (xy 118.234873 131.045239) + (xy 118.205442 131.018033) + (xy 118.19592 131.013823) + (xy 118.192779 131.01176) + (xy 118.189477 131.009945) + (xy 118.181299 131.003498) + (xy 118.162494 130.996894) + (xy 118.143497 130.990223) + (xy 118.134297 130.98658) + (xy 118.107181 130.974592) + (xy 118.097654 130.97038) + (xy 118.087278 130.969481) + (xy 118.081966 130.968117) + (xy 118.080853 130.967779) + (xy 118.077582 130.967075) + (xy 118.070104 130.964449) + (xy 118.06492 130.964) + (xy 118.029434 130.964) + (xy 118.018562 130.96353) + (xy 117.980241 130.960211) + (xy 117.970133 130.962722) + (xy 117.95975 130.963539) + (xy 117.959689 130.962763) + (xy 117.949571 130.964) + (xy 117.623034 130.964) + (xy 117.612162 130.96353) + (xy 117.573841 130.960211) + (xy 117.563732 130.962722) + (xy 117.534948 130.969872) + (xy 117.525261 130.971878) + (xy 117.496025 130.976744) + (xy 117.496023 130.976745) + (xy 117.485748 130.978455) + (xy 117.47658 130.983402) + (xy 117.472997 130.984629) + (xy 117.469568 130.986113) + (xy 117.459466 130.988622) + (xy 117.448347 130.995802) + (xy 117.444657 130.996894) + (xy 117.44116 130.998407) + (xy 117.440977 130.997983) + (xy 117.380271 131.01595) + (xy 117.312108 130.996094) + (xy 117.265499 130.942539) + (xy 117.254 130.88995) + (xy 117.254 125.411804) + (xy 137.944161 125.411804) + (xy 137.945385 125.422143) + (xy 137.948127 125.445314) + (xy 137.948479 125.451279) + (xy 137.948572 125.451271) + (xy 137.949 125.456449) + (xy 137.949 125.461649) + (xy 137.949854 125.466778) + (xy 137.949854 125.466781) + (xy 137.952182 125.480768) + (xy 137.953019 125.486647) + (xy 137.959069 125.537765) + (xy 137.963049 125.546053) + (xy 137.964558 125.555119) + (xy 137.969503 125.564283) + (xy 137.969503 125.564284) + (xy 137.988996 125.60041) + (xy 137.991693 125.605703) + (xy 138.010542 125.644958) + (xy 138.010544 125.644962) + (xy 138.013975 125.652106) + (xy 138.017584 125.656399) + (xy 138.019507 125.658322) + (xy 138.021293 125.660269) + (xy 138.021329 125.660334) + (xy 138.021201 125.660451) + (xy 138.021692 125.661008) + (xy 138.024788 125.666746) + (xy 138.064436 125.703396) + (xy 138.064547 125.703499) + (xy 138.068113 125.706928) + (xy 138.208665 125.84748) + (xy 138.242691 125.909792) + (xy 138.244492 125.95302) + (xy 138.243465 125.960823) + (xy 138.241745 125.973889) + (xy 138.239218 125.99308) + (xy 138.246602 126.059957) + (xy 138.254475 126.131268) + (xy 138.256642 126.150898) + (xy 138.259251 126.158029) + (xy 138.259252 126.158031) + (xy 138.3082 126.291787) + (xy 138.311207 126.300005) + (xy 138.315443 126.306308) + (xy 138.315443 126.306309) + (xy 138.384219 126.408658) + (xy 138.399764 126.431792) + (xy 138.405383 126.436905) + (xy 138.405384 126.436906) + (xy 138.456675 126.483577) + (xy 138.517201 126.538651) + (xy 138.656737 126.614413) + (xy 138.810317 126.654704) + (xy 138.892689 126.655998) + (xy 138.961476 126.657079) + (xy 138.961479 126.657079) + (xy 138.969074 126.657198) + (xy 138.976478 126.655502) + (xy 138.97648 126.655502) + (xy 139.034202 126.642282) + (xy 139.123844 126.621751) + (xy 139.265691 126.550409) + (xy 139.302466 126.519) + (xy 139.380652 126.452224) + (xy 139.380654 126.452221) + (xy 139.386426 126.447292) + (xy 139.479079 126.318351) + (xy 139.484534 126.304782) + (xy 139.493226 126.28316) + (xy 139.537193 126.227416) + (xy 139.604318 126.204291) + (xy 139.67329 126.221128) + (xy 139.703328 126.245359) + (xy 139.708653 126.251212) + (xy 139.714304 126.259963) + (xy 139.722482 126.26641) + (xy 139.722483 126.266411) + (xy 139.740808 126.280857) + (xy 139.745271 126.284823) + (xy 139.745332 126.284751) + (xy 139.749289 126.288104) + (xy 139.752972 126.291787) + (xy 139.757207 126.294813) + (xy 139.757209 126.294815) + (xy 139.768732 126.303049) + (xy 139.773478 126.306612) + (xy 139.813914 126.338489) + (xy 139.822588 126.341535) + (xy 139.830066 126.346879) + (xy 139.840041 126.349862) + (xy 139.840043 126.349863) + (xy 139.879374 126.361625) + (xy 139.885022 126.36346) + (xy 139.924517 126.37733) + (xy 139.933589 126.380516) + (xy 139.939177 126.381) + (xy 139.941888 126.381) + (xy 139.94454 126.381115) + (xy 139.944617 126.381138) + (xy 139.94461 126.381308) + (xy 139.945341 126.381354) + (xy 139.951587 126.383222) + (xy 140.005681 126.381097) + (xy 140.010627 126.381) + (xy 141.289994 126.381) + (xy 141.358115 126.401002) + (xy 141.37909 126.417905) + (xy 142.09235 127.131166) + (xy 142.107649 127.15011) + (xy 142.108658 127.151218) + (xy 142.114304 127.159963) + (xy 142.122481 127.166409) + (xy 142.140803 127.180853) + (xy 142.145269 127.184822) + (xy 142.14533 127.184751) + (xy 142.149294 127.18811) + (xy 142.152971 127.191787) + (xy 142.168789 127.203091) + (xy 142.173459 127.206597) + (xy 142.213914 127.238489) + (xy 142.222588 127.241535) + (xy 142.230066 127.246879) + (xy 142.240041 127.249862) + (xy 142.240043 127.249863) + (xy 142.279374 127.261625) + (xy 142.285022 127.26346) + (xy 142.324517 127.27733) + (xy 142.333589 127.280516) + (xy 142.339177 127.281) + (xy 142.341888 127.281) + (xy 142.34454 127.281115) + (xy 142.344617 127.281138) + (xy 142.34461 127.281308) + (xy 142.345341 127.281354) + (xy 142.351587 127.283222) + (xy 142.40568 127.281097) + (xy 142.410626 127.281) + (xy 144.145916 127.281) + (xy 144.170127 127.283577) + (xy 144.171626 127.283648) + (xy 144.181804 127.285839) + (xy 144.213754 127.282058) + (xy 144.215314 127.281873) + (xy 144.221279 127.281521) + (xy 144.221271 127.281428) + (xy 144.226449 127.281) + (xy 144.231649 127.281) + (xy 144.236778 127.280146) + (xy 144.236781 127.280146) + (xy 144.250768 127.277818) + (xy 144.256647 127.276981) + (xy 144.297423 127.272155) + (xy 144.307765 127.270931) + (xy 144.316053 127.266951) + (xy 144.325119 127.265442) + (xy 144.370412 127.241003) + (xy 144.375703 127.238307) + (xy 144.414958 127.219458) + (xy 144.414962 127.219456) + (xy 144.422106 127.216025) + (xy 144.426399 127.212416) + (xy 144.428322 127.210493) + (xy 144.430269 127.208707) + (xy 144.430334 127.208671) + (xy 144.430451 127.208799) + (xy 144.431008 127.208308) + (xy 144.436746 127.205212) + (xy 144.473499 127.165453) + (xy 144.476928 127.161887) + (xy 145.12091 126.517905) + (xy 145.183222 126.483879) + (xy 145.210005 126.481) + (xy 147.345916 126.481) + (xy 147.370127 126.483577) + (xy 147.371626 126.483648) + (xy 147.381804 126.485839) + (xy 147.415314 126.481873) + (xy 147.421279 126.481521) + (xy 147.421271 126.481428) + (xy 147.426449 126.481) + (xy 147.431649 126.481) + (xy 147.436778 126.480146) + (xy 147.436781 126.480146) + (xy 147.450768 126.477818) + (xy 147.456647 126.476981) + (xy 147.497423 126.472155) + (xy 147.507765 126.470931) + (xy 147.516053 126.466951) + (xy 147.525119 126.465442) + (xy 147.570412 126.441003) + (xy 147.575703 126.438307) + (xy 147.614958 126.419458) + (xy 147.614962 126.419456) + (xy 147.622106 126.416025) + (xy 147.626399 126.412416) + (xy 147.628322 126.410493) + (xy 147.630269 126.408707) + (xy 147.630334 126.408671) + (xy 147.630451 126.408799) + (xy 147.631008 126.408308) + (xy 147.636746 126.405212) + (xy 147.673499 126.365453) + (xy 147.676928 126.361887) + (xy 147.831163 126.207652) + (xy 147.850112 126.192348) + (xy 147.851214 126.191345) + (xy 147.859963 126.185696) + (xy 147.880857 126.159192) + (xy 147.884823 126.154729) + (xy 147.884751 126.154668) + (xy 147.888104 126.150711) + (xy 147.891787 126.147028) + (xy 147.903051 126.131265) + (xy 147.906614 126.126519) + (xy 147.932041 126.094265) + (xy 147.938489 126.086086) + (xy 147.941535 126.077412) + (xy 147.946879 126.069934) + (xy 147.961625 126.020626) + (xy 147.96346 126.014978) + (xy 147.97789 125.973889) + (xy 147.97789 125.973888) + (xy 147.980516 125.966411) + (xy 147.981 125.960823) + (xy 147.981 125.959444) + (xy 147.982869 125.950763) + (xy 147.985331 125.951293) + (xy 148.003639 125.897645) + (xy 148.059255 125.853517) + (xy 148.107299 125.846287) + (xy 148.107244 125.845588) + (xy 148.117098 125.844812) + (xy 148.117464 125.844758) + (xy 148.128 125.84567) + (xy 148.165078 125.83646) + (xy 148.231589 125.819939) + (xy 148.23159 125.819939) + (xy 148.241697 125.817428) + (xy 148.278693 125.79354) + (xy 148.346768 125.773392) + (xy 148.403242 125.790216) + (xy 148.404137 125.788192) + (xy 148.511285 125.835562) + (xy 148.628 125.84567) + (xy 148.665078 125.83646) + (xy 148.731589 125.819939) + (xy 148.73159 125.819939) + (xy 148.741697 125.817428) + (xy 148.840116 125.75388) + (xy 148.855349 125.734558) + (xy 148.906194 125.67006) + (xy 148.906194 125.670059) + (xy 148.912644 125.661878) + (xy 148.927532 125.619484) + (xy 148.948835 125.558823) + (xy 148.948836 125.55882) + (xy 148.951461 125.551344) + (xy 148.951907 125.546194) + (xy 148.951907 125.273028) + (xy 148.971909 125.204907) + (xy 149.025565 125.158414) + (xy 149.095839 125.14831) + (xy 149.100681 125.149179) + (xy 149.107171 125.151458) + (xy 149.112321 125.151904) + (xy 149.810743 125.151904) + (xy 149.897071 125.137535) + (xy 149.921506 125.124351) + (xy 149.957926 125.104699) + (xy 150.000172 125.081905) + (xy 150.079695 124.995878) + (xy 150.127065 124.88873) + (xy 150.137173 124.772015) + (xy 150.119534 124.701002) + (xy 150.116112 124.687226) + (xy 150.119102 124.616292) + (xy 150.140058 124.578076) + (xy 150.141398 124.576404) + (xy 150.199904 124.475676) + (xy 150.204411 124.464294) + (xy 150.203791 124.453575) + (xy 150.194603 124.450006) + (xy 149.85828 124.450006) + (xy 149.843129 124.448394) + (xy 149.843126 124.44846) + (xy 149.842856 124.448448) + (xy 149.842847 124.448554) + (xy 149.840401 124.448342) + (xy 149.840397 124.448342) + (xy 149.837697 124.448108) + (xy 149.139275 124.448108) + (xy 149.134144 124.448962) + (xy 149.128966 124.44939) + (xy 149.128938 124.449057) + (xy 149.117458 124.450006) + (xy 148.762126 124.450006) + (xy 148.746888 124.45448) + (xy 148.736572 124.466386) + (xy 148.676846 124.504771) + (xy 148.630477 124.509405) + (xy 148.572018 124.504342) + (xy 148.561909 124.506853) + (xy 148.468429 124.530073) + (xy 148.468428 124.530073) + (xy 148.458321 124.532584) + (xy 148.421325 124.556472) + (xy 148.35325 124.57662) + (xy 148.296776 124.559796) + (xy 148.295881 124.56182) + (xy 148.188733 124.51445) + (xy 148.072018 124.504342) + (xy 148.061909 124.506853) + (xy 147.968429 124.530073) + (xy 147.968428 124.530073) + (xy 147.958321 124.532584) + (xy 147.921325 124.556472) + (xy 147.85325 124.57662) + (xy 147.796776 124.559796) + (xy 147.795881 124.56182) + (xy 147.688733 124.51445) + (xy 147.572018 124.504342) + (xy 147.533664 124.513869) + (xy 147.46273 124.510879) + (xy 147.404674 124.470014) + (xy 147.377927 124.404248) + (xy 147.377759 124.380713) + (xy 147.387173 124.272015) + (xy 147.365853 124.186185) + (xy 147.361442 124.168426) + (xy 147.361442 124.168425) + (xy 147.358931 124.158318) + (xy 147.344338 124.135718) + (xy 148.745607 124.135718) + (xy 148.746227 124.146437) + (xy 148.755415 124.150006) + (xy 149.091738 124.150006) + (xy 149.106889 124.151618) + (xy 149.106892 124.151552) + (xy 149.107162 124.151564) + (xy 149.107171 124.151458) + (xy 149.109617 124.15167) + (xy 149.109621 124.15167) + (xy 149.112321 124.151904) + (xy 149.810743 124.151904) + (xy 149.815874 124.15105) + (xy 149.821052 124.150622) + (xy 149.82108 124.150955) + (xy 149.83256 124.150006) + (xy 150.187892 124.150006) + (xy 150.201423 124.146033) + (xy 150.202248 124.140291) + (xy 150.180205 124.083311) + (xy 150.170979 124.067137) + (xy 150.139273 124.026918) + (xy 150.112808 123.961038) + (xy 150.121268 123.908602) + (xy 150.120264 123.908344) + (xy 150.122855 123.898253) + (xy 150.127065 123.88873) + (xy 150.137173 123.772015) + (xy 150.134662 123.761906) + (xy 150.116112 123.687226) + (xy 150.119102 123.616292) + (xy 150.140058 123.578076) + (xy 150.141398 123.576404) + (xy 150.199904 123.475676) + (xy 150.204411 123.464294) + (xy 150.203791 123.453575) + (xy 150.194603 123.450006) + (xy 149.85828 123.450006) + (xy 149.843129 123.448394) + (xy 149.843126 123.44846) + (xy 149.842856 123.448448) + (xy 149.842847 123.448554) + (xy 149.840401 123.448342) + (xy 149.840397 123.448342) + (xy 149.837697 123.448108) + (xy 149.139275 123.448108) + (xy 149.134144 123.448962) + (xy 149.128966 123.44939) + (xy 149.128938 123.449057) + (xy 149.117458 123.450006) + (xy 148.762126 123.450006) + (xy 148.748595 123.453979) + (xy 148.74777 123.459721) + (xy 148.769813 123.516701) + (xy 148.779039 123.532875) + (xy 148.810745 123.573094) + (xy 148.83721 123.638974) + (xy 148.82875 123.69141) + (xy 148.829754 123.691668) + (xy 148.827163 123.701759) + (xy 148.822953 123.711282) + (xy 148.812845 123.827997) + (xy 148.815356 123.838106) + (xy 148.833906 123.912786) + (xy 148.830916 123.98372) + (xy 148.80996 124.021936) + (xy 148.80862 124.023608) + (xy 148.750114 124.124336) + (xy 148.745607 124.135718) + (xy 147.344338 124.135718) + (xy 147.335043 124.121322) + (xy 147.314895 124.053247) + (xy 147.331719 123.996773) + (xy 147.329695 123.995878) + (xy 147.346 123.958996) + (xy 147.377065 123.88873) + (xy 147.387173 123.772015) + (xy 147.384662 123.761906) + (xy 147.361442 123.668426) + (xy 147.361442 123.668425) + (xy 147.358931 123.658318) + (xy 147.335043 123.621322) + (xy 147.314895 123.553247) + (xy 147.331719 123.496773) + (xy 147.329695 123.495878) + (xy 147.343658 123.464294) + (xy 147.377065 123.38873) + (xy 147.387173 123.272015) + (xy 147.379617 123.241596) + (xy 147.382607 123.170662) + (xy 147.423472 123.112606) + (xy 147.489238 123.085859) + (xy 147.512772 123.085691) + (xy 147.56487 123.090203) + (xy 147.628 123.09567) + (xy 147.665078 123.08646) + (xy 147.731589 123.069939) + (xy 147.73159 123.069939) + (xy 147.741697 123.067428) + (xy 147.778693 123.04354) + (xy 147.846768 123.023392) + (xy 147.903242 123.040216) + (xy 147.904137 123.038192) + (xy 148.011285 123.085562) + (xy 148.128 123.09567) + (xy 148.165078 123.08646) + (xy 148.231589 123.069939) + (xy 148.23159 123.069939) + (xy 148.241697 123.067428) + (xy 148.278693 123.04354) + (xy 148.346768 123.023392) + (xy 148.403242 123.040216) + (xy 148.404137 123.038192) + (xy 148.511285 123.085562) + (xy 148.628 123.09567) + (xy 148.634444 123.094069) + (xy 148.701771 123.108214) + (xy 148.744061 123.145097) + (xy 148.744566 123.145791) + (xy 148.755415 123.150006) + (xy 149.091738 123.150006) + (xy 149.106889 123.151618) + (xy 149.106892 123.151552) + (xy 149.107162 123.151564) + (xy 149.107171 123.151458) + (xy 149.109617 123.15167) + (xy 149.109621 123.15167) + (xy 149.112321 123.151904) + (xy 149.810743 123.151904) + (xy 149.815874 123.15105) + (xy 149.821052 123.150622) + (xy 149.82108 123.150955) + (xy 149.83256 123.150006) + (xy 150.187892 123.150006) + (xy 150.201423 123.146033) + (xy 150.202248 123.140291) + (xy 150.180205 123.083311) + (xy 150.170979 123.067137) + (xy 150.139273 123.026918) + (xy 150.112808 122.961038) + (xy 150.121268 122.908602) + (xy 150.120264 122.908344) + (xy 150.122855 122.898253) + (xy 150.127065 122.88873) + (xy 150.137173 122.772015) + (xy 150.122087 122.711282) + (xy 150.111442 122.668426) + (xy 150.111442 122.668425) + (xy 150.108931 122.658318) + (xy 150.045383 122.559899) + (xy 150.037204 122.553452) + (xy 150.037203 122.55345) + (xy 149.961563 122.493821) + (xy 149.961562 122.493821) + (xy 149.953381 122.487371) + (xy 149.882494 122.462477) + (xy 149.850326 122.45118) + (xy 149.850323 122.451179) + (xy 149.842847 122.448554) + (xy 149.837697 122.448108) + (xy 149.139275 122.448108) + (xy 149.134144 122.448962) + (xy 149.120819 122.45118) + (xy 149.098595 122.454879) + (xy 149.028114 122.446333) + (xy 148.973443 122.401039) + (xy 148.951907 122.330589) + (xy 148.951907 122.080772) + (xy 148.937538 121.994444) + (xy 148.881908 121.891343) + (xy 148.795881 121.81182) + (xy 148.688733 121.76445) + (xy 148.572018 121.754342) + (xy 148.561909 121.756853) + (xy 148.468429 121.780073) + (xy 148.468428 121.780073) + (xy 148.458321 121.782584) + (xy 148.421325 121.806472) + (xy 148.35325 121.82662) + (xy 148.296776 121.809796) + (xy 148.295881 121.81182) + (xy 148.188733 121.76445) + (xy 148.072018 121.754342) + (xy 148.061909 121.756853) + (xy 147.968429 121.780073) + (xy 147.968428 121.780073) + (xy 147.958321 121.782584) + (xy 147.921325 121.806472) + (xy 147.85325 121.82662) + (xy 147.796776 121.809796) + (xy 147.795881 121.81182) + (xy 147.688733 121.76445) + (xy 147.572018 121.754342) + (xy 147.561909 121.756853) + (xy 147.468429 121.780073) + (xy 147.468428 121.780073) + (xy 147.458321 121.782584) + (xy 147.359902 121.846132) + (xy 147.353455 121.854311) + (xy 147.353453 121.854312) + (xy 147.293824 121.929952) + (xy 147.287374 121.938134) + (xy 147.248557 122.048668) + (xy 147.248111 122.053818) + (xy 147.248111 122.326984) + (xy 147.228109 122.395105) + (xy 147.174453 122.441598) + (xy 147.104179 122.451702) + (xy 147.099337 122.450833) + (xy 147.092847 122.448554) + (xy 147.087697 122.448108) + (xy 146.389275 122.448108) + (xy 146.302947 122.462477) + (xy 146.199846 122.518107) + (xy 146.120323 122.604134) + (xy 146.072953 122.711282) + (xy 146.062845 122.827997) + (xy 146.065356 122.838106) + (xy 146.075354 122.878354) + (xy 146.091087 122.941694) + (xy 146.114975 122.97869) + (xy 146.135123 123.046765) + (xy 146.118299 123.103239) + (xy 146.120323 123.104134) + (xy 146.072953 123.211282) + (xy 146.062845 123.327997) + (xy 146.065356 123.338106) + (xy 146.080297 123.398254) + (xy 146.091087 123.441694) + (xy 146.114975 123.47869) + (xy 146.135123 123.546765) + (xy 146.118299 123.603239) + (xy 146.120323 123.604134) + (xy 146.072953 123.711282) + (xy 146.068569 123.761906) + (xy 146.064934 123.803872) + (xy 146.039129 123.870013) + (xy 145.981662 123.911703) + (xy 145.939404 123.919) + (xy 145.554084 123.919) + (xy 145.529873 123.916423) + (xy 145.528374 123.916352) + (xy 145.518196 123.914161) + (xy 145.486246 123.917942) + (xy 145.484686 123.918127) + (xy 145.478721 123.918479) + (xy 145.478729 123.918572) + (xy 145.473551 123.919) + (xy 145.468351 123.919) + (xy 145.463222 123.919854) + (xy 145.463219 123.919854) + (xy 145.449232 123.922182) + (xy 145.443353 123.923019) + (xy 145.402577 123.927845) + (xy 145.392235 123.929069) + (xy 145.383947 123.933049) + (xy 145.374881 123.934558) + (xy 145.365717 123.939503) + (xy 145.365716 123.939503) + (xy 145.32959 123.958996) + (xy 145.324297 123.961693) + (xy 145.285042 123.980542) + (xy 145.285038 123.980544) + (xy 145.277894 123.983975) + (xy 145.273601 123.987584) + (xy 145.271678 123.989507) + (xy 145.269731 123.991293) + (xy 145.269666 123.991329) + (xy 145.269549 123.991201) + (xy 145.268992 123.991692) + (xy 145.263254 123.994788) + (xy 145.238159 124.021936) + (xy 145.226501 124.034547) + (xy 145.223072 124.038113) + (xy 143.67909 125.582095) + (xy 143.616778 125.616121) + (xy 143.589995 125.619) + (xy 143.400471 125.619) + (xy 143.33235 125.598998) + (xy 143.306342 125.573778) + (xy 143.305012 125.57495) + (xy 143.299988 125.569251) + (xy 143.295687 125.562993) + (xy 143.28685 125.555119) + (xy 143.209998 125.486647) + (xy 143.177138 125.45737) + (xy 143.169735 125.45345) + (xy 143.069025 125.400127) + (xy 143.036816 125.383073) + (xy 143.027078 125.380627) + (xy 142.890193 125.346244) + (xy 142.890189 125.346244) + (xy 142.882822 125.344393) + (xy 142.875222 125.344353) + (xy 142.875221 125.344353) + (xy 142.810427 125.344014) + (xy 142.724047 125.343561) + (xy 142.716667 125.345333) + (xy 142.716665 125.345333) + (xy 142.577037 125.378855) + (xy 142.577035 125.378856) + (xy 142.569657 125.380627) + (xy 142.428565 125.45345) + (xy 142.422843 125.458442) + (xy 142.422841 125.458443) + (xy 142.314642 125.552831) + (xy 142.314639 125.552834) + (xy 142.308917 125.557826) + (xy 142.277149 125.603027) + (xy 142.227399 125.673815) + (xy 142.217619 125.68773) + (xy 142.197437 125.739494) + (xy 142.165202 125.822173) + (xy 142.159943 125.835661) + (xy 142.158951 125.843195) + (xy 142.157308 125.849595) + (xy 142.120993 125.910602) + (xy 142.057461 125.942291) + (xy 141.986882 125.934601) + (xy 141.946171 125.907356) + (xy 141.807652 125.768837) + (xy 141.792348 125.749888) + (xy 141.791345 125.748786) + (xy 141.785696 125.740037) + (xy 141.759192 125.719143) + (xy 141.754729 125.715177) + (xy 141.754668 125.715249) + (xy 141.750711 125.711896) + (xy 141.747028 125.708213) + (xy 141.742776 125.705174) + (xy 141.731268 125.696951) + (xy 141.726519 125.693386) + (xy 141.686086 125.661511) + (xy 141.677412 125.658465) + (xy 141.669934 125.653121) + (xy 141.659959 125.650138) + (xy 141.659957 125.650137) + (xy 141.620626 125.638375) + (xy 141.614978 125.63654) + (xy 141.573889 125.62211) + (xy 141.573888 125.62211) + (xy 141.566411 125.619484) + (xy 141.560823 125.619) + (xy 141.558112 125.619) + (xy 141.55546 125.618885) + (xy 141.555383 125.618862) + (xy 141.55539 125.618692) + (xy 141.554659 125.618646) + (xy 141.548413 125.616778) + (xy 141.495526 125.618856) + (xy 141.49432 125.618903) + (xy 141.489374 125.619) + (xy 140.210005 125.619) + (xy 140.141884 125.598998) + (xy 140.12091 125.582095) + (xy 139.547905 125.00909) + (xy 139.513879 124.946778) + (xy 139.511 124.919995) + (xy 139.511 124.398351) + (xy 139.495442 124.304881) + (xy 139.435212 124.193254) + (xy 139.408354 124.168426) + (xy 139.377917 124.140291) + (xy 139.34207 124.107154) + (xy 139.284958 124.081905) + (xy 139.235585 124.060077) + (xy 139.235582 124.060076) + (xy 139.226061 124.055867) + (xy 139.215689 124.054969) + (xy 139.215686 124.054968) + (xy 139.141666 124.048558) + (xy 139.099694 124.044923) + (xy 138.976594 124.075501) + (xy 138.967845 124.08115) + (xy 138.967843 124.081151) + (xy 138.964498 124.083311) + (xy 138.870037 124.144304) + (xy 138.863591 124.152481) + (xy 138.831198 124.193571) + (xy 138.773317 124.234684) + (xy 138.702397 124.237978) + (xy 138.640954 124.202406) + (xy 138.638795 124.199894) + (xy 138.635212 124.193254) + (xy 138.54207 124.107154) + (xy 138.484958 124.081905) + (xy 138.435585 124.060077) + (xy 138.435582 124.060076) + (xy 138.426061 124.055867) + (xy 138.415689 124.054969) + (xy 138.415686 124.054968) + (xy 138.341666 124.048558) + (xy 138.299694 124.044923) + (xy 138.176594 124.075501) + (xy 138.167845 124.08115) + (xy 138.167843 124.081151) + (xy 138.164498 124.083311) + (xy 138.070037 124.144304) + (xy 137.991511 124.243914) + (xy 137.988061 124.253738) + (xy 137.98806 124.25374) + (xy 137.952111 124.356108) + (xy 137.949484 124.363589) + (xy 137.949 124.369177) + (xy 137.949 125.375916) + (xy 137.946423 125.400127) + (xy 137.946352 125.401626) + (xy 137.944161 125.411804) + (xy 117.254 125.411804) + (xy 117.254 118.80652) + (xy 117.274002 118.738399) + (xy 117.327658 118.691906) + (xy 117.397932 118.681802) + (xy 117.462512 118.711296) + (xy 117.469018 118.717347) + (xy 117.507342 118.755604) + (xy 117.526212 118.768525) + (xy 117.609125 118.80518) + (xy 117.627202 118.810108) + (xy 117.639787 118.811576) + (xy 117.647088 118.812) + (xy 118.281885 118.812) + (xy 118.297124 118.807525) + (xy 118.298329 118.806135) + (xy 118.3 118.798452) + (xy 118.3 117.913548) + (xy 118.6 117.913548) + (xy 118.6 118.793885) + (xy 118.604475 118.809124) + (xy 118.605865 118.810329) + (xy 118.613548 118.812) + (xy 119.25284 118.812) + (xy 119.260286 118.811558) + (xy 119.273336 118.810006) + (xy 119.291374 118.805048) + (xy 119.374231 118.768245) + (xy 119.393085 118.755287) + (xy 119.455604 118.692658) + (xy 119.468525 118.673788) + (xy 119.50518 118.590875) + (xy 119.510108 118.572798) + (xy 119.511576 118.560213) + (xy 119.512 118.552912) + (xy 119.512 117.918115) + (xy 119.507525 117.902876) + (xy 119.506135 117.901671) + (xy 119.498452 117.9) + (xy 118.618115 117.9) + (xy 118.602876 117.904475) + (xy 118.601671 117.905865) + (xy 118.6 117.913548) + (xy 118.3 117.913548) + (xy 118.3 116.706115) + (xy 118.298659 116.701548) + (xy 118.6 116.701548) + (xy 118.6 117.581885) + (xy 118.604475 117.597124) + (xy 118.605865 117.598329) + (xy 118.613548 117.6) + (xy 119.493885 117.6) + (xy 119.509124 117.595525) + (xy 119.510329 117.594135) + (xy 119.512 117.586452) + (xy 119.512 116.94716) + (xy 119.511558 116.939714) + (xy 119.510006 116.926664) + (xy 119.505048 116.908626) + (xy 119.468245 116.825769) + (xy 119.455287 116.806915) + (xy 119.392658 116.744396) + (xy 119.373788 116.731475) + (xy 119.290875 116.69482) + (xy 119.272798 116.689892) + (xy 119.260213 116.688424) + (xy 119.252912 116.688) + (xy 118.618115 116.688) + (xy 118.602876 116.692475) + (xy 118.601671 116.693865) + (xy 118.6 116.701548) + (xy 118.298659 116.701548) + (xy 118.295525 116.690876) + (xy 118.294135 116.689671) + (xy 118.286452 116.688) + (xy 117.64716 116.688) + (xy 117.639714 116.688442) + (xy 117.626664 116.689994) + (xy 117.608626 116.694952) + (xy 117.525769 116.731755) + (xy 117.506915 116.744713) + (xy 117.469173 116.782521) + (xy 117.40689 116.8166) + (xy 117.33607 116.811597) + (xy 117.279197 116.7691) + (xy 117.254329 116.702601) + (xy 117.254 116.693503) + (xy 117.254 112.473888) + (xy 120.23154 112.473888) + (xy 120.23154 112.924312) + (xy 120.232747 112.930379) + (xy 120.246394 112.998986) + (xy 120.242028 112.999854) + (xy 120.24702 113.046544) + (xy 120.246245 113.049184) + (xy 120.246394 113.049214) + (xy 120.23154 113.123888) + (xy 120.23154 113.574312) + (xy 120.232747 113.580379) + (xy 120.246394 113.648986) + (xy 120.242028 113.649854) + (xy 120.24702 113.696544) + (xy 120.246245 113.699184) + (xy 120.246394 113.699214) + (xy 120.23154 113.773888) + (xy 120.23154 114.224312) + (xy 120.237664 114.2551) + (xy 120.246394 114.298986) + (xy 120.242028 114.299854) + (xy 120.24702 114.346544) + (xy 120.246245 114.349184) + (xy 120.246394 114.349214) + (xy 120.23154 114.423888) + (xy 120.23154 114.874312) + (xy 120.246394 114.948986) + (xy 120.253286 114.9593) + (xy 120.253287 114.959303) + (xy 120.296082 115.023349) + (xy 120.302975 115.033665) + (xy 120.313291 115.040558) + (xy 120.377337 115.083353) + (xy 120.37734 115.083354) + (xy 120.387654 115.090246) + (xy 120.399821 115.092666) + (xy 120.399823 115.092667) + (xy 120.438787 115.100417) + (xy 120.462328 115.1051) + (xy 121.862752 115.1051) + (xy 121.886293 115.100417) + (xy 121.925257 115.092667) + (xy 121.925259 115.092666) + (xy 121.937426 115.090246) + (xy 121.94774 115.083354) + (xy 121.947743 115.083353) + (xy 122.011789 115.040558) + (xy 122.022105 115.033665) + (xy 122.028998 115.023349) + (xy 122.071793 114.959303) + (xy 122.071794 114.9593) + (xy 122.078686 114.948986) + (xy 122.09354 114.874312) + (xy 122.09354 114.479867) + (xy 122.113542 114.411746) + (xy 122.167198 114.365253) + (xy 122.204677 114.355464) + (xy 122.204616 114.3551) + (xy 122.204618 114.3551) + (xy 122.222318 114.352154) + (xy 122.228118 114.351328) + (xy 122.275735 114.345692) + (xy 122.283477 114.341974) + (xy 122.29195 114.340564) + (xy 122.334091 114.317826) + (xy 122.339381 114.315131) + (xy 122.375426 114.297822) + (xy 122.37543 114.29782) + (xy 122.382574 114.294389) + (xy 122.386576 114.291025) + (xy 122.388497 114.289104) + (xy 122.389438 114.288241) + (xy 122.392892 114.286544) + (xy 122.395299 114.28499) + (xy 122.395481 114.285272) + (xy 122.453161 114.256938) + (xy 122.474603 114.2551) + (xy 124.010477 114.2551) + (xy 124.097809 114.240564) + (xy 124.106976 114.235618) + (xy 124.192946 114.189231) + (xy 124.192947 114.18923) + (xy 124.202112 114.184285) + (xy 124.282562 114.097255) + (xy 124.330484 113.988858) + (xy 124.34071 113.870782) + (xy 124.338199 113.860673) + (xy 124.337382 113.850292) + (xy 124.339974 113.850088) + (xy 124.342327 113.794314) + (xy 124.383011 113.737253) + (xy 124.388512 113.734285) + (xy 124.420932 113.699214) + (xy 124.428737 113.69077) + (xy 124.468962 113.647255) + (xy 124.516884 113.538858) + (xy 124.52711 113.420782) + (xy 124.498539 113.30576) + (xy 124.43425 113.206194) + (xy 124.341176 113.132821) + (xy 124.297441 113.117462) + (xy 124.236834 113.096178) + (xy 124.236833 113.096178) + (xy 124.229353 113.093551) + (xy 124.229304 113.093547) + (xy 124.17 113.061327) + (xy 124.135843 112.999087) + (xy 124.140757 112.928261) + (xy 124.146639 112.91484) + (xy 124.187341 112.834958) + (xy 124.191842 112.826125) + (xy 124.211961 112.6991) + (xy 124.191842 112.572075) + (xy 124.133455 112.457484) + (xy 124.042516 112.366545) + (xy 123.927925 112.308158) + (xy 123.832854 112.2931) + (xy 122.028247 112.2931) + (xy 121.958246 112.271866) + (xy 121.937426 112.257954) + (xy 121.925259 112.255534) + (xy 121.925257 112.255533) + (xy 121.886293 112.247783) + (xy 121.862752 112.2431) + (xy 120.462328 112.2431) + (xy 120.438787 112.247783) + (xy 120.399823 112.255533) + (xy 120.399821 112.255534) + (xy 120.387654 112.257954) + (xy 120.37734 112.264846) + (xy 120.377337 112.264847) + (xy 120.31484 112.306607) + (xy 120.302975 112.314535) + (xy 120.296082 112.324851) + (xy 120.253287 112.388897) + (xy 120.253286 112.3889) + (xy 120.246394 112.399214) + (xy 120.23154 112.473888) + (xy 117.254 112.473888) + (xy 117.254 111.30652) + (xy 117.274002 111.238399) + (xy 117.327658 111.191906) + (xy 117.397932 111.181802) + (xy 117.462512 111.211296) + (xy 117.469018 111.217347) + (xy 117.507342 111.255604) + (xy 117.526212 111.268525) + (xy 117.609125 111.30518) + (xy 117.627202 111.310108) + (xy 117.639787 111.311576) + (xy 117.647088 111.312) + (xy 118.281885 111.312) + (xy 118.297124 111.307525) + (xy 118.298329 111.306135) + (xy 118.3 111.298452) + (xy 118.3 110.413548) + (xy 118.6 110.413548) + (xy 118.6 111.293885) + (xy 118.604475 111.309124) + (xy 118.605865 111.310329) + (xy 118.613548 111.312) + (xy 119.25284 111.312) + (xy 119.260286 111.311558) + (xy 119.273336 111.310006) + (xy 119.291374 111.305048) + (xy 119.374231 111.268245) + (xy 119.393085 111.255287) + (xy 119.455604 111.192658) + (xy 119.468525 111.173788) + (xy 119.50518 111.090875) + (xy 119.510108 111.072798) + (xy 119.511576 111.060213) + (xy 119.512 111.052912) + (xy 119.512 110.418115) + (xy 119.507525 110.402876) + (xy 119.506135 110.401671) + (xy 119.498452 110.4) + (xy 118.618115 110.4) + (xy 118.602876 110.404475) + (xy 118.601671 110.405865) + (xy 118.6 110.413548) + (xy 118.3 110.413548) + (xy 118.3 109.206115) + (xy 118.298659 109.201548) + (xy 118.6 109.201548) + (xy 118.6 110.081885) + (xy 118.604475 110.097124) + (xy 118.605865 110.098329) + (xy 118.613548 110.1) + (xy 119.493885 110.1) + (xy 119.509124 110.095525) + (xy 119.510329 110.094135) + (xy 119.512 110.086452) + (xy 119.512 109.44716) + (xy 119.511558 109.439714) + (xy 119.510006 109.426664) + (xy 119.505048 109.408626) + (xy 119.468245 109.325769) + (xy 119.455287 109.306915) + (xy 119.392658 109.244396) + (xy 119.373788 109.231475) + (xy 119.290875 109.19482) + (xy 119.272798 109.189892) + (xy 119.260213 109.188424) + (xy 119.252912 109.188) + (xy 118.618115 109.188) + (xy 118.602876 109.192475) + (xy 118.601671 109.193865) + (xy 118.6 109.201548) + (xy 118.298659 109.201548) + (xy 118.295525 109.190876) + (xy 118.294135 109.189671) + (xy 118.286452 109.188) + (xy 117.64716 109.188) + (xy 117.639714 109.188442) + (xy 117.626664 109.189994) + (xy 117.608626 109.194952) + (xy 117.525769 109.231755) + (xy 117.506915 109.244713) + (xy 117.469173 109.282521) + (xy 117.40689 109.3166) + (xy 117.33607 109.311597) + (xy 117.279197 109.2691) + (xy 117.254329 109.202601) + (xy 117.254 109.193503) + (xy 117.254 98.38) + (xy 117.274002 98.311879) + (xy 117.327658 98.265386) + (xy 117.38 98.254) + (xy 156.62 98.254) + ) + ) + (filled_polygon + (layer "F.Cu") + (pts + (xy 146.81713 124.701002) + (xy 146.863623 124.754658) + (xy 146.875009 124.807) + (xy 146.875009 125.231891) + (xy 146.879484 125.24713) + (xy 146.880874 125.248335) + (xy 146.888557 125.250006) + (xy 147.060611 125.250006) + (xy 147.069972 125.249306) + (xy 147.074273 125.24866) + (xy 147.14461 125.258316) + (xy 147.198561 125.304465) + (xy 147.219 125.373261) + (xy 147.219 125.593) + (xy 147.198998 125.661121) + (xy 147.145342 125.707614) + (xy 147.093 125.719) + (xy 145.054084 125.719) + (xy 145.029873 125.716423) + (xy 145.028374 125.716352) + (xy 145.018196 125.714161) + (xy 144.986246 125.717942) + (xy 144.984686 125.718127) + (xy 144.978721 125.718479) + (xy 144.978729 125.718572) + (xy 144.973551 125.719) + (xy 144.968351 125.719) + (xy 144.963222 125.719854) + (xy 144.963219 125.719854) + (xy 144.949232 125.722182) + (xy 144.943353 125.723019) + (xy 144.932656 125.724285) + (xy 144.862656 125.712428) + (xy 144.81018 125.664608) + (xy 144.791886 125.596009) + (xy 144.813585 125.528409) + (xy 144.828745 125.510071) + (xy 145.379095 124.959721) + (xy 145.99777 124.959721) + (xy 146.019813 125.016701) + (xy 146.029039 125.032875) + (xy 146.101153 125.124351) + (xy 146.11473 125.137101) + (xy 146.210554 125.203329) + (xy 146.227279 125.211523) + (xy 146.340469 125.24732) + (xy 146.353714 125.249901) + (xy 146.356394 125.250006) + (xy 146.556894 125.250006) + (xy 146.572133 125.245531) + (xy 146.573338 125.244141) + (xy 146.575009 125.236458) + (xy 146.575009 124.968121) + (xy 146.570534 124.952882) + (xy 146.569144 124.951677) + (xy 146.561461 124.950006) + (xy 146.012126 124.950006) + (xy 145.998595 124.953979) + (xy 145.99777 124.959721) + (xy 145.379095 124.959721) + (xy 145.620913 124.717903) + (xy 145.683223 124.683879) + (xy 145.710006 124.681) + (xy 146.749009 124.681) + ) + ) + ) + (zone (net 1) (net_name "GND") (layer "B.Cu") (tstamp 00000000-0000-0000-0000-00005bcab468) (hatch edge 0.508) + (connect_pads (clearance 0.254)) + (min_thickness 0.254) (filled_areas_thickness no) + (fill yes (thermal_gap 0.254) (thermal_bridge_width 0.3)) + (polygon + (pts + (xy 117 98) + (xy 157 98) + (xy 157 136) + (xy 117 136) + ) + ) + (filled_polygon + (layer "B.Cu") + (pts + (xy 156.688121 98.274002) + (xy 156.734614 98.327658) + (xy 156.746 98.38) + (xy 156.746 102.8076) + (xy 156.725998 102.875721) + (xy 156.672342 102.922214) + (xy 156.62 102.9336) + (xy 152.874788 102.9336) + (xy 152.851247 102.938283) + (xy 152.812283 102.946033) + (xy 152.812281 102.946034) + (xy 152.800114 102.948454) + (xy 152.7898 102.955346) + (xy 152.789797 102.955347) + (xy 152.725751 102.998142) + (xy 152.715435 103.005035) + (xy 152.708542 103.015351) + (xy 152.665747 103.079397) + (xy 152.665746 103.0794) + (xy 152.658854 103.089714) + (xy 152.644 103.164388) + (xy 152.644 103.774812) + (xy 152.658854 103.849486) + (xy 152.665746 103.8598) + (xy 152.665747 103.859803) + (xy 152.708542 103.923849) + (xy 152.715435 103.934165) + (xy 152.800114 103.990746) + (xy 152.804534 103.991625) + (xy 152.855554 104.032741) + (xy 152.877974 104.100104) + (xy 152.860415 104.168895) + (xy 152.809104 104.216666) + (xy 152.800114 104.218454) + (xy 152.715435 104.275035) + (xy 152.708542 104.285351) + (xy 152.665747 104.349397) + (xy 152.665746 104.3494) + (xy 152.658854 104.359714) + (xy 152.644 104.434388) + (xy 152.644 105.044812) + (xy 152.658854 105.119486) + (xy 152.665746 105.1298) + (xy 152.665747 105.129803) + (xy 152.708542 105.193849) + (xy 152.715435 105.204165) + (xy 152.800114 105.260746) + (xy 152.804534 105.261625) + (xy 152.855554 105.302741) + (xy 152.877974 105.370104) + (xy 152.860415 105.438895) + (xy 152.809104 105.486666) + (xy 152.800114 105.488454) + (xy 152.715435 105.545035) + (xy 152.708542 105.555351) + (xy 152.665747 105.619397) + (xy 152.665746 105.6194) + (xy 152.658854 105.629714) + (xy 152.644 105.704388) + (xy 152.644 106.314812) + (xy 152.658854 106.389486) + (xy 152.665746 106.3998) + (xy 152.665747 106.399803) + (xy 152.708542 106.463849) + (xy 152.715435 106.474165) + (xy 152.725751 106.481058) + (xy 152.789797 106.523853) + (xy 152.7898 106.523854) + (xy 152.800114 106.530746) + (xy 152.812281 106.533166) + (xy 152.812283 106.533167) + (xy 152.851247 106.540917) + (xy 152.874788 106.5456) + (xy 156.62 106.5456) + (xy 156.688121 106.565602) + (xy 156.734614 106.619258) + (xy 156.746 106.6716) + (xy 156.746 107.8876) + (xy 156.725998 107.955721) + (xy 156.672342 108.002214) + (xy 156.62 108.0136) + (xy 152.874788 108.0136) + (xy 152.851247 108.018283) + (xy 152.812283 108.026033) + (xy 152.812281 108.026034) + (xy 152.800114 108.028454) + (xy 152.7898 108.035346) + (xy 152.789797 108.035347) + (xy 152.725751 108.078142) + (xy 152.715435 108.085035) + (xy 152.708542 108.095351) + (xy 152.665747 108.159397) + (xy 152.665746 108.1594) + (xy 152.658854 108.169714) + (xy 152.644 108.244388) + (xy 152.644 108.854812) + (xy 152.658854 108.929486) + (xy 152.665746 108.9398) + (xy 152.665747 108.939803) + (xy 152.708542 109.003849) + (xy 152.715435 109.014165) + (xy 152.725751 109.021058) + (xy 152.789797 109.063853) + (xy 152.7898 109.063854) + (xy 152.800114 109.070746) + (xy 152.812281 109.073166) + (xy 152.812283 109.073167) + (xy 152.851247 109.080917) + (xy 152.874788 109.0856) + (xy 156.62 109.0856) + (xy 156.688121 109.105602) + (xy 156.734614 109.159258) + (xy 156.746 109.2116) + (xy 156.746 135.62) + (xy 156.725998 135.688121) + (xy 156.672342 135.734614) + (xy 156.62 135.746) + (xy 156.1454 135.746) + (xy 156.077279 135.725998) + (xy 156.030786 135.672342) + (xy 156.0194 135.62) + (xy 156.0194 131.945188) + (xy 156.004546 131.870514) + (xy 155.997654 131.8602) + (xy 155.997653 131.860197) + (xy 155.954858 131.796151) + (xy 155.947965 131.785835) + (xy 155.937649 131.778942) + (xy 155.873603 131.736147) + (xy 155.8736 131.736146) + (xy 155.863286 131.729254) + (xy 155.851119 131.726834) + (xy 155.851117 131.726833) + (xy 155.812153 131.719083) + (xy 155.788612 131.7144) + (xy 155.178188 131.7144) + (xy 155.154647 131.719083) + (xy 155.115683 131.726833) + (xy 155.115681 131.726834) + (xy 155.103514 131.729254) + (xy 155.0932 131.736146) + (xy 155.093197 131.736147) + (xy 155.029151 131.778942) + (xy 155.018835 131.785835) + (xy 154.962254 131.870514) + (xy 154.961375 131.874934) + (xy 154.920259 131.925954) + (xy 154.852896 131.948374) + (xy 154.784105 131.930815) + (xy 154.736334 131.879504) + (xy 154.734546 131.870514) + (xy 154.677965 131.785835) + (xy 154.667649 131.778942) + (xy 154.603603 131.736147) + (xy 154.6036 131.736146) + (xy 154.593286 131.729254) + (xy 154.581119 131.726834) + (xy 154.581117 131.726833) + (xy 154.542153 131.719083) + (xy 154.518612 131.7144) + (xy 153.908188 131.7144) + (xy 153.884647 131.719083) + (xy 153.845683 131.726833) + (xy 153.845681 131.726834) + (xy 153.833514 131.729254) + (xy 153.8232 131.736146) + (xy 153.823197 131.736147) + (xy 153.759151 131.778942) + (xy 153.748835 131.785835) + (xy 153.692254 131.870514) + (xy 153.691375 131.874934) + (xy 153.650259 131.925954) + (xy 153.582896 131.948374) + (xy 153.514105 131.930815) + (xy 153.466334 131.879504) + (xy 153.464546 131.870514) + (xy 153.407965 131.785835) + (xy 153.397649 131.778942) + (xy 153.333603 131.736147) + (xy 153.3336 131.736146) + (xy 153.323286 131.729254) + (xy 153.311119 131.726834) + (xy 153.311117 131.726833) + (xy 153.272153 131.719083) + (xy 153.248612 131.7144) + (xy 152.638188 131.7144) + (xy 152.614647 131.719083) + (xy 152.575683 131.726833) + (xy 152.575681 131.726834) + (xy 152.563514 131.729254) + (xy 152.5532 131.736146) + (xy 152.553197 131.736147) + (xy 152.489151 131.778942) + (xy 152.478835 131.785835) + (xy 152.422254 131.870514) + (xy 152.421375 131.874934) + (xy 152.380259 131.925954) + (xy 152.312896 131.948374) + (xy 152.244105 131.930815) + (xy 152.196334 131.879504) + (xy 152.194546 131.870514) + (xy 152.137965 131.785835) + (xy 152.127649 131.778942) + (xy 152.063603 131.736147) + (xy 152.0636 131.736146) + (xy 152.053286 131.729254) + (xy 152.041119 131.726834) + (xy 152.041117 131.726833) + (xy 152.002153 131.719083) + (xy 151.978612 131.7144) + (xy 151.368188 131.7144) + (xy 151.344647 131.719083) + (xy 151.305683 131.726833) + (xy 151.305681 131.726834) + (xy 151.293514 131.729254) + (xy 151.2832 131.736146) + (xy 151.283197 131.736147) + (xy 151.219151 131.778942) + (xy 151.208835 131.785835) + (xy 151.152254 131.870514) + (xy 151.151375 131.874934) + (xy 151.110259 131.925954) + (xy 151.042896 131.948374) + (xy 150.974105 131.930815) + (xy 150.926334 131.879504) + (xy 150.924546 131.870514) + (xy 150.867965 131.785835) + (xy 150.857649 131.778942) + (xy 150.793603 131.736147) + (xy 150.7936 131.736146) + (xy 150.783286 131.729254) + (xy 150.771119 131.726834) + (xy 150.771117 131.726833) + (xy 150.732153 131.719083) + (xy 150.708612 131.7144) + (xy 150.098188 131.7144) + (xy 150.074647 131.719083) + (xy 150.035683 131.726833) + (xy 150.035681 131.726834) + (xy 150.023514 131.729254) + (xy 150.0132 131.736146) + (xy 150.013197 131.736147) + (xy 149.949151 131.778942) + (xy 149.938835 131.785835) + (xy 149.882254 131.870514) + (xy 149.881375 131.874934) + (xy 149.840259 131.925954) + (xy 149.772896 131.948374) + (xy 149.704105 131.930815) + (xy 149.656334 131.879504) + (xy 149.654546 131.870514) + (xy 149.597965 131.785835) + (xy 149.587649 131.778942) + (xy 149.523603 131.736147) + (xy 149.5236 131.736146) + (xy 149.513286 131.729254) + (xy 149.501119 131.726834) + (xy 149.501117 131.726833) + (xy 149.462153 131.719083) + (xy 149.438612 131.7144) + (xy 148.828188 131.7144) + (xy 148.804647 131.719083) + (xy 148.765683 131.726833) + (xy 148.765681 131.726834) + (xy 148.753514 131.729254) + (xy 148.7432 131.736146) + (xy 148.743197 131.736147) + (xy 148.679151 131.778942) + (xy 148.668835 131.785835) + (xy 148.612254 131.870514) + (xy 148.611375 131.874934) + (xy 148.570259 131.925954) + (xy 148.502896 131.948374) + (xy 148.434105 131.930815) + (xy 148.386334 131.879504) + (xy 148.384546 131.870514) + (xy 148.327965 131.785835) + (xy 148.317649 131.778942) + (xy 148.253603 131.736147) + (xy 148.2536 131.736146) + (xy 148.243286 131.729254) + (xy 148.231119 131.726834) + (xy 148.231117 131.726833) + (xy 148.192153 131.719083) + (xy 148.168612 131.7144) + (xy 147.558188 131.7144) + (xy 147.534647 131.719083) + (xy 147.495683 131.726833) + (xy 147.495681 131.726834) + (xy 147.483514 131.729254) + (xy 147.4732 131.736146) + (xy 147.473197 131.736147) + (xy 147.409151 131.778942) + (xy 147.398835 131.785835) + (xy 147.342254 131.870514) + (xy 147.341375 131.874934) + (xy 147.300259 131.925954) + (xy 147.232896 131.948374) + (xy 147.164105 131.930815) + (xy 147.116334 131.879504) + (xy 147.114546 131.870514) + (xy 147.057965 131.785835) + (xy 147.047649 131.778942) + (xy 146.983603 131.736147) + (xy 146.9836 131.736146) + (xy 146.973286 131.729254) + (xy 146.961119 131.726834) + (xy 146.961117 131.726833) + (xy 146.922153 131.719083) + (xy 146.898612 131.7144) + (xy 146.288188 131.7144) + (xy 146.264647 131.719083) + (xy 146.225683 131.726833) + (xy 146.225681 131.726834) + (xy 146.213514 131.729254) + (xy 146.2032 131.736146) + (xy 146.203197 131.736147) + (xy 146.139151 131.778942) + (xy 146.128835 131.785835) + (xy 146.072254 131.870514) + (xy 146.071375 131.874934) + (xy 146.030259 131.925954) + (xy 145.962896 131.948374) + (xy 145.894105 131.930815) + (xy 145.846334 131.879504) + (xy 145.844546 131.870514) + (xy 145.787965 131.785835) + (xy 145.777649 131.778942) + (xy 145.713603 131.736147) + (xy 145.7136 131.736146) + (xy 145.703286 131.729254) + (xy 145.691119 131.726834) + (xy 145.691117 131.726833) + (xy 145.652153 131.719083) + (xy 145.628612 131.7144) + (xy 145.018188 131.7144) + (xy 144.994647 131.719083) + (xy 144.955683 131.726833) + (xy 144.955681 131.726834) + (xy 144.943514 131.729254) + (xy 144.9332 131.736146) + (xy 144.933197 131.736147) + (xy 144.869151 131.778942) + (xy 144.858835 131.785835) + (xy 144.802254 131.870514) + (xy 144.801375 131.874934) + (xy 144.760259 131.925954) + (xy 144.692896 131.948374) + (xy 144.624105 131.930815) + (xy 144.576334 131.879504) + (xy 144.574546 131.870514) + (xy 144.517965 131.785835) + (xy 144.507649 131.778942) + (xy 144.443603 131.736147) + (xy 144.4436 131.736146) + (xy 144.433286 131.729254) + (xy 144.421119 131.726834) + (xy 144.421117 131.726833) + (xy 144.382153 131.719083) + (xy 144.358612 131.7144) + (xy 143.748188 131.7144) + (xy 143.724647 131.719083) + (xy 143.685683 131.726833) + (xy 143.685681 131.726834) + (xy 143.673514 131.729254) + (xy 143.6632 131.736146) + (xy 143.663197 131.736147) + (xy 143.599151 131.778942) + (xy 143.588835 131.785835) + (xy 143.532254 131.870514) + (xy 143.531375 131.874934) + (xy 143.490259 131.925954) + (xy 143.422896 131.948374) + (xy 143.354105 131.930815) + (xy 143.306334 131.879504) + (xy 143.304546 131.870514) + (xy 143.247965 131.785835) + (xy 143.237649 131.778942) + (xy 143.173603 131.736147) + (xy 143.1736 131.736146) + (xy 143.163286 131.729254) + (xy 143.151119 131.726834) + (xy 143.151117 131.726833) + (xy 143.112153 131.719083) + (xy 143.088612 131.7144) + (xy 142.478188 131.7144) + (xy 142.454647 131.719083) + (xy 142.415683 131.726833) + (xy 142.415681 131.726834) + (xy 142.403514 131.729254) + (xy 142.3932 131.736146) + (xy 142.393197 131.736147) + (xy 142.329151 131.778942) + (xy 142.318835 131.785835) + (xy 142.262254 131.870514) + (xy 142.261375 131.874934) + (xy 142.220259 131.925954) + (xy 142.152896 131.948374) + (xy 142.084105 131.930815) + (xy 142.036334 131.879504) + (xy 142.034546 131.870514) + (xy 141.977965 131.785835) + (xy 141.967649 131.778942) + (xy 141.903603 131.736147) + (xy 141.9036 131.736146) + (xy 141.893286 131.729254) + (xy 141.881119 131.726834) + (xy 141.881117 131.726833) + (xy 141.842153 131.719083) + (xy 141.818612 131.7144) + (xy 141.208188 131.7144) + (xy 141.184647 131.719083) + (xy 141.145683 131.726833) + (xy 141.145681 131.726834) + (xy 141.133514 131.729254) + (xy 141.1232 131.736146) + (xy 141.123197 131.736147) + (xy 141.059151 131.778942) + (xy 141.048835 131.785835) + (xy 140.992254 131.870514) + (xy 140.991375 131.874934) + (xy 140.950259 131.925954) + (xy 140.882896 131.948374) + (xy 140.814105 131.930815) + (xy 140.766334 131.879504) + (xy 140.764546 131.870514) + (xy 140.707965 131.785835) + (xy 140.697649 131.778942) + (xy 140.633603 131.736147) + (xy 140.6336 131.736146) + (xy 140.623286 131.729254) + (xy 140.611119 131.726834) + (xy 140.611117 131.726833) + (xy 140.572153 131.719083) + (xy 140.548612 131.7144) + (xy 139.938188 131.7144) + (xy 139.914647 131.719083) + (xy 139.875683 131.726833) + (xy 139.875681 131.726834) + (xy 139.863514 131.729254) + (xy 139.8532 131.736146) + (xy 139.853197 131.736147) + (xy 139.789151 131.778942) + (xy 139.778835 131.785835) + (xy 139.722254 131.870514) + (xy 139.721375 131.874934) + (xy 139.680259 131.925954) + (xy 139.612896 131.948374) + (xy 139.544105 131.930815) + (xy 139.496334 131.879504) + (xy 139.494546 131.870514) + (xy 139.437965 131.785835) + (xy 139.427649 131.778942) + (xy 139.363603 131.736147) + (xy 139.3636 131.736146) + (xy 139.353286 131.729254) + (xy 139.341119 131.726834) + (xy 139.341117 131.726833) + (xy 139.302153 131.719083) + (xy 139.278612 131.7144) + (xy 138.668188 131.7144) + (xy 138.644647 131.719083) + (xy 138.605683 131.726833) + (xy 138.605681 131.726834) + (xy 138.593514 131.729254) + (xy 138.5832 131.736146) + (xy 138.583197 131.736147) + (xy 138.519151 131.778942) + (xy 138.508835 131.785835) + (xy 138.452254 131.870514) + (xy 138.451375 131.874934) + (xy 138.410259 131.925954) + (xy 138.342896 131.948374) + (xy 138.274105 131.930815) + (xy 138.226334 131.879504) + (xy 138.224546 131.870514) + (xy 138.167965 131.785835) + (xy 138.157649 131.778942) + (xy 138.093603 131.736147) + (xy 138.0936 131.736146) + (xy 138.083286 131.729254) + (xy 138.071119 131.726834) + (xy 138.071117 131.726833) + (xy 138.032153 131.719083) + (xy 138.008612 131.7144) + (xy 137.398188 131.7144) + (xy 137.374647 131.719083) + (xy 137.335683 131.726833) + (xy 137.335681 131.726834) + (xy 137.323514 131.729254) + (xy 137.3132 131.736146) + (xy 137.313197 131.736147) + (xy 137.249151 131.778942) + (xy 137.238835 131.785835) + (xy 137.182254 131.870514) + (xy 137.181375 131.874934) + (xy 137.140259 131.925954) + (xy 137.072896 131.948374) + (xy 137.004105 131.930815) + (xy 136.956334 131.879504) + (xy 136.954546 131.870514) + (xy 136.897965 131.785835) + (xy 136.887649 131.778942) + (xy 136.823603 131.736147) + (xy 136.8236 131.736146) + (xy 136.813286 131.729254) + (xy 136.801119 131.726834) + (xy 136.801117 131.726833) + (xy 136.762153 131.719083) + (xy 136.738612 131.7144) + (xy 136.128188 131.7144) + (xy 136.104647 131.719083) + (xy 136.065683 131.726833) + (xy 136.065681 131.726834) + (xy 136.053514 131.729254) + (xy 136.0432 131.736146) + (xy 136.043197 131.736147) + (xy 135.979151 131.778942) + (xy 135.968835 131.785835) + (xy 135.912254 131.870514) + (xy 135.911375 131.874934) + (xy 135.870259 131.925954) + (xy 135.802896 131.948374) + (xy 135.734105 131.930815) + (xy 135.686334 131.879504) + (xy 135.684546 131.870514) + (xy 135.627965 131.785835) + (xy 135.617649 131.778942) + (xy 135.553603 131.736147) + (xy 135.5536 131.736146) + (xy 135.543286 131.729254) + (xy 135.531119 131.726834) + (xy 135.531117 131.726833) + (xy 135.492153 131.719083) + (xy 135.468612 131.7144) + (xy 134.858188 131.7144) + (xy 134.834647 131.719083) + (xy 134.795683 131.726833) + (xy 134.795681 131.726834) + (xy 134.783514 131.729254) + (xy 134.7732 131.736146) + (xy 134.773197 131.736147) + (xy 134.709151 131.778942) + (xy 134.698835 131.785835) + (xy 134.642254 131.870514) + (xy 134.641375 131.874934) + (xy 134.600259 131.925954) + (xy 134.532896 131.948374) + (xy 134.464105 131.930815) + (xy 134.416334 131.879504) + (xy 134.414546 131.870514) + (xy 134.357965 131.785835) + (xy 134.347649 131.778942) + (xy 134.283603 131.736147) + (xy 134.2836 131.736146) + (xy 134.273286 131.729254) + (xy 134.261119 131.726834) + (xy 134.261117 131.726833) + (xy 134.222153 131.719083) + (xy 134.198612 131.7144) + (xy 133.588188 131.7144) + (xy 133.564647 131.719083) + (xy 133.525683 131.726833) + (xy 133.525681 131.726834) + (xy 133.513514 131.729254) + (xy 133.5032 131.736146) + (xy 133.503197 131.736147) + (xy 133.439151 131.778942) + (xy 133.428835 131.785835) + (xy 133.372254 131.870514) + (xy 133.371375 131.874934) + (xy 133.330259 131.925954) + (xy 133.262896 131.948374) + (xy 133.194105 131.930815) + (xy 133.146334 131.879504) + (xy 133.144546 131.870514) + (xy 133.087965 131.785835) + (xy 133.077649 131.778942) + (xy 133.013603 131.736147) + (xy 133.0136 131.736146) + (xy 133.003286 131.729254) + (xy 132.991119 131.726834) + (xy 132.991117 131.726833) + (xy 132.952153 131.719083) + (xy 132.928612 131.7144) + (xy 132.318188 131.7144) + (xy 132.294647 131.719083) + (xy 132.255683 131.726833) + (xy 132.255681 131.726834) + (xy 132.243514 131.729254) + (xy 132.2332 131.736146) + (xy 132.233197 131.736147) + (xy 132.169151 131.778942) + (xy 132.158835 131.785835) + (xy 132.151942 131.796151) + (xy 132.109147 131.860197) + (xy 132.109146 131.8602) + (xy 132.102254 131.870514) + (xy 132.0874 131.945188) + (xy 132.0874 135.62) + (xy 132.067398 135.688121) + (xy 132.013742 135.734614) + (xy 131.9614 135.746) + (xy 130.7454 135.746) + (xy 130.677279 135.725998) + (xy 130.630786 135.672342) + (xy 130.6194 135.62) + (xy 130.6194 131.945188) + (xy 130.604546 131.870514) + (xy 130.597654 131.8602) + (xy 130.597653 131.860197) + (xy 130.554858 131.796151) + (xy 130.547965 131.785835) + (xy 130.537649 131.778942) + (xy 130.473603 131.736147) + (xy 130.4736 131.736146) + (xy 130.463286 131.729254) + (xy 130.451119 131.726834) + (xy 130.451117 131.726833) + (xy 130.412153 131.719083) + (xy 130.388612 131.7144) + (xy 129.778188 131.7144) + (xy 129.754647 131.719083) + (xy 129.715683 131.726833) + (xy 129.715681 131.726834) + (xy 129.703514 131.729254) + (xy 129.6932 131.736146) + (xy 129.693197 131.736147) + (xy 129.629151 131.778942) + (xy 129.618835 131.785835) + (xy 129.562254 131.870514) + (xy 129.561375 131.874934) + (xy 129.520259 131.925954) + (xy 129.452896 131.948374) + (xy 129.384105 131.930815) + (xy 129.336334 131.879504) + (xy 129.334546 131.870514) + (xy 129.277965 131.785835) + (xy 129.267649 131.778942) + (xy 129.203603 131.736147) + (xy 129.2036 131.736146) + (xy 129.193286 131.729254) + (xy 129.181119 131.726834) + (xy 129.181117 131.726833) + (xy 129.142153 131.719083) + (xy 129.118612 131.7144) + (xy 128.508188 131.7144) + (xy 128.484647 131.719083) + (xy 128.445683 131.726833) + (xy 128.445681 131.726834) + (xy 128.433514 131.729254) + (xy 128.4232 131.736146) + (xy 128.423197 131.736147) + (xy 128.359151 131.778942) + (xy 128.348835 131.785835) + (xy 128.292254 131.870514) + (xy 128.291375 131.874934) + (xy 128.250259 131.925954) + (xy 128.182896 131.948374) + (xy 128.114105 131.930815) + (xy 128.066334 131.879504) + (xy 128.064546 131.870514) + (xy 128.007965 131.785835) + (xy 127.997649 131.778942) + (xy 127.933603 131.736147) + (xy 127.9336 131.736146) + (xy 127.923286 131.729254) + (xy 127.911119 131.726834) + (xy 127.911117 131.726833) + (xy 127.872153 131.719083) + (xy 127.848612 131.7144) + (xy 127.238188 131.7144) + (xy 127.214647 131.719083) + (xy 127.175683 131.726833) + (xy 127.175681 131.726834) + (xy 127.163514 131.729254) + (xy 127.1532 131.736146) + (xy 127.153197 131.736147) + (xy 127.089151 131.778942) + (xy 127.078835 131.785835) + (xy 127.022254 131.870514) + (xy 127.021375 131.874934) + (xy 126.980259 131.925954) + (xy 126.912896 131.948374) + (xy 126.844105 131.930815) + (xy 126.796334 131.879504) + (xy 126.794546 131.870514) + (xy 126.737965 131.785835) + (xy 126.727649 131.778942) + (xy 126.663603 131.736147) + (xy 126.6636 131.736146) + (xy 126.653286 131.729254) + (xy 126.641119 131.726834) + (xy 126.641117 131.726833) + (xy 126.602153 131.719083) + (xy 126.578612 131.7144) + (xy 125.968188 131.7144) + (xy 125.944647 131.719083) + (xy 125.905683 131.726833) + (xy 125.905681 131.726834) + (xy 125.893514 131.729254) + (xy 125.8832 131.736146) + (xy 125.883197 131.736147) + (xy 125.819151 131.778942) + (xy 125.808835 131.785835) + (xy 125.752254 131.870514) + (xy 125.751375 131.874934) + (xy 125.710259 131.925954) + (xy 125.642896 131.948374) + (xy 125.574105 131.930815) + (xy 125.526334 131.879504) + (xy 125.524546 131.870514) + (xy 125.467965 131.785835) + (xy 125.457649 131.778942) + (xy 125.393603 131.736147) + (xy 125.3936 131.736146) + (xy 125.383286 131.729254) + (xy 125.371119 131.726834) + (xy 125.371117 131.726833) + (xy 125.332153 131.719083) + (xy 125.308612 131.7144) + (xy 124.698188 131.7144) + (xy 124.674647 131.719083) + (xy 124.635683 131.726833) + (xy 124.635681 131.726834) + (xy 124.623514 131.729254) + (xy 124.6132 131.736146) + (xy 124.613197 131.736147) + (xy 124.549151 131.778942) + (xy 124.538835 131.785835) + (xy 124.482254 131.870514) + (xy 124.481375 131.874934) + (xy 124.440259 131.925954) + (xy 124.372896 131.948374) + (xy 124.304105 131.930815) + (xy 124.256334 131.879504) + (xy 124.254546 131.870514) + (xy 124.197965 131.785835) + (xy 124.187649 131.778942) + (xy 124.123603 131.736147) + (xy 124.1236 131.736146) + (xy 124.113286 131.729254) + (xy 124.101119 131.726834) + (xy 124.101117 131.726833) + (xy 124.062153 131.719083) + (xy 124.038612 131.7144) + (xy 123.428188 131.7144) + (xy 123.404647 131.719083) + (xy 123.365683 131.726833) + (xy 123.365681 131.726834) + (xy 123.353514 131.729254) + (xy 123.3432 131.736146) + (xy 123.343197 131.736147) + (xy 123.279151 131.778942) + (xy 123.268835 131.785835) + (xy 123.212254 131.870514) + (xy 123.211375 131.874934) + (xy 123.170259 131.925954) + (xy 123.102896 131.948374) + (xy 123.034105 131.930815) + (xy 122.986334 131.879504) + (xy 122.984546 131.870514) + (xy 122.927965 131.785835) + (xy 122.917649 131.778942) + (xy 122.853603 131.736147) + (xy 122.8536 131.736146) + (xy 122.843286 131.729254) + (xy 122.831119 131.726834) + (xy 122.831117 131.726833) + (xy 122.792153 131.719083) + (xy 122.768612 131.7144) + (xy 122.158188 131.7144) + (xy 122.134647 131.719083) + (xy 122.095683 131.726833) + (xy 122.095681 131.726834) + (xy 122.083514 131.729254) + (xy 122.0732 131.736146) + (xy 122.073197 131.736147) + (xy 122.009151 131.778942) + (xy 121.998835 131.785835) + (xy 121.942254 131.870514) + (xy 121.941375 131.874934) + (xy 121.900259 131.925954) + (xy 121.832896 131.948374) + (xy 121.764105 131.930815) + (xy 121.716334 131.879504) + (xy 121.714546 131.870514) + (xy 121.657965 131.785835) + (xy 121.647649 131.778942) + (xy 121.583603 131.736147) + (xy 121.5836 131.736146) + (xy 121.573286 131.729254) + (xy 121.561119 131.726834) + (xy 121.561117 131.726833) + (xy 121.522153 131.719083) + (xy 121.498612 131.7144) + (xy 120.888188 131.7144) + (xy 120.864647 131.719083) + (xy 120.825683 131.726833) + (xy 120.825681 131.726834) + (xy 120.813514 131.729254) + (xy 120.8032 131.736146) + (xy 120.803197 131.736147) + (xy 120.739151 131.778942) + (xy 120.728835 131.785835) + (xy 120.672254 131.870514) + (xy 120.671375 131.874934) + (xy 120.630259 131.925954) + (xy 120.562896 131.948374) + (xy 120.494105 131.930815) + (xy 120.446334 131.879504) + (xy 120.444546 131.870514) + (xy 120.387965 131.785835) + (xy 120.377649 131.778942) + (xy 120.313603 131.736147) + (xy 120.3136 131.736146) + (xy 120.303286 131.729254) + (xy 120.291119 131.726834) + (xy 120.291117 131.726833) + (xy 120.252153 131.719083) + (xy 120.228612 131.7144) + (xy 119.618188 131.7144) + (xy 119.594647 131.719083) + (xy 119.555683 131.726833) + (xy 119.555681 131.726834) + (xy 119.543514 131.729254) + (xy 119.5332 131.736146) + (xy 119.533197 131.736147) + (xy 119.469151 131.778942) + (xy 119.458835 131.785835) + (xy 119.402254 131.870514) + (xy 119.401375 131.874934) + (xy 119.360259 131.925954) + (xy 119.292896 131.948374) + (xy 119.224105 131.930815) + (xy 119.176334 131.879504) + (xy 119.174546 131.870514) + (xy 119.117965 131.785835) + (xy 119.107649 131.778942) + (xy 119.043603 131.736147) + (xy 119.0436 131.736146) + (xy 119.033286 131.729254) + (xy 119.021119 131.726834) + (xy 119.021117 131.726833) + (xy 118.982153 131.719083) + (xy 118.958612 131.7144) + (xy 118.348188 131.7144) + (xy 118.324647 131.719083) + (xy 118.285683 131.726833) + (xy 118.285681 131.726834) + (xy 118.273514 131.729254) + (xy 118.2632 131.736146) + (xy 118.263197 131.736147) + (xy 118.199151 131.778942) + (xy 118.188835 131.785835) + (xy 118.181942 131.796151) + (xy 118.139147 131.860197) + (xy 118.139146 131.8602) + (xy 118.132254 131.870514) + (xy 118.1174 131.945188) + (xy 118.1174 135.62) + (xy 118.097398 135.688121) + (xy 118.043742 135.734614) + (xy 117.9914 135.746) + (xy 117.38 135.746) + (xy 117.311879 135.725998) + (xy 117.265386 135.672342) + (xy 117.254 135.62) + (xy 117.254 125.99308) + (xy 138.239218 125.99308) + (xy 138.256642 126.150898) + (xy 138.311207 126.300005) + (xy 138.315443 126.306308) + (xy 138.315443 126.306309) + (xy 138.394978 126.424669) + (xy 138.399764 126.431792) + (xy 138.405383 126.436905) + (xy 138.405384 126.436906) + (xy 138.511585 126.533541) + (xy 138.517201 126.538651) + (xy 138.656737 126.614413) + (xy 138.810317 126.654704) + (xy 138.892689 126.655998) + (xy 138.961476 126.657079) + (xy 138.961479 126.657079) + (xy 138.969074 126.657198) + (xy 138.976478 126.655502) + (xy 138.97648 126.655502) + (xy 139.034202 126.642282) + (xy 139.123844 126.621751) + (xy 139.265691 126.550409) + (xy 139.29365 126.52653) + (xy 139.380652 126.452224) + (xy 139.380654 126.452221) + (xy 139.386426 126.447292) + (xy 139.390856 126.441127) + (xy 139.390859 126.441124) + (xy 139.396355 126.433475) + (xy 139.452349 126.389827) + (xy 139.498678 126.381) + (xy 142.19944 126.381) + (xy 142.267561 126.401002) + (xy 142.294822 126.424669) + (xy 142.295524 126.425483) + (xy 142.299764 126.431792) + (xy 142.305384 126.436906) + (xy 142.305386 126.436908) + (xy 142.411585 126.533541) + (xy 142.417201 126.538651) + (xy 142.556737 126.614413) + (xy 142.710317 126.654704) + (xy 142.792689 126.655998) + (xy 142.861476 126.657079) + (xy 142.861479 126.657079) + (xy 142.869074 126.657198) + (xy 142.876478 126.655502) + (xy 142.87648 126.655502) + (xy 142.934202 126.642282) + (xy 143.023844 126.621751) + (xy 143.165691 126.550409) + (xy 143.19365 126.52653) + (xy 143.280652 126.452224) + (xy 143.280654 126.452221) + (xy 143.286426 126.447292) + (xy 143.379079 126.318351) + (xy 143.438301 126.171032) + (xy 143.460673 126.013839) + (xy 143.460818 126) + (xy 143.441743 125.842373) + (xy 143.385619 125.693846) + (xy 143.327776 125.609683) + (xy 143.299989 125.569252) + (xy 143.299987 125.56925) + (xy 143.295687 125.562993) + (xy 143.177138 125.45737) + (xy 143.169735 125.45345) + (xy 143.043528 125.386627) + (xy 143.043529 125.386627) + (xy 143.036816 125.383073) + (xy 143.027078 125.380627) + (xy 142.890193 125.346244) + (xy 142.890189 125.346244) + (xy 142.882822 125.344393) + (xy 142.875222 125.344353) + (xy 142.875221 125.344353) + (xy 142.810427 125.344014) + (xy 142.724047 125.343561) + (xy 142.716667 125.345333) + (xy 142.716665 125.345333) + (xy 142.577037 125.378855) + (xy 142.577035 125.378856) + (xy 142.569657 125.380627) + (xy 142.428565 125.45345) + (xy 142.422843 125.458442) + (xy 142.422841 125.458443) + (xy 142.314642 125.552831) + (xy 142.314639 125.552834) + (xy 142.308917 125.557826) + (xy 142.30455 125.564039) + (xy 142.304545 125.564045) + (xy 142.303557 125.565451) + (xy 142.302575 125.566233) + (xy 142.299465 125.569687) + (xy 142.298889 125.569169) + (xy 142.248023 125.609683) + (xy 142.200471 125.619) + (xy 139.500471 125.619) + (xy 139.43235 125.598998) + (xy 139.406342 125.573778) + (xy 139.405012 125.57495) + (xy 139.399988 125.569251) + (xy 139.395687 125.562993) + (xy 139.277138 125.45737) + (xy 139.269735 125.45345) + (xy 139.143528 125.386627) + (xy 139.143529 125.386627) + (xy 139.136816 125.383073) + (xy 139.127078 125.380627) + (xy 138.990193 125.346244) + (xy 138.990189 125.346244) + (xy 138.982822 125.344393) + (xy 138.975222 125.344353) + (xy 138.975221 125.344353) + (xy 138.910427 125.344014) + (xy 138.824047 125.343561) + (xy 138.816667 125.345333) + (xy 138.816665 125.345333) + (xy 138.677037 125.378855) + (xy 138.677035 125.378856) + (xy 138.669657 125.380627) + (xy 138.528565 125.45345) + (xy 138.522843 125.458442) + (xy 138.522841 125.458443) + (xy 138.414642 125.552831) + (xy 138.414639 125.552834) + (xy 138.408917 125.557826) + (xy 138.317619 125.68773) + (xy 138.259943 125.835661) + (xy 138.239218 125.99308) + (xy 117.254 125.99308) + (xy 117.254 98.38) + (xy 117.274002 98.311879) + (xy 117.327658 98.265386) + (xy 117.38 98.254) + (xy 156.62 98.254) + ) + ) + ) + (group "board_edge" (id 55959446-f960-4233-827e-96ff1fbe4f50) + (members + 103f6d42-92f5-4124-8bee-144c92aca775 + d9c93f10-1129-47c3-bf26-abbdba86ec6f + ) + ) +) diff --git a/qa/data/severities.kicad_pro b/qa/data/severities.kicad_pro new file mode 100644 index 0000000000..2e29c1f73f --- /dev/null +++ b/qa/data/severities.kicad_pro @@ -0,0 +1,417 @@ +{ + "board": { + "design_settings": { + "defaults": { + "board_outline_line_width": 0.049999999999999996, + "copper_line_width": 0.19999999999999998, + "copper_text_italic": false, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "copper_text_upright": false, + "courtyard_line_width": 0.049999999999999996, + "dimension_precision": 4, + "dimension_units": 3, + "dimensions": { + "arrow_length": 1270000, + "extension_offset": 500000, + "keep_text_aligned": true, + "suppress_zeroes": false, + "text_position": 0, + "units_format": 1 + }, + "fab_line_width": 0.09999999999999999, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, + "other_line_width": 0.09999999999999999, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 0.0, + "height": 0.4, + "width": 1.35 + }, + "silk_line_width": 0.12, + "silk_text_italic": false, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.15, + "silk_text_upright": false, + "zones": { + "45_degree_only": false, + "min_clearance": 0.254 + } + }, + "diff_pair_dimensions": [ + { + "gap": 0.0, + "via_gap": 0.0, + "width": 0.0 + } + ], + "drc_exclusions": [], + "meta": { + "filename": "board_design_settings.json", + "version": 2 + }, + "rule_severities": { + "annular_width": "error", + "clearance": "error", + "copper_edge_clearance": "error", + "copper_sliver": "warning", + "courtyards_overlap": "error", + "diff_pair_gap_out_of_range": "error", + "diff_pair_uncoupled_length_too_long": "error", + "drill_out_of_range": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "hole_clearance": "error", + "hole_near_hole": "error", + "invalid_outline": "error", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "length_out_of_range": "error", + "lib_footprint_issues": "ignore", + "malformed_courtyard": "error", + "microvia_drill_out_of_range": "error", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "net_conflict": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "error", + "pth_inside_courtyard": "ignore", + "shorting_items": "error", + "silk_over_copper": "ignore", + "silk_overlap": "warning", + "skew_out_of_range": "error", + "solder_mask_bridge": "error", + "starved_thermal": "error", + "text_height": "warning", + "text_thickness": "warning", + "too_many_vias": "error", + "track_dangling": "ignore", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_dangling": "warning", + "zone_has_empty_net": "error", + "zones_intersect": "error" + }, + "rules": { + "allow_blind_buried_vias": false, + "allow_microvias": false, + "max_error": 0.005, + "min_aperture_clearance": 0.049999999999999996, + "min_clearance": 0.0, + "min_copper_edge_clearance": 0.25, + "min_hole_clearance": 0.0, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.19999999999999998, + "min_microvia_drill": 0.09999999999999999, + "min_resolved_spokes": 2, + "min_silk_clearance": 0.0, + "min_text_height": 0.7999999999999999, + "min_text_thickness": 0.12, + "min_through_hole_diameter": 0.3, + "min_track_width": 0.19999999999999998, + "min_via_annular_width": 0.049999999999999996, + "min_via_diameter": 0.39999999999999997, + "solder_mask_to_copper_clearance": 0.0, + "use_height_for_length_calcs": true + }, + "track_widths": [ + 0.0, + 0.3, + 0.35, + 0.4 + ], + "via_dimensions": [ + { + "diameter": 0.0, + "drill": 0.0 + }, + { + "diameter": 1.0, + "drill": 0.5 + } + ], + "zones_allow_external_fillets": false, + "zones_use_no_outline": true + }, + "layer_presets": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "erc": { + "erc_exclusions": [], + "meta": { + "version": 0 + }, + "pin_map": [ + [ + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 2 + ], + [ + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 2, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 1, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ] + ], + "rule_severities": { + "bus_definition_conflict": "error", + "bus_label_syntax": "error", + "bus_to_bus_conflict": "error", + "bus_to_net_conflict": "error", + "different_unit_footprint": "error", + "different_unit_net": "error", + "duplicate_sheet_names": "error", + "global_label_dangling": "warning", + "hier_label_mismatch": "error", + "label_dangling": "error", + "lib_symbol_issues": "warning", + "multiple_net_names": "warning", + "net_not_bus_member": "warning", + "no_connect_connected": "warning", + "no_connect_dangling": "warning", + "pin_not_connected": "error", + "pin_not_driven": "error", + "pin_to_pin": "error", + "power_pin_not_driven": "error", + "similar_labels": "warning", + "unresolved_variable": "error", + "wire_dangling": "error" + } + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "issue1358.kicad_pro", + "version": 1 + }, + "net_settings": { + "classes": [ + { + "bus_width": 12.0, + "clearance": 0.2, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.3, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.25, + "via_diameter": 0.8, + "via_drill": 0.4, + "wire_width": 6.0 + } + ], + "meta": { + "version": 1 + }, + "net_colors": null + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "specctra_dsn": "", + "step": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "drawing": { + "default_bus_thickness": 12.0, + "default_junction_size": 36.0, + "default_line_thickness": 6.0, + "default_text_size": 50.0, + "default_wire_thickness": 6.0, + "field_names": [], + "intersheets_ref_prefix": "", + "intersheets_ref_short": false, + "intersheets_ref_show": false, + "intersheets_ref_suffix": "", + "junction_size_choice": 3, + "pin_symbol_size": 25.0, + "text_offset_ratio": 0.3 + }, + "legacy_lib_dir": "", + "legacy_lib_list": [], + "meta": { + "version": 0 + }, + "net_format_name": "", + "page_layout_descr_file": "", + "plot_directory": "", + "spice_adjust_passive_values": false, + "spice_external_command": "spice \"%I\"", + "subpart_first_id": 65, + "subpart_id_separator": 0 + }, + "sheets": [ + [ + "155f8eea-0e5f-4cd4-af54-d2a6a7cc5844", + "AM2315 sensors I2C interface" + ], + [ + "3171c8e1-e8bd-4b55-9726-8c0ea0490320", + "230V & general interface" + ], + [ + "155f8eea-0e5f-4cd4-af54-d2a6a7cc5844", + "" + ] + ], + "text_variables": {} +} diff --git a/qa/pcbnew/CMakeLists.txt b/qa/pcbnew/CMakeLists.txt index d669cb59cc..59c0a15d76 100644 --- a/qa/pcbnew/CMakeLists.txt +++ b/qa/pcbnew/CMakeLists.txt @@ -41,6 +41,7 @@ set( QA_PCBNEW_SRCS test_tracks_cleaner.cpp test_zone_filler.cpp + drc/test_custom_rule_severities.cpp drc/test_drc_courtyard_invalid.cpp drc/test_drc_courtyard_overlap.cpp drc/test_drc_regressions.cpp diff --git a/qa/pcbnew/drc/test_custom_rule_severities.cpp b/qa/pcbnew/drc/test_custom_rule_severities.cpp new file mode 100644 index 0000000000..9098fa09fb --- /dev/null +++ b/qa/pcbnew/drc/test_custom_rule_severities.cpp @@ -0,0 +1,84 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors. + * + * 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 +#include +#include +#include +#include +#include +#include + + +struct DRC_REGRESSION_TEST_FIXTURE +{ + DRC_REGRESSION_TEST_FIXTURE() : + m_settingsManager( true /* headless */ ) + { } + + SETTINGS_MANAGER m_settingsManager; + std::unique_ptr m_board; +}; + + +BOOST_FIXTURE_TEST_CASE( DRCCustomRuleSeverityTest, DRC_REGRESSION_TEST_FIXTURE ) +{ + // This board has two edge-connectors. There is a custom DRC rule which conditionally + // applies to one of them and sets the edge-clearance severity to "ignore". It should + // therefore only generate edge-clearance violations for the other edge connector. + + KI_TEST::LoadBoard( m_settingsManager, "severities", m_board ); + KI_TEST::FillZones( m_board.get(), 6 ); + + std::vector violations; + BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); + + bds.m_DRCEngine->SetViolationHandler( + [&]( const std::shared_ptr& aItem, wxPoint aPos ) + { + PCB_MARKER temp( aItem, aPos ); + + if( bds.m_DrcExclusions.find( temp.Serialize() ) == bds.m_DrcExclusions.end() ) + violations.push_back( *aItem ); + } ); + + bds.m_DRCEngine->RunTests( EDA_UNITS::MILLIMETRES, true, false ); + + if( violations.size() == 8 ) + { + BOOST_CHECK_EQUAL( 1, 1 ); // quiet "did not check any assertions" warning + BOOST_TEST_MESSAGE( "Custom rule severity test passed" ); + } + else + { + BOOST_CHECK_EQUAL( violations.size(), 8 ); + + std::map itemMap; + m_board->FillItemMap( itemMap ); + + for( const DRC_ITEM& item : violations ) + BOOST_TEST_MESSAGE( item.ShowReport( EDA_UNITS::INCHES, RPT_SEVERITY_ERROR, itemMap ) ); + + BOOST_ERROR( "Custom rule severity test failed" ); + } +} diff --git a/qa/pcbnew/drc/test_solder_mask_bridging.cpp b/qa/pcbnew/drc/test_solder_mask_bridging.cpp index bd90cd142d..3ba17ad00a 100644 --- a/qa/pcbnew/drc/test_solder_mask_bridging.cpp +++ b/qa/pcbnew/drc/test_solder_mask_bridging.cpp @@ -73,10 +73,7 @@ BOOST_FIXTURE_TEST_CASE( DRCSolderMaskBridgingTest, DRC_REGRESSION_TEST_FIXTURE m_board->FillItemMap( itemMap ); for( const DRC_ITEM& item : violations ) - { - BOOST_TEST_MESSAGE( item.ShowReport( EDA_UNITS::INCHES, RPT_SEVERITY_ERROR, - itemMap ) ); - } + BOOST_TEST_MESSAGE( item.ShowReport( EDA_UNITS::INCHES, RPT_SEVERITY_ERROR, itemMap ) ); BOOST_ERROR( "DRC solder mask bridge test failed" ); }