| 52 | |
| 53 | |
| 54 | def _has_property(node: dict, path: list[str], expected: str) -> bool: |
| 55 | if not path: |
| 56 | return False |
| 57 | current, remaining = path[0], path[1:] |
| 58 | if not remaining and current in node["fields"]: |
| 59 | value = node["fields"][current] |
| 60 | if isinstance(value, bool): |
| 61 | return str(value).lower() == expected.lower() |
| 62 | return str(value) == expected |
| 63 | if current in node["children"]: |
| 64 | if remaining and remaining[0] == "*": |
| 65 | return any(_has_property(child, remaining[1:], expected) for child in node["children"][current]) |
| 66 | if remaining and node["children"][current]: |
| 67 | return _has_property(node["children"][current][0], remaining, expected) |
| 68 | return False |
| 69 | |
| 70 | |
| 71 | def _matches_ai206(code: str) -> bool: |