rbx.cp 0.5.28__py3-none-any.whl → 0.5.29__py3-none-any.whl

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.
rbx/box/main.py CHANGED
@@ -48,6 +48,7 @@ from rbx.box.solutions import (
48
48
  run_solutions,
49
49
  )
50
50
  from rbx.box.statements import build_statements
51
+ from rbx.box.testcases import TestcaseEntry
51
52
 
52
53
  app = typer.Typer(no_args_is_help=True, cls=annotations.AliasGroup)
53
54
  app.add_typer(
@@ -343,6 +344,14 @@ def irun(
343
344
  '-g',
344
345
  help='Generator call to use to generate a single test for execution.',
345
346
  ),
347
+ testcase: Optional[str] = typer.Option(
348
+ None,
349
+ '--testcase',
350
+ '--test',
351
+ '-tc',
352
+ '-t',
353
+ help='Testcase to run, in the format "[group]/[index]". If not specified, will run interactively.',
354
+ ),
346
355
  print: bool = typer.Option(
347
356
  False, '--print', '-p', help='Whether to print outputs to terminal.'
348
357
  ),
@@ -370,13 +379,6 @@ def irun(
370
379
  )
371
380
  return
372
381
 
373
- main_solution = package.get_main_solution()
374
- if check and main_solution is None:
375
- console.console.print(
376
- '[warning]No main solution found, running without checkers.[/warning]'
377
- )
378
- check = False
379
-
380
382
  tracked_solutions = None
381
383
  if outcome is not None:
382
384
  tracked_solutions = {
@@ -411,6 +413,7 @@ def irun(
411
413
  generator=generators.get_call_from_string(generator)
412
414
  if generator is not None
413
415
  else None,
416
+ testcase_entry=TestcaseEntry.parse(testcase) if testcase else None,
414
417
  print=print,
415
418
  sanitized=sanitized,
416
419
  )
rbx/box/schema.py CHANGED
@@ -20,6 +20,12 @@ def NameField(**kwargs):
20
20
  )
21
21
 
22
22
 
23
+ def FNameField(**kwargs):
24
+ return Field(
25
+ pattern=r'^[a-zA-Z0-9][a-zA-Z0-9\-_]*$', min_length=3, max_length=128, **kwargs
26
+ )
27
+
28
+
23
29
  def _check_oneof(model_obj: BaseModel, fields: List[str]):
24
30
  has = []
25
31
  for field in fields:
@@ -100,9 +106,9 @@ class ExpectedOutcome(AutoEnum):
100
106
  if self.match(Outcome.TIME_LIMIT_EXCEEDED):
101
107
  return 'yellow'
102
108
  if self.match(Outcome.RUNTIME_ERROR):
103
- return 'lnumber'
109
+ return 'blue'
104
110
  if self.match(Outcome.MEMORY_LIMIT_EXCEEDED):
105
- return 'cyan'
111
+ return 'yellow'
106
112
  return 'magenta'
107
113
 
108
114
  def is_slow(self) -> bool:
@@ -173,14 +179,14 @@ class Testcase(BaseModel):
173
179
  inputPath: pathlib.Path = Field(description="""The path of the input file.""")
174
180
 
175
181
  outputPath: Optional[pathlib.Path] = Field(
176
- None, description="""The path of the output file."""
182
+ default=None, description="""The path of the output file."""
177
183
  )
178
184
 
179
185
 
180
186
  class GeneratorCall(BaseModel):
181
187
  model_config = ConfigDict(extra='forbid')
182
188
 
183
- name: str = NameField(description='The name of the generator to call.')
189
+ name: str = FNameField(description='The name of the generator to call.')
184
190
 
185
191
  args: Optional[str] = Field(
186
192
  None, description='The arguments to pass to the generator.'
@@ -403,12 +409,15 @@ that is correct and used as reference -- and should have the `accepted` outcome.
403
409
  return res
404
410
 
405
411
  @model_validator(mode='after')
406
- def check_first_solution_is_main(self):
412
+ def check_first_solution_is_main_if_there_is_ac(self):
413
+ if all(sol.outcome != Outcome.ACCEPTED for sol in self.solutions):
414
+ # No main solution.
415
+ return self
407
416
  if self.solutions:
408
417
  if self.solutions[0].outcome != ExpectedOutcome.ACCEPTED:
409
418
  raise PydanticCustomError(
410
419
  'MISSING_MAIN_SOLUTION',
411
- 'The first solution in the package must have the "ACCEPTED" outcome.',
420
+ 'The first solution in the package must have the "ACCEPTED" outcome if there are ACCEPTED solutions.',
412
421
  )
413
422
  return self
414
423
 
rbx/box/solutions.py CHANGED
@@ -16,7 +16,7 @@ import rich.text
16
16
  import typer
17
17
  from pydantic import BaseModel
18
18
 
19
- from rbx import console
19
+ from rbx import console, utils
20
20
  from rbx.box import checkers, package
21
21
  from rbx.box.code import SanitizationLevel, compile_item, find_language_name, run_item
22
22
  from rbx.box.deferred import Deferred
@@ -25,7 +25,13 @@ from rbx.box.environment import (
25
25
  ExecutionConfig,
26
26
  VerificationLevel,
27
27
  )
28
- from rbx.box.generators import generate_output_for_testcase, generate_standalone
28
+ from rbx.box.generators import (
29
+ GenerationMetadata,
30
+ expand_generator_call,
31
+ extract_generation_testcases,
32
+ generate_output_for_testcase,
33
+ generate_standalone,
34
+ )
29
35
  from rbx.box.retries import Retrier
30
36
  from rbx.box.schema import (
31
37
  ExpectedOutcome,
@@ -35,7 +41,7 @@ from rbx.box.schema import (
35
41
  Testcase,
36
42
  TestcaseGroup,
37
43
  )
38
- from rbx.box.testcases import find_built_testcases
44
+ from rbx.box.testcases import TestcaseEntry, find_built_testcases
39
45
  from rbx.grading.steps import (
40
46
  DigestOrDest,
41
47
  DigestOrSource,
@@ -419,26 +425,97 @@ def run_solutions(
419
425
  )
420
426
 
421
427
 
422
- def _run_interactive_solutions(
428
+ async def _generate_testcase_interactively(
423
429
  progress: Optional[StatusProgress] = None,
424
- tracked_solutions: Optional[Set[str]] = None,
425
- verification: VerificationLevel = VerificationLevel.NONE,
426
430
  generator: Optional[GeneratorCall] = None,
431
+ testcase_entry: Optional[TestcaseEntry] = None,
427
432
  check: bool = True,
428
- print: bool = False,
429
433
  sanitized: bool = False,
430
- ) -> Iterator[EvaluationItem]:
431
- pkg = package.find_problem_package_or_die()
434
+ print: bool = False,
435
+ ) -> Testcase:
432
436
  main_solution = package.get_main_solution()
433
- check = check and main_solution is not None
434
-
435
- checker_digest = checkers.compile_checker() if check else None
436
- compiled_solutions = compile_solutions(
437
- progress=progress, tracked_solutions=tracked_solutions, sanitized=sanitized
437
+ irun_dir = package.get_problem_iruns_dir()
438
+ inputs_dir = irun_dir / 'inputs'
439
+ inputs_dir.mkdir(parents=True, exist_ok=True)
440
+ testcase = Testcase(
441
+ inputPath=inputs_dir / '000.in',
442
+ outputPath=(inputs_dir / '000.out') if check else None,
438
443
  )
439
444
 
445
+ is_manual = False
446
+ generation_metadata = None
447
+ if generator is not None:
448
+ generation_metadata = GenerationMetadata(
449
+ generator_call=expand_generator_call(generator),
450
+ copied_to=testcase,
451
+ )
452
+ elif testcase_entry is not None:
453
+ extracted = extract_generation_testcases([testcase_entry])
454
+ if not extracted:
455
+ console.console.print(
456
+ f'[error]Failed searching for testcase [item]{testcase_entry}[/item].[/error]'
457
+ )
458
+ raise typer.Exit(1)
459
+ generation_metadata = extracted[0].metadata
460
+ # Replace destination with the irun testcase we're using.
461
+ generation_metadata.copied_to = testcase
462
+ else:
463
+ with utils.no_progress(progress):
464
+ input = console.multiline_prompt('Testcase input')
465
+ testcase.inputPath.write_text(input)
466
+ console.console.print()
467
+
468
+ if (
469
+ testcase.outputPath is not None
470
+ and not testcase.outputPath.is_file()
471
+ and main_solution is None
472
+ ):
473
+ with utils.no_progress(progress):
474
+ output = console.multiline_prompt('Testcase output')
475
+ testcase.outputPath.write_text(output)
476
+ console.console.print()
477
+
478
+ generation_metadata = GenerationMetadata(
479
+ copied_to=testcase,
480
+ )
481
+ is_manual = True
482
+
483
+ # 1. Generate testcase.
484
+ if generation_metadata is not None:
485
+ generate_standalone(
486
+ generation_metadata,
487
+ progress=progress,
488
+ validate=True,
489
+ )
490
+ if testcase_entry is not None:
491
+ console.console.print(
492
+ f'Using input from testcase [item]{testcase_entry}[/item].'
493
+ )
494
+ elif generation_metadata.generator_call is not None:
495
+ console.console.print(
496
+ f'Using input from generator call [item]{generation_metadata.generator_call.name} {generation_metadata.generator_call.args}[/item].'
497
+ )
498
+ if print and not is_manual:
499
+ console.console.print(testcase.inputPath.read_text())
500
+ else:
501
+ console.console.print(
502
+ f'Input was written to [item]{testcase.inputPath.resolve()}[/item]'
503
+ )
504
+ console.console.print()
505
+
506
+ # 2. Generate test output from reference
440
507
  main_solution_digest = None
441
- if check and main_solution is not None:
508
+ if check and not (
509
+ testcase.outputPath is not None and testcase.outputPath.is_file()
510
+ ):
511
+ if main_solution is None:
512
+ console.console.print(
513
+ '[error]Checking is enabled but no main solution or custom output was specified.[/error]'
514
+ )
515
+ raise typer.Exit(1)
516
+
517
+ if progress:
518
+ progress.update('Compiling main solution...')
442
519
  try:
443
520
  main_solution_digest = compile_item(
444
521
  main_solution,
@@ -452,6 +529,42 @@ def _run_interactive_solutions(
452
529
  )
453
530
  raise
454
531
 
532
+ if main_solution_digest is not None:
533
+ if progress:
534
+ progress.update('Generating output for test...')
535
+ # TODO: Add stderr path
536
+ generate_output_for_testcase(main_solution_digest, testcase)
537
+
538
+ if check and testcase.outputPath is not None and not testcase.outputPath.is_file():
539
+ # Output was not created, throw an error.
540
+ console.console.print(
541
+ '[error]Checking is enabled but no output could be generated for this testcase.[/error]'
542
+ )
543
+ console.console.print(
544
+ '[error]Either specify it explicitly or provide a main solution.[/error]'
545
+ )
546
+ raise typer.Exit(1)
547
+
548
+ return testcase
549
+
550
+
551
+ def _run_interactive_solutions(
552
+ testcase: Testcase,
553
+ progress: Optional[StatusProgress] = None,
554
+ tracked_solutions: Optional[Set[str]] = None,
555
+ verification: VerificationLevel = VerificationLevel.NONE,
556
+ check: bool = True,
557
+ sanitized: bool = False,
558
+ ) -> Iterator[EvaluationItem]:
559
+ pkg = package.find_problem_package_or_die()
560
+
561
+ if check and progress:
562
+ progress.update('Compiling checker...')
563
+ checker_digest = checkers.compile_checker() if check else None
564
+ compiled_solutions = compile_solutions(
565
+ progress=progress, tracked_solutions=tracked_solutions, sanitized=sanitized
566
+ )
567
+
455
568
  solutions = list(enumerate(pkg.solutions))
456
569
  if tracked_solutions is not None:
457
570
  solutions = [
@@ -459,33 +572,9 @@ def _run_interactive_solutions(
459
572
  ]
460
573
 
461
574
  irun_dir = package.get_problem_iruns_dir()
462
- shutil.rmtree(str(irun_dir), ignore_errors=True)
463
- irun_dir.mkdir(parents=True, exist_ok=True)
464
- inputs_dir = irun_dir / 'inputs'
465
- inputs_dir.mkdir(parents=True, exist_ok=True)
466
- input_path = inputs_dir / '000.in'
467
- output_path = input_path.with_suffix('.out')
468
575
 
469
- if generator is not None:
470
- expanded_call = generate_standalone(generator, input_path)
471
- console.console.print(
472
- f'Using input from generator call [item]{expanded_call.name} {expanded_call.args}[/item].'
473
- )
474
- if print:
475
- console.console.print(input_path.read_text())
476
- else:
477
- console.console.print(
478
- f'Input was written to [item]{input_path.resolve()}[/item]'
479
- )
480
- console.console.print()
481
- else:
482
- input = console.multiline_prompt('Testcase input')
483
- input_path.write_text(input)
484
- testcase = Testcase(inputPath=input_path, outputPath=output_path if check else None)
485
-
486
- if main_solution_digest is not None:
487
- # TODO: Add stderr path
488
- generate_output_for_testcase(main_solution_digest, testcase)
576
+ if progress:
577
+ progress.update('Running solutions...')
489
578
 
490
579
  for i, solution in solutions:
491
580
  output_dir = irun_dir / f'{i}'
@@ -513,27 +602,38 @@ async def run_and_print_interactive_solutions(
513
602
  tracked_solutions: Optional[Set[str]] = None,
514
603
  verification: VerificationLevel = VerificationLevel.NONE,
515
604
  generator: Optional[GeneratorCall] = None,
605
+ testcase_entry: Optional[TestcaseEntry] = None,
516
606
  check: bool = True,
517
607
  print: bool = False,
518
608
  sanitized: bool = False,
519
609
  ):
610
+ # Ensure path is new.
611
+ irun_dir = package.get_problem_iruns_dir()
612
+ shutil.rmtree(str(irun_dir), ignore_errors=True)
613
+ irun_dir.mkdir(parents=True, exist_ok=True)
614
+
520
615
  pkg = package.find_problem_package_or_die()
616
+ testcase = await _generate_testcase_interactively(
617
+ progress=progress,
618
+ generator=generator,
619
+ testcase_entry=testcase_entry,
620
+ check=check,
621
+ sanitized=sanitized,
622
+ print=print,
623
+ )
521
624
  items = _run_interactive_solutions(
625
+ testcase,
522
626
  progress=progress,
523
627
  tracked_solutions=tracked_solutions,
524
628
  verification=verification,
525
629
  check=check,
526
- generator=generator,
527
630
  sanitized=sanitized,
528
- print=print,
529
631
  )
530
632
 
531
- if progress:
532
- progress.stop()
533
-
534
633
  for item in items:
535
634
  sol = pkg.solutions[item.solution_index]
536
- _print_solution_header(sol, console.console, is_irun=True)
635
+ with utils.no_progress(progress):
636
+ _print_solution_header(sol, console.console, is_irun=True)
537
637
 
538
638
  eval = await item.eval()
539
639
 
@@ -557,7 +657,7 @@ async def run_and_print_interactive_solutions(
557
657
 
558
658
 
559
659
  def _get_solution_repr(sol: Solution) -> List[Tuple[str, str]]:
560
- fg_color = sol.outcome.style().replace('lnumber', 'cyan')
660
+ fg_color = sol.outcome.style()
561
661
  return [
562
662
  ('', f'{str(sol.path)} '),
563
663
  (f'fg:{fg_color}', sol.outcome.name),
@@ -590,9 +690,9 @@ def get_outcome_style_verdict(outcome: Outcome) -> str:
590
690
  if outcome == Outcome.TIME_LIMIT_EXCEEDED:
591
691
  return 'yellow'
592
692
  if outcome == Outcome.RUNTIME_ERROR:
593
- return 'lnumber'
693
+ return 'blue'
594
694
  if outcome == Outcome.MEMORY_LIMIT_EXCEEDED:
595
- return 'cyan'
695
+ return 'yellow'
596
696
  return 'magenta'
597
697
 
598
698
 
rbx/box/stresses.py CHANGED
@@ -9,7 +9,11 @@ from pydantic import BaseModel
9
9
  from rbx import console
10
10
  from rbx.box import checkers, package, validators
11
11
  from rbx.box.code import SanitizationLevel, compile_item, run_item
12
- from rbx.box.generators import generate_standalone
12
+ from rbx.box.generators import (
13
+ GenerationMetadata,
14
+ expand_generator_call,
15
+ generate_standalone,
16
+ )
13
17
  from rbx.box.retries import Retrier
14
18
  from rbx.box.schema import CodeItem, GeneratorCall, Stress, Testcase
15
19
  from rbx.box.solutions import compile_solutions, get_outcome_style_verdict
@@ -123,9 +127,12 @@ def run_stress(
123
127
  input_path = runs_dir / '.stress' / 'input'
124
128
  input_path.parent.mkdir(parents=True, exist_ok=True)
125
129
 
126
- expanded_generator_call = generate_standalone(
127
- stress.generator,
128
- input_path,
130
+ expanded_generator_call = expand_generator_call(stress.generator)
131
+ generate_standalone(
132
+ GenerationMetadata(
133
+ generator_call=expanded_generator_call,
134
+ copied_to=Testcase(inputPath=input_path),
135
+ ),
129
136
  generator_digest=generator_digest,
130
137
  validator_digest=compiled_validator[1]
131
138
  if compiled_validator is not None
rbx/box/testcases.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import pathlib
2
2
  import shutil
3
- from typing import List
3
+ from typing import List, Tuple
4
4
 
5
5
  import typer
6
6
  from pydantic import BaseModel
@@ -11,6 +11,22 @@ from rbx.box.package import get_build_testgroup_path, get_build_tests_path
11
11
  from rbx.box.schema import Testcase, TestcaseGroup
12
12
 
13
13
 
14
+ class TestcaseEntry(BaseModel):
15
+ group: str
16
+ index: int
17
+
18
+ def key(self) -> Tuple[str, int]:
19
+ return self.group, self.index
20
+
21
+ def __str__(self) -> str:
22
+ return f'{self.group}/{self.index}'
23
+
24
+ @classmethod
25
+ def parse(cls, spec: str) -> 'TestcaseEntry':
26
+ group, index = spec.split('/')
27
+ return TestcaseEntry(group=group.strip(), index=int(index))
28
+
29
+
14
30
  class TestcaseData(BaseModel):
15
31
  input: str
16
32
  output: str
rbx/utils.py CHANGED
@@ -98,12 +98,18 @@ def save_ruyaml(path: pathlib.Path, yml: ruyaml.YAML, data: ruyaml.Any):
98
98
  yml.dump(data, f)
99
99
 
100
100
 
101
- def confirm_on_status(status: Optional[rich.status.Status], *args, **kwargs) -> bool:
101
+ @contextlib.contextmanager
102
+ def no_progress(status: Optional[rich.status.Status]):
102
103
  if status:
103
104
  status.stop()
104
- res = rich.prompt.Confirm.ask(*args, **kwargs, console=console)
105
+ yield
105
106
  if status:
106
107
  status.start()
108
+
109
+
110
+ def confirm_on_status(status: Optional[rich.status.Status], *args, **kwargs) -> bool:
111
+ with no_progress(status):
112
+ res = rich.prompt.Confirm.ask(*args, **kwargs, console=console)
107
113
  return res
108
114
 
109
115
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rbx.cp
3
- Version: 0.5.28
3
+ Version: 0.5.29
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9,<4.0
@@ -32,9 +32,6 @@ Requires-Dist: textual (>=0.79.1,<0.80.0)
32
32
  Requires-Dist: typer (>=0.15.1,<0.16.0)
33
33
  Description-Content-Type: text/markdown
34
34
 
35
- <p align="center">
36
- <img src="docs/rbx_transparent.png" width="240px">
37
- </p>
38
35
  <p align="center">
39
36
  <em>The go-to CLI tool for competitive programmers and setters.</em>
40
37
  </p>
@@ -2,7 +2,7 @@ rbx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  rbx/annotations.py,sha256=Z3jBUyZoXkrz34jko3Rft0bnMME6nWb0vsV5I3HlgR0,3064
3
3
  rbx/autoenum.py,sha256=cusv8ClXRlDVvhZ8eDrtYcL_2peXlHugAey_ht8roXk,12025
4
4
  rbx/box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- rbx/box/builder.py,sha256=0TiRQJoHqLHAI8QwBrscbaJmhdcmialVtP_oEkfHcs0,3260
5
+ rbx/box/builder.py,sha256=eynVPyRdpYtSNmr8MP7-8jspNH74lj-DclwtiIcJrvM,3280
6
6
  rbx/box/cd.py,sha256=9a_SOnzoJBXxxffp4Wbf3UKXIwKuN3Hvj7K6SocALwE,1194
7
7
  rbx/box/checkers.py,sha256=VpgDzevOK7hrffG2zJGxquNiu-a9Fl3wquLn7xadcK0,6285
8
8
  rbx/box/code.py,sha256=sD3kpQaPU8_E5TJFjRL-tgGxz-qyC0oKsyykgQArbJA,11606
@@ -20,9 +20,9 @@ rbx/box/deferred.py,sha256=II3X9e87JCOZtmspnHh-n4PFqh-FsH_oc0XJHZ9ZYVQ,691
20
20
  rbx/box/download.py,sha256=MFP-R26JiYGAP89I0TK-0fYc69Fsd20tsBqgtRCy5AE,2234
21
21
  rbx/box/environment.py,sha256=47NtyuVC6zSQKAtQaXPEXvqcD-KJiuWRpWF8pYvcG4c,11158
22
22
  rbx/box/extensions.py,sha256=gIC73VbF1897er3iIMhaIw6GE8o1t43M7q97Iz7-_lg,503
23
- rbx/box/generators.py,sha256=bzURQrNEscCO8_3BYXCyGK9ZneX4-eOJZP5JJV28f3I,16350
23
+ rbx/box/generators.py,sha256=CVTFHlLton7puNxlfH1tTyOvpIQCb4H-KtmhUyl_si8,20440
24
24
  rbx/box/generators_test.py,sha256=mQqHepAMYa6zV_PseQALI0nIX6AdQktt6lh94muFhNw,1758
25
- rbx/box/main.py,sha256=PZYbC2k6f2pMIuj1-X_yEANCWYstkIXJ7Bg0Szi37YA,23293
25
+ rbx/box/main.py,sha256=ErfFSaMzXs12dmc2PazHYZlhGHjkAwdO1sLtsHz5taI,23428
26
26
  rbx/box/package.py,sha256=SSckCXo7Zh412_qjYhSNwConjhR0Sk8911qGJU34Hac,11851
27
27
  rbx/box/packaging/boca/extension.py,sha256=hQhcbocNfW2ESv5RalS1wf6uvOoOfOnR_gHvbXUbSzY,852
28
28
  rbx/box/packaging/boca/packager.py,sha256=FOhSRg5K5Y4qNB0WyTR3DKgrpObf9I0JbyGpJHOtxpo,10673
@@ -38,9 +38,9 @@ rbx/box/presets/lock_schema.py,sha256=6sRPnyePOC8yy-5WcD5JRZdDJHf8loqbvpQ1IPiOU9
38
38
  rbx/box/presets/schema.py,sha256=mZmSPkQsw7eQM0lQN6er1MO_LiW1ObwwAZFDK0F5fxE,1962
39
39
  rbx/box/retries.py,sha256=z7cIh1QmLVUsTr3Attt_28dbwNg6KWTwpulcWCFwMPo,4667
40
40
  rbx/box/sanitizers/warning_stack.py,sha256=RI97_GJgdjTKIXY_r0EKp5h0qQQSDSdNDh5K7zINrqs,2861
41
- rbx/box/schema.py,sha256=mPEOchzoGDwk_S9wUw1DKqwJWJ0S5GTxQnZIlm9BFwo,13709
41
+ rbx/box/schema.py,sha256=1A-NqOKkXY4QWIwwkWuKQgTR2nJVV_JYEfXmVE9d470,14035
42
42
  rbx/box/setter_config.py,sha256=sg38rzTuT0RNANNV558cSCORvovOK6EIz_ioVzaTkGI,4223
43
- rbx/box/solutions.py,sha256=DDiMfSEsZaipzCZf7raiiIY5HbelIvYQIoyoEjtQlKI,38478
43
+ rbx/box/solutions.py,sha256=AkvAJ2msVj-FHVfT3XwTFrvMXwJEGV_SF3imnvARogg,41871
44
44
  rbx/box/solutions_test.py,sha256=Cx7Goon_0sz_PaUcD8qa8gmjgzOVub6VHss3CB0GaA0,1524
45
45
  rbx/box/statements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  rbx/box/statements/build_statements.py,sha256=upsMT-cAnSvbmKgtijdFc0OxPcyeBxRG92hY6dN-ZOk,11920
@@ -49,11 +49,11 @@ rbx/box/statements/joiners.py,sha256=ZbxomnMjEFT8yf5WSWUB4tBa3DL3AhjGEuh8uqHyDdg
49
49
  rbx/box/statements/latex.py,sha256=LkcHwXjMFxbw--Gj9T1VkFKQFsXhY9dN7xZHpZycNW8,1346
50
50
  rbx/box/statements/latex_jinja.py,sha256=7WBfn1h8DpqCAmSE6Av64HfURMnJ2AO4QX1CD72sz5E,7096
51
51
  rbx/box/statements/schema.py,sha256=g3KgBn4nIqx-0utH8R2FCqPmJP969chhYfn96chQgd4,3851
52
- rbx/box/stresses.py,sha256=ejgNOQNCvfyeDmnOI52iplVKOgx4yLFcEJSVG67NVfs,11556
52
+ rbx/box/stresses.py,sha256=ceFpkZVKBfKKVrKFjeARdub5VGKmU9JPZwj-FxcqYjQ,11771
53
53
  rbx/box/stressing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
54
  rbx/box/stressing/finder_parser.py,sha256=jXpYNa4FyugzmHi3r96Uv4rU1krRQJc5Ihr9jf1cvNo,11918
55
55
  rbx/box/stressing/generator_parser.py,sha256=oHZryjR3YohgaSO9WEirQ7b2e-98WgZStF0N99W4Thw,7380
56
- rbx/box/testcases.py,sha256=bi7T5xXkwyWOkoI6ILcaf2gSSVuuNtZjhP5yL0DJAu4,1452
56
+ rbx/box/testcases.py,sha256=d10qlOLK-gzedL3PYm56eq5R4D_kBjTBC1S9VKlRkz0,1850
57
57
  rbx/box/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
58
  rbx/box/ui/captured_log.py,sha256=ptICDPViVnz-_2NfrcB0SSBXNW5L74zI-vAZNN7kSok,11319
59
59
  rbx/box/ui/css/app.tcss,sha256=apd5PkPEvl5jK3kE2qrxPyVED1VnvSsj08QQwzUPwEA,786
@@ -162,9 +162,9 @@ rbx/testdata/box1/wa.sol.cpp,sha256=qsHmvtLJOFI_sdvUT6ITqk7FJYqhrRTCmEIRdy4gSGE,
162
162
  rbx/testdata/caching/executable.py,sha256=WKRHNf_fprFJd1Fq1ubmQtR3mZzTYVNwKPLWuZ4HrWg,10
163
163
  rbx/testdata/compatible,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
164
164
  rbx/testing_utils.py,sha256=ZZLKMUHlZ4HwsuNY50jqSBJ9HhpnFdba7opjDsvXE1U,2084
165
- rbx/utils.py,sha256=WlmnF4whc0-6ksVZoOhmom2bR2spT6zETFHjnpJOCsA,4383
166
- rbx_cp-0.5.28.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
167
- rbx_cp-0.5.28.dist-info/METADATA,sha256=-USuUd5PUdLlp6Y2Iw4NVwH1w69ELnwu4fkOFG6gKhc,3290
168
- rbx_cp-0.5.28.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
169
- rbx_cp-0.5.28.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
170
- rbx_cp-0.5.28.dist-info/RECORD,,
165
+ rbx/utils.py,sha256=q1ZmfVCD6rdKVVZFBqwVetldSgGAbIh_KLHseBTUSiQ,4511
166
+ rbx_cp-0.5.29.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
167
+ rbx_cp-0.5.29.dist-info/METADATA,sha256=tU0tBGxpQHo5ixeqzCwUZUK3q0JDhoMMv7MUVqPntLM,3212
168
+ rbx_cp-0.5.29.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
169
+ rbx_cp-0.5.29.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
170
+ rbx_cp-0.5.29.dist-info/RECORD,,