html = '<STR_LIT>'<EOL>return html % (self.hrule(), text)<EOL>

Wrapper for all footnotes.

        :param text: contents of all footnotes.


if self.options.get('<STR_LIT>'):<EOL><INDENT>return '<STR_LIT>'<EOL><DEDENT>return '<STR_LIT>'<EOL>


src = escape_link(src)<EOL>text = escape(text, quote=True)<EOL>if title:<EOL><INDENT>title = escape(title, quote=True)<EOL>html = '<STR_LIT>' % (src, text, title)<EOL><DEDENT>else:<EOL><INDENT>html = '<STR_LIT>' % (src, text)<EOL><DEDENT>if self.options.get('<STR_LIT>'):<EOL><INDENT>return '<STR_LIT>' % html<EOL><DEDENT>return '<STR_LIT>' % html<EOL>

Rendering a image with title and text.

        :param src: source link of the image.
        :param title: title text of the image.
        :param text: alt text of the image.


return '<STR_LIT>' % text.rstrip('<STR_LIT:\n>')<EOL>

Rendering <blockquote> with the given text.

        :param text: text content of the blockquote.


if self.options.get('<STR_LIT>') andhtml.lower().startswith('<STR_LIT>'):<EOL><INDENT>return '<STR_LIT>'<EOL><DEDENT>if self.options.get('<STR_LIT>'):<EOL><INDENT>return escape(html)<EOL><DEDENT>return html<EOL>

Rendering block level pure html content.

        :param html: text content of the html snippet.


html = (<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>) % (escape(key), escape(key), index)<EOL>return html<EOL>

Rendering the ref anchor of a footnote.

        :param key: identity key for the footnote.
        :param index: the index count of current footnote.


return '<STR_LIT>'<EOL>

Returns the default, empty output value for the renderer.

        All renderer methods use the '+=' operator to append to this value.
        Default is a string so rendering HTML can build up a result string with
        the rendered Markdown.

        Can be overridden by Renderer subclasses to be types like an empty
        list, allowing the renderer to create a tree-like structure to
        represent the document (which can then be reprocessed later into a
        separate format like docx or pdf).


def process_docstring(app, what, name, obj, options, lines):

markdown = "<STR_LIT:\n>".join(lines)<EOL>rest = m2r(markdown)<EOL>rest.replace("<STR_LIT:\r\n>", "<STR_LIT:\n>")<EOL>del lines[:]<EOL>lines.extend(rest.split("<STR_LIT:\n>"))<EOL>


return self.renderer.rest_role(m.group(<NUM_LIT:0>))<EOL>


return self.renderer.image_link(<EOL>m.group('<STR_LIT:url>'), m.group('<STR_LIT:target>'), m.group('<STR_LIT>'))<EOL>


return '<STR_LIT>'.format(text)<EOL>

Rendering *emphasis* text.

        :param text: text content for emphasis.


mark = '<STR_LIT>' if ordered else '<STR_LIT>'<EOL>lines = body.splitlines()<EOL>for i, line in enumerate(lines):<EOL><INDENT>if line and not line.startswith(self.list_marker):<EOL><INDENT>lines[i] = '<STR_LIT:U+0020>' * len(mark) + line<EOL><DEDENT><DEDENT>return '<STR_LIT>'.format(<EOL>'<STR_LIT:\n>'.join(lines)).replace(self.list_marker, mark)<EOL>

Rendering list tags like ``<ul>`` and ``<ol>``.

        :param body: body contents of the list.
        :param ordered: whether this list is ordered or not.


if not self.state.document.settings.file_insertion_enabled:<EOL><INDENT>raise self.warning('<STR_LIT>' % self.name)<EOL><DEDENT>source = self.state_machine.input_lines.source(<EOL>self.lineno - self.state_machine.input_offset - <NUM_LIT:1>)<EOL>source_dir = os.path.dirname(os.path.abspath(source))<EOL>path = rst.directives.path(self.arguments[<NUM_LIT:0>])<EOL>path = os.path.normpath(os.path.join(source_dir, path))<EOL>path = utils.relative_path(None, path)<EOL>path = nodes.reprunicode(path)<EOL>encoding = self.options.get(<EOL>'<STR_LIT>', self.state.document.settings.input_encoding)<EOL>e_handler = self.state.document.settings.input_encoding_error_handler<EOL>tab_width = self.options.get(<EOL>'<STR_LIT>', self.state.document.settings.tab_width)<EOL>try:<EOL><INDENT>self.state.document.settings.record_dependencies.add(path)<EOL>include_file = io.FileInput(source_path=path,<EOL>encoding=encoding,<EOL>error_handler=e_handler)<EOL><DEDENT>except UnicodeEncodeError as error:<EOL><INDENT>raise self.severe('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(self.name, SafeString(path)))<EOL><DEDENT>except IOError as error:<EOL><INDENT>raise self.severe('<STR_LIT>' %<EOL>(self.name, ErrorString(error)))<EOL><DEDENT>try:<EOL><INDENT>rawtext = include_file.read()<EOL><DEDENT>except UnicodeError as error:<EOL><INDENT>raise self.severe('<STR_LIT>' %<EOL>(self.name, ErrorString(error)))<EOL><DEDENT>config = self.state.document.settings.env.config<EOL>converter = M2R(no_underscore_emphasis=config.no_underscore_emphasis)<EOL>include_lines = statemachine.string2lines(converter(rawtext),<EOL>tab_width,<EOL>convert_whitespace=True)<EOL>self.state_machine.insert_input(include_lines, path)<EOL>return []<EOL>

Most of this method is from ``docutils.parser.rst.Directive``.

        docutils version: 0.12


table = '<STR_LIT>'<EOL>if header and not header.isspace():<EOL><INDENT>table = (table + self.indent + '<STR_LIT>' +<EOL>self._indent_block(header) + '<STR_LIT:\n>')<EOL><DEDENT>else:<EOL><INDENT>table = table + '<STR_LIT:\n>'<EOL><DEDENT>table = table + self._indent_block(body) + '<STR_LIT>'<EOL>return table<EOL>

Rendering table element. Wrap header and body in it.

        :param header: header part of the table.
        :param body: body part of the table.


return '<STR_LIT>' + content + '<STR_LIT:\n>'<EOL>

Rendering a table cell. Like ``<th>`` ``<td>``.

        :param content: content of current table cell.
        :param header: whether this is header or not.
        :param align: align of current table cell.


return '<STR_LIT>'.format(key)<EOL>


return marker<EOL>


return self.renderer.inline_math(m.group(<NUM_LIT:1>))<EOL>


return '<STR_LIT>'<EOL>


return '<STR_LIT>' + self._indent_block(html) + '<STR_LIT>'<EOL>


if self.options.get('<STR_LIT>'):<EOL><INDENT>return self._raw_html('<STR_LIT>') + '<STR_LIT:\n>'<EOL><DEDENT>return self._raw_html('<STR_LIT>') + '<STR_LIT:\n>'<EOL>


return '<STR_LIT:\n>' + self.list_marker + text<EOL>

Rendering list item snippet. Like ``<li>``.


global _is_sphinx<EOL>_is_sphinx = True<EOL>app.add_config_value('<STR_LIT>', False, '<STR_LIT>')<EOL>app.add_source_parser('<STR_LIT>', M2RParser)<EOL>app.add_directive('<STR_LIT>', MdInclude)<EOL>


def validate(self, filename, module, classname, ignore):

with open(os.path.normpath(os.path.join('<STR_LIT>', '<STR_LIT>', filename))) as f:<EOL><INDENT>docs = f.read()<EOL><DEDENT>module = module_loading.import_module(module)<EOL>methods = re.findall(r'<STR_LIT>', docs, flags=re.M)<EOL>attributes = re.findall(r'<STR_LIT>', docs, flags=re.M)<EOL>documented = set(filter(lambda x: x.startswith(classname), [a for a in methods] + attributes))<EOL>implemented = set(classname + '<STR_LIT:.>' + x for x in dir(getattr(module, classname))<EOL>if not x.startswith('<STR_LIT:_>') or x == '<STR_LIT>')<EOL>print(implemented)<EOL>ignored = set(classname + '<STR_LIT:.>' + x for x in ignore)<EOL>self.assertSetEqual(implemented - documented - ignored, set(), msg='<STR_LIT>')<EOL>self.assertSetEqual(documented - implemented - ignored, set(), msg='<STR_LIT>')<EOL>

Finds all automethod and autoattribute statements in an rst file
comparing them to the attributes found in the actual class


return os.path.join(__name__.split('<STR_LIT:.>')[-<NUM_LIT:2>], path)<EOL>

Prepend the effect package name to a path so resources
can still be loaded when copied into a new effect package.


@property<EOL><INDENT>def geometry_vertices(self) -> int:<DEDENT>

return self.program.geometry_vertices<EOL>

int: The maximum number of vertices that
the geometry shader will output.


@classmethod<EOL><INDENT>def from_single(cls, meta: ProgramDescription, source: str):<DEDENT>

instance = cls(meta)<EOL>instance.vertex_source = ShaderSource(<EOL>VERTEX_SHADER,<EOL>meta.path or meta.vertex_shader,<EOL>source<EOL>)<EOL>if GEOMETRY_SHADER in source:<EOL><INDENT>instance.geometry_source = ShaderSource(<EOL>GEOMETRY_SHADER,<EOL>meta.path or meta.geometry_shader,<EOL>source,<EOL>)<EOL><DEDENT>if FRAGMENT_SHADER in source:<EOL><INDENT>instance.fragment_source = ShaderSource(<EOL>FRAGMENT_SHADER,<EOL>meta.path or meta.fragment_shader,<EOL>source,<EOL>)<EOL><DEDENT>if TESS_CONTROL_SHADER in source:<EOL><INDENT>instance.tess_control_source = ShaderSource(<EOL>TESS_CONTROL_SHADER,<EOL>meta.path or meta.tess_control_shader,<EOL>source,<EOL>)<EOL><DEDENT>if TESS_EVALUATION_SHADER in source:<EOL><INDENT>instance.tess_evaluation_source = ShaderSource(<EOL>TESS_EVALUATION_SHADER,<EOL>meta.path or meta.tess_evaluation_shader,<EOL>source,<EOL>)<EOL><DEDENT>return instance<EOL>

Initialize a single glsl string containing all shaders


@property<EOL><INDENT>def subroutines(self) -> Tuple[str, ...]:<DEDENT>

return self.program.subroutines<EOL>


<EOL>out_attribs = []<EOL>if not self.fragment_source:<EOL><INDENT>if self.geometry_source:<EOL><INDENT>out_attribs = self.geometry_source.find_out_attribs()<EOL><DEDENT>else:<EOL><INDENT>out_attribs = self.vertex_source.find_out_attribs()<EOL><DEDENT><DEDENT>program = self.ctx.program(<EOL>vertex_shader=self.vertex_source.source,<EOL>geometry_shader=self.geometry_source.source if self.geometry_source else None,<EOL>fragment_shader=self.fragment_source.source if self.fragment_source else None,<EOL>tess_control_shader=self.tess_control_source.source if self.tess_control_source else None,<EOL>tess_evaluation_shader=self.tess_evaluation_source.source if self.tess_evaluation_source else None,<EOL>varyings=out_attribs,<EOL>)<EOL>program.extra = {'<STR_LIT>': self.meta}<EOL>return program<EOL>

Creates a shader program.

Returns:
    ModernGL Program instance


@property<EOL><INDENT>def glo(self) -> int:<DEDENT>

return self.program.glo<EOL>

int: The internal OpenGL object.
This values is provided for debug purposes only.


def __init__(self, meta: ProgramDescription, program: moderngl.Program):

self.program = program<EOL>self.meta = meta<EOL>

Create a shader using either a file path or a name
:param meta: The ProgramMeta
:param program: The program instance


return self.program.mglo<EOL>


def render(self, program: moderngl.Program, mode=None, vertices=-<NUM_LIT:1>, first=<NUM_LIT:0>, instances=<NUM_LIT:1>):

vao = self.instance(program)<EOL>if mode is None:<EOL><INDENT>mode = self.mode<EOL><DEDENT>vao.render(mode, vertices=vertices, first=first, instances=instances)<EOL>

Render the VAO.

Args:
    program: The ``moderngl.Program``

Keyword Args:
    mode: Override the draw mode (``TRIANGLES`` etc)
    vertices (int): The number of vertices to transform
    first (int): The index of the first vertex to start with
    instances (int): The number of instances


def content(self, attributes: List[str]):

formats = []<EOL>attrs = []<EOL>for attrib_format, attrib in zip(self.attrib_formats, self.attributes):<EOL><INDENT>if attrib not in attributes:<EOL><INDENT>formats.append(attrib_format.pad_str())<EOL>continue<EOL><DEDENT>formats.append(attrib_format.format)<EOL>attrs.append(attrib)<EOL>attributes.remove(attrib)<EOL><DEDENT>if not attrs:<EOL><INDENT>return None<EOL><DEDENT>return (<EOL>self.buffer,<EOL>"<STR_LIT>".format("<STR_LIT:U+0020>".join(formats), '<STR_LIT>' if self.per_instance else '<STR_LIT>'),<EOL>*attrs<EOL>)<EOL>


def __init__(self, buffer: moderngl.Buffer, buffer_format: str, attributes=None, per_instance=False):

self.buffer = buffer<EOL>self.attrib_formats = types.parse_attribute_formats(buffer_format)<EOL>self.attributes = attributes<EOL>self.per_instance = per_instance<EOL>if self.buffer.size % self.vertex_size != <NUM_LIT:0>:<EOL><INDENT>raise VAOError("<STR_LIT>".format(<EOL>buffer_format, self.vertex_size, self.buffer.size % self.vertex_size<EOL>))<EOL><DEDENT>self.vertices = self.buffer.size // self.vertex_size<EOL>

:param buffer: The vbo object
:param format: The format of the buffer


def __init__(self, name="<STR_LIT>", mode=moderngl.TRIANGLES):

self.ctx = context.ctx()<EOL>self.name = name<EOL>self.mode = mode<EOL>try:<EOL><INDENT>DRAW_MODES[self.mode]<EOL><DEDENT>except KeyError:<EOL><INDENT>raise VAOError("<STR_LIT>".format(DRAW_MODES.values()))<EOL><DEDENT>self.buffers = []<EOL>self._index_buffer = None<EOL>self._index_element_size = None<EOL>self.vertex_count = <NUM_LIT:0><EOL>self.vaos = {}<EOL>

Create and empty VAO

Keyword Args:
    name (str): The name for debug purposes
    mode (int): Default draw mode


def __init__(self, format_string: str, components: int, bytes_per_component: int):

self.format = format_string<EOL>self.components = components<EOL>self.bytes_per_component = bytes_per_component<EOL>

:param format_string: moderngl format string
:param components: components
:param byte_size: byte per component


def attribute_format(frmt: str) -> BufferFormat:

try:<EOL><INDENT>return ATTRIBUTE_FORMATS[frmt]<EOL><DEDENT>except KeyError:<EOL><INDENT>raise ValueError("<STR_LIT>".format(<EOL>frmt, ATTRIBUTE_FORMATS.keys()<EOL>))<EOL><DEDENT>

Look up info about an attribute format
:param frmt: Format of an
:return: BufferFormat instance


def update(self, aspect_ratio=None, fov=None, near=None, far=None):

self.aspect_ratio = aspect_ratio or self.aspect_ratio<EOL>self.fov = fov or self.fov<EOL>self.near = near or self.near<EOL>self.far = far or self.far<EOL>self.matrix = Matrix44.perspective_projection(self.fov, self.aspect_ratio, self.near, self.far)<EOL>

Update the internal projection matrix based on current values
or values passed in if specified.

:param aspect_ratio: New aspect ratio
:param fov: New field of view
:param near: New near value
:param far: New far value


def draw(self, texture, pos=(<NUM_LIT:0.0>, <NUM_LIT:0.0>), scale=(<NUM_LIT:1.0>, <NUM_LIT:1.0>)):

if not self.initialized:<EOL><INDENT>self.init()<EOL><DEDENT>self._texture2d_shader["<STR_LIT>"].value = (pos[<NUM_LIT:0>] - <NUM_LIT:1.0>, pos[<NUM_LIT:1>] - <NUM_LIT:1.0>)<EOL>self._texture2d_shader["<STR_LIT>"].value = (scale[<NUM_LIT:0>], scale[<NUM_LIT:1>])<EOL>texture.use(location=<NUM_LIT:0>)<EOL>self._texture2d_sampler.use(location=<NUM_LIT:0>)<EOL>self._texture2d_shader["<STR_LIT>"].value = <NUM_LIT:0><EOL>self._quad.render(self._texture2d_shader)<EOL>self._texture2d_sampler.clear(location=<NUM_LIT:0>)<EOL>

Draw texture using a fullscreen quad.
By default this will conver the entire screen.

:param pos: (tuple) offset x, y
:param scale: (tuple) scale x, y


def draw_depth(self, texture, near, far, pos=(<NUM_LIT:0.0>, <NUM_LIT:0.0>), scale=(<NUM_LIT:1.0>, <NUM_LIT:1.0>)):

if not self.initialized:<EOL><INDENT>self.init()<EOL><DEDENT>self._depth_shader["<STR_LIT>"].value = (pos[<NUM_LIT:0>] - <NUM_LIT:1.0>, pos[<NUM_LIT:1>] - <NUM_LIT:1.0>)<EOL>self._depth_shader["<STR_LIT>"].value = (scale[<NUM_LIT:0>], scale[<NUM_LIT:1>])<EOL>self._depth_shader["<STR_LIT>"].value = near<EOL>self._depth_shader["<STR_LIT>"].value = far<EOL>self._depth_sampler.use(location=<NUM_LIT:0>)<EOL>texture.use(location=<NUM_LIT:0>)<EOL>self._depth_shader["<STR_LIT>"].value = <NUM_LIT:0><EOL>self._quad.render(self._depth_shader)<EOL>self._depth_sampler.clear(location=<NUM_LIT:0>)<EOL>

Draw depth buffer linearized.
By default this will draw the texture as a full screen quad.
A sampler will be used to ensure the right conditions to draw the depth buffer.

:param near: Near plane in projection
:param far: Far plane in projection
:param pos: (tuple) offset x, y
:param scale: (tuple) scale x, y


<EOL>if getattr(self, '<STR_LIT>', None):<EOL><INDENT>self.paths = getattr(settings, self.settings_attr)<EOL><DEDENT>path_found = None<EOL>for entry in self.paths:<EOL><INDENT>abspath = entry / path<EOL>if abspath.exists():<EOL><INDENT>path_found = abspath<EOL><DEDENT><DEDENT>return path_found<EOL>

Find a file in the path. The file may exist in multiple
paths. The last found file will be returned.

:param path: The path to find
:return: The absolute path to the file or None if not found


if self.last_x is None:<EOL><INDENT>self.last_x = x<EOL><DEDENT>if self.last_y is None:<EOL><INDENT>self.last_y = y<EOL><DEDENT>x_offset = self.last_x - x<EOL>y_offset = self.last_y - y<EOL>self.last_x = x<EOL>self.last_y = y<EOL>x_offset *= self.mouse_sensitivity<EOL>y_offset *= self.mouse_sensitivity<EOL>self.yaw -= x_offset<EOL>self.pitch += y_offset<EOL>if self.pitch > <NUM_LIT>:<EOL><INDENT>self.pitch = <NUM_LIT><EOL><DEDENT>if self.pitch < -<NUM_LIT>:<EOL><INDENT>self.pitch = -<NUM_LIT><EOL><DEDENT>self._update_yaw_and_pitch()<EOL>

Set the rotation state of the camera

:param x: viewport x pos
:param y: viewport y pos


self._update_yaw_and_pitch()<EOL>return self._gl_look_at(self.position, self.position + self.dir, self._up)<EOL>

:return: The current view matrix for the camera


<EOL>now = time.time()<EOL>t = max(now - self._last_time, <NUM_LIT:0>)<EOL>self._last_time = now<EOL>if self._xdir == POSITIVE:<EOL><INDENT>self.position += self.right * self.velocity * t<EOL><DEDENT>elif self._xdir == NEGATIVE:<EOL><INDENT>self.position -= self.right * self.velocity * t<EOL><DEDENT>if self._zdir == NEGATIVE:<EOL><INDENT>self.position += self.dir * self.velocity * t<EOL><DEDENT>elif self._zdir == POSITIVE:<EOL><INDENT>self.position -= self.dir * self.velocity * t<EOL><DEDENT>if self._ydir == POSITIVE:<EOL><INDENT>self.position += self.up * self.velocity * t<EOL><DEDENT>elif self._ydir == NEGATIVE:<EOL><INDENT>self.position -= self.up * self.velocity * t<EOL><DEDENT>return self._gl_look_at(self.position, self.position + self.dir, self._up)<EOL>


front = Vector3([<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT:0.0>])<EOL>front.x = cos(radians(self.yaw)) * cos(radians(self.pitch))<EOL>front.y = sin(radians(self.pitch))<EOL>front.z = sin(radians(self.yaw)) * cos(radians(self.pitch))<EOL>self.dir = vector.normalise(front)<EOL>self.right = vector.normalise(vector3.cross(self.dir, self._up))<EOL>self.up = vector.normalise(vector3.cross(self.right, self.dir))<EOL>

Updates the camera vectors based on the current yaw and pitch


if pos is None:<EOL><INDENT>vec = Vector3(pos)<EOL><DEDENT>if vec is None:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return self._gl_look_at(self.position, vec, self._up)<EOL>

Look at a specific point

:param vec: Vector3 position
:param pos: python list [x, y, x]
:return: Camera matrix


self.position = Vector3([x, y, z])<EOL>

Set the 3D position of the camera

:param x: float
:param y: float
:param z: float


def add_attribute(self, attr_type, name, components):

self.attributes[attr_type] = {"<STR_LIT:name>": name, "<STR_LIT>": components}<EOL>

Add metadata about the mesh
:param attr_type: POSITION, NORMAL etc
:param name: The attribute name used in the program
:param components: Number of floats


def draw(self, projection_matrix=None, view_matrix=None, camera_matrix=None, time=<NUM_LIT:0>):

Draw the mesh using the assigned mesh program

:param projection_matrix: projection_matrix (bytes)
:param view_matrix: view_matrix (bytes)
:param camera_matrix: camera_matrix (bytes)


def draw(self, projection_matrix=None, camera_matrix=None, time=<NUM_LIT:0>):

projection_matrix = projection_matrix.astype('<STR_LIT>').tobytes()<EOL>camera_matrix = camera_matrix.astype('<STR_LIT>').tobytes()<EOL>for node in self.root_nodes:<EOL><INDENT>node.draw(<EOL>projection_matrix=projection_matrix,<EOL>camera_matrix=camera_matrix,<EOL>time=time,<EOL>)<EOL><DEDENT>self.ctx.clear_samplers(<NUM_LIT:0>, <NUM_LIT:4>)<EOL>

Draw all the nodes in the scene

:param projection_matrix: projection matrix (bytes)
:param camera_matrix: camera_matrix (bytes)
:param time: The current time


def __init__(self, name, mesh_programs=None, **kwargs):

self.name = name<EOL>self.root_nodes = []<EOL>self.nodes = []<EOL>self.materials = []<EOL>self.meshes = []<EOL>self.cameras = []<EOL>self.bbox_min = None<EOL>self.bbox_max = None<EOL>self.diagonal_size = <NUM_LIT:1.0><EOL>self.bbox_vao = geometry.bbox()<EOL>self.bbox_program = programs.load(ProgramDescription(<EOL>label='<STR_LIT>',<EOL>path='<STR_LIT>'))<EOL>self._view_matrix = matrix44.create_identity()<EOL>

:param name: Unique name or path for the scene
:param mesh_programs: List of MeshPrograms to apply to the scene
:param loader: Loader class for the scene if relevant


for mesh in self.meshes:<EOL><INDENT>mesh.vao.release()<EOL><DEDENT>

Destroy the scene data and deallocate buffers


mixer.music.stop()<EOL>return self.get_time()<EOL>

Stop the music

Returns:
    The current location in the music


mixer.music.pause()<EOL>self.pause_time = self.get_time()<EOL>self.paused = True<EOL>


if self.paused:<EOL><INDENT>self.start()<EOL><DEDENT>else:<EOL><INDENT>self.pause()<EOL><DEDENT>


if value < <NUM_LIT:0>:<EOL><INDENT>value = <NUM_LIT:0><EOL><DEDENT>self.offset += self.get_time() - value<EOL>

Set the current time. This can be used to jump in the timeline.

Args:
    value (float): The new time


if self.pause_time:<EOL><INDENT>self.start()<EOL><DEDENT>else:<EOL><INDENT>self.pause()<EOL><DEDENT>


if self.pause_time is not None:<EOL><INDENT>curr_time = self.pause_time - self.offset - self.start_time<EOL>return curr_time<EOL><DEDENT>curr_time = time.time()<EOL>return curr_time - self.start_time - self.offset<EOL>

Get the current time in seconds

Returns:
    The current time in seconds


self.stop_time = time.time()<EOL>return self.stop_time - self.start_time - self.offset<EOL>

Stop the timer

Returns:
    The time the timer was stopped


raise NotImplementedError()<EOL>

Stop the timer. Should only be called once when stopping the timer.

Returns:
    The time the timer was stopped

Raises:
    NotImplementedError


raise NotImplementedError()<EOL>

Pause the timer

Raises:
    NotImplementedError


self.controller.playing = False<EOL>


self.controller.playing = not self.controller.playing<EOL>


config = getattr(settings, '<STR_LIT>', None)<EOL>if config is None:<EOL><INDENT>config = {}<EOL><DEDENT>self.mode = config.get('<STR_LIT>') or '<STR_LIT>'<EOL>self.files = config.get('<STR_LIT>') or '<STR_LIT>'<EOL>self.project = config.get('<STR_LIT>') or '<STR_LIT>'<EOL>self.rps = config.get('<STR_LIT>', <NUM_LIT>)<EOL>self.start_paused = False<EOL>self.controller = TimeController(self.rps)<EOL>if self.mode == '<STR_LIT>':<EOL><INDENT>self.rocket = Rocket.from_socket(self.controller, track_path=self.files)<EOL>self.start_paused = True<EOL><DEDENT>elif self.mode == '<STR_LIT>':<EOL><INDENT>self.rocket = Rocket.from_project_file(self.controller, self.project)<EOL><DEDENT>elif self.mode == '<STR_LIT>':<EOL><INDENT>self.rocket = Rocket.from_files(self.controller, self.files)<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>".format(self.mode))<EOL><DEDENT>for track in tracks.tacks:<EOL><INDENT>self.rocket.tracks.add(track)<EOL><DEDENT>for track in tracks.tacks:<EOL><INDENT>self.rocket.track(track.name)<EOL><DEDENT>self.rocket.update()<EOL>super().__init__(**kwargs)<EOL>

Initialize the rocket timer using values from settings


self.player.stop()<EOL>return self.get_time()<EOL>

Stop the music

Returns:
    The current time in seconds


self.music.start()<EOL>if not self.start_paused:<EOL><INDENT>self.rocket.start()<EOL><DEDENT>


Set the current time jumping in the timeline

Args:
    value (float): The new time value


self.controller.playing = not self.controller.playing<EOL>self.music.toggle_pause()<EOL>


self.rocket.update()<EOL>return self.music.get_time()<EOL>


def render_lights_debug(self, camera_matrix, projection):

self.ctx.enable(moderngl.BLEND)<EOL>self.ctx.blend_func = moderngl.SRC_ALPHA, moderngl.ONE_MINUS_SRC_ALPHA<EOL>for light in self.point_lights:<EOL><INDENT>m_mv = matrix44.multiply(light.matrix, camera_matrix)<EOL>light_size = light.radius<EOL>self.debug_shader["<STR_LIT>"].write(projection.tobytes())<EOL>self.debug_shader["<STR_LIT>"].write(m_mv.astype('<STR_LIT>').tobytes())<EOL>self.debug_shader["<STR_LIT:size>"].value = light_size<EOL>self.unit_cube.render(self.debug_shader, mode=moderngl.LINE_STRIP)<EOL><DEDENT>self.ctx.disable(moderngl.BLEND)<EOL>


@property<EOL><INDENT>def window(self) -> BaseWindow:<DEDENT>

return self._window<EOL>


def get_scene(self, label: str) -> Scene:

return self._project.get_scene(label)<EOL>

Get a scene by its label

Args:
    label (str): The label for the scene

Returns: The :py:class:`Scene` instance


def create_projection(self, fov: float = <NUM_LIT>, near: float = <NUM_LIT:1.0>, far: float = <NUM_LIT>, aspect_ratio: float = None):

return matrix44.create_perspective_projection_matrix(<EOL>fov,<EOL>aspect_ratio or self.window.aspect_ratio,<EOL>near,<EOL>far,<EOL>dtype='<STR_LIT>',<EOL>)<EOL>

Create a projection matrix with the following parameters.
When ``aspect_ratio`` is not provided the configured aspect
ratio for the window will be used.

Args:
    fov (float): Field of view (float)
    near (float): Camera near value
    far (float): Camrea far value

Keyword Args:
    aspect_ratio (float): Aspect ratio of the viewport

Returns:
    The projection matrix as a float32 :py:class:`numpy.array`


def create_transformation(self, rotation=None, translation=None):

mat = None<EOL>if rotation is not None:<EOL><INDENT>mat = Matrix44.from_eulers(Vector3(rotation))<EOL><DEDENT>if translation is not None:<EOL><INDENT>trans = matrix44.create_from_translation(Vector3(translation))<EOL>if mat is None:<EOL><INDENT>mat = trans<EOL><DEDENT>else:<EOL><INDENT>mat = matrix44.multiply(mat, trans)<EOL><DEDENT><DEDENT>return mat<EOL>

Creates a transformation matrix woth rotations and translation.

Args:
    rotation: 3 component vector as a list, tuple, or :py:class:`pyrr.Vector3`
    translation: 3 component vector as a list, tuple, or :py:class:`pyrr.Vector3`

Returns:
    A 4x4 matrix as a :py:class:`numpy.array`


@property<EOL><INDENT>def sys_camera(self) -> camera.SystemCamera:<DEDENT>

return self._sys_camera<EOL>


@property<EOL><INDENT>def name(self) -> str:<DEDENT>

return self._name<EOL>


normal_m = Matrix33.from_matrix44(modelview)<EOL>normal_m = normal_m.inverse<EOL>normal_m = normal_m.transpose()<EOL>return normal_m<EOL>

Creates a normal matrix from modelview matrix

Args:
    modelview: The modelview matrix

Returns:
    A 3x3 Normal matrix as a :py:class:`numpy.array`


def get_program(self, label: str) -> moderngl.Program:

return self._project.get_program(label)<EOL>

Get a program by its label

Args:
    label (str): The label for the program

Returns: py:class:`moderngl.Program` instance


pass<EOL>

Implement the initialize when extending the class.
This method is responsible for fetching or creating resources
and doing genereal initalization of the effect.

The effect initializer is called when all resources are loaded
(with the exception of resources you manually load in the
the initializer).

If your effect requires arguments during initialiation you
are free to add positional and keyword arguments.

You **do not** have to call the superclass initializer though ``super()``

Example::

    def __init__(self):
        # Fetch reference to resource by their label
        self.program = self.get_program('simple_textured')
        self.texture = self.get_texture('bricks')
        # .. create a cube etc ..


def get_effect(self, label: str) -> '<STR_LIT>':

return self._project.get_effect(label)<EOL>

Get an effect instance by label.

Args:
    label (str): Label for the data file

Returns: The :py:class:`Effect` instance


def get_track(self, name: str) -> Track:

return resources.tracks.get(name)<EOL>

Gets or creates a rocket track.
Only avaiable when using a Rocket timer.

Args:
    name (str): The rocket track name

Returns:
    The :py:class:`rocket.Track` instance


self.effect_classes = []<EOL>for _, cls in inspect.getmembers(self.effect_module):<EOL><INDENT>if inspect.isclass(cls):<EOL><INDENT>if cls == Effect:<EOL><INDENT>continue<EOL><DEDENT>if issubclass(cls, Effect):<EOL><INDENT>self.effect_classes.append(cls)<EOL>self.effect_class_map[cls.__name__] = cls<EOL>cls._name = "<STR_LIT>".format(self.effect_module_name, cls.__name__)<EOL><DEDENT><DEDENT><DEDENT>

Iterate the module attributes picking out effects


<EOL>try:<EOL><INDENT>name = '<STR_LIT>'.format(self.name, '<STR_LIT>')<EOL>self.dependencies_module = importlib.import_module(name)<EOL><DEDENT>except ModuleNotFoundError as err:<EOL><INDENT>raise EffectError(<EOL>(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>).format(self.name, err))<EOL><DEDENT>try:<EOL><INDENT>self.resources = getattr(self.dependencies_module, '<STR_LIT>')<EOL><DEDENT>except AttributeError:<EOL><INDENT>raise EffectError("<STR_LIT>".format(name))<EOL><DEDENT>if not isinstance(self.resources, list):<EOL><INDENT>raise EffectError(<EOL>"<STR_LIT>".format(<EOL>name, type(self.resources)))<EOL><DEDENT>try:<EOL><INDENT>self.effect_packages = getattr(self.dependencies_module, '<STR_LIT>')<EOL><DEDENT>except AttributeError:<EOL><INDENT>raise EffectError("<STR_LIT>".format(name))<EOL><DEDENT>if not isinstance(self.effect_packages, list):<EOL><INDENT>raise EffectError(<EOL>"<STR_LIT>".format(<EOL>name, type(self.effects)))<EOL><DEDENT>


def get_effect_resources(self) -> List[Any]:

resources = []<EOL>for package in self.packages:<EOL><INDENT>resources.extend(package.resources)<EOL><DEDENT>return resources<EOL>

Get all resources registed in effect packages.
These are typically located in ``resources.py``


for package in package_list:<EOL><INDENT>self.add_package(package)<EOL><DEDENT>

Polulate the registry with effect packages.

:param module_list: List of effect module paths


def runnable_effects(self) -> List[Type[Effect]]:

return [cls for cls in self.effect_classes if cls.runnable]<EOL>

Returns the runnable effect in the package


def get_package(self, name) -> '<STR_LIT>':

name, cls_name = parse_package_string(name)<EOL>try:<EOL><INDENT>return self.package_map[name]<EOL><DEDENT>except KeyError:<EOL><INDENT>raise EffectError("<STR_LIT>".format(name))<EOL><DEDENT>

Get a package by python path. Can also contain path to an effect.

Args:
    name (str): Path to effect package or effect

Returns:
    The requested EffectPackage

Raises:
    EffectError when no package is found


name, cls_name = parse_package_string(name)<EOL>if name in self.package_map:<EOL><INDENT>return<EOL><DEDENT>package = EffectPackage(name)<EOL>package.load()<EOL>self.packages.append(package)<EOL>self.package_map[package.name] = package<EOL>self.polulate(package.effect_packages)<EOL>

Registers a single package

:param name: (str) The effect package to add


parts = path.split('<STR_LIT:.>')<EOL>if parts[-<NUM_LIT:1>][<NUM_LIT:0>].isupper():<EOL><INDENT>return "<STR_LIT:.>".join(parts[:-<NUM_LIT:1>]), parts[-<NUM_LIT:1>]<EOL><DEDENT>return path, "<STR_LIT>"<EOL>

Parse the effect package string.
Can contain the package python path or path to effect class in an effect package.

Examples::

    # Path to effect pacakge
    examples.cubes

    # Path to effect class
    examples.cubes.Cubes

Args:
    path: python path to effect package. May also include effect class name.

Returns:
    tuple: (package_path, effect_class)


def __init__(self, area, text_lines=None, aspect_ratio=<NUM_LIT:1.0>):

super().__init__()<EOL>self.area = area<EOL>self._text_lines = text_lines<EOL>self._projection_bytes = None<EOL>self._aspect_ratio = <NUM_LIT:1.0><EOL>self.aspect_ratio = aspect_ratio<EOL>self._vao = None<EOL>self._config = self.get_data('<STR_LIT>')<EOL>self._texture = self.get_texture('<STR_LIT>')<EOL>self._program = self.get_program('<STR_LIT>')<EOL>self._string_buffer = None<EOL>self._init(FontMeta(self._config))<EOL>self._string_buffer = self.ctx.buffer(reserve=self.area[<NUM_LIT:0>] * <NUM_LIT:4> * self.area[<NUM_LIT:1>])<EOL>self._string_buffer.clear(chunk=b'<STR_LIT>')<EOL>pos = self.ctx.buffer(data=bytes([<NUM_LIT:0>] * <NUM_LIT:4> * <NUM_LIT:3>))<EOL>self._vao = VAO("<STR_LIT>", mode=moderngl.POINTS)<EOL>self._vao.buffer(pos, '<STR_LIT>', '<STR_LIT>')<EOL>self._vao.buffer(self._string_buffer, '<STR_LIT>', '<STR_LIT>', per_instance=True)<EOL>self.text_lines = self._text_lines<EOL>

:param area: (x, y) Text area size (number of characters)
:param size: Text size
:param text: Initial text lines


def load_shader(self, shader_type: str, path: str):

if path:<EOL><INDENT>resolved_path = self.find_program(path)<EOL>if not resolved_path:<EOL><INDENT>raise ValueError("<STR_LIT>".format(shader_type, path))<EOL><DEDENT>print("<STR_LIT>", path)<EOL>with open(resolved_path, '<STR_LIT:r>') as fd:<EOL><INDENT>return fd.read()<EOL><DEDENT><DEDENT>


accessor = primitive.attributes.get('<STR_LIT>')<EOL>return accessor.min, accessor.max<EOL>


if not self.uri:<EOL><INDENT>return False<EOL><DEDENT>return self.uri.startswith("<STR_LIT>")<EOL>


buffer_info = []<EOL>for name, accessor in primitive.attributes.items():<EOL><INDENT>info = VBOInfo(*accessor.info())<EOL>info.attributes.append((name, info.components))<EOL>if buffer_info and buffer_info[-<NUM_LIT:1>].buffer_view == info.buffer_view:<EOL><INDENT>if buffer_info[-<NUM_LIT:1>].interleaves(info):<EOL><INDENT>buffer_info[-<NUM_LIT:1>].merge(info)<EOL>continue<EOL><DEDENT><DEDENT>buffer_info.append(info)<EOL><DEDENT>return buffer_info<EOL>

Pre-parse buffer mappings for each VBO to detect interleaved data for a primitive


if self.data.get('<STR_LIT>'):<EOL><INDENT>for ext in self.data.get('<STR_LIT>'):<EOL><INDENT>if ext not in supported:<EOL><INDENT>raise ValueError("<STR_LIT>".format(ext))<EOL><DEDENT><DEDENT><DEDENT>if self.data.get('<STR_LIT>'):<EOL><INDENT>for ext in self.data.get('<STR_LIT>'):<EOL><INDENT>if ext not in supported:<EOL><INDENT>raise ValueError("<STR_LIT>".format(ext))<EOL><DEDENT><DEDENT><DEDENT>

"extensionsRequired": ["KHR_draco_mesh_compression"],
"extensionsUsed": ["KHR_draco_mesh_compression"]


return self.camera is not None or self.mesh is not None<EOL>

Is this just a reference node to a resource?


return self.uri is not None and not self.has_data_uri<EOL>

Buffer represents an independent bin file?


self.path = self.find_scene(self.meta.path)<EOL>if not self.path:<EOL><INDENT>raise ValueError("<STR_LIT>".format(self.meta.path))<EOL><DEDENT>self.scene = Scene(self.path)<EOL>if self.path.suffix == '<STR_LIT>':<EOL><INDENT>self.load_gltf()<EOL><DEDENT>if self.path.suffix == '<STR_LIT>':<EOL><INDENT>self.load_glb()<EOL><DEDENT>self.meta.check_version()<EOL>self.meta.check_extensions(self.supported_extensions)<EOL>self.load_images()<EOL>self.load_samplers()<EOL>self.load_textures()<EOL>self.load_materials()<EOL>self.load_meshes()<EOL>self.load_nodes()<EOL>self.scene.calc_scene_bbox()<EOL>self.scene.prepare()<EOL>return self.scene<EOL>

Deferred loading of the scene

:param scene: The scene object
:param file: Resolved path if changed by finder


<EOL>for acc in self.accessors:<EOL><INDENT>acc.bufferView = self.buffer_views[acc.bufferViewId]<EOL><DEDENT>for buffer_view in self.buffer_views:<EOL><INDENT>buffer_view.buffer = self.buffers[buffer_view.bufferId]<EOL><DEDENT>for mesh in self.meshes:<EOL><INDENT>for primitive in mesh.primitives:<EOL><INDENT>if getattr(primitive, "<STR_LIT>", None) is not None:<EOL><INDENT>primitive.indices = self.accessors[primitive.indices]<EOL><DEDENT>for name, value in primitive.attributes.items():<EOL><INDENT>primitive.attributes[name] = self.accessors[value]<EOL><DEDENT><DEDENT><DEDENT>for image in self.images:<EOL><INDENT>if image.bufferViewId is not None:<EOL><INDENT>image.bufferView = self.buffer_views[image.bufferViewId]<EOL><DEDENT><DEDENT>


pass<EOL>

checks if the images references in textures exist


if getattr(primitive, "<STR_LIT>") is None:<EOL><INDENT>return None, None<EOL><DEDENT>_, component_type, buffer = primitive.indices.read()<EOL>return component_type, buffer<EOL>

Loads the index buffer / polygon list for a primitive


<EOL>dtype = NP_COMPONENT_DTYPE[self.componentType.value]<EOL>return ACCESSOR_TYPE[self.type], self.componentType, self.bufferView.read(<EOL>byte_offset=self.byteOffset,<EOL>dtype=dtype,<EOL>count=self.count * ACCESSOR_TYPE[self.type],<EOL>)<EOL>

Reads buffer data
:return: component count, component type, data


dtype = NP_COMPONENT_DTYPE[self.component_type.value]<EOL>data = numpy.frombuffer(<EOL>self.buffer.read(byte_length=self.byte_length, byte_offset=self.byte_offset),<EOL>count=self.count * self.components,<EOL>dtype=dtype,<EOL>)<EOL>return dtype, data<EOL>


raise NotImplementedError()<EOL>


found_path = None<EOL>for finder in finders:<EOL><INDENT>result = finder.find(path)<EOL>if result:<EOL><INDENT>found_path = result<EOL><DEDENT><DEDENT>return found_path<EOL>

Find the last occurance of the file in finders


self.meta = meta<EOL>

:param meta: ResourceDescription instance


<EOL>data = image.tobytes()<EOL>components = len(data) // (image.size[<NUM_LIT:0>] * image.size[<NUM_LIT:1>])<EOL>return components, data<EOL>


self.meta.resolved_path = self.find_data(self.meta.path)<EOL>if not self.meta.resolved_path:<EOL><INDENT>raise ImproperlyConfigured("<STR_LIT>".format(self.meta.path))<EOL><DEDENT>print("<STR_LIT>", self.meta.path)<EOL>with open(self.meta.resolved_path, '<STR_LIT:r>') as fd:<EOL><INDENT>return fd.read()<EOL><DEDENT>


view.init(*args, **kwargs)<EOL>


settings.setup()<EOL>settings.update(**kwargs)<EOL>


pass<EOL>

Forwarded key events from the system.

:param key: The key that was pressed or released.
:param action: ACTION_PRESS, ACTION_RELEASE
:param mods: Bit field describing which modifier keys were held down.


def draw(self, time, frametime, target):

for effect in self.effects:<EOL><INDENT>value = effect.rocket_timeline_track.time_value(time)<EOL>if value > <NUM_LIT:0.5>:<EOL><INDENT>effect.draw(time, frametime, target)<EOL><DEDENT><DEDENT>

Fetch track value for every runnable effect.
If the value is > 0.5 we draw it.


parser = self.create_parser(argv[<NUM_LIT:0>], argv[<NUM_LIT:1>])<EOL>options = parser.parse_args(argv[<NUM_LIT:2>:])<EOL>cmd_options = vars(options)<EOL>args = cmd_options.pop('<STR_LIT:args>', ())<EOL>self.handle(*args, **cmd_options)<EOL>

Called by the system when executing the command from the command line.
This should not be overridden.

:param argv: Arguments from command line


def print_help(self, prog_name, subcommand):

parser = self.create_parser(prog_name, subcommand)<EOL>parser.print_help()<EOL>

Prints the help text generated by the argument parser defined for this command.
This method should not be overridden.

:param prog_name: name of the program that started the command.
:param subcommand: The subcommand name


pass<EOL>

This method is for adding arguments to a command.
When extending this class we define the arguments
by adding it to the parser passed in.

:param parser: The parser to add arguments to (standard argparse)


raise NotImplementedError()<EOL>

The actual run logic for the command.

:param args: arguments from the argparser
:param options: keyword arguments from the argparser


with open(os.path.join(self.template_dir, '<STR_LIT>'), '<STR_LIT:r>') as fd:<EOL><INDENT>data = fd.read().format(project_name=self.project_name)<EOL><DEDENT>with open('<STR_LIT>', '<STR_LIT:w>') as fd:<EOL><INDENT>fd.write(data)<EOL><DEDENT>os.chmod('<STR_LIT>', <NUM_LIT>)<EOL>

Write manage.py in the current directory


def find_commands(command_dir: str) -> List[str]:

if not command_dir:<EOL><INDENT>return []<EOL><DEDENT>return [name for _, name, is_pkg in pkgutil.iter_modules([command_dir])<EOL>if not is_pkg and not name.startswith('<STR_LIT:_>')]<EOL>

Get all command names in the a folder

:return: List of commands names


if not argv:<EOL><INDENT>argv = sys.argv<EOL><DEDENT>system_commands = find_commands(system_command_dir())<EOL>project_commands = find_commands(project_command_dir())<EOL>project_package = project_package_name()<EOL>command = argv[<NUM_LIT:1>] if len(argv) > <NUM_LIT:1> else None<EOL>if command in system_commands:<EOL><INDENT>cmd = load_command_class('<STR_LIT>', command)<EOL>cmd.run_from_argv(argv)<EOL><DEDENT>elif command in project_commands:<EOL><INDENT>cmd = load_command_class(project_package, command)<EOL>cmd.run_from_argv(argv)<EOL><DEDENT>else:<EOL><INDENT>print("<STR_LIT>")<EOL>for name in system_commands:<EOL><INDENT>print("<STR_LIT>".format(name))<EOL><DEDENT>for name in project_commands:<EOL><INDENT>print("<STR_LIT>".format(name))<EOL><DEDENT><DEDENT>

Currently the only entrypoint (manage.py, demosys-admin)


return self._get_resource(label, self._scenes, "<STR_LIT>")<EOL>

Gets a scene by label

Args:
    label (str): The label for the scene to fetch

Returns:
    Scene instance


@property<EOL><INDENT>def ctx(self) -> moderngl.Context:<DEDENT>

return context.ctx()<EOL>


for _, effect in self._effects.items():<EOL><INDENT>effect.post_load()<EOL><DEDENT>

Called after resources are loaded before effects starts rendering.
It simply iterates each effect instance calling their ``post_load`` methods.


def create_effect(self, label: str, name: str, *args, **kwargs) -> Effect:

effect_cls = effects.find_effect_class(name)<EOL>effect = effect_cls(*args, **kwargs)<EOL>effect._label = label<EOL>if label in self._effects:<EOL><INDENT>raise ValueError("<STR_LIT>".format(label))<EOL><DEDENT>self._effects[label] = effect<EOL>return effect<EOL>

Create an effect instance adding it to the internal effects dictionary using the label as key.

Args:
    label (str): The unique label for the effect instance
    name (str): Name or full python path to the effect class we want to instantiate
    args: Positional arguments to the effect initializer
    kwargs: Keyword arguments to the effect initializer

Returns:
    The newly created Effect instance


raise NotImplementedError()<EOL>

Create instances of effects.
Must be implemented or ``NotImplementedError`` is raised.


def get_effect(self, label: str) -> Effect:

return self._get_resource(label, self._effects, "<STR_LIT>")<EOL>

Get an effect instance by label

Args:
    label (str): The label for the effect instance

Returns:
    Effect class instance


def get_effect_class(self, class_name, package_name=None) -> Type[Effect]:

if package_name:<EOL><INDENT>return effects.find_effect_class("<STR_LIT>".format(package_name, class_name))<EOL><DEDENT>return effects.find_effect_class(class_name)<EOL>

Get an effect class from the effect registry.

Args:
    class_name (str): The exact class name of the effect

Keyword Args:
    package_name (str): The python path to the effect package the effect name is located.
                        This is optional and can be used to avoid issue with class name collisions.

Returns:
    Effect class


return quad_2d(<NUM_LIT>, <NUM_LIT>, <NUM_LIT:0.0>, <NUM_LIT:0.0>)<EOL>

Creates a screen aligned quad using two triangles with normals and texture coordiantes.

Returns:
    A :py:class:`demosys.opengl.vao.VAO` instance.


def plane_xz(size=(<NUM_LIT:10>, <NUM_LIT:10>), resolution=(<NUM_LIT:10>, <NUM_LIT:10>)) -> VAO:

sx, sz = size<EOL>rx, rz = resolution<EOL>dx, dz = sx / rx, sz / rz  <EOL>ox, oz = -sx / <NUM_LIT:2>, -sz / <NUM_LIT:2>  <EOL>def gen_pos():<EOL><INDENT>for z in range(rz):<EOL><INDENT>for x in range(rx):<EOL><INDENT>yield ox + x * dx<EOL>yield <NUM_LIT:0><EOL>yield oz + z * dz<EOL><DEDENT><DEDENT><DEDENT>def gen_uv():<EOL><INDENT>for z in range(rz):<EOL><INDENT>for x in range(rx):<EOL><INDENT>yield x / (rx - <NUM_LIT:1>)<EOL>yield <NUM_LIT:1> - z / (rz - <NUM_LIT:1>)<EOL><DEDENT><DEDENT><DEDENT>def gen_normal():<EOL><INDENT>for _ in range(rx * rz):<EOL><INDENT>yield <NUM_LIT:0.0><EOL>yield <NUM_LIT:1.0><EOL>yield <NUM_LIT:0.0><EOL><DEDENT><DEDENT>def gen_index():<EOL><INDENT>for z in range(rz - <NUM_LIT:1>):<EOL><INDENT>for x in range(rx - <NUM_LIT:1>):<EOL><INDENT>yield z * rz + x + <NUM_LIT:1><EOL>yield z * rz + x<EOL>yield z * rz + x + rx<EOL>yield z * rz + x + <NUM_LIT:1><EOL>yield z * rz + x + rx<EOL>yield z * rz + x + rx + <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>pos_data = numpy.fromiter(gen_pos(), dtype=numpy.float32)<EOL>uv_data = numpy.fromiter(gen_uv(), dtype=numpy.float32)<EOL>normal_data = numpy.fromiter(gen_normal(), dtype=numpy.float32)<EOL>index_data = numpy.fromiter(gen_index(), dtype=numpy.uint32)<EOL>vao = VAO("<STR_LIT>", mode=moderngl.TRIANGLES)<EOL>vao.buffer(pos_data, '<STR_LIT>', ['<STR_LIT>'])<EOL>vao.buffer(uv_data, '<STR_LIT>', ['<STR_LIT>'])<EOL>vao.buffer(normal_data, '<STR_LIT>', ['<STR_LIT>'])<EOL>vao.index_buffer(index_data, index_element_size=<NUM_LIT:4>)<EOL>return vao<EOL>

Generates a plane on the xz axis of a specific size and resolution.
Normals and texture coordinates are also included.

Args:
    size: (x, y) tuple
    resolution: (x, y) tuple

Returns:
    A :py:class:`demosys.opengl.vao.VAO` instance


def points_random_3d(count, range_x=(-<NUM_LIT>, <NUM_LIT>), range_y=(-<NUM_LIT>, <NUM_LIT>), range_z=(-<NUM_LIT>, <NUM_LIT>), seed=None) -> VAO:

random.seed(seed)<EOL>def gen():<EOL><INDENT>for _ in range(count):<EOL><INDENT>yield random.uniform(*range_x)<EOL>yield random.uniform(*range_y)<EOL>yield random.uniform(*range_z)<EOL><DEDENT><DEDENT>data = numpy.fromiter(gen(), count=count * <NUM_LIT:3>, dtype=numpy.float32)<EOL>vao = VAO("<STR_LIT>", mode=moderngl.POINTS)<EOL>vao.buffer(data, '<STR_LIT>', ['<STR_LIT>'])<EOL>return vao<EOL>

Generates random positions inside a confied box.

Args:
    count (int): Number of points to generate

Keyword Args:
    range_x (tuple): min-max range for x axis: Example (-10.0. 10.0)
    range_y (tuple): min-max range for y axis: Example (-10.0. 10.0)
    range_z (tuple): min-max range for z axis: Example (-10.0. 10.0)
    seed (int): The random seed

Returns:
    A :py:class:`demosys.opengl.vao.VAO` instance


def sphere(radius=<NUM_LIT:0.5>, sectors=<NUM_LIT:32>, rings=<NUM_LIT:16>) -> VAO:

R = <NUM_LIT:1.0> / (rings - <NUM_LIT:1>)<EOL>S = <NUM_LIT:1.0> / (sectors - <NUM_LIT:1>)<EOL>vertices = [<NUM_LIT:0>] * (rings * sectors * <NUM_LIT:3>)<EOL>normals = [<NUM_LIT:0>] * (rings * sectors * <NUM_LIT:3>)<EOL>uvs = [<NUM_LIT:0>] * (rings * sectors * <NUM_LIT:2>)<EOL>v, n, t = <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0><EOL>for r in range(rings):<EOL><INDENT>for s in range(sectors):<EOL><INDENT>y = math.sin(-math.pi / <NUM_LIT:2> + math.pi * r * R)<EOL>x = math.cos(<NUM_LIT:2> * math.pi * s * S) * math.sin(math.pi * r * R)<EOL>z = math.sin(<NUM_LIT:2> * math.pi * s * S) * math.sin(math.pi * r * R)<EOL>uvs[t] = s * S<EOL>uvs[t + <NUM_LIT:1>] = r * R<EOL>vertices[v] = x * radius<EOL>vertices[v + <NUM_LIT:1>] = y * radius<EOL>vertices[v + <NUM_LIT:2>] = z * radius<EOL>normals[n] = x<EOL>normals[n + <NUM_LIT:1>] = y<EOL>normals[n + <NUM_LIT:2>] = z<EOL>t += <NUM_LIT:2><EOL>v += <NUM_LIT:3><EOL>n += <NUM_LIT:3><EOL><DEDENT><DEDENT>indices = [<NUM_LIT:0>] * rings * sectors * <NUM_LIT:6><EOL>i = <NUM_LIT:0><EOL>for r in range(rings - <NUM_LIT:1>):<EOL><INDENT>for s in range(sectors - <NUM_LIT:1>):<EOL><INDENT>indices[i] = r * sectors + s<EOL>indices[i + <NUM_LIT:1>] = (r + <NUM_LIT:1>) * sectors + (s + <NUM_LIT:1>)<EOL>indices[i + <NUM_LIT:2>] = r * sectors + (s + <NUM_LIT:1>)<EOL>indices[i + <NUM_LIT:3>] = r * sectors + s<EOL>indices[i + <NUM_LIT:4>] = (r + <NUM_LIT:1>) * sectors + s<EOL>indices[i + <NUM_LIT:5>] = (r + <NUM_LIT:1>) * sectors + (s + <NUM_LIT:1>)<EOL>i += <NUM_LIT:6><EOL><DEDENT><DEDENT>vbo_vertices = numpy.array(vertices, dtype=numpy.float32)<EOL>vbo_normals = numpy.array(normals, dtype=numpy.float32)<EOL>vbo_uvs = numpy.array(uvs, dtype=numpy.float32)<EOL>vbo_elements = numpy.array(indices, dtype=numpy.uint32)<EOL>vao = VAO("<STR_LIT>", mode=mlg.TRIANGLES)<EOL>vao.buffer(vbo_vertices, '<STR_LIT>', ['<STR_LIT>'])<EOL>vao.buffer(vbo_normals, '<STR_LIT>', ['<STR_LIT>'])<EOL>vao.buffer(vbo_uvs, '<STR_LIT>', ['<STR_LIT>'])<EOL>vao.index_buffer(vbo_elements, index_element_size=<NUM_LIT:4>)<EOL>return vao<EOL>

Creates a sphere.

Keyword Args:
    radius (float): Radius or the sphere
    rings (int): number or horizontal rings
    sectors (int): number of vertical segments

Returns:
    A :py:class:`demosys.opengl.vao.VAO` instance


glfw.set_window_should_close(self.window, True)<EOL>


self.frames += <NUM_LIT:1><EOL>glfw.swap_buffers(self.window)<EOL>self.poll_events()<EOL>

Swaps buffers, incement the framecounter and pull events.


print("<STR_LIT>".format(glfw.get_version(), glfw.__version__))<EOL>if glfw.get_version() < self.min_glfw_version:<EOL><INDENT>raise ValueError("<STR_LIT>".format(self.min_glfw_version))<EOL><DEDENT>

Ensure glfw library  version is compatible


self.width = width<EOL>self.height = height<EOL>self.buffer_width, self.buffer_height = glfw.get_framebuffer_size(self.window)<EOL>self.set_default_viewport()<EOL>

Sets the new size and buffer size internally


self.width, self.height = width, height<EOL>self.buffer_width, self.buffer_height = width, height<EOL>self.resize(width, height)<EOL>

Pyglet specific callback for window resize events.


return self.window.has_exit<EOL>

returns the ``has_exit`` state in the pyglet window


if not self.window.context:<EOL><INDENT>return<EOL><DEDENT>self.frames += <NUM_LIT:1><EOL>self.window.flip()<EOL>self.window.dispatch_events()<EOL>

Swap buffers, increment frame counter and pull events


super().__init__()<EOL>pyglet.options['<STR_LIT>'] = False<EOL>config = pyglet.gl.Config()<EOL>config.double_buffer = True<EOL>config.major_version = self.gl_version.major<EOL>config.minor_version = self.gl_version.minor<EOL>config.forward_compatible = True<EOL>config.sample_buffers = <NUM_LIT:1> if self.samples > <NUM_LIT:1> else <NUM_LIT:0><EOL>config.samples = self.samples<EOL>self.window = PygletWrapper(<EOL>width=self.width, height=self.height,<EOL>caption=self.title,<EOL>resizable=self.resizable,<EOL>vsync=self.vsync,<EOL>fullscreen=self.fullscreen,<EOL>)<EOL>self.window.set_mouse_visible(self.cursor)<EOL>self.window.event(self.on_key_press)<EOL>self.window.event(self.on_key_release)<EOL>self.window.event(self.on_mouse_motion)<EOL>self.window.event(self.on_resize)<EOL>self.ctx = moderngl.create_context(require=self.gl_version.code)<EOL>context.WINDOW = self<EOL>self.fbo = self.ctx.screen<EOL>self.set_default_viewport()<EOL>

Opens a window using pyglet, registers input callbacks
and creates a moderngl context.


def on_key_press(self, symbol, modifiers):

self.keyboard_event(symbol, self.keys.ACTION_PRESS, modifiers)<EOL>

Pyglet specific key press callback.
Forwards and translates the events to :py:func:`keyboard_event`


def on_mouse_motion(self, x, y, dx, dy):

<EOL>self.cursor_event(x, self.buffer_height - y, dx, dy)<EOL>

Pyglet specific mouse motion callback.
Forwards and traslates the event to :py:func:`cursor_event`


def on_key_release(self, symbol, modifiers):

self.keyboard_event(symbol, self.keys.ACTION_RELEASE, modifiers)<EOL>

Pyglet specific key release callback.
Forwards and translates the events to :py:func:`keyboard_event`


super().__init__()<EOL>self._closed = False<EOL>gl = QtOpenGL.QGLFormat()<EOL>gl.setVersion(self.gl_version.major, self.gl_version.minor)<EOL>gl.setProfile(QtOpenGL.QGLFormat.CoreProfile)<EOL>gl.setDepthBufferSize(<NUM_LIT>)<EOL>gl.setDoubleBuffer(True)<EOL>gl.setSwapInterval(<NUM_LIT:1> if self.vsync else <NUM_LIT:0>)<EOL>if self.samples > <NUM_LIT:1>:<EOL><INDENT>gl.setSampleBuffers(True)<EOL>gl.setSamples(self.samples)<EOL><DEDENT>self.app = QtWidgets.QApplication([])<EOL>self.widget = QtOpenGL.QGLWidget(gl)<EOL>self.widget.setWindowTitle(self.title)<EOL>if self.fullscreen:<EOL><INDENT>rect = QtWidgets.QDesktopWidget().screenGeometry()<EOL>self.width = rect.width()<EOL>self.height = rect.height()<EOL>self.buffer_width = rect.width() * self.widget.devicePixelRatio()<EOL>self.buffer_height = rect.height() * self.widget.devicePixelRatio()<EOL><DEDENT>if self.resizable:<EOL><INDENT>size_policy = QtWidgets.QSizePolicy(<EOL>QtWidgets.QSizePolicy.Expanding,<EOL>QtWidgets.QSizePolicy.Expanding,<EOL>)<EOL>self.widget.setSizePolicy(size_policy)<EOL>self.widget.resize(self.width, self.height)<EOL><DEDENT>else:<EOL><INDENT>self.widget.setFixedSize(self.width, self.height)<EOL><DEDENT>self.widget.move(QtWidgets.QDesktopWidget().rect().center() - self.widget.rect().center())<EOL>self.widget.resizeGL = self.resize  <EOL>self.widget.show()<EOL>if not self.cursor:<EOL><INDENT>self.widget.setCursor(QtCore.Qt.BlankCursor)<EOL><DEDENT>if self.fullscreen:<EOL><INDENT>self.widget.showFullScreen()<EOL><DEDENT>self.widget.setMouseTracking(True)<EOL>self.widget.keyPressEvent = self.keyPressEvent<EOL>self.widget.keyReleaseEvent = self.keyReleaseEvent<EOL>self.widget.mouseMoveEvent = self.mouseMoveEvent<EOL>self.ctx = moderngl.create_context(require=self.gl_version.code)<EOL>context.WINDOW = self<EOL>self.fbo = self.ctx.screen<EOL>self.buffer_width = self.width * self.widget.devicePixelRatio()<EOL>self.buffer_height = self.height * self.widget.devicePixelRatio()<EOL>self.set_default_viewport()<EOL>

Creates a pyqt application and window overriding the
built in event loop. Sets up keyboard and mouse events
and creates a ``monderngl.Context``.


self._closed = True<EOL>


self.keyboard_event(event.key(), self.keys.ACTION_PRESS, <NUM_LIT:0>)<EOL>

Pyqt specific key press callback function.
Translates and forwards events to :py:func:`keyboard_event`.


self.cursor_event(event.x(), event.y(), <NUM_LIT:0>, <NUM_LIT:0>)<EOL>

Pyqt specific mouse event callback
Translates and forwards events to :py:func:`cursor_event`.


self.frames += <NUM_LIT:1><EOL>self.widget.swapBuffers()<EOL>self.app.processEvents()<EOL>

Swaps buffers, increments the frame counter and pulls events


self.keyboard_event(event.key(), self.keys.ACTION_RELEASE, <NUM_LIT:0>)<EOL>

Pyqt specific key release callback function.
Translates and forwards events to :py:func:`keyboard_event`.


self.width = width<EOL>self.height = height<EOL>self.buffer_width, self.buffer_height = self.width, self.height<EOL>self.set_default_viewport()<EOL>


super().__init__()<EOL>self.window_closing = False<EOL>self.tmp_size_x = c_int()<EOL>self.tmp_size_y = c_int()<EOL>print("<STR_LIT>", self.get_library_version())<EOL>if sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) != <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_CONTEXT_MAJOR_VERSION, self.gl_version.major)<EOL>sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_CONTEXT_MINOR_VERSION, self.gl_version.minor)<EOL>sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_CONTEXT_PROFILE_MASK, sdl2.SDL_GL_CONTEXT_PROFILE_CORE)<EOL>sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG, <NUM_LIT:1>)<EOL>sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_DOUBLEBUFFER, <NUM_LIT:1>)<EOL>sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_DEPTH_SIZE, <NUM_LIT>)<EOL>sdl2.SDL_ShowCursor(sdl2.SDL_ENABLE if self.cursor else sdl2.SDL_DISABLE)<EOL>if self.samples > <NUM_LIT:1>:<EOL><INDENT>sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_MULTISAMPLEBUFFERS, <NUM_LIT:1>)<EOL>sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_MULTISAMPLESAMPLES, self.samples)<EOL><DEDENT>flags = sdl2.SDL_WINDOW_OPENGL<EOL>if self.fullscreen:<EOL><INDENT>flags |= sdl2.SDL_WINDOW_FULLSCREEN_DESKTOP<EOL><DEDENT>else:<EOL><INDENT>if self.resizable:<EOL><INDENT>flags |= sdl2.SDL_WINDOW_RESIZABLE<EOL><DEDENT><DEDENT>self.window = sdl2.SDL_CreateWindow(<EOL>self.title.encode(),<EOL>sdl2.SDL_WINDOWPOS_UNDEFINED,<EOL>sdl2.SDL_WINDOWPOS_UNDEFINED,<EOL>self.width,<EOL>self.height,<EOL>flags<EOL>)<EOL>if not self.window:<EOL><INDENT>raise ValueError("<STR_LIT>", sdl2.SDL_GetError())<EOL><DEDENT>self.context = sdl2.SDL_GL_CreateContext(self.window)<EOL>sdl2.video.SDL_GL_SetSwapInterval(<NUM_LIT:1> if self.vsync else <NUM_LIT:0>)<EOL>self.ctx = moderngl.create_context(require=self.gl_version.code)<EOL>context.WINDOW = self<EOL>self.fbo = self.ctx.screen<EOL>self.set_default_viewport()<EOL>

Initializes sdl2, sets up key and mouse events and
creates a ``moderngl.Context`` using the context sdl2 createad.

Using the sdl2 window requires sdl binaries and PySDL2.


self.sys_camera.rot_state(x, y)<EOL>

The standard mouse movement event method.
Can be overriden to add new functionality.
By default this feeds the system camera with new values.

Args:
    x: The current mouse x position
    y: The current mouse y position
    dx: Delta x postion (x position difference from the previous event)
    dy: Delta y postion (y position difference from the previous event)


@property<EOL><INDENT>def buffer_size(self) -> Tuple[int, int]:<DEDENT>

return (self.buffer_width, self.buffer_height)<EOL>

(width, heigh) buffer size of the window.

This is the actual buffer size of the window
taking UI scale into account. A 1920 x 1080
window running in an environment with UI scale 2.0
would have a 3840 x 2160 window buffer.


<EOL>expected_height = int(self.buffer_width / self.aspect_ratio)<EOL>blank_space = self.buffer_height - expected_height<EOL>self.fbo.viewport = (<NUM_LIT:0>, blank_space // <NUM_LIT:2>, self.buffer_width, expected_height)<EOL>

Calculates the viewport based on the configured aspect ratio in settings.
Will add black borders if the window do not match the viewport.


raise NotImplementedError()<EOL>

The actual teardown of the window.

Raises:
    NotImplementedError


raise NotImplementedError()<EOL>

Set the window in close state. This doesn't actually close the window,
but should make :py:func:`should_close` return ``True`` so the
main loop can exit gracefully.

Raises:
    NotImplementedError


raise NotImplementedError()<EOL>

Check if window should close. This should always be checked in the main draw loop.

Raises:
    NotImplementedError


Resize the window. Should normallty be overriden
when implementing a window as most window libraries need additional logic here.

Args:
    width (int): Width of the window
    height: (int): Height of the window


def window(raise_on_error=True) -> BaseWindow:

if not WINDOW and raise_on_error:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>return WINDOW<EOL>

The window instance we are rendering to

:param raise_on_error: Raise an error if the window is not created yet


super().__init__()<EOL>self.headless_frames = getattr(settings, '<STR_LIT>', <NUM_LIT:0>)<EOL>self.headless_duration = getattr(settings, '<STR_LIT>', <NUM_LIT:0>)<EOL>if not self.headless_frames and not self.headless_duration:<EOL><INDENT>raise ImproperlyConfigured("<STR_LIT>")<EOL><DEDENT>self._close = False<EOL>self.ctx = moderngl.create_standalone_context(require=self.gl_version.code)<EOL>context.WINDOW = self<EOL>self.fbo = self.ctx.framebuffer(<EOL>color_attachments=self.ctx.texture(self.size, <NUM_LIT:4>),<EOL>depth_attachment=self.ctx.depth_texture(self.size),<EOL>)<EOL>self.set_default_viewport()<EOL>self.fbo.use()<EOL>

Creates a standalone ``moderngl.Context``.
The headless window currently have no event input from keyboard or mouse.

Using this window require either ``settings`` values to be present:

* ``HEADLESS_FRAMES``: How many frames should be rendered before closing the window
* ``HEADLESS_DURATION``: How many seconds rendering should last before the window closes


self._close = True<EOL>


self.fbo.use()<EOL>

Binds the framebuffer representing this window


@property<EOL><INDENT>def loader_cls(self) -> Type:<DEDENT>

return self._kwargs.get('<STR_LIT>')<EOL>

(Type) The loader class for this resource


@property<EOL><INDENT>def resolved_path(self) -> Path:<DEDENT>

return self.kwargs.get('<STR_LIT>')<EOL>

(pathlib.Path) The resolved path by a finder


@property<EOL><INDENT>def kwargs(self) -> Dict[str, str]:<DEDENT>

return self._kwargs<EOL>

(dict) All keywords arguments passed to the resource


self._check_meta(meta)<EOL>self.resolve_loader(meta)<EOL>self._resources.append(meta)<EOL>

Add a resource to this pool.
The resource is loaded and returned when ``load_pool()`` is called.

:param meta: The resource description


return self._kwargs.get('<STR_LIT>') or self.default_loader<EOL>


def get_loader(self, meta: ResourceDescription, raise_on_error=False) -> BaseLoader:

for loader in self._loaders:<EOL><INDENT>if loader.name == meta.loader:<EOL><INDENT>return loader<EOL><DEDENT><DEDENT>if raise_on_error:<EOL><INDENT>raise ImproperlyConfigured(<EOL>"<STR_LIT>".format(<EOL>meta.loader, meta, [loader.name for loader in self._loaders]))<EOL><DEDENT>

Attempts to get a loader

:param meta: The resource description instance
:param raise_on_error: Raise ImproperlyConfigured if the loader cannot be resolved
:returns: The requested loader class


return self._kwargs.get('<STR_LIT:path>')<EOL>

(str) The path to a resource when a single file is specified


def resolve_loader(self, meta: ProgramDescription):

if not meta.loader:<EOL><INDENT>meta.loader = '<STR_LIT>' if meta.path else '<STR_LIT>'<EOL><DEDENT>for loader_cls in self._loaders:<EOL><INDENT>if loader_cls.name == meta.loader:<EOL><INDENT>meta.loader_cls = loader_cls<EOL>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise ImproperlyConfigured(<EOL>(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>).format(meta.path)<EOL>)<EOL><DEDENT>


dirs = list(self.PROGRAM_DIRS)<EOL>dirs.append(directory)<EOL>self.PROGRAM_DIRS = dirs<EOL>


for name, value in kwargs.items():<EOL><INDENT>setattr(self, name, value)<EOL><DEDENT>


def show_type(self, edge_type, **kwargs):

for v in self.g.nodes():<EOL><INDENT>e = (v, v)<EOL>if self.g.is_edge(e) and self.g.ep(e, '<STR_LIT>') == edge_type:<EOL><INDENT>ei = self.g.edge_index[e]<EOL>self.g.set_vp(v, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL>self.g.set_vp(v, '<STR_LIT>', self.edge2queue[ei].colors['<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>self.g.set_vp(v, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL>self.g.set_vp(v, '<STR_LIT>', [<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT>])<EOL><DEDENT><DEDENT>for e in self.g.edges():<EOL><INDENT>if self.g.ep(e, '<STR_LIT>') == edge_type:<EOL><INDENT>self.g.set_ep(e, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>self.g.set_ep(e, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT><DEDENT>self.draw(update_colors=False, **kwargs)<EOL>self._update_all_colors()<EOL>

Draws the network, highlighting queues of a certain type.

        The colored vertices represent self loops of type ``edge_type``.
        Dark edges represent queues of type ``edge_type``.

        Parameters
        ----------
        edge_type : int
            The type of vertices and edges to be shown.
        **kwargs
            Any additional parameters to pass to :meth:`.draw`, and
            :meth:`.QueueNetworkDiGraph.draw_graph`

        Notes
        -----
        The colors are defined by the class attribute ``colors``. The
        relevant colors are ``vertex_active``, ``vertex_inactive``,
        ``vertex_highlight``, ``edge_active``, and ``edge_inactive``.

        Examples
        --------
        The following code highlights all edges with edge type ``2``.
        If the edge is a loop then the vertex is highlighted as well.
        In this case all edges with edge type ``2`` happen to be loops.

        >>> import queueing_tool as qt
        >>> g = qt.generate_pagerank_graph(100, seed=13)
        >>> net = qt.QueueNetwork(g, seed=13)
        >>> fname = 'edge_type_2.png'
        >>> net.show_type(2, fname=fname) # doctest: +SKIP

        .. figure:: edge_type_2-1.png
           :align: center


def get_agent_data(self, queues=None, edge=None, edge_type=None, return_header=False):

queues = _get_queues(self.g, queues, edge, edge_type)<EOL>data = {}<EOL>for qid in queues:<EOL><INDENT>for agent_id, dat in self.edge2queue[qid].data.items():<EOL><INDENT>datum = np.zeros((len(dat), <NUM_LIT:6>))<EOL>datum[:, :<NUM_LIT:5>] = np.array(dat)<EOL>datum[:, <NUM_LIT:5>] = qid<EOL>if agent_id in data:<EOL><INDENT>data[agent_id] = np.vstack((data[agent_id], datum))<EOL><DEDENT>else:<EOL><INDENT>data[agent_id] = datum<EOL><DEDENT><DEDENT><DEDENT>dType = [<EOL>('<STR_LIT:a>', float),<EOL>('<STR_LIT:s>', float),<EOL>('<STR_LIT:d>', float),<EOL>('<STR_LIT:q>', float),<EOL>('<STR_LIT:n>', float),<EOL>('<STR_LIT:id>', float)<EOL>]<EOL>for agent_id, dat in data.items():<EOL><INDENT>datum = np.array([tuple(d) for d in dat.tolist()], dtype=dType)<EOL>datum = np.sort(datum, order='<STR_LIT:a>')<EOL>data[agent_id] = np.array([tuple(d) for d in datum])<EOL><DEDENT>if return_header:<EOL><INDENT>return data, '<STR_LIT>'<EOL><DEDENT>return data<EOL>

Gets data from queues and organizes it by agent.

        If none of the parameters are given then data from every
        :class:`.QueueServer` is retrieved.

        Parameters
        ----------
        queues : int or *array_like* (optional)
            The edge index (or an iterable of edge indices) identifying
            the :class:`QueueServer(s)<.QueueServer>` whose data will
            be retrieved.
        edge : 2-tuple of int or *array_like* (optional)
            Explicitly specify which queues to retrieve agent data
            from. Must be either:

            * A 2-tuple of the edge's source and target vertex
              indices, or
            * An iterable of 2-tuples of the edge's source and
              target vertex indices.

        edge_type : int or an iterable of int (optional)
            A integer, or a collection of integers identifying which
            edge types to retrieve agent data from.
        return_header : bool (optonal, default: False)
            Determines whether the column headers are returned.

        Returns
        -------
        dict
            Returns a ``dict`` where the keys are the
            :class:`Agent's<.Agent>` ``agent_id`` and the values are
            :class:`ndarrays<~numpy.ndarray>` for that
            :class:`Agent's<.Agent>` data. The columns of this array
            are as follows:

            * First: The arrival time of an agent.
            * Second: The service start time of an agent.
            * Third: The departure time of an agent.
            * Fourth: The length of the queue upon the agents arrival.
            * Fifth: The total number of :class:`Agents<.Agent>` in the
              :class:`.QueueServer`.
            * Sixth: the :class:`QueueServer's<.QueueServer>` id
              (its edge index).

        headers : str (optional)
            A comma seperated string of the column headers. Returns
            ``'arrival,service,departure,num_queued,num_total,q_id'``


def simulate(self, n=<NUM_LIT:1>, t=None):

if not self._initialized:<EOL><INDENT>msg = ("<STR_LIT>"<EOL>"<STR_LIT>")<EOL>raise QueueingToolError(msg)<EOL><DEDENT>if t is None:<EOL><INDENT>for dummy in range(n):<EOL><INDENT>self._simulate_next_event(slow=False)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>now = self._t<EOL>while self._t < now + t:<EOL><INDENT>self._simulate_next_event(slow=False)<EOL><DEDENT><DEDENT>

Simulates the network forward.

        Simulates either a specific number of events or for a specified
        amount of simulation time.

        Parameters
        ----------
        n : int (optional, default: 1)
            The number of events to simulate. If ``t`` is not given
            then this parameter is used.
        t : float (optional)
            The amount of simulation time to simulate forward. If
            given, ``t`` is used instead of ``n``.

        Raises
        ------
        QueueingToolError
            Will raise a :exc:`.QueueingToolError` if the
            ``QueueNetwork`` has not been initialized. Call
            :meth:`.initialize` before calling this method.

        Examples
        --------
        Let ``net`` denote your instance of a ``QueueNetwork``. Before
        you simulate, you need to initialize the network, which allows
        arrivals from outside the network. To initialize with 2 (random
        chosen) edges accepting arrivals run:

        >>> import queueing_tool as qt
        >>> g = qt.generate_pagerank_graph(100, seed=50)
        >>> net = qt.QueueNetwork(g, seed=50)
        >>> net.initialize(2)

        To simulate the network 50000 events run:

        >>> net.num_events
        0
        >>> net.simulate(50000)
        >>> net.num_events
        50000

        To simulate the network for at least 75 simulation time units
        run:

        >>> t0 = net.current_time
        >>> net.simulate(t=75)
        >>> t1 = net.current_time
        >>> t1 - t0 # doctest: +ELLIPSIS
        75...


net = QueueNetwork(None)<EOL>net.g = self.g.copy()<EOL>net.max_agents = copy.deepcopy(self.max_agents)<EOL>net.nV = copy.deepcopy(self.nV)<EOL>net.nE = copy.deepcopy(self.nE)<EOL>net.num_agents = copy.deepcopy(self.num_agents)<EOL>net.num_events = copy.deepcopy(self.num_events)<EOL>net._t = copy.deepcopy(self._t)<EOL>net._initialized = copy.deepcopy(self._initialized)<EOL>net._prev_edge = copy.deepcopy(self._prev_edge)<EOL>net._blocking = copy.deepcopy(self._blocking)<EOL>net.colors = copy.deepcopy(self.colors)<EOL>net.out_edges = copy.deepcopy(self.out_edges)<EOL>net.in_edges = copy.deepcopy(self.in_edges)<EOL>net.edge2queue = copy.deepcopy(self.edge2queue)<EOL>net._route_probs = copy.deepcopy(self._route_probs)<EOL>if net._initialized:<EOL><INDENT>keys = [q._key() for q in net.edge2queue if q._time < np.infty]<EOL>net._fancy_heap = PriorityQueue(keys, net.nE)<EOL><DEDENT>return net<EOL>


def stop_collecting_data(self, queues=None, edge=None, edge_type=None):

queues = _get_queues(self.g, queues, edge, edge_type)<EOL>for k in queues:<EOL><INDENT>self.edge2queue[k].collect_data = False<EOL><DEDENT>

Tells the queues to stop collecting data on agents.

        If none of the parameters are given then every
        :class:`.QueueServer` will stop collecting data.

        Parameters
        ----------
        queues : int, *array_like* (optional)
            The edge index (or an iterable of edge indices) identifying
            the :class:`QueueServer(s)<.QueueServer>` that will stop
            collecting data.
        edge : 2-tuple of int or *array_like* (optional)
            Explicitly specify which queues will stop collecting data.
            Must be either:

            * A 2-tuple of the edge's source and target vertex
              indices, or
            * An iterable of 2-tuples of the edge's source and
              target vertex indices.

        edge_type : int or an iterable of int (optional)
            A integer, or a collection of integers identifying which
            edge types will stop collecting data.


if return_matrix:<EOL><INDENT>mat = np.zeros((self.nV, self.nV))<EOL>for v in self.g.nodes():<EOL><INDENT>ind = [e[<NUM_LIT:1>] for e in sorted(self.g.out_edges(v))]<EOL>mat[v, ind] = self._route_probs[v]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>mat = {<EOL>k: {e[<NUM_LIT:1>]: p for e, p in zip(sorted(self.g.out_edges(k)), value)}<EOL>for k, value in enumerate(self._route_probs)<EOL>}<EOL><DEDENT>return mat<EOL>

Returns the routing probabilities for each vertex in the
        graph.

        Parameters
        ----------
        return_matrix : bool (optional, the default is ``True``)
            Specifies whether an :class:`~numpy.ndarray` is returned.
            If ``False``, a dict is returned instead.

        Returns
        -------
        out : a dict or :class:`~numpy.ndarray`
            The transition probabilities for each vertex in the graph.
            If ``out`` is an :class:`~numpy.ndarray`, then
            ``out[v, u]`` returns the probability of a transition from
            vertex ``v`` to vertex ``u``. If ``out`` is a dict
            then ``out_edge[v][u]`` is the probability of moving from
            vertex ``v`` to the vertex ``u``.

        Examples
        --------
        Lets change the routing probabilities:

        >>> import queueing_tool as qt
        >>> import networkx as nx
        >>> g = nx.sedgewick_maze_graph()
        >>> net = qt.QueueNetwork(g)

        Below is an adjacency list for the graph ``g``.

        >>> ans = qt.graph2dict(g, False)
        >>> {k: sorted(v) for k, v in ans.items()}
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: [2, 5, 7],
         1: [7],
         2: [0, 6],
         3: [4, 5],
         4: [3, 5, 6, 7],
         5: [0, 3, 4],
         6: [2, 4],
         7: [0, 1, 4]}

        The default transition matrix is every out edge being equally
        likely:

        >>> net.transitions(False)  # doctest: +ELLIPSIS
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: {2: 0.333..., 5: 0.333..., 7: 0.333...},
         1: {7: 1.0},
         2: {0: 0.5, 6: 0.5},
         3: {4: 0.5, 5: 0.5},
         4: {3: 0.25, 5: 0.25, 6: 0.25, 7: 0.25},
         5: {0: 0.333..., 3: 0.333..., 4: 0.333...},
         6: {2: 0.5, 4: 0.5},
         7: {0: 0.333..., 1: 0.333..., 4: 0.333...}}

        Now we will generate a random routing matrix:

        >>> mat = qt.generate_transition_matrix(g, seed=96)
        >>> net.set_transitions(mat)
        >>> net.transitions(False)  # doctest: +ELLIPSIS
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: {2: 0.112..., 5: 0.466..., 7: 0.420...},
         1: {7: 1.0},
         2: {0: 0.561..., 6: 0.438...},
         3: {4: 0.545..., 5: 0.454...},
         4: {3: 0.374..., 5: 0.381..., 6: 0.026..., 7: 0.217...},
         5: {0: 0.265..., 3: 0.460..., 4: 0.274...},
         6: {2: 0.673..., 4: 0.326...},
         7: {0: 0.033..., 1: 0.336..., 4: 0.630...}}

        What this shows is the following: when an :class:`.Agent` is at
        vertex ``2`` they will transition to vertex ``0`` with
        probability ``0.561`` and route to vertex ``6`` probability
        ``0.438``, when at vertex ``6`` they will transition back to
        vertex ``2`` with probability ``0.673`` and route vertex ``4``
        probability ``0.326``, etc.


g = self.g<EOL>for v in g.nodes():<EOL><INDENT>self.g.set_vp(v, '<STR_LIT>', [<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT>])<EOL>is_active = False<EOL>my_iter = g.in_edges(v) if g.is_directed() else g.out_edges(v)<EOL>for e in my_iter:<EOL><INDENT>ei = g.edge_index[e]<EOL>if self.edge2queue[ei]._active:<EOL><INDENT>is_active = True<EOL>break<EOL><DEDENT><DEDENT>if is_active:<EOL><INDENT>self.g.set_vp(v, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>self.g.set_vp(v, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT><DEDENT>for e in g.edges():<EOL><INDENT>ei = g.edge_index[e]<EOL>if self.edge2queue[ei]._active:<EOL><INDENT>self.g.set_ep(e, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>self.g.set_ep(e, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT><DEDENT>self.draw(update_colors=False, **kwargs)<EOL>self._update_all_colors()<EOL>

Draws the network, highlighting active queues.

        The colored vertices represent vertices that have at least one
        queue on an in-edge that is active. Dark edges represent
        queues that are active, light edges represent queues that are
        inactive.

        Parameters
        ----------
        **kwargs
            Any additional parameters to pass to :meth:`.draw`, and
            :meth:`.QueueNetworkDiGraph.draw_graph`.

        Notes
        -----
        Active queues are :class:`QueueServers<.QueueServer>` that
        accept arrivals from outside the network. The colors are
        defined by the class attribute ``colors``. The relevant keys
        are ``vertex_active``, ``vertex_inactive``, ``edge_active``,
        and ``edge_inactive``.


def start_collecting_data(self, queues=None, edge=None, edge_type=None):

queues = _get_queues(self.g, queues, edge, edge_type)<EOL>for k in queues:<EOL><INDENT>self.edge2queue[k].collect_data = True<EOL><DEDENT>

Tells the queues to collect data on agents' arrival, service
        start, and departure times.

        If none of the parameters are given then every
        :class:`.QueueServer` will start collecting data.

        Parameters
        ----------
        queues : :any:`int`, *array_like* (optional)
            The edge index (or an iterable of edge indices) identifying
            the :class:`QueueServer(s)<.QueueServer>` that will start
            collecting data.
        edge : 2-tuple of int or *array_like* (optional)
            Explicitly specify which queues will collect data. Must be
            either:

            * A 2-tuple of the edge's source and target vertex
              indices, or
            * An iterable of 2-tuples of the edge's source and
              target vertex indices.

        edge_type : int or an iterable of int (optional)
            A integer, or a collection of integers identifying which
            edge types will be set active.


if isinstance(mat, dict):<EOL><INDENT>for key, value in mat.items():<EOL><INDENT>probs = list(value.values())<EOL>if key not in self.g.node:<EOL><INDENT>msg = "<STR_LIT>"<EOL>raise ValueError(msg)<EOL><DEDENT>elif len(self.out_edges[key]) > <NUM_LIT:0> and not np.isclose(sum(probs), <NUM_LIT:1>):<EOL><INDENT>msg = "<STR_LIT>"<EOL>raise ValueError(msg)<EOL><DEDENT>elif (np.array(probs) < <NUM_LIT:0>).any():<EOL><INDENT>msg = "<STR_LIT>"<EOL>raise ValueError(msg)<EOL><DEDENT>for k, e in enumerate(sorted(self.g.out_edges(key))):<EOL><INDENT>self._route_probs[key][k] = value.get(e[<NUM_LIT:1>], <NUM_LIT:0>)<EOL><DEDENT><DEDENT><DEDENT>elif isinstance(mat, np.ndarray):<EOL><INDENT>non_terminal = np.array([self.g.out_degree(v) > <NUM_LIT:0> for v in self.g.nodes()])<EOL>if mat.shape != (self.nV, self.nV):<EOL><INDENT>msg = ("<STR_LIT>"<EOL>"<STR_LIT>").format(self.nV, self.nV)<EOL>raise ValueError(msg)<EOL><DEDENT>elif not np.allclose(np.sum(mat[non_terminal, :], axis=<NUM_LIT:1>), <NUM_LIT:1>):<EOL><INDENT>msg = "<STR_LIT>"<EOL>raise ValueError(msg)<EOL><DEDENT>elif (mat < <NUM_LIT:0>).any():<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>for k in range(self.nV):<EOL><INDENT>for j, e in enumerate(sorted(self.g.out_edges(k))):<EOL><INDENT>self._route_probs[k][j] = mat[k, e[<NUM_LIT:1>]]<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

Change the routing transitions probabilities for the
        network.

        Parameters
        ----------
        mat : dict or :class:`~numpy.ndarray`
            A transition routing matrix or transition dictionary. If
            passed a dictionary, the keys are source vertex indices and
            the values are dictionaries with target vertex indicies
            as the keys and the probabilities of routing from the
            source to the target as the values.

        Raises
        ------
        ValueError
            A :exc:`.ValueError` is raised if: the keys in the dict
            don't match with a vertex index in the graph; or if the
            :class:`~numpy.ndarray` is passed with the wrong shape,
            must be (``num_vertices``, ``num_vertices``); or the values
            passed are not probabilities (for each vertex they are
            positive and sum to 1);
        TypeError
            A :exc:`.TypeError` is raised if mat is not a dict or
            :class:`~numpy.ndarray`.

        Examples
        --------
        The default transition matrix is every out edge being equally
        likely:

        >>> import queueing_tool as qt
        >>> adjacency = {
        ...     0: [2],
        ...     1: [2, 3],
        ...     2: [0, 1, 2, 4],
        ...     3: [1],
        ...     4: [2],
        ... }
        >>> g = qt.adjacency2graph(adjacency)
        >>> net = qt.QueueNetwork(g)
        >>> net.transitions(False)  # doctest: +ELLIPSIS
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: {2: 1.0},
         1: {2: 0.5, 3: 0.5},
         2: {0: 0.25, 1: 0.25, 2: 0.25, 4: 0.25},
         3: {1: 1.0},
         4: {2: 1.0}}

        If you want to change only one vertex's transition
        probabilities, you can do so with the following:

        >>> net.set_transitions({1 : {2: 0.75, 3: 0.25}})
        >>> net.transitions(False)  # doctest: +ELLIPSIS
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: {2: 1.0},
         1: {2: 0.75, 3: 0.25},
         2: {0: 0.25, 1: 0.25, 2: 0.25, 4: 0.25},
         3: {1: 1.0},
         4: {2: 1.0}}

        One can generate a transition matrix using
        :func:`.generate_transition_matrix`. You can change all
        transition probabilities with an :class:`~numpy.ndarray`:

        >>> mat = qt.generate_transition_matrix(g, seed=10)
        >>> net.set_transitions(mat)
        >>> net.transitions(False)  # doctest: +ELLIPSIS
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: {2: 1.0},
         1: {2: 0.962..., 3: 0.037...},
         2: {0: 0.301..., 1: 0.353..., 2: 0.235..., 4: 0.108...},
         3: {1: 1.0},
         4: {2: 1.0}}

        See Also
        --------
        :meth:`.transitions` : Return the current routing
            probabilities.
        :func:`.generate_transition_matrix` : Generate a random routing
            matrix.


leader = self.find(s)<EOL>return self._size[leader]<EOL>

Returns the number of elements in the set that ``s`` belongs to.

        Parameters
        ----------
        s : object
            An object

        Returns
        -------
        out : int
            The number of elements in the set that ``s`` belongs to.


s1, s2 = self.find(a), self.find(b)<EOL>if s1 != s2:<EOL><INDENT>r1, r2  = self._rank[s1], self._rank[s2]<EOL>if r2 > r1:<EOL><INDENT>r1, r2 = r2, r1<EOL>s1, s2 = s2, s1<EOL><DEDENT>if r1 == r2:<EOL><INDENT>self._rank[s1] += <NUM_LIT:1><EOL><DEDENT>self._leader[s2] = s1<EOL>self._size[s1]  += self._size[s2]<EOL>self.nClusters  -= <NUM_LIT:1><EOL><DEDENT>

Merges the set that contains ``a`` with the set that contains ``b``.

        Parameters
        ----------
        a, b : objects
            Two objects whose sets are to be merged.


pSet   = [s]<EOL>parent = self._leader[s]<EOL>while parent != self._leader[parent]:<EOL><INDENT>pSet.append(parent)<EOL>parent = self._leader[parent]<EOL><DEDENT>if len(pSet) > <NUM_LIT:1>:<EOL><INDENT>for a in pSet:<EOL><INDENT>self._leader[a] = parent<EOL><DEDENT><DEDENT>return parent<EOL>

Locates the leader of the set to which the element ``s`` belongs.

        Parameters
        ----------
        s : object
            An object that the ``UnionFind`` contains.

        Returns
        -------
        object
            The leader of the set that contains ``s``.


self.blocked += <NUM_LIT:1><EOL>

Adds one to the number of times the agent has been blocked
        from entering a queue.


def desired_destination(self, network, edge):

n = len(network.out_edges[edge[<NUM_LIT:1>]])<EOL>if n <= <NUM_LIT:1>:<EOL><INDENT>return network.out_edges[edge[<NUM_LIT:1>]][<NUM_LIT:0>]<EOL><DEDENT>u = uniform()<EOL>pr = network._route_probs[edge[<NUM_LIT:1>]]<EOL>k = _choice(pr, u, n)<EOL>return network.out_edges[edge[<NUM_LIT:1>]][k]<EOL>

Returns the agents next destination given their current
        location on the network.

        An ``Agent`` chooses one of the out edges at random. The
        probability that the ``Agent`` will travel along a specific
        edge is specified in the :class:`QueueNetwork's<.QueueNetwork>`
        transition matrix.

        Parameters
        ----------
        network : :class:`.QueueNetwork`
            The :class:`.QueueNetwork` where the Agent resides.
        edge : tuple
            A 4-tuple indicating which edge this agent is located at.
            The first two slots indicate the current edge's source and
            target vertices, while the third slot indicates this edges
            ``edge_index``. The last slot indicates the edge type of
            that edge

        Returns
        -------
        out : int
            Returns an the edge index corresponding to the agents next
            edge to visit in the network.

        See Also
        --------
        :meth:`.transitions` : :class:`QueueNetwork's<.QueueNetwork>`
            method that returns the transition probabilities for each
            edge in the graph.


def queue_action(self, queue, *args, **kwargs):

if isinstance(queue, ResourceQueue):<EOL><INDENT>if self._has_resource:<EOL><INDENT>self._has_resource = False<EOL>self._had_resource = True<EOL><DEDENT>else:<EOL><INDENT>if queue.num_servers > <NUM_LIT:0>:<EOL><INDENT>queue.set_num_servers(queue.num_servers - <NUM_LIT:1>)<EOL>self._has_resource = True<EOL>self._had_resource = False<EOL><DEDENT><DEDENT><DEDENT>

Function that specifies the interaction with a
        :class:`.ResourceQueue` upon departure.

        When departuring from a :class:`.ResourceQueue` (or a
        :class:`.QueueServer`), this method is called. If the agent
        does not already have a resource then it decrements the number
        of servers at :class:`.ResourceQueue` by one. Note that this
        only applies to :class:`ResourceQueue's<.ResourceQueue>`.

        Parameters
        ----------
        queue : :class:`.QueueServer`
            The instance of the queue that the ``ResourceAgent`` will
            interact with.


return len(self.queue)<EOL>

Returns the number of agents waiting in line to be served.

        Returns
        -------
        out : int
            The number of agents waiting in line to be served.


self.data = {}<EOL>self._num_arrivals = <NUM_LIT:0><EOL>self._oArrivals = <NUM_LIT:0><EOL>self.num_departures = <NUM_LIT:0><EOL>self.num_system = <NUM_LIT:0><EOL>self._num_total = <NUM_LIT:0><EOL>self._current_t = <NUM_LIT:0><EOL>self._time = infty<EOL>self._next_ct = <NUM_LIT:0><EOL>self._active = False<EOL>self.queue = collections.deque()<EOL>inftyAgent = InftyAgent()<EOL>self._arrivals = [inftyAgent]<EOL>self._departures = [inftyAgent]<EOL>

Clears out the queue. Removes all arrivals, departures, and
        queued agents from the :class:`.QueueServer`, resets
        ``num_arrivals``, ``num_departures``, ``num_system``, and the clock to
        zero. It also clears any stored ``data`` and the server is then
        set to inactive.


if self._departures[<NUM_LIT:0>]._time < self._arrivals[<NUM_LIT:0>]._time:<EOL><INDENT>return <NUM_LIT:2><EOL><DEDENT>elif self._arrivals[<NUM_LIT:0>]._time < infty:<EOL><INDENT>return <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>return <NUM_LIT:0><EOL><DEDENT>

Returns an integer representing whether the next event is
        an arrival, a departure, or nothing.

        Returns
        -------
        out : int
            An integer representing whether the next event is an
            arrival or a departure: ``1`` corresponds to an arrival,
            ``2`` corresponds to a departure, and ``0`` corresponds to
            nothing scheduled to occur.


if len(self._departures) > <NUM_LIT:1>:<EOL><INDENT>agent = heappop(self._departures)<EOL>if t is None:<EOL><INDENT>agent._time = self.service_f(agent._time)<EOL><DEDENT>else:<EOL><INDENT>agent._time = t<EOL><DEDENT>heappush(self._departures, agent)<EOL>self._update_time()<EOL><DEDENT>

Adds an extra service time to the next departing
        :class:`Agent's<.Agent>` service time.

        Parameters
        ----------
        t : float (optional)
            Specifies the departing time for the agent scheduled
            to depart next. If ``t`` is not given, then an additional
            service time is added to the next departing agent.


self._active = False<EOL>

Changes the ``active`` attribute to False.


def poisson_random_measure(t, rate, rate_max):

scale = <NUM_LIT:1.0> / rate_max<EOL>t = t + exponential(scale)<EOL>while rate_max * uniform() > rate(t):<EOL><INDENT>t = t + exponential(scale)<EOL><DEDENT>return t<EOL>

A function that returns the arrival time of the next arrival for
    a Poisson random measure.

    Parameters
    ----------
    t : float
        The start time from which to simulate the next arrival time.
    rate : function
        The *intensity function* for the measure, where ``rate(t)`` is
        the expected arrival rate at time ``t``.
    rate_max : float
        The maximum value of the ``rate`` function.

    Returns
    -------
    out : float
        The time of the next arrival.

    Notes
    -----
    This function returns the time of the next arrival, where the
    distribution of the number of arrivals between times :math:`t` and
    :math:`t+s` is Poisson with mean

    .. math::

       \int_{t}^{t+s} dx \, r(x)

    where :math:`r(t)` is the supplied ``rate`` function. This function
    can only simulate processes that have bounded intensity functions.
    See chapter 6 of [3]_ for more on the mathematics behind Poisson
    random measures; the book's publisher, Springer, has that chapter
    available online for free at (`pdf`_\).

    A Poisson random measure is sometimes called a non-homogeneous
    Poisson process. A Poisson process is a special type of Poisson
    random measure.

    .. _pdf: http://www.springer.com/cda/content/document/\
                cda_downloaddocument/9780387878584-c1.pdf

    Examples
    --------
    Suppose you wanted to model the arrival process as a Poisson
    random measure with rate function :math:`r(t) = 2 + \sin( 2\pi t)`.
    Then you could do so as follows:

    >>> import queueing_tool as qt
    >>> import numpy as np
    >>> np.random.seed(10)
    >>> rate  = lambda t: 2 + np.sin(2 * np.pi * t)
    >>> arr_f = lambda t: qt.poisson_random_measure(t, rate, 3)
    >>> arr_f(1)  # doctest: +ELLIPSIS
    1.491...

    References
    ----------
    .. [3] Cinlar, Erhan. *Probability and stochastics*. Graduate Texts in\
           Mathematics. Vol. 261. Springer, New York, 2011.\
           :doi:`10.1007/978-0-387-87859-1`


if not self._active:<EOL><INDENT>self._active = True<EOL>self._add_arrival()<EOL><DEDENT>

Changes the ``active`` attribute to True. Agents may now
        arrive from outside the network.


return False<EOL>

Returns whether the queue is at capacity or not.

        Returns
        -------
        bool
            Always returns ``False``, since the ``QueueServer`` class
            has infinite capacity.


def adjacency2graph(adjacency, edge_type=None, adjust=<NUM_LIT:1>, **kwargs):

if isinstance(adjacency, np.ndarray):<EOL><INDENT>adjacency = _matrix2dict(adjacency)<EOL><DEDENT>elif isinstance(adjacency, dict):<EOL><INDENT>adjacency = _dict2dict(adjacency)<EOL><DEDENT>else:<EOL><INDENT>msg = ("<STR_LIT>"<EOL>"<STR_LIT>")<EOL>raise TypeError(msg)<EOL><DEDENT>if edge_type is None:<EOL><INDENT>edge_type = {}<EOL><DEDENT>else:<EOL><INDENT>if isinstance(edge_type, np.ndarray):<EOL><INDENT>edge_type = _matrix2dict(edge_type, etype=True)<EOL><DEDENT>elif isinstance(edge_type, dict):<EOL><INDENT>edge_type = _dict2dict(edge_type)<EOL><DEDENT><DEDENT>for u, ty in edge_type.items():<EOL><INDENT>for v, et in ty.items():<EOL><INDENT>adjacency[u][v]['<STR_LIT>'] = et<EOL><DEDENT><DEDENT>g = nx.from_dict_of_dicts(adjacency, create_using=nx.DiGraph())<EOL>adjacency = nx.to_dict_of_dicts(g)<EOL>adjacency = _adjacency_adjust(adjacency, adjust, True)<EOL>return nx.from_dict_of_dicts(adjacency, create_using=nx.DiGraph())<EOL>

Takes an adjacency list, dict, or matrix and returns a graph.

    The purpose of this function is take an adjacency list (or matrix)
    and return a :class:`.QueueNetworkDiGraph` that can be used with a
    :class:`.QueueNetwork` instance. The Graph returned has the
    ``edge_type`` edge property set for each edge. Note that the graph may
    be altered.

    Parameters
    ----------
    adjacency : dict or :class:`~numpy.ndarray`
        An adjacency list as either a dict, or an adjacency matrix.
    adjust : int ``{1, 2}`` (optional, default: 1)
        Specifies what to do when the graph has terminal vertices
        (nodes with no out-edges). Note that if ``adjust`` is not 2
        then it is assumed to be 1. There are two choices:

        * ``adjust = 1``: A loop is added to each terminal node in the
          graph, and their ``edge_type`` of that loop is set to 0.
        * ``adjust = 2``: All edges leading to terminal nodes have
          their ``edge_type`` set to 0.

    **kwargs :
        Unused.

    Returns
    -------
    out : :any:`networkx.DiGraph`
        A directed graph with the ``edge_type`` edge property.

    Raises
    ------
    TypeError
        Is raised if ``adjacency`` is not a dict or
        :class:`~numpy.ndarray`.

    Examples
    --------
    If terminal nodes are such that all in-edges have edge type ``0``
    then nothing is changed. However, if a node is a terminal node then
    a loop is added with edge type 0.

    >>> import queueing_tool as qt
    >>> adj = {
    ...     0: {1: {}},
    ...     1: {2: {},
    ...         3: {}},
    ...     3: {0: {}}}
    >>> eTy = {0: {1: 1}, 1: {2: 2, 3: 4}, 3: {0: 1}}
    >>> # A loop will be added to vertex 2
    >>> g = qt.adjacency2graph(adj, edge_type=eTy)
    >>> ans = qt.graph2dict(g)
    >>> sorted(ans.items())     # doctest: +NORMALIZE_WHITESPACE
    [(0, {1: {'edge_type': 1}}),
     (1, {2: {'edge_type': 2}, 3: {'edge_type': 4}}),
     (2, {2: {'edge_type': 0}}),
     (3, {0: {'edge_type': 1}})]

    You can use a dict of lists to represent the adjacency list.

    >>> adj = {0 : [1], 1: [2, 3], 3: [0]}
    >>> g = qt.adjacency2graph(adj, edge_type=eTy)
    >>> ans = qt.graph2dict(g)
    >>> sorted(ans.items())     # doctest: +NORMALIZE_WHITESPACE
    [(0, {1: {'edge_type': 1}}),
     (1, {2: {'edge_type': 2}, 3: {'edge_type': 4}}),
     (2, {2: {'edge_type': 0}}),
     (3, {0: {'edge_type': 1}})]

    Alternatively, you could have this function adjust the edges that
    lead to terminal vertices by changing their edge type to 0:

    >>> # The graph is unaltered
    >>> g = qt.adjacency2graph(adj, edge_type=eTy, adjust=2)
    >>> ans = qt.graph2dict(g)
    >>> sorted(ans.items())     # doctest: +NORMALIZE_WHITESPACE
    [(0, {1: {'edge_type': 1}}),
     (1, {2: {'edge_type': 0}, 3: {'edge_type': 4}}),
     (2, {}),
     (3, {0: {'edge_type': 1}})]


def lines_scatter_args(self, line_kwargs=None, scatter_kwargs=None, pos=None):

if pos is not None:<EOL><INDENT>self.set_pos(pos)<EOL><DEDENT>elif self.pos is None:<EOL><INDENT>self.set_pos()<EOL><DEDENT>edge_pos = [<NUM_LIT:0> for e in self.edges()]<EOL>for e in self.edges():<EOL><INDENT>ei = self.edge_index[e]<EOL>edge_pos[ei] = (self.pos[e[<NUM_LIT:0>]], self.pos[e[<NUM_LIT:1>]])<EOL><DEDENT>line_collecton_kwargs = {<EOL>'<STR_LIT>': edge_pos,<EOL>'<STR_LIT>': self.edge_color,<EOL>'<STR_LIT>': (<NUM_LIT:1>,),<EOL>'<STR_LIT>': (<NUM_LIT:1>,),<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': plt.cm.ocean_r,<EOL>'<STR_LIT>': <NUM_LIT:5>,<EOL>'<STR_LIT>': <NUM_LIT:0>,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>}<EOL>scatter_kwargs_ = {<EOL>'<STR_LIT:x>': self.pos[:, <NUM_LIT:0>],<EOL>'<STR_LIT:y>': self.pos[:, <NUM_LIT:1>],<EOL>'<STR_LIT:s>': <NUM_LIT:50>,<EOL>'<STR_LIT:c>': self.vertex_fill_color,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT:o>',<EOL>'<STR_LIT>': <NUM_LIT:2>,<EOL>'<STR_LIT>': plt.cm.ocean_r,<EOL>'<STR_LIT>': <NUM_LIT:1>,<EOL>'<STR_LIT>': self.vertex_color,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>}<EOL>line_kwargs = {} if line_kwargs is None else line_kwargs<EOL>scatter_kwargs = {} if scatter_kwargs is None else scatter_kwargs<EOL>for key, value in line_kwargs.items():<EOL><INDENT>if key in line_collecton_kwargs:<EOL><INDENT>line_collecton_kwargs[key] = value<EOL><DEDENT><DEDENT>for key, value in scatter_kwargs.items():<EOL><INDENT>if key in scatter_kwargs_:<EOL><INDENT>scatter_kwargs_[key] = value<EOL><DEDENT><DEDENT>return line_collecton_kwargs, scatter_kwargs_<EOL>

Returns the arguments used when plotting.

        Takes any keyword arguments for
        :class:`~matplotlib.collections.LineCollection` and
        :meth:`~matplotlib.axes.Axes.scatter` and returns two
        dictionaries with all the defaults set.

        Parameters
        ----------
        line_kwargs : dict (optional, default: ``None``)
            Any keyword arguments accepted by
            :class:`~matplotlib.collections.LineCollection`.
        scatter_kwargs : dict (optional, default: ``None``)
            Any keyword arguments accepted by
            :meth:`~matplotlib.axes.Axes.scatter`.

        Returns
        -------
        tuple
            A 2-tuple of dicts. The first entry is the keyword
            arguments for
            :class:`~matplotlib.collections.LineCollection` and the
            second is the keyword args for
            :meth:`~matplotlib.axes.Axes.scatter`.

        Notes
        -----
        If a specific keyword argument is not passed then the defaults
        are used.


edges = []<EOL>for e in self.edges():<EOL><INDENT>if self.adj[e[<NUM_LIT:0>]][e[<NUM_LIT:1>]].get('<STR_LIT>') == edge_type:<EOL><INDENT>edges.append(e)<EOL><DEDENT><DEDENT>return edges<EOL>

Returns all edges with the specified edge type.

        Parameters
        ----------
        edge_type : int
            An integer specifying what type of edges to return.

        Returns
        -------
        out : list of 2-tuples
            A list of 2-tuples representing the edges in the graph
            with the specified edge type.

        Examples
        --------
        Lets get type 2 edges from the following graph

        >>> import queueing_tool as qt
        >>> adjacency = {
        ...     0: {1: {'edge_type': 2}},
        ...     1: {2: {'edge_type': 1},
        ...         3: {'edge_type': 4}},
        ...     2: {0: {'edge_type': 2}},
        ...     3: {3: {'edge_type': 0}}
        ... }
        >>> G = qt.QueueNetworkDiGraph(adjacency)
        >>> ans = G.get_edge_type(2)
        >>> ans.sort()
        >>> ans
        [(0, 1), (2, 0)]


n = len(matrix)<EOL>adj = {k: {} for k in range(n)}<EOL>for k in range(n):<EOL><INDENT>for j in range(n):<EOL><INDENT>if matrix[k, j] != <NUM_LIT:0>:<EOL><INDENT>adj[k][j] = {} if not etype else matrix[k, j]<EOL><DEDENT><DEDENT><DEDENT>return adj<EOL>

Takes an adjacency matrix and returns an adjacency list.