ssc_codegen 0.8.20__tar.gz → 0.8.22__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.
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/PKG-INFO +1 -1
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/pyproject.toml +1 -1
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/__init__.py +1 -1
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_/__init__.py +2 -2
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_/nodes_array.py +8 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_/nodes_string.py +20 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/go_goquery.py +2 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/js_pure.py +28 -2
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/py_base.py +40 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/document.py +42 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/tokens.py +4 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/.gitignore +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/LICENSE +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/README.md +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/_compat.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_/base.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_/nodes_cast.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_/nodes_core.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_/nodes_filter.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_/nodes_selectors.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_/nodes_validate.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_build/__init__.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_build/main.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/ast_build/utils.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/cli/__init__.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/cli/cli_callbacks.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/cli/cli_utils.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/cli/code_callbacks.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/cli/consts.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/cli/main.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/cli/runtime_parse_runners.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/compiler.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/consts.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/__init__.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/base.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/helpers.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/py_bs4.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/py_parsel.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/py_selectolax.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/templates/__init__.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/templates/go_goquery.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/converters/templates/js_pure.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/document_utlis.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/json_struct.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/json_to_scc.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/logs.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/pseudo_selectors.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/schema.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/selector_utils.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/static_checker/__init__.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/static_checker/base.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/static_checker/callbacks.py +0 -0
- {ssc_codegen-0.8.20 → ssc_codegen-0.8.22}/ssc_codegen/str_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ssc_codegen
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.22
|
|
4
4
|
Summary: Python-dsl code converter to html parser for web scraping
|
|
5
5
|
Project-URL: Documentation, https://github.com/vypivshiy/selector_schema_codegen#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/vypivshiy/selector_schema_codegen/issues
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from .base import BaseAstNode
|
|
2
|
-
from .nodes_array import ExprIndex, ExprToListLength, ExprListStringJoin
|
|
2
|
+
from .nodes_array import ExprIndex, ExprToListLength, ExprListStringJoin, ExprListUnique
|
|
3
3
|
from .nodes_cast import ExprNested, ExprJsonify, ExprToInt, ExprToFloat, ExprToListInt, ExprToListFloat, ExprToBool
|
|
4
4
|
from .nodes_core import (ExprReturn,
|
|
5
5
|
ExprNoReturn,
|
|
@@ -31,6 +31,6 @@ from .nodes_string import ExprStringTrim, ExprStringRegex, ExprStringSplit, Expr
|
|
|
31
31
|
ExprListStringFormat, ExprListStringReplace, ExprListStringRightTrim, ExprListStringLeftTrim, \
|
|
32
32
|
ExprListStringRegexSub, \
|
|
33
33
|
ExprStringRmPrefix, ExprStringRmSuffix, ExprStringRmPrefixAndSuffix, ExprListStringRmPrefixAndSuffix, \
|
|
34
|
-
ExprListStringRmPrefix, ExprListStringRmSuffix
|
|
34
|
+
ExprListStringRmPrefix, ExprListStringRmSuffix, ExprStringMapReplace, ExprListStringMapReplace
|
|
35
35
|
from .nodes_validate import ExprIsCss, ExprIsEqual, ExprStringIsRegex, ExprIsXpath, ExprIsNotEqual, ExprIsContains, \
|
|
36
36
|
ExprListStringAnyRegex, ExprListStringAllRegex, ExprHasAttr, ExprListHasAttr
|
|
@@ -31,3 +31,11 @@ class ExprToListLength(BaseAstNode[T_EMPTY_KWARGS, tuple]):
|
|
|
31
31
|
kind: ClassVar[TokenType] = TokenType.EXPR_LIST_LEN
|
|
32
32
|
accept_type: VariableType = VariableType.LIST_ANY
|
|
33
33
|
ret_type: VariableType = VariableType.INT
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(kw_only=True)
|
|
37
|
+
class ExprListUnique(BaseAstNode[T_EMPTY_KWARGS, tuple]):
|
|
38
|
+
# TODO: support LIST_INT, LIST_FLOAT
|
|
39
|
+
kind: ClassVar[TokenType] = TokenType.EXPR_LIST_UNIQUE
|
|
40
|
+
accept_type: VariableType = VariableType.LIST_STRING
|
|
41
|
+
ret_type: VariableType = VariableType.LIST_STRING
|
|
@@ -93,6 +93,26 @@ class ExprListStringReplace(BaseAstNode[KW_STR_REPL, tuple[str, str]]):
|
|
|
93
93
|
ret_type: VariableType = VariableType.LIST_STRING
|
|
94
94
|
|
|
95
95
|
|
|
96
|
+
KW_STR_MAP_REPL = TypedDict(
|
|
97
|
+
"KW_STR_MAP_REPL", {"old": tuple[str, ...], "new": tuple[str, ...]}
|
|
98
|
+
)
|
|
99
|
+
ARGS_STR_MAP_REPL = tuple[tuple[str, ...], tuple[str, ...]]
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass(kw_only=True)
|
|
103
|
+
class ExprStringMapReplace(BaseAstNode[KW_STR_MAP_REPL, ARGS_STR_MAP_REPL]):
|
|
104
|
+
kind: ClassVar[TokenType] = TokenType.EXPR_STRING_MAP_REPLACE
|
|
105
|
+
accept_type: VariableType = VariableType.STRING
|
|
106
|
+
ret_type: VariableType = VariableType.STRING
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@dataclass(kw_only=True)
|
|
110
|
+
class ExprListStringMapReplace(BaseAstNode[KW_STR_MAP_REPL, ARGS_STR_MAP_REPL]):
|
|
111
|
+
kind: ClassVar[TokenType] = TokenType.EXPR_LIST_STRING_MAP_REPLACE
|
|
112
|
+
accept_type: VariableType = VariableType.LIST_STRING
|
|
113
|
+
ret_type: VariableType = VariableType.LIST_STRING
|
|
114
|
+
|
|
115
|
+
|
|
96
116
|
KW_STR_RE = TypedDict(
|
|
97
117
|
"KW_STR_RE", {"pattern": str, "group": int, "ignore_case": bool}
|
|
98
118
|
)
|
|
@@ -101,6 +101,9 @@ from ssc_codegen.ast_ import (
|
|
|
101
101
|
FilterStrLenLe,
|
|
102
102
|
FilterStrLenGt,
|
|
103
103
|
FilterStrLenGe,
|
|
104
|
+
ExprListUnique,
|
|
105
|
+
ExprStringMapReplace,
|
|
106
|
+
ExprListStringMapReplace,
|
|
104
107
|
)
|
|
105
108
|
from ssc_codegen.converters.base import BaseCodeConverter
|
|
106
109
|
from ssc_codegen.converters.helpers import (
|
|
@@ -376,14 +379,14 @@ def pre_str_split(node: ExprStringSplit) -> str:
|
|
|
376
379
|
def pre_str_replace(node: ExprStringReplace) -> str:
|
|
377
380
|
prv, nxt = prev_next_var(node)
|
|
378
381
|
old, new = node.unpack_args()
|
|
379
|
-
return f"let {nxt} = {prv}.
|
|
382
|
+
return f"let {nxt} = {prv}.replaceAll({old!r}, {new!r});"
|
|
380
383
|
|
|
381
384
|
|
|
382
385
|
@CONVERTER(ExprListStringReplace.kind)
|
|
383
386
|
def pre_list_str_replace(node: ExprListStringReplace) -> str:
|
|
384
387
|
prv, nxt = prev_next_var(node)
|
|
385
388
|
old, new = node.unpack_args()
|
|
386
|
-
return f"let {nxt} = {prv}.map(e => e.
|
|
389
|
+
return f"let {nxt} = {prv}.map(e => e.replaceAll({old!r}, {new!r}));"
|
|
387
390
|
|
|
388
391
|
|
|
389
392
|
@CONVERTER(ExprStringRegex.kind)
|
|
@@ -914,3 +917,26 @@ def pre_filter_str_len_ge(node: FilterStrLenGe) -> str:
|
|
|
914
917
|
if not is_first_node_cond(node) and is_prev_node_atomic_cond(node):
|
|
915
918
|
return f" && {expr}"
|
|
916
919
|
return expr
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
@CONVERTER(ExprListUnique.kind)
|
|
923
|
+
def pre_list_unique(node: ExprListUnique) -> str:
|
|
924
|
+
prv, nxt = prev_next_var(node)
|
|
925
|
+
# save order guaranteed
|
|
926
|
+
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#description
|
|
927
|
+
return f"let {nxt} = [...new Set({prv})]; "
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
@CONVERTER(ExprStringMapReplace.kind)
|
|
931
|
+
def pre_str_map_repl(node: ExprStringMapReplace) -> str:
|
|
932
|
+
old_arr, new_arr = node.unpack_args()
|
|
933
|
+
prv, nxt = prev_next_var(node)
|
|
934
|
+
# py list<str> literal syntax equal js Array<string> literak
|
|
935
|
+
return f"let {nxt} = {old_arr}.reduce((s, v, i) => s.replaceAll(v, {new_arr}[i] ?? ''), {prv});"
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
@CONVERTER(ExprListStringMapReplace.kind)
|
|
939
|
+
def pre_list_str_map_repl(node: ExprListStringMapReplace) -> str:
|
|
940
|
+
old_arr, new_arr = node.unpack_args()
|
|
941
|
+
prv, nxt = prev_next_var(node)
|
|
942
|
+
return f"let {nxt} = {prv}.map(s => {old_arr}.reduce((s, v, i) => s.replaceAll(v, {new_arr}[i] ?? ''), s));"
|
|
@@ -103,6 +103,9 @@ from ssc_codegen.ast_ import (
|
|
|
103
103
|
FilterStrLenLe,
|
|
104
104
|
FilterStrLenGt,
|
|
105
105
|
FilterStrLenGe,
|
|
106
|
+
ExprListUnique,
|
|
107
|
+
ExprStringMapReplace,
|
|
108
|
+
ExprListStringMapReplace,
|
|
106
109
|
)
|
|
107
110
|
from ssc_codegen.converters.base import (
|
|
108
111
|
BaseCodeConverter,
|
|
@@ -175,6 +178,7 @@ import sys
|
|
|
175
178
|
import json
|
|
176
179
|
from typing import List, Dict, TypedDict, Union, Optional
|
|
177
180
|
from contextlib import suppress
|
|
181
|
+
from functools import reduce
|
|
178
182
|
|
|
179
183
|
if sys.version_info >= (3, 10):
|
|
180
184
|
from types import NoneType
|
|
@@ -271,6 +275,9 @@ class BasePyCodeConverter(BaseCodeConverter):
|
|
|
271
275
|
FilterStrLenLe.kind: pre_filter_str_len_le,
|
|
272
276
|
FilterStrLenGe.kind: pre_filter_str_len_ge,
|
|
273
277
|
FilterStrLenGt.kind: pre_filter_str_len_gt,
|
|
278
|
+
ExprListUnique.kind: pre_list_unique,
|
|
279
|
+
ExprStringMapReplace.kind: pre_str_map_replace,
|
|
280
|
+
ExprListStringMapReplace.kind: pre_list_str_map_replace,
|
|
274
281
|
}
|
|
275
282
|
|
|
276
283
|
self.post_definitions = {
|
|
@@ -1069,3 +1076,36 @@ def pre_filter_str_len_ge(node: FilterStrLenGe) -> str:
|
|
|
1069
1076
|
if not is_first_node_cond(node) and is_prev_node_atomic_cond(node):
|
|
1070
1077
|
return f" and {expr}"
|
|
1071
1078
|
return expr
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
def pre_list_unique(node: ExprListUnique) -> str:
|
|
1082
|
+
indent = (
|
|
1083
|
+
INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
|
|
1084
|
+
)
|
|
1085
|
+
prv, nxt = prev_next_var(node)
|
|
1086
|
+
# use `dict.fromkeys()` instead `set()` for guarantees insertion order (py 3.7+) reason
|
|
1087
|
+
return f"{indent}{nxt} = list(dict.fromkeys({prv}))"
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
def pre_str_map_replace(node: ExprStringMapReplace) -> str:
|
|
1091
|
+
indent = (
|
|
1092
|
+
INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
|
|
1093
|
+
)
|
|
1094
|
+
old_arr, new_arr = node.unpack_args()
|
|
1095
|
+
replacements = dict(zip(old_arr, new_arr))
|
|
1096
|
+
|
|
1097
|
+
prv, nxt = prev_next_var(node)
|
|
1098
|
+
expr = f"reduce(lambda acc, kv: acc.replace(kv[0], kv[1]), {replacements}.items(), {prv})"
|
|
1099
|
+
return f"{indent}{nxt} = {expr}"
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
def pre_list_str_map_replace(node: ExprListStringMapReplace) -> str:
|
|
1103
|
+
indent = (
|
|
1104
|
+
INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
|
|
1105
|
+
)
|
|
1106
|
+
old_arr, new_arr = node.unpack_args()
|
|
1107
|
+
replacements = dict(zip(old_arr, new_arr))
|
|
1108
|
+
|
|
1109
|
+
prv, nxt = prev_next_var(node)
|
|
1110
|
+
expr = f"[reduce(lambda acc, kv: acc.replace(kv[0], kv[1]), {replacements}.items(), i) for i in {prv}]"
|
|
1111
|
+
return f"{indent}{nxt} = {expr}"
|
|
@@ -75,6 +75,9 @@ from ssc_codegen.ast_ import (
|
|
|
75
75
|
FilterStrLenLe,
|
|
76
76
|
FilterStrLenGt,
|
|
77
77
|
FilterStrLenGe,
|
|
78
|
+
ExprListUnique,
|
|
79
|
+
ExprListStringMapReplace,
|
|
80
|
+
ExprStringMapReplace,
|
|
78
81
|
)
|
|
79
82
|
from ssc_codegen.document_utlis import (
|
|
80
83
|
analyze_re_expression,
|
|
@@ -487,8 +490,47 @@ class ArrayDocument(BaseDocument):
|
|
|
487
490
|
self._add(ExprFilter(body=expr.stack))
|
|
488
491
|
return self
|
|
489
492
|
|
|
493
|
+
def unique(self) -> Self:
|
|
494
|
+
"""Remove duplicates from array-like object
|
|
495
|
+
|
|
496
|
+
- accept LIST_STRING, return LIST_STRING
|
|
497
|
+
"""
|
|
498
|
+
self._add(ExprListUnique())
|
|
499
|
+
return self
|
|
500
|
+
|
|
490
501
|
|
|
491
502
|
class StringDocument(BaseDocument):
|
|
503
|
+
def repl_map(self, replace_table: dict[str, str]) -> Self:
|
|
504
|
+
old_args = tuple(replace_table.keys())
|
|
505
|
+
new_args = tuple(replace_table.values())
|
|
506
|
+
|
|
507
|
+
match self.stack_last_ret:
|
|
508
|
+
case VariableType.LIST_STRING:
|
|
509
|
+
self._add(
|
|
510
|
+
ExprListStringMapReplace(
|
|
511
|
+
kwargs={"old": old_args, "new": new_args}
|
|
512
|
+
)
|
|
513
|
+
)
|
|
514
|
+
case VariableType.STRING:
|
|
515
|
+
self._add(
|
|
516
|
+
ExprStringMapReplace(
|
|
517
|
+
kwargs={"old": old_args, "new": new_args}
|
|
518
|
+
)
|
|
519
|
+
)
|
|
520
|
+
case _:
|
|
521
|
+
LOGGER.warning(
|
|
522
|
+
"repl_map(%s): Expected type(s) %s got %s",
|
|
523
|
+
replace_table,
|
|
524
|
+
(VariableType.LIST_STRING.name, VariableType.STRING.name),
|
|
525
|
+
self.stack_last_ret.name,
|
|
526
|
+
)
|
|
527
|
+
self._add(
|
|
528
|
+
ExprStringMapReplace(
|
|
529
|
+
kwargs={"old": old_args, "new": new_args}
|
|
530
|
+
)
|
|
531
|
+
)
|
|
532
|
+
return self
|
|
533
|
+
|
|
492
534
|
def rm_prefix(self, substr: str) -> Self:
|
|
493
535
|
"""remove prefix from string by substr
|
|
494
536
|
|
|
@@ -131,6 +131,7 @@ class TokenType(IntEnum):
|
|
|
131
131
|
EXPR_STRING_RM_PREFIX = auto()
|
|
132
132
|
EXPR_STRING_RM_SUFFIX = auto()
|
|
133
133
|
EXPR_STRING_RM_PREFIX_AND_SUFFIX = auto()
|
|
134
|
+
EXPR_STRING_MAP_REPLACE = auto()
|
|
134
135
|
|
|
135
136
|
# LIST_STRING
|
|
136
137
|
EXPR_LIST_REGEX_SUB = auto()
|
|
@@ -142,10 +143,13 @@ class TokenType(IntEnum):
|
|
|
142
143
|
EXPR_LIST_STRING_RM_PREFIX = auto()
|
|
143
144
|
EXPR_LIST_STRING_RM_SUFFIX = auto()
|
|
144
145
|
EXPR_LIST_STRING_RM_PREFIX_AND_SUFFIX = auto()
|
|
146
|
+
EXPR_LIST_STRING_MAP_REPLACE = auto()
|
|
147
|
+
|
|
145
148
|
# ARRAY
|
|
146
149
|
EXPR_LIST_ANY_INDEX = auto()
|
|
147
150
|
EXPR_LIST_JOIN = auto()
|
|
148
151
|
EXPR_LIST_LEN = auto()
|
|
152
|
+
EXPR_LIST_UNIQUE = auto()
|
|
149
153
|
|
|
150
154
|
# ASSERT
|
|
151
155
|
IS_EQUAL = auto()
|
|
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
|