annet 3.19.0__tar.gz → 3.20.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of annet might be problematic. Click here for more details.
- {annet-3.19.0/annet.egg-info → annet-3.20.0}/PKG-INFO +1 -1
- {annet-3.19.0 → annet-3.20.0}/annet/generators/__init__.py +5 -6
- annet-3.20.0/annet/generators/annotate.py +37 -0
- {annet-3.19.0 → annet-3.20.0}/annet/generators/base.py +12 -3
- {annet-3.19.0 → annet-3.20.0}/annet/generators/entire.py +11 -12
- {annet-3.19.0 → annet-3.20.0}/annet/generators/jsonfragment.py +6 -17
- {annet-3.19.0 → annet-3.20.0}/annet/generators/partial.py +32 -52
- {annet-3.19.0 → annet-3.20.0}/annet/generators/result.py +14 -23
- {annet-3.19.0 → annet-3.20.0/annet.egg-info}/PKG-INFO +1 -1
- {annet-3.19.0 → annet-3.20.0}/annet.egg-info/SOURCES.txt +1 -0
- {annet-3.19.0 → annet-3.20.0}/AUTHORS +0 -0
- {annet-3.19.0 → annet-3.20.0}/LICENSE +0 -0
- {annet-3.19.0 → annet-3.20.0}/MANIFEST.in +0 -0
- {annet-3.19.0 → annet-3.20.0}/README.md +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/fetchers/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/fetchers/stub/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/fetchers/stub/fetcher.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/file/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/file/provider.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/common/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/common/adapter.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/common/client.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/common/manufacturer.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/common/models.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/common/query.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/common/status_client.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/common/storage_base.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/common/storage_opts.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/provider.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v24/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v24/models.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v24/storage.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v37/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v37/models.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v37/storage.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v41/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v41/models.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v41/storage.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v42/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v42/models.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/adapters/netbox/v42/storage.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annet.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/command.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/diff.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/errors.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/filter_acl.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/jsontools.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/lib.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/netdev/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/netdev/db.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/netdev/devdb/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/netdev/devdb/data/devdb.json +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/netdev/views/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/netdev/views/dump.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/netdev/views/hardware.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/output.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/patching.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/rbparser/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/rbparser/acl.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/rbparser/deploying.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/rbparser/ordering.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/rbparser/platform.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/rbparser/syntax.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/rulebook/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/rulebook/common.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/annlib/types.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/api/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/argparse.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/bgp_models.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/cli.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/cli_args.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/configs/context.yml +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/configs/logging.yaml +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/connectors.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/deploy.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/deploy_ui.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/diff.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/filtering.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/gen.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/generators/common/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/generators/common/initial.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/generators/exceptions.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/generators/perf.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/generators/ref.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/hardware.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/implicit.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/lib.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/mesh/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/mesh/basemodel.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/mesh/device_models.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/mesh/executor.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/mesh/match_args.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/mesh/models_converter.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/mesh/peer_models.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/mesh/port_processor.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/mesh/registry.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/output.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/parallel.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/patching.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/reference.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl/action.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl/condition.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl/match_builder.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl/policy.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl/result.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl/routemap.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl/statement_builder.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl_generators/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl_generators/aspath.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl_generators/community.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl_generators/cumulus_frr.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl_generators/entities.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl_generators/execute.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl_generators/policy.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl_generators/prefix_lists.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rpl_generators/rd.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/arista/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/arista/aaa.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/arista/iface.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/aruba/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/aruba/ap_env.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/aruba/misc.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/b4com/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/b4com/file.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/b4com/iface.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/cisco/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/cisco/iface.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/cisco/misc.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/cisco/vlandb.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/common.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/deploying.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/generic/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/generic/misc.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/h3c/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/h3c/aaa.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/h3c/bgp.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/h3c/iface.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/h3c/misc.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/h3c/vlandb.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/huawei/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/huawei/aaa.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/huawei/bgp.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/huawei/iface.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/huawei/misc.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/huawei/vlandb.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/juniper/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/juniper/iface.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/nexus/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/nexus/iface.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/patching.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/routeros/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/routeros/file.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/arista.deploy +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/arista.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/arista.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/aruba.deploy +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/aruba.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/aruba.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/b4com.deploy +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/b4com.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/b4com.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/cisco.deploy +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/cisco.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/cisco.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/h3c.deploy +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/h3c.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/h3c.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/huawei.deploy +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/huawei.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/huawei.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/iosxr.deploy +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/iosxr.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/iosxr.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/juniper.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/juniper.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/nexus.deploy +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/nexus.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/nexus.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/nokia.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/optixtrans.deploy +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/optixtrans.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/optixtrans.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/pc.deploy +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/pc.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/pc.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/ribbon.deploy +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/ribbon.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/routeros.order +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/rulebook/texts/routeros.rul +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/storage.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/text_term_format.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/tracing.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/types.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/base.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/arista.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/aruba.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/b4com.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/cisco.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/h3c.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/huawei.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/iosxr.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/juniper.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/nexus.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/nokia.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/optixtrans.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/pc.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/ribbon.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/library/routeros.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/registry.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet/vendors/tabparser.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet.egg-info/dependency_links.txt +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet.egg-info/entry_points.txt +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet.egg-info/requires.txt +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet.egg-info/top_level.txt +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/example/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/example/hostname.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/example/lldp.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/mesh_example/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/mesh_example/bgp.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/mesh_example/mesh_logic.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/rpl_example/__init__.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/rpl_example/generator.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/rpl_example/items.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/rpl_example/mesh.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/annet_generators/rpl_example/route_policy.py +0 -0
- {annet-3.19.0 → annet-3.20.0}/requirements.txt +0 -0
- {annet-3.19.0 → annet-3.20.0}/setup.cfg +0 -0
- {annet-3.19.0 → annet-3.20.0}/setup.py +0 -0
|
@@ -26,11 +26,12 @@ from annet.types import (
|
|
|
26
26
|
)
|
|
27
27
|
from annet.vendors import registry_connector, tabparser
|
|
28
28
|
|
|
29
|
+
from .annotate import AbstractAnnotateFormatter, annotate_formatter_connector
|
|
29
30
|
from .base import BaseGenerator
|
|
30
31
|
from .base import ParamsList as ParamsList
|
|
31
32
|
from .base import TextGenerator as TextGenerator
|
|
32
33
|
from .entire import Entire
|
|
33
|
-
from .exceptions import GeneratorError, NotSupportedDevice
|
|
34
|
+
from .exceptions import GeneratorError, InvalidValueFromGenerator, NotSupportedDevice
|
|
34
35
|
from .jsonfragment import JSONFragment
|
|
35
36
|
from .partial import PartialGenerator
|
|
36
37
|
from .perf import GeneratorPerfMesurer
|
|
@@ -165,11 +166,10 @@ def _run_partial_generator(gen: "PartialGenerator", run_args: GeneratorPartialRu
|
|
|
165
166
|
safe_config = odict()
|
|
166
167
|
|
|
167
168
|
if not gen.supports_device(device):
|
|
168
|
-
logger.
|
|
169
|
+
logger.debug("generator %s is not supported for device %s", gen, device.hostname)
|
|
169
170
|
return None
|
|
170
171
|
|
|
171
|
-
span
|
|
172
|
-
if span:
|
|
172
|
+
if span := tracing_connector.get().get_current_span():
|
|
173
173
|
tracing_connector.get().set_device_attributes(span, run_args.device)
|
|
174
174
|
tracing_connector.get().set_dimensions_attributes(span, gen, run_args.device)
|
|
175
175
|
span.set_attributes({
|
|
@@ -184,8 +184,7 @@ def _run_partial_generator(gen: "PartialGenerator", run_args: GeneratorPartialRu
|
|
|
184
184
|
logger.info("Generating PARTIAL ...")
|
|
185
185
|
try:
|
|
186
186
|
output = gen(device, run_args.annotate)
|
|
187
|
-
except NotSupportedDevice:
|
|
188
|
-
# это исключение нужно передать выше в оригинальном виде
|
|
187
|
+
except NotSupportedDevice: # это исключение нужно передать выше в оригинальном виде
|
|
189
188
|
raise
|
|
190
189
|
except Exception as err:
|
|
191
190
|
filename, lineno = gen.get_running_line()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
from types import GeneratorType
|
|
3
|
+
|
|
4
|
+
from annet.connectors import Connector
|
|
5
|
+
|
|
6
|
+
from .base import BaseGenerator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AbstractAnnotateFormatter(abc.ABC):
|
|
10
|
+
def __init__(self, gen: BaseGenerator):
|
|
11
|
+
self.gen = gen
|
|
12
|
+
self._annotation_module = ".".join(gen.__class__.__module__.split(".")[-2:])
|
|
13
|
+
|
|
14
|
+
@abc.abstractmethod
|
|
15
|
+
def make_annotation(self, running_gen: GeneratorType) -> str:
|
|
16
|
+
raise NotImplementedError
|
|
17
|
+
|
|
18
|
+
def get_running_line(self, running_gen: GeneratorType) -> tuple[str, int]:
|
|
19
|
+
if not running_gen or not running_gen.gi_frame:
|
|
20
|
+
return repr(running_gen), -1
|
|
21
|
+
return self._annotation_module, running_gen.gi_frame.f_lineno
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DefaultAnnotateFormatter(AbstractAnnotateFormatter):
|
|
25
|
+
def make_annotation(self, running_gen: GeneratorType) -> str:
|
|
26
|
+
return "%s:%d" % self.get_running_line(running_gen)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class _AnnotateFormatterConnector(Connector[AbstractAnnotateFormatter]):
|
|
30
|
+
name = "AnnotateFormatterConnector"
|
|
31
|
+
ep_name = "annotate_formatter"
|
|
32
|
+
|
|
33
|
+
def _get_default(self) -> type[AbstractAnnotateFormatter]:
|
|
34
|
+
return DefaultAnnotateFormatter
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
annotate_formatter_connector = _AnnotateFormatterConnector()
|
|
@@ -2,15 +2,20 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import abc
|
|
4
4
|
import contextlib
|
|
5
|
+
import re
|
|
5
6
|
import textwrap
|
|
6
|
-
from typing import
|
|
7
|
+
from typing import List, Union
|
|
7
8
|
|
|
8
9
|
from annet import tracing
|
|
9
|
-
from annet.vendors import tabparser
|
|
10
10
|
from annet.tracing import tracing_connector
|
|
11
|
+
from annet.vendors import tabparser
|
|
12
|
+
|
|
11
13
|
from .exceptions import InvalidValueFromGenerator
|
|
12
14
|
|
|
13
15
|
|
|
16
|
+
NONE_SEARCHER = re.compile(r"\bNone\b")
|
|
17
|
+
|
|
18
|
+
|
|
14
19
|
class DefaultBlockIfCondition:
|
|
15
20
|
pass
|
|
16
21
|
|
|
@@ -53,11 +58,15 @@ def _split_and_strip(text):
|
|
|
53
58
|
# =====
|
|
54
59
|
class BaseGenerator:
|
|
55
60
|
TYPE: str
|
|
56
|
-
TAGS: List[str]
|
|
61
|
+
TAGS: List[str] = []
|
|
57
62
|
|
|
58
63
|
def supports_device(self, device) -> bool: # pylint: disable=unused-argument
|
|
59
64
|
return True
|
|
60
65
|
|
|
66
|
+
@classmethod
|
|
67
|
+
def get_aliases(cls) -> set[str]:
|
|
68
|
+
return {cls.__name__, *cls.TAGS}
|
|
69
|
+
|
|
61
70
|
|
|
62
71
|
class TreeGenerator(BaseGenerator):
|
|
63
72
|
def __init__(self, indent=" "):
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import pkgutil
|
|
4
|
-
import re
|
|
5
4
|
import types
|
|
6
|
-
from typing import FrozenSet, Iterable, List, Optional,
|
|
5
|
+
from typing import FrozenSet, Iterable, List, Optional, Union
|
|
7
6
|
|
|
8
7
|
from annet.lib import flatten, mako_render
|
|
9
8
|
|
|
10
|
-
from .base import BaseGenerator, _filter_str
|
|
11
|
-
from .exceptions import
|
|
9
|
+
from .base import NONE_SEARCHER, BaseGenerator, _filter_str
|
|
10
|
+
from .exceptions import InvalidValueFromGenerator
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
class Entire(BaseGenerator):
|
|
@@ -62,10 +61,6 @@ class Entire(BaseGenerator):
|
|
|
62
61
|
|
|
63
62
|
# =====
|
|
64
63
|
|
|
65
|
-
@classmethod
|
|
66
|
-
def get_aliases(cls) -> Set[str]:
|
|
67
|
-
return {cls.__name__, *cls.TAGS}
|
|
68
|
-
|
|
69
64
|
def __call__(self, device):
|
|
70
65
|
self.__device = device
|
|
71
66
|
parts = []
|
|
@@ -73,15 +68,19 @@ class Entire(BaseGenerator):
|
|
|
73
68
|
if isinstance(run_res, str):
|
|
74
69
|
run_res = (run_res,)
|
|
75
70
|
if run_res is None or not isinstance(run_res, (tuple, types.GeneratorType)):
|
|
76
|
-
raise Exception("generator %s returns %s" % (
|
|
77
|
-
|
|
71
|
+
raise Exception("generator %s returns %s" % (self.__class__.__name__, type(run_res)))
|
|
72
|
+
|
|
78
73
|
for text in run_res:
|
|
79
74
|
if isinstance(text, tuple):
|
|
80
75
|
text = " ".join(map(_filter_str, flatten(text)))
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
if NONE_SEARCHER.search(text):
|
|
77
|
+
raise InvalidValueFromGenerator(
|
|
78
|
+
"Found 'None' in yield result: %s" % text
|
|
79
|
+
)
|
|
83
80
|
parts.append(text)
|
|
81
|
+
|
|
84
82
|
ret = "\n".join(parts)
|
|
85
83
|
if self.ENSURE_END_NEWLINE and not ret.endswith("\n"):
|
|
86
84
|
ret += "\n"
|
|
85
|
+
|
|
87
86
|
return ret
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import contextlib
|
|
4
|
-
from typing import
|
|
5
|
-
Any,
|
|
6
|
-
Dict,
|
|
7
|
-
List,
|
|
8
|
-
Optional,
|
|
9
|
-
Set,
|
|
10
|
-
Union,
|
|
11
|
-
)
|
|
4
|
+
from typing import Any, Optional, Union
|
|
12
5
|
|
|
13
6
|
from annet.storage import Device, Storage
|
|
7
|
+
|
|
14
8
|
from .base import TreeGenerator, _filter_str
|
|
15
9
|
|
|
16
10
|
|
|
@@ -18,13 +12,12 @@ class JSONFragment(TreeGenerator):
|
|
|
18
12
|
"""Generates parts of JSON config file."""
|
|
19
13
|
|
|
20
14
|
TYPE = "JSON_FRAGMENT"
|
|
21
|
-
TAGS: List[str] = []
|
|
22
15
|
|
|
23
16
|
def __init__(self, storage: Storage):
|
|
24
17
|
super().__init__()
|
|
25
18
|
self.storage = storage
|
|
26
|
-
self._json_config:
|
|
27
|
-
self._config_pointer:
|
|
19
|
+
self._json_config: dict[str, Any] = {}
|
|
20
|
+
self._config_pointer: list[str] = []
|
|
28
21
|
|
|
29
22
|
# if two generators edit same file, commands from generator with greater `reload_prio` will be used
|
|
30
23
|
if not hasattr(self, "reload_prio"):
|
|
@@ -36,11 +29,7 @@ class JSONFragment(TreeGenerator):
|
|
|
36
29
|
def path(self, device: Device) -> Optional[str]:
|
|
37
30
|
raise NotImplementedError("Required PATH for JSON_FRAGMENT generator")
|
|
38
31
|
|
|
39
|
-
|
|
40
|
-
def get_aliases(cls) -> Set[str]:
|
|
41
|
-
return {cls.__name__, *cls.TAGS}
|
|
42
|
-
|
|
43
|
-
def acl(self, device: Device) -> Union[str, List[str]]:
|
|
32
|
+
def acl(self, device: Device) -> Union[str, list[str]]:
|
|
44
33
|
"""
|
|
45
34
|
Restrict the generator to a specified ACL using JSON Pointer syntax.
|
|
46
35
|
|
|
@@ -48,7 +37,7 @@ class JSONFragment(TreeGenerator):
|
|
|
48
37
|
"""
|
|
49
38
|
raise NotImplementedError("Required ACL for JSON_FRAGMENT generator")
|
|
50
39
|
|
|
51
|
-
def acl_safe(self, device: Device) -> Union[str,
|
|
40
|
+
def acl_safe(self, device: Device) -> Union[str, list[str]]:
|
|
52
41
|
"""
|
|
53
42
|
Restrict the generator to a specified safe ACL using JSON Pointer syntax.
|
|
54
43
|
|
|
@@ -1,32 +1,23 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
from annet.lib import (
|
|
12
|
-
add_annotation,
|
|
13
|
-
flatten,
|
|
14
|
-
)
|
|
15
|
-
from .base import TreeGenerator, _filter_str
|
|
16
|
-
from .exceptions import NotSupportedDevice
|
|
3
|
+
from typing import Iterable, Union
|
|
4
|
+
|
|
5
|
+
from annet.lib import add_annotation, flatten
|
|
6
|
+
|
|
7
|
+
from .annotate import AbstractAnnotateFormatter, annotate_formatter_connector
|
|
8
|
+
from .base import NONE_SEARCHER, TreeGenerator, _filter_str
|
|
9
|
+
from .exceptions import InvalidValueFromGenerator
|
|
17
10
|
|
|
18
11
|
|
|
19
12
|
class PartialGenerator(TreeGenerator):
|
|
20
13
|
TYPE = "PARTIAL"
|
|
21
|
-
TAGS: List[str] = []
|
|
22
14
|
|
|
23
15
|
def __init__(self, storage):
|
|
24
16
|
super().__init__()
|
|
25
17
|
self.storage = storage
|
|
26
|
-
self._annotate = False
|
|
27
18
|
self._running_gen = None
|
|
19
|
+
self._annotate: AbstractAnnotateFormatter = annotate_formatter_connector.get(self)
|
|
28
20
|
self._annotations = []
|
|
29
|
-
self._annotation_module = self.__class__.__module__ or ""
|
|
30
21
|
|
|
31
22
|
def supports_device(self, device) -> bool:
|
|
32
23
|
if self.__class__.run is PartialGenerator.run:
|
|
@@ -35,19 +26,19 @@ class PartialGenerator(TreeGenerator):
|
|
|
35
26
|
return True
|
|
36
27
|
|
|
37
28
|
def acl(self, device):
|
|
38
|
-
acl_func
|
|
39
|
-
if acl_func:
|
|
29
|
+
if acl_func := self._get_vendor_func(device.hw.vendor, "acl"):
|
|
40
30
|
return acl_func(device)
|
|
31
|
+
return None
|
|
41
32
|
|
|
42
33
|
def acl_safe(self, device):
|
|
43
|
-
acl_func
|
|
44
|
-
if acl_func:
|
|
34
|
+
if acl_func := self._get_vendor_func(device.hw.vendor, "acl_safe"):
|
|
45
35
|
return acl_func(device)
|
|
36
|
+
return None
|
|
46
37
|
|
|
47
|
-
def run(self, device) -> Iterable[Union[str, tuple]]:
|
|
48
|
-
run_func
|
|
49
|
-
if run_func:
|
|
38
|
+
def run(self, device) -> Iterable[Union[str, tuple]] | None:
|
|
39
|
+
if run_func := self._get_vendor_func(device.hw.vendor, "run"):
|
|
50
40
|
return run_func(device)
|
|
41
|
+
return None
|
|
51
42
|
|
|
52
43
|
def get_user_runner(self, device):
|
|
53
44
|
if self.__class__.run is not PartialGenerator.run:
|
|
@@ -56,26 +47,15 @@ class PartialGenerator(TreeGenerator):
|
|
|
56
47
|
|
|
57
48
|
def _get_vendor_func(self, vendor: str, func_name: str):
|
|
58
49
|
attr_name = f"{func_name}_{vendor}"
|
|
59
|
-
|
|
60
|
-
return getattr(self, attr_name)
|
|
61
|
-
return None
|
|
50
|
+
return getattr(self, attr_name, None)
|
|
62
51
|
|
|
63
52
|
# =====
|
|
64
53
|
|
|
65
|
-
|
|
66
|
-
def get_aliases(cls) -> Set[str]:
|
|
67
|
-
return {cls.__name__, *cls.TAGS}
|
|
68
|
-
|
|
69
|
-
def __call__(self, device, annotate=False):
|
|
54
|
+
def __call__(self, device, annotate: bool = False):
|
|
70
55
|
self._indents = []
|
|
71
56
|
self._rows = []
|
|
72
|
-
self._running_gen = self.run(device)
|
|
73
|
-
self._annotate = annotate
|
|
74
|
-
|
|
75
|
-
if annotate and self.__class__.__module__:
|
|
76
|
-
self._annotation_module = ".".join(
|
|
77
|
-
self.__class__.__module__.split(".")[-2:])
|
|
78
57
|
|
|
58
|
+
self._running_gen = self.run(device)
|
|
79
59
|
for text in self._running_gen:
|
|
80
60
|
if isinstance(text, tuple):
|
|
81
61
|
text = " ".join(map(_filter_str, flatten(text)))
|
|
@@ -83,9 +63,12 @@ class PartialGenerator(TreeGenerator):
|
|
|
83
63
|
text = _filter_str(text)
|
|
84
64
|
self._append_text(text)
|
|
85
65
|
|
|
86
|
-
for row in self._rows:
|
|
87
|
-
|
|
88
|
-
|
|
66
|
+
for (row, annotation) in zip(self._rows, self._annotations):
|
|
67
|
+
if NONE_SEARCHER.search(row):
|
|
68
|
+
raise InvalidValueFromGenerator(
|
|
69
|
+
"Found 'None' in yield result: %s" % add_annotation(row, annotation)
|
|
70
|
+
)
|
|
71
|
+
|
|
89
72
|
if annotate:
|
|
90
73
|
generated_rows = (
|
|
91
74
|
add_annotation(x, y)
|
|
@@ -93,23 +76,20 @@ class PartialGenerator(TreeGenerator):
|
|
|
93
76
|
)
|
|
94
77
|
else:
|
|
95
78
|
generated_rows = self._rows
|
|
96
|
-
|
|
79
|
+
|
|
80
|
+
return "\n".join((*generated_rows, ""))
|
|
97
81
|
|
|
98
82
|
def _append_text(self, text):
|
|
99
83
|
def annotation_cb(row):
|
|
100
|
-
|
|
101
|
-
|
|
84
|
+
self._annotations.append(
|
|
85
|
+
self._annotate.make_annotation(self._running_gen)
|
|
86
|
+
)
|
|
102
87
|
return row
|
|
103
88
|
|
|
104
|
-
self._append_text_cb(
|
|
105
|
-
text,
|
|
106
|
-
annotation_cb if self._annotate else None
|
|
107
|
-
)
|
|
89
|
+
self._append_text_cb(text, row_cb=annotation_cb)
|
|
108
90
|
|
|
109
|
-
def get_running_line(self):
|
|
110
|
-
|
|
111
|
-
return (repr(self._running_gen), -1)
|
|
112
|
-
return self._annotation_module, self._running_gen.gi_frame.f_lineno
|
|
91
|
+
def get_running_line(self) -> tuple[str, int]:
|
|
92
|
+
return self._annotate.get_running_line(self._running_gen)
|
|
113
93
|
|
|
114
94
|
@classmethod
|
|
115
95
|
def literal(cls, item):
|
|
@@ -2,19 +2,10 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import textwrap
|
|
4
4
|
from collections import OrderedDict as odict
|
|
5
|
-
from typing import
|
|
6
|
-
Any,
|
|
7
|
-
Callable,
|
|
8
|
-
Dict,
|
|
9
|
-
Optional,
|
|
10
|
-
Sequence,
|
|
11
|
-
Tuple,
|
|
12
|
-
)
|
|
5
|
+
from typing import Any, Callable, Optional, Sequence
|
|
13
6
|
|
|
14
7
|
from annet.annlib import jsontools
|
|
15
|
-
from annet.lib import
|
|
16
|
-
merge_dicts,
|
|
17
|
-
)
|
|
8
|
+
from annet.lib import merge_dicts
|
|
18
9
|
from annet.reference import RefMatcher, RefTracker
|
|
19
10
|
from annet.types import (
|
|
20
11
|
GeneratorEntireResult,
|
|
@@ -24,7 +15,7 @@ from annet.types import (
|
|
|
24
15
|
|
|
25
16
|
|
|
26
17
|
def _combine_acl_text(
|
|
27
|
-
partial_results:
|
|
18
|
+
partial_results: dict[str, GeneratorPartialResult],
|
|
28
19
|
acl_getter: Callable[[GeneratorPartialResult], str]
|
|
29
20
|
) -> str:
|
|
30
21
|
acl_text = ""
|
|
@@ -43,9 +34,9 @@ class RunGeneratorResult:
|
|
|
43
34
|
"""
|
|
44
35
|
|
|
45
36
|
def __init__(self):
|
|
46
|
-
self.partial_results:
|
|
47
|
-
self.entire_results:
|
|
48
|
-
self.json_fragment_results:
|
|
37
|
+
self.partial_results: dict[str, GeneratorPartialResult] = {}
|
|
38
|
+
self.entire_results: dict[str, GeneratorEntireResult] = {}
|
|
39
|
+
self.json_fragment_results: dict[str, GeneratorJSONFragmentResult] = {}
|
|
49
40
|
self.ref_track: RefTracker = RefTracker()
|
|
50
41
|
self.ref_matcher: RefMatcher = RefMatcher()
|
|
51
42
|
|
|
@@ -62,14 +53,14 @@ class RunGeneratorResult:
|
|
|
62
53
|
def add_json_fragment(self, result: GeneratorJSONFragmentResult) -> None:
|
|
63
54
|
self.json_fragment_results[result.name] = result
|
|
64
55
|
|
|
65
|
-
def config_tree(self, safe: bool = False) ->
|
|
56
|
+
def config_tree(self, safe: bool = False) -> dict[str, Any]: # OrderedDict
|
|
66
57
|
tree = odict()
|
|
67
58
|
for gr in self.partial_results.values():
|
|
68
59
|
config = gr.safe_config if safe else gr.config
|
|
69
60
|
tree = merge_dicts(tree, config)
|
|
70
61
|
return tree
|
|
71
62
|
|
|
72
|
-
def new_files(self, safe: bool = False) ->
|
|
63
|
+
def new_files(self, safe: bool = False) -> dict[str, tuple[str, str]]:
|
|
73
64
|
files = {}
|
|
74
65
|
for gr in self.entire_results.values():
|
|
75
66
|
if not safe or gr.is_safe:
|
|
@@ -84,14 +75,14 @@ class RunGeneratorResult:
|
|
|
84
75
|
|
|
85
76
|
def new_json_fragment_files(
|
|
86
77
|
self,
|
|
87
|
-
old_files:
|
|
78
|
+
old_files: dict[str, Optional[str]],
|
|
88
79
|
use_acl: bool = True,
|
|
89
80
|
safe: bool = False,
|
|
90
81
|
filters: Sequence[str] | None = None,
|
|
91
|
-
) ->
|
|
82
|
+
) -> dict[str, tuple[Any, Optional[str]]]:
|
|
92
83
|
# TODO: safe
|
|
93
|
-
files:
|
|
94
|
-
reload_prios:
|
|
84
|
+
files: dict[str, tuple[Any, Optional[str]]] = {}
|
|
85
|
+
reload_prios: dict[str, int] = {}
|
|
95
86
|
for generator_result in self.json_fragment_results.values():
|
|
96
87
|
filepath = generator_result.path
|
|
97
88
|
if filepath not in files:
|
|
@@ -105,7 +96,7 @@ class RunGeneratorResult:
|
|
|
105
96
|
result_acl = generator_result.acl_safe
|
|
106
97
|
else:
|
|
107
98
|
result_acl = None
|
|
108
|
-
previous_config:
|
|
99
|
+
previous_config: dict[str, Any] = files[filepath][0]
|
|
109
100
|
new_fragment = generator_result.config
|
|
110
101
|
new_config = jsontools.apply_json_fragment(
|
|
111
102
|
previous_config, new_fragment,
|
|
@@ -126,7 +117,7 @@ class RunGeneratorResult:
|
|
|
126
117
|
files[filepath] = (new_config, reload_cmd)
|
|
127
118
|
return files
|
|
128
119
|
|
|
129
|
-
def perf_mesures(self) ->
|
|
120
|
+
def perf_mesures(self) -> dict[str, dict[str, int]]:
|
|
130
121
|
mesures = {}
|
|
131
122
|
for gr in self.partial_results.values():
|
|
132
123
|
mesures[gr.name] = {"total": gr.perf.total,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|