rushti 2.2.1__tar.gz → 2.2.3__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.
- {rushti-2.2.1/src/rushti.egg-info → rushti-2.2.3}/PKG-INFO +1 -1
- {rushti-2.2.1 → rushti-2.2.3}/pyproject.toml +1 -1
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/__init__.py +1 -1
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/execution.py +9 -5
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/tm1_build.py +11 -4
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/tm1_objects.py +181 -3
- {rushti-2.2.1 → rushti-2.2.3/src/rushti.egg-info}/PKG-INFO +1 -1
- {rushti-2.2.1 → rushti-2.2.3}/LICENSE +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/README.md +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/setup.cfg +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/_shlex_utils.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/app_paths.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/checkpoint.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/cli.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/__init__.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/build.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/db.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/resume.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/stats/__init__.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/stats/analyze.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/stats/export.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/stats/list.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/stats/optimize.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/stats/visualize.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/tasks/__init__.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/tasks/expand.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/tasks/export.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/tasks/push.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/tasks/validate.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/commands/tasks/visualize.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/contention_analyzer.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/dag.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/dashboard.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/db_admin.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/exclusive.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/logging.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/logging_setup.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/messages.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/optimization_report.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/optimizer.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/parsing.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/results_writer.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/settings.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/stats/__init__.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/stats/dynamodb.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/stats/paths.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/stats/repository.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/stats/signature.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/stats/sqlite.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/task.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/taskfile.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/taskfile_ops.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/templates/__init__.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/templates/visualization.html +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/tm1_integration.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/utils.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti/visualization_template.py +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti.egg-info/SOURCES.txt +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti.egg-info/dependency_links.txt +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti.egg-info/entry_points.txt +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti.egg-info/requires.txt +0 -0
- {rushti-2.2.1 → rushti-2.2.3}/src/rushti.egg-info/top_level.txt +0 -0
|
@@ -5,7 +5,7 @@ This package provides tools for executing TM1 TI processes in parallel
|
|
|
5
5
|
with dependency management, checkpoint/resume support, and execution logging.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
__version__ = "2.2.
|
|
8
|
+
__version__ = "2.2.3"
|
|
9
9
|
__app_name__ = "RushTI"
|
|
10
10
|
|
|
11
11
|
# Core exports for programmatic use
|
|
@@ -195,11 +195,15 @@ def setup_tm1_services(
|
|
|
195
195
|
# case no connection file provided or connection file expired
|
|
196
196
|
if tm1_server_name not in tm1_services:
|
|
197
197
|
resolved_params = resolve_tm1_params(config, tm1_server_name)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
198
|
+
# RushTI-managed defaults; any value explicitly set in
|
|
199
|
+
# config.ini takes precedence (avoids "multiple values for
|
|
200
|
+
# keyword argument" when e.g. connection_pool_size is set).
|
|
201
|
+
service_kwargs = {
|
|
202
|
+
"session_context": session_context,
|
|
203
|
+
"connection_pool_size": max_workers,
|
|
204
|
+
}
|
|
205
|
+
service_kwargs.update(resolved_params)
|
|
206
|
+
tm1_services[tm1_server_name] = TM1Service(**service_kwargs)
|
|
203
207
|
|
|
204
208
|
if connection_file:
|
|
205
209
|
# implicitly re-connects if session is timed out
|
|
@@ -32,16 +32,19 @@ from TM1py.Objects import (
|
|
|
32
32
|
Process,
|
|
33
33
|
Subset,
|
|
34
34
|
)
|
|
35
|
+
from TM1py.Utils import integerize_version
|
|
35
36
|
|
|
36
37
|
from rushti.tm1_objects import (
|
|
37
38
|
MEASURE_ATTRIBUTES,
|
|
38
39
|
MEASURE_ELEMENTS,
|
|
39
40
|
PROCESS_DATA,
|
|
40
41
|
PROCESS_DATASOURCE,
|
|
41
|
-
|
|
42
|
+
PROCESS_EPILOG_V11,
|
|
43
|
+
PROCESS_EPILOG_V12,
|
|
42
44
|
PROCESS_METADATA,
|
|
43
45
|
PROCESS_PARAMETERS,
|
|
44
|
-
|
|
46
|
+
PROCESS_PROLOG_V11,
|
|
47
|
+
PROCESS_PROLOG_V12,
|
|
45
48
|
PROCESS_VARIABLES,
|
|
46
49
|
RUN_ID_SEED_ELEMENTS,
|
|
47
50
|
SAMPLE_DATA,
|
|
@@ -558,12 +561,16 @@ def _create_process(tm1: TM1Service, process_name: str, force: bool = False) ->
|
|
|
558
561
|
logger.info(f"Replacing existing process: {process_name}")
|
|
559
562
|
tm1.processes.delete(process_name)
|
|
560
563
|
|
|
564
|
+
is_v12 = integerize_version(tm1.version, 2) >= 12
|
|
565
|
+
prolog = PROCESS_PROLOG_V12 if is_v12 else PROCESS_PROLOG_V11
|
|
566
|
+
epilog = PROCESS_EPILOG_V12 if is_v12 else PROCESS_EPILOG_V11
|
|
567
|
+
|
|
561
568
|
process = Process(
|
|
562
569
|
name=process_name,
|
|
563
|
-
prolog_procedure=
|
|
570
|
+
prolog_procedure=prolog,
|
|
564
571
|
metadata_procedure=PROCESS_METADATA,
|
|
565
572
|
data_procedure=PROCESS_DATA,
|
|
566
|
-
epilog_procedure=
|
|
573
|
+
epilog_procedure=epilog,
|
|
567
574
|
datasource_type=PROCESS_DATASOURCE["Type"],
|
|
568
575
|
datasource_ascii_decimal_separator=PROCESS_DATASOURCE["asciiDecimalSeparator"],
|
|
569
576
|
datasource_ascii_delimiter_char=PROCESS_DATASOURCE["asciiDelimiterChar"],
|
|
@@ -10,8 +10,14 @@ Object Definitions:
|
|
|
10
10
|
- TASK_ID_ELEMENT_COUNT: Number of elements to generate for task_id dimension (1..N)
|
|
11
11
|
- RUN_ID_SEED_ELEMENTS: Seed elements for run_id dimension
|
|
12
12
|
- WORKFLOW_SEED_ELEMENTS: Seed elements for workflow dimension
|
|
13
|
-
-
|
|
13
|
+
- PROCESS_PROLOG_V11 / PROCESS_PROLOG_V12: Prolog body per TM1 major version
|
|
14
|
+
- PROCESS_EPILOG_V11 / PROCESS_EPILOG_V12: Epilog body per TM1 major version
|
|
14
15
|
- SAMPLE_DATA: Sample cube data for demonstration taskfiles
|
|
16
|
+
|
|
17
|
+
The v12 variants drop calls to functions that were removed or are unsupported
|
|
18
|
+
on TM1 v12 (``CubeGetLogChanges`` / ``CubeSetLogChanges`` and
|
|
19
|
+
``ExecuteCommand``). Source-file cleanup on v12 is handled by the TM1-native
|
|
20
|
+
``ASCIIDelete`` instead of shelling out to ``cmd /c del``.
|
|
15
21
|
"""
|
|
16
22
|
|
|
17
23
|
# ---------------------------------------------------------------------------
|
|
@@ -85,7 +91,7 @@ WORKFLOW_SEED_ELEMENTS = ["Sample_Stage_Mode", "Sample_Optimal_Mode"]
|
|
|
85
91
|
# TI Process: }rushti.load.results
|
|
86
92
|
# ---------------------------------------------------------------------------
|
|
87
93
|
|
|
88
|
-
|
|
94
|
+
PROCESS_PROLOG_V11 = r"""#################################################################################################
|
|
89
95
|
##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0~~##
|
|
90
96
|
#################################################################################################
|
|
91
97
|
|
|
@@ -208,6 +214,142 @@ CubeSetLogChanges( cCubeTgt, 0 );
|
|
|
208
214
|
#Region - DataSource
|
|
209
215
|
|
|
210
216
|
|
|
217
|
+
### Assign data source
|
|
218
|
+
If( nErrors = 0 );
|
|
219
|
+
DatasourceType = 'CHARACTERDELIMITED';
|
|
220
|
+
DatasourceNameForServer = cFileSrc;
|
|
221
|
+
DatasourceASCIIHeaderRecords = 1;
|
|
222
|
+
DatasourceASCIIDelimiter=',';
|
|
223
|
+
DatasourceASCIIDecimalSeparator='.';
|
|
224
|
+
DatasourceASCIIThousandSeparator='';
|
|
225
|
+
EndIf;
|
|
226
|
+
|
|
227
|
+
#EndRegion - DataSource
|
|
228
|
+
#################################################################################################
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
# v12 prolog: identical to v11 except the CubeGetLogChanges / CubeSetLogChanges
|
|
232
|
+
# block is removed. Those functions are unsupported on TM1 v12 and would cause
|
|
233
|
+
# the TI to fail at compile time.
|
|
234
|
+
PROCESS_PROLOG_V12 = r"""#################################################################################################
|
|
235
|
+
##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0~~##
|
|
236
|
+
#################################################################################################
|
|
237
|
+
|
|
238
|
+
#****Begin: Generated Statements***
|
|
239
|
+
#****End: Generated Statements****
|
|
240
|
+
|
|
241
|
+
#################################################################################################
|
|
242
|
+
### CHANGE HISTORY:
|
|
243
|
+
### MODIFICATION DATE CHANGED BY COMMENT
|
|
244
|
+
### 2026-01-15 Nicolas Bisurgi Creation of Process
|
|
245
|
+
### YYYY-MM-DD Developer Name Reason for modification here
|
|
246
|
+
#################################################################################################
|
|
247
|
+
#Region @DOC
|
|
248
|
+
# Description:
|
|
249
|
+
# This process will load RushTI result files into a TM1 cube
|
|
250
|
+
|
|
251
|
+
# Use case:
|
|
252
|
+
# Storing RushTI execution stats in a TM1 Cube
|
|
253
|
+
|
|
254
|
+
# Note:
|
|
255
|
+
# * This process assumes a there is a rushti compliant cube and dimensions. If you don't have it
|
|
256
|
+
# * please run: rushti.py build --tm1-instance tm1srv01
|
|
257
|
+
#EndRegion @DOC
|
|
258
|
+
#################################################################################################
|
|
259
|
+
|
|
260
|
+
#################################################################################################
|
|
261
|
+
#Region Process Declarations
|
|
262
|
+
### Process Parameters
|
|
263
|
+
# a short description of what the process does goes here in cAction variable, e.g. "copied data from cube A to cube B". This will be written to the message log if pLogOutput=1
|
|
264
|
+
cAction = 'loading rushti stats into ' | pTargetCube;
|
|
265
|
+
cParamArray = '';
|
|
266
|
+
# to use the parameter array remove the line above and uncomment the line below, adding the needed parameters in the provided format
|
|
267
|
+
#cParamArray = 'pLogOutput:%pLogOutput%, pTemp:%pTemp%';
|
|
268
|
+
|
|
269
|
+
### Global Variables
|
|
270
|
+
StringGlobalVariable('sProcessReturnCode');
|
|
271
|
+
NumericGlobalVariable('nProcessReturnCode');
|
|
272
|
+
|
|
273
|
+
### Standard Constants
|
|
274
|
+
cThisProcName = GetProcessName();
|
|
275
|
+
cUserName = TM1User();
|
|
276
|
+
cTimeStamp = TimSt( Now, '\Y\m\d\h\i\s' );
|
|
277
|
+
cRandomInt = NumberToString( INT( RAND( ) * 1000 ));
|
|
278
|
+
cTempObjName = Expand('%cThisProcName%_%cTimeStamp%_%cRandomInt%');
|
|
279
|
+
cViewClr = '}bedrock_clear_' | cTempObjName;
|
|
280
|
+
cViewSrc = '}bedrock_source_' | cTempObjName;
|
|
281
|
+
cMsgErrorLevel = 'ERROR';
|
|
282
|
+
cMsgErrorContent = 'Process:%cThisProcName% ErrorMsg:%sMessage%';
|
|
283
|
+
cLogInfo = 'Process:%cThisProcName% run with parameters %cParamArray%';
|
|
284
|
+
sDelimEleStart = '¦';
|
|
285
|
+
sDelimDim = '&';
|
|
286
|
+
sDelimEle = '+';
|
|
287
|
+
nProcessReturnCode = 0;
|
|
288
|
+
nErrors = 0;
|
|
289
|
+
nMetadataRecordCount= 0;
|
|
290
|
+
nDataRecordCount = 0;
|
|
291
|
+
|
|
292
|
+
### Process Specific Constants
|
|
293
|
+
cFileSrc = pSourceFile;
|
|
294
|
+
cCubeTgt = pTargetCube;
|
|
295
|
+
|
|
296
|
+
#EndRegion Process Declarations
|
|
297
|
+
#################################################################################################
|
|
298
|
+
|
|
299
|
+
### LogOutput parameters
|
|
300
|
+
IF( pLogoutput = 1 );
|
|
301
|
+
LogOutput('INFO', Expand( cLogInfo ) );
|
|
302
|
+
ENDIF;
|
|
303
|
+
|
|
304
|
+
#################################################################################################
|
|
305
|
+
#Region Validate Parameters
|
|
306
|
+
|
|
307
|
+
# pLogOutput
|
|
308
|
+
If( pLogOutput >= 1 );
|
|
309
|
+
pLogOutput = 1;
|
|
310
|
+
Else;
|
|
311
|
+
pLogOutput = 0;
|
|
312
|
+
EndIf;
|
|
313
|
+
|
|
314
|
+
# Validate source file
|
|
315
|
+
If( Trim( cFileSrc ) @= '' );
|
|
316
|
+
nErrors = nErrors + 1;
|
|
317
|
+
sMessage = 'No source cfileube specified.';
|
|
318
|
+
LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );
|
|
319
|
+
ElseIf( FileExists( cFileSrc ) = 0 );
|
|
320
|
+
nErrors = nErrors + 1;
|
|
321
|
+
sMessage = Expand( 'Invalid source file specified: %cFileSrc%.');
|
|
322
|
+
LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );
|
|
323
|
+
EndIf;
|
|
324
|
+
|
|
325
|
+
# Validate target cube
|
|
326
|
+
If( Trim( cCubeTgt ) @= '' );
|
|
327
|
+
nErrors = nErrors + 1;
|
|
328
|
+
sMessage = 'No target cube specified.';
|
|
329
|
+
LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );
|
|
330
|
+
ElseIf( CubeExists( cCubeTgt ) = 0 );
|
|
331
|
+
nErrors = nErrors + 1;
|
|
332
|
+
sMessage = Expand( 'Invalid target cube specified: %cCubeTgt%.');
|
|
333
|
+
LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );
|
|
334
|
+
EndIf;
|
|
335
|
+
|
|
336
|
+
# If any parameters fail validation then set data source of process to null and go directly to epilog
|
|
337
|
+
If( nErrors > 0 );
|
|
338
|
+
DataSourceType = 'NULL';
|
|
339
|
+
If( pStrictErrorHandling = 1 );
|
|
340
|
+
ProcessQuit;
|
|
341
|
+
Else;
|
|
342
|
+
ProcessBreak;
|
|
343
|
+
EndIf;
|
|
344
|
+
EndIf;
|
|
345
|
+
|
|
346
|
+
#################################################################################################
|
|
347
|
+
#EndRegion Validate Parameters
|
|
348
|
+
|
|
349
|
+
#################################################################################################
|
|
350
|
+
#Region - DataSource
|
|
351
|
+
|
|
352
|
+
|
|
211
353
|
### Assign data source
|
|
212
354
|
If( nErrors = 0 );
|
|
213
355
|
DatasourceType = 'CHARACTERDELIMITED';
|
|
@@ -271,7 +413,7 @@ CellPutS(vsucceed_on_minor_errors, pTargetCube, vworkflow, vrun_id, vtask_id, 's
|
|
|
271
413
|
CellPutS(voriginal_task_id, pTargetCube, vworkflow, vrun_id, vtask_id, 'original_task_id');
|
|
272
414
|
"""
|
|
273
415
|
|
|
274
|
-
|
|
416
|
+
PROCESS_EPILOG_V11 = r"""#################################################################################################
|
|
275
417
|
##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0~~##
|
|
276
418
|
#################################################################################################
|
|
277
419
|
|
|
@@ -308,6 +450,42 @@ EndIf;
|
|
|
308
450
|
|
|
309
451
|
### End Epilog ###"""
|
|
310
452
|
|
|
453
|
+
# v12 epilog: source-file cleanup uses TM1-native ASCIIDelete (no shell-out),
|
|
454
|
+
# and the CubeSetLogChanges restore is omitted because the v12 prolog does not
|
|
455
|
+
# toggle transaction logging.
|
|
456
|
+
PROCESS_EPILOG_V12 = r"""#################################################################################################
|
|
457
|
+
##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0~~##
|
|
458
|
+
#################################################################################################
|
|
459
|
+
|
|
460
|
+
#****Begin: Generated Statements***
|
|
461
|
+
#****End: Generated Statements****
|
|
462
|
+
|
|
463
|
+
### If required delete the source file
|
|
464
|
+
if(pDeleteSourceFile=1);
|
|
465
|
+
Sleep(1000);
|
|
466
|
+
ASCIIDelete(pSourceFile);
|
|
467
|
+
endif;
|
|
468
|
+
|
|
469
|
+
### Return code & final error message handling
|
|
470
|
+
If( nErrors > 0 );
|
|
471
|
+
sMessage = 'the process incurred at least 1 error. Please see above lines in this file for more details.';
|
|
472
|
+
nProcessReturnCode = 0;
|
|
473
|
+
LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );
|
|
474
|
+
sProcessReturnCode = Expand( '%sProcessReturnCode% Process:%cThisProcName% completed with errors. Check tm1server.log for details.' );
|
|
475
|
+
If( pStrictErrorHandling = 1 );
|
|
476
|
+
ProcessQuit;
|
|
477
|
+
EndIf;
|
|
478
|
+
Else;
|
|
479
|
+
sProcessAction = Expand( 'Process:%cThisProcName% successfully %cAction%. %nDataRecordCount% records processed.' );
|
|
480
|
+
sProcessReturnCode = Expand( '%sProcessReturnCode% %sProcessAction%' );
|
|
481
|
+
nProcessReturnCode = 1;
|
|
482
|
+
If( pLogoutput = 1 );
|
|
483
|
+
LogOutput('INFO', Expand( sProcessAction ) );
|
|
484
|
+
EndIf;
|
|
485
|
+
EndIf;
|
|
486
|
+
|
|
487
|
+
### End Epilog ###"""
|
|
488
|
+
|
|
311
489
|
PROCESS_PARAMETERS = [
|
|
312
490
|
{
|
|
313
491
|
"Name": "pSourceFile",
|
|
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
|