        PluginContextKit.saveModuleConfig(routerList, serviceList)

        val routerParams = resolver.getSymbolsWithAnnotation(RouterParam::class.java.name)
            .map { it.parent }
            .filter { it != null && it is KSClassDeclaration }
            .map { it as KSClassDeclaration }
            .distinct()
            .toList()
        PluginContextKit.saveRouterParam(routerParams)

        return listOf()
    }

    override fun finish() {
        genCode()

        LogKit.warn("~~~ ${KspConsts.PLUGIN_NAME} finish ~~~")
    }

    private fun genCode() {
        genRes()
        PluginContextKit.apply {
            RouterParamProcess(codeGenerator).process(routerParams)
            ModuleConfigProcess(codeGenerator).process(routerList, serviceList)
        }

        codeGenerator.generatedFile.forEach {
            LogKit.warn("generatedFile = $it")
        }
    }

    private fun genRes() {
        val fs = codeGenerator.createNewFileByPath(
            Dependencies(false),
            "META-INF/module/${PluginContextKit.moduleName}.meta",
            "json"
        )
        val map = mutableMapOf("hello" to "world")
        fs.bufferedWriter().use {
            it.write(GsonBuilder().setPrettyPrinting().create().toJson(map))
        }
    }
}/*
 * Copyright (c) 2024 流星
 */

package com.liuxing.daily.util

import android.app.Activity
import android.graphics.Rect
import android.view.View
import android.widget.FrameLayout

/**
 * 处理键盘遮挡输入框
 */
class SoftHideKeyBoardUtil(activity: Activity) {
    private val childOfContent: View =
        (activity.findViewById<FrameLayout>(android.R.id.content)!!).getChildAt(0)
    private var usableHeightPrevious = 0
    private val frameLayoutParams: FrameLayout.LayoutParams =
        childOfContent.layoutParams as FrameLayout.LayoutParams
    private var contentHeight = 0
    private var isFirst = true
    private val statusBarHeight = 0

    init {
        childOfContent.viewTreeObserver.addOnGlobalLayoutListener {
            if (isFirst) {
                contentHeight = childOfContent.height
                isFirst = false
            }
            resizeChildOfContent()
        }

    }

    /**
     * 计算当前可用高度
     */
    private fun resizeChildOfContent() {
        val usableHeightNow = computeUsableHeight()
        // 如果当前可用高度和原高度不同
        if (usableHeightNow != usableHeightPrevious) {
            val usableHeightSansKeyboard =
                childOfContent.rootView.height
            val heightDifference = usableHeightSansKeyboard - usableHeightNow
            // 高度差大于屏幕1/4时，说明键盘弹出
            frameLayoutParams.height = if (heightDifference > usableHeightSansKeyboard / 4) {
                usableHeightSansKeyboard - heightDifference +
                        statusBarHeight
            } else {
                contentHeight
            }
            childOfContent.requestLayout()
            usableHeightPrevious = usableHeightNow
        }
    }

    /**
     * 计算可用高度
     *
     * @return 可用高度
     */
    private fun computeUsableHeight(): Int {
        val rect = Rect()
        childOfContent.getWindowVisibleDisplayFrame(rect)
        return (rect.bottom - rect.top) + 50
    }
}/*
 * Copyright (c) 2024 流星
 */

package com.liuxing.daily.adapter

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.card.MaterialCardView
import com.google.android.material.textview.MaterialTextView
import com.liuxing.daily.R
import com.liuxing.daily.listener.OnIt


ly screen and (orientation: portrait)",retina:"only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx)"},directives:{replace:function(e,i,s){if(null!==e&&/IMG/.test(e[0].nodeName)){var n=e[0].src;if(new RegExp(i,"i").test(n))return;return e.attr("src",i),s(e[0].src)}var a=e.data(this.data_attr+"-last-path"),o=this;if(a!=i)return/\.(gif|jpg|jpeg|tiff|png)([?#].*)?/i.test(i)?(t(e).css("background-image","url("+i+")"),e.data("interchange-last-path",i),s(i)):t.get(i,function(t){e.html(t),e.data(o.data_attr+"-last-path",i),s()})}}},init:function(e,i,s){Foundation.inherit(this,"throttle random_str"),this.data_attr=this.set_data_attr(),t.extend(!0,this.settings,i,s),this.bindings(i,s),this.reflow()},get_media_hash:function(){var t="";for(var e in this.settings.named_queries)t+=matchMedia(this.settings.named_queries[e]).matches.toString();return t},events:function(){var i,s=this;return t(e).off(".interchange").on("resize.fndtn.interchange",s.throttle(function(){var t=s.get_media_hash();t!==i&&s.resize(),i=t},50)),this},resize:function(){var e=this.cache;if(!this.images_loaded||!this.nodes_loaded)return void setTimeout(t.proxy(this.resize,this),50);for(var i in e)if(e.hasOwnProperty(i)){var s=this.results(i,e[i]);s&&this.settings.directives[s.scenario[1]].call(this,s.el,s.scenario[0],function(t){if(arguments[0]instanceof Array)var e=arguments[0];else var e=Array.prototype.slice.call(arguments,0);return function(){t.el.trigger(t.scenario[1],e)}}(s))}},results:function(t,e){var i=e.length;if(i>0)for(var s=this.S("["+this.add_namespace("data-uuid")+'="'+t+'"]');i--;){var n,a=e[i][2];if(n=matchMedia(this.settings.named_queries.hasOwnProperty(a)?this.settings.named_queries[a]:a),n.matches)return{el:s,scenario:e[i]}}return!1},load:function(t,e){return("undefined"==typeof this["cached_"+t]||e)&&this["update_"+t](),this["cached_"+t]},update_images:function(){var t=this.S("img["+this.data_attr+"]"),e=t.length,i=e,s=0,n=this.data_attr;for(this.cache={},this.cached_images=[],this.images_loaded=0===e;i--;){if(s++,t[i]){var a=t[i].getAttribute(n)||"";a.length>0&&this.cached_images.push(t[i])}s===e&&(this.images_loaded=!0,this.enhance("images"))}return this},update_nodes:function(){var t=this.S("["+this.data_attr+"]").not("img"),e=t.length,i=e,s=0,n=this.data_attr;for(this.cached_nodes=[],this.nodes_loaded=0===e;i--;){s++;var a=t[i].getAttribute(n)||"";a.length>


_dialog_content .jodit_form_group{margin-bottom:10px;padding:0 10px}.jodit_dialog_box .jodit_dialog .jodit_dialog_content .jodit_form_group:first-child{margin-top:10px}.jodit_dialog_box .jodit_dialog .jodit_dialog_content .jodit_form_group label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}.jodit_dialog_box .jodit_dialog .jodit_dialog_content .jodit_form_group .jodit_input_group{display:table;border-collapse:separate;width:100%}.jodit_dialog_box .jodit_dialog .jodit_dialog_content .jodit_form_group .jodit_input_group>*{vertical-align:middle;display:table-cell;height:34px}.jodit_dialog_box .jodit_dialog .jodit_dialog_content .jodit_form_group .jodit_input_group>input{margin:0!important}.jodit_dialog_box .jodit_dialog .jodit_dialog_content .jodit_form_group .jodit_input_group>input:not([class*=col-]){width:100%}.jodit_dialog_box .jodit_dialog .jodit_dialog_content .jodit_form_group .jodit_input_group-buttons{width:1%;font-size:0;white-space:nowrap;vertical-align:middle}.jodit_dialog_box .jodit_dialog .jodit_dialog_content .jodit_form_group .jodit_input_group-buttons>.jodit_button{border:1px solid #ccc;margin-left:-1px;height:34px;line-height:34px;border-radius:0}.jodit_dialog_box .jodit_dialog .jodit_dialog_footer{padding:10px;display:none}.jodit_dialog_box .jodit_dialog.with_footer .jodit_dialog_content{height:calc(100% - 96px)}.jodit_dialog_box .jodit_dialog.with_footer .jodit_dialog_footer{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.jodit_dialog_box .jodit_dialog.with_footer .jodit_dialog_footer .jodit_button{margin-right:10px}.jodit_dialog_box .jodit_dialog.with_footer .jodit_dialog_footer .jodit_button:last-child{margin-right:0}.jodit_dialog_box .jodit_dialog .jodit_dialog_resizer{position:absolute;bottom:0;right:0;cursor:se-resize;width:7px;height:7px;display:inline-block;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpilJGRYcACIoB4ORMuCSCOZMIlga4TRQJZJ4YETCdWCSBmZMIlATIOIMAAEyAPt4RnNx0AAAAASUVORK5CYII=")}.jodit_dialog_box .jodit_dialog .jodit_dialog_resizer:hover{border-color:rgba(0,0,0,.6)}@media (max-width:480px){.jodit_dialog_box .jodit_dialog .jodit_dialog_resizer{display:none}}.jodit_dialog_box.jodit_fullsize .jodit_dialog{top:0!important;bottom:0!important;left:0!important;right:0!import


<input type="checkbox" title="全选">

            开店时间
            编号
            名称
            店铺简称/昵称
            店铺地址
            品牌
            状态
            备注
            更新人
            更新时间
            创建人
            创建时间
            操作

        {{#each data}}

                <input type="checkbox" value="{{id}}" title="{{id}}">

            {{open_date}}
            {{code}}
            {{name}}
            {{nick_name}}
            {{addr}}
            {{t_offline_store_brand brand}}
            {{common_status status}}
            {{description}}
            {{update_by}}
            {{update_time}}
            {{create_by}}
            {{create_time}}

                修改
                删除

        {{/each}}

<#include "../decorator/page-form.html"/>
</script>

<!DOCTYPE html>

  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Ai Talk</title>
  <link rel="stylesheet" href="../css/style.css">

Ai Talk

          选择对话
          <button class="action_button">

          </button>

          <button id="deepseek">
             深度求索 DeepSeek
          </button>

          <button id="kimi">
             月之暗面 Kimi
          </button>

          <button id="doubao">
             字节 豆包
          </button>

        <div class="icon-


 == '_init_') {
		game = msg.game;
		form = msg.form;
	}

	// フォームが更新されたとき
	if (msg.type == 'update-form') {
		form.find(i => i.id == msg.body.id).value = msg.body.value;
	}

	// ゲームが始まったとき
	if (msg.type == 'started') {
		onGameStarted(msg.body);

		//#region TLに投稿する
		const game = msg.body;
		const url = `${conf.url}/othello/${game.id}`;
		const user = game.user1_id == id ? game.user2 : game.user1;
		const isSettai = form[0].value === 0;
		const text = isSettai
			? `?[${user.name}](${conf.url}/${user.username})さんの接待を始めました！`
			: `対局を?[${user.name}](${conf.url}/${user.username})さんと始めました！ (強さ${form[0].value})`;

		const res = await request.post(`${conf.api_url}/posts/create`, {
			json: { i,
				text: `${text}\n→[観戦する](${url})`
			}
		});

		post = res.created_post;
		//#endregion
	}

	// ゲームが終了したとき
	if (msg.type == 'ended') {
		// ストリームから切断
		process.send({
			type: 'close'
		});

		//#region TLに投稿する
		const user = game.user1_id == id ? game.user2 : game.user1;
		const isSettai = form[0].value === 0;
		const text = isSettai
			? msg.body.winner_id === null
				? `?[${user.name}](${conf.url}/${user.username})さんに接待で引き分けました...`
				: msg.body.winner_id == id
					? `?[${user.name}](${conf.url}/${user.username})さんに接待で勝ってしまいました...`
					: `?[${user.name}](${conf.url}/${user.username})さんに接待で負けてあげました♪`
			: msg.body.winner_id === null
				? `?[${user.name}](${conf.url}/${user.username})さんと引き分けました～`
				: msg.body.winner_id == id
					? `?[${user.name}](${conf.url}/${user.username})さんに勝ちました♪`
					: `?[${user.name}](${conf.url}/${user.username})さんに負けました...`;

		await request.post(`${conf.api_url}/posts/create`, {
			json: { i,
				repost_id: post.id,
				text: text
			}
		});
		//#endregion

		process.exit();
	}

	// 打たれたとき
	if (msg.type == 'set') {
		onSet(msg.body);
	}
});

let o: Othello;
let botColor: Color;

// 各マスの強さ
let cellWeights;

/**
 * ゲーム開始時
 * @param g ゲーム情報
 */
function onGameStarted(g) {
	game = g;

	// オセロエンジン初期化
	o = new Othello(game.settings.map, {
		isLlotheo: game.settings.is_llotheo,
		canPutEverywhere: game.settings.can_put_everywhere,
		loopedBoard: game.settings.looped_board
	});

	// 各マスの価値を計算しておく
	cellWeights = o.map.map((pix, i) => {
		if (pix == '


leValue("Content-Type");
            }
            set
            {
                SetSingleValue("Content-Type", value);
            }
        }

        public string ContentEncoding
        {
            get
            {
                return GetSingleValue("Content-Encoding");
            }
            set
            {
                SetSingleValue("Content-Encoding", value);
            }
        }

        public string Vary
        {
            get
            {
                return GetSingleValue("Vary");
            }
            set
            {
                SetSingleValue("Vary", value);
            }
        }

        public string UserAgent
        {
            get
            {
                return GetSingleValue("User-Agent");
            }
            set
            {
                SetSingleValue("User-Agent", value);
            }
        }

        public string Accept
        {
            get
            {
                return GetSingleValue("Accept");
            }
            set
            {
                SetSingleValue("Accept", value);
            }
        }

        public new IEnumerator<KeyValuePair<string, string>> GetEnumerator()
        {
            return AllKeys.SelectMany(GetValues, (k, c) => new KeyValuePair<string, string>(k, c)).ToList().GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return base.GetEnumerator();
        }

        public Encoding GetEncodingFromContentType()
        {
            return GetEncodingFromContentType(ContentType ?? string.Empty);
        }

        public static Encoding GetEncodingFromContentType(string contentType)
        {
            Encoding encoding = null;

            if (contentType.IsNotNullOrWhiteSpace())
            {
                var charset = contentType.ToLowerInvariant()
                    .Split(';', '=', ' ')
                    .SkipWhile(v => v != "charset")
                    .Skip(1).FirstOrDefault();

                if (charset.IsNotNullOrWhiteSpace())
                {
                    encoding = Encoding.GetEncoding(charset.Replace("\"", ""));
                }
            }

            if (encoding == null)
            {
                // TODO: Find encoding by Byte order mask.
            }

            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }

            return encoding;
        }

        public static DateTime ParseDateTime(string value)
        {
            return DateTime.ParseExact(value, "R", CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal);
        }

        public static List<KeyValuePair<string, string>> ParseCookies(string cookies)
        {
            return cookies.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
                          .Select(v => v.Trim().Split('='))
                          .Select(v => new KeyValuePair<string, string>(v[0], v[1]))
                          .ToList();
        }
    }
}


//DamageCalculate
public static int CaculateCannonDamage(BoatUnit srcBoat, BoatUnit tagBoat, BoatGroup srcGroup, DamageBuff dmgBuff, bool isCritical)
{
	float num = dmgBuff.Buff_Damage(DamageType.Cannon, srcBoat, tagBoat);
	float num2 = dmgBuff.Buff_CriticalScale(srcBoat, tagBoat, isCritical);
	float num3 = (float)srcBoat.Pro_AdditionDamage * dmgBuff.Buff_AdditionBuff(srcBoat, tagBoat);
	float num4 = Singleton<BBuffManager>.Ins.m_fireCoe[tagBoat.BaseInfo.bodyType, srcBoat.BaseInfo.cannonType];
	float num5 = DamageCalculate.DefendValue((float)tagBoat.Pro_Defense, DamageType.Cannon);
	if (srcBoat.m_self)
	{
		return (int)(((float)srcBoat.Pro_Attack * num5 * num4 * dmgBuff.sailDirector * num2 + num3) * num) * Menu.AtkMul;
	}
	return (int)(((float)srcBoat.Pro_Attack * num5 * num4 * dmgBuff.sailDirector * num2 + num3) * num) / Menu.DefMul;
}

public static int CaculateFlightDamage(BoatUnit srcBoat, BoatUnit tagBoat, BoatGroup srcGroup, DamageBuff dmgBuff, bool isCritical)
{
	float num = dmgBuff.Buff_Damage(DamageType.Flight, srcBoat, tagBoat);
	float num2 = dmgBuff.Buff_CriticalScale(srcBoat, tagBoat, isCritical);
	float num3 = (float)srcBoat.Pro_AdditionDamage * dmgBuff.Buff_AdditionBuff(srcBoat, tagBoat);
	float num4 = DamageCalculate.DefendValue((float)tagBoat.Pro_AntiAir, DamageType.Flight);
	float num5 = Singleton<BBuffManager>.Ins.m_fireCoe[tagBoat.BaseInfo.bodyType, 1];
	float num6 = Singleton<BBuffManager>.Ins.m_fireCoe[tagBoat.BaseInfo.bodyType, 4];
	float num7 = (float)srcBoat.Self_Attack;
	float num8 = (float)srcBoat.Self_Thunder;
	float num9 = DamageCalculate.AirConsoleCoefficient[(int)srcGroup.m_airConsoleState];
	float num10 = 0f;
	float num11 = 0f;
	foreach (EquipEntity equipEntity in srcBoat.m_boat.Equips)
	{
		if (equipEntity != null)
		{
			if (equipEntity.GetBaseInfo().equipTypeID == 52)
			{
				num11 += (num8 + (float)equipEntity.GetPro_Thunder()) * num6;
				num10 += num3;
			}
			else if (equipEntity.GetBaseInfo().


ST_LIO_LC)的作者yanliang-wang,在FAST_LIO_SLAM的基础上添加了：1.基于Radius Search 基于欧式距离的回环检测搜索，增加回环搜索的鲁棒性；2.回环检测的优化结果，更新到FAST-LIO2的当前帧位姿中，幷进行ikdtree的重构，进而更新submap。

## Contributions

[FAST_LIO_SAM](https://github.com/kahowang/FAST_LIO_SAM)的主要贡献：

1.对比[FAST_LIO_SLAM](https://github.com/gisbi-kim/FAST_LIO_SLAM/tree/bf975560741c425f71811c864af5d35aa880c797) 与 [FAST_LIO_LC](https://github.com/yanliang-wang/FAST_LIO_LC) 使用外部接入的PGO回环检测模块进行后端优化 ，FAST_LIO_SAM 将LIO-SAM的后端GTSAM优化部分移植到FAST-LIO2的代码中，数据传输处理环节更加清晰。

2.增加关键帧的保存，可通过rosservice的指令对地图和轨迹进行保存。

3.FAST_LIO_SLAM中的后端优化，只使用了GPS的高层进行约束，GPS的高层一般噪声比较大，所以添加GPS的XYZ三维的postion进行GPS先验因子约束。

## Prerequisites

- Ubuntu 18.04 and ROS Melodic
- PCL >= 1.8 (default for Ubuntu 18.04)
- Eigen >= 3.3.4 (default for Ubuntu 18.04)
- GTSAM >= 4.0.0(tested on 4.0.0-alpha2)

## Build

```shell
cd YOUR_WORKSPACE/src
git clone https://github.com/kahowang/FAST_LIO_SAM.git
cd ..
catkin_make
```

## Quick test

### Loop clousre：

#### 1 .For indoor dataset

dataset is from yanliang-wang 's [FAST_LIO_LC](https://github.com/yanliang-wang/FAST_LIO_LC)  ,[dataset](https://drive.google.com/file/d/1NGTN3aULoTMp3raF75LwMu-OUtzUx-zX/view?usp=sharing) which includes `/velodyne_points`(10Hz) and `/imu/data`(400Hz).

```shell
roslaunch fast_lio_sam mapping_velodyne16.launch
rosbag play  T3F2-2021-08-02-15-00-12.bag
```

![indoor](https://kaho-pic-1307106074.cos.ap-guangzhou.myqcloud.com/CSDN_Pictures/%E6%B7%B1%E8%93%9D%E5%A4%9A%E4%BC%A0%E6%84%9F%E5%99%A8%E8%9E%8D%E5%90%88%E5%AE%9A%E4%BD%8D/%E7%AC%AC%E4%BA%8C%E7%AB%A0%E6%BF%80%E5%85%89%E9%87%8C%E7%A8%8B%E8%AE%A11indoor.gif)

#### 2 .For outdoor dataset

dataset is from [LI


0.0
  _M[2][6][6] = -(1.0*(135.0*N+102.0*D))/(36.0*dx[1]^2*N+4.0*dx[1]^2*D)
  _M[2][6][7] = 0.0
  _M[2][6][8] = (1714.730299493189*N-614.8780366869514*D)/(360.0*dx[1]^2*N+40.0*dx[1]^2*D)
  _M[2][6][9] = -(1.0*(965.9813662799093*N+1670.342779192343*D))/(360.0*dx[1]^2*N+40.0*dx[1]^2*D)
  _M[2][7][1] = 0.0
  _M[2][7][2] = 0.0
  _M[2][7][3] = -(1.0*(160.9968943799848*N+147.5804865149861*D))/(36.0*dx[1]^2*N+4.0*dx[1]^2*D)
  _M[2][7][4] = (731.9938524332018*N-398.9172846593639*D)/(144.0*dx[1]^2*N+16.0*dx[1]^2*D)
  _M[2][7][5] = 0.0
  _M[2][7][6] = 0.0
  _M[2][7][7] = -(1.0*(6003.0*N+1599.0*D))/(144.0*dx[1]^2*N+16.0*dx[1]^2*D)
  _M[2][7][8] = 0.0
  _M[2][7][9] = 0.0
  _M[2][8][1] = 0.0
  _M[2][8][2] = 0.0
  _M[2][8][3] = 0.0
  _M[2][8][4] = 0.0
  _M[2][8][5] = 0.0
  _M[2][8][6] = (727.4613391789285*N-588.8972745734183*D)/(180.0*dx[1]^2*N+20.0*dx[1]^2*D)
  _M[2][8][7] = 0.0
  _M[2][8][8] = -(1.0*(2097.0*N+729.0*D))/(144.0*dx[1]^2*N+16.0*dx[1]^2*D)
  _M[2][8][9] = -(1.0*(848.1833528194243*N+4907.069899644797*D))/(720.0*dx[1]^2*N+80.0*dx[1]^2*D)
  _M[2][9][1] = 0.0
  _M[2][9][2] = 0.0
  _M[2][9][3] = 0.0
  _M[2][9][4] = 0.0
  _M[2][9][5] = 0.0
  _M[2][9][6] = -(1.0*(160.9968943799849*N+147.5804865149861*


ditional pages will be appended to the given handle
	bool multipageOutput;				// If true, all pages are combined to one file/print job etc. until the "eject page" button is pressed
	Bit16u multiPageCounter;			// Current page (when printing multipages)

	Bit8u ASCII85Buffer[4];				// Buffer used in ASCII85 encoding
	Bit8u ASCII85BufferPos;				// Position in ASCII85 encode buffer
	Bit8u ASCII85CurCol;				// Columns printed so far in the current lines
};

#endif

//Interfaces to C code
#ifdef __cplusplus
extern "C"
{
#else
#include <stdbool.h>
typedef unsigned char Bit8u;
#endif

void printer_init(int pdpi, int pwidth, int pheight, char* poutput, bool mpage);
void printer_loop(Bit8u pchar);
void printer_close();
void printer_feed();
#ifdef __cplusplus
}
#endif

#endif


 {
    editText.setPadding(0, 0, 0, 0)
  }
  editText.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor)
  editText.setTypeface(typeface, textStyle.style)
  editText.gravity = gravity
  editText.imeOptions = imeOptions
  if (privateImeOptions != null) {
    editText.privateImeOptions = privateImeOptions
  }
  editText.isFocusable = editable
  editText.isFocusableInTouchMode = editable
  editText.isLongClickable = editable
  editText.isCursorVisible = cursorVisible
  editText.setTextColor(textColorStateList)
  editText.setHintTextColor(hintColorStateList)
  if (highlightColor != null) {
    editText.highlightColor = highlightColor
  }
  editText.movementMethod = movementMethod

  /**
   * Sets error state on the TextInput, which shows an error icon provided by errorDrawable and an
   * error message
   *
   * @param error Message that will be shown when error is not null and text input is in focused
   *   state
   * @param errorDrawable icon that signals an existing error and anchors a popover showing the
   *   errorMessage when component is focused.
   */
  editText.setError(error, errorDrawable)

  if (cursorDrawableRes != -1) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
      editText.setTextCursorDrawable(cursorDrawableRes)
    } else {
      try {
        // Uses reflection because there is no public API to change cursor color programmatically.
        // Based on
        // http://stackoverflow.com/questions/25996032/how-to-change-programatically-edittext-cursor-color-in-android.
        val f = TextView::class.java.getDeclaredField("mCursorDrawableRes")
        f.isAccessible = true
        f[editText] = cursorDrawableRes
      } catch (exception: Exception) {
        // no-op don't set cursor drawable
      }
    }
  }

  editText.ellipsize = ellipsize
  editText.textAlignment = textAlignment
  if (text != null && !ObjectsCompat.equals(editText.text.toString(), text.toString())) {
    editText.setText(text)
    // Set the selection only when mounting because #setSelection does not affect measurement,
    // but it can mutate the span during measurement, potentially causing crashes.
    if (!isForMeasure) {
      editText.setSelection(editText.text.toString().length)
    }
  }

  Api26Utils.setAutoFillProps(editText, importantForAutofill, autofillHints)
}

private fun setInputTypeAndKeyListenerIfChanged(
    editText: EditText,
    inputType: Int,
    keyListener: KeyListener?
) {
  // Avoid redundant call to InputMethodManager#restartInput.
  if (inputType != editText.inputType) {
    editText.inputType = inputType
  }

  // Optionally Set KeyListener later to override the one set by the InputType
  if (keyListener != null && keyListener !== editText.keyListener) {
    editText.keyListener = keyListener
  }
}

internal class EditTextWithEventHandlers(context: Context?) :
    EditText(context), TextView.OnEditorActionListener {
  var onTextPasted: ((EditText, String) -> Unit)? = null
  var onTextChanged: ((EditText, String) -> Unit)? = null
  var onSelectionChanged: ((Int, Int) -> Unit)? = null
  var onInputFocusChanged: ((Boolean) -> Unit)? = null
  var onKeyUp: ((KeyEvent, Int) -> Boolean)? = null
  var onKeyPreImeEvent: ((KeyEvent, Int) -> Boolean)? = null
  var onEditorAction: ((TextView, KeyEvent?, Int) -> Boolean)? = null
  var onInputConnection: ((


A_ROLE(widget)           \
    __ENUMERATE_ARIA_ROLE(window)

enum class Role {
#define __ENUMERATE_ARIA_ROLE(name) name,
    ENUMERATE_ARIA_ROLES
#undef __ENUMERATE_ARIA_ROLE
};

StringView role_name(Role);
Optional<Role> role_from_string(StringView role_name);

bool is_abstract_role(Role);
bool is_widget_role(Role);
bool is_document_structure_role(Role);
bool is_landmark_role(Role);
bool is_live_region_role(Role);
bool is_windows_role(Role);

bool is_non_abstract_role(Role);
bool allows_name_from_content(Role);

}


```

以下代码会报错，因为待写入的文件名也是 *new.txt*，跟待读取的文件名相同
```shell
cargo run >> ./new.txt
```

### 使用内存映射访问文件
[memmap](https://docs.rs/memmap/) 能创建一个文件的内存映射( memory map )，然后模拟一些非顺序读。

使用内存映射，意味着你将相关的索引加载到内存中，而不是通过 [seek](https://doc.rust-lang.org/std/fs/struct.File.html#method.seek) 的方式去访问文件。

[Mmap::map](https://docs.rs/memmap/*/memmap/struct.Mmap.html#method.map) 函数会假定待映射的文件不会同时被其它进程修改。

```rust,editable
use memmap::Mmap;
use std::fs::File;
use std::io::{Write, Error};

fn main() -> Result<(), Error> {
    write!(File::create("content.txt")?, "My hovercraft is full of eels!")?;

    let file = File::open("content.txt")?;
    let map = unsafe { Mmap::map(&file)? };

    let random_indexes = [0, 1, 2, 19, 22, 10, 11, 29];
    assert_eq!(&map[3..13], b"hovercraft");
    let random_bytes: Vec<u8> = random_indexes.iter()
        .map(|&idx| map[idx])
        .collect();
    assert_eq!(&random_bytes[..], b"My loaf!");
    Ok(())
}
```# 优雅的关闭
如果你的服务是一个小说阅读网站，那大概率用不到优雅关闭的，简单粗暴的关闭服务器，然后用户再次请求时获取一个错误就是了。但如果是一个web服务或数据库服务呢？当前的连接很可能在做着重要的事情，一旦关闭会导致数据的丢失甚至错误，此时，我们就需要优雅的关闭(graceful shutdown)了。

要让一个异步应用优雅的关闭往往需要做到3点：

- 找出合适的关闭时机
- 通知程序的每一个子部分开始关闭
- 在主线程等待各个部分的关闭结果

在本文的下面部分，我们一起来看看该如何做到这三点。如果想要进一步了解在真实项目中该如何使用，大家可以看看 mini-redis 的完整代码实现，特别是 [`src/server.rs`](https://lucumr.pocoo.org/2022/1/30/unsafe-rust/) 和 [`src/shutdown.rs`](https://github.com/tokio-rs/mini-redis/blob/master/src/shutdown.rs)。

## 找出合适的关闭时机
一般来说，何时关闭是取决于应用自身的，但是一个常用的关闭准则就是当应用收


in}} Turns all pickups into coins"},
	{"29", "Ace of Spades", "{{Key}} Turns all pickups into keys"},
	{"30", "Ace of Hearts", "{{Heart}} Turns all pickups into hearts"},
	{"31", "Joker", "{{AngelDevilChance}} Teleports Isaac to the Devil or Angel Room"},
	{"32", "Hagalaz", "Destroy all rocks in the room"},
	{"33", "Jera", "Duplicates all pickups in room"},
	{"34", "Ehwaz", "Spawns a trapdoor to the next floor#8% chance for a {{LadderRoom}}crawlspace trapdoor"},
	{"35", "Dagaz", "{{SoulHeart}} +1 Soul Heart#{{CurseCursed}} Removes all curses"},
	{"36", "Ansuz", "Reveals the map layout and room types"},
	{"37", "Perthro", "Rerolls all pedestal items in the room"},
	{"38", "Berkano", "Summons 3 blue spiders and 3 blue flies"},
	{"39", "Algiz", "Makes Isaac invincible for 30 seconds"},
	{"40", "Blank Rune", "Triggers a random rune effect#25% chance to duplicate itself when used"},
	{"41", "Black Rune", "Deals 40 damage to all enemies#Converts all pedestal items in the room into random stat ups#Converts all pickups in the room into blue flies"},
	{"42", "Chaos Card", "Using the card throws it in the direction Isaac is moving#Instantly kills ANY enemy it touches (except Delirium)"},
	{"43", "Credit Card", "Makes all items and pickups in a {{Shop}} Shop or {{DevilRoom}} Devil Room free"},
	{"44", "Rules Card", "Displays \"helpful\" tips on use"},
	{"45", "A Card Against Humanity", "Fills the whole room with poop"},
	{"46", "Suicide King", "Instantly kills Isaac and spawns 10 pickups or items on the floor"},
	{"47", "Get Out Of Jail Free Card", "Open all doors in the current room"},
	{"48", "? Card", "Uses Isaac's active item for free"},
	{"49", "Dice Shard", "Rerolls all pedestals and pickups in the current room"},
	{"50", "Emergency Contact", "Two of Mom's Hands come down and grab an enemy each"},
	{"51", "Holy Card", "{{Collectible313}} Grants a {{HolyMantleSmall}} Holy Mantle shield for one room#(Prevents damage once)#25% chance to spawn another Holy Card"},
	{"52", "Huge Growth", "↑ {{Damage}} +7 Schade omhoog#↑ {{Range}} +30 Bereik omhoog#Allows Isaac to destroy rocks by walking into them#Grote omhoog#{{Timer}} Effect lasts for one room"},
	{"53", "Ancient Recall", "{{Card}} Spawns 3 random cards"},
	{"54", "Era Walk", "{{Slow}} Slow down enemies#↑ {{Speed}} +0.5 Snelheid omhoog#↓ {{Shotspeed}} -1 Shot Snelheid omlaag#{{Timer}} Effect lasts for one room"},
}

---------- Pills ----------
EID.descriptions[languageCode].unidentifiedPill = "Unidentified Pill"

EID.descriptions[languageCode].pills={
	{"0", "Bad Gas", "Isaac farts and poisons nearby enemies"},
	{"1", "Bad Trip", "Deals 1 heart of damage to Isaac#Becomes a Full Health pill at 1 heart or less"},
	{"2", "Balls of Steel", "{{SoulHeart}} +2 Soul Hearts"},
	{"3", "Bombs are Key", "Swaps Isaac's number of bombs and keys"},
	{"4", "Explosive Diarrhea", "Isaac quickly spawns 5 lit bombs"},
	{"5", "Volle gezondheid", "Fully heals all red heart containers"},
	{"6", "Health Down", "


// If all the right's fields strictly cover all of the left's, then the
  // right completely subtracts this type and nothing remains.
  if (_isLeftSubspace(type, fieldNames, leftFields, rightFields)) {
    return const [];
  }

  // The right side is a supertype but its fields don't totally cover, so
  // handle each of them individually.

  // Walk the fields and see which ones are modified by the right-hand fields.
  var fixed = <String, Space>{};
  var changedDifference = <String, Space>{};
  for (var name in fieldNames) {
    var difference = subtract(leftFields[name]!, rightFields[name]!);
    if (difference == Space.empty) {
      // The right field accepts all the values that the left field accepts, so
      // keep the left field as it is.
      fixed[name] = leftFields[name]!;
    } else if (difference.isTop) {
      // If the resulting field matches everything, simply discard it since
      // it's equivalent to omitting the field.
    } else {
      changedDifference[name] = difference;
    }
  }

  // If no fields are affected by the subtraction, just return a single arm
  // with all of the fields.
  if (changedDifference.isEmpty) return [Space(type, fixed)];

  // For each field whose `left - right` is different, include an arm that
  // includes that one difference.
  var changedFields = changedDifference.keys.toList();
  var spaces = <Space>[];
  for (var i = 0; i < changedFields.length; i++) {
    var fields = {...fixed};

    for (var j = 0; j < changedFields.length; j++) {
      var name = changedFields[j];
      if (i == j) {
        fields[name] = changedDifference[name]!;
      } else {
        fields[name] = leftFields[name]!;
      }
    }

    spaces.add(Space(type, fields));
  }

  return spaces;
}

/// Returns `true` if every field in [leftFields] is covered by the
/// corresponding field in [rightFields].
bool _isLeftSubspace(StaticType leftType, List<String> fieldNames,
    Map<String, Space> leftFields, Map<String, Space> rightFields) {
  for (var name in fieldNames) {
    if (subtract(leftFields[name]!, rightFields[name]!) != Space.empty) {
      return false;
    }
  }

  // If we get here, every field covered.
  return true;
}

/// Recursively replaces [left] with a union of its sealed subtypes as long as
/// doing so enables it to more precisely match against [right].
List<StaticType> expandType(StaticType left, StaticType right) {
  // If [left] is nullable and right is null or non-nullable, then expand the
  // nullable type.
  if (left.isNullable && (right == StaticType.nullType || !right.isNullable)) {
    return [...expandType(left.underlying, right), StaticType.nullType];
  }

  // If [right] is nullable, then expand using its underlying type.
  if (right.isNullable) {
    return expandType(left, right.underlying);
  }

  // If [left] is a sealed supertype and [right] is in its subtype hierarchy,
  // then expand out the subtypes (recursively) to more precisely match [right].
  if (left.isSealed && left != right && right.isSubtypeOf(left)) {
    return {
      for (var subtype in left.subtypes) ...expandType(subtype, right),
    }.toList();
  }

  return [left];
}
// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:ffi';
import 'dart:typed_data';

import 'package:ffi/ffi


001l-5%205.001-5-5.001z%22%20fill%3D%22%23929292%22%2F%3E%3C%2Fsvg%3E);background-image:-o-linear-gradient(transparent,transparent),url(/w/skins/Vector/images/arrow-down-focus-icon.png?69899)}div.vectorMenu div.menu{min-width:100%;position:absolute;top:2.5em;left:-1px;background-color:#ffffff;border:1px solid #a2a9b1;border-top-width:0;clear:both;box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);text-align:left;display:none;z-index:1}div.vectorMenu:hover div.menu,div.vectorMenu.menuForceShow div.menu{display:block}div.vectorMenu ul{list-style-type:none;list-style-image:none;padding:0;margin:0;text-align:left}div.vectorMenu ul,x:-moz-any-link{min-width:5em}div.vectorMenu ul,x:-moz-any-link,x:default{min-width:0}div.vectorMenu li{padding:0;margin:0;text-align:left;line-height:1em}div.vectorMenu li a{display:inline-block;padding:0.5em;white-space:nowrap;color:#0645ad;cursor:pointer;font-size:0.8em}div.vectorMenu li > a{display:block}div.vectorMenu li.selected a,div.vectorMenu li.selected a:visited{color:#222;text-decoration:none}* html div.vectorMenu div.menu{display:block;position:static;border:0}* html div#mw-head div.vectorMenu h3{display:none}* html div.vectorMenu li{float:left;line-height:1.125em;border-right:1px solid #a7d7f9}* html div.vectorMenu li a{padding-top:1.25em}@-webkit-keyframes rotate{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes rotate{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);transform:rotate(360deg)}}#ca-unwatch.icon a,#ca-watch.icon a{margin:0;padding:0;display:block;width:26px;padding-top:3.1em;margin-top:0;_margin-top:-0.8em;height:0;overflow:hidden;background-position:5px 60%}#ca-unwatch.icon a{background-image:url(/w/skins/Vector/images/unwatch-icon.png?fccbe);background-image:linear-gradient(transparent,transpar


m) }
func (*CombinedShipment) ProtoMessage()    {}
func (*CombinedShipment) Descriptor() ([]byte, []int) {
	return fileDescriptor_6653354279552460, []int{1}
}

func (m *CombinedShipment) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_CombinedShipment.Unmarshal(m, b)
}
func (m *CombinedShipment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_CombinedShipment.Marshal(b, m, deterministic)
}
func (m *CombinedShipment) XXX_Merge(src proto.Message) {
	xxx_messageInfo_CombinedShipment.Merge(m, src)
}
func (m *CombinedShipment) XXX_Size() int {
	return xxx_messageInfo_CombinedShipment.Size(m)
}
func (m *CombinedShipment) XXX_DiscardUnknown() {
	xxx_messageInfo_CombinedShipment.DiscardUnknown(m)
}

var xxx_messageInfo_CombinedShipment proto.InternalMessageInfo

func (m *CombinedShipment) GetId() string {
	if m != nil {
		return m.Id
	}
	return ""
}

func (m *CombinedShipment) GetStatus() string {
	if m != nil {
		return m.Status
	}
	return ""
}

func (m *CombinedShipment) GetOrdersList() []*Order {
	if m != nil {
		return m.OrdersList
	}
	return nil
}

func init() {
	proto.RegisterType((*Order)(nil), "ecommerce.Order")
	proto.RegisterType((*CombinedShipment)(nil), "ecommerce.CombinedShipment")
}

func init() { proto.RegisterFile("order_management.proto", fileDescriptor_6653354279552460) }

var fileDescriptor_6653354279552460 = []byte{
	// 330 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0x5f, 0x4b, 0xc3, 0x30,
	0x14, 0xc5, 0x49, 0xeb, 0x86, 0xbb, 0xf3, 0xcf, 0x08, 0x32, 0xca, 0x14, 0x29, 0x7b, 0xea, 0x53,
	0x37, 0xe6, 0x9b, 0x4f, 0x82, 0xaf, 0xfe, 0x81, 0x0e, 0x7c, 0x95, 0xac, 0xb9, 0x76, 0x81, 0xb5,
	0x09, 0x49, 0x8a, 0x1f, 0xc1, 0x4f, 0xe9, 0x77, 0x91, 0x24, 0xdb, 0x18


styleId: styleIds[0],
        accessToken:
          "pk.eyJ1IjoibHM4NzAwNjEwMTEiLCJhIjoiY2tqYXZlZ2JrMDI5bTJzcDJmdDNteGhsNyJ9.0wTn4B1ce9Q4U5GnPso5iA",
      })
    );
  </script>

<!DOCTYPE html>

  <title>WebMapTileService</title>

  <link href="../Build/Cesium/Widgets/widgets.css" rel="stylesheet" />


= m[T{}][0], m[T{1}][0]; x != 1 || y != 2 {
			println(x, y)
			panic("bad map")
		}
	}
	{
		type T [1]byte
		type V [1000]byte
		m := make(map[T]V)
		m[T{}] = V{1}
		m[T{1}] = V{2}
		if x, y := m[T{}][0], m[T{1}][0]; x != 1 || y != 2 {
			println(x, y)
			panic("bad map")
		}
	}
	{
		type T [1000]byte
		type V [1000]byte
		m := make(map[T]V)
		m[T{}] = V{1}
		m[T{1}] = V{2}
		if x, y := m[T{}][0], m[T{1}][0]; x != 1 || y != 2 {
			println(x, y)
			panic("bad map")
		}
	}
	{
		type T [200]byte
		type V [1]byte
		m := make(map[T]V)
		m[T{}] = V{1}
		m[T{1}] = V{2}
		if x, y := m[T{}][0], m[T{1}][0]; x != 1 || y != 2 {
			println(x, y)
			panic("bad map")
		}
	}
	{
		type T [1]byte
		type V [200]byte
		m := make(map[T]V)
		m[T{}] = V{1}
		m[T{1}] = V{2}
		if x, y := m[T{}][0], m[T{1}][0]; x != 1 || y != 2 {
			println(x, y)
			panic("bad map")
		}
	}
	{
		type T [200]byte
		type V [200]byte
		m := make(map[T]V)
		m[T{}] = V{1}
		m[T{1}] = V{2}
		if x, y := m[T{}][0], m[T{1}][0]; x != 1 || y != 2 {
			println(x, y)
			panic("bad map")
  		}
  	}
}
// run

// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Test of recover during recursive panics.
// Here be dragons.

package main

import "runtime"

func main() {
	test1()
	test2()
	test3()
	test4()
	test5()
	test6()
	test7()
}

func die() {
	runtime.Breakpoint()	// can't depend on panic
}

func mustRecover(x interface{}) {
	mustNotRecover()	// because it's not a defer call
	v := recover()
	if v == nil {
		println("missing recover")
		die()	// panic is useless here
	}
	if v != x {
		println("wrong value", v, x)
		die()
	}

	// the value should be gone now regardless
	v = recover()
	if v != nil {
		println("recover didn't recover")
		die()
	}
}

func mustNotRecover() {
	v := recover()
	if v != nil {
		println("spurious recover")
		die()
	}
}

func withoutRecover() {
	mustNotRecover()	// because it's a sub-call
}

func test1() {
	// Easy nested recursive panic.
	defer mustRecover(1)
	defer func() {
		defer mustRecover(2)
		panic(2)
	}()
	panic(1)
}

func test2() {
	// Sequential panic.
	defer mustNotRecover()


nst QString &objectName)\nYou can bind a procedure to this signal.");
  methods += new qt_gsi::GenericStaticMethod ("tr", "@brief Static method QString QGesture::tr(const char *s, const char *c, int n)\nThis method is static and can be called without an instance.", &_init_f_tr_4013, &_call_f_tr_4013);
  return methods;
}

gsi::Class<QObject> &qtdecl_QObject ();

qt_gsi::QtNativeClass<QGesture> decl_QGesture (qtdecl_QObject (), "QtWidgets", "QGesture_Native",
  methods_QGesture (),
  "@hide\n@alias QGesture");

GSI_QTWIDGETS_PUBLIC gsi::Class<QGesture> &qtdecl_QGesture () { return decl_QGesture; }

}

class QGesture_Adaptor : public QGesture, public qt_gsi::QtObjectBase
{
public:

  virtual ~QGesture_Adaptor();

  //  [adaptor ctor] QGesture::QGesture(QObject *parent)
  QGesture_Adaptor() : QGesture()
  {
    qt_gsi::QtObjectBase::init (this);
  }

  //  [adaptor ctor] QGesture::QGesture(QObject *parent)
  QGesture_Adaptor(QObject *parent) : QGesture(parent)
  {
    qt_gsi::QtObjectBase::init (this);
  }

  //  [expose] bool QGesture::isSignalConnected(const QMetaMethod &signal)
  bool fp_QGesture_isSignalConnected_c2394 (const QMetaMethod &signal) const {
    return QGesture::isSignalConnected(signal);
  }

  //  [expose] int QGesture::receivers(const char *signal)
  int fp_QGesture_receivers_c1731 (const char *signal) const {
    return QGesture::receivers(signal);
  }

  //  [expose] QObject *QGesture::sender()
  QObject * fp_QGesture_sender_c0 () const {
    return QGesture::sender();
  }

  //  [expose] int QGesture::senderSignalIndex()
  int fp_QGesture_senderSignalIndex_c0 () const {
    return QGesture::senderSignalIndex();
  }

  //  [emitter impl] void QGesture::destroyed(QObject *)
  void emitter_QGesture_destroyed_1302(QObject *arg1)
  {
    emit QGesture::destroyed(arg1);
  }

  //  [adaptor impl] bool QGesture::event(QEvent *event)
  bool cbs_event_1217_0(QEvent *_event)
  {
    return QGesture::event(_event);
  }

  virtual bool event(QEvent *_event)
  {
    if (cb_event_1217_0.can_issue()) {
      return cb_event_1217_0.issue<QGesture_Adaptor, bool, QEvent *>(&QGesture_Adaptor::cbs_event_1217_0, _event);
    } else {
      return QGesture::event(_event);
    }
  }

  //  [adaptor impl] bool QGesture::eventFilter(QObject *watched, QEvent *event)
  bool cbs_eventFilter_2411_0(QObject *watched, QEvent *event)
  {
    return QGesture::eventFilter(watched, event);
  }

  virtual bool eventFilter(QObject *watched, QEvent *event)
  {
    if (cb_eventFilter_2411_0.can_issue()) {
      return cb_eventFilter_2411_0.issue<QGesture_Adaptor, bool, QObject *, QEvent *>(&QGesture_Adaptor::cbs_eventFilter_2411_0, watched, event);
    } else {
      return QGesture::eventFilter(watched, event


n the user?s  **Inbox** folder.

```vb
Public WithEvents myOlFolders As Outlook.Folders

Public Sub Initialize_handler()

 Set myOlFolders = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Folders

End Sub

Private Sub myOlFolders_FolderAdd(ByVal Folder As Outlook.Folder)

 Folder.Display

End Sub
```

## See also

#### Concepts

[Folders Object](folders-object-outlook.md)

---
title: Conflicts Object (Outlook)
keywords: vbaol11.chm399
f1_keywords:
- vbaol11.chm399
ms.prod: outlook
api_name:
- Outlook.Conflicts
ms.assetid: c4e1c060-519a-a6d1-8fb2-c7dfa1e3e66f
ms.date: 06/08/2017
---

# Conflicts Object (Outlook)

Contains a collection of  **[Conflict](conflict-object-outlook.md)** objects that represent all Microsoft Outlook items that are in conflict with a particular Outlook item.

## Remarks

Use the  **[Conflicts](mailitem-conflicts-property-outlook.md)** property of any Outlook item, such as **[MailItem](mailitem-object-outlook.md)**, to return the **Conflicts** object.

Use the  **[Count](conflicts-count-property-outlook.md)** property of the **Conflicts** object to determine if the item is invloved in a conflict. A non-zero value indicates conflict.

Use the  **[Item](conflicts-item-method-outlook.md)** method to retrieve a particular conflict item from the **Conflicts** collection object.

Use the  **[GetFirst](conflicts-getfirst-method-outlook.md)**, **[GetNext](conflicts-getnext-method-outlook.md)**, **[GetPrevious](conflicts-getprevious-method-outlook.md)**, and **[GetLast](conflicts-getlast-method-outlook.md)** methods to traverse the **Conflicts** collection.

## Example

The following Microsoft Visual Basic for Applications (VBA) example uses the  **Count** property of the **Conflicts** object to determine if the item is involved in any conflict. To run this example, make sure an e-mail item is open in the active window.

```
Sub CheckConflicts()

 Dim myItem As Outlook.MailItem

 Dim myConflicts As Outlook.Conflicts

 Set myItem = Application.ActiveInspector.CurrentItem

 Set myConflicts = myItem.Conflicts

 If (myConflicts.Count > 0) Then

 MsgBox ("This item is involved in a conflict.")

 Else

 MsgBox ("This item is not involved in any conflicts.")

 End If

End Sub
```

## Methods

|**Name**|
|:-----|
|[GetFirst](conflicts-getfirst-method-outlook.md)|
|[GetLast](conflicts-getlast-method-outlook.md)|
|[GetNext](conflicts-getnext-method-outlook.md)|
|[GetPrevious](conflicts-getprevious-method-outlook.md)|
|[Item](conflicts-item-method-outlook.md)|

## Properties

|**Name**|
|:-----|
|[Application](conflicts-application-property-outlook.md)|
|[Class](conflicts-class-property-outlook.md)|
|[Count](conflicts-count-property-outlook.md)|
|[Parent](conflicts-parent-property-outlook.md)|
|[Session](conflicts-session-property-outlook.md)|

## See also

#### Other resources

[Outlook Object Model Reference](http://msdn.microsoft.com/library/73221b13-d8d8-99b8-3394-b95dbbfd5ddc%28Office.15%29.aspx)
---
title: ContactItem.User2 Property (Outlook)
keywords: vbaol11.chm1071
f1_keywords:
- vbaol11.


-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z"],redhat:[512,512,[],"f7bc","M341.52 285.56c33.65 0 82.34-6.94 82.34-47 .22-6.74.86-1.82-20.88-96.24-4.62-19.15-8.68-27.84-42.31-44.65-26.09-13.34-82.92-35.37-99.73-35.37-15.66 0-20.2 20.17-38.87 20.17-18 0-31.31-15.06-48.12-15.06-16.14 0-26.66 11-34.78 33.62-27.5 77.55-26.28 74.27-26.12 78.27 0 24.8 97.64 106.11 228.47 106.11M429 254.84c4.65 22 4.65 24.35 4.65 27.25 0 37.66-42.33 58.56-98 58.56-125.74.08-235.91-73.65-235.91-122.33a49.55 49.55 0 0 1 4.06-19.72C58.56 200.86 0 208.93 0 260.63c0 84.67 200.63 189 359.49 189 121.79 0 152.51-55.08 152.51-98.58 0-34.21-29.59-73.05-82.93-96.24"],yoast:[448,512,[],"f2b1","M91.3 76h186l-7 18.9h-179c-39.7 0-71.9 31.6-71.9 70.3v205.4c0 35.4 24.9 70.3 84 70.3V460H91.3C41.2 460 0 419.8 0


try.
  const { current, next } = calculateWriteKeys(spec, precision, now);

  const multi = redis.multi();

  // Remove this clientID from the current and next set.
  multi.srem(current, clientID); // O(1)
  multi.srem(next, clientID); // O(1)

  // Get the current count.
  multi.scard(current); // O(1)

  // Do this now.
  const [, , [, count]] = await multi.exec();

  logger.debug({ took: timer(), count, spec }, "removed story viewer");

  return count;
}

export async function countStoryViewers(
  redis: Redis,
  spec: KeySpec,
  precision: number,
  now = new Date()
) {
  const timer = createTimer();

  // Compute the key for this entry.
  const key = calculateReadKey(spec, precision, now);

  // Count the number of clientID's.
  const count = await redis.scard(key);

  logger.debug({ took: timer(), count, spec }, "counted story viewers");

  return count;
}
import { octagon } from "../../../fight/octagon"
import Fighter from "../../fighter"
import FighterFighting from "../../fighter-fighting/fighter-fighting"
import { fighterRetreatImplementation, maxNearEdgeDistance } from "../../fighter-fighting/fighter-retreat.i"
import Logistics from "../../fighter-fighting/logistics"
import Proximity, { getSmallestAngleBetween2Directions } from "../../fighter-fighting/proximity"

const {point1, point2} = octagon.edges.top
const topEdgeY = (point1.y + point2.y)/2
const topEdgeXMiddle = (point1.x + point2.x)/2

const mockFighting = {
  modelState: 'Idle',
  fighter: {skin: 'Default'},
  movement: {coords: {x: undefined, y: undefined}}
} as FighterFighting

const testFighter = {
  name: 'test fighter',
  fighting: mockFighting
} as Fighter

mockFighting.proximity = new Proximity(mockFighting)

mockFighting.movement.coords.y = topEdgeY - maxNearEdgeDistance + 10

const flanker1 = {
  fighting: {
    enemyTargetedForAttack: testFighter,
    movement: {
      coords: {x: undefined , y: undefined}
    },
    proximity : undefined
  }
} as Fighter
flanker1.fighting.proximity = new Proximity(flanker1.fighting)

const flanker2 = {
  fighting: {
    enemyTargetedForAttack: testFighter,
    movement: {
      coords: {x: undefined , y: undefined}
    },
    proximity : undefined
  }
} as Fighter

flanker2.fighting.proximity = new Proximity(flanker2.fighting)

jest
  .spyOn(Logistics.prototype, 'flanked', 'get')
  .mockImplementation(() => ({flankers: [flanker1, flanker2]}));

mockFighting.logistics = new Logistics(mockFighting)
console.log('flanked ', mockFighting.logistics.flanked)

const {
  publicProperties: {
    getDirectionBetweenFlankers
  },
  privateProperties: {
  }
} = fighterRetreatImplementation(mockFighting)

describe('getDirectionBetweenFlankers', () => {

  test(`
    when
      - flankers are same distance below
      - and; equal distance on either side
    expect
      - returned direction to be 180
  `, () => {

      testFighter.fighting.movement.coords = {
        x: topEdgeXMiddle,
        y: topEdgeY - (maxNearEdgeDistance * .9)
      }
      flanker1.fighting.movement.coords = {
        x: topEdgeXMiddle - 40,
        y: testFighter.fighting.movement


      }
      for (other in nearNodes) {
        segments.add(LineSegment(node.position, other.position))
      }
      return segments
    }

    // Define some sick FX
    val blur = ApproximateGaussianBlur().apply {
      window = 30
      sigma = 15.0
      spread = 5.0
      gain = 2.5
    }

    // Other cool blends include ColorDodge and Lighten - both subtly different but similar effects
    val blendFilter = Add()

    val rt = renderTarget(w, h, multisample = BufferMultisample.Disabled) {
      colorBuffer()
      depthBuffer()
    }

    var packed = PackCompleteResult(generateMovingBodies(nBodies, Vector2(w * 0.5, h * 0.5), 30.0))

    extend {
      // get that rng
      val rng = Random(seed.toLong())

      val sizeFn = { body: MovingBody ->
        val targetRadius = map(
          noiseRange.first, noiseRange.second,
          radiusRange.first, radiusRange.second,
          simplex(seed, body.position / noiseScale)
        )
        // technically the value will never "arrive" but it gets very close very fast so, y'know ... good enough for me!
        body.radius = abs(body.radius + targetRadius) / 2.0
      }

      // Using `incremental = false` will not return bodies until the packing is complete
      var lastTime = System.currentTimeMillis()
      packed = packCirclesControlled(
        bodies = packed.bodies,
        incremental = false, rng = rng, sizeFn = sizeFn
      )
      println("Circle packing complete. Took ${(System.currentTimeMillis() - lastTime) / 1000.0} seconds")
      lastTime = System.currentTimeMillis()

      val composite = compose {
        // A layer for the non-blurred things
        layer {
          draw {
            for ((index, body) in packed.bodies.withIndex()) {
              if (body.radius < 1.0) continue
              val shade =
                simplex(seed, Vector3(body.position.x, body.position.y, index.toDouble()) / noiseScale) * 0.5 + 0.5

              drawer.strokeWeight = 1.0
              drawer.stroke = spectrum.index(shade)
              drawer.circle(Circle(body.position, circleRadius))
              drawer.lineSegments(connectNodes(body, packed.bodies, 1.25))
            }
          }
        }

        // And a layer for the blurred things 😎
        layer {
          blend(blendFilter)
          draw {
            for ((index, body) in packed.bodies.withIndex()) {
              if (body.radius < 1.0) continue
              val shade = simplex(seed, Vector3(body.position.x, body.position.y, index.toDouble()) / noiseScale) * 0.5 + 0.5

              drawer.strokeWeight = 3.0
              drawer.stroke = spectrum.index(shade) // .opacify(0.1)
              drawer.lineSegments(connectNodes(body, packed.bodies, 1.25))
            }
          }
          post(blur)
        }
      }
      println("Composing layers complete. Took ${(System.currentTimeMillis() - lastTime) / 1000.0} seconds")

      // Render to the render target, save file, then scale and draw to screen
      drawer.isolatedWithTarget(rt) {
        drawer.ortho(rt)
        drawer.clear(ColorRGBa.BLACK)
        composite.draw(drawer)
      }

      val targetFile = File("screenshots/$progName/${timestamp()}-seed-$seed.png")
      targetFile.parentFile?.let { file ->
        if (!file.exists()) {
          fil


, 0x734a26dc54257410)
#define _m028 _SDK_MAGIC_PROPERTY(_SDK_ESCAPE(uint32_t), "_NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES.ContextBackFillSize", context_back_fill_size, 0x620, 0x20, true, 0xf2404344616cee93)
#define _m029 _SDK_MAGIC_PROPERTY(_SDK_ESCAPE(uint32_t*), "_NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES.SupportedOidList", supported_oid_list, 0x640, 0x40, true, 0x19a467f44e92a639)
#define _m030 _SDK_MAGIC_PROPERTY(_SDK_ESCAPE(uint32_t), "_NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES.SupportedOidListLength", supported_oid_list_length, 0x680, 0x20, true, 0xb87ec6b6eb159c2b)
#define _m031 _SDK_MAGIC_PROPERTY(_SDK_ESCAPE(uint32_t), "_NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES.AutoNegotiationFlags", auto_negotiation_flags, 0x6a0, 0x20, true, 0x6b1bf5edbd798b52)
#define _m032 _SDK_MAGIC_PROPERTY(_SDK_ESCAPE(struct ndis::pm_capabilities_t*), "_NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES.PowerManagementCapabilitiesEx", power_management_capabilities_ex, 0x6c0, 0x40, true, 0xe1e78ef2aa3aeff9)
#else
#define _m000
#define _m001
#define _m002
#define _m003
#define _m004
#define _m005
#define _m006
#define _m007
#define _m008
#define _m009
#define _m010
#define _m011
#define _m012
#define _m013
#define _m014
#define _m015
#define _m016
#define _m017
#define _m018
#define _m019
#define _m020
#define _m021
#define _m022
#define _m023
#define _m024
#define _m025
#define _m026
#define _m027
#define _m028
#define _m029
#define _m030
#define _m031
#define _m032
#endif#if !IN_PARSER
#define _m00 _SDK_MAGIC_PROPERTY(_SDK_ESCAPE(struct ndis::object_header_t), "_NDIS_RESTART_GENERAL_ATTRIBUTES.Header", header, 0x0, 0x20, true, 0xc575d7e827640cf4)
#define _m01 _SDK_MAGIC_PROPERTY(_SDK_ESCAPE(uint32_t), "_NDIS_RESTART_GENERAL_ATTRIBUTES.MtuSize", mtu_size, 0x20, 0x20, true, 0xee32c0988bed4cb8)
#define _m02 _SDK_MAGIC_PROPERTY(_SDK_ESCAPE(uint64_t), "_NDIS_RESTART_GENERAL_ATTRIBUTES.MaxXmitLinkSpeed", max_xmit_link_speed, 0x40, 0x40, true, 0x5870df3622a2c889)
#define _m03 _SDK_MAGIC_PROPERTY(_SDK_ESCAPE(uint64_t), "_NDIS_RESTART_GENERAL_ATTRIBUTES.MaxRcvLinkSpeed", max_rcv_link_speed, 0x80, 0x40, true, 0x6751b8ec4dd5396f)
#define _m04 _SDK_MAGIC_PROPERTY(_SDK_ESCAPE(uint32_t), "_NDIS_RESTART_GENERAL_ATTRIBUTES.LookaheadSize", lookahead_size, 0xc0, 0x20, true, 0x6f57878b6ad24775)
#define


/*
 *  (c) Copyright 1986 HEWLETT-PACKARD COMPANY
 *
 *  To anyone who acknowledges that this file is provided "AS IS"
 *  without any express or implied warranty:
 *      permission to use, copy, modify, and distribute this file
 *  for any purpose is hereby granted without fee, provided that
 *  the above copyright notice and this notice appears in all
 *  copies, and that the name of Hewlett-Packard Company not be
 *  used in advertising or publicity pertaining to distribution
 *  of the software without specific, written prior permission.
 *  Hewlett-Packard Company makes no representations about the
 *  suitability of this software for any purpose.
 */

/* HPUX_ID = "@(#) $Revision: 1.1 $" */
/* strlen(s): Return length of string s */

#define start   arg0
#define end     ret0
#define tmp1    arg1
#define tmp2    arg2

#include "DEFS.h"

ENTRY(strlen)
        movb,=,n        start,end,$null_ptr
        depi            0,31,2,end
        comb,<>         start,end,$not_aligned
        ldws,ma         4(end),tmp1
        comib,tr        0,0,$loop       /* avoid INDIGO two register interlock */
        uxor,nbz        0,tmp1,0
$not_aligned:
        /*
        ;       Tricky code.  The problem is that the value of of the word
        ;       including the start of the string has some garbage bytes that
        ;       may be 0.  We don't want them to stop the string scan.  So
        ;       we make those bytes non-zero (and any old non-zero value
        ;       will do).  Notice that the end pointer has been rounded
        ;       down to a word boundary, and then incremented to the next
        ;       word by the time we get here.  Therefore, (start-end)


r_status_changed=IS_NOT_MEMBER >> MEMBER
    )
)
async def bot_added_as_member(event: ChatMemberUpdated, bot: Bot):
    # Вариант посложнее: бота добавили как обычного участника.
    # Но может отсутствовать право написания сообщений, поэтому заранее проверим.
    chat_info = await bot.get_chat(event.chat.id)
    if chat_info.permissions.can_send_messages:
        await event.answer(
            text=f"Привет! Спасибо, что добавили меня в "
                 f'{chats_variants[event.chat.type]} "{event.chat.title}" '
                 f"как обычного участника. ID чата: {event.chat.id}"
        )
    else:
        print("Как-нибудь логируем эту ситуацию")
```

Но, как и всегда, есть нюанс, и чтобы его увидеть, надо добавить бота в группу,
а затем сконвертировать её в супергруппу. Для наглядности, я создал группу
со своим ботом [@my_id_bot](https://t.me/my_id_bot), а затем добавил туда тестового бота с кодом, описанным выше.
Внимание на картинку:

![конвертация группы в супергруппу](images/special-updates/group_supergroup.png)

Ой, почему-то бот отреагировал так, как будто его только что добавили, хотя вроде как ничего не изменилось.
На деле, конвертация группы в супергруппу для бота выглядит как добавление в новый чат. К счастью, в
этом случае боту также приходит Message с непустыми полями
`migrate_from_chat_id` и `migrate_to_chat_id`. А дальше дело за малым: при срабатывании события `my_chat_member`
на добавление в супергруппу проверять, что за последнее время (скажем, за пару секунд) не было сообщений
с непустым полем `migrate_to_chat_id`.

Решение практически полностью повторяет описанные выше примеры и более того, реализовано в моём [@my_id_bot](https://t.me/my_id_bot):
[вот так](https://github.com/MasterGroosha/my-id-bot/blob/17fa99945dd4eb186a7f2a200567829641edbe74/bot/handlers/add_or_migrate.py)
(звёздочки на гитхабе всячески приветствуются)

!!! info "Группы и супергруппы"
    Вопреки частому заблуждению, обычные группы по-прежнему существуют и никуда исчезать не собираются. Официальные
    клиенты Telegram исходно создают именно обычную группу, которая неявно при наступлении некоторого события
    конвертируется в супергруппу. И есть серьёзные подозрения, что такое поведение в ближайш


00054FAC  81 8C 00 A0 */	lwz r12, 0xa0(r12)
/* 80058070 00054FB0  7D 89 03 A6 */	mtctr r12
/* 80058074 00054FB4  4E 80 04 21 */	bctrl
/* 80058078 00054FB8  38 60 00 00 */	li r3, 0
.L_8005807C:
/* 8005807C 00054FBC  BB 41 00 08 */	lmw r26, 8(r1)
/* 80058080 00054FC0  80 01 00 24 */	lwz r0, 0x24(r1)
/* 80058084 00054FC4  7C 08 03 A6 */	mtlr r0
/* 80058088 00054FC8  38 21 00 20 */	addi r1, r1, 0x20
/* 8005808C 00054FCC  4E 80 00 20 */	blr
.endfn changeTexture__12J2DPictureExFPC7ResTIMGUcP10JUTPalette

.fn changeTexture__12J2DPictureExFPCcUcP10JUTPalette, global
/* 80058090 00054FD0  94 21 FF E0 */	stwu r1, -0x20(r1)
/* 80058094 00054FD4  7C 08 02 A6 */	mflr r0
/* 80058098 00054FD8  90 01 00 24 */	stw r0, 0x24(r1)
/* 8005809C 00054FDC  93 E1 00 1C */	stw r31, 0x1c(r1)
/* 800580A0 00054FE0  7C DF 33 78 */	mr r31, r6
/* 800580A4 00054FE4  93 C1 00 18 */	stw r30, 0x18(r1)
/* 800580A8 00054FE8  7C BE 2B 78 */	mr r30, r5
/* 800580AC 00054FEC  93 A1 00 14 */	stw r29, 0x14(r1)
/* 800580B0 00054FF0  7C 7D 1B 78 */	mr r29, r3
/* 800580B4 00054FF4  7C 83 23 78 */	mr r3, r4
/* 800580B8 00054FF8  4B FE 8A 25 */	bl getNameResource__9J2DScreenFPCc
/* 800580BC 00054FFC  81 9D 00 00 */	lwz r12, 0(r29)
/* 800580C0 00055000  7C 64 1B 78 */	mr r4, r3
/* 800580C4 00055004  7F A3 EB 78 */	mr r3, r29
/* 800580C8 00055008  7F C5 F3 78 */	mr r5, r30
/* 800580CC 0005500C  81 8C 01 18 */	lwz r12, 0x118(r12)
/* 800580D0 00055010  7F E6 FB 78 */	mr r6, r31
/* 800580D4 00055014  7D 89 03 A6 */	mtctr r12
/* 800580D8 00055018  4E 80 04 21 */	bctrl
/* 800580DC 0005501C  80 01 00 24 */	lwz r0, 0x24(r1)
/* 800580E0 00055020  83 E1 00 1C */	lwz r31, 0x1c(r1)
/* 800580E4 00055024  83 C1 00 18 */	lwz r30, 0x18(r1)
/* 800580E8 00055028  83 A1 00 14 */	lwz r29, 0x14(r1)
/* 800580EC 0005502C  7C 08 03 A6 */	mtlr r0
/* 800580F0 00055030  38 21 00 20 */	addi r1, r1, 0x20
/* 800580F4 00055034  4E 80 00 20 */	blr
.endfn changeTexture__12J2DPictureExFPCcUcP10JUTPalette


    }

    private fun getNutrientTotalFromMonth(
        nutrient: StatisticsNutrientType,
        month: Int
    ): HashMap<Int, Int> {
        val monthString = getMonthStringFromInt(month)
        val days = dayDao.getAllDaysInMonth(monthString) as ArrayList<Day>
        val values = hashMapOf<Int, Int>()
        // add empty entries
        for (day in days) {
            val t = day.getTotalNutrient(nutrient).roundToInt()
            values[day.date.day.toIntOrNull() ?: 1] = t
        }
        return values
    }

    private fun getMonthStringFromInt(month: Int): String {
        val monthString = month.toString()
        val monthInt = month + 1
        return if (monthString.length == 1) "0".plus(monthInt) else monthInt.toString()
    }

    fun updateProducts(day: Day) {
        products.postValue(day.getAllProducts())
    }

    private fun getDaysFromCurrentMonth(monthEnum: MonthEnum): Int {
        val calendar = Calendar.getInstance()
        calendar.set(currentYear, monthEnum.code, 1)
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
    }

    private fun setNewBarDataset(nutrientType: StatisticsNutrientType, monthEnum: MonthEnum) =
        CoroutineScope(Dispatchers.IO).launch {
            nutrient.postValue(nutrientType)
            monthPosition.postValue(monthEnum.code)
            barDataSet.postValue(
                BarDataSet(
                    getBarEntries(nutrientType, monthEnum),
                    nutrientType.name
                )
            )
        }

    fun setNewPieDataset(day: Day) {
        val entriesPie = arrayListOf<PieEntry>()
        val proteins = day.getTotalNutrient(StatisticsNutrientType.PROTEINS)
        val fats = day.getTotalNutrient(StatisticsNutrientType.FATS)
        val carbs = day.getTotalNutrient(StatisticsNutrientType.CARBS)
        // return if empty
        if ((proteins + fats + carbs).roundToInt() == 0) return
        entriesPie.add(PieEntry(proteins, "Proteins"))
        entriesPie.add(PieEntry(fats, "Fats"))
        entriesPie.add(PieEntry(carbs, "Carbs"))
        val pieDataSetV = PieDataSet(entriesPie, "")
        pieDataSetV.valueTextSize = 16f
        pieDataSetV.colors = getPieColors()
        pieDataSet.postValue(pieDataSetV)
    }

    private fun getPieColors(): MutableList<Int> {
        return mutableListOf(
            Color.parseColor("#EC6B56"),
            Color.parseColor("#FFC154"),
            Color.parseColor("#47B39C")
        )
    }

    private fun getBarEntries(
        nutrientType: StatisticsNutrientType,
        monthEnum: MonthEnum
    ): MutableList<BarEntry> {
        val arr = arrayListOf<BarEntry>()
        val daysInMonth = getDaysFromCurrentMonth(monthEnum)
        // add empty entries
        // start from 1 to display columns correctly
        for (i in 1 until daysInMonth + 1) {
            arr.add(BarEntry(i.toFloat(), 0f))
        }
        // fill up with real days
        try {
            val filledDays =
                getNutrientTotalFromMonth(nutrientType, monthEnum.code)
            filledDays.forEach {
                arr[it.key - 1] = BarEntry(it.key.toFloat(), it.value.toFloat())
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return arr
    }

    private fun getDefaultStatisticsNutrientType(): StatisticsNutrientType {
        return StatisticsNutrientType.values()[nutrient.value?.code


    await AudioTool.loadAll();
    inited = true;
  }

  ///初始化
  Future<void> onLoad() async {
    await init();
    final background = Background.create(gameRef.viewport);
    await gameRef.add(background);
    final deadLine = DeadLine.create(gameRef.viewport);
    await gameRef.add(deadLine);
    GameState.scoreComponent =
        Scores.create(gameRef.viewport, text: GameState.score.toString());
    await gameRef.add(GameState.scoreComponent);
    final settingButton = SettingButton.create(gameRef.viewport);
    await gameRef.add(settingButton);
    await GenerateBall(gameRef).generateBall();
    //初始化 game controllers
    await gameRef.add(UpdateBallsFalling());
    await gameRef.add(UpdateBallsBounce());
    await gameRef.add(UpdateLevelUp());
    await gameRef.add(UpdateDeadLine());
    await gameRef.add(UpdateGravity());
  }
}
import 'package:flame/game.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import '../game/my_game.dart';
import '../tools/navigator_tool.dart';
import '../tools/sensor_tool.dart';
import '../tools/system_tool.dart';

class GamePage extends StatefulWidget {
  final bool hide;
  GamePage({this.hide});
  @override
  _GamePageState createState() => _GamePageState();
}

class _GamePageState extends State<GamePage> {
  @override
  void initState() {
    super.initState();
    SensorTool.start();
  }

  @override
  void dispose() {
    SensorTool.stop();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: LayoutBuilder(
          builder: (_, constraints) {
            SystemTool.changeStatusBarColor();
            return GameWidget(
              game: MyGame(
                constraints.maxWidth,
                constraints.maxHeight,
                hide: widget.hide,
              ),
            );
          },
        ),
      ),
    );
  }
}
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui';

import 'package:flutter/services.dart';

import '../file_tool.dart';

class ImageCaches {
  final Map<String, _ImageLoader> _loadedFiles = {};

  void clear() {
    _loadedFiles.clear();
  }

  Image fromCache(String fileName) {
    final image = _loadedFiles[fileName];
    //todo default img
    return image?.loadedImage ?? _loadedFiles.values.first.loadedImage;
  }

  Future<Image> loadBytes(String path, Uint8List bytes) async {
    _loadedFiles[path] = _ImageLoader(_loadBytes(bytes));
    return await _loadedFiles[path].retrieve();
  }

  Future<Image> loadImage(String path, Image img) async {
    _loadedFiles[path] = _ImageLoader(Future.value(img));
    return await _loadedFiles[path].retrieve();
  }

  Future<List<Image>> loadAll(List<String> fileNames) async {
    return Future.wait(fileNames.map(load));
  }

  Future<Image> load(String fileName) async {
    return fileName.startsWith('/') ? fromFile(fileName) : fromBundle(fileName);
  }

  Future<Image> fromBundle(String fileName) async {
    if (!_loadedFiles.containsKey(fileName)) {
      _loadedFiles[fileName] = _ImageLoader(_fetchToMemory(fileName));
    }
    return await _loadedFiles[fileName].retrieve();
  }

  Future<Image> fromFile(String path) async {


 then t[k4] = v4
			if k5 then t[k5] = v5
			if k6 then t[k6] = v6
			if k7 then t[k7] = v7
			if k8 then t[k8] = v8
			if k9 then t[k9] = v9
			if k10 then t[k10] = v10
			if k11 then t[k11] = v11
			if k12 then t[k12] = v12
			if k13 then t[k13] = v13
			if k14 then t[k14] = v14
			if k15 then t[k15] = v15
			if k16 then t[k16] = v16
			if k17 then t[k17] = v17
			if k18 then t[k18] = v18
			if k19 then t[k19] = v19
			if k20 then t[k20] = v20
			end end end end end end end end end end end end end end end end end end end end
		end
		return t
	end
	if lua51 then
		tmp = loadstring("local t = {}; return function(...) for k in pairs(t) do t[k] = nil end; for i = 1, select('#', ...), 2 do if select(i, ...) then t[select(i, ...)] = select(i+1, ...) else break; end; end; return t; end")()
	end
end
local tmp2
do
	local t = {}
	function tmp2(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20)
		for k in pairs(t) do
			t[k] = nil
		end
		if k1 then t[k1] = v1
		if k2 then t[k2] = v2
		if k3 then t[k3] = v3
		if k4 then t[k4] = v4
		if k5 then t[k5] = v5
		if k6 then t[k6] = v6
		if k7 then t[k7] = v7
		if k8 then t[k8] = v8
		if k9 then t[k9] = v9
		if k10 then t[k10] = v10
		if k11 then t[k11] = v11
		if k12 then t[k12] = v12
		if k13 then t[k13] = v13
		if k14 then t[k14] = v14
		if k15 then t[k15] = v15
		if k16 then t[k16] = v16
		if k17 then t[k17] = v17
		if k18 then t[k18] = v18
		if k19 then t[k19] = v19
		if k20 then t[k20] = v20
		end end end end end end end end end end end end end end end end end end end end
		return t
	end
	if lua51 then
		tmp2 = loadstring("local t = {}; return function(...) for k in pairs(t) do t[k] = nil end; for i = 1, select('#', ...), 2 do if select(i, ...) then t[select(i, ...)] = select(i+1, ...) else break; end; end; return t; end")()
	end
end
local levels
local buttons

local function GetScaledCursorPosition()
	local x, y = GetCursorPosition()
	local scale = UIParent:GetEffectiveScale()
	return x / scale, y / scale
end

local function StartCounting(self, levelNum)
	for i = levelNum, table.


Detail = str.Trim();

            // 修改性别数据，1男0女，而本地是1男2女
            if (dic.TryGetValue("sex", out str)) Sex = str.ToInt() == 1 ? 1 : 2;

            // small image: http://tb.himg.baidu.com/sys/portraitn/item/{$portrait}
            // large image: http://tb.himg.baidu.com/sys/portrait/item/{$portrait}
            if (dic.TryGetValue("portrait", out str)) Avatar = "http://tb.himg.baidu.com/sys/portrait/item/" + str.Trim();

            // 百度升级协议后，用户名带有星号，不能要
            if (!UserName.IsNullOrEmpty() && UserName.Contains("*"))
            {
                if (NickName.IsNullOrEmpty()) NickName = UserName;
                UserName = null;
            }

            // 生日
            if (dic.TryGetValue("birthday", out str))
            {
                var dt = str.ToDateTime();
                if (dt.Year > 1000) Birthday = dt;
            }
        }

        ///// <summary>根据授权码获取访问令牌</summary>
        ///// <param name="code"></param>
        ///// <returns></returns>
        //public override String GetAccessToken(String code)
        //{
        //    var html = base.GetAccessToken(code);

        //    var dic = Items;
        //    if (dic.TryGetValue("error", out var error)) throw new Exception($"{error} {dic["error_description"]}");

        //    return html;
        //}
    }
}


/tr>

        {% if promotedRequests %}
        {% for elem in promotedRequests %}

            {{elem.fullname}}
            {{elem.shortIdentifier}}
            {{elem.licenseAuthorName}}
            {{elem.submissionDatetime}}

              {% csrf_token %}
              <button id='unarchive_button{{elem.id}}' class='btn btn-success' width='25px' value='Unarchive'>Unarchive</button>

        {% endfor %}
        {% endif %}

{% include "app/modal.html" %}

{% endblock %}
{% block script_block %}

{% endblock %}
{% extends 'app/base.html' %}
{% load static %}
{% block body1 %}

 {{ error1 }}

 {{ error2 }}

Join the community

{{ invalid }}</


mall) {
		h1 {
			font-size: 2em;
		}

		h2 {
			font-size: 1.5em;
		}

		h3 {
			font-size: 1.25em;
		}
	}

	sub {
		font-size: 0.8em;
		position: relative;
		top: 0.5em;
	}

	sup {
		font-size: 0.8em;
		position: relative;
		top: -0.5em;
	}

	blockquote {
		border-left: solid 4px _palette(border);
		font-style: italic;
		margin: 0 0 _size(element-margin) 0;
		padding: (_size(element-margin) / 4) 0 (_size(element-margin) / 4) _size(element-margin);
	}

	code {
		background: _palette(border-bg);
		font-family: _font(family-fixed);
		font-size: 0.9em;
		margin: 0 0.25em;
		padding: 0.25em 0.65em;
	}

	pre {
		-webkit-overflow-scrolling: touch;
		font-family: _font(family-fixed);
		font-size: 0.9em;
		margin: 0 0 _size(element-margin) 0;

		code {
			display: block;
			line-height: 1.75;
			padding: 1em 1.5em;
			overflow-x: auto;
		}
	}

	hr {
		border: 0;
		border-bottom: solid 1px _palette(border);
		margin: _size(element-margin) 0;

		&.major {
			margin: (_size(element-margin) * 1.5) 0;
		}
	}

	.align-left {
		text-align: left;
	}

	.align-center {
		text-align: center;
	}

	.align-right {
		text-align: right;
	}///
/// Forty by HTML5 UP
/// html5up.net | @ajlkn
/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
///

/* Menu */

	#menu {
		@include vendor('transition', (
			'transform #{_duration(menu)} ease',
			'opacity #{_duration(menu)} ease',
			'visibility #{_duration(menu)}'
		));
		@include vendor('align-items', 'center');
		@include vendor('display', 'flex');
		@include vendor('justify-content', 'center');
		@include vendor('pointer-events', 'none');
		background: transparentize(_palette(bg), 0.1);
		box-shadow: none;
		height: 100%;
		left: 0;
		opacity: 0;
		overflow: hidden;
		padding: 3em 2em;
		position: fixed;
		top: 0;
		visibility: hidden;
		width: 100%;
		z-index: _misc(z-index-base) + 2;

		.inner {
			@include vendor('transition', (
				'transform #{_duration(menu)} ease-out',
				'opacity #{_duration(menu)} ease',
				'visibility #{_duration(menu)}'
			));
			@include vendor('transform', 'rotateX(20deg)');
			-webkit-overflow-scrolling: touch;
			max-width: 100%;
			max-height: 100vh;
			opacity: 0;
			overflow: auto;
			text-align: center;
			visibility: hidden;
			width: 18em;

			> :first-child {
				margin-top: _size(element-margin);
			}

			> :last-child {
				margin-bottom: (_size(element-margin) * 1.5);
			}
		}

		ul {
			margin: 0 0 (_size(element-margin) * 0.5) 0;

			&.links {
				list-style: none;


// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the License.txt file in the project root for more information.

using System;

namespace TestUtilities
{
    /// <summary>
    /// Encapsulates exit code and output/error streams of a process.
    /// </summary>
    public sealed class ProcessResult
    {
        public int ExitCode { get; }
        public string Output { get; }
        public string Errors { get; }

        public ProcessResult(int exitCode, string output, string errors)
        {
            ExitCode = exitCode;


d == completed]

# Пример использования
if __name__ == "__main__":
    task_list = TaskList()

    task1 = Task("Write report", priority=2)
    task_list.add_task(task1)
    task2 = Task("Buy groceries", priority=1)
    task_list.add_task(task2)
    task3 = Task("Call client", priority=3, deadline=datetime.datetime(2023, 10, 1))
    task_list.add_task(task3)

    task_list.sort_by_priority()

    print("All Tasks:")
    for task in task_list.tasks:
        print(task)

    task2.mark_completed()

    completed_tasks = task_list.filter_by_status(completed=True)
    print("Completed Tasks:")
    for task in completed_tasks:
        print(task)

    print("Updated Task List:")
    for task in task_list.tasks:
        print(task)
```

Проведите тестирование для алгоритма, используемого в системе управления задачами.

Требования к тестам:

1. **Тест инициализации задачи `test_task_initialization`**:
    - Создать экземпляр задачи с описанием, полученным из параметризованной фикстуры `sample_task`.
    - Убедиться, что приоритет равен `1`, дедлайн не установлен и задача не помечена как завершенная.

2. **Тест отметки задачи как выполненной `test_mark_completed`**:
    - Создать экземпляр задачи с описанием, полученным из параметризованной фикстуры `sample_task`.
    - Вызвать метод `mark_completed()` для того, чтобы отметить задачу как выполненную.
    - Убедиться, что статус выполнения изменился на "Выполнено".

3. **Тест установки дедлайна для задачи `test_set_deadline`:**
    - Создать экземпляр задачи с описанием, полученным из параметризованной фикстуры `sample_task`.
    - Установить `deadline` для задачи, используя модуль `datetime`.
    - Установить дедлайн для задачи с использованием метода `set_deadline()` и передать в него созданный объект дедлайна `deadline`.
    - Проверить, что дедлайн задачи `sample_task` теперь соответствует установленному дедлайну `deadline`.

4. **Тест строкового представления задачи `test_task_string_representation`**:
    - Создать экземпляр задачи с описанием, полученным из параметризованной фикстуры `sample_task`.
    - Убедиться, что строковое представление задачи `str(sample_task)` соответствует ожидаемому формату, который создается на основе атрибутов задачи:
    ```
    "Description: [описание]
     Priority: 1
     Status: Not Completed
     No Deadline"
    ```

5. **Тест инициализации списка задач `test_tasklist_initialization`**:
    - Создать пустой список задач `TaskList`.
    - Убедиться, что список задач пуст.


 = 'shenanigans!'

        original_other_namespace_value = self.admin.assert_icommand(
            ['iadmin', 'get_grid_configuration', other_namespace, option_name], 'STDOUT')[1].strip()

        _, out, _ = self.admin.assert_icommand(
            ['iadmin', 'set_grid_configuration', namespace, option_name, option_value], 'STDERR',
            f'Failed to set grid configuration for namespace [{namespace}] and option [{option_name}] [ec=-169000]')
        self.assertIn('Specified grid configuration is not allowed to be modified.', out)

        # Assert that the value was appropriately not updated in the other namespace.
        self.assertEqual(
            original_other_namespace_value,
            self.admin.assert_icommand(
                ['iadmin', 'get_grid_configuration', other_namespace, option_name], 'STDOUT')[1].strip())

    def test_set_database_schema_version_is_disallowed(self):
        namespace = 'database'
        option_name = 'schema_version'
        option_value = '9001'

        original_value = self.admin.assert_icommand(
            ['iadmin', 'get_grid_configuration', namespace, option_name], 'STDOUT')[1].strip()

        # Make sure the value is not set to our ridiculous test value.
        self.assertNotEqual(option_value, original_value)

        _, out, _ = self.admin.assert_icommand(
            ['iadmin', 'set_grid_configuration', namespace, option_name, option_value], 'STDERR',
            f'Failed to set grid configuration for namespace [{namespace}] and option [{option_name}] [ec=-169000]')
        self.assertIn('Specified grid configuration is not allowed to be modified.', out)

        # Assert that the value was appropriately not updated.
        self.assertEqual(
            original_value,
            self.admin.assert_icommand(['iadmin', 'get_grid_configuration', namespace, option_name], 'STDOUT')[1].strip())

    @unittest.skip('This situation cannot happen with the current protected configs. Write this test if/when it can.')
    def test_set_mutable_grid_configuration_with_option_name_that_is_protected_in_another_namespace(self):
        # This is the situation:
        #   R_GRID_CONFIGRUATION
        #                   namespace           |       option_name        | option_value
        #         ------------------------------+--------------------------+--------------
        #          namespace1                   | option1                  | will_not_change
        #          namespace1                   | option2                  | can_change
        #          namespace2                   | option1                  | can_change
        #          namespace2                   | option2                  | will_not_change
        #
        #   Here is the deny list:
        #       | namespace  | option_name |
        #       | ---------- | ----------- |
        #       | namespace1 | option1     |
        #       | namespace2 | option2     |
        #
        #   And then this is run:
        #   $ iadmin set_grid_configuration namespace2 option1 what_happens_now
        #
        #   Only option2 is protected for namespace namespace2. Need to make sure that option1 is allowed to be modified
        #   even though it is in the deny list for the namespace1 namespace.
        pass


 Uint8List serverKexInit,
    required Uint8List hostKey,
    required Uint8List clientPublicKey,
    required Uint8List serverPublicKey,
    required BigInt sharedSecret,
  }) {
    final writer = SSHMessageWriter();
    writer.writeUtf8(clientVersion);
    writer.writeUtf8(serverVersion);
    writer.writeString(clientKexInit);
    writer.writeString(serverKexInit);
    writer.writeString(hostKey);

    if (groupExchange != null) {
      writer.writeUint32(SSHKexDH.gexMin);
      writer.writeUint32(SSHKexDH.gexPref);
      writer.writeUint32(SSHKexDH.gexMax);
      writer.writeMpint(groupExchange.p);
      writer.writeMpint(groupExchange.g);
    }

    writer.writeString(clientPublicKey);
    writer.writeString(serverPublicKey);
    writer.writeMpint(sharedSecret);

    final message = writer.takeBytes();
    digest.update(message, 0, message.length);
    final result = Uint8List(digest.digestSize);
    digest.doFinal(result, 0);
    return result;
  }

  /// Derive various keys from the exchange hash.
  static Uint8List deriveKey({
    required Digest digest,
    required BigInt sharedSecret,
    required Uint8List exchangeHash,
    required SSHDeriveKeyType keyType,
    required Uint8List sessionId,
    required int keySize,
  }) {
    final result = BytesBuilder(copy: false);

    while (result.length < keySize) {
      final writer = SSHMessageWriter();
      writer.writeMpint(sharedSecret);
      writer.writeBytes(exchangeHash);
      if (result.isEmpty) {
        writer.writeUint8(keyType.magicChar);
        writer.writeBytes(sessionId);
      } else {
        writer.writeBytes(result.toBytes());
      }

      final dataToHash = writer.takeBytes();
      // final digester = SHA256Digest();
      digest.update(dataToHash, 0, dataToHash.length);
      final hash = Uint8List(digest.digestSize);
      digest.doFinal(hash, 0);
      result.add(hash);
    }

    return Uint8List.sublistView(result.takeBytes(), 0, keySize);
  }
}

enum SSHDeriveKeyType {
  clientIV,
  serverIV,
  clientKey,
  serverKey,
  clientMacKey,
  serverMacKey,
}

extension SSHDeriveKeyTypeX on SSHDeriveKeyType {
  /// The magic character used in ke derivation.
  int get magicChar {
    switch (this) {
      case SSHDeriveKeyType.clientIV:
        return 'A'.codeUnits.first;
      case SSHDeriveKeyType.serverIV:
        return 'B'.codeUnits.first;
      case SSHDeriveKeyType.clientKey:
        return 'C'.codeUnits.first;
      case SSHDeriveKeyType.serverKey:
        return 'D'.codeUnits.first;
      case SSHDeriveKeyType.clientMacKey:
        return 'E'.codeUnits.first;
      case SSHDeriveKeyType.serverMacKey:
        return 'F'.codeUnits.first;
    }
  }
}
import 'package:dartssh2/src/http/http_content_type.dart';

/// Headers for HTTP requests and responses.
///
/// In some situations, headers are immutable:
///
/// * [HttpRequest] and [HttpClientResponse] always have immutable headers.
///
/// * [HttpResponse] and [HttpClientRequest] have immutable headers
///   from the moment the body is written to.
///
/// In these situations, the mutating methods throw exceptions.
///
/// For all operations on HTTP headers the header name is
/// case-insensitive.
///
/// To set the value of a header use the `set()` method:
///
///     request.headers.set(HttpHeaders.cacheControlHeader,
///                         'max-age=3600, must-revalidate');
///
/// To retrieve the value of a header use the `value()` method:
///
///     print(request.headers.value(HttpHeaders.userAgentHeader));
///
/// An `HttpHeaders` object holds a list of values for each name
/// as


ATION",
        CL_INVALID_GL_OBJECT => "CL_INVALID_GL_OBJECT",
        CL_INVALID_BUFFER_SIZE => "CL_INVALID_BUFFER_SIZE",
        CL_INVALID_MIP_LEVEL => "CL_INVALID_MIP_LEVEL",
        CL_INVALID_GLOBAL_WORK_SIZE => "CL_INVALID_GLOBAL_WORK_SIZE",
        CL_INVALID_PROPERTY => "CL_INVALID_PROPERTY",
        CL_INVALID_IMAGE_DESCRIPTOR => "CL_INVALID_IMAGE_DESCRIPTOR",
        CL_INVALID_COMPILER_OPTIONS => "CL_INVALID_COMPILER_OPTIONS",
        CL_INVALID_LINKER_OPTIONS => "CL_INVALID_LINKER_OPTIONS",
        CL_INVALID_DEVICE_PARTITION_COUNT => "CL_INVALID_DEVICE_PARTITION_COUNT",
        CL_INVALID_PIPE_SIZE => "CL_INVALID_PIPE_SIZE",
        CL_INVALID_DEVICE_QUEUE => "CL_INVALID_DEVICE_QUEUE",
        CL_INVALID_SPEC_ID => "CL_INVALID_SPEC_ID",
        CL_MAX_SIZE_RESTRICTION_EXCEEDED => "CL_MAX_SIZE_RESTRICTION_EXCEEDED",

        CL_PLATFORM_NOT_FOUND_KHR => "CL_PLATFORM_NOT_FOUND_KHR",

        _ => "UNKNOWN_ERROR",
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_error_text() {
        let cl_success_text = error_text(CL_SUCCESS);
        assert_eq!("CL_SUCCESS", cl_success_text);

        let cl_device_not_found_text = error_text(CL_DEVICE_NOT_FOUND);
        assert_eq!("CL_DEVICE_NOT_FOUND", cl_device_not_found_text);

        let cl_max_size_restriction_exceeded_text = error_text(CL_MAX_SIZE_RESTRICTION_EXCEEDED);
        assert_eq!(
            "CL_MAX_SIZE_RESTRICTION_EXCEEDED",
            cl_max_size_restriction_exceeded_text
        );

        let cl_platform_not_found_khr_text = error_text(CL_PLATFORM_NOT_FOUND_KHR);
        assert_eq!("CL_PLATFORM_NOT_FOUND_KHR", cl_platform_not_found_khr_text);

        let unknown_error_text = error_text(CL_MAX_SIZE_RESTRICTION_EXCEEDED - 1);
        assert_eq!("UNKNOWN_ERROR", unknown_error_text);
    }
}
<filename>src/optimal_plan.rs
use model::{
    Unit,
};

#[cfg(all(feature = "enable_debug", feature = "enable_debug_optimal_plan"))]
use model::{
    ColorF32,
    CustomData,
};

use crate::my_strategy::{
    SIMULATOR_DEFAULT_FLAGS,
    Debug,
    Plan,
    Planner,
    Positionable,
    Simulator,
    Vec2,
    World,
    XorShiftRng,
};

#[cfg(all(feature = "enable_debug", feature = "enable_debug_optimal_plan"))]
use crate::my_strategy::{
    Location,
    Rectangular,
};

#[inline(never)]
pub fn get_optimal_plan(current_unit: &Unit, global_destination: Vec2, world: &World,
        rng: &mut XorShiftRng, debug: &mut Debug) -> Plan {
    let tiles_path = world.find_shortcut_tiles_path(current_unit.id, current_unit.location(), global_destination.as_location());

    #[cfg(all(feature = "enable_debug", feature = "enable_debug_optimal_plan"))]
    render_tiles_path(current_unit, &tiles_path, debug);

    let local_destination = if !tiles_path.is_empty() {
        tiles_path[0].bottom()


 Trom / STpt",
        "021. Trom / HTpt",
        "022. Trom / Sax",
        "023. Farfisa",
        "024. CP-70",
        "025. CP-70Mello",
        "026. CP-70 Brite",
        "027. Piano Bass",
        "028. Wurlitzer1",
        "029. Wurlitzer2",
        "030. DynoRhodes1",
        "031. DynoRhodes2",
        "032. FendrRhodes",
        "033. Clavinet",
        "034. Brite Clav",
        "035. Mini Moog 1",
        "036. Mini Moog 2",
        "037. Mini Moog 3",
        "038. Mini Moog 4",
        "039. Mini Moog 5",
        "040. Mini Moog 6",
        "041. Micro Moog",
        "042. TaurusPedal",
        "043. Jaco Bass",
        "044. M12 Lead 1",
        "045. M12 Lead 2",
        "046. ARP 2600",
        "047. RockDXman",
        "048. P5 SyncLead",
        "049. Moog 55 Rez",
        "050. Memory Moog",
        "051. OBX Saws",
        "052. P5GuitarPad",
        "053. Matrix Pad",
        "054. P5 Piper",
        "055. P5 Strings",
        "056. M12 Strings",
        "057. ARP Strings",
        "058. AAAHs",
        "059. Picked Bass",
        "060. Finger Bass",
        "061. Finger Tre",
        "062. Pickd 8 Top",
        "063. Fingr 8 Top",
        "064. Fingr 8 Tre",
        "065. The Guitar",
        "066. Twelv Top 1",
        "067. Twelv Top 2",
        "068. Twelv Top 3",
        "069. Drum Kit 1",
        "070. Drum Kit 2",
        "071. Drum Kit 3",
        "072. Drum Kit 4",
        "073. Drum Kit 5",
        "074. Drum Kit 6",
        "075. Drum Kit 7",
        "076. Large Hall",
        "077. Medium Room",
        "078. Tiled Room",
        "079. Gated Short",
        "080. Gated Long1",
        "081. Gated Long2",
        "082. Lush Reverb",
        "083. BlushReverb",
        "084. FullOn Verb",
        "085. Dry Kick",
        "086. Kick Verb",
        "087. Dry Snare",
        "088. Snare Verb",
        "089. Dry Tom",
        "090. Wet Tom",
        "091. High Hat 1",
        "092. High Hat 2",
        "093. High Hat 3",
        "094. Ride Ping",
        "095. Ride Bell",
        "096. Crash",
        "097. Cowbell",
        "098. Tambourine",
        "099. Side Stick",
        "100. Clave",
        "101. Square",
        "102. Sawtooth",
        "103. Triangle",
        "104. Moog Saw 1",
        "105. Moog Saw 2",
        "106. Moog Saw 3",
        "107. Moog Saw 4",
        "108. Moog Sqr 1",
        "109. Moog Sqr 2",
        "110. Moog Sqr 3",
        "111. Moog Sqr 4",
        "112. Moog Sqr 5",
        "113. Moog Sqr 6",
        "114. Moog Rect 1",
        "115. Moog Rect 2",
        "116. Moog Rect 3",
        "117. Moog Rect 4",
        "118. Moog Rect 5",
        "119. Moog Pulse1",
        "120. Moog Pulse2",
        "121. Moog Pulse3",
        "122. Moog Pulse4",
        "123. Moog Pulse5",


  .gridle-debug .push-tablet-9:after, .push-tablet-9.gridle-debug:after { content: "push-tablet-9" !important; }
  .pull-tablet-9 { right: 75.0%; }
  .gridle-debug .pull-tablet-9:after, .pull-tablet-9.gridle-debug:after { content: "pull-tablet-9" !important; }
  .prefix-tablet-9 { margin-left: 75.0%; }
  .gridle-debug .prefix-tablet-9:after, .prefix-tablet-9.gridle-debug:after { content: "prefix-tablet-9" !important; }
  .suffix-tablet-9 { margin-right: 75.0%; }
  .gridle-debug .suffix-tablet-9:after, .suffix-tablet-9.gridle-debug:after { content: "suffix-tablet-9" !important; }
  .grid-tablet-10 { width: 83.33333%; *width: expression((this.parentNode.clientWidth/12*10 - parseInt(this.currentStyle['paddingLeft']) - parseInt(this.currentStyle['paddingRight'])) + 'px'); }
  .gridle-debug .grid-tablet-10:before, .grid-tablet-10.gridle-debug:before { content: "grid-tablet-10"; }
  .gridle-debug .grid-tablet-10.parent:before, .grid-tablet-10.gridle-debug.parent:before { content: "grid-parent-tablet-10"; }
  .push-tablet-10 { left: 83.33333%; }
  .gridle-debug .push-tablet-10:after, .push-tablet-10.gridle-debug:after { content: "push-tablet-10" !important; }
  .pull-tablet-10 { right: 83.33333%; }
  .gridle-debug .pull-tablet-10:after, .pull-tablet-10.gridle-debug:after { content: "pull-tablet-10" !important; }
  .prefix-tablet-10 { margin-left: 83.33333%; }
  .gridle-debug .prefix-tablet-10:after, .prefix-tablet-10.gridle-debug:after { content: "prefix-tablet-10" !important; }
  .suffix-tablet-10 { margin-right: 83.33333%; }
  .gridle-debug .suffix-tablet-10:after, .suffix-tablet-10.gridle-debug:after { content: "suffix-tablet-10" !important; }
  .grid-tablet-11 { width: 91.66667%; *width: expression((this.parentNode.clientWidth/12*11 - parseInt(this.currentStyle['paddingLeft']) - parseInt(this.currentStyle['paddingRight'])) + 'px'); }
  .gridle-debug .grid-tablet-11:before, .grid-tablet-11.gridle-debug:before { content: "grid-tablet-11"; }
  .gridle-debug .grid-tablet-11.parent:before, .grid-tablet-11.gridle-debug.parent:before { content: "grid-parent-tablet-11"; }
  .push-tablet-11 { left: 91.66667%; }
  .gridle-debug .push-tablet-11:after, .push-tablet-11.gridle-debug:after { content: "push-tablet-11" !important; }
  .pull-tablet-11 { right: 91.66667%; }
  .gridle-debug .pull-tablet-11:after, .pull-tablet-11.gridle-debug:after { content: "pull-tablet-11" !important; }
  .prefix-tablet-11 { margin-left: 91.66667%; }
  .gridle-debug .prefix-tablet-11:after, .prefix-tablet-11.gridle-debug:after { content: "prefix-tablet-11" !important; }


 normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/s/notoserifkr/v28/3JnoSDn90Gmq2mr3blnHaTZXbOtLJDvui3JOncjmeM5z4ZvTefxutxWKI13DA9agQzxl4iCfvB7KDWw.97.woff2)
    format("woff2");
  unicode-range:
    U+2479-2487, U+249c-24d1, U+24d3-24d7, U+24d9-24e9, U+24eb-24f4,
    U+2500-2501, U+2503, U+250c-2513, U+2515-2516, U+2518-2540;
}
/* [98] */
@font-face {
  font-family: "Noto Serif KR";
  font-style: normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/s/notoserifkr/v28/3JnoSDn90Gmq2mr3blnHaTZXbOtLJDvui3JOncjmeM5z4ZvTefxutxWKI13DA9agQzxl4iCfvB7KDWw.98.woff2)
    format("woff2");
  unicode-range:
    U+215b-215e, U+2162-2169, U+2170-2179, U+2195-2199, U+21b0-21b4, U+21bc,
    U+21c0, U+21c4-21c5, U+21cd, U+21cf-21d4, U+21e0-21e3, U+21e6-21e9, U+2200,
    U+2202-2203, U+2206-2209, U+220b-220c, U+220f, U+2211, U+2213, U+221a,
    U+221d-2220, U+2222, U+2225-2227, U+2229-222c, U+222e, U+2234-2237, U+223d,
    U+2243, U+2245, U+2248, U+2250-2253, U+225a, U+2260-2262, U+2264-2267,
    U+226a-226b, U+226e-2273, U+2276-2277, U+2279-227b, U+2280-2287,
    U+228a-228b, U+2295-2297, U+22a3-22a5, U+22bb-22bc, U+22ce-22cf,
    U+22da-22db, U+22ee-22ef, U+2306, U+2312, U+2314, U+2467-2478;
}
/* [99] */
@font-face {
  font-family: "Noto Serif KR";
  font-style: normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/s/notoserifkr/v28/3JnoSDn90Gmq2mr3blnHaTZXbOtLJDvui3JOncjmeM5z4ZvTefxutxWKI13DA9agQzxl4iCfvB7KDWw.99.woff2)
    format("woff2");
  unicode-range:
    U+81-82, U+84, U+a2-a5, U+a7-a8, U+aa, U+ac-ad, U+b1-b3, U+b6, U+b8-ba,
    U+bc-be, U+c0, U+c2, U+c6-cb,


      ComparisonOp::StartsWith,
                vec![BString::from("foobar")]
            )
        );

        Ok(())
    }

    #[test]
    fn test_parse_subfield_matcher_comparison_ends_with() -> TestResult {
        assert_eq!(
            parse_subfield_matcher_comparison(b"a =$ 'foobar'")?.1,
            SubfieldMatcher::Comparison(
                vec!['a'],
                ComparisonOp::EndsWith,
                vec![BString::from("foobar")]
            )
        );

        Ok(())
    }

    #[test]
    fn test_parse_subfield_matcher_regex() -> TestResult {
        assert_eq!(
            parse_subfield_matcher_regex(b"a =~ '^(foo|bar)$'")?.1,
            SubfieldMatcher::Comparison(
                vec!['a'],
                ComparisonOp::Re,
                vec![BString::from("^(foo|bar)$")]
            )
        );

        assert!(parse_subfield_matcher_regex(b"0 =~ '^Tp[123]($'").is_err());

        Ok(())
    }

    #[test]
    fn test_parse_subfield_matcher_in() -> TestResult {
        assert_eq!(
            parse_subfield_matcher_in(b"0 in [ '123'  , '456' ] ")?.1,
            SubfieldMatcher::Comparison(
                vec!['0'],
                ComparisonOp::In,
                vec![BString::from("123"), BString::from("456")]
            )
        );

        assert_eq!(
            parse_subfield_matcher_in(b"0 not in ['123', '456']")?.1,
            SubfieldMatcher::Not(Box::new(SubfieldMatcher::Comparison(
                vec!['0'],
                ComparisonOp::In,
                vec![BString::from("123"), BString::from("456")]
            )))
        );

        assert!(parse_subfield_matcher_in(b"0 in []").is_err());

        Ok(())
    }

    #[test]
    fn test_parse_subfield_matcher_exists() -> TestResult {
        assert_eq!(
            parse_subfield_matcher_exists(b" 0? ")?.1,
            SubfieldMatcher::Exists(vec!['0'])
        );

        assert_eq!(
            parse_subfield_matcher_exists(b"[ab]?")?.1,
            SubfieldMatcher::Exists(vec!['a', 'b'])
        );

        Ok(())
    }

    #[test]
    fn test_parse_subfield_matcher_group() -> TestResult {
        assert_eq!(
            parse_subfield_matcher_group(b" ( 0? ) ")?.1,
            SubfieldMatcher::Group(Box::new(SubfieldMatcher::Exists(vec![
                '0'
            ])))
        );

        assert_eq!(
            parse_subfield_matcher_group(b" ( (0?) ) ")?.1,
            SubfieldMatcher::Group(Box::new(SubfieldMatcher::Group(Box::new(
                SubfieldMatcher::Exists(vec!['0'])
            ))))
        );

        assert!(parse_subfield_matcher_group(b"((0?)").is_err());

        Ok(())
    }

    #[test]
    fn test_parse_subfield_matcher_not() -> TestResult {
        assert_eq!(
            parse_subfield_matcher_not(b" !0? ")?.1,
            SubfieldMatcher::Not(Box::new(SubfieldMatcher::Exists(vec!['0'])))
        );

        assert_eq!(
            parse_subfield_matcher_not(b" !(0?) ")?.1,
            SubfieldMatcher::Not(Box::new(SubfieldMatcher::Group(Box::new