rbx.cp 0.5.51__py3-none-any.whl → 0.5.53__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/cli.py CHANGED
@@ -122,10 +122,12 @@ def main(
122
122
  state.STATE.debug_logs = debug_logs
123
123
 
124
124
 
125
- # @app.command('ui', hidden=True)
126
- # @package.within_problem
127
- # def ui():
128
- # ui_pkg.start()
125
+ @app.command('ui', hidden=True)
126
+ @package.within_problem
127
+ def ui():
128
+ from rbx.box.ui import main as ui_pkg
129
+
130
+ ui_pkg.start()
129
131
 
130
132
 
131
133
  @app.command(
rbx/box/code.py CHANGED
@@ -193,7 +193,7 @@ def _check_stack_limit():
193
193
  ```
194
194
  function rbx() {{
195
195
  local rbx_bin=`bash -c "type -P rbx"`
196
- ulimit -s {target_text // 1024} && $rbx_bin $@
196
+ ulimit -s {target_text // 1024} && $rbx_bin "$@"
197
197
  }}
198
198
  ```
199
199
  """
@@ -0,0 +1,18 @@
1
+ import pathlib
2
+
3
+ import mkdocs_gen_files
4
+
5
+ from rbx.box.contest.schema import Contest
6
+ from rbx.box.environment import Environment
7
+ from rbx.box.package import Package
8
+ from rbx.box.presets.lock_schema import PresetLock
9
+ from rbx.box.presets.schema import Preset
10
+ from rbx.box.statements.schema import Statement
11
+ from rbx.utils import dump_schema_str
12
+
13
+ models = [Package, Environment, Contest, Preset, PresetLock, Statement]
14
+
15
+ for model in models:
16
+ path = pathlib.Path('schemas') / f'{model.__name__}.json'
17
+ with mkdocs_gen_files.open(str(path), 'w') as f:
18
+ f.write(dump_schema_str(model))
rbx/box/environment.py CHANGED
@@ -4,7 +4,7 @@ from enum import Enum
4
4
  from typing import Annotated, List, Optional, Type, TypeVar
5
5
 
6
6
  import typer
7
- from pydantic import BaseModel, ConfigDict, ValidationError
7
+ from pydantic import BaseModel, ConfigDict, Field, ValidationError
8
8
 
9
9
  from rbx import config, console, utils
10
10
  from rbx.box.extensions import Extensions, LanguageExtensions
@@ -143,6 +143,13 @@ class EnvironmentLanguage(BaseModel):
143
143
  return self.get_extension(name, cls) or cls()
144
144
 
145
145
 
146
+ class TimingConfig(BaseModel):
147
+ model_config = ConfigDict(extra='forbid')
148
+
149
+ # Formula to use to calculate the time limit for the environment.
150
+ formula: str = 'step_up(max(fastest * 3, slowest * 1.5), 100)'
151
+
152
+
146
153
  class Environment(BaseModel):
147
154
  model_config = ConfigDict(extra='forbid')
148
155
 
@@ -167,6 +174,9 @@ class Environment(BaseModel):
167
174
  # Identifier of the preset that should be used when creating new problems.
168
175
  preset: str = 'default'
169
176
 
177
+ # Timing configuration for the environment.
178
+ timing: TimingConfig = Field(default_factory=TimingConfig)
179
+
170
180
  # Extensions to be added to the environment.
171
181
  extensions: Optional[Extensions] = None
172
182
 
rbx/box/main.py CHANGED
@@ -1,2 +1,6 @@
1
1
  # flake8: noqa
2
+ import nest_asyncio
3
+
4
+ nest_asyncio.apply()
5
+
2
6
  from rbx.box.cli import app
@@ -250,6 +250,24 @@ def _get_statement_blocks(statement: Statement) -> StatementBlocks:
250
250
  )
251
251
 
252
252
 
253
+ def _get_explanations(explanations: Dict[int, str]) -> str:
254
+ entries = []
255
+ for i in sorted(explanations):
256
+ explanation = explanations[i]
257
+ entries.append(f'\\textbf{{Explanation for example {i + 1}}}\n\n{explanation}')
258
+ return '\n\n'.join(entries)
259
+
260
+
261
+ def _get_notes_with_explanations(blocks: StatementBlocks) -> Optional[str]:
262
+ notes = blocks.blocks.get('notes')
263
+ explanations = blocks.explanations
264
+ if notes is None and not explanations:
265
+ return None
266
+ if notes is None:
267
+ return _get_explanations(blocks.explanations)
268
+ return notes + '\n\n' + _get_explanations(blocks.explanations)
269
+
270
+
253
271
  def _upload_statement_resources(problem: api.Problem, statement: Statement):
254
272
  assets = get_relative_assets(statement.path, statement.assets)
255
273
  for asset, relative_asset in assets:
@@ -293,7 +311,7 @@ def _upload_statement(problem: api.Problem):
293
311
  input=blocks.blocks.get('input'),
294
312
  output=blocks.blocks.get('output'),
295
313
  interaction=blocks.blocks.get('interaction'),
296
- notes=blocks.blocks.get('notes'),
314
+ notes=_get_notes_with_explanations(blocks),
297
315
  )
298
316
  problem.save_statement(
299
317
  lang=code_to_langs([language])[0], problem_statement=polygon_statement
@@ -311,8 +329,8 @@ async def upload_problem(name: str):
311
329
  name = _normalize_problem_name(name)
312
330
  problem = _find_or_create_problem(name)
313
331
  _update_problem_info(problem)
314
- _update_checker(problem)
315
332
  _update_rbx_header(problem)
333
+ _update_checker(problem)
316
334
 
317
335
  if (
318
336
  pkg.type == TaskType.COMMUNICATION
rbx/box/solutions.py CHANGED
@@ -5,7 +5,7 @@ import dataclasses
5
5
  import pathlib
6
6
  import shutil
7
7
  from collections.abc import Iterator
8
- from typing import Dict, Iterable, List, Optional, Set, Tuple
8
+ from typing import Any, Dict, Iterable, List, Optional, Set, Tuple
9
9
 
10
10
  import rich
11
11
  import rich.live
@@ -16,7 +16,7 @@ import typer
16
16
  from pydantic import BaseModel
17
17
 
18
18
  from rbx import console, utils
19
- from rbx.box import checkers, package
19
+ from rbx.box import checkers, environment, package
20
20
  from rbx.box.code import (
21
21
  SanitizationLevel,
22
22
  compile_item,
@@ -1244,6 +1244,16 @@ async def print_run_report(
1244
1244
  return ok
1245
1245
 
1246
1246
 
1247
+ def _step_up(x: Any, step: int) -> int:
1248
+ x = int(x)
1249
+ return (x + step - 1) // step * step
1250
+
1251
+
1252
+ def _step_down(x: Any, step: int) -> int:
1253
+ x = int(x)
1254
+ return x // step * step
1255
+
1256
+
1247
1257
  async def estimate_time_limit(
1248
1258
  console: rich.console.Console,
1249
1259
  result: RunSolutionResult,
@@ -1262,12 +1272,12 @@ async def estimate_time_limit(
1262
1272
  for solution in result.skeleton.solutions:
1263
1273
  timings = []
1264
1274
  for evals in structured_evaluations[str(solution.path)].values():
1265
- for eval in evals:
1266
- if eval is None:
1275
+ for ev in evals:
1276
+ if ev is None:
1267
1277
  continue
1268
- eval = await eval()
1269
- if eval.log.time is not None:
1270
- timings.append(int(eval.log.time * 1000))
1278
+ ev = await ev()
1279
+ if ev.log.time is not None:
1280
+ timings.append(int(ev.log.time * 1000))
1271
1281
 
1272
1282
  if not timings:
1273
1283
  console.print(
@@ -1301,7 +1311,19 @@ async def estimate_time_limit(
1301
1311
  f'Slowest language: {slowest_language} ({slowest_language_time} ms)'
1302
1312
  )
1303
1313
 
1304
- estimated_tl = int(max(fastest_time * 3, slowest_time * 1.5))
1305
- console.print(f'[success]Estimated time limit:[/success] {estimated_tl} ms')
1314
+ env = environment.get_environment()
1315
+ estimated_tl = int(
1316
+ eval(
1317
+ env.timing.formula,
1318
+ {
1319
+ 'fastest': fastest_time,
1320
+ 'slowest': slowest_time,
1321
+ 'step_up': _step_up,
1322
+ 'step_down': _step_down,
1323
+ },
1324
+ )
1325
+ )
1306
1326
 
1327
+ console.print(f'Using formula: {env.timing.formula}')
1328
+ console.print(f'[success]Estimated time limit:[/success] {estimated_tl} ms')
1307
1329
  return estimated_tl
rbx/box/stresses.py CHANGED
@@ -1,8 +1,8 @@
1
- import functools
2
1
  import time
3
2
  from shutil import rmtree
4
3
  from typing import List, Optional
5
4
 
5
+ import async_lru
6
6
  import syncer
7
7
  import typer
8
8
  from pydantic import BaseModel
@@ -147,7 +147,7 @@ async def run_stress(
147
147
  else None,
148
148
  )
149
149
 
150
- @functools.cache
150
+ @async_lru.alru_cache
151
151
  async def run_solution_fn(
152
152
  solution: str,
153
153
  retry_index: Optional[int] = None,
@@ -197,7 +197,7 @@ async def run_stress(
197
197
  raise typer.Exit(1)
198
198
  expected_output_path = main_testcase_log.stdout_absolute_path
199
199
 
200
- @functools.cache
200
+ @async_lru.alru_cache
201
201
  async def run_solution_and_checker_fn(
202
202
  call: finder_parser.FinderCall,
203
203
  input_path=input_path,
@@ -242,9 +242,12 @@ async def run_stress(
242
242
  checker_result=eval.result,
243
243
  )
244
244
 
245
- runner = finder_parser.FinderTreeRunner(
246
- runner=syncer.sync(run_solution_and_checker_fn)
247
- )
245
+ @syncer.sync
246
+ async def run_fn(*args, **kwargs):
247
+ # Wrap the runner in a syncer.sync to make it work with the finder parser.
248
+ return await run_solution_and_checker_fn(*args, **kwargs)
249
+
250
+ runner = finder_parser.FinderTreeRunner(runner=run_fn)
248
251
  finder_outcome: finder_parser.FinderOutcome = runner.transform(parsed_finder)
249
252
 
250
253
  internal_error_results = [
@@ -8,7 +8,7 @@ import re
8
8
  import signal
9
9
  import struct
10
10
  import termios
11
- from typing import Callable, List, Optional
11
+ from typing import Callable, List, Optional, Tuple
12
12
 
13
13
  import pyte
14
14
  import textual
@@ -321,10 +321,14 @@ class LogDisplay(ScrollView, can_focus=True):
321
321
  loop.remove_reader(pout)
322
322
  event.set()
323
323
 
324
- async def cleanup():
324
+ async def cleanup(wait_tp: Optional[Tuple[int, int]] = None):
325
+ if self.exitcode is not None:
326
+ return
325
327
  try:
326
328
  loop.remove_reader(pout)
327
- _, exitstatus = os.waitpid(pid, os.WNOHANG)
329
+ if wait_tp is None:
330
+ wait_tp = os.waitpid(pid, os.WNOHANG)
331
+ _, exitstatus = wait_tp
328
332
  exitcode = os.waitstatus_to_exitcode(exitstatus)
329
333
  self.exitcode = exitcode
330
334
  except ChildProcessError:
@@ -352,8 +356,8 @@ class LogDisplay(ScrollView, can_focus=True):
352
356
  async def wait():
353
357
  while True:
354
358
  try:
355
- if os.waitpid(pid, os.WNOHANG) != (0, 0):
356
- await cleanup()
359
+ if (wait_tp := os.waitpid(pid, os.WNOHANG)) != (0, 0):
360
+ await cleanup(wait_tp)
357
361
  except ChildProcessError:
358
362
  break
359
363
  await asyncio.sleep(0.5)
rbx/box/ui/css/app.tcss CHANGED
@@ -3,7 +3,7 @@ Screen {
3
3
  color: $text;
4
4
  }
5
5
 
6
- rbxApp > Screen {
6
+ Screen {
7
7
  align: center middle;
8
8
  }
9
9
 
rbx/box/ui/run.py CHANGED
@@ -4,7 +4,7 @@ from typing import Optional, Set
4
4
  import textual
5
5
  from rich.text import Text
6
6
  from textual.app import ComposeResult
7
- from textual.containers import Center, Container, Grid
7
+ from textual.containers import Center, Grid
8
8
  from textual.coordinate import Coordinate
9
9
  from textual.screen import Screen
10
10
  from textual.widgets import Button, DataTable, Footer, Header, SelectionList
@@ -57,12 +57,12 @@ class SolutionReportScreen(Screen):
57
57
  cursor_type='row', cursor_foreground_priority='renderable'
58
58
  )
59
59
  if self.log_display_state is not None:
60
- yield LogDisplay()
60
+ yield LogDisplay(id='build-output')
61
61
 
62
62
  def on_mount(self):
63
- self.query_one(
64
- '#build-output', Container
65
- ).border_title = 'Test generation and validation'
63
+ # self.query_one(
64
+ # '#build-output', Container
65
+ # ).border_title = 'Test generation and validation'
66
66
  for solution, table in zip(
67
67
  self.skeleton.solutions,
68
68
  self.query(DataTable),
@@ -86,8 +86,7 @@ class SolutionReportScreen(Screen):
86
86
  return i
87
87
  raise
88
88
 
89
- def process(self, item: EvaluationItem):
90
- textual.log(item)
89
+ async def process(self, item: EvaluationItem):
91
90
  pkg = package.find_problem_package_or_die()
92
91
  sol_idx_in_skeleton = self._find_solution_index_in_skeleton(
93
92
  pkg.solutions[item.solution_index]
@@ -102,12 +101,12 @@ class SolutionReportScreen(Screen):
102
101
 
103
102
  table.update_cell_at(
104
103
  Coordinate(row=row_idx, column=2),
105
- get_testcase_markup_verdict(item.eval),
104
+ get_testcase_markup_verdict(await item.eval()),
106
105
  update_width=True,
107
106
  )
108
107
  table.update_cell_at(
109
108
  Coordinate(row=row_idx, column=3),
110
- get_evals_formatted_time([item.eval]),
109
+ get_evals_formatted_time([await item.eval()]),
111
110
  update_width=True,
112
111
  )
113
112
 
@@ -158,11 +157,11 @@ class RunScreen(Screen):
158
157
  def on_screen_resume(self):
159
158
  self.query_one('#run-sols', SelectionList).focus()
160
159
 
161
- def on_button_pressed(self, _: Button.Pressed):
162
- self.action_run()
160
+ async def on_button_pressed(self, _: Button.Pressed):
161
+ await self.action_run()
163
162
 
164
163
  @textual.work(thread=True)
165
- def _run_solutions(self, tracked_solutions: Set[str], check: bool):
164
+ async def _run_solutions(self, tracked_solutions: Set[str], check: bool):
166
165
  main_solution = package.get_main_solution()
167
166
  if check and main_solution is None:
168
167
  console.console.print(
@@ -176,9 +175,11 @@ class RunScreen(Screen):
176
175
  exitcode = self.app.call_from_thread(build)
177
176
 
178
177
  if exitcode != 0:
179
- textual.log('early quit')
178
+ textual.log(f'early quit: {exitcode}')
180
179
  return
181
180
 
181
+ textual.log('build finished ok, running solutions')
182
+
182
183
  res = run_solutions(tracked_solutions=tracked_solutions, check=check)
183
184
 
184
185
  async def mount_report_widget() -> SolutionReportScreen:
@@ -191,15 +192,15 @@ class RunScreen(Screen):
191
192
  )
192
193
  return screen
193
194
 
194
- new_screen = self.app.call_from_thread(mount_report_widget)
195
+ new_screen = await mount_report_widget()
195
196
 
196
- def process(item: EvaluationItem):
197
- new_screen.process(item)
197
+ async def process_item(item: EvaluationItem):
198
+ await new_screen.process(item)
198
199
 
199
200
  for item in res.items:
200
- self.app.call_from_thread(process, item)
201
+ self.app.call_from_thread(process_item, item)
201
202
 
202
- def action_run(self):
203
+ async def action_run(self):
203
204
  sols = self.query_one('#run-sols', SelectionList)
204
205
  config = self.query_one('#run-config', SelectionList)
205
206
 
rbx/testing_utils.py CHANGED
@@ -17,9 +17,9 @@ def get_testdata_path() -> pathlib.Path:
17
17
 
18
18
 
19
19
  def clear_all_functools_cache():
20
- from rbx.box import environment, package
20
+ from rbx.box import environment, header, package
21
21
 
22
- pkgs = [environment, package]
22
+ pkgs = [environment, package, header]
23
23
 
24
24
  for pkg in pkgs:
25
25
  for fn in pkg.__dict__.values():
rbx/utils.py CHANGED
@@ -57,21 +57,32 @@ def get_app_path() -> pathlib.Path:
57
57
  return pathlib.Path(app_dir)
58
58
 
59
59
 
60
- def ensure_schema(model: Type[BaseModel]) -> pathlib.Path:
61
- path = get_app_path() / 'schemas' / f'{model.__name__}.json'
60
+ def dump_schema_str(model: Type[BaseModel]) -> str:
61
+ return json.dumps(model.model_json_schema(), indent=4)
62
+
63
+
64
+ def dump_schema(model: Type[BaseModel], path: pathlib.Path):
62
65
  path.parent.mkdir(parents=True, exist_ok=True)
63
- schema = json.dumps(model.model_json_schema(), indent=4)
66
+ schema = dump_schema_str(model)
64
67
  path.write_text(schema)
68
+
69
+
70
+ def ensure_schema(model: Type[BaseModel]) -> pathlib.Path:
71
+ path = get_app_path() / 'schemas' / f'{model.__name__}.json'
72
+ dump_schema(model, path)
65
73
  return path.resolve()
66
74
 
67
75
 
68
76
  def model_json(model: BaseModel) -> str:
69
- ensure_schema(model.__class__)
70
77
  return model.model_dump_json(indent=4, exclude_unset=True, exclude_none=True)
71
78
 
72
79
 
80
+ def uploaded_schema_path(model: Type[BaseModel]) -> str:
81
+ return f'https://rsalesc.github.io/rbx/schemas/{model.__name__}.json'
82
+
83
+
73
84
  def model_to_yaml(model: BaseModel) -> str:
74
- path = ensure_schema(model.__class__)
85
+ path = uploaded_schema_path(model.__class__)
75
86
  return f'# yaml-language-server: $schema={path}\n\n' + yaml.dump(
76
87
  model.model_dump(mode='json', exclude_unset=True, exclude_none=True),
77
88
  sort_keys=False,
@@ -80,7 +91,6 @@ def model_to_yaml(model: BaseModel) -> str:
80
91
 
81
92
 
82
93
  def model_from_yaml(model: Type[T], s: str) -> T:
83
- ensure_schema(model)
84
94
  return model(**yaml.safe_load(s))
85
95
 
86
96
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rbx.cp
3
- Version: 0.5.51
3
+ Version: 0.5.53
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9,<4.0
@@ -10,6 +10,7 @@ Classifier: Programming Language :: Python :: 3.10
10
10
  Classifier: Programming Language :: Python :: 3.11
11
11
  Classifier: Programming Language :: Python :: 3.12
12
12
  Classifier: Programming Language :: Python :: 3.13
13
+ Requires-Dist: async-lru (>=2.0.5,<3.0.0)
13
14
  Requires-Dist: chardet (>=5.2.0,<6.0.0)
14
15
  Requires-Dist: fastapi (>=0.115.8,<0.116.0)
15
16
  Requires-Dist: filelock (>=3.14.0,<4.0.0)
@@ -19,6 +20,7 @@ Requires-Dist: lark (>=1.2.2,<2.0.0)
19
20
  Requires-Dist: latexbuild (>=0.2.2,<0.3.0)
20
21
  Requires-Dist: mechanize (>=0.4.10,<0.5.0)
21
22
  Requires-Dist: more-itertools (>=10.5.0,<11.0.0)
23
+ Requires-Dist: nest-asyncio (>=1.6.0,<2.0.0)
22
24
  Requires-Dist: pydantic (==2.8.2)
23
25
  Requires-Dist: pydantic-xml[lxml] (>=2.11.0,<3.0.0)
24
26
  Requires-Dist: pyte (>=0.8.2,<0.9.0)
@@ -5,8 +5,8 @@ rbx/box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  rbx/box/builder.py,sha256=MDm2qqmhedAbhn3rWP6cDwbBsGhV6sz_2sg1zLkPDw0,3613
6
6
  rbx/box/cd.py,sha256=9a_SOnzoJBXxxffp4Wbf3UKXIwKuN3Hvj7K6SocALwE,1194
7
7
  rbx/box/checkers.py,sha256=eb4tqtVUJYlme_Vkj2TGkUABM7EMS0P1EswhMYjN7BI,11459
8
- rbx/box/cli.py,sha256=lGyAa5WrK8h61QWC2OrOWuC8Va0VOZedQnY-_0uOp3k,26703
9
- rbx/box/code.py,sha256=g2e3PPGQFNRnMBkTuqw3D4nFS8hnvzNCDc4vVSYGugY,18846
8
+ rbx/box/cli.py,sha256=GPoGDgmaV1lXL9puXhUbZUIEU0lOMvdH1kD4TGCXkCo,26738
9
+ rbx/box/code.py,sha256=hmA2EoGOr13AYzicHNsnU2SkFW-44l7kOdu8QRwTJlI,18848
10
10
  rbx/box/compile.py,sha256=OJLthDQ921w9vyoE6Gk1Df54i5RwtRJ2YG-8XEfefcs,2489
11
11
  rbx/box/conftest.py,sha256=sEmciXSeDC-wmrZ1JSxbsUenKNP_VWW32mrCun2pY3I,1070
12
12
  rbx/box/contest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -19,7 +19,8 @@ rbx/box/contest/statements.py,sha256=Or8gFb6P_oViGdeiVgepXsvd_W84mA7LRaVmiAXWWSg
19
19
  rbx/box/creation.py,sha256=Evz7K6JoarD-4JJQsZsgoxU9FgCF9Z7-LfuroG4Cqls,2444
20
20
  rbx/box/deferred.py,sha256=II3X9e87JCOZtmspnHh-n4PFqh-FsH_oc0XJHZ9ZYVQ,691
21
21
  rbx/box/download.py,sha256=DxAiAk4lDYWEz1C9UTvZzHTq6hgm4fxGezApm2IkCTM,2601
22
- rbx/box/environment.py,sha256=S-OLvR2_Nac8m923b9AtDhOY3goRJXlPA_I3s7BeDqQ,11162
22
+ rbx/box/dump_schemas.py,sha256=3j5t47_vJmXj0BCczxDX6ByOcsfolGEDNCBXlPpk86w,593
23
+ rbx/box/environment.py,sha256=fZnNQCdpG3xzKne0FY7gkuaopy6fdYvVFAXeHmC1ZOo,11498
23
24
  rbx/box/extensions.py,sha256=Von8kIeXvNFTkGlMRMTvL2HIHPwlkuiMswr-ydbGV1w,519
24
25
  rbx/box/formatting.py,sha256=3phFRHzqVXj4Ok1yDhCq6Clbw6KlqwJNpMhs--oTWFI,405
25
26
  rbx/box/generators.py,sha256=5-3K0JSLR9GbV0LmOkvNsWiQaMvhFBrI56ZaV1WgodQ,13472
@@ -27,7 +28,7 @@ rbx/box/generators_test.py,sha256=J7aBfuJhU84MWDWzgReRoOuQw_hVa09B8gTKAvL2XVo,19
27
28
  rbx/box/header.py,sha256=ifErXcIxG5lM5AyRiHDr7JE401vR4ORNXCNpHXxN_ls,2001
28
29
  rbx/box/lazy_importing_main.py,sha256=6Z8As7qVFFT619xHH9Xt8VCH57NjC4aDxfAgkWiUwT8,116
29
30
  rbx/box/lazy_importing_test.py,sha256=B0-b3y_DkxEmtVfu4NfmVsgVdFl6kRCsEL6GLMHJISo,628
30
- rbx/box/main.py,sha256=Imwc0ZkheOpa5r8S0Xpb8RLQzJgxb9vyuSR4_wab11g,43
31
+ rbx/box/main.py,sha256=a8CYi77kOywPFly4-ucEIJLXQW-1NFp91kK2fA42YTE,86
31
32
  rbx/box/naming.py,sha256=OiaiLe0k1sBx4vIXemUqnzfdNte79rrCgOvBze9XaTw,940
32
33
  rbx/box/package.py,sha256=YuX_FS6yKx6FaFz0NF0cx3v6jzhqwvsLr3Oprx_TTJA,13645
33
34
  rbx/box/packaging/boca/extension.py,sha256=EQALNEOv4zVDXSKs_dk11n92y7cBZVn8TogIK683lE0,890
@@ -39,7 +40,7 @@ rbx/box/packaging/packager.py,sha256=da2haC1L9cG30myneMrRIAdGubtid0Xmy38BHKPCZZ4
39
40
  rbx/box/packaging/polygon/packager.py,sha256=GfZ-Dc2TDKkb3QNnfOy8yxldho2L401Ao06oWg--Gcs,11714
40
41
  rbx/box/packaging/polygon/polygon_api.py,sha256=mPKEqiwANJ1nr-JhOgzGMaDhnbljsAgzzPHW6kkf7R4,41016
41
42
  rbx/box/packaging/polygon/test.py,sha256=bgEju5PwudgyfwxXJagm8fM6CJVlWM6l_-2q1V-oKaQ,3069
42
- rbx/box/packaging/polygon/upload.py,sha256=2WyEXlfprLUDbq-9AMB5hXOQVvvmsT1-stO60MHrEo0,11182
43
+ rbx/box/packaging/polygon/upload.py,sha256=woaqf2vcWmvCyBXtAesBUOaMcVUns3hkuzXqzcgAjyo,11826
43
44
  rbx/box/packaging/polygon/xml_schema.py,sha256=ZgcLyvxggMUccbTNdzflue5G-FTN2_ZmOGGF7FD0Y5A,2851
44
45
  rbx/box/presets/__init__.py,sha256=BwmjBw8wF8yiZFjCYBjMk-HGMZaRwhlfszbWAj3B0vw,18689
45
46
  rbx/box/presets/fetch.py,sha256=F-BCOlvEBEyDqtOhiDuGPn4EDtA4Bwm-fqHJ7zZGlW8,1975
@@ -49,7 +50,7 @@ rbx/box/retries.py,sha256=tRk2K1bXw2xnwkAj2CsktRHTEhw7YKcPxMQTT6mCy-E,4707
49
50
  rbx/box/sanitizers/warning_stack.py,sha256=RI97_GJgdjTKIXY_r0EKp5h0qQQSDSdNDh5K7zINrqs,2861
50
51
  rbx/box/schema.py,sha256=tOQ1tLHqc_5V-UgrzM44aS8ULAkq-IkeErxjLCFVA8I,16778
51
52
  rbx/box/setter_config.py,sha256=s53talhwM6FTGDCcBhY7IlZ6_6mJ3PMp6V4kTtaSs50,4262
52
- rbx/box/solutions.py,sha256=zv6jYdJG8cLFe0rNO3f7pgGYnXQaeECYXOo5CQ90VBs,44155
53
+ rbx/box/solutions.py,sha256=1DnO6iygX9IflVk5ierP0oL9LS8EuU2cSui8z1YhN08,44653
53
54
  rbx/box/solutions_test.py,sha256=TCowbxBG3SvDlFO5-qtBj_M_HrAHe0IJaI1XwoQ1d00,1718
54
55
  rbx/box/state.py,sha256=MMf3DvfQji0jKEliCHct2Tpp_0epL1tvP8HbHNArQIc,166
55
56
  rbx/box/statements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -59,7 +60,7 @@ rbx/box/statements/joiners.py,sha256=jItNXkAbTjFQpPMgfDMW86n3vMTbaE8sgo9I8Yf4Txg
59
60
  rbx/box/statements/latex.py,sha256=LkcHwXjMFxbw--Gj9T1VkFKQFsXhY9dN7xZHpZycNW8,1346
60
61
  rbx/box/statements/latex_jinja.py,sha256=7WBfn1h8DpqCAmSE6Av64HfURMnJ2AO4QX1CD72sz5E,7096
61
62
  rbx/box/statements/schema.py,sha256=ES8EUE9JE_uJlDwQx1kZd_5nQJyABtlnjP5IjbWaJ-0,3897
62
- rbx/box/stresses.py,sha256=cY7cCqnCs_bO61MrsUDJGxL4oZDaR5_4ifgPLD7XdSM,12134
63
+ rbx/box/stresses.py,sha256=k-m8Q2IVd5dap2fSDCbVqLj2LKqXzz6rIR8j9F8sLhY,12310
63
64
  rbx/box/stressing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
65
  rbx/box/stressing/finder_parser.py,sha256=jXpYNa4FyugzmHi3r96Uv4rU1krRQJc5Ihr9jf1cvNo,11918
65
66
  rbx/box/stressing/generator_parser.py,sha256=oHZryjR3YohgaSO9WEirQ7b2e-98WgZStF0N99W4Thw,7380
@@ -69,10 +70,10 @@ rbx/box/testcase_utils.py,sha256=31rvCpLi681R6Xm1WpG8HPDOkTtF0bRWa8IsmdWGLCk,755
69
70
  rbx/box/testcases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
71
  rbx/box/testcases/main.py,sha256=_I7h_obRcpNLRQ6dDJDIE5NAvTyn5nBOhdsBhRA_PvU,5442
71
72
  rbx/box/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
- rbx/box/ui/captured_log.py,sha256=ptICDPViVnz-_2NfrcB0SSBXNW5L74zI-vAZNN7kSok,11319
73
- rbx/box/ui/css/app.tcss,sha256=apd5PkPEvl5jK3kE2qrxPyVED1VnvSsj08QQwzUPwEA,786
73
+ rbx/box/ui/captured_log.py,sha256=BIlhMFrDcWFa9YD8pUY21G-fJSIBzAz9lpaCZH2WJmc,11526
74
+ rbx/box/ui/css/app.tcss,sha256=88tmZCnn4Y2wD-JFEGHoD3VuJGhMU7S7rM2k8FHUZek,777
74
75
  rbx/box/ui/main.py,sha256=b0rHcBF42W4AOCv7WhtiGf_rUnY0yxpqO5oj3wfR4R4,984
75
- rbx/box/ui/run.py,sha256=wMEXrEFdQvMHz2hRKAFIithTnTtaL0kNQZu0jKmb8jI,7060
76
+ rbx/box/ui/run.py,sha256=Ed5zk3kg3vMggQCud-5GimfGL_n_QwtgATiIim5HYw0,7169
76
77
  rbx/box/unit.py,sha256=PY96t8qnsHLsoJVanbDnrIx-s8Dada9Fj_v375MhvTw,6477
77
78
  rbx/box/validators.py,sha256=oqlNhw7jivbbH5l8g3xwihPRy76AM7MA3G4A8nyI_V0,10416
78
79
  rbx/box/validators_test.py,sha256=WY4Ho-wlsPHc0YNuz0KFVd6KQ9ouuiou3w5_zMOZ4Fs,362
@@ -190,10 +191,10 @@ rbx/submitors/submitor.py,sha256=8q-Hbdahxt30ciT_R9j_xF6lEPUh9IcfAUnzjQjbvHU,457
190
191
  rbx/test.py,sha256=tZyTrXDK8MLR-1TyCRxiOiNz-PhlXVpshfUGphakkT4,11830
191
192
  rbx/testcase.py,sha256=yKOq3CAJZ1YTmInvnoIs0u1iJnRj_X85XiWbLI-p9d8,1951
192
193
  rbx/testcase_rendering.py,sha256=nfmv6dSEqd4aR3TsaODwkKGK6AXty_DDKtWf_ejiQpI,2084
193
- rbx/testing_utils.py,sha256=ZXMysGXpTtvS1lfLL38FuD5iSIyxi3ARjQePDrUmEtc,2067
194
- rbx/utils.py,sha256=6e1eXRzNE-52D0UVtqclePxqR4Haiqt8qWCrSVjnGuE,4585
195
- rbx_cp-0.5.51.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
196
- rbx_cp-0.5.51.dist-info/METADATA,sha256=wALvGgPfDA7gajXxA98TcHv67w54c_zWxRH7uXIMo_4,3261
197
- rbx_cp-0.5.51.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
198
- rbx_cp-0.5.51.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
199
- rbx_cp-0.5.51.dist-info/RECORD,,
194
+ rbx/testing_utils.py,sha256=x_PqD8Zd2PkN91NxVHUnSTs044-1WK5KKtttKQBXpFs,2083
195
+ rbx/utils.py,sha256=SfR844_i0ebRDMkmS_w1YdZiWPc6h2RGADygewlWRbA,4845
196
+ rbx_cp-0.5.53.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
197
+ rbx_cp-0.5.53.dist-info/METADATA,sha256=Gy6mjUs1yQKV0576ZRyBp5g3mjvxbU2L4t2xFf1u39s,3348
198
+ rbx_cp-0.5.53.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
199
+ rbx_cp-0.5.53.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
200
+ rbx_cp-0.5.53.dist-info/RECORD,,