1"use strict";(self.webpackChunksimulately=self.webpackChunksimulately||[]).push([[4074],{5680:(e,n,t)=>{t.d(n,{xA:()=>c,yg:()=>g});var a=t(6540);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function s(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function l(e,n){if(null==e)return{};var t,a,i=function(e,n){if(null==e)return{};var t,a,i={},o=Object.keys(e);for(a=0;a<o.length;a++)t=o[a],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)t=o[a],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var r=a.createContext({}),p=function(e){var n=a.useContext(r),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(r.Provider,{value:n},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,o=e.originalType,r=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),u=i,g=d["".concat(r,".").concat(u)]||d[u]||m[u]||o;return t?a.createElement(g,s(s({ref:n},c),{},{components:t})):a.createElement(g,s({ref:n},c))}));function g(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var o=t.length,s=new Array(o);s[0]=u;var l={};for(var r in n)hasOwnProperty.call(n,r)&&(l[r]=n[r]);l.originalType=e,l[d]="string"==typeof e?e:i,s[1]=l;for(var p=2;p<o;p++)s[p]=t[p];return a.createElement.apply(null,s)}return a.createElement.apply(null,t)}u.displayName="MDXCreateElement"},1720:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=t(8168),i=(t(6540),t(5680));const o={sidebar_position:0},s="Getting Started",l={unversionedId:"snippets/isaac-sim/getting-started",id:"snippets/isaac-sim/getting-started",title:"Getting Started",description:"Welcome to the Getting Started for using IsaacSim. Here, we will quickly go through:",source:"@site/docs/3_snippets/isaac-sim/getting-started.md",sourceDirName:"3_snippets/isaac-sim",slug:"/snippets/isaac-sim/getting-started",permalink:"/docs/snippets/isaac-sim/getting-started",draft:!1,editUrl:"https://github.com/geng-haoran/Simulately/edit/main/docs/3_snippets/isaac-sim/getting-started.md",tags:[],version:"current",sidebarPosition:0,frontMatter:{sidebar_position:0},sidebar:"tutorialSidebar",previous:{title:"IsaacSim",permalink:"/docs/category/isaacsim"},next:{title:"Camera Sensors",permalink:"/docs/snippets/isaac-sim/camera"}},r={},p=[{value:"An efficient way of dev in Isaac Sim",id:"an-efficient-way-of-dev-in-isaac-sim",level:2},{value:"Three workflows in Isaac Sim",id:"three-workflows-in-isaac-sim",level:2},{value:"Quick-Start in Extensions",id:"quick-start-in-extensions",level:2},{value:"Create an Extensions with the <code>BaseSample</code> class.",id:"create-an-extensions-with-the-basesample-class",level:3},{value:"Edit the <code>extension.toml</code>",id:"edit-the-extensiontoml",level:4},{value:"Create a Base Extension in <code>demo.py</code>",id:"create-a-base-extension-in-demopy",level:4},{value:"Set Up Extension Loading in <code>demo_extensions.py</code>",id:"set-up-extension-loading-in-demo_extensionspy",level:4},{value:"Import Essentials in <code>__init__.py</code>",id:"import-essentials-in-__init__py",level:4},{value:"Set Up the Scene in <code>setup_scene</code>",id:"set-up-the-scene-in-setup_scene",level:3},{value:"Add a Robot",id:"add-a-robot",level:4},{value:"Add a Table with a Cube",id:"add-a-table-with-a-cube",level:4},{value:"Set Up Physics Step Callback",id:"set-up-physics-step-callback",level:3},{value:"Physics States",id:"physics-states",level:3},{value:"Robot Control",id:"robot-control",level:3},{value:"Quick-Start in Standalone Extensions",id:"quick-start-in-standalone-extensions",level:2},{value:"Migrate to / Create a Standalone Extension",id:"migrate-to--create-a-standalone-extension",level:3},{value:"Obtaining the <code>World</code> instance",id:"obtaining-the-world-instance",level:3},{value:"Simulation steps",id:"simulation-steps",level:3},{value:"Closing the simulation app",id:"closing-the-simulation-app",level:3}],c={toc:p},d="wrapper";
1function m(e){let{components:n,...t}=e;return(0,i.yg)(d,(0,a.A)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.yg)("h1",{id:"getting-started"},"Getting Started"),(0,i.yg)("p",null,"Welcome to the Getting Started for using IsaacSim. Here, we will quickly go through:"),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},"An efficient way of development in Isaac Sim"),(0,i.yg)("li",{parentName:"ol"},"Three workflows (GUI, extensions, and standalone extensions)"),(0,i.yg)("li",{parentName:"ol"},"GUI in Isaac Sim"),(0,i.yg)("li",{parentName:"ol"},"Standalone Python")),(0,i.yg)("p",null,"Some information are borrowed from the ",(0,i.yg)("a",{parentName:"p",href:"https://docs.omniverse.nvidia.com/isaacsim/latest/index.html"},"official docs of Isaac Sim"),", but we provide a more concentrated version to get you ready."),(0,i.yg)("h2",{id:"an-efficient-way-of-dev-in-isaac-sim"},"An efficient way of dev in Isaac Sim"),(0,i.yg)("p",null,"Before we get started, here are several things you need to know:"),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},'Like other modules like the Create in Omniverse, Isaac Sim is also built on Omniverse Kit. Almost all the functions are implemented as "extensions", ',(0,i.yg)("em",{parentName:"li"},"i.e.")," every action you do in the GUI can be implemented via coding."),(0,i.yg)("li",{parentName:"ol"},"You can find the Isaac Sim local folder at ",(0,i.yg)("inlineCode",{parentName:"li"},"INSTALL_DIRECTORY/pkg/isaac-sim-VERSION/"),". For ubuntu, ",(0,i.yg)("inlineCode",{parentName:"li"},"INSTALL_DIRECTORY")," is ",(0,i.yg)("inlineCode",{parentName:"li"},"~/.local/share/ov/")," by default. It would be a rapid way, if you want to add new features to your app, to perform a search in this folder to find possibly relative codes."),(0,i.yg)("li",{parentName:"ol"},"For docs, always start from ",(0,i.yg)("a",{parentName:"li",href:"https://docs.omniverse.nvidia.com/isaacsim/latest/index.html"},"this main page")," for the latest version of the documentation, and use the built-in searching (rather than directly searching on Google, which may provide out-of-date links).")),(0,i.yg)("h2",{id:"three-workflows-in-isaac-sim"},"Three workflows in Isaac Sim"),(0,i.yg)("p",null,"There are three workflows in Isaac Sim that you can use to develop:"),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},"GUI: directly interacting with the Isaac Sim GUI, pushing buttons, connecting action graphs, to implement what you want. This is useful if you want to:",(0,i.yg)("ul",{parentName:"li"},(0,i.yg)("li",{parentName:"ul"},"constructing a scene or buiding a robot"),(0,i.yg)("li",{parentName:"ul"},"tune the physical parameters (",(0,i.yg)("em",{parentName:"li"},"e.g."),", joint damping and stifness, light temperature, ",(0,i.yg)("em",{parentName:"li"},"e.t.c"),")"))),(0,i.yg)("li",{parentName:"ol"},"Extensions: Start from the menu bar in a launched Isaac Sim, which pops out a panel for your app. You interact with your app inside. This is useful if you want to:",(0,i.yg)("ul",{parentName:"li"},(0,i.yg)("li",{parentName:"ul"},"interact with your app or provide some arguments (",(0,i.yg)("em",{parentName:"li"},"e.g.")," the position you want the robot to go) to the app in play"),(0,i.yg)("li",{parentName:"ul"},"build a plug-in for Isaac Sim, rather than just performing simulations"))),(0,i.yg)("li",{parentName:"ol"},"Standalone extensions: Start by running scripts, . This is useful if you want to:",(0,i.yg)("ul",{parentName:"li"},(0,i.yg)("li",{parentName:"ul"},"run your app in headless mode"),(0,i.yg)("li",{parentName:"ul"},"control over timing of physics and rendering steps")))),(0,i.yg)("p",null,(0,i.yg)("a",{parentName:"p",href:"https://docs.omniverse.nvidia.com/isaacsim/latest/introductory_tutorials/tutorial_intro_workflows.html"},"This page")," provides a more thorough introduction."),(0,i.yg)("h2",{id:"quick-start-in-extensions"},"Quick-Start in Extensions"),(0,i.yg)("p",null,"In this section, we will switch to the extensions workflow, which is a more structured way to programming, as you can leverage a pre-defined base classes ",(0,i.yg)("inlineCode",{parentName:"p"},"BaseSample")," and you just to implement some APIs such as scene setup or physics step. Besides, saving the files in the extensions codes triggers hot-reload in Isaac Sim, which boosts your development."),(0,i.yg)("h3",{id:"create-an-extensions-with-the-basesample-class"},"Create an Extensions with the ",(0,i.yg)("inlineCode",{parentName:"h3"},"BaseSample")," class."),(0,i.yg)("p",null,"Make a directory that is structured as:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre"},".\n\u251c\u2500\u2500 config\n\u2502\xa0\xa0 \u2514\u2500\u2500 extension.toml\n\u2514\u2500\u2500 scripts\n \u251c\u2500\u2500 __init__.py\n \u251c\u2500\u2500 demo.py\n \u2514\u2500\u2500 demo_extensions.py\n")),(0,i.yg)("h4",{id:"edit-the-extensiontoml"},"Edit the ",(0,i.yg)("inlineCode",{parentName:"h4"},"extension.toml")),(0,i.yg)("p",null,"This file tells the Isaac Sim how to load the extension."),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-ini"},'[core]\nreloadable = true\norder = 0\n\n[package]\nversion = "1.0.0"\ncategory = "Simulation"\ntitle = "Isaac Sim Demo"\ndescription = "Isaac Sim Demo for Simulately."\nauthors = ["Jane Doe"]\nrepository = ""\nkeywords = ["simulately", "simulation", "robot"]\nwriteTarget.kit = true\n\n[dependencies]\n"omni.kit.uiapp" = {}\n"omni.physx" = {}\n"omni.isaac.dynamic_control" = {}\n"omni.isaac.motion_planning" = {}\n"omni.isaac.synthetic_utils" = {}\n"omni.isaac.ui" = {}\n"omni.isaac.core" = {}\n"omni.isaac.franka" = {}\n"omni.isaac.manipulators" = {}\n"omni.isaac.dofbot" = {}\n"omni.isaac.universal_robots" = {}\n"omni.isaac.motion_generation" = {}\n"omni.graph.action" = {}\n"omni.graph.nodes" = {}\n"omni.graph.core" = {}\n"omni.isaac.quadruped" = {}\n"omni.isaac.wheeled_robots" = {}\n\n[[python.module]]\nname = "scripts"\n\n[[test]]\ntimeout = 960\n')),(0,i.yg)("h4",{id:"create-a-base-extension-in-demopy"},"Create a Base Extension in ",(0,i.yg)("inlineCode",{parentName:"h4"},"demo.py")),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},"import numpy as np\nfrom omni.isaac.core.objects import FixedCuboid, DynamicCuboid\nfrom omni.isaac.examples.base_sample import BaseSample\n\nclass Demo(BaseSample):\n def __init__(self) -> None:\n super().__init__()\n return\n\n def setup_sce
1ne(self):\n # Used to add assets.\n # Only called to load the world starting from an EMPTY stage.\n pass\n\n async def setup_post_load(self):\n pass\n\n def physics_step(self, step_size):\n pass\n")),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"The ",(0,i.yg)("inlineCode",{parentName:"li"},"setup_scene")," allows us to add assets to the scene. It is called to load the world, only if the stage is totally empty."),(0,i.yg)("li",{parentName:"ul"},"The ",(0,i.yg)("inlineCode",{parentName:"li"},"setup_post_load"),' is called upon hitting the "LOAD" button, working in an asynchronized way. It comes in handy to get the latest simulation handles.'),(0,i.yg)("li",{parentName:"ul"},"The ",(0,i.yg)("inlineCode",{parentName:"li"},"physics_step")," is called in each simulation step when the simulation is running. You can add control logics to it to control the scene.")),(0,i.yg)("h4",{id:"set-up-extension-loading-in-demo_extensionspy"},"Set Up Extension Loading in ",(0,i.yg)("inlineCode",{parentName:"h4"},"demo_extensions.py")),(0,i.yg)("p",null,"This file loads essential classes from the surrounding files to load the extension in to the simulation app."),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},'import os\nfrom omni.isaac.examples.base_sample import BaseSampleExtension\nfrom .demo import Demo\nfrom omni.kit.menu.utils import add_menu_items, remove_menu_items\nfrom omni.isaac.ui.menu import make_menu_item_description\n\nEXTENSION_TITLE = "Launch Demo"\n\nclass DemoExtension(BaseSampleExtension):\n def on_startup(self, ext_id: str):\n super().on_startup(ext_id)\n super().start_extension(\n menu_name="",\n submenu_name="",\n name="Demo",\n title="Isaac Sim Demo",\n doc_link="",\n overview="Simulately Isaac Sim Demo",\n file_path=os.path.abspath(__file__),\n sample=Demo()\n )\n')),(0,i.yg)("h4",{id:"import-essentials-in-__init__py"},"Import Essentials in ",(0,i.yg)("inlineCode",{parentName:"h4"},"__init__.py")),(0,i.yg)("p",null,"Just like any other ",(0,i.yg)("inlineCode",{parentName:"p"},"__init__.py"),", this file imports essential libraries to make a package:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},"from .demo import Demo\nfrom .demo_extension import DemoExtension\n")),(0,i.yg)("h3",{id:"set-up-the-scene-in-setup_scene"},"Set Up the Scene in ",(0,i.yg)("inlineCode",{parentName:"h3"},"setup_scene")),(0,i.yg)("p",null,"We will set up the scene using the ",(0,i.yg)("inlineCode",{parentName:"p"},"setup_scene")," function. We first add a ground plane to hold everything:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},"def setup_scene(self):\n # ...\n\n world = self.get_world()\n world.scene.add_default_ground_plane()\n\n # ...\n")),(0,i.yg)("p",null,"It first get the handle to the world to manage it with ",(0,i.yg)("inlineCode",{parentName:"p"},"self.get_world()"),". Then, it adds a default ground plane with ",(0,i.yg)("inlineCode",{parentName:"p"},"add_default_ground_plane()"),", which adds a blue-white plane to the world, which also includes a sphere light and other essential components."),(0,i.yg)("p",null,"Now, we will add a robot and some objects to the scene. For more information concerning stage management, please refer to ",(0,i.yg)("a",{parentName:"p",href:"./stage_management"},"Stage Management in Isaac Sim")),(0,i.yg)("h4",{id:"add-a-robot"},"Add a Robot"),(0,i.yg)("p",null,"Then, we add a robot to the scene."),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},'def setup_scene(self):\n # ...\n\n world = self.get_world()\n\n # ...\n\n world.scene.add(Franka(prim_path="/World/Franka", name="franka"))\n self._franka = world.scene.get_object(f"franka")\n')),(0,i.yg)("h4",{id:"add-a-table-with-a-cube"},"Add a Table with a Cube"),(0,i.yg)("p",null,"Now, let's add a table (a fixed cuboid) as well a cube on it (a dynamic cuboid), in front of the robot."),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"}
1,'def setup_scene(self):\n # ...\n\n world = self.get_world()\n\n # ...\n\n world.scene.add(\n FixedCuboid(\n prim_path=f"/World/table",\n name=f"table",\n scale=np.array([0.5, 1.25, 0.2]),\n color=np.array([1.0, 1.0, 1.0]),\n position=np.array([0.7, 0.0, 0.1])\n )\n )\n\n world.scene.add(self._franka)\n fancy_cube = world.scene.add(\n DynamicCuboid(\n prim_path="/World/cube",\n name="cube",\n scale=np.array([0.2, 0.2, 0.2]),\n color=np.array([0, 0, 1.0]),\n position=np.array([0.7, 0.0, 0.3])\n ))\n\n self._table = world.scene.get_object(f"table")\n self._cube = world.scene.get_object("cube")\n')),(0,i.yg)("h3",{id:"set-up-physics-step-callback"},"Set Up Physics Step Callback"),(0,i.yg)("p",null,"In each simulation step, before computing the physics, you can manipulate the simulation with a callback function, which we usually set up using:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},'async def setup_post_load(self):\n self._world = self.get_world()\n self._world.add_physics_callback("sim_step", callback_fn=self.physics_step)\n # ...\n\ndef physics_step(self, step_size):\n pass\n')),(0,i.yg)("h3",{id:"physics-states"},"Physics States"),(0,i.yg)("p",null,"To know about the physics states in the simulation, we can leverage APIs through the ",(0,i.yg)("inlineCode",{parentName:"p"},"World")," instance."),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},'async def setup_post_load(self):\n # ...\n\n self._cube = self._world.scene.get_object("cube")\n\n # ...\n\ndef physics_step(self, step_size):\n # ...\n\n pos, rot = self._cube.get_world_pose()\n lin_vel = self._cube.get_linear_velocity()\n\n # ...\n')),(0,i.yg)("h3",{id:"robot-control"},"Robot Control"),(0,i.yg)("p",null,"To control the robot, there are several ways. The most direct way is to apply action while providing the desired joint positions:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},"def physics_step(self, step_size):\n # ...\n\n self._franka.apply_action(ArticulationAction([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])) # Desired joint positions for arm\n # or\n self._franka.apply_action(ArticulationAction([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.04, 0.04])) # Desired joint positions for arm and gripper\n\n # ...\n")),(0,i.yg)("p",null,"This will control the robot to the given joint positions with a controller, and the joint positions in the list is matched following the joint indices. Also, for a robot like Franka Emika Panda, the built-in implementation allows you to interact with the ",(0,i.yg)("inlineCode",{parentName:"p"},"Robot")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"Articulation")," APIs, for instance,"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},"def physics_step(self, step_size):\n # ...\n\n self._franka.apply_action(ArticulationAction([0.04, 0.04])) # Desired joint positions for gripper\n \n # ...\n")),(0,i.yg)("p",null,"For more advanced ways of controlling the robot, consider referring to ",(0,i.yg)("a",{parentName:"p",href:"./rmpflow"},"RMPFlow"),", ",(0,i.yg)("a",{parentName:"p",href:"./control-robots-ros-bridge"},"Controlling Robots with ROS Bridge"),", ",(0,i.yg)("em",{parentName:"p"},"e.t.c"),"."),(0,i.yg)("h2",{id:"quick-start-in-standalone-extensions"},"Quick-Start in Standalone Extensions"),(0,i.yg)("p",null,"Coding in Isaac Sim endows powerful simulations. In this section, we will show procedures to migrate the extension code to the standalone extension version. For more information, you can refer to ",(0,i.yg)("a",{parentName:"p",href:"https://docs.omniverse.nvidia.com/isaacsim/latest/core_api_tutorials/tutorial_core_hello_world.html#converting-the-example-to-a-standalone-application"},"this page"),"."),(0,i.yg)("p",null,"A standalone extension is a python script. To run it, go to your installation directory of your isaac sim (",(0,i.yg)("inlineCode",{parentName:"p"},"INSTALL_DIRECTORY/pkg/isaac-sim-VERSION"),"), you will find a ",(0,i.yg)("inlineCode",{parentName:"p"},"python.sh")," here. To start a standalone app, you run:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-shell"},"./python.sh PATH_TO_YOUR_APP.py\n")),(0,i.yg)("h3",{id:"migrate-to--create-a-standalone-extension"},"Migrate to / Create a Standalone Extension"),(0,i.yg)("p",null,"Now, let's add something to our script. First, we launch the simulation application with"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},'from omni.isaac.kit import SimulationApp\napp = SimulationApp({"headless": False})\n\nfrom omni.isaac.core import World\n# other imports\n')),(0,i.yg)("p",null,"This two lines launches the Kit window, and are recommended to be added as the very first two lines of your script, as importing other dependencies before them may cuase problems."),(0,i.yg)("h3",{id:"obtaining-the-world-instance"},"Obtaining the ",(0,i.yg)("inlineCode",{parentName:"h3"},"World")," instance"),(0,i.yg)("p",null,"To obtain the ",(0,i.yg)("inlineCode",{parentName:"p"},"World")," instance, use:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},"from omni.isaac.core import World\n\nworld = World()\n")),(0,i.yg)("h3",{id:"simulation-steps"},"Simulation steps"),(0,i.yg)("p",null,"The substitute for using the ",(0,i.yg)("inlineCode",{parentName:"p"},"physics_step")," function as the callback is to create a loop and step the simulation inside:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},"world.reset()\nN_STEPS = 10000\n\nfor i in range(N_STEPS):\n # Do your things\n\n world.step(render=True)\n")),(0,i.yg)("h3",{id:"closing-the-simulation-app"},"Closing the simulation app"),(0,i.yg)("p",null,"In the end, close the simulation app:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-python"},"app.close()\n")))}m.isMDXComponent=!0}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.