async def get_latest_answer():
    global query_resp_history
    if interaction.current_agent is None:
        return JSONResponse(status_code=404, content={"error": "No agent available"})
    uid = str(uuid.uuid4())
    if not any(q["answer"] == interaction.current_agent.last_answer for q in query_resp_history):
        query_resp = {
            "done": "false",
            "answer": interaction.current_agent.last_answer,
            "reasoning": interaction.current_agent.last_reasoning,
            "agent_name": interaction.current_agent.agent_name if interaction.current_agent else "None",
            "success": interaction.current_agent.success,
            "blocks": {f'{i}': block.jsonify() for i, block in enumerate(interaction.get_last_blocks_result())} if interaction.current_agent else {},
            "status": interaction.current_agent.get_status_message if interaction.current_agent else "No status available",
            "uid": uid
        }
        interaction.current_agent.last_answer = ""
        interaction.current_agent.last_reasoning = ""
        query_resp_history.append(query_resp)
        return JSONResponse(status_code=200, content=query_resp)
    if query_resp_history:
        return JSONResponse(status_code=200, content=query_resp_history[-1])
    return JSONResponse(status_code=404, content={"error": "No answer available"})


def main():
    parser = argparse.ArgumentParser(
        prog="moshi_import", description="Imports moshi checkpoints"
    )
    parser.add_argument("checkpoint", help="The checkpoint to be imported.")
    parser.add_argument("out", help="The safetensors out file.")
    args = parser.parse_args()

    out_path = Path(args.out)

    if out_path.exists():
        print("file already exists")
    else:
        import_model(args.checkpoint, out_path)
    print(out_path)


    def _add_partial_read_service(self, ioi, elements):
        """
        Add the partial read service to the tag IOI
        """
        RequestService = 0x52
        RequestPathSize = int(len(ioi)/2)
        read_service = pack('<BB', RequestService, RequestPathSize)
        read_service += ioi
        read_service += pack('<H', int(elements))
        read_service += pack('<I', self.Offset)
        return read_service


    def __init__(self, real):
        pass


    def action_redirect_to_forum(self):
        self.ensure_one()
        action = self.env.ref('website_forum.action_forum_post').read()[0]
        action['view_mode'] = 'tree'
        action['context'] = {
            'create': False
        }
        action['domain'] = [('forum_id', '=', self.forum_id.id)]

        return action


        def insert_item(buf, at, newpos):
            newtext = "".join(item[0] for item in buf)
            newsc = buf[0][2]  # start char of first item in buffer
            newec = buf[-1][3]  # end char of last item in buffer
            parts.insert(insertat, (newtext, newpos, newsc, newec))


    def _sample_data(self, indices):
        """Sample batch of training data from a list of tasks.

        Args:
            indices (list): List of task indices to sample from.

        Returns:
            torch.Tensor: Obervations, with shape :math:`(X, N, O^*)` where X
                is the number of tasks. N is batch size.
            torch.Tensor: Actions, with shape :math:`(X, N, A^*)`.
            torch.Tensor: Rewards, with shape :math:`(X, N, 1)`.
            torch.Tensor: Next obervations, with shape :math:`(X, N, O^*)`.
            torch.Tensor: Dones, with shape :math:`(X, N, 1)`.

        """
        # transitions sampled randomly from replay buffer
        initialized = False
        for idx in indices:
            batch = self._replay_buffers[idx].sample_transitions(
                self._batch_size)
            if not initialized:
                o = batch['observations'][np.newaxis]
                a = batch['actions'][np.newaxis]
                r = batch['rewards'][np.newaxis]
                no = batch['next_observations'][np.newaxis]
                d = batch['dones'][np.newaxis]
                initialized = True
            else:
                o = np.vstack((o, batch['observations'][np.newaxis]))
                a = np.vstack((a, batch['actions'][np.newaxis]))
                r = np.vstack((r, batch['rewards'][np.newaxis]))
                no = np.vstack((no, batch['next_observations'][np.newaxis]))
                d = np.vstack((d, batch['dones'][np.newaxis]))

        o = torch.as_tensor(o, device=global_device()).float()
        a = torch.as_tensor(a, device=global_device()).float()
        r = torch.as_tensor(r, device=global_device()).float()
        no = torch.as_tensor(no, device=global_device()).float()
        d = torch.as_tensor(d, device=global_device()).float()

        return o, a, r, no, d


    def _wrap_object(self, space, obj):
        return space.newlong_from_rarith_int(obj)


def test_detection(detection_predictor, test_image):
    detection_results = detection_predictor([test_image])

    assert len(detection_results) == 1
    assert detection_results[0].image_bbox == [0, 0, 1024, 1024]

    bboxes = detection_results[0].bboxes
    assert len(bboxes) == 4


def save_audio_file(base64_data: str, filename: str = "output.mp3") -> None:
    audio_bytes = base64.b64decode(base64_data)
    with open(filename, "wb") as file:
        file.write(audio_bytes)


    def test_record(self):
        install_dir = self.mkdtemp()
        project_dir, dist = self.create_dist(py_modules=['hello'],
                                             scripts=['sayhi'])
        os.chdir(project_dir)
        self.write_file('hello.py', "def main(): print 'o hai'")
        self.write_file('sayhi', 'from hello import main; main()')

        cmd = install(dist)
        dist.command_obj['install'] = cmd
        cmd.root = install_dir
        cmd.record = os.path.join(project_dir, 'filelist')
        cmd.ensure_finalized()
        cmd.run()

        f = open(cmd.record)
        try:
            content = f.read()
        finally:
            f.close()

        found = [os.path.basename(line) for line in content.splitlines()]
        expected = ['hello.py', 'hello.pyc', 'sayhi',
                    'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]]
        self.assertEqual(found, expected)


  def _GetDeviceAddresses(self, excluded_iface):
    """Returns the IP addresses on all connected devices.
    Excludes interface |excluded_iface| on the selected device.
    """
    my_device = str(self._device)
    addresses = []
    for device_serial in android_device.GetDeviceSerials(None):
      try:
        device = device_utils.DeviceUtils(device_serial)
        if device_serial == my_device:
          excluded = excluded_iface
        else:
          excluded = 'no interfaces excluded on other devices'
        output = device.RunShellCommand(
            ['ip', '-o', '-4', 'addr'], check_return=True)
        addresses += [
            line.split()[3] for line in output if excluded not in line]
      except device_errors.CommandFailedError:
        logging.warning('Unable to determine IP addresses for %s',
                        device_serial)
    return addresses


def install_package(*packages):
    subprocess.check_call([sys.executable, "-m", "pip", "install", *packages])


def partial_fields(target_class, kwargs):
    return target_class(**{k: v for k, v in kwargs.items() if hasattr(target_class, k)})


def create_demo(model_path, save_path):
    model = initialize_model(model_path)

    with gr.Blocks() as demo:
        gr.Markdown("# Hunyuan Video Generation")

        with gr.Row():
            with gr.Column():
                prompt = gr.Textbox(label="Prompt", value="A cat walks on the grass, realistic style.")
                with gr.Row():
                    resolution = gr.Dropdown(
                        choices=[
                            # 720p
                            ("1280x720 (16:9, 720p)", "1280x720"),
                            ("720x1280 (9:16, 720p)", "720x1280"),
                            ("1104x832 (4:3, 720p)", "1104x832"),
                            ("832x1104 (3:4, 720p)", "832x1104"),
                            ("960x960 (1:1, 720p)", "960x960"),
                            # 540p
                            ("960x544 (16:9, 540p)", "960x544"),
                            ("544x960 (9:16, 540p)", "544x960"),
                            ("832x624 (4:3, 540p)", "832x624"),
                            ("624x832 (3:4, 540p)", "624x832"),
                            ("720x720 (1:1, 540p)", "720x720"),
                        ],
                        value="1280x720",
                        label="Resolution"
                    )
                    video_length = gr.Dropdown(
                        label="Video Length",
                        choices=[
                            ("2s(65f)", 65),
                            ("5s(129f)", 129),
                        ],
                        value=129,
                    )
                num_inference_steps = gr.Slider(1, 100, value=50, step=1, label="Number of Inference Steps")
                show_advanced = gr.Checkbox(label="Show Advanced Options", value=False)
                with gr.Row(visible=False) as advanced_row:
                    with gr.Column():
                        seed = gr.Number(value=-1, label="Seed (-1 for random)")
                        guidance_scale = gr.Slider(1.0, 20.0, value=1.0, step=0.5, label="Guidance Scale")
                        flow_shift = gr.Slider(0.0, 10.0, value=7.0, step=0.1, label="Flow Shift")
                        embedded_guidance_scale = gr.Slider(1.0, 20.0, value=6.0, step=0.5, label="Embedded Guidance Scale")
                show_advanced.change(fn=lambda x: gr.Row(visible=x), inputs=[show_advanced], outputs=[advanced_row])
                generate_btn = gr.Button("Generate")

            with gr.Column():
                output = gr.Video(label="Generated Video")

        generate_btn.click(
            fn=lambda *inputs: generate_video(model, *inputs),
            inputs=[
                prompt,
                resolution,
                video_length,
                seed,
                num_inference_steps,
                guidance_scale,
                flow_shift,
                embedded_guidance_scale
            ],
            outputs=output
        )

    return demo


def with_community_info(func):
    """
    Decorator: Show community info before executing the command
    """

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        show_community_info()
        return func(*args, **kwargs)

    return wrapper


    def _getReplyValues(self, tag_name, elements, data):
        """
        Gather up all the values in the reply/replies
        """
        tag, base_tag, index = _parseTagName(tag_name, 0)
        data_type = self.KnownTags[base_tag][0]
        fmt = self.CIPTypes[data_type][2]
        vals = []

        data_size = self.CIPTypes[data_type][0]
        numbytes = len(data)-data_size
        counter = 0

        # this is going to check if the data type was a struct
        # if so, return the raw data
        if data_type == 160:
            tmp = unpack_from('<h', data, 2)[0]
            if tmp != self.StructIdentifier:
                d = data[4:4+len(data)]
                vals.append(d)
                self.Offset += len(data)
                return vals

        while True:
            index = 2+(counter*data_size)
            if index > numbytes:
                break
            if data_type == 160:
                index = 4+(counter*data_size)
                name_len = unpack_from('<L', data, index)[0]
                s = data[index+4:index+4+name_len]
                vals.append(str(s.decode(self.StringEncoding)))

            elif data_type == 218:
                # remove the data type
                data = data[2:]
                while len(data) > 0:
                    # get the next string length
                    length = unpack_from('<B', data, 0)[0]
                    # remove the length from the packet
                    data = data[1:]
                    # grab the string
                    s = data[:length]
                    vals.append(str(s.decode(self.StringEncoding)))
                    # remove the string from the packet
                    data = data[length:]
                break
            else:
                returnvalue = unpack_from(fmt, data, index)[0]
                vals.append(returnvalue)

            self.Offset += data_size
            counter += 1

        return vals


    def assignment_callback(offsets: Mapping[Partition, int]) -> None:
        assignment_callback.called = True
        assert inner_consumer.tell() == {partition: 0}
        assert consumer.tell() == {partition: 0}


    def pbar_update(self, name: str = "", item_name: str = ""):
        if self.pbar.n < self.total:
            self.pbar.update()
            self.update_progress(
                f"正在进行{name}, 剩余{self.total - self.pbar.n}个{item_name}, 预计剩余时间: {get_pbar_remaining(n=self.pbar.n, total=self.total, start_time=self.start_time)}",
                int((self.pbar.n / self.total) * 100),
            )


    def consumer(self):
        return Consumer(self._location, self._enable_ssl, self._cert_path, self._topic, self._group, partition_id=None)


def test_parse_hparam_args__decimal():
    hparam_args = ['--foo', 'HParams(boo=0.01)']
    assert parse_hparam_args(hparam_args) == {'foo': HParams(boo=0.01)}


    def graph(self, graph):
        self._graph = graph


def test_merge_configs():
    """ Test the merging of two configurations via `add_config`.
    """

    @configurable
    def configured(arg, arg_two):
        pass

    @configurable
    def other_configured(arg):
        pass

    add_config({configured: HParams(arg='arg', arg_two='arg_two')})
    add_config({other_configured: HParams()})
    assert len(get_config()) == 2
    assert get_config()[_get_function_signature(configured.__wrapped__)]['arg'] == 'arg'
    add_config({configured: HParams(arg='gra')})
    assert len(get_config()) == 2
    assert get_config()[_get_function_signature(configured.__wrapped__)]['arg'] == 'gra'
    assert get_config()[_get_function_signature(configured.__wrapped__)]['arg_two'] == 'arg_two'


	def test_domain_filter_matching(self):
		"""Test that domain filters work correctly with glob patterns"""
		registry = ActionRegistry()

		# Create actions with different domain patterns
		actions = {
			'exact_match': RegisteredAction(
				name='exact_match',
				description='Exact domain match',
				function=lambda: None,
				param_model=EmptyParamModel,
				domains=['example.com'],
				page_filter=None,
			),
			'subdomain_match': RegisteredAction(
				name='subdomain_match',
				description='Subdomain wildcard match',
				function=lambda: None,
				param_model=EmptyParamModel,
				domains=['*.example.com'],
				page_filter=None,
			),
			'prefix_match': RegisteredAction(
				name='prefix_match',
				description='Prefix wildcard match',
				function=lambda: None,
				param_model=EmptyParamModel,
				domains=['example*'],
				page_filter=None,
			),
			'non_matching': RegisteredAction(
				name='non_matching',
				description='Non-matching domain',
				function=lambda: None,
				param_model=EmptyParamModel,
				domains=['other.com'],
				page_filter=None,
			),
		}

		registry.actions = actions

		# Test exact domain match
		mock_page = MagicMock(spec=Page)
		mock_page.url = 'https://example.com/page'

		exact_match_description = registry.get_prompt_description(mock_page)
		assert 'exact_match' in exact_match_description
		assert 'non_matching' not in exact_match_description

		# Test subdomain match
		mock_page.url = 'https://sub.example.com/page'
		subdomain_match_description = registry.get_prompt_description(mock_page)
		assert 'subdomain_match' in subdomain_match_description
		assert 'exact_match' not in subdomain_match_description

		# Test prefix match
		mock_page.url = 'https://example123.org/page'
		prefix_match_description = registry.get_prompt_description(mock_page)
		assert 'prefix_match' in prefix_match_description


    def producer(self):
        return SimpleProducer(self._location, self._enable_ssl, self._cert_path, self._topic, self._codec,
                              batch_size=DEFAULT_BATCH_SIZE,
                              buffer_memory=DEFAULT_BUFFER_MEMORY)


def find_nearest_bucket(h, w, resolution=640):
    min_metric = float('inf')
    best_bucket = None
    for (bucket_h, bucket_w) in bucket_options[resolution]:
        metric = abs(h * bucket_w - w * bucket_h)
        if metric <= min_metric:
            min_metric = metric
            best_bucket = (bucket_h, bucket_w)
    return best_bucket


def small2large(x):
    # (d * d, width, width) -> (d * width, d * width)
    x = x.reshape(args.divide, args.divide, width, width, -1)
    x = np.transpose(x, (0, 2, 1, 3, 4))
    x = x.reshape(args.divide * width, args.divide * width, -1)
    return x


async def test_exclude_specific_custom_types():
    """Test excluding specific custom entity types while keeping others."""
    graphiti = Graphiti(NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD)

    try:
        await graphiti.build_indices_and_constraints()

        # Define multiple entity types
        entity_types = {
            'Person': Person,
            'Organization': Organization,
            'Location': Location,
        }

        # Add an episode with content that would create all types
        episode_content = (
            'Sarah Johnson from Google visited the San Francisco office to discuss the new project.'
        )

        result = await graphiti.add_episode(
            name='Office Visit',
            episode_body=episode_content,
            source_description='Visit report',
            reference_time=datetime.now(timezone.utc),
            entity_types=entity_types,
            excluded_entity_types=['Organization', 'Location'],  # Exclude these types
            group_id='test_exclude_custom',
        )

        assert result is not None

        # Search for nodes to verify only Person and Entity types were created
        search_results = await graphiti.search_(
            query='Sarah Johnson Google San Francisco', group_ids=['test_exclude_custom']
        )

        found_nodes = search_results.nodes

        # Should have Person and Entity type nodes, but no Organization or Location
        for node in found_nodes:
            assert 'Entity' in node.labels
            # Should not have excluded types
            assert 'Organization' not in node.labels, (
                f'Found excluded Organization in node: {node.name}'
            )
            assert 'Location' not in node.labels, f'Found excluded Location in node: {node.name}'

        # Should find at least one Person entity (Sarah Johnson)
        person_nodes = [n for n in found_nodes if 'Person' in n.labels]
        assert len(person_nodes) > 0, 'Should have found at least one Person entity'

        # Clean up
        await _cleanup_test_nodes(graphiti, 'test_exclude_custom')

    finally:
        await graphiti.close()


def _sign_alg_name_to_id(s_alg):
    """Try to convert signature algorithm name to SignatureAlgorithm TLS ID.

    accepts also a string with a single number in it
    """
    try:
        return int(s_alg)
    except ValueError:
        return getattr(SignatureAlgorithm, s_alg)


    def get(self, name: str):
        """
        Get the alias by name
        """
        return self.primary_to_aliases.get(name, set())


def resample(audio_tensor, sr0, sr1, device):
    global resample_transform_dict
    key = "%s-%s-%s" % (sr0, sr1, str(device))
    if key not in resample_transform_dict:
        resample_transform_dict[key] = torchaudio.transforms.Resample(sr0, sr1).to(device)
    return resample_transform_dict[key](audio_tensor)


    def __init__(
        self,
        config: OpenHandsConfig,
        event_stream: EventStream,
        sid: str = 'default',
        plugins: list[PluginRequirement] | None = None,
        env_vars: dict[str, str] | None = None,
        status_callback: Callable | None = None,
        attach_to_existing: bool = False,
        headless_mode: bool = True,
        user_id: str | None = None,
        git_provider_tokens: PROVIDER_TOKEN_TYPE | None = None,
    ):
        # Read Runloop API key from environment variable
        runloop_api_key = os.getenv('RUNLOOP_API_KEY')
        if not runloop_api_key:
            raise ValueError('RUNLOOP_API_KEY environment variable is required for Runloop runtime')

        self.devbox: DevboxView | None = None
        self.config = config
        self.runloop_api_client = Runloop(
            bearer_token=runloop_api_key,
        )
        self.container_name = CONTAINER_NAME_PREFIX + sid
        super().__init__(
            config,
            event_stream,
            sid,
            plugins,
            env_vars,
            status_callback,
            attach_to_existing,
            headless_mode,
            user_id,
            git_provider_tokens,
        )
        # Buffer for container logs
        self._vscode_url: str | None = None


def test_cosine_extraction(tester: Crawl4AiTester):
    print("\n=== Testing Cosine Extraction ===")
    request = {
        "urls": ["https://www.nbcnews.com/business"],
        "priority": 8,
        "extraction_config": {
            "type": "cosine",
            "params": {
                "semantic_filter": "business finance economy",
                "word_count_threshold": 10,
                "max_dist": 0.2,
                "top_k": 3,
            },
        },
    }

    try:
        result = tester.submit_and_wait(request)
        extracted = json.loads(result["result"]["extracted_content"])
        print(f"Extracted {len(extracted)} text clusters")
        print("First cluster tags:", extracted[0]["tags"])
        assert result["result"]["success"]
    except Exception as e:
        print(f"Cosine extraction test failed: {str(e)}")


def save_yaml_file(file_path: str, data: dict) -> None:
    with open(file_path, 'w', encoding='utf-8') as file:
        yaml.safe_dump(data,
                       file,
                       default_flow_style=False,
                       allow_unicode=True,
                       indent=2,
                       sort_keys=False)


def nfort_flags(conf):
	v=conf.env
	v['_FCMODOUTFLAGS']=[]
	v['FCFLAGS_DEBUG']=[]
	v['FCFLAGS_fcshlib']=[]
	v['LINKFLAGS_fcshlib']=[]
	v['FCSTLIB_MARKER']=''
	v['FCSHLIB_MARKER']=''


    def __init__(self, open, high, low, close):
        pass


def writable_preferred_server_selector(selection):
    """Like PrimaryPreferred but doesn't use tags or latency."""
    return (writable_server_selector(selection) or
            secondary_server_selector(selection))


def compute_chunk(chunk, chunk_expr, part):
    return compute(chunk_expr, {chunk: part})


    def upsert_mapped_projects(user_id: int, project_id: int):
        """ Add project to mapped projects if it doesn't exist, otherwise return """
        User.upsert_mapped_projects(user_id, project_id)


def select(self, timeout: Optional[float] = ...) -> List[Tuple[SelectorKey, _EventMask]]: ...


    def test_mean(self):
        self.check('CAN15/GMPEtInterface_Low_combo.csv',
                   max_discrep_percentage=900.)


def get_converter():
    converter = DocumentConverter(allowed_formats=[InputFormat.CSV])

    return converter


def format_duration(milliseconds):
    """将毫秒转换为时分秒的显示格式"""
    total_seconds = milliseconds / 1000
    hours = int(total_seconds // 3600)
    minutes = int((total_seconds % 3600) // 60)
    seconds = int(total_seconds % 60)

    if hours > 0:
        return f"{hours:02d}时{minutes:02d}分{seconds:02d}秒"
    elif minutes > 0:
        return f"{minutes:02d}分{seconds:02d}秒"
    else:
        return f"{seconds:02d}秒"


        def _prediction_to_probabilities(y: np.ndarray, classes: List[Any]) -> np.ndarray:
            """Transforms predicted probabilities to match with OpenML class indices.

            Parameters
            ----------
            y : np.ndarray
                Predicted probabilities (possibly omitting classes if they were not present in the
                training data).
            model_classes : list
                List of classes known_predicted by the model, ordered by their index.

            Returns
            -------
            np.ndarray
            """
            # y: list or numpy array of predictions
            # model_classes: sklearn classifier mapping from original array id to
            # prediction index id
            if not isinstance(classes, list):
                raise ValueError("please convert model classes to list prior to " "calling this fn")
            result = np.zeros((len(y), len(classes)), dtype=np.float32)
            for obs, prediction_idx in enumerate(y):
                result[obs][prediction_idx] = 1.0
            return result


    def deactivate_restore(self):
        if self.is_restore_active:
            for seq in self.RESTORE_SEQUENCES:
                self.text.event_delete(self.RESTORE_VIRTUAL_EVENT_NAME, seq)
            self.is_restore_active = False


    def __init__(self, id):
        if id < 0:
            self.id = c_uint32(id).value
        else:
            self.id = id
        if zibe_errors.error_codes.has_key(self.id):
            error_data = zibe_errors.error_codes[self.id]
            self.message = error_data[1]
            self.name = error_data[0]
        else:
            self.message = 'Unknown error 0x%x' % self.id


  def __init__(
      self,
      name: str,
      disallow_transfer_to_parent: bool = False,
      parent_agent: Optional[BaseAgent] = None,
  ):
    # Use a string model instead of mock
    super().__init__(name=name, model="gemini-1.5-pro", sub_agents=[])
    self.disallow_transfer_to_parent = disallow_transfer_to_parent
    self.parent_agent = parent_agent


    def test_finalize_options(self):
        dist = Distribution({'name': 'xx'})
        cmd = install(dist)

        # must supply either prefix/exec-prefix/home or
        # install-base/install-platbase -- not both
        cmd.prefix = 'prefix'
        cmd.install_base = 'base'
        self.assertRaises(DistutilsOptionError, cmd.finalize_options)

        # must supply either home or prefix/exec-prefix -- not both
        cmd.install_base = None
        cmd.home = 'home'
        self.assertRaises(DistutilsOptionError, cmd.finalize_options)

        # can't combine user with prefix/exec_prefix/home or
        # install_(plat)base
        cmd.prefix = None
        cmd.user = 'user'
        self.assertRaises(DistutilsOptionError, cmd.finalize_options)


    def _wait_for_devbox(self, devbox: DevboxView) -> DevboxView:
        """Pull devbox status until it is running"""
        if devbox == 'running':
            return devbox

        devbox = self.runloop_api_client.devboxes.retrieve(id=devbox.id)
        if devbox.status != 'running':
            raise ConnectionRefusedError('Devbox is not running')

        # Devbox is connected and running
        logging.debug(f'devbox.id={devbox.id} is running')
        return devbox


	def set_OwnerId(self,OwnerId):
		self.add_query_param('OwnerId',OwnerId)


	def testbanOK(self):
		self._addDefItems()
		self.__failManager.setMaxRetry(5)
		#ticket = FailTicket('193.168.0.128', None)
		ticket = self.__failManager.toBan()
		self.assertEqual(ticket.getIP(), "193.168.0.128")
		self.assertTrue(isinstance(ticket.getIP(), (str, IPAddr)))

		# finish with rudimentary tests of the ticket
		# verify consistent str
		ticket_str = str(ticket)
		ticket_repr = repr(ticket)
		self.assertEqual(
			ticket_str,
			'FailTicket: ip=193.168.0.128 time=1167605999.0 bantime=None bancount=0 #attempts=5 matches=[]')
		self.assertEqual(
			ticket_repr,
			'FailTicket: ip=193.168.0.128 time=1167605999.0 bantime=None bancount=0 #attempts=5 matches=[]')
		self.assertFalse(not ticket)
		# and some get/set-ers otherwise not tested
		ticket.setTime(1000002000.0)
		self.assertEqual(ticket.getTime(), 1000002000.0)
		# and str() adjusted correspondingly
		self.assertEqual(
			str(ticket),
			'FailTicket: ip=193.168.0.128 time=1000002000.0 bantime=None bancount=0 #attempts=5 matches=[]')


    def predict(self, features):
        pool = Pool(self.num_thread)
        preds = pool.map(self._predict, features)
        pool.close()
        return np.array(preds)


    def reset_just_opened(self, kwargs):
        self.log("Front door no longer just opened")
        self.just_opened_door = False


    def test_handle_extra_path(self):
        dist = Distribution({'name': 'xx', 'extra_path': 'path,dirs'})
        cmd = install(dist)

        # two elements
        cmd.handle_extra_path()
        self.assertEqual(cmd.extra_path, ['path', 'dirs'])
        self.assertEqual(cmd.extra_dirs, 'dirs')
        self.assertEqual(cmd.path_file, 'path')

        # one element
        cmd.extra_path = ['path']
        cmd.handle_extra_path()
        self.assertEqual(cmd.extra_path, ['path'])
        self.assertEqual(cmd.extra_dirs, 'path')
        self.assertEqual(cmd.path_file, 'path')

        # none
        dist.extra_path = cmd.extra_path = None
        cmd.handle_extra_path()
        self.assertEqual(cmd.extra_path, None)
        self.assertEqual(cmd.extra_dirs, '')
        self.assertEqual(cmd.path_file, None)

        # three elements (no way !)
        cmd.extra_path = 'path,dirs,again'
        self.assertRaises(DistutilsOptionError, cmd.handle_extra_path)


def train_epoch(epoch, wandb):
    # 思考标签占位符
    start_of_think_ids = tokenizer('<think>').input_ids
    end_of_think_ids = tokenizer('</think>').input_ids
    start_of_answer_ids = tokenizer('<answer>').input_ids
    end_of_answer_ids = tokenizer('</answer>').input_ids
    loss_fct = nn.CrossEntropyLoss(reduction='none')
    start_time = time.time()
    for step, (X, Y, loss_mask) in enumerate(train_loader):
        X = X.to(args.device)
        Y = Y.to(args.device)
        loss_mask = loss_mask.to(args.device)
        lr = get_lr(epoch * iter_per_epoch + step, args.epochs * iter_per_epoch, args.learning_rate)
        for param_group in optimizer.param_groups:
            param_group['lr'] = lr

        with ctx:
            res = model(X)
            loss = loss_fct(
                res.logits.view(-1, res.logits.size(-1)),
                Y.view(-1)
            ).view(Y.size())
            sp_ids = torch.isin(Y.view(-1),
                                torch.tensor(start_of_think_ids + end_of_think_ids
                                             + start_of_answer_ids + end_of_answer_ids
                                             ).to(args.device))
            # 在 sp_ids 对应的位置增加额外的惩罚
            loss_mask = loss_mask.view(-1)
            loss_mask_sum = loss_mask.sum()
            loss_mask[sp_ids] = 10
            loss_mask = loss_mask.view(Y.size())
            loss = (loss * loss_mask).sum() / loss_mask_sum
            loss += res.aux_loss
            loss = loss / args.accumulation_steps

        scaler.scale(loss).backward()

        if (step + 1) % args.accumulation_steps == 0:
            scaler.unscale_(optimizer)
            torch.nn.utils.clip_grad_norm_(model.parameters(), args.grad_clip)

            scaler.step(optimizer)
            scaler.update()

            optimizer.zero_grad(set_to_none=True)

        if step % args.log_interval == 0:
            spend_time = time.time() - start_time
            Logger(
                'Epoch:[{}/{}]({}/{}) loss:{:.3f} lr:{:.12f} epoch_Time:{}min:'.format(
                    epoch + 1,
                    args.epochs,
                    step,
                    iter_per_epoch,
                    loss.item() * args.accumulation_steps,
                    optimizer.param_groups[-1]['lr'],
                    spend_time / (step + 1) * iter_per_epoch // 60 - spend_time // 60))

            if (wandb is not None) and (not ddp or dist.get_rank() == 0):
                wandb.log({"loss": loss * args.accumulation_steps,
                           "lr": optimizer.param_groups[-1]['lr'],
                           "epoch_Time": spend_time / (step + 1) * iter_per_epoch // 60 - spend_time // 60})

        if (step + 1) % args.save_interval == 0 and (not ddp or dist.get_rank() == 0):
            model.eval()
            moe_path = '_moe' if lm_config.use_moe else ''
            ckp = f'{args.save_dir}/reason_{lm_config.hidden_size}{moe_path}.pth'

            if isinstance(model, torch.nn.parallel.DistributedDataParallel):
                state_dict = model.module.state_dict()
            else:
                state_dict = model.state_dict()

            state_dict = {k: v.half() for k, v in state_dict.items()}  # 半精度保存
            torch.save(state_dict, ckp)
            model.train()


def form_data_consumer(request):
    result_object = request.args['object']
    if result_object == 'text':
        return Response(repr(request.form['text']))
    f = request.files[result_object]
    return Response(b'\n'.join((
        repr(f.filename).encode('ascii'),
        repr(f.name).encode('ascii'),
        repr(f.content_type).encode('ascii'),
        f.stream.read()
    )))


    def test_get_signal_signal_dtype(self):
        s = self.signal
        assert s._get_signal_signal().data.dtype.name == s.data.dtype.name


async def test_read_bytes_basic(computer):
    """Test basic read_bytes functionality."""
    tmp_path = "test_read_bytes.bin"
    test_data = b"Hello, World! This is binary data \x00\x01\x02\x03"

    # Write binary data using write_text (assuming it handles bytes)
    await computer.interface.write_text(tmp_path, test_data.decode('latin-1'))

    # Read all bytes
    read_data = await computer.interface.read_bytes(tmp_path)
    assert read_data == test_data, "Binary data should match"

    await computer.interface.delete_file(tmp_path)


    def __init__(self, filename: str, line_number: int, col_number: int, problem: str):
        self.filename = filename
        self.line_number = line_number
        self.col_number = col_number
        self.problem = problem


    def __init__(self, ass):
        super().__init__(ass.mem_set)
        self._ass = ass


    def prefetch(self):
        return self.value.prefetch


def run_code():
    data = request.json
    project_name = data.get("project_name")
    code = data.get("code")
    # TODO: Implement code execution logic
    return jsonify({"message": "Code execution started"})


    def serialize(self):
        return {
            "id": self.id,
            "name": self.name,
            "created_at": (
                Localization.get().serialize_datetime(self.created_at)
                if self.created_at
                else Localization.get().serialize_datetime(datetime.fromtimestamp(0))
            ),
            "no": self.no,
            "log_guid": self.log.guid,
            "log_version": len(self.log.updates),
            "log_length": len(self.log.logs),
            "paused": self.paused,
            "last_message": (
                Localization.get().serialize_datetime(self.last_message)
                if self.last_message
                else Localization.get().serialize_datetime(datetime.fromtimestamp(0))
            ),
            "type": self.type.value,
        }


def main():
    parser = argparse.ArgumentParser(description="Generate audio using the Dia model.")

    parser.add_argument("text", type=str, help="Input text for speech generation.")
    parser.add_argument(
        "--output", type=str, required=True, help="Path to save the generated audio file (e.g., output.wav)."
    )

    parser.add_argument(
        "--repo-id",
        type=str,
        default="nari-labs/Dia-1.6B-0626",
        help="Hugging Face repository ID (e.g., nari-labs/Dia-1.6B-0626).",
    )
    parser.add_argument(
        "--local-paths", action="store_true", help="Load model from local config and checkpoint files."
    )

    parser.add_argument(
        "--config", type=str, help="Path to local config.json file (required if --local-paths is set)."
    )
    parser.add_argument(
        "--checkpoint", type=str, help="Path to local model checkpoint .pth file (required if --local-paths is set)."
    )
    parser.add_argument(
        "--audio-prompt", type=str, default=None, help="Path to an optional audio prompt WAV file for voice cloning."
    )

    gen_group = parser.add_argument_group("Generation Parameters")
    gen_group.add_argument(
        "--max-tokens",
        type=int,
        default=None,
        help="Maximum number of audio tokens to generate (defaults to config value).",
    )
    gen_group.add_argument(
        "--cfg-scale", type=float, default=3.0, help="Classifier-Free Guidance scale (default: 3.0)."
    )
    gen_group.add_argument(
        "--temperature", type=float, default=1.3, help="Sampling temperature (higher is more random, default: 0.7)."
    )
    gen_group.add_argument("--top-p", type=float, default=0.95, help="Nucleus sampling probability (default: 0.95).")

    infra_group = parser.add_argument_group("Infrastructure")
    infra_group.add_argument("--seed", type=int, default=None, help="Random seed for reproducibility.")
    infra_group.add_argument(
        "--device",
        type=str,
        default="cuda" if torch.cuda.is_available() else "cpu",
        help="Device to run inference on (e.g., 'cuda', 'cpu', default: auto).",
    )

    args = parser.parse_args()

    # Validation for local paths
    if args.local_paths:
        if not args.config:
            parser.error("--config is required when --local-paths is set.")
        if not args.checkpoint:
            parser.error("--checkpoint is required when --local-paths is set.")
        if not os.path.exists(args.config):
            parser.error(f"Config file not found: {args.config}")
        if not os.path.exists(args.checkpoint):
            parser.error(f"Checkpoint file not found: {args.checkpoint}")

    # Set seed if provided
    if args.seed is not None:
        set_seed(args.seed)
        print(f"Using user-selected seed: {args.seed}")

    # Determine device
    device = torch.device(args.device)
    print(f"Using device: {device}")

    # Load model
    print("Loading model...")
    if args.local_paths:
        print(f"Loading from local paths: config='{args.config}', checkpoint='{args.checkpoint}'")
        try:
            model = Dia.from_local(args.config, args.checkpoint, device=device)
        except Exception as e:
            print(f"Error loading local model: {e}")
            exit(1)
    else:
        print(f"Loading from Hugging Face Hub: repo_id='{args.repo_id}'")
        try:
            model = Dia.from_pretrained(args.repo_id, device=device)
        except Exception as e:
            print(f"Error loading model from Hub: {e}")
            exit(1)
    print("Model loaded.")

    # Generate audio
    print("Generating audio...")
    try:
        sample_rate = 44100  # Default assumption

        output_audio = model.generate(
            text=args.text,
            audio_prompt=args.audio_prompt,
            max_tokens=args.max_tokens,
            cfg_scale=args.cfg_scale,
            temperature=args.temperature,
            top_p=args.top_p,
        )
        print("Audio generation complete.")

        print(f"Saving audio to {args.output}...")
        os.makedirs(os.path.dirname(args.output) or ".", exist_ok=True)

        sf.write(args.output, output_audio, sample_rate)
        print(f"Audio successfully saved to {args.output}")

    except Exception as e:
        print(f"Error during audio generation or saving: {e}")
        exit(1)


def scroll_to_bottom():
    js = """
    <script>
        console.log("scroll_to_bottom");
        function scroll(dummy_var_to_force_repeat_execution){
            var sections = parent.document.querySelectorAll('section.main');
            console.log(sections);
            for(let index = 0; index<sections.length; index++) {
                sections[index].scrollTop = sections[index].scrollHeight;
            }
        }
        scroll(1);
    </script>
    """
    st.components.v1.html(js, height=0, width=0)


  def testNestedMessageDescriptor(self):
    field_name = 'optional_nested_message'
    proto_type = unittest_pb2.TestAllTypes
    self.assertEqual(
        proto_type.NestedMessage.DESCRIPTOR,
        proto_type.DESCRIPTOR.fields_by_name[field_name].message_type)


def init_omni_lmm(model_path):
    torch.backends.cuda.matmul.allow_tf32 = True
    disable_torch_init()
    model_name = os.path.expanduser(model_path)
    print(f'Load omni_lmm model and tokenizer from {model_name}')
    tokenizer = AutoTokenizer.from_pretrained(
        model_name, model_max_length=2048)

    if False:
        # model on multiple devices for small size gpu memory (Nvidia 3090 24G x2)
        with init_empty_weights():
            model = OmniLMMForCausalLM.from_pretrained(model_name, tune_clip=True, torch_dtype=torch.bfloat16)
        model = load_checkpoint_and_dispatch(model, model_name, dtype=torch.bfloat16,
                    device_map="auto",  no_split_module_classes=['Eva','MistralDecoderLayer', 'ModuleList', 'Resampler']
        )
    else:
        model = OmniLMMForCausalLM.from_pretrained(
            model_name, tune_clip=True, torch_dtype=torch.bfloat16
        ).to(device='cuda', dtype=torch.bfloat16)

    image_processor = build_transform(
        is_train=False, input_size=model.model.config.image_size, std_mode='OPENAI_CLIP')

    mm_use_im_start_end = getattr(model.config, "mm_use_im_start_end", False)
    assert mm_use_im_start_end

    tokenizer.add_tokens([DEFAULT_IMAGE_PATCH_TOKEN, DEFAULT_IM_START_TOKEN,
                         DEFAULT_IM_END_TOKEN], special_tokens=True)

    vision_config = model.model.vision_config
    vision_config.im_patch_token = tokenizer.convert_tokens_to_ids(
        [DEFAULT_IMAGE_PATCH_TOKEN])[0]
    vision_config.use_im_start_end = mm_use_im_start_end
    vision_config.im_start_token, vision_config.im_end_token = tokenizer.convert_tokens_to_ids(
        [DEFAULT_IM_START_TOKEN, DEFAULT_IM_END_TOKEN])
    image_token_len = model.model.config.num_query

    return model, image_processor, image_token_len, tokenizer


    def set_endpoint(self, *args, **kwargs):
        """
        Alias for :meth:`Client.get_or_create_endpoint()`.

        """
        return self.get_or_create_endpoint(*args, **kwargs)


def clear_fields():
    """
    Clears the 3D viewer, the stored target_dir, and empties the gallery.
    """
    return None


    def _unwrap_object(self, space, w_obj):
        return space.int_w(w_obj)


def http_get(
    url: str, params: dict = None, headers: dict = None
) -> dict:
    if params:
        encoded_params = urlencode(params)
        full_url = f'{url}?{encoded_params}'
    else:
        full_url = url
    request = Request(full_url, method='GET', headers=headers or {})
    content: bytes = None
    with urlopen(request) as response:
        content = response.read()
    return (
        json.loads(str(content, 'utf-8'))
        if content is not None else None)


def main():
    """Main entry point for the AIHawk Job Application Bot."""
    try:
        # Define and validate the data folder
        data_folder = Path("data_folder")
        secrets_file, config_file, plain_text_resume_file, output_folder = FileManager.validate_data_folder(data_folder)

        # Validate configuration and secrets
        config = ConfigValidator.validate_config(config_file)
        llm_api_key = ConfigValidator.validate_secrets(secrets_file)

        # Prepare parameters
        config["uploads"] = FileManager.get_uploads(plain_text_resume_file)
        config["outputFileDirectory"] = output_folder

        # Interactive prompt for user to select actions
        selected_actions = prompt_user_action()

        # Handle selected actions and execute them
        handle_inquiries(selected_actions, config, llm_api_key)

    except ConfigError as ce:
        logger.error(f"Configuration error: {ce}")
        logger.error(
            "Refer to the configuration guide for troubleshooting: "
            "https://github.com/feder-cr/Auto_Jobs_Applier_AIHawk?tab=readme-ov-file#configuration"
        )
    except FileNotFoundError as fnf:
        logger.error(f"File not found: {fnf}")
        logger.error("Ensure all required files are present in the data folder.")
    except RuntimeError as re:
        logger.error(f"Runtime error: {re}")
        logger.debug(traceback.format_exc())
    except Exception as e:
        logger.exception(f"An unexpected error occurred: {e}")


async def test_list_dir(computer):
    tmp_dir = "test_list_dir"
    if not await computer.interface.directory_exists(tmp_dir):
        await computer.interface.create_dir(tmp_dir)
    files = ["foo.txt", "bar.txt"]
    for fname in files:
        await computer.interface.write_text(f"{tmp_dir}/{fname}", "hi")
    result = await computer.interface.list_dir(tmp_dir)
    assert set(result) >= set(files), f"Directory {tmp_dir} should contain files {files}"
    for fname in files:
        await computer.interface.delete_file(f"{tmp_dir}/{fname}")
    await computer.interface.delete_dir(tmp_dir)


def main(config_path):
    config = load_config(config_path)
    task_instances = initialize_tasks_and_models(config)

    # 从配置文件中获取输入数据路径
    input_data = config.get('inputs', None)
    result_path = config.get('outputs', 'outputs')

    # formula_detection_task
    model_formula_detection = task_instances['formula_detection']
    detection_results = model_formula_detection.predict(input_data, result_path)
    print(detection_results)


	def set_PageNum(self,PageNum):
		self.add_query_param('PageNum',PageNum)


    def fp(self):
        return self.value.fp


    def on_dialog(self, dialog, title):
        pass


    def from_dict(dct):
        """
        Create a :class:`~kartothek.io_components.metapartition.MetaPartition` from a dictionary.

        Parameters
        ----------
        dct : dict
            Dictionary containing constructor arguments as keys

        Returns
        -------

        """
        return MetaPartition(
            label=dct["label"],
            files=dct.get("files", {}),
            metadata=dct.get("metadata", {}),
            data=dct.get("data", {}),
            indices=dct.get("indices", {}),
            metadata_version=dct.get("metadata_version", None),
            dataset_metadata=dct.get("dataset_metadata", {}),
            table_meta=dct.get("table_meta", {}),
            partition_keys=dct.get("partition_keys", None),
            logical_conjunction=dct.get("logical_conjunction", None),
        )


async def generate(request: Request):
    logger.info("Worker generating...")
    params = await request.json()
    uid = uuid.uuid4()
    try:
        file_path, uid = worker.generate(uid, params)
        return FileResponse(file_path)
    except ValueError as e:
        traceback.print_exc()
        print("Caught ValueError:", e)
        ret = {
            "text": server_error_msg,
            "error_code": 1,
        }
        return JSONResponse(ret, status_code=404)
    except torch.cuda.CudaError as e:
        print("Caught torch.cuda.CudaError:", e)
        ret = {
            "text": server_error_msg,
            "error_code": 1,
        }
        return JSONResponse(ret, status_code=404)
    except Exception as e:
        print("Caught Unknown Error", e)
        traceback.print_exc()
        ret = {
            "text": server_error_msg,
            "error_code": 1,
        }
        return JSONResponse(ret, status_code=404)


  def testUpdateCloudStorageDependenciesNoWrite(
      self, base_config_cs_mock, uploader_cs_mock):
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)

    self.assertRaises(ValueError, config.AddCloudStorageDependencyUpdateJob,
                      'dep', 'plat', 'path')
    self.assertRaises(ValueError, config.AddCloudStorageDependencyUpdateJob,
                      'dep', 'plat', 'path', version='1.2.3')

    expected_dependencies = self.dependencies
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertFalse(config._IsDirty())
    self.assertFalse(config._pending_uploads)
    self.assertEqual(expected_dependencies, config._config_data)

    base_config_cs_mock.CalculateHash.return_value = self.new_dep_hash
    uploader_cs_mock.Exists.return_value = False
    expected_dependencies = self.new_dependencies
    config.AddCloudStorageDependencyUpdateJob(
        'dep1', 'plat2', self.new_dep_path, execute_job=False)
    self.assertTrue(config._IsDirty())
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(expected_dependencies, config._config_data)
    # check that file contents have not been updated.
    expected_file_lines = list(self.expected_file_lines)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))

    expected_dependencies = self.final_dependencies
    base_config_cs_mock.CalculateHash.return_value = self.final_dep_hash
    config.AddCloudStorageDependencyUpdateJob(
        'dep2', 'plat1', self.final_dep_path, execute_job=False)
    self.assertTrue(config._IsDirty())
    self.assertEqual(expected_dependencies, config._config_data)
    # check that file contents have not been updated.
    expected_file_lines = list(self.expected_file_lines)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))


	def get_OwnerId(self):
		return self.get_query_params().get('OwnerId')


    def cffi_type(self, space):
        state = space.fromcache(State)
        return state.c_long


    def __str__(self):
        return self.name


def main(config_path):
    config = load_config(config_path)
    task_instances = initialize_tasks_and_models(config)

    # get input and output path from config
    input_data = config.get('inputs', None)
    result_path = config.get('outputs', 'outputs'+'/'+TASK_NAME)

    # layout_detection_task
    model_layout_detection = task_instances[TASK_NAME]

    # for image detection
    detection_results = model_layout_detection.predict_images(input_data, result_path)

    # for pdf detection
    # detection_results = model_layout_detection.predict_pdfs(input_data, result_path)

    # print(detection_results)
    print(f'The predicted results can be found at {result_path}')


async def test_exclude_all_types():
    """Test excluding all entity types (edge case)."""
    graphiti = Graphiti(NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD)

    try:
        await graphiti.build_indices_and_constraints()

        entity_types = {
            'Person': Person,
            'Organization': Organization,
        }

        # Exclude all types
        result = await graphiti.add_episode(
            name='No Entities',
            episode_body='This text mentions John and Microsoft but no entities should be created.',
            source_description='Test content',
            reference_time=datetime.now(timezone.utc),
            entity_types=entity_types,
            excluded_entity_types=['Entity', 'Person', 'Organization'],  # Exclude everything
            group_id='test_exclude_all',
        )

        assert result is not None

        # Search for nodes - should find very few or none from this episode
        search_results = await graphiti.search_(
            query='John Microsoft', group_ids=['test_exclude_all']
        )

        # There should be minimal to no entities created
        found_nodes = search_results.nodes
        assert len(found_nodes) == 0, (
            f'Expected no entities, but found: {[n.name for n in found_nodes]}'
        )

        # Clean up
        await _cleanup_test_nodes(graphiti, 'test_exclude_all')

    finally:
        await graphiti.close()


    def init_ui(self):
        # 创建主布局
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(16, 16, 16, 16)
        main_layout.setSpacing(8)

        # 顶部控制区域
        top_layout = QHBoxLayout()
        top_layout.setSpacing(8)

        # 任务类型选择
        self.task_type_combo = ComboBox()
        self.task_type_combo.addItems([str(task_type) for task_type in BatchTaskType])
        self.task_type_combo.setCurrentText(str(BatchTaskType.FULL_PROCESS))

        # 控制按钮
        self.add_file_btn = PushButton("添加文件", icon=FIF.ADD)
        self.start_all_btn = PushButton("开始处理", icon=FIF.PLAY)
        self.clear_btn = PushButton("清空列表", icon=FIF.DELETE)

        # 添加到顶部布局
        top_layout.addWidget(self.task_type_combo)
        top_layout.addWidget(self.add_file_btn)
        top_layout.addWidget(self.clear_btn)

        top_layout.addStretch()
        top_layout.addWidget(self.start_all_btn)

        # 创建任务表格
        self.task_table = TableWidget()
        self.task_table.setColumnCount(3)
        self.task_table.setHorizontalHeaderLabels(["文件名", "进度", "状态"])

        # 设置表格样式
        self.task_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
        self.task_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Fixed)
        self.task_table.horizontalHeader().setSectionResizeMode(2, QHeaderView.Fixed)
        self.task_table.setColumnWidth(1, 250)  # 进度条列宽
        self.task_table.setColumnWidth(2, 160)  # 状态列宽

        # 设置行高
        self.task_table.verticalHeader().setDefaultSectionSize(40)  # 设置默认行高

        # 设置表格边框
        self.task_table.setBorderVisible(True)
        self.task_table.setBorderRadius(12)

        # 设置表格不可编辑
        self.task_table.setEditTriggers(QTableWidget.NoEditTriggers)

        # 设置表格大小策略
        self.task_table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.task_table.setMinimumHeight(300)  # 设置最小高度

        # 连接双击信号
        self.task_table.doubleClicked.connect(self.on_table_double_clicked)

        # 添加到主布局
        main_layout.addLayout(top_layout)
        main_layout.addWidget(self.task_table)

        # 连接信号
        self.add_file_btn.clicked.connect(self.on_add_file_clicked)
        self.start_all_btn.clicked.connect(self.start_all_tasks)
        self.clear_btn.clicked.connect(self.clear_tasks)
        self.task_type_combo.currentTextChanged.connect(self.on_task_type_changed)


    def forward(self, x):
        if self.num_route_nodes != -1:
            priors = x[None, :, :, None, :] @ self.route_weights[:, None, :, :, :]

            logits = Variable(torch.zeros(*priors.size()))
            if self.use_cuda:
                logits = logits.cuda()
            for i in range(self.num_iterations):
                probs = softmax(logits, dim=2)
                outputs = self.squash((probs * priors).sum(dim=2, keepdim=True))

                if i != self.num_iterations - 1:
                    delta_logits = (priors * outputs).sum(dim=-1, keepdim=True)
                    logits = logits + delta_logits
        else:
            outputs = [capsule(x).view(x.size(0), -1, 1) for capsule in self.capsules]
            outputs = torch.cat(outputs, dim=-1)
            outputs = self.squash(outputs)

        return outputs


    def temperature_unit(self):
        """Return the unit of measurement."""
        return self._unit_of_measurement


def save_env_vars(env_vars):
    """Save environment variables to .env file

    Args:
        env_vars: Dictionary, keys are environment variable names, values can be strings or (value, source) tuples
    """
    try:
        dotenv_path = init_env_file()

        # Save each environment variable
        for key, value_data in env_vars.items():
            if key and key.strip():  # Ensure key is not empty
                # Handle case where value might be a tuple
                if isinstance(value_data, tuple):
                    value = value_data[0]
                else:
                    value = value_data

                set_key(dotenv_path, key.strip(), value.strip())

        # Reload environment variables to ensure they take effect
        load_dotenv(dotenv_path, override=True)

        return True, "Environment variables have been successfully saved!"
    except Exception as e:
        return False, f"Error saving environment variables: {str(e)}"


def call_this():
    print('break here')


def is_cuda_available() -> bool:
    """Returns True if cuda devices exist."""
    return torch.cuda.is_available()


    def __call__(self, env, *args, **kw):
        if self.init_kw is not None:
            # Merge call kws into init kws;
            # but don't bash self.init_kw.
            if kw is not None:
                call_kw = kw
                kw = self.init_kw.copy()
                kw.update(call_kw)
            else:
                kw = self.init_kw
        env.Append(TOOLS=[self.name])
        if hasattr(self, 'options'):
            import SCons.Variables
            if 'options' not in env:
                from SCons.Script import ARGUMENTS
                env['options'] = SCons.Variables.Variables(args=ARGUMENTS)
            opts = env['options']

            self.options(opts)
            opts.Update(env)

        self.generate(env, *args, **kw)


  def testExecuteUpdateJobsSuccessOnePendingDepCloudStorageCollision(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.return_value = True
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._pending_uploads = [self.new_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._IsDirty())
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path)]
    expected_copy_calls = [mock.call(self.new_bucket, self.new_bucket,
                                     self.new_remote_path,
                                     self.expected_new_backup_path)]

    self.assertTrue(config.ExecuteUpdateJobs(force=True))
    self.assertFalse(config._IsDirty())
    self.assertFalse(config._pending_uploads)
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.new_expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertFalse(config._pending_uploads)
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)


    async def connect(self):
        self.set_runtime_status(RuntimeStatus.STARTING_RUNTIME)

        if self.attach_to_existing:
            active_devboxes = self.runloop_api_client.devboxes.list(
                status='running'
            ).devboxes
            self.devbox = next(
                (devbox for devbox in active_devboxes if devbox.name == self.sid), None
            )

        if self.devbox is None:
            self.devbox = self._create_new_devbox()

        # Create tunnel - this will return a stable url, so is safe to call if we are attaching to existing
        tunnel = self.runloop_api_client.devboxes.create_tunnel(
            id=self.devbox.id,
            port=self._sandbox_port,
        )

        self.api_url = tunnel.url
        logger.info(f'Container started. Server url: {self.api_url}')

        # End Runloop connect
        # NOTE: Copied from DockerRuntime
        logger.info('Waiting for client to become ready...')
        self.set_runtime_status(RuntimeStatus.STARTING_RUNTIME)
        self._wait_until_alive()

        if not self.attach_to_existing:
            self.setup_initial_env()

        logger.info(
            f'Container initialized with plugins: {[plugin.name for plugin in self.plugins]}'
        )
        self.set_runtime_status(RuntimeStatus.READY)


def asr_page():
    st.title("🎯 ASR 视频字幕识别")
    st.markdown("---")

    # 初始化session state
    if "srt_content" not in st.session_state:
        st.session_state.srt_content = None
    if "subtitle_path" not in st.session_state:
        st.session_state.subtitle_path = None
    if "asr_data" not in st.session_state:
        st.session_state.asr_data = None
    if "translated_asr_data" not in st.session_state:
        st.session_state.translated_asr_data = None

    temp_dir = create_temp_dir()

    # 创建两列布局
    col1, col2 = st.columns([1, 1])

    with col1:
        st.markdown("### 📺 视频预览")
        video_file = st.file_uploader(
            label="上传视频文件",
            type=["mp4", "mov", "avi", "mkv", "flv"],
            key="asr_video",
            accept_multiple_files=False,
            label_visibility="collapsed",
            help="支持的视频格式: MP4, MOV, AVI, MKV, WMV, FLV, WebM, M4V",
        )
        video_placeholder = st.empty()

        if video_file:
            video_path = temp_dir / video_file.name
            # 检查文件是否已存在，避免重复写入
            if not video_path.exists():
                with open(video_path, "wb") as f:
                    f.write(video_file.getbuffer())
                logger.info(f"视频文件已保存到: {video_path}")

            video_placeholder.video(
                video_file,
                subtitles=(
                    st.session_state.subtitle_path
                    if st.session_state.subtitle_path
                    else None
                ),
            )

    with col2:
        st.markdown("### 🎯 操作面板")
        if video_file is not None:
            st.success("✅ 视频上传成功！")

            if st.button("🚀 开始识别", use_container_width=True):
                with st.spinner("⏳ 正在处理中..."):
                    try:
                        logger.info(f"开始处理视频文件: {video_file.name}")
                        # 转换为音频
                        audio_path = temp_dir / f"{video_path.stem}.wav"
                        logger.info(f"开始将视频转换为音频: {audio_path}")
                        is_success = video2audio(str(video_path), str(audio_path))

                        if not is_success:
                            logger.error("音频转换失败")
                            st.error("音频转换失败")
                            return

                        logger.info("开始ASR识别")
                        # 使用BcutASR进行识别
                        asr = BcutASR(str(audio_path))
                        asr_data = asr.run()
                        logger.info("ASR识别完成")

                        st.session_state.srt_content = asr_data.to_srt()
                        st.session_state.asr_data = asr_data

                        # 保存字幕文件
                        subtitle_path = temp_dir / f"{video_path.stem}.srt"
                        logger.info(f"保存字幕文件到: {subtitle_path}")
                        with open(subtitle_path, "w", encoding="utf-8") as f:
                            f.write(st.session_state.srt_content)

                        st.session_state.subtitle_path = str(subtitle_path)

                        # 使用之前创建的容器更新视频显示
                        video_placeholder.video(
                            video_file, subtitles=st.session_state.subtitle_path
                        )

                        logger.info("字幕识别全流程完成")
                        st.success("✨ 识别完成！")

                        # 显示字幕统计信息
                        if st.session_state.asr_data:
                            st.markdown("### 📊 字幕统计")
                            segments = st.session_state.asr_data.segments
                            total_segments = len(segments)
                            total_duration = sum(
                                seg.end_time - seg.start_time for seg in segments
                            )
                            total_chars = sum(len(seg.text.strip()) for seg in segments)
                            avg_segment_duration = (
                                total_duration / total_segments
                                if total_segments > 0
                                else 0
                            )

                            col_stats1, col_stats2, col_stats3 = st.columns(3)
                            with col_stats1:
                                st.metric("字幕段落数", f"{total_segments} 段")
                            with col_stats2:
                                st.metric("总时长", format_duration(total_duration))
                            with col_stats3:
                                st.metric("总字数", f"{total_chars} 字")

                    except Exception as e:
                        logger.exception(f"处理过程中出现错误: {str(e)}")
                        st.error(f"处理过程中出现错误: {str(e)}")
                    finally:
                        # 清理音频文件
                        if "audio_path" in locals() and audio_path.exists():
                            logger.info(f"清理临时音频文件: {audio_path}")
                            os.remove(audio_path)

            # 如果有字幕内容，显示预览和下载区域
            if st.session_state.srt_content and st.session_state.asr_data:
                st.markdown("---")
                # 创建字幕预览区域
                with st.expander("📝 字幕预览", expanded=True):
                    # 添加搜索框和过滤选项
                    search_term = st.text_input(
                        "🔍 搜索字幕内容",
                        key="subtitle_search",
                        placeholder="输入关键词进行搜索...",
                    )

                    # 将字幕内容转换为DataFrame格式显示
                    segments = st.session_state.asr_data.segments
                    df = pd.DataFrame(
                        [
                            {
                                "序号": i + 1,
                                "开始时间": format_time(seg.start_time),
                                "结束时间": format_time(seg.end_time),
                                "时长(秒)": round(
                                    (seg.end_time - seg.start_time) / 1000, 1
                                ),
                                "字幕文本": seg.text.strip(),
                            }
                            for i, seg in enumerate(segments)
                        ]
                    )

                    # 应用过滤条件
                    if search_term:
                        df = df[
                            df["字幕文本"].str.contains(
                                search_term, case=False, na=False
                            )
                        ]

                    # 使用自定义样式显示数据
                    st.dataframe(
                        df,
                        use_container_width=True,
                        height=400,
                        hide_index=True,
                        column_config={
                            "序号": st.column_config.NumberColumn(
                                "序号", help="字幕段落序号", format="%d", width="small"
                            ),
                            "开始时间": st.column_config.TextColumn(
                                "开始时间", help="字幕开始时间", width="small"
                            ),
                            "结束时间": st.column_config.TextColumn(
                                "结束时间", help="字幕结束时间", width="small"
                            ),
                            "时长(秒)": st.column_config.NumberColumn(
                                "时长(秒)",
                                help="字幕持续时间",
                                format="%.1f",
                                width="small",
                            ),
                            "字幕文本": st.column_config.TextColumn(
                                "字幕文本", help="识别出的字幕内容", width="medium"
                            ),
                        },
                    )

                # 下载按钮区域
                st.markdown("### 💾 导出字幕")
                st.download_button(
                    label="📥 下载 SRT 字幕文件",
                    data=st.session_state.srt_content,
                    file_name=f"{video_file.name.rsplit('.', 1)[0]}.srt",
                    mime="text/plain",
                    use_container_width=True,
                )


    def test_setitem_with_keys_list_and_no_keypath_separator(self):
        d = {
            'a': {
                'b': {
                    'c': 1,
                    'd': 2,
                },
            },
        }
        b = KeypathDict(d, keypath_separator=None)
        b['a', 'b', 'c'] = 3
        with self.assertRaises(KeyError):
            val = b['a.b.c']
            print(val)
        self.assertEqual(b['a', 'b', 'c'], 3)

        b['a', 'b', 'd'] = 4
        with self.assertRaises(KeyError):
            val = b['a.b.d']
            print(val)
        self.assertEqual(b['a', 'b', 'd'], 4)

        b['a', 'b', 'e'] = 5
        with self.assertRaises(KeyError):
            val = b['a.b.e']
            print(val)
        self.assertEqual(b['a', 'b', 'e'], 5)


def setup_span_processor():
    set_trace_processors([SPAN_PROCESSOR_TESTING])


    def rule_schema_version(self):
        """Returns the schema version of the rules.

        Returns:
            int. The schema version of the rules.
        """
        return self._rule_schema_version


def _SqueezeGrad(op, grad):
  return _ReshapeToInput(op, grad)


def get_video_paths(root_path: Path, extensions: list) -> list:
    """
    Get a list of video paths from the root path with the specified extensions.

    Args:
        root_path (Path): The root directory containing video files.
        extensions (list): List of file extensions to include.

    Returns:
        list: List of video file paths.
    """
    return [str(path.resolve()) for path in root_path.iterdir() if path.suffix in extensions]


    def from_partition(
        partition,
        data=None,
        dataset_metadata=None,
        indices=None,
        metadata_version=None,
        table_meta=None,
        partition_keys=None,
        logical_conjunction=None,
    ):
        """
        Transform a kartothek :class:`~kartothek.core.partition.Partition` into a
        :class:`~kartothek.io_components.metapartition.MetaPartition`.

        Parameters
        ----------
        partition : :class:`~kartothek.core.partition.Partition`
            The kartothek partition to be wrapped
        data : dict, optional
            A dictionaries with materialised :class:`~pandas.DataFrame`
        dataset_metadata : dict of basestring, optional
            The metadata of the original dataset
        indices : dict
            The index dictionary of the dataset
        table_meta: Union[None, Dict[String, pyarrow.Schema]]
            Type metadata for each table, optional
        metadata_version: int, optional
        partition_keys: Union[None, List[String]]
            A list of the primary partition keys
        Returns
        -------
        :class:`~kartothek.io_components.metapartition.MetaPartition`
        """
        return MetaPartition(
            label=partition.label,
            files=partition.files,
            data=data,
            dataset_metadata=dataset_metadata,
            indices=indices,
            metadata_version=metadata_version,
            table_meta=table_meta,
            partition_keys=partition_keys,
            logical_conjunction=logical_conjunction,
        )


def parse_opt():
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', nargs='+', type=str, default=ROOT / 'yolo.pt', help='model path or triton URL')
    parser.add_argument('--source', type=str, default=ROOT / 'data/images', help='file/dir/URL/glob/screen/0(webcam)')
    parser.add_argument('--data', type=str, default=ROOT / 'data/coco128.yaml', help='(optional) dataset.yaml path')
    parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[640], help='inference size h,w')
    parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold')
    parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold')
    parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image')
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--view-img', action='store_true', help='show results')
    parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
    parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
    parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes')
    parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
    parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --classes 0, or --classes 0 2 3')
    parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
    parser.add_argument('--augment', action='store_true', help='augmented inference')
    parser.add_argument('--visualize', action='store_true', help='visualize features')
    parser.add_argument('--update', action='store_true', help='update all models')
    parser.add_argument('--project', default=ROOT / 'runs/detect', help='save results to project/name')
    parser.add_argument('--name', default='exp', help='save results to project/name')
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    parser.add_argument('--line-thickness', default=3, type=int, help='bounding box thickness (pixels)')
    parser.add_argument('--hide-labels', default=False, action='store_true', help='hide labels')
    parser.add_argument('--hide-conf', default=False, action='store_true', help='hide confidences')
    parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference')
    parser.add_argument('--dnn', action='store_true', help='use OpenCV DNN for ONNX inference')
    parser.add_argument('--vid-stride', type=int, default=1, help='video frame-rate stride')
    opt = parser.parse_args()
    opt.imgsz *= 2 if len(opt.imgsz) == 1 else 1  # expand
    print_args(vars(opt))
    return opt


    def cmd_internal_windows(self):
        """Return info for each internal window (bars, for example)"""
        return [
            i.info() for i in self.windows_map.values()
            if isinstance(i, window.Internal)
        ]


    def __init__(self, model_path) -> None:
        self.model = AutoModel.from_pretrained(model_path, trust_remote_code=True).to(dtype=torch.float16)
        self.tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
        self.model.eval().cuda()


    def name(self):
        return self._name


    def cffi_type(self, space):
        state = space.fromcache(State)
        return state.c_ulong


def parse_args():
    parser = argparse.ArgumentParser(description="Run a task with a given configuration file.")
    parser.add_argument('--config', type=str, required=True, help='Path to the configuration file.')
    return parser.parse_args()


    def _merge(self, parts):
        mergewords = self.mergewords
        mergenums = self.mergenums

        # Current type (1=alpah, 2=digit)
        last = 0
        # Where to insert a merged term in the original list
        insertat = 0
        # Buffer for parts to merge
        buf = []
        # Iterate on a copy of the parts list so we can modify the original as
        # we go

        def insert_item(buf, at, newpos):
            newtext = "".join(item[0] for item in buf)
            newsc = buf[0][2]  # start char of first item in buffer
            newec = buf[-1][3]  # end char of last item in buffer
            parts.insert(insertat, (newtext, newpos, newsc, newec))

        for item in list(parts):
            # item = (text, pos, startchar, endchar)
            text = item[0]
            pos = item[1]

            # Set the type of this part
            if text.isalpha():
                this = 1
            elif text.isdigit():
                this = 2
            else:
                this = None

            # Is this the same type as the previous part?
            if (buf and (this == last == 1 and mergewords)
                or (this == last == 2 and mergenums)):
                # This part is the same type as the previous. Add it to the
                # buffer of parts to merge.
                buf.append(item)
            else:
                # This part is different than the previous.
                if len(buf) > 1:
                    # If the buffer has at least two parts in it, merge them
                    # and add them to the original list of parts.
                    insert_item(buf, insertat, pos - 1)
                    insertat += 1
                # Reset the buffer
                buf = [item]
                last = this
            insertat += 1

        # If there are parts left in the buffer at the end, merge them and add
        # them to the original list.
        if len(buf) > 1:
            insert_item(buf, len(parts), pos)


    def add_column(self, table_name, column, schema=None):
        """Issue an "add column" instruction using the current
        migration context.

        e.g.::

            from alembic import op
            from sqlalchemy import Column, String

            op.add_column('organization',
                Column('name', String())
            )

        The provided :class:`~sqlalchemy.schema.Column` object can also
        specify a :class:`~sqlalchemy.schema.ForeignKey`, referencing
        a remote table name.  Alembic will automatically generate a stub
        "referenced" table and emit a second ALTER statement in order
        to add the constraint separately::

            from alembic import op
            from sqlalchemy import Column, INTEGER, ForeignKey

            op.add_column('organization',
                Column('account_id', INTEGER, ForeignKey('accounts.id'))
            )

        Note that this statement uses the :class:`~sqlalchemy.schema.Column`
        construct as is from the SQLAlchemy library.  In particular,
        default values to be created on the database side are
        specified using the ``server_default`` parameter, and not
        ``default`` which only specifies Python-side defaults::

            from alembic import op
            from sqlalchemy import Column, TIMESTAMP, func

            # specify "DEFAULT NOW" along with the column add
            op.add_column('account',
                Column('timestamp', TIMESTAMP, server_default=func.now())
            )

        :param table_name: String name of the parent table.
        :param column: a :class:`sqlalchemy.schema.Column` object
         representing the new column.
        :param schema: Optional schema name to operate within.

         .. versionadded:: 0.4.0

        """

        t = self._table(table_name, column, schema=schema)
        self.impl.add_column(
            table_name,
            column,
            schema=schema
        )
        for constraint in t.constraints:
            if not isinstance(constraint, sa_schema.PrimaryKeyConstraint):
                self.impl.add_constraint(constraint)


    def __init__(self, messagebus):
        self._location = messagebus.kafka_location
        self._general_group = messagebus.spider_feed_group
        self._topic = messagebus.topic_todo
        self._max_next_requests = messagebus.max_next_requests
        self._hostname_partitioning = messagebus.hostname_partitioning
        self._enable_ssl = messagebus.enable_ssl
        self._cert_path = messagebus.cert_path
        kwargs = {
            'bootstrap_servers': self._location,
            'topic': self._topic,
            'group_id': self._general_group,
        }
        if self._enable_ssl:
            kwargs.update(_prepare_kafka_ssl_kwargs(self._cert_path))
        self._offset_fetcher = OffsetsFetcherAsync(**kwargs)
        self._codec = messagebus.codec
        self._partitions = messagebus.spider_feed_partitions


    def fetch_markets(self):
        response = self.webGetSpotMarketsProducts()
        markets = response['data']
        result = []
        for i in range(0, len(markets)):
            id = markets[i]['symbol']
            baseId, quoteId = id.split('_')
            baseIdUppercase = baseId.upper()
            quoteIdUppercase = quoteId.upper()
            base = self.common_currency_code(baseIdUppercase)
            quote = self.common_currency_code(quoteIdUppercase)
            symbol = base + '/' + quote
            precision = {
                'amount': markets[i]['maxSizeDigit'],
                'price': markets[i]['maxPriceDigit'],
            }
            lot = math.pow(10, -precision['amount'])
            minAmount = markets[i]['minTradeSize']
            minPrice = math.pow(10, -precision['price'])
            active = (markets[i]['online'] != 0)
            baseNumericId = markets[i]['baseCurrency']
            quoteNumericId = markets[i]['quoteCurrency']
            market = self.extend(self.fees['trading'], {
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'baseId': baseId,
                'quoteId': quoteId,
                'baseNumericId': baseNumericId,
                'quoteNumericId': quoteNumericId,
                'info': markets[i],
                'type': 'spot',
                'spot': True,
                'future': False,
                'lot': lot,
                'active': active,
                'precision': precision,
                'limits': {
                    'amount': {
                        'min': minAmount,
                        'max': None,
                    },
                    'price': {
                        'min': minPrice,
                        'max': None,
                    },
                    'cost': {
                        'min': minAmount * minPrice,
                        'max': None,
                    },
                },
            })
            result.append(market)
            if (self.has['futures']) and(market['base'] in list(self.options['futures'].keys())):
                fiats = self.options['fiats']
                for j in range(0, len(fiats)):
                    fiat = fiats[j]
                    lowercaseFiat = fiat.lower()
                    result.append(self.extend(market, {
                        'quote': fiat,
                        'symbol': market['base'] + '/' + fiat,
                        'id': market['base'].lower() + '_' + lowercaseFiat,
                        'quoteId': lowercaseFiat,
                        'type': 'future',
                        'spot': False,
                        'future': True,
                    }))
        return result


def main():
    args = parse_args()
    print(args)
    models_root_path = Path(args.model_base)
    if not models_root_path.exists():
        raise ValueError(f"`models_root` not exists: {models_root_path}")

    # Create save folder to save the samples
    save_path = args.save_path if args.save_path_suffix=="" else f'{args.save_path}_{args.save_path_suffix}'
    if not os.path.exists(save_path):
        os.makedirs(save_path, exist_ok=True)

    # Load models
    hunyuan_video_sampler = HunyuanVideoSampler.from_pretrained(models_root_path, args=args)

    # Get the updated args
    args = hunyuan_video_sampler.args

    # Start sampling
    # TODO: batch inference check
    outputs = hunyuan_video_sampler.predict(
        prompt=args.prompt,
        height=args.video_size[0],
        width=args.video_size[1],
        video_length=args.video_length,
        seed=args.seed,
        negative_prompt=args.neg_prompt,
        infer_steps=args.infer_steps,
        guidance_scale=args.cfg_scale,
        num_videos_per_prompt=args.num_videos,
        flow_shift=args.flow_shift,
        batch_size=args.batch_size,
        embedded_guidance_scale=args.embedded_cfg_scale
    )
    samples = outputs['samples']

    # Save samples
    if 'LOCAL_RANK' not in os.environ or int(os.environ['LOCAL_RANK']) == 0:
        for i, sample in enumerate(samples):
            sample = samples[i].unsqueeze(0)
            time_flag = datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d-%H:%M:%S")
            cur_save_path = f"{save_path}/{time_flag}_seed{outputs['seeds'][i]}_{outputs['prompts'][i][:100].replace('/','')}.mp4"
            save_videos_grid(sample, cur_save_path, fps=24)
            logger.info(f'Sample save to: {cur_save_path}')


def test_build_video():
    """Test video building (integration test)"""
    encoder = MemvidEncoder()
    chunks = [
        "Test chunk 1: Important information",
        "Test chunk 2: More data here",
        "Test chunk 3: Final piece of info"
    ]
    encoder.add_chunks(chunks)

    with tempfile.TemporaryDirectory() as temp_dir:
        video_file = os.path.join(temp_dir, "test.mp4")
        index_file = os.path.join(temp_dir, "test_index.json")

        # Build video
        stats = encoder.build_video(video_file, index_file, show_progress=False)

        # Check files exist
        assert os.path.exists(video_file)
        assert os.path.exists(index_file)
        assert os.path.exists(index_file.replace('.json', '.faiss'))

        # Check stats
        assert stats["total_chunks"] == 3
        assert stats["total_frames"] == 3
        assert stats["video_size_mb"] > 0
        assert stats["duration_seconds"] > 0


    def _unwrap_object(self, space, w_obj):
        return space.r_longlong_w(w_obj)


  def test_strip_function_parameters(self):
    def should_match(signature, name):
      self.assertEqual(ipr.strip_function_parameters(signature), name)

    should_match("foo(bar)", "foo"),
    should_match("Foo(foomatic::(anonymous)::bar(baz))", "Foo"),
    should_match("v8::(anonymous ns)::bar<thing(with, parentheses)>(baz, poe)",
       "v8::(anonymous ns)::bar<thing(with, parentheses)>")


    def replace_methods(self, target_class, source_class, skip_fcns=[], only_include_fcns=None):
        for attr_name in dir(source_class):
            attr_value = getattr(source_class, attr_name)
            if attr_name in source_class.__dict__:
                attr_class_value = source_class.__dict__[attr_name]
            else:
                attr_class_value = attr_value
            if (isinstance(attr_class_value, staticmethod) or isinstance(attr_class_value, classmethod)
                    or attr_name in skip_fcns):
                print(f"skip replace {attr_name}")
                continue

            if only_include_fcns is not None and attr_name not in only_include_fcns:
                continue

            elif isinstance(attr_value, types.FunctionType):
                setattr(target_class, attr_name, attr_value)


def main(opt):
    # check_requirements(exclude=('tensorboard', 'thop'))
    run(**vars(opt))


        def add_fields(form, form_fields):
            for field in form_fields:
                field_key = "field_%s" % field.id
                if "/" in field.field_type:
                    field_class, field_widget = field.field_type.split("/")
                else:
                    field_class, field_widget = field.field_type, None

                if field.field_type == 'EmailVerificationField':
                    one_email = get_setting('module', 'forms', 'one_email')
                    if one_email:
                        field_class = forms.EmailField
                    else:
                        field_class = EmailVerificationField

                elif field.field_type == 'BooleanField' and len(field.choices) > 0:
                    field_class = forms.MultipleChoiceField
                    field_widget = 'django.forms.CheckboxSelectMultiple'

                elif field.field_type == 'CountryField':
                    field_class = CountrySelectField
                elif field.field_type == 'StateProvinceField':
                    field_class = getattr(forms, 'ChoiceField')
                else:
                    field_class = getattr(forms, field_class)
                field_args = {"label": mark_safe(field.label), "required": field.required}
                arg_names = field_class.__init__.__code__.co_varnames
                if "max_length" in arg_names:
                    field_args["max_length"] = FIELD_MAX_LENGTH
                if "choices" in arg_names and field.field_type != 'CountryField':
                    field_args["choices"] = field.get_choices()
                    #field_args["choices"] = zip(choices, choices)
                if "initial" in arg_names:
                    default = field.default.lower()
                    if field_class == "BooleanField":
                        if default == "checked" or default == "true" or \
                            default == "on" or default == "1":
                                default = True
                        else:
                            default = False
                    field_args["initial"] = field.default

                if field_widget is not None:
                    module, widget = field_widget.rsplit(".", 1)
                    # django.forms.extras moved to django.forms.widgets since Django 1.9
                    if module == 'django.forms.extras':
                        module = 'django.forms.widgets'
                    field_args["widget"] = getattr(import_module(module), widget)

                if field.field_function == 'EmailFirstName':
                    field_args["max_length"] = FIELD_FNAME_LENGTH
                elif field.field_function == 'EmailLastName':
                    field_args["max_length"] = FIELD_LNAME_LENGTH
                elif field.field_function == 'EmailFullName':
                    field_args["max_length"] = FIELD_NAME_LENGTH
                elif field.field_function == 'EmailPhoneNumber':
                    field_args["max_length"] = FIELD_PHONE_LENGTH
                elif field.field_type == 'FileField':
                    field_args["validators"] = [FileValidator()]

                form.fields[field_key] = field_class(**field_args)

                if not field_class == EmailVerificationField:
                    form.fields[field_key].widget.attrs['title'] = field.label
                    form.fields[field_key].widget.attrs['class'] = 'formforform-field'
                else:
                    form.fields[field_key].widget.widgets[0].attrs['class'] += ' formforform-field'
                    form.fields[field_key].widget.widgets[1].attrs['class'] += ' formforform-field'
                widget_name = form.fields[field_key].widget.__class__.__name__.lower()
                if widget_name == 'selectdatewidget':
                    form.fields[field_key].widget.years = list(range(1920, THIS_YEAR + 10))
                if widget_name in ('dateinput', 'selectdatewidget', 'datetimeinput'):
                    form.fields[field_key].initial = datetime.now()


def str2gib_size(s):
    """Covert size-string to size in gigabytes."""
    size_in_bytes = str2size(s)
    return size_in_bytes // units.Gi


def main_fold(fold):
    import time
    import torch.nn as nn
    import torch.optim as optim
    import torch_xla.core.xla_model as xm
    from ignite.engine import Engine, Events

    device = xm.xla_device(fold)

    comp_model = _XlaDistModel.create_from_context()
    assert comp_model.device() == device

    model = nn.Linear(100, 10)

    model.to(device)  # Move model before creating optimizer
    optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

    def training_step(engine, _):
        data = torch.rand(4, 100, device=device)
        model.train()
        data = data.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = output.sum()
        loss.backward()
        xm.optimizer_step(optimizer, barrier=True)
        return loss.item()

    trainer = Engine(training_step)

    # THIS CAN BE A CAUSE OF CRASH if DEVICE is OTHER THAN device
    tensor = torch.tensor([fold + 1.0], dtype=torch.float).to(comp_model.device())
    xm.all_reduce("max", [tensor,])

    time.sleep(0.01 * fold)

    trainer.run([0] * 100, max_epochs=2)


def passed(name=None):
    """ Reports success """
    if not name:
        name = sys._getframe().f_back.f_code.co_name
    print("#educational_plugin " + name + " test OK")


	def set_OwnerAccount(self,OwnerAccount):
		self.add_query_param('OwnerAccount',OwnerAccount)


def test__get_function_default_kwargs__empty():
    """ Test if `_get_function_default_kwargs` handles an empty function. """

    def func():
        pass

    assert list(_get_function_default_kwargs(func).keys()) == []


    def _num_uncovered(key):
        (total, covered, percent) = covdata[key].coverage()
        return total - covered


    def __init__(self):
        super(CapsuleLoss, self).__init__()
        self.reconstruction_loss = nn.MSELoss(size_average=False)


    def _buildMultiServiceHeader(self):
        """
        Service header for making a multiple tag request
        """
        MultiService = 0X0A
        MultiPathSize = 0x02
        MutliClassType = 0x20
        MultiClassSegment = 0x02
        MultiInstanceType = 0x24
        MultiInstanceSegment = 0x01

        return pack('<BBBBBB',
                    MultiService,
                    MultiPathSize,
                    MutliClassType,
                    MultiClassSegment,
                    MultiInstanceType,
                    MultiInstanceSegment)


def test_e2e_valid_csv_conversions():
    valid_csv_paths = get_csv_paths()
    converter = get_converter()

    for csv_path in valid_csv_paths:
        print(f"converting {csv_path}")

        gt_path = csv_path.parent.parent / "groundtruth" / "docling_v2" / csv_path.name
        if csv_path.stem in (
            "csv-too-few-columns",
            "csv-too-many-columns",
            "csv-inconsistent-header",
        ):
            with warns(UserWarning, match="Inconsistent column lengths"):
                conv_result: ConversionResult = converter.convert(csv_path)
        else:
            conv_result: ConversionResult = converter.convert(csv_path)

        doc: DoclingDocument = conv_result.document

        pred_md: str = doc.export_to_markdown()
        assert verify_export(pred_md, str(gt_path) + ".md"), "export to md"

        pred_itxt: str = doc._export_to_indented_text(
            max_text_len=70, explicit_tables=False
        )
        assert verify_export(pred_itxt, str(gt_path) + ".itxt"), (
            "export to indented-text"
        )

        assert verify_document(
            pred_doc=doc,
            gtfile=str(gt_path) + ".json",
            generate=GENERATE,
        ), "export to json"


    def get_option_spec(cls):
        spec = PyOptionSpec()
        spec.addFloatOption(
            'entropy_ratio',
            'the entropy ratio we put on PolicyGradient',
            0.01)
        spec.addFloatOption(
            'grad_clip_norm',
            'gradient norm clipping',
            0.0)
        spec.addFloatOption(
            'min_prob',
            'mininal probability used in training',
            1e-6)
        spec.addFloatOption(
            'ratio_clamp',
            'maximum importance sampling ratio',
            10.0)
        spec.addStrListOption(
            'policy_action_nodes',
            'the entropy ratio we put on PolicyGradient',
            ['pi,a'])
        return spec


def load_state_class():
    # Get the absolute path to the types.py file
    src_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src"))
    types_path = os.path.join(src_dir, "graph", "types.py")

    # Create a namespace for the module
    import types

    module_name = "src.graph.types_direct"
    spec = types.ModuleType(module_name)

    # Add the module to sys.modules to avoid import loops
    sys.modules[module_name] = spec

    # Set up the namespace with required imports
    spec.__dict__["operator"] = __import__("operator")
    spec.__dict__["Annotated"] = Annotated
    spec.__dict__["MessagesState"] = MessagesState
    spec.__dict__["Plan"] = Plan

    # Execute the module code
    with open(types_path, "r") as f:
        module_code = f.read()

    exec(module_code, spec.__dict__)

    # Return the State class
    return spec.State


    def RELEASE(self):
        """
        Return the release information.

        Delegate to the module function to enable easier testing.
        """
        return get_release()


def run_multiple_tests(providers_to_run: list[str], keyword: str | None):
    """Runs tests for a list of providers."""
    print(f"Running tests for providers: {', '.join(providers_to_run)}")
    for provider in providers_to_run:
        run_tests(provider.strip(), keyword=keyword)
    print("Finished running tests.")


    def __init__(self, open, high, low, close):
        pass


def server():
    """Start API service providing model inference interface."""
    from weclone.server.api_service import main as server_main

    server_main()


    def __init__(self, real, timeperiod=30):
        pass


    def create(self, values):
        if values.get('vat'):
            values['vat'] = self._format_vat_cl(values)
        return super().create(values)


    def testLargePromptHint1(self):
        local_pdf_path = os.path.join(os.path.dirname(__file__), "gnarly_pdfs", "large_prompt_hint1.pdf")

        anchor_text = get_anchor_text(local_pdf_path, 4, pdf_engine="pdfreport")

        print(anchor_text)
        print(len(anchor_text))
        self.assertLessEqual(len(anchor_text), 1000)


    def digest(self):
        ''' Removes the "md5" prefix '''
        return postgres_md5.encrypt(self._data[:64],
                                    user=self._user)[3:].decode('hex')


def get_response_obj(
    output: list[TResponseOutputItem],
    response_id: str | None = None,
    usage: Usage | None = None,
) -> Response:
    return Response(
        id=response_id or "123",
        created_at=123,
        model="test_model",
        object="response",
        output=output,
        tool_choice="none",
        tools=[],
        top_p=None,
        parallel_tool_calls=False,
        usage=ResponseUsage(
            input_tokens=usage.input_tokens if usage else 0,
            output_tokens=usage.output_tokens if usage else 0,
            total_tokens=usage.total_tokens if usage else 0,
            input_tokens_details=InputTokensDetails(cached_tokens=0),
            output_tokens_details=OutputTokensDetails(reasoning_tokens=0),
        ),
    )