pyarmor 8.0.7__zip → 8.0.9__zip
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 pyarmor might be problematic. Click here for more details.
- {pyarmor-8.0.7 → pyarmor-8.0.9}/PKG-INFO +1 -1
- {pyarmor-8.0.7 → pyarmor-8.0.9}/README.md +8 -8
- {pyarmor-8.0.7 → pyarmor-8.0.9}/pyarmor.egg-info/PKG-INFO +1 -1
- {pyarmor-8.0.7 → pyarmor-8.0.9}/pyarmor.egg-info/SOURCES.txt +5 -1
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/context.py +1 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/default.cfg +1 -1
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/config.py +1 -1
- pyarmor-8.0.9/src/platforms/darwin/x86_64/_pytransform.dylib +0 -0
- pyarmor-8.0.9/src/platforms/linux/x86/_pytransform.so +0 -0
- pyarmor-8.0.9/src/platforms/linux/x86_64/_pytransform.so +0 -0
- pyarmor-8.0.9/src/platforms/windows/x86/_pytransform.dll +0 -0
- pyarmor-8.0.9/src/platforms/windows/x86_64/_pytransform.dll +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/pyarmor.py +4 -1
- pyarmor-8.0.7/src/cli/ruler.py +0 -659
- {pyarmor-8.0.7 → pyarmor-8.0.9}/MANIFEST.in +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/pyarmor.egg-info/dependency_links.txt +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/pyarmor.egg-info/entry_points.txt +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/pyarmor.egg-info/requires.txt +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/pyarmor.egg-info/top_level.txt +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/setup.cfg +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/setup.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/README.rst +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/__init__.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/__main__.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/benchmark.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/build_meta.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/__init__.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/__main__.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/config.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/errors.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/generate.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/mixer.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/register.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/repack.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/resource.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cli/shell.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/cobuilder.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/README-ZH.md +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/README.md +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/build-for-exe.bat +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/build-for-freeze.bat +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/build-with-project.bat +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/build-with-project.sh +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/cx_Freeze/hello.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/cx_Freeze/queens.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/cx_Freeze/setup.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/helloworld/foo.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/obfuscate-app.bat +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/obfuscate-app.sh +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/obfuscate-pkg.bat +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/obfuscate-pkg.sh +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pack-obfuscated-scripts.bat +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pack-obfuscated-scripts.sh +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/py2exe/hello.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/py2exe/queens.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/py2exe/setup.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Arithmetic.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Calls.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/CommandLine.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Constructs.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Dict.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Exceptions.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Imports.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Instances.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Lists.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Lookups.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/NewInstances.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Numbers.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Setup.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Strings.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/Tuples.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/With.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/clockres.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/package/__init__.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/package/submodule.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/pybench.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/pybench/systimes.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/simple/queens.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/testmod/hello.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/testmod/queens.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/testpkg/main.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/testpkg/mypkg/__init__.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/examples/testpkg/mypkg/foo.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/helper/__init__.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/helper/build_data_module.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/helper/buildext.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/helper/get_bind_key.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/helper/get_license_info.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/helper/get_platform_name.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/helper/merge.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/helper/repack.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/helper/superuntime.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/license.tri +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/packer.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/plugins/README.md +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/plugins/check_ntp_time.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/polyfills/__init__.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/polyfills/argparse.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/product.key +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/project.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/protect_code.pt +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/protect_code2.pt +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/public.key +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/public_capsule.zip +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/pyarmor-webui.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/pyshield.key +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/pyshield.lic +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/pytransform.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/reform.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/register.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/sppmode.py +0 -0
- {pyarmor-8.0.7 → pyarmor-8.0.9}/src/utils.py +0 -0
|
@@ -51,7 +51,7 @@ Run it
|
|
|
51
51
|
|
|
52
52
|
Also look at the [getting started][tutorial]
|
|
53
53
|
|
|
54
|
-
[tutorial]: https://pyarmor.readthedocs.io/en/
|
|
54
|
+
[tutorial]: https://pyarmor.readthedocs.io/en/stable/tutorial/getting-started.html
|
|
55
55
|
|
|
56
56
|
## License
|
|
57
57
|
|
|
@@ -63,7 +63,7 @@ limitations for each license type and how to purchase Pyarmor license.
|
|
|
63
63
|
|
|
64
64
|
Also read [EULA of Pyarmor](LICENSE)
|
|
65
65
|
|
|
66
|
-
[licenses]: https://pyarmor.readthedocs.io/en/
|
|
66
|
+
[licenses]: https://pyarmor.readthedocs.io/en/stable/licenses.html
|
|
67
67
|
|
|
68
68
|
## Getting help
|
|
69
69
|
|
|
@@ -82,12 +82,12 @@ Not found anything? See [asking questions in github][asking].
|
|
|
82
82
|
|
|
83
83
|
Send email to <pyarmor@163.com> for business and security issue.
|
|
84
84
|
|
|
85
|
-
[faq]: https://pyarmor.readthedocs.io/en/
|
|
85
|
+
[faq]: https://pyarmor.readthedocs.io/en/stable/questions.html
|
|
86
86
|
[issues]: https://github.com/dashingsoft/pyarmor/issues
|
|
87
|
-
[genindex]: https://pyarmor.readthedocs.io/en/
|
|
88
|
-
[mastertoc]: https://pyarmor.readthedocs.io/en/
|
|
89
|
-
[asking]: https://pyarmor.readthedocs.io/en/
|
|
90
|
-
[doc]: https://pyarmor.readthedocs.io/en/
|
|
87
|
+
[genindex]: https://pyarmor.readthedocs.io/en/stable/genindex.html
|
|
88
|
+
[mastertoc]: https://pyarmor.readthedocs.io/en/stable/index.html#table-of-contents
|
|
89
|
+
[asking]: https://pyarmor.readthedocs.io/en/stable/questions.html#asking-questions-in-github
|
|
90
|
+
[doc]: https://pyarmor.readthedocs.io/en/stable/
|
|
91
91
|
|
|
92
92
|
## Resources
|
|
93
93
|
|
|
@@ -98,7 +98,7 @@ Send email to <pyarmor@163.com> for business and security issue.
|
|
|
98
98
|
中文资源
|
|
99
99
|
|
|
100
100
|
* [Pyarmor 网站](https://pyarmor.dashingsoft.com/index-zh.html)
|
|
101
|
-
* [Pyarmor 8.0 在线文档](https://pyarmor.readthedocs.io/zh/
|
|
101
|
+
* [Pyarmor 8.0 在线文档](https://pyarmor.readthedocs.io/zh/stable/)
|
|
102
102
|
* [Pyarmor 7.x 在线文档](https://pyarmor.readthedocs.io/zh/v7.x/))
|
|
103
103
|
|
|
104
104
|
## Change logs
|
|
@@ -42,7 +42,6 @@ src/cli/mixer.py
|
|
|
42
42
|
src/cli/register.py
|
|
43
43
|
src/cli/repack.py
|
|
44
44
|
src/cli/resource.py
|
|
45
|
-
src/cli/ruler.py
|
|
46
45
|
src/cli/shell.py
|
|
47
46
|
src/examples/README-ZH.md
|
|
48
47
|
src/examples/README.md
|
|
@@ -99,6 +98,11 @@ src/helper/get_platform_name.py
|
|
|
99
98
|
src/helper/merge.py
|
|
100
99
|
src/helper/repack.py
|
|
101
100
|
src/helper/superuntime.py
|
|
101
|
+
src/platforms/darwin/x86_64/_pytransform.dylib
|
|
102
|
+
src/platforms/linux/x86/_pytransform.so
|
|
103
|
+
src/platforms/linux/x86_64/_pytransform.so
|
|
104
|
+
src/platforms/windows/x86/_pytransform.dll
|
|
105
|
+
src/platforms/windows/x86_64/_pytransform.dll
|
|
102
106
|
src/plugins/README.md
|
|
103
107
|
src/plugins/check_ntp_time.py
|
|
104
108
|
src/polyfills/__init__.py
|
|
@@ -260,6 +260,7 @@ class Context(object):
|
|
|
260
260
|
from shutil import copy
|
|
261
261
|
path = os.path.dirname(__file__)
|
|
262
262
|
public_capsule = os.path.join(path, '..', 'public_capsule.zip')
|
|
263
|
+
os.makedirs(self.reg_path, exist_ok=True)
|
|
263
264
|
copy(public_capsule, filename)
|
|
264
265
|
return filename
|
|
265
266
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1619,8 +1619,11 @@ def call_pyarmor_cli():
|
|
|
1619
1619
|
|
|
1620
1620
|
def find_cli_command(argv):
|
|
1621
1621
|
args = argv[1:6]
|
|
1622
|
+
if set(['hdinfo', 'download', 'info', 'init']).intersection(args):
|
|
1623
|
+
return False
|
|
1624
|
+
|
|
1622
1625
|
cmds = 'generate', 'gen', 'g', 'register', 'reg', 'r', 'cfg'
|
|
1623
|
-
return not args or len(args) < 2 or set(cmds).intersection(args)
|
|
1626
|
+
return (not args) or len(args) < 2 or set(cmds).intersection(args)
|
|
1624
1627
|
|
|
1625
1628
|
|
|
1626
1629
|
def main_entry_8():
|
pyarmor-8.0.7/src/cli/ruler.py
DELETED
|
@@ -1,659 +0,0 @@
|
|
|
1
|
-
#! /usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
#
|
|
4
|
-
#############################################################
|
|
5
|
-
# #
|
|
6
|
-
# Copyright @ 2023 - Dashingsoft corp. #
|
|
7
|
-
# All rights reserved. #
|
|
8
|
-
# #
|
|
9
|
-
# Pyarmor #
|
|
10
|
-
# #
|
|
11
|
-
# Version: 8.0.1 - #
|
|
12
|
-
# #
|
|
13
|
-
#############################################################
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
# @File: cli/ruler.py
|
|
17
|
-
#
|
|
18
|
-
# @Author: Jondy Zhao (pyarmor@163.com)
|
|
19
|
-
#
|
|
20
|
-
# @Create Date: Tue Feb 7 10:46:47 CST 2023
|
|
21
|
-
#
|
|
22
|
-
|
|
23
|
-
# Start of source code
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
import ast
|
|
27
|
-
import re
|
|
28
|
-
|
|
29
|
-
from fnmatch import fnmatchcase
|
|
30
|
-
from json import dumps as json_dumps
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
SCOPE_NODE_TYPES = ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def abs_name(qualname, name, level=0):
|
|
37
|
-
if not level:
|
|
38
|
-
return name
|
|
39
|
-
if qualname.count('.') < level:
|
|
40
|
-
raise RuntimeError('relative import overflow')
|
|
41
|
-
return '.'.join(qualname.split('.')[:-level] + ([name] if name else []))
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def apply_rule(name, rule):
|
|
45
|
-
'''Return True if name matches rule, otherwise False
|
|
46
|
-
|
|
47
|
-
>>> apply_rule('abc', '*c')
|
|
48
|
-
True
|
|
49
|
-
>>> apply_rule('abc', 'ab*')
|
|
50
|
-
True
|
|
51
|
-
>>> apply_rule('abc', 'a*c')
|
|
52
|
-
True
|
|
53
|
-
>>> apply_rule('abc', '/[a-z]+/')
|
|
54
|
-
True
|
|
55
|
-
>>> apply_rule('abc', 'xyz abc 123')
|
|
56
|
-
True
|
|
57
|
-
>>> apply_rule('abc', 'abc')
|
|
58
|
-
True
|
|
59
|
-
>>> apply_rule('abc', 'a b c')
|
|
60
|
-
False
|
|
61
|
-
'''
|
|
62
|
-
|
|
63
|
-
if rule.startswith('*'):
|
|
64
|
-
return name.endswith(rule[1:])
|
|
65
|
-
elif rule.endswith('*'):
|
|
66
|
-
return name.startswith(rule[:-1])
|
|
67
|
-
elif rule.startswith('/'):
|
|
68
|
-
return bool(re.match(rule[1:-1], name))
|
|
69
|
-
elif rule.find(' ') > 0:
|
|
70
|
-
return name in rule.split()
|
|
71
|
-
else:
|
|
72
|
-
return fnmatchcase(name, rule)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def check_rules(value, includes, excludes):
|
|
76
|
-
return ((not includes or any([apply_rule(x, value) for x in includes]))
|
|
77
|
-
and not any([apply_rule(x, value) for x in excludes]))
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
class Visitor(object):
|
|
81
|
-
'''Travel each ndoe with its ancestors in stack
|
|
82
|
-
|
|
83
|
-
>>> tree = ast.parse('a = b')
|
|
84
|
-
|
|
85
|
-
>>> def show(item):
|
|
86
|
-
... node, attr = item[:2]
|
|
87
|
-
... s = type(node).__name__ + '.' + attr
|
|
88
|
-
... if len(item) == 3:
|
|
89
|
-
... s += '[%d]' % item[2]
|
|
90
|
-
... return s
|
|
91
|
-
|
|
92
|
-
>>> visitor = Visitor(tree)
|
|
93
|
-
>>> for node in visitor.travel():
|
|
94
|
-
... print('visit node:', type(node).__name__)
|
|
95
|
-
... print('ancestors: ', [show(x) for x in visitor._stack])
|
|
96
|
-
visit node: Assign
|
|
97
|
-
ancestors: ['Module.body[0]']
|
|
98
|
-
visit node: Name
|
|
99
|
-
ancestors: ['Module.body[0]', 'Assign.targets[0]']
|
|
100
|
-
visit node: Name
|
|
101
|
-
ancestors: ['Module.body[0]', 'Assign.value']
|
|
102
|
-
'''
|
|
103
|
-
|
|
104
|
-
def __init__(self, tree):
|
|
105
|
-
self._tree = tree
|
|
106
|
-
self._stack = []
|
|
107
|
-
|
|
108
|
-
@property
|
|
109
|
-
def stack(self):
|
|
110
|
-
return [x for x in self._stack if isinstance(x, SCOPE_NODE_TYPES)]
|
|
111
|
-
|
|
112
|
-
@property
|
|
113
|
-
def domain(self):
|
|
114
|
-
return '.'.join([x[0].name for x in self.stack])
|
|
115
|
-
|
|
116
|
-
@property
|
|
117
|
-
def top(self, n=0):
|
|
118
|
-
return self._stack[-n - 1]
|
|
119
|
-
|
|
120
|
-
def travel(self, ignored=None):
|
|
121
|
-
|
|
122
|
-
def visit(node):
|
|
123
|
-
for attr, child in ast.iter_fields(node):
|
|
124
|
-
if attr in ('ctx',):
|
|
125
|
-
continue
|
|
126
|
-
|
|
127
|
-
if ignored and isinstance(child, ignored):
|
|
128
|
-
continue
|
|
129
|
-
|
|
130
|
-
if isinstance(child, ast.AST):
|
|
131
|
-
self._stack.append((node, attr))
|
|
132
|
-
yield child
|
|
133
|
-
for x in visit(child):
|
|
134
|
-
yield x
|
|
135
|
-
self._stack.pop()
|
|
136
|
-
|
|
137
|
-
elif isinstance(child, list):
|
|
138
|
-
index = 0
|
|
139
|
-
for item in child:
|
|
140
|
-
if isinstance(item, ast.AST):
|
|
141
|
-
self._stack.append((node, attr, index))
|
|
142
|
-
yield item
|
|
143
|
-
for x in visit(item):
|
|
144
|
-
yield x
|
|
145
|
-
self._stack.pop()
|
|
146
|
-
index += 1
|
|
147
|
-
|
|
148
|
-
for x in visit(self._tree):
|
|
149
|
-
yield x
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
class Ruler(object):
|
|
153
|
-
|
|
154
|
-
def __init__(self, includes, excludes):
|
|
155
|
-
self._includes = includes if includes else []
|
|
156
|
-
self._excludes = excludes if excludes else []
|
|
157
|
-
|
|
158
|
-
def check(self, value):
|
|
159
|
-
return check_rules(value, self._includes, self._excludes)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
class NodeRuler(Ruler):
|
|
163
|
-
|
|
164
|
-
def __init__(self, includes, excludes, visitor=None):
|
|
165
|
-
super().__init__(includes, excludes)
|
|
166
|
-
self._visitor = visitor
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
# Unused but reserved
|
|
170
|
-
def _check_node_rule(node, qualname, rule):
|
|
171
|
-
n = rule.find(':')
|
|
172
|
-
rscope = '' if n == -1 else rule[:n]
|
|
173
|
-
rname = rule[n+1:]
|
|
174
|
-
|
|
175
|
-
if qualname.startswith(rscope) or \
|
|
176
|
-
(rscope[:1] == '@' and node.lineno == int(rscope[1:])):
|
|
177
|
-
callee_name = get_node_name(node)
|
|
178
|
-
if callee_name is None:
|
|
179
|
-
return False
|
|
180
|
-
if rname[0] == '=':
|
|
181
|
-
return rname[1:] == callee_name
|
|
182
|
-
elif rname[0] == '+':
|
|
183
|
-
return callee_name.startswith(rname)
|
|
184
|
-
elif rname[0] == '-':
|
|
185
|
-
return callee_name.endswith(rname[1:])
|
|
186
|
-
elif rname[0] == '*':
|
|
187
|
-
# TBD: auto mode
|
|
188
|
-
return False
|
|
189
|
-
elif rname[0] == '/':
|
|
190
|
-
return callee_name.find(rname[1:]) > -1
|
|
191
|
-
elif rname[0] == '?':
|
|
192
|
-
return re.search(rname[:1], callee_name) is not None
|
|
193
|
-
else:
|
|
194
|
-
return callee_name in rname.split()
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
############################################################
|
|
198
|
-
#
|
|
199
|
-
# Define classes and functions for module types
|
|
200
|
-
#
|
|
201
|
-
############################################################
|
|
202
|
-
|
|
203
|
-
class Dict(dict):
|
|
204
|
-
|
|
205
|
-
def __getattr__(self, attr):
|
|
206
|
-
if attr in self._FIELDS:
|
|
207
|
-
return self[attr]
|
|
208
|
-
raise AttributeError(attr)
|
|
209
|
-
|
|
210
|
-
def __eq__(self, a):
|
|
211
|
-
return self.name == a.name and self.cls == a.cls
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
class Field(Dict):
|
|
215
|
-
|
|
216
|
-
_FIELDS = 'name', 'cls'
|
|
217
|
-
|
|
218
|
-
def __init__(self, name, cls='', private=0):
|
|
219
|
-
super().__init__(name=name, cls=cls)
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
class Type(Dict):
|
|
223
|
-
|
|
224
|
-
_FIELDS = 'name', 'cls', 'fields', 'privates', 'imports'
|
|
225
|
-
|
|
226
|
-
def __init__(self, name, cls='class'):
|
|
227
|
-
super().__init__(name=name, cls=cls, fields=[], imports={})
|
|
228
|
-
|
|
229
|
-
def append(self, field):
|
|
230
|
-
if field and field not in self.fields:
|
|
231
|
-
self.fields.append(field)
|
|
232
|
-
|
|
233
|
-
def find(self, name):
|
|
234
|
-
for x in self.fields:
|
|
235
|
-
if name == x.name:
|
|
236
|
-
return x
|
|
237
|
-
for x in self.imports:
|
|
238
|
-
if x == name:
|
|
239
|
-
return self.imports[x]
|
|
240
|
-
|
|
241
|
-
def imp_node(self, node, qualname=''):
|
|
242
|
-
if isinstance(node, ast.Import):
|
|
243
|
-
for x in node.names:
|
|
244
|
-
asname = x.asname if x.asname else x.name
|
|
245
|
-
self.imports[asname] = Field(x.name, 'module')
|
|
246
|
-
|
|
247
|
-
elif isinstance(node, ast.ImportFrom):
|
|
248
|
-
pkgname = '.' * node.level + node.module if node.module else ''
|
|
249
|
-
for x in node.names:
|
|
250
|
-
asname = x.asname if x.asname else x.name
|
|
251
|
-
self.imports[asname] = Field(pkgname + ',' + x.name, '?')
|
|
252
|
-
|
|
253
|
-
def add_node(self, node):
|
|
254
|
-
name = node.id if isinstance(node, ast.Name) else \
|
|
255
|
-
node.name if isinstance(node, SCOPE_NODE_TYPES) else \
|
|
256
|
-
None
|
|
257
|
-
if name:
|
|
258
|
-
cls = '' if isinstance(node, ast.Name) else \
|
|
259
|
-
'class' if isinstance(node, ast.ClassDef) else \
|
|
260
|
-
'function' if isinstance(node, ast.FunctionDef) else \
|
|
261
|
-
'asyncfunction'
|
|
262
|
-
self.append(Field(name, cls))
|
|
263
|
-
|
|
264
|
-
def extend(self, fields):
|
|
265
|
-
for x in fields:
|
|
266
|
-
if isinstance(x, ast.AST):
|
|
267
|
-
self.add_node(x)
|
|
268
|
-
continue
|
|
269
|
-
|
|
270
|
-
self.append(x if isinstance(x, Field) else
|
|
271
|
-
Field(x) if isinstance(x, str) else
|
|
272
|
-
None)
|
|
273
|
-
|
|
274
|
-
def __str__(self):
|
|
275
|
-
return json_dumps(self, indent=2)
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
class ModuleInfo(object):
|
|
279
|
-
|
|
280
|
-
def __init__(self, name=None, node=None, co=None):
|
|
281
|
-
self._name = name
|
|
282
|
-
self._node = node
|
|
283
|
-
self._co = co
|
|
284
|
-
|
|
285
|
-
def reset(self, name=None, node=None, co=None):
|
|
286
|
-
self._name = name
|
|
287
|
-
self._node = node
|
|
288
|
-
self._co = co
|
|
289
|
-
|
|
290
|
-
@property
|
|
291
|
-
def module_types(self):
|
|
292
|
-
return self._get_module_types(self._name, self._node)
|
|
293
|
-
|
|
294
|
-
@property
|
|
295
|
-
def using_modules(self):
|
|
296
|
-
return self._get_using_modules(self._name, self._node)
|
|
297
|
-
|
|
298
|
-
def _search_class_attrs(self, func):
|
|
299
|
-
func_attrs = set()
|
|
300
|
-
|
|
301
|
-
def visit(node):
|
|
302
|
-
if isinstance(node, ast.Assign):
|
|
303
|
-
for target in node.targets:
|
|
304
|
-
if isinstance(target, ast.Attribute):
|
|
305
|
-
stack = []
|
|
306
|
-
while isinstance(target, ast.Attribute):
|
|
307
|
-
stack.insert(0, target.attr)
|
|
308
|
-
target = target.value
|
|
309
|
-
if isinstance(target, ast.Name):
|
|
310
|
-
if target.id == prefix:
|
|
311
|
-
func_attrs.add(stack[0])
|
|
312
|
-
|
|
313
|
-
elif isinstance(node, SCOPE_NODE_TYPES):
|
|
314
|
-
func_attrs.add(node)
|
|
315
|
-
|
|
316
|
-
else:
|
|
317
|
-
for child in ast.iter_child_nodes(node):
|
|
318
|
-
visit(child)
|
|
319
|
-
|
|
320
|
-
prefix = func.args.args[0].arg if func.args.args else '@'
|
|
321
|
-
for x in func.body:
|
|
322
|
-
visit(x)
|
|
323
|
-
return func_attrs
|
|
324
|
-
|
|
325
|
-
def _get_module_types(self, qualname, tree):
|
|
326
|
-
module_types = {}
|
|
327
|
-
scope = []
|
|
328
|
-
|
|
329
|
-
def prepare(node):
|
|
330
|
-
if isinstance(node, SCOPE_NODE_TYPES):
|
|
331
|
-
key = '.'.join(scope)
|
|
332
|
-
if key in module_types:
|
|
333
|
-
module_types[key].add_node(node)
|
|
334
|
-
|
|
335
|
-
scope.append(node.name)
|
|
336
|
-
|
|
337
|
-
if isinstance(node, ast.ClassDef):
|
|
338
|
-
key = '.'.join(scope)
|
|
339
|
-
# TBD: ? duplicated class names in one script
|
|
340
|
-
module_types[key] = Type(key)
|
|
341
|
-
|
|
342
|
-
for child in ast.iter_child_nodes(node):
|
|
343
|
-
prepare(child)
|
|
344
|
-
|
|
345
|
-
if isinstance(node, SCOPE_NODE_TYPES):
|
|
346
|
-
scope.pop()
|
|
347
|
-
|
|
348
|
-
def visit(node):
|
|
349
|
-
if isinstance(node, ast.Assign):
|
|
350
|
-
key = '.'.join(scope)
|
|
351
|
-
if key in module_types:
|
|
352
|
-
for target in node.targets:
|
|
353
|
-
if isinstance(target, ast.Name):
|
|
354
|
-
module_types[key].add_node(target)
|
|
355
|
-
|
|
356
|
-
elif isinstance(node, ast.Import):
|
|
357
|
-
key = '.'.join(scope)
|
|
358
|
-
if key in module_types:
|
|
359
|
-
module_types[key].imp_node(node)
|
|
360
|
-
|
|
361
|
-
elif isinstance(node, ast.ImportFrom):
|
|
362
|
-
key = '.'.join(scope)
|
|
363
|
-
if key in module_types:
|
|
364
|
-
# TBD: node.names = ['*']
|
|
365
|
-
module_types[key].imp_node(node, qualname)
|
|
366
|
-
|
|
367
|
-
elif isinstance(node, SCOPE_NODE_TYPES):
|
|
368
|
-
key = '.'.join(scope)
|
|
369
|
-
scope.append(node.name)
|
|
370
|
-
if key != qualname and key in module_types \
|
|
371
|
-
and hasattr(node, 'func') and hasattr(node, 'args') \
|
|
372
|
-
and 'staticmethod' not in node.decorator_list:
|
|
373
|
-
module_types[key].extend(self._search_class_attrs(node))
|
|
374
|
-
|
|
375
|
-
for child in ast.iter_child_nodes(node):
|
|
376
|
-
visit(child)
|
|
377
|
-
|
|
378
|
-
if isinstance(node, SCOPE_NODE_TYPES):
|
|
379
|
-
scope.pop()
|
|
380
|
-
|
|
381
|
-
module_types[qualname] = Type(qualname, cls='module')
|
|
382
|
-
scope = [qualname]
|
|
383
|
-
prepare(tree)
|
|
384
|
-
|
|
385
|
-
scope = [qualname]
|
|
386
|
-
visit(tree)
|
|
387
|
-
|
|
388
|
-
return module_types
|
|
389
|
-
|
|
390
|
-
def _get_using_modules(self, qualname, tree):
|
|
391
|
-
using_modules = set()
|
|
392
|
-
|
|
393
|
-
def visit(node):
|
|
394
|
-
if isinstance(node, ast.Import):
|
|
395
|
-
using_modules.update([x.name for x in node.names])
|
|
396
|
-
|
|
397
|
-
elif isinstance(node, ast.ImportFrom):
|
|
398
|
-
using_modules.add(abs_name(qualname, node.module, node.level))
|
|
399
|
-
|
|
400
|
-
else:
|
|
401
|
-
for child in ast.iter_child_nodes(node):
|
|
402
|
-
visit(child)
|
|
403
|
-
|
|
404
|
-
visit(tree)
|
|
405
|
-
return using_modules
|
|
406
|
-
|
|
407
|
-
# The following methodes are unused
|
|
408
|
-
def _get_hidden_imports(self, tree):
|
|
409
|
-
hidden_imports = []
|
|
410
|
-
|
|
411
|
-
def visit(node):
|
|
412
|
-
if (isinstance(node, ast.Call)
|
|
413
|
-
and isinstance(node.func, ast.Name)
|
|
414
|
-
and node.func.id in ('__import__', '__dict__')
|
|
415
|
-
and node.func.args
|
|
416
|
-
and isinstance(node.func.args[0], (ast.Str, ast.Constant))):
|
|
417
|
-
# TODO: __import__(x, , , from_list, level)
|
|
418
|
-
pass
|
|
419
|
-
|
|
420
|
-
elif (isinstance(node, ast.Call)
|
|
421
|
-
and isinstance(node.func, ast.Name)
|
|
422
|
-
and node.func.id in ('getattr', 'setattr')
|
|
423
|
-
and len(node.args) > 1
|
|
424
|
-
and isinstance(node.args[0], (ast.Name))
|
|
425
|
-
and isinstance(node.args[1], (ast.Str, ast.Constant))):
|
|
426
|
-
# TODO: getattr or setattr for node.args[0].id
|
|
427
|
-
pass
|
|
428
|
-
|
|
429
|
-
for child in ast.iter_child_nodes(node):
|
|
430
|
-
visit(child)
|
|
431
|
-
|
|
432
|
-
visit(tree)
|
|
433
|
-
return hidden_imports
|
|
434
|
-
|
|
435
|
-
def _get_chain_attrs(self, tree):
|
|
436
|
-
chain_attrs = {}
|
|
437
|
-
scope = []
|
|
438
|
-
|
|
439
|
-
def visit(node):
|
|
440
|
-
if isinstance(node, SCOPE_NODE_TYPES):
|
|
441
|
-
scope.append(node.name)
|
|
442
|
-
|
|
443
|
-
elif isinstance(node, ast.Attribute):
|
|
444
|
-
stack = []
|
|
445
|
-
attrnode = node
|
|
446
|
-
while isinstance(attrnode, ast.Attribute):
|
|
447
|
-
stack.insert(0, attrnode.attr)
|
|
448
|
-
attrnode = attrnode.value
|
|
449
|
-
|
|
450
|
-
key = '.'.join(scope)
|
|
451
|
-
chain_attrs.setdefault(key, set())
|
|
452
|
-
|
|
453
|
-
# case: a.b.c
|
|
454
|
-
if isinstance(attrnode, ast.Name):
|
|
455
|
-
chain_attrs[key].add('.'.join([attrnode.id] + stack))
|
|
456
|
-
return
|
|
457
|
-
|
|
458
|
-
# case: Cls().x.y.z
|
|
459
|
-
elif (isinstance(attrnode, ast.Call) and
|
|
460
|
-
isinstance(attrnode.func, ast.Name)):
|
|
461
|
-
chain_attrs[key].add('.'.join([attrnode.func.id] + stack))
|
|
462
|
-
return
|
|
463
|
-
|
|
464
|
-
# case: 'abc'.join(...)
|
|
465
|
-
elif isinstance(attrnode, (ast.Str, ast.Constant)):
|
|
466
|
-
value = getattr(attrnode,
|
|
467
|
-
's' if hasattr(attrnode, 's') else 'value')
|
|
468
|
-
chain_attrs[key].add('.'.join([type(value)] + stack))
|
|
469
|
-
return
|
|
470
|
-
|
|
471
|
-
else:
|
|
472
|
-
chain_attrs[key].add('.'.join(['?'] + stack))
|
|
473
|
-
node = attrnode
|
|
474
|
-
|
|
475
|
-
for child in ast.iter_child_nodes(node):
|
|
476
|
-
visit(child)
|
|
477
|
-
|
|
478
|
-
if isinstance(node, SCOPE_NODE_TYPES):
|
|
479
|
-
scope.pop()
|
|
480
|
-
|
|
481
|
-
visit(tree)
|
|
482
|
-
return chain_attrs
|
|
483
|
-
|
|
484
|
-
def _get_body_names(self, node):
|
|
485
|
-
attrs = set()
|
|
486
|
-
|
|
487
|
-
def visit(node):
|
|
488
|
-
if isinstance(node, ast.Assign):
|
|
489
|
-
for target in node.targets:
|
|
490
|
-
if isinstance(target, ast.Name):
|
|
491
|
-
attrs.add(target)
|
|
492
|
-
|
|
493
|
-
elif isinstance(node, SCOPE_NODE_TYPES):
|
|
494
|
-
attrs.add(node)
|
|
495
|
-
|
|
496
|
-
else:
|
|
497
|
-
for child in ast.iter_child_nodes(node):
|
|
498
|
-
visit(child)
|
|
499
|
-
|
|
500
|
-
for x in node.body:
|
|
501
|
-
visit(x)
|
|
502
|
-
return attrs
|
|
503
|
-
|
|
504
|
-
def _get_module_names(self, tree):
|
|
505
|
-
module_names = {}
|
|
506
|
-
scope = []
|
|
507
|
-
|
|
508
|
-
def visit(node):
|
|
509
|
-
if isinstance(node, SCOPE_NODE_TYPES):
|
|
510
|
-
scope.append(node.name)
|
|
511
|
-
|
|
512
|
-
elif isinstance(node, ast.Name):
|
|
513
|
-
key = '.'.join(scope)
|
|
514
|
-
module_names.setdefault(key, set())
|
|
515
|
-
module_names[key].add(node.id)
|
|
516
|
-
return
|
|
517
|
-
|
|
518
|
-
for child in ast.iter_child_nodes(node):
|
|
519
|
-
visit(child)
|
|
520
|
-
|
|
521
|
-
if isinstance(node, SCOPE_NODE_TYPES):
|
|
522
|
-
scope.pop()
|
|
523
|
-
|
|
524
|
-
visit(tree)
|
|
525
|
-
return module_names
|
|
526
|
-
|
|
527
|
-
def _get_module_attrs(self, tree):
|
|
528
|
-
module_attrs = set()
|
|
529
|
-
|
|
530
|
-
def visit(node):
|
|
531
|
-
if isinstance(node, ast.Assign):
|
|
532
|
-
for target in node.targets:
|
|
533
|
-
if isinstance(target, ast.Name):
|
|
534
|
-
module_attrs.add(target.id)
|
|
535
|
-
|
|
536
|
-
elif isinstance(node, SCOPE_NODE_TYPES):
|
|
537
|
-
module_attrs.add(node.name)
|
|
538
|
-
|
|
539
|
-
else:
|
|
540
|
-
for child in ast.iter_child_nodes(node):
|
|
541
|
-
visit(child)
|
|
542
|
-
|
|
543
|
-
def visit2(node):
|
|
544
|
-
if isinstance(node, ast.Global):
|
|
545
|
-
module_attrs.update(node.names)
|
|
546
|
-
|
|
547
|
-
else:
|
|
548
|
-
for child in ast.iter_child_nodes(node):
|
|
549
|
-
visit2(child)
|
|
550
|
-
|
|
551
|
-
visit(tree)
|
|
552
|
-
visit2(tree)
|
|
553
|
-
return module_attrs
|
|
554
|
-
|
|
555
|
-
def _get_import_names(self, tree):
|
|
556
|
-
import_names = {}
|
|
557
|
-
|
|
558
|
-
def visit(node):
|
|
559
|
-
if isinstance(node, ast.ImportFrom):
|
|
560
|
-
name = '.' * node.level + node.module if node.module else ''
|
|
561
|
-
import_names.setdefault(name, set())
|
|
562
|
-
import_names[name].update([x.name for x in node.names])
|
|
563
|
-
else:
|
|
564
|
-
for child in ast.iter_child_nodes(node):
|
|
565
|
-
visit(child)
|
|
566
|
-
|
|
567
|
-
visit(tree)
|
|
568
|
-
return import_names
|
|
569
|
-
|
|
570
|
-
def _get_import_modules(self, tree):
|
|
571
|
-
import_modules = {}
|
|
572
|
-
|
|
573
|
-
def visit(node):
|
|
574
|
-
if isinstance(node, ast.Import):
|
|
575
|
-
for name, asname in [(x.name, x.asname) for x in node.names]:
|
|
576
|
-
import_modules[asname if asname else name] = name
|
|
577
|
-
|
|
578
|
-
else:
|
|
579
|
-
for child in ast.iter_child_nodes(node):
|
|
580
|
-
visit(child)
|
|
581
|
-
|
|
582
|
-
visit(tree)
|
|
583
|
-
return import_modules
|
|
584
|
-
|
|
585
|
-
def _get_import_attrs(self, tree):
|
|
586
|
-
module_attrs = {}
|
|
587
|
-
Attr = ast.Attribute
|
|
588
|
-
Name = ast.Name
|
|
589
|
-
|
|
590
|
-
def visit(node):
|
|
591
|
-
if isinstance(node, Attr) and isinstance(node.value, Name):
|
|
592
|
-
name = node.value.id
|
|
593
|
-
if name in self.import_modules:
|
|
594
|
-
module_attrs.setdefault(name, set())
|
|
595
|
-
module_attrs[name].add(node.attr)
|
|
596
|
-
else:
|
|
597
|
-
for child in ast.iter_child_nodes(node):
|
|
598
|
-
visit(child)
|
|
599
|
-
|
|
600
|
-
visit(tree)
|
|
601
|
-
return module_attrs
|
|
602
|
-
|
|
603
|
-
def _get_mapped_names(self, tree):
|
|
604
|
-
mapped_names = {'': set(self._get_module_attrs(tree))}
|
|
605
|
-
scope = []
|
|
606
|
-
|
|
607
|
-
def visit(node):
|
|
608
|
-
if isinstance(node, SCOPE_NODE_TYPES):
|
|
609
|
-
if scope:
|
|
610
|
-
key = '.'.join(scope)
|
|
611
|
-
mapped_names.setdefault(key, set())
|
|
612
|
-
mapped_names[key].add(node.name)
|
|
613
|
-
scope.append(node.name)
|
|
614
|
-
|
|
615
|
-
for child in ast.iter_child_nodes(node):
|
|
616
|
-
visit(child)
|
|
617
|
-
|
|
618
|
-
if isinstance(node, SCOPE_NODE_TYPES):
|
|
619
|
-
scope.pop()
|
|
620
|
-
|
|
621
|
-
visit(tree)
|
|
622
|
-
return mapped_names
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
class PackageRelations(object):
|
|
626
|
-
|
|
627
|
-
def __init__(self, ctx):
|
|
628
|
-
self.ctx = ctx
|
|
629
|
-
|
|
630
|
-
def _import_star_names(self, modname):
|
|
631
|
-
try:
|
|
632
|
-
return dir(__import__(modname))
|
|
633
|
-
except ModuleNotFoundError:
|
|
634
|
-
pass
|
|
635
|
-
|
|
636
|
-
def process(self, clean=True):
|
|
637
|
-
for res in self.ctx.resources:
|
|
638
|
-
if not res.is_script():
|
|
639
|
-
continue
|
|
640
|
-
|
|
641
|
-
if not res.mtree:
|
|
642
|
-
res.reparse()
|
|
643
|
-
|
|
644
|
-
qualname = res.fullname
|
|
645
|
-
minfo = ModuleInfo(qualname, res.mtree)
|
|
646
|
-
|
|
647
|
-
self.ctx.module_types.update(minfo.module_types)
|
|
648
|
-
self.ctx.module_relations[qualname] = minfo.using_modules
|
|
649
|
-
|
|
650
|
-
if clean:
|
|
651
|
-
res.clean()
|
|
652
|
-
|
|
653
|
-
#
|
|
654
|
-
# End of source code
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
if __name__ == "__main__":
|
|
658
|
-
import doctest
|
|
659
|
-
doctest.testmod()
|
|
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
|
|
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
|