oints, verticalPoints = propsIncludingDefaults.verticalPoints;\n    // No horizontal points are specified\n    if ((!horizontalPoints || !horizontalPoints.length) && lodash_isFunction__WEBPACK_IMPORTED_MODULE_1___default()(horizontalCoordinatesGenerator)) {\n        var isHorizontalValues = horizontalValues && horizontalValues.length;\n        var generatorResult = horizontalCoordinatesGenerator({\n            yAxis: yAxis ? _objectSpread(_objectSpread({}, yAxis), {}, {\n                ticks: isHorizontalValues ? horizontalValues : yAxis.ticks\n            }) : undefined,\n            width: chartWidth,\n            height: chartHeight,\n            offset: offset\n        }, isHorizontalValues ? true : syncWithTicks);\n        (0,_util_LogUtils__WEBPACK_IMPORTED_MODULE_8__.warn)(Array.isArray(generatorResult), \"horizontalCoordinatesGenerator should return Array but instead it returned [\".concat(_typeof(generatorResult), \"]\"));\n        if (Array.isArray(generatorResult)) {\n            horizontalPoints = generatorResult;\n        }\n    }\n    // No vertical points are specified\n    if ((!verticalPoints || !verticalPoints.length) && lodash_isFunction__WEBPACK_IMPORTED_MODULE_1___default()(verticalCoordinatesGenerator)) {\n        var isVerticalValues = verticalValues && verticalValues.length;\n        var _generatorResult = verticalCoordinatesGenerator({\n            xAxis: xAxis ? _objectSpread(_objectSpread({}, xAxis), {}, {\n                ticks: isVerticalValues ? verticalValues : xAxis.ticks\n            }) : undefined,\n            width: chartWidth,\n            height: chartHeight,\n            offset: offset\n        }, isVerticalValues ? true : syncWithTicks);\n        (0,_util_LogUtils__WEBPACK_IMPORTED_MODULE_8__.warn)(Array.isArray(_generatorResult), \"verticalCoordinatesGenerator should return Array but instead it returned [\".concat(_typeof(_generatorResult), \"]\"));\n        if (Array.isArray(_generatorResult)) {\n            verticalPoints = _generatorResult;\n        }\n    }\n    return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"g\", {\n        className: \"recharts-cartesian-grid\"\n    }, /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Background, {\n        fill: propsIncludingDefaults.fill,\n        fillOpacity: propsIncludingDefaults.fillOpacity,\n        x: propsIncludingDefaults.x,\n        y: propsIncludingDefaults.y,\n        width: propsIncludingDefaults.width,\n        height: propsIncludingDefaults.height,\n        ry: propsIncludingDefaults.ry\n    }), /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(HorizontalGridLines, _extends({}, propsIncludingDefaults, {\n        offset: offset,\n        horizontalPoints: horizontalPoints,\n        xAxis: xAxis,\n        yAxis: yAxis\n    })), /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(VerticalGridLines, _extends({}, propsIncludingDefaults, {\n        offset: offset,\n        verticalPoints: verticalPoints,\n        xAxis: xAxis,\n        yAxis: yAxis\n    })), /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(HorizontalStripes, _extends({}, propsIncludingDefaults, {\n        horizontalPoints: horizontalPoints\n    })), /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(VerticalStripes, _extends({}, propsIncludingDefaults, {\n        verticalPoints: verticalPoints\n    })));\n}\nCartesianGrid.displayName = \"CartesianGrid\";\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2


public void Ex_hex_literal()
        {
            var pySrc = "0x_1234";
            var sExp = "0x_1234";
            Assert.Equal(sExp, Xlat(pySrc));
        }

        [Fact]
        public void Ex_list_unpackers()
        {
            var pySrc = "[ 1, 2, *foo, 3, 4]";
            var sExp =
@"ListUtils.Unpack<object>(new object[] {
    1,
    2,
}, foo, new object[] {
    3,
    4,
})";
            Assert.Equal(sExp, Xlat(pySrc));
        }

        [Fact]
        public void Ex_tuple_unpacker()
        {
            var pySrc = "(1, 2, *foo, 3, 4)";
            var sExp =
@"TupleUtils.Unpack<object>(new object[] {
    1,
    2,
}, foo, new object[] {
    3,
    4,
})";
            Assert.Equal(sExp, Xlat(pySrc));
        }

        [Fact(DisplayName = nameof(Ex_FormatString))]
        public void Ex_FormatString()
        {
            var pySrc = "f'Hello {world}'";
            var sExp = "$\"Hello {world}\"";
            Assert.Equal(sExp, Xlat(pySrc));
        }

        [Fa


B6EE38 800F7C98 0018C0C0 */  sll   $t8, $t8, 3
/* B6EE3C 800F7C9C 03193021 */  addu  $a2, $t8, $t9
/* B6EE40 800F7CA0 1880000D */  blez  $a0, .L800F7CD8
/* B6EE44 800F7CA4 00802825 */   move  $a1, $a0
/* B6EE48 800F7CA8 000270C0 */  sll   $t6, $v0, 3
.L800F7CAC:
/* B6EE4C 800F7CAC 00CE1821 */  addu  $v1, $a2, $t6
/* B6EE50 800F7CB0 906F0004 */  lbu   $t7, 4($v1)
/* B6EE54 800F7CB4 550F0004 */  bnel  $t0, $t7, .L800F7CC8
/* B6EE58 800F7CB8 24420001 */   addiu $v0, $v0, 1
/* B6EE5C 800F7CBC A0670004 */  sb    $a3, 4($v1)
/* B6EE60 800F7CC0 308200FF */  andi  $v0, $a0, 0xff
/* B6EE64 800F7CC4 24420001 */  addiu $v0, $v0, 1
.L800F7CC8:
/* B6EE68 800F7CC8 304200FF */  andi  $v0, $v0, 0xff
/* B6EE6C 800F7CCC 0045082A */  slt   $at, $v0, $a1
/* B6EE70 800F7CD0 5420FFF6 */  bnezl $at, .L800F7CAC
/* B6EE74 800F7CD4 000270C0 */   sll   $t6, $v0, 3
.L800F7CD8:
/* B6EE78 800F7CD8 8FBF001C */  lw    $ra, 0x1c($sp)
/* B6EE7C 800F7CDC 8FB00018 */  lw    $s0, 0x18($sp)
/* B6EE80 800F7CE0 27BD0030 */  addiu $sp, $sp, 0x30
/* B6EE84 800F7CE4 03E00008 */  jr    $ra
/* B6EE88 800F7CE8 00000000 */   nop

glabel func_800F7CEC
/* B6EE8C 800F7CEC 27BDFF50 */  addiu $sp, $sp, -0xb0
/* B6EE90 800F7CF0 AFB50044 */  sw    $s5, 0x44($sp)
/* B6EE94 800F7CF4 AFB3003C */  sw    $s3, 0x3c($sp)
/* B6EE98 800F7CF8 AFB10034 */  sw    $s1, 0x34($sp)
/* B6EE9C 800F7CFC 3C027FFF */  lui   $v0, (0x7FFFFFFF >> 16) # lui $v0, 0x7fff
/* B6EEA0 800F7D00 AFBF0054 */  sw    $ra, 0x54($sp)
/* B6EEA4 800F7D04 AFBE0050 */  sw    $fp, 0x50($sp)
/* B6EEA8 800F7D08 AFB7004C */  sw    $s7, 0x4c($sp)
/* B6EEAC 800F7D0C AFB60048 */  sw    $s6, 0x48($sp)
/* B6EEB0 800F7D10 AFB40040 */  sw    $s4, 0x40($sp)
/* B6EEB4 800F7D14 AFB20038 */  sw    $s2, 0x


		}
		printf("%d %d\n", ans, p);
	}

	return 0;
}
```

## 样例程序 2

```c++
#include <stdio.h>

int main()
{
	int n, t, tmp, i;
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d", &n);
		int ans = 1, p = 1, len = 0;
		for (i = 1; i <= n; i++)
		{
			scanf("%d", &tmp);
			if (tmp == 1)
				len++;
			else
			{
				if (len > ans)
				{
					ans = len;
					p = i - len;
				}
				len = 0;
			}
		}
		if (len > ans)
		{
			ans = len;
			p = n - len + 1;
		}
		// 注意若读入的最后一位为 1，len 不为 0，需多进行一次判断
		printf("%d %d\n", ans, p);
	}
}
```

<div style="page-break-after: always;"></div>

# F - 方形「方形造形術」

| 难度  |   考点   |
| :---: | :------: |
|   4   | 多重循环 |

## 题目分析

本题有很多解法，核心思路是“找规律”，即找到输出与行数之间的关系，并用循环输出。

以下提供一些思路参考：

* 图案是很美观的**对称**图形；
* 图案输出分为两种，背景和字母，其中字母是按顺序输出的。

以下提供两个示例程序，分别是：

1. 思路非常简单、解法**极其暴力**，但是十分冗长的解法。适合头脑混乱时无脑解题用；
2. 优雅但是不那么容易想到的解法。适合头脑清晰时使用。

PS：笔者认为本题的图形还挺美的，大家可以用 `'|'` `'\'` `'/'` `'>'` `')'` `'*'` `'+'` `'.'` `'^'` 等各种字符做背景看看效果。

## 示例程序 1

主要思路：

将图案分拆为上下两部分，只对上部分进行思考，下部分则直接复制上部分代码改变循环顺序输出；将图案的每一行分为三部分，分别是左背景、字母、右背景，再分别进行循环输出。

对于第 $i$ 行，其字母数量为 $2i + 1$，而左右背景字符数分别为 $n - i - 1$。而字母又是回文结构，同样可以先输出前半部分，再将后半部分反向输出。

具体代码如下：

```c++
#include<stdio.h>

int main()
{
    int bg, n;	// bg: background
    int i, j, k, l, fast, close;
	char char_out;
    char a[100];

    scanf("%c %d", &bg, &n);
    for (i = 0; i < n; i++) {	// 上半部分（含中线），循环从 i 递增至 n - 1
        for (j = 0; j < n - i - 1; j++) {	// 输出左背景
            putchar(bg);
        }
        // 输出字母
        for (j = 0; j <=


nil)
//	mockClient.On("SetLogger", mock.Anything)
//
//	mockClient.On("Error").Return(nil).Times(4)
//	mockClient.On("FlushAsync", mock.Anything).Return(abciclient.NewReqRes(abci.ToRequestFlush()), nil)
//	mockClient.On("SetResponseCallback", mock.MatchedBy(func(cb abciclient.Callback) bool { callback = cb; return true }))
//
//	app := kvstore.NewApplication()
//	cc := proxy.NewLocalClientCreator(app)
//	mp, cleanup, err := newMempoolWithAppMock(cc, mockClient)
//	require.NoError(t, err)
//	defer cleanup()
//
//	// Add 4 transactions to the mempool by calling the mempool's `CheckTx` on each of them.
//	txs := []types.Tx{[]byte{0x01}, []byte{0x02}, []byte{0x03}, []byte{0x04}}
//	for _, tx := range txs {
//		reqRes := abciclient.NewReqRes(abci.ToRequestCheckTx(abci.RequestCheckTx{Tx: tx}))
//		reqRes.Response = abci.ToResponseCheckTx(abci.ResponseCheckTx{Code: abci.CodeTypeOK})
//
//		mockClient.On("CheckTxAsync", mock.Anything, mock.Anything).Return(reqRes, nil)
//		err := mp.CheckTxSync(tx, nil, mempool.TxInfo{})
//		require.NoError(t, err)
//
//		// ensure that the callback that the mempool sets on the ReqRes is run.
//		reqRes.InvokeCallback()
//	}
//
//	// Calling update to remove the first transaction from the mempool.
//	// This call also triggers the mempool to recheck its remaining transactions.
//	err = mp.Update(0, []types.Tx{txs[0]}, abciResponses(1, abci.CodeTypeOK), nil, nil)
//	require.Nil(t, err)
//
//	// The mempool has now sent its requests off to the client to be rechecked
//	// and is waiting for the corresponding callbacks to be called.
//	// We now call the mempool-supplied callback on the first and third transaction.
//	// This simulates the client dropping the second request.
//	// Previous versions of this code panicked when the ABCI application missed
//	// a recheck-tx request.
//	resp := abci.ResponseCheckTx{Code: abci.CodeTypeOK}
//	req := abci.RequestCheckTx{Tx: txs[1]}
//	callback(abci.ToRequestCheckTx(req), abci.ToResponseCheckTx(resp))
//
//	req = abci.RequestCheckTx{Tx: txs[3]}
//	callback(abci.ToRequestCheckTx(req), abci.ToResponseCheckTx(resp))
//	mockClient.AssertExpectations(t)
//}

func TestMempool_KeepInvalidTxsInCache(t *testing.T) {
	app := kvstore.NewApplication()
	cc := proxy.NewLocalClientCreator(app)
	wcfg := config.DefaultConfig()
	wcfg.Mempool.KeepInvalidTxsInCache = true
	mp, cleanup := newMempoolWithAppAndConfig(cc, wcfg)
	defer cleanup()

	// 1. An invalid transaction must remain in the cache after Update
	{
		a := make([]byte, 8)
		binary.BigEndian.PutUint64(a, 0)

		b := make([]byte, 8)
		binary.BigEndian.PutUint64(b, 1)

		err := mp.CheckTxSync(b, nil, mempool.TxInfo{})
		require.NoError(t, err)

		// simulate new block
		_ = app.DeliverTx(abci.RequestDeliverTx{Tx: a})
		_ = app.DeliverTx(ab


* 保存抄送人
     *
     * @param workPoolPo
     * @param reqJson
     * @param userDto
     */
    private void saveCopyStaff(WorkPoolPo workPoolPo, JSONObject reqJson, UserDto userDto) {
        if (!reqJson.containsKey("copyStaffs")) {
            return;
        }
        JSONArray copyStaffs = reqJson.getJSONArray("copyStaffs");
        if (ListUtil.isNull(copyStaffs)) {
            return;
        }
        WorkCopyPo workCopyPo = null;
        for (int copyIndex = 0; copyIndex < copyStaffs.size(); copyIndex++) {
            workCopyPo = new WorkCopyPo();
            workCopyPo.setCopyId(GenerateCodeFactory.getGeneratorId("11"));
            workCopyPo.setStaffId(copyStaffs.getJSONObject(copyIndex).getString("staffId"));
            workCopyPo.setStaffName(copyStaffs.getJSONObject(copyIndex).getString("staffName"));
            workCopyPo.setStoreId(reqJson.getString("storeId"));
            workCopyPo.setWorkId(workPoolPo.getWorkId());
            workCopyPo.setCommunityId(reqJson.getString("communityId"));
            workCopyPo.setState(WorkCopyDto.STATE_DOING);
            workCopyV1InnerServiceSMOImpl.saveWorkCopy(workCopyPo);
        }
    }

    /**
     * 保存内容
     *
     * @param workPoolPo
     * @param reqJson
     * @param userDto
     */
    private void saveContent(WorkPoolPo workPoolPo, JSONObject reqJson, UserDto userDto) {

        JSONArray contents = reqJson.getJSONArray("contents");
        JSONObject content = null;
        for (int cIndex = 0; cIndex < contents.size(); cIndex++) {
            content = contents.getJSONObject(cIndex);
            WorkPoolContentPo workPoolContentPo = new WorkPoolContentPo();
            workPoolContentPo.setContentId(GenerateCodeFactory.getGeneratorId("11"));
            workPoolContentPo.setContent(content.getString("content"));
            workPoolContentPo.setWorkId(workPoolPo.getWorkId());
            workPoolContentPo.setCommunityId(reqJson.getString("communityId"));
            workPoolContentPo.setStoreId(reqJson.getString("storeId"));
            workPoolContentPo.setSeqNum(cIndex + 1);
            content.put("contentId", workPoolContentPo.getContentId());
            workPoolContentV1InnerServiceSMOImpl.saveWorkPoolContent(workPoolContentPo);
        }
    }

    private void saveFile(WorkPoolPo workPoolPo, JSONObject reqJson, UserDto userDto) {

        JSONArray pathUrls = reqJson.getJSONArray("pathUrls");
        if (ListUtil.isNull(pathUrls)) {
            return;
        }
        for (int urlIndex = 0; urlIndex < pathUrls.size(); urlIndex++) {
            WorkPoolFilePo workPoolFilePo = new WorkPoolFilePo();
            workPoolFilePo.setCommunityId(workPoolPo.getCommunityId());
            workPoolFilePo.setFileType(WorkPoolFileDto.FILE_TYPE_START);
            workPoolFilePo.setFileId(GenerateCodeFactory.getGeneratorId("11"));
            workPoolFilePo.setWorkId(workPoolPo.getWorkId());
            workPoolFilePo.setTaskId("-1");
            workPoolFilePo.setPathUrl(pathUrls.getString(urlIndex));
            workPoolFilePo.setStoreId(workPoolPo.getStoreId());
            workPoolFilePo.setItemId("-1");
            workPoolFilePo.setCon


_BBAA
		// count mod 4 = 3 -> [ ## ## ## ## | AA BB CC    ] -> 0xCCBB_AA##             -> 0x80CC_BBAA

		count = ~count << 3;

		if (BitConverter.IsLittleEndian)
		{
			partialResult >>= 8; // make some room for the 0x80 byte
			partialResult |= 0x8000_0000u; // put the 0x80 byte at the beginning
			partialResult >>= (int)count & 0x1F; // shift out all previously consumed bytes
		}
		else
		{
			partialResult <<= 8; // make some room for the 0x80 byte
			partialResult |= 0x80u; // put the 0x80 byte at the end
			partialResult <<= (int)count & 0x1F; // shift out all previously consumed bytes
		}

		DoFinalRoundsAndReturn:

		// Now that we've computed the final partial result, merge it in and run two rounds of
		// the block function to finish out the Marvin algorithm.

		p0 += partialResult;
		Block(ref p0, ref p1);
		Block(ref p0, ref p1);

		return (int)(p1 ^ p0);

		InputTooSmallToEnterMainLoop:

		// We had only 0 .. 3 bytes to begin with, so we can't perform any 32-bit reads.
		// This means that we're going to be building up the final result right away and
		// will only ever run two rounds total of the block function. Let's initialize
		// the partial result to "no data".

		if (BitConverter.IsLittleEndian)
		{
			partialResult = 0x80u;
		}
		else
		{
			partialResult = 0x80000000u;
		}

		if ((count & 0b_0001) != 0)
		{
			// If the buffer is 1 or 3 bytes in length, let's read a single byte now
			// and merge it into our partial result. This will result in partialResult
			// having one of the two values below, where AA BB CC are the buffer bytes.
			//
			//                  (little-endian / big-endian)
			// [ AA          ]  -> 0x0000_80AA / 0xAA80_0000
			// [ AA BB CC    ]  -> 0x0000_80CC / 0xCC80_0000

			partialResult = Unsafe.AddByteOffset(ref data, (IntPtr)((uint)count & 2));

			if (BitConverter.IsLittl


ype)
        return str
      end,
      damageMerge = function(damageIdList, multiples, tableHeardName, formatType)
        local num = 0
        for index, damageId in ipairs(damageIdList) do
          local damageAttrTableMgr = Z.TableMgr.GetTable("DamageAttrTableMgr")
          local damageAttrTableRow = damageAttrTableMgr.GetRow(damageId)
          if damageAttrTableRow == nil then
            return ""
          end
          if tableHeardName == nil or tableHeardName == "" then
            logError("[Skill] Skill.Damage() \231\154\132\232\161\168\229\164\180\228\184\141\230\173\163\231\161\174,damageId :" .. damageId)
            return ""
          end
          local maxLevel = #damageAttrTableRow[tableHeardName]
          local level = skillFightLevelTableRow.Level or 1
          if tableHeardName == "PVEDamageRadio" then
            if remodelLevel <= 0 then
              level = 1
            end
            if starTableRow and starTableRow.TransformationType then
              for _, value in ipairs(starTableRow.TransformationType) do
                if value[1] == E.RemodelInfoType.SkillDamageMultiple then
                  level = value[3] + 1
                end
              end
            end
          end
          if maxLevel < level then
            level = maxLevel
          end
          local multiple = multiples[index]
          if multiple == nil then
            logError("[Skill] SkillEffect() \231\154\132\229\144\136\229\185\182\229\143\130\230\149\176\229\128\141\230\149\176\228\184\141\229\140\185\233\133\141")
            return ""
          end
          num = num + damageAttrTableRow[tableHeardName][level] * multiple
        end
        local str = ret.formatFloatParam(num, formatType)
        return str
      end,
      effectcd = function()
        local reduceNumber = 0
        if starTableRow and starTableRow.TransformationType then
          for _, value in ipairs(starTableRow.TransformationType) do
            if value[1] == E.RemodelInfoType.ReduceSkillCD then
              reduceNumber = value[3] / 1000
            end
          end
        end
        local cd = Lang("Seconds", {
          val = tostring(skillFightLevelTableRow.PVECoolTime - reduceNumber):gsub("%.0+$", "")
        })
        return cd
      end,
      chargetime = function()
        local reduceNumber = 0
        if starTableRow and starTableRow.TransformationType then
          for _, value in ipairs(starTableRow.TransformationType) do
            if value[1] == E.RemodelInfoType.ReduceSkillCharge then
              reduceNumber = value[3]
            end
          end
        end
        local skillRow = Z.TableMgr.GetTable("SkillTableMgr").GetRow(skillId)
        if skillRow == nil then
          return ""
        end
        return Lang("Seconds", {
          val = tostring((skillRow.EnergyChargeTime - reduceNumber) / 1000):gsub("%.0+$", "")
        })
      end
    }
  }
  local skillAttrDes = skilleffectTableRow.SkillAttrDes
  if skillAttrDes == nil or skillAttrDes == nil or #skillAttrDes < 1 then
    return nil
  end
  local tab = {}
  for _, attrDes in ipairs(skillAttrDes) do
    if #attrDes ~= 2 then
      logError("SkillEffectTable \232\161\168 SkillAttrDes \233\133\141\231\189\174\233\148\153\232\175\175,ID\228\184\186:" .. skilleffectTableRow.Id)
    end


Tetromino = this.getNewTetromino();
					}
					else {
						this.currentTetromino = this.nextTetromino;
					}
					this.timeOfNextAutoStep = this.game.time.now + this.timeBetweenSteps;
					this.timeToAllowInput = this.game.time.now + this.inputCooldownTime;
					this.nextTetromino = this.getNewTetromino();
				} else {
					this.handleInput();
					if (this.game.time.now > this.timeOfNextAutoStep) {
						this.timeOfNextAutoStep = this.game.time.now + this.timeBetweenSteps;
						if (!this.tryShiftCurrentTetromino(0, -1)) {
							this.finalizeTetromino();
						}
						this.refreshNeeded = true;
					}
				}
				break;
			case GameplayState.END:
				if (this.restartKey.justDown) {
					this.cleanup();
					this.gameplayState = GameplayState.PLAY;
				}
				break;
		}
	}
	/**Generates data for a new Tetromino.*/
	private getNewTetromino() {
		const numberOfValidShapes = 7;
		var type: TetrominoType = Math.floor(Math.random() * numberOfValidShapes) + 1;
		var shape: number[][] = this.getShapeAndRotation(type, 0);
		var spawnX = this.getRandomSpawnX(type);
		var spawnY: number = this.gridVerticalSize - (shape[1].length - 2);
		return new TetrominoActor(type, spawnX, spawnY);
	}
	/**According to the offical Tetris ruleset, O and I Tetrominos spawn in the center, while the others spawn in the center-left.*/
	private getRandomSpawnX(type: TetrominoType) {
		const spawnAreaCellWidth = 4;
		const centerOffset = 2;
		const leftCenterOffset = 4;
		var center = Math.floor(this.gridHorizontalSize * 0.5);
		var offset = (type == TetrominoType.O || type == TetrominoType.I) ? centerOffset : leftCenterOffset;
		return center + (Math.floor(Math.random() * spawnAreaCellWidth) - offset);
	}
	/**Detects and processes input for the Play game state.*/
	private handleInput() {
		if (this.currentTetromino != null && this.game.time.now > this.timeToAllowInput) {
			if (this.downKey.isDown) {
				if (this.tryDropCurrentTetromino()) {
					this.onInputApplied();
					this.timeOfNextAutoStep = this.game.time.now + this.timeBetweenSteps;
				}
			}
			else if (this.upKey.isDown) {
				if (this.tryRotateCurrentTetromino()) {
					this.onInputApplied();
				}
			}
			else if (this.rightKey.isDown) {
				if (this.tryShiftCurrentTetromino(1, 0)) {
					this.onInputApplied();
				}
			}
			else if (this.leftKey.isDown) {
				if (this.tryShiftCurrentTetromino(-1, 0)) {
					this.onInputApplied();
				}
			}
			else if (this.restartKey.justDown) {
				this.cleanup();
			}
		}
	}
	/**Rotates the current Tetromino, if possible.*/
	private tryRotateCurrentTetromino() {
		if (this.currentTetromino != null) {
			var newRotation: number = this.currentTetromino.rotation + 1;
			if (newRotation >= 4) {
				newRotation = 0;
			}
			if (this.getIsTetrominoFreeAtProjectedPosition(this.currentTetromino.type,
				newRotation,
				this.currentTetromino.x,
				this.currentT


layerPos[i].x && pos.y == otherPlayerPos[i].y) {
                return true;
            }
        }
        return false;
    }

    /**
     * @desc 获取墙对应方向是否可走的 map， {0，1，2，3}对应{向上，向下，向左，向右}
     * @param walls 现有墙的信息
     * @return arrivalMap
     */
    _initWallMap(walls: Array<WallVO>): Array<Array<Array<boolean>>> {
        let arrivalMap = new Array<Array<Array<boolean>>>();
        for (let i = 0; i < ChessboardLimit.CHESS_LIMIT; i++) {
            let arrival = new Array<Array<boolean>>();
            for (let j = 0; j < ChessboardLimit.CHESS_LIMIT; j++) {
                let arr = new Array<boolean>();
                //可以向上
                if (j >= 0 && j < ChessboardLimit.CHESS_LIMIT - 1) {
                    arr[0] = true
                }
                //可以向下
                if (j > 0 && j <= ChessboardLimit.CHESS_LIMIT - 1) {
                    arr[1] = true
                }
                //可以向左
                if (i > 0 && i <= ChessboardLimit.CHESS_LIMIT - 1) {
                    arr[2] = true
                }
                //可以向右
                if (i >= 0 && i < ChessboardLimit.CHESS_LIMIT - 1) {
                    arr[3] = true
                }
                arrival[j] = arr;
            }
            arrivalMap[i] = arrival;
        }

        for (let i = 0; i < walls.length; i++) {
            //横木板
            if (walls[i].wallType == "horizontal") {
                arrivalMap[walls[i].position.x][walls[i].position.y][0] = false
                arrivalMap[walls[i].position.x + 1][walls[i].position.y][0] = false
                arrivalMap[walls[i].position.x][walls[i].position.y + 1][1] = false
                arrivalMap[walls[i].position.x + 1][walls[i].position.y + 1][1] = false
            }
            //纵木板
            if (walls[i].wallType == "vertical") {
                arrivalMap[walls[i].position.x + 1][walls[i].position.y][2] = false
                arrivalMap[walls[i].position.x + 1][walls[i].position.y + 1][2] = false
                arrivalMap[walls[i].position.x][walls[i].position.y][3] = false
                arrivalMap[walls[i].position.x][walls[i].position.y + 1][3] = false
            }
        }

        return arrivalMap;
    }

    /**
     * @desc 墙体坐标转换(视角转换由 from => to)
     * @param fromPlayerID 用户唯一标识
     * @param toPlayerID 用户唯一标识
     * @param wallInfo  墙体信息
     * @return WallVO
     */
    rotationWall(fromPlayerID: string, toPlayerID: string, wallInfo: WallVO): WallVO {
        const gameProxy = this.facade.retrieveProxy(GameProxy.NAME) as GameProxy;
        let gameInfo = gameProxy.getGame();
        let playerCount = Util.getPlayerCntByType(gameInfo.gameType);
        let rotationMul = 2;
        if (playerCount == 4) {
            // 4人游戏中，如果需要转换，每隔一个用户需要转换1次，所以最终转换次数要乘1
            rotationMul = 1;
        }

        let fromPlayerIndex = 0;
        let toPlayerIndex = 0;
        // 获取playerID对应用户信息的下标
        for (let i = 0; i < playerCount; i++) {
            if (gameInfo.playersInfo[i].playerID == fromPlayerID) {
                fromPlayerIndex = i;
            }
            if (game


 _RTCINTERNAL_DEPRECATED  void   __fastcall _RTC_CheckStackVars(void *_Esp, _RTC_framedesc *_Fd);
    _RTCINTERNAL_DEPRECATED  void   __fastcall _RTC_CheckStackVars2(void *_Esp, _RTC_framedesc *_Fd, _RTC_ALLOCA_NODE *_AllocaList);
    _RTCINTERNAL_DEPRECATED  void   __fastcall _RTC_AllocaHelper(_RTC_ALLOCA_NODE *_PAllocaBase, size_t _CbSize, _RTC_ALLOCA_NODE **_PAllocaInfoList);
#endif
    /* Unintialized Local call */
    void   __cdecl     _RTC_UninitUse(const char *_Varname);

#if !defined(_M_CEE) && !defined(_M_CEE_PURE)
    /* These unsupported functions are deprecated in native mode and not supported at all in /clr mode */

#endif

    /* Subsystem initialization stuff */
    void    __cdecl    _RTC_Shutdown(void);
    void    __cdecl    _RTC_InitBase(void);

#ifdef __NOTHROW
    #undef __NOTHROW
#endif

#ifdef  __cplusplus

    void* _ReturnAddress();
}

#endif

#ifdef  _MSC_VER
#pragma pack(pop)
#endif  /* _MSC_VER */

#endif /* _INC_RTCAPI */
/* 88bf0570-3001-4e78-a5f2-be5765546192 */


      var NodeKey: KeyNodePublic,
      var Peers: List<Tailcfg.Node>? = null,
      var Expiry: Time,
      var Domain: String,
      var UserProfiles: Map<String, Tailcfg.UserProfile>,
      var TKAEnabled: Boolean,
      var DNS: Tailcfg.DNSConfig? = null,
      var AllCaps: List<String> = emptyList()
  ) {
    // Keys are tailcfg.UserIDs thet get stringified
    // Helpers
    fun currentUserProfile(): Tailcfg.UserProfile? {
      return userProfile(User())
    }

    fun User(): UserID {
      return SelfNode.User
    }

    fun userProfile(id: Long): Tailcfg.UserProfile? {
      return UserProfiles[id.toString()]
    }

    fun getPeer(id: StableNodeID): Tailcfg.Node? {
      if (id == SelfNode.StableID) {
        return SelfNode
      }
      return Peers?.find { it.StableID == id }
    }

    override fun equals(other: Any?): Boolean {
      if (this === other) return true
      if (other !is NetworkMap) return false

      return SelfNode == other.SelfNode &&
          NodeKey == other.NodeKey &&
          Peers == other.Peers &&
          Expiry == other.Expiry &&
          User() == other.User() &&
          Domain == other.Domain &&
          UserProfiles == other.UserProfiles &&
          TKAEnabled == other.TKAEnabled
    }

    fun hasCap(capability: String): Boolean {
      return AllCaps.contains(capability)
    }
  }
}
package com.tainzhi.android.videoplayer

import android.app.Application
import android.content.Context
import com.tainzhi.android.videoplayer.util.CoroutineDispatcherProvider
import com.tainzhi.android.videoplayer.di.databaseModule
import com.tainzhi.android.videoplayer.di.repositoryModule
import com.tainzhi.android.videoplayer.di.viewModelModule
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.TestCoroutineScope
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.setMain
import org.junit.rules.*
import org.junit.runner.*
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.dsl.module
import org.mockito.*

/**
 * File:     MainCoroutineScopeRule
 * Author:   tainzhi
 * Created:  2021/1/12 20:07
 * Mail:     QFQ61@qq.com
 * Description:
 */
class MainCoroutineScopeRule constructor(val dispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()) :
        TestWatcher(),
        TestCoroutineScope by TestCoroutineScope(dispatcher) {

    @Mock
    private lateinit var mockContext: Context

    override fun starting(description: Description?) {
        super.starting(description)
        // If your codebase allows the injection of other dispatchers like
        // Dispatchers.Default and Dispatchers.IO, consider injecting all of them here
        // and renaming this class to `CoroutineScopeRule`
        //
        // All injected dispatchers in a test should point to a single instance of
        // TestCoroutineDispatcher.
        Dispatchers.setMain(dispatcher)

        mockContext = Application()

        // 替换掉默认的 Dispatchers.default, 它不能用于测试
        val testCoroutineModule = module {
            single {
                CoroutineDispatcherProvider(
                        dispatcher, dispatcher, dispatcher
                )
            }
        }
        startKoin {
            androidContext(mockContext)
            module


Y_10_FULL | QD_PHY_10_HALF)
#define QD_PHY_MODE_AUTO_FULL    (QD_PHY_100_FULL | QD_PHY_10_FULL)
#define QD_PHY_MODE_AUTO_HALF    (QD_PHY_100_HALF | QD_PHY_10_HALF)

#define QD_PHY_MODE_100_FULL    QD_PHY_100_FULL
#define QD_PHY_MODE_100_HALF    QD_PHY_100_HALF
#define QD_PHY_MODE_10_FULL        QD_PHY_10_FULL
#define QD_PHY_MODE_10_HALF        QD_PHY_10_HALF

/* Gigabit Phy related definition */
#define QD_GIGPHY_1000X_FULL_CAP    0x8
#define QD_GIGPHY_1000X_HALF_CAP    0x4
#define QD_GIGPHY_1000T_FULL_CAP    0x2
#define QD_GIGPHY_1000T_HALF_CAP    0x1

#define QD_GIGPHY_1000X_CAP        (QD_GIGPHY_1000X_FULL_CAP|QD_GIGPHY_1000X_HALF_CAP)
#define QD_GIGPHY_1000T_CAP        (QD_GIGPHY_1000T_FULL_CAP|QD_GIGPHY_1000T_HALF_CAP)

#define QD_GIGPHY_1000X_FULL        0x20
#define QD_GIGPHY_1000X_HALF        0x40

#define QD_GIGPHY_1000T_FULL        0x200
#define QD_GIGPHY_1000T_HALF        0x100

/* Bit definition for QD_PHY_INT_ENABLE_REG */
#define QD_PHY_INT_SPEED_CHANGED        0x4000
#define QD_PHY_INT_DUPLEX_CHANGED        0x2000
#define QD_PHY_INT_PAGE_RECEIVED        0x1000
#define QD_PHY_INT_AUTO_NEG_COMPLETED        0x800
#define QD_PHY_INT_LINK_STATUS_CHANGED        0x400
#define QD_PHY_INT_SYMBOL_ERROR            0x200
#define QD_PHY_INT_FALSE_CARRIER        0x100
#define QD_PHY_INT_FIFO_FLOW            0x80
#define QD_PHY_INT_CROSSOVER_CHANGED        0x40
#define QD_PHY_INT_POLARITY_CHANGED        0x2
#define QD_PHY_INT_JABBER            0x1

/* Bit definition for DEVICE Interrupt */
#define QD_DEV_INT_WATCHDOG            0x8000
#define QD_DEV_INT_JAMLIMIT            0x4000
#define QD_DEV_INT_DUPLEX_MISMATCH    0x2000
#define QD_DEV_INT_WAKE_EVENT         0x1000

/* Definition for Multi Address Mode */
#define QD_REG_SMI_COMMAND        0x0
#define QD_REG_SMI_DATA            0x1

/* Bit definition for QD_REG_SMI_COMMAND */
#define QD_SMI_BUSY                0x8000
#define QD_SMI_MODE                0x1000
#define QD_SMI_MODE_BIT            12
#define QD_SMI_OP_BIT            10
#define QD_SMI_OP_SIZE            2
#define QD_SMI_DEV_ADDR_BIT        5
#define QD_SMI_DEV_ADDR_SIZE    5
#define QD_SMI_REG_ADDR_BIT        0
#define QD_SMI_REG_ADDR_SIZE    5

#define QD_SMI_CLAUSE45            0
#define QD_SMI_CLAUSE22            1

#define QD_SMI_WRITE            0x01
#define QD_SMI_READ                0x02

#endif /* __gtDrvSwRegsh */


编码/解码。必须以大写字母开头的字段才是可导出的。
type response2 struct {
	Page   int      `json:"page"`
	Fruits []string `json:"fruits"`
}

func main() {

	// 首先我们来看一下基本数据类型到 JSON 字符串的编码过程。
	// 这是一些原子值的例子。
	bolB, _ := json.Marshal(true)
	fmt.Println(string(bolB))

	intB, _ := json.Marshal(1)
	fmt.Println(string(intB))

	fltB, _ := json.Marshal(2.34)
	fmt.Println(string(fltB))

	strB, _ := json.Marshal("gopher")
	fmt.Println(string(strB))

	// 这是一些切片和 map 编码成 JSON 数组和对象的例子。
	slcD := []string{"apple", "peach", "pear"}
	slcB, _ := json.Marshal(slcD)
	fmt.Println(string(slcB))

	mapD := map[string]int{"apple": 5, "lettuce": 7}
	mapB, _ := json.Marshal(mapD)
	fmt.Println(string(mapB))

	// JSON 包可以自动的编码你的自定义类型。
	// 编码的输出只包含可导出的字段，并且默认使用字段名作为 JSON 数据的键名。
	res1D := &response1{
		Page:   1,
		Fruits: []string{"apple", "peach", "pear"}}
	res1B, _ := json.Marshal(res1D)
	fmt.Println(string(res1B))

	// 你可以给结构字段声明标签来自定义编码的 JSON 数据的键名。
	// 上面 `Response2` 的定义，就是这种标签的一个例子。
	res2D := &response2{
		Page:   1,
		Fruits: []string{"apple", "peach", "pear"}}
	res2B, _ := json.Marshal(res2D)
	fmt.Println(string(res2B))

	// 现在来看看将  JSON 数据解码为 Go 值的过程。
	// 这是一个普通数据结构的解码例子。
	byt := []byte(`{"num":6.13,"strs":["a","b"]}`)

	// 我们需要提供一个 JSON 包可以存放解码数据的变量。
	// 这里的 `map[string]interface{}` 是一个键为 string，值为任意值的 map。
	var dat map[string]interface{}

	// 这是实际的解码，以及相关错误的检查。
	if err := json.Unmarshal(byt, &dat); err != nil {
		panic(err)
	}
	fmt.Println(dat)

	// 为了使用解码 map 中的值，我们需要将他们进行适当的类型转换。
	// 例如，这里我们将 `num` 的值转换成 `float64` 类型。
	num := dat["num"].(float64)
	fmt.Println(num)

	// 访问嵌套的值需要一系列的转化。
	strs := dat["strs"].([]interface{}


ub132ps 4096(%rdx), %ymm28, %ymm25
// CHECK:  encoding: [0x62,0x62,0x1d,0x20,0x9a,0x8a,0x00,0x10,0x00,0x00]
          vfmsub132ps 4096(%rdx), %ymm28, %ymm25

// CHECK: vfmsub132ps -4096(%rdx), %ymm28, %ymm25
// CHECK:  encoding: [0x62,0x62,0x1d,0x20,0x9a,0x4a,0x80]
          vfmsub132ps -4096(%rdx), %ymm28, %ymm25

// CHECK: vfmsub132ps -4128(%rdx), %ymm28, %ymm25
// CHECK:  encoding: [0x62,0x62,0x1d,0x20,0x9a,0x8a,0xe0,0xef,0xff,0xff]
          vfmsub132ps -4128(%rdx), %ymm28, %ymm25

// CHECK: vfmsub132ps 508(%rdx){1to8}, %ymm28, %ymm25
// CHECK:  encoding: [0x62,0x62,0x1d,0x30,0x9a,0x4a,0x7f]
          vfmsub132ps 508(%rdx){1to8}, %ymm28, %ymm25

// CHECK: vfmsub132ps 512(%rdx){1to8}, %ymm28, %ymm25
// CHECK:  encoding: [0x62,0x62,0x1d,0x30,0x9a,0x8a,0x00,0x02,0x00,0x00]
          vfmsub132ps 512(%rdx){1to8}, %ymm28, %ymm25

// CHECK: vfmsub132ps -512(%rdx){1to8}, %ymm28, %ymm25
// CHECK:  encoding: [0x62,0x62,0x1d,0x30,0x9a,0x4a,0x80]
          vfmsub132ps -512(%rdx){1to8}, %ymm28, %ymm25

// CHECK: vfmsub132ps -516(%rdx){1to8}, %ymm28, %ymm25
// CHECK:  encoding: [0x62,0x62,0x1d,0x30,0x9a,0x8a,0xfc,0xfd,0xff,0xff]
          vfmsub132ps -516(%rdx){1to8}, %ymm28, %ymm25

// CHECK: vfmsub132pd %xmm20, %xmm21, %xmm18
// CHECK:  encoding: [0x62,0xa2,0xd5,0x00,0x9a,0xd4]
          vfmsub132pd %xmm20, %xmm21, %xmm18

// CHECK: vfmsub132pd %xmm20, %xmm21, %xmm18 {%k1}
// CHECK:  encoding: [0x62,0xa2,0xd5,0x01,0x9a,0xd4]
          vfmsub132pd %xmm20, %xmm21, %xmm18 {%k1}

// CHECK: vfmsub132pd %xmm20, %xmm21, %xmm18 {%k1} {z}
// CHECK:  encoding: [0x62,0xa2,0xd5,0x81,0x9a,0xd4]
          vfmsub132pd %xmm20, %xmm21, %xmm18 {%k1} {z}

// CHECK: vfmsub132pd (%rcx), %xmm21, %xmm18
// CHECK:  encoding: [0x62,0xe2,0xd5,0x00,0x9a,0x11]
          vfmsub132pd (%rcx), %xmm21, %xmm18

// CHECK: vfmsub132pd 291(%rax,%r14,8), %xm


jǐnxiù","brocade"
"儘快","jǐnkuài","as soon as possible"
"進程","jìnchéng","course; process"
"進而","jìn'ér","then"
"進取","jìnqǔ","keep for going ahead"
"進展","jìnzhǎn","evolve; get along"
"晉升","jìnshēng","promote"
"禁","jìn","ban; prohibit"
"禁區","jìnqū","forbidden zone preserve"
"近年","jìnnián","in recent years"
"近期","jìnqī","in the near future"
"近視","jìnshì","myopia"
"近似","jìnsì","approximate"
"勁頭","jìntóu","energy; vigor"
"驚慌","jīnghuāng","scared"
"精打細算","jīng dǎ xì suàn","pinch pennies"
"精華","jīnghuá","elite; distillate"
"精簡","jīngjiǎn","simplify; condense"
"精美","jīngměi","refined"
"精密","jīngmì","exact; close"
"精確","jīngquè","accurate; exact"
"精通","jīngtōng","be well up in master"
"精心","jīngxīn","meticulous"
"精益求精","jīng yì qiú jīng","keep improving"
"兢兢業業","jīngjīng yèyè","cautious and conscientious"
"經典","jīngdiǎn","classics; scriptures"
"經商","jīng shāng","be in business; trade"
"經受","jīngshòu","endure; go through"
"經銷","jīngxiāo","sell"
"莖","jīng","stalk; stem"
"警戒","jǐngjiè","guard; watch"
"警衛","jǐngwèi","guard"
"景","jǐng","scene"
"頸","jǐng","neck"
"靜悄悄","jìngqiāoqiāo","very quiet"
"境地","jìngdì","condition; circumstance"
"境界","jìngjiè","realm; extent reached"
"敬","jìng","respect"
"敬而遠之","jìng ér yuǎn zhī","keep someone at a respectful distance"
"鏡頭","jìngtóu","lens"
"競選","jìngxuǎn","run for"
"凈化","jìnghuà","purify"
"糾紛","jiūfēn","dissension; tangle"
"玖","jiǔ","nine"
"酒會","jiǔhuì","cocktail party"
"酒精","jiǔjīng","alcohol"
"救濟","jiùjì","redress; relief"
"救災","jiù zāi","provide disaster relief"
"就餐","jiùcān","have meals"
"就地","jiùdì","on the spot"
"就近","jiùjìn","handily"
"就算","jiùsuàn","even if"
"就業","jiù yè","take up an occupation"
"就職","jiù zhí","accession"
"鞠躬","jū gōng","bow"
"拘留","jūliú","impound"
"拘束","jūshù","constrained; ill at ease"
"居","jū","reside; live"
"


max_login_attempts,
                "lockout_duration": self.config.lockout_duration_seconds,
                "max_input_length": self.config.max_input_length,
            }
        }

# ===== [05] SINGLETON PATTERN ================================================
_security_manager_instance: Optional[SecurityManager] = None

def get_security_manager() -> SecurityManager:
    """보안 관리자 싱글톤 인스턴스 반환"""
    global _security_manager_instance
    if _security_manager_instance is None:
        _security_manager_instance = SecurityManager()
    return _security_manager_instance

# ===== [06] CONVENIENCE FUNCTIONS ============================================
def validate_input(
    value: Any,
    input_type: InputType,
    field_name: str = "입력값",
    security_level: SecurityLevel = SecurityLevel.MEDIUM
) -> Tuple[bool, Optional[str]]:
    """입력값 검증 편의 함수"""
    return get_security_manager().validate_input(value, input_type, field_name, security_level)

def sanitize_error_message(error: Exception, context: Optional[Dict[str, Any]] = None) -> str:
    """에러 메시지 정화 편의 함수"""
    return get_security_manager().sanitize_error_message(error, context)

def check_login_attempts(identifier: str) -> Tuple[bool, Optional[str]]:
    """로그인 시도 확인 편의 함수"""
    return get_security_manager().check_login_attempts(identifier)

def record_login_attempt(identifier: str, success: bool) -> None:
    """로그인 시도 기록 편의 함수"""
    get_security_manager().record_login_attempt(identifier, success)

# ===== [07] END ==============================================================


(Error(`Expected "${f}" to evaluate truthy`));
    }
  }
}

type Passes = Record<string, string[]>;
type Failures = Record<string, Record<string, Error[]>>;

export async function runTests(suites: typeof TestSuite[], container: HTMLElement) {
  addCss();

  const passes: Passes = {};
  const failures: Failures = {};

  const scheduleRender = createScheduler(() => render(passes, failures, container));
  await runSuites(suites, passes, failures, scheduleRender);

  logResults(passes, failures);
}

function addCss() {
  const style = document.createElement('style');
  style.textContent = `
.results {
  padding: 20px;
  background-color: black;
  color: white;
  font-family: monospace;
  font-size: 13px;
}
h1 {
  margin-top: 0px;
  color: white;
}
.fail {
  color: red;
}
.pass {
  color: lime;
}
.suite {
  margin-left: 1em;
}
.test {
  margin-left: 2em;
}
.error {
  margin: 0;
  margin-left: 3em;
  color: #999;
}
`;
  document.head.appendChild(style);
}

function createScheduler(task: () => void): () => void {
  let scheduled = false;
  return function scheduleTask() {
    if (!scheduled) {
      scheduled = true;
      requestAnimationFrame(() => {
        scheduled = false;
        task();
      });
    }
  }
}

async function runSuites(suites: typeof TestSuite[], passes: Passes, failures: Failures, scheduleRender: () => void) {
  for (const suite of suites) {
    for (const testName of Object.getOwnPropertyNames(suite.prototype)) {
      if (!testName.startsWith('test')) {
        continue;
      }

      const test = new suite();
      try {
        await (test as any)[testName]();
      } catch (error) {
        test.errors.push(error);
      }
      test.tearDown();

      if (test.errors.length > 0) {
        if (!(suite.name in failures)) {
          failures[suite.name] = {};
        }
        failures[suite.name][testName] = test.errors;
      } else {
        if (!(suite.name in passes)) {
          passes[suite.name] = [];
        }
        passes[suite.name].push(testName);
      }
      scheduleRender();
    }
  }
}

function countPasses(passes: Passes) {
  let count = 0;
  for (const tests of Object.values(passes)) {
    count += tests.length;
  }
  return count;
}

function countFailures(failures: Failures) {
  let count = 0;
  for (const testErrors of Object.values(failures)) {
    count += Object.values(testErrors).length;
  }
  return count;
}

function createElement(tag: string, classNames: string[] | null, text: string | null, children: HTMLElement[] | null): HTMLElement {
  const element = document.createElement(tag);
  if (classNames) {
    for (const className of classNames) {
      element.classList.add(className);
    }
  }
  if (text) {
    element.textContent = text;
  }
  if (children) {
    for (const child of children) {
      element.appendChild(child);
    }
  }
  return element;
}

function render(passes: Passes, failures: Failures, container: HTMLElement) {
  container.textContent = '';
  const results = createElement('div', ['results'], null, [
    createElement('h1', null, 'Test results', null),
    creat


/* SPDX-License-Identifier: GPL-2.0 */
/* linux/arch/sparc/lib/memset.S: Sparc optimized memset, bzero and clear_user code
 * Copyright (C) 1991,1996 Free Software Foundation
 * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
 *
 * Calls to memset returns initial %o0. Calls to bzero returns 0, if ok, and
 * number of bytes not yet set if exception occurs and we were called as
 * clear_user.
 */

#include <asm/ptrace.h>
#include <asm/export.h>

/* Work around cpp -rob */
#define ALLOC #alloc
#define EXECINSTR #execinstr
#define EX(x,y,a,b) 				\
98: 	x,y;					\
	.section .fixup,ALLOC,EXECINSTR;	\
	.align	4;				\
99:	ba 30f;					\
	 a, b, %o0;				\
	.section __ex_table,ALLOC;		\
	.align	4;				\
	.word	98b, 99b;			\
	.text;					\
	.align	4

#define EXT(start,end,handler) 			\
	.section __ex_table,ALLOC;		\
	.align	4;				\
	.word	start, 0, end, handler;		\
	.text;					\
	.align	4

/* Please don't change these macros, unless you change the logic
 * in the .fixup section below as well.
 * Store 64 bytes at (BASE + OFFSET) using value SOURCE. */
#define ZERO_BIG_BLOCK(base, offset, source)    \
	std	source, [base + offset + 0x00]; \
	std	source, [base + offset + 0x08]; \
	std	source, [base + offset + 0x10]; \
	std	source, [base + offset + 0x18]; \
	std	source, [base + offset + 0x20]; \
	std	source, [base + offset + 0x28]; \
	std	source, [base + offset + 0x30]; \
	std	source, [base + offset + 0x38];

#define ZERO_LAST_BLOCKS(base, offset, source)	\
	std	source, [base - offset - 0x38]; \
	std	source, [base - offset - 0x30]; \
	std	source, [base - offset - 0x28]; \
	std	source, [base - offset - 0x20]; \
	std	source, [base - offset - 0x18]; \
	std	source, [base - offset - 0x10]; \
	std	source, [base - offset - 0x08]; \
	std	source, [base - offset - 0x00];

	.text
	.align


	if len(ret) == 0 {
		panic("no return value specified for GetPriceByID")
	}

	var r0 interface{}
	var r1 error
	if rf, ok := ret.Get(0).(func(string, int64) (interface{}, error)); ok {
		return rf(currentUser, id)
	}
	if rf, ok := ret.Get(0).(func(string, int64) interface{}); ok {
		r0 = rf(currentUser, id)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(interface{})
		}
	}

	if rf, ok := ret.Get(1).(func(string, int64) error); ok {
		r1 = rf(currentUser, id)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// MockAccountingComponent_GetPriceByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPriceByID'
type MockAccountingComponent_GetPriceByID_Call struct {
	*mock.Call
}

// GetPriceByID is a helper method to define mock.On call
//   - currentUser string
//   - id int64
func (_e *MockAccountingComponent_Expecter) GetPriceByID(currentUser interface{}, id interface{}) *MockAccountingComponent_GetPriceByID_Call {
	return &MockAccountingComponent_GetPriceByID_Call{Call: _e.mock.On("GetPriceByID", currentUser, id)}
}

func (_c *MockAccountingComponent_GetPriceByID_Call) Run(run func(currentUser string, id int64)) *MockAccountingComponent_GetPriceByID_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run(args[0].(string), args[1].(int64))
	})
	return _c
}

func (_c *MockAccountingComponent_GetPriceByID_Call) Return(_a0 interface{}, _a1 error) *MockAccountingComponent_GetPriceByID_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

func (_c *MockAccountingComponent_GetPriceByID_Call) RunAndReturn(run func(string, int64) (interface{}, error)) *MockAccountingComponent_GetPriceByID_Call {
	_c.Call.Return(run)
	return _c
}

// GetQuotaByID provides a mock function with given fields: currentUser
func (_m *MockAccountingComponent) GetQuotaByID(currentUser string) (interface{}, error) {
	ret := _m.Called(currentUser)

	if len(ret) == 0 {
		panic("no return value specified for GetQuotaByID")
	}

	var r0 interface{}
	var r1 error
	if rf, ok := ret.Get(0).(func(string) (interface{}, error)); ok {
		return rf(currentUser)
	}
	if rf, ok := ret.Get(0).(func(string) interface{}); ok {
		r0 = rf(currentUser)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(interface{})
		}
	}

	if rf, ok := ret.Get(1).(func(string) error); ok {
		r1 = rf(currentUser)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// MockAccountingComponent_GetQuotaByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetQuotaByID'
type MockAccountingComponent_GetQuotaByID_Call struct {
	*mock.Call
}

// GetQuotaByID is a helper method to define mock.On call
//   - currentUser string
func (_e *MockAccountingComponent_Expecter) GetQuotaByID(currentUser interface{}) *MockAccountingComponent_GetQuotaByID_Call {
	return &MockAccountingComponent_G


loadTerminal_A_02)].Demo_PlayASForDemo({'ASName': 'GetOffStone_Skl', 'TargetIndex': -1, 'SeqBank': 0, 'IsIgnoreSame': False, 'IsEnabledAnimeDriven': 0, 'ClothWarpMode': 1, 'MorphingFrame': -1.0, 'IsWaitFinish': False})
        EventSystemActor.Demo_WaitFrame({'IsWaitFinish': True, 'Frame': 30})
        FldObj_DownloadTerminal_A_02[Demo641_1_SheikPadSetOff(FldObj_DownloadTerminal_A_02)].Demo_TrigNullASPlay({'IsWaitFinish': True, 'IsIgnoreSame': False, 'ASSlot': 0, 'SequenceBank': 0, 'ASName': 'Demo641_1-C01-Obj_DRCStoneStand_A_01-A-0'})
        EventSystemActor.Demo_WaitFrame({'IsWaitFinish': True, 'Frame': 50})
        FldObj_DownloadTerminal_A_02[Demo641_1_SheikPadSetOff(FldObj_DownloadTerminal_A_02)].Demo_TrigNullASPlay({'IsWaitFinish': True, 'IsIgnoreSame': False, 'ASSlot': 0, 'SequenceBank': 0, 'ASName': 'Demo641_1-C01-Obj_DRCStoneStand_A_01-A-1'})
        EventSystemActor.Demo_WaitFrame({'IsWaitFinish': True, 'Frame': 25})
    } {

        fork {
            Item_Conductor.Demo_Bind({'NodeName': 'Loc_Stone', 'IsWaitFinish': False, 'RotOffsetX': 0.0, 'RotOffsetY': 0.0, 'RotOffsetZ': 0.0, 'TransOffsetX': 0.0, 'TransOffsetY': 0.0, 'TransOffsetZ': 0.0, 'ActorName': 'ShiekerStoneBindTargetActorName', 'UniqueName': 'ShiekerStoneBindTargetUniqueName'})
        } {
            Item_Conductor.Demo_TrigNullASPlay({'IsWaitFinish': False, 'ASName': 'Off', 'ASSlot': 0, 'SequenceBank': 0, 'IsIgnoreSame': True})
        }

    }

}

void BindShiekerStone() {

    fork {
        FldObj_DownloadTerminal_A_02[BindShiekerStone(FldObj_DownloadTerminal_A_02)].Demo_TrigNullASPlay({'IsWaitFinish': True, 'IsIgnoreSame': False, 'ASName': 'ActivatedWait', 'ASSlot': 0, 'SequenceBank': 0})
        FldObj_DownloadTerminal_A_02[BindShiekerStone(FldObj_DownloadTerminal_A_02)].Demo_PlayASForDemo({'IsWaitFinish': False, 'TargetIndex': -1, 'SeqBank': 0, 'IsIgnoreSame': False, 'IsEnabledAnimeDriven': 0, 'ClothWarpMode': 1, 'MorphingFrame': -1.0, 'ASName': 'ActivatedWait_Skl'})
    } {
        Item_Conductor.Demo_Bind({'NodeName': 'Loc_Stone', 'IsWaitFinish': False, 'RotOffsetX': 0.0, 'RotOffsetY': 0.0, 'RotOffsetZ': 0.0, 'TransOffsetX': 0.0, 'TransOffsetY': 0.0, 'TransOffsetZ': 0.0, 'ActorName': 'ShiekerStoneBindTargetActorName', 'UniqueName': 'ShiekerStoneBindTargetUniqueName'})
    } {
        Item_Conductor.Demo_TrigNullASPlay({'IsWaitFinish': False, 'ASName': 'Off', 'ASSlot': 0, 'SequenceBank': 0, 'IsIgnoreSame': True})
    }

}


// Copyright (c) rubicon IT GmbH, www.rubicon.eu
//
// See the NOTICE file distributed with this work for additional information
// regarding copyright ownership.  rubicon licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License.  You may obtain a copy of the
// License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
// License for the specific language governing permissions and limitations
// under the License.
//
using System;
using System.Linq;
using System.Linq.Expressions;
using NUnit.Framework;
using Remotion.Linq.Clauses.Expressions;
using Remotion.Linq.Development.UnitTesting;
using Remotion.Linq.UnitTests.Parsing.Structure.IntermediateModel;
using Remotion.Linq.UnitTests.TestDomain;

namespace Remotion.Linq.UnitTests.Clauses.Expressions
{
  [TestFixture]
  public class SubQueryExpressionTest : ExpressionNodeTestBase
  {
#if NET_3_5
    [Test]
    public void NodeType ()
    {
      Assert.That (SubQueryExpression.ExpressionType,


(script);

            mta.triggerEvent("better-browsers:loaded", ']].. id ..[[')
        };

        document.body.appendChild(iframe);
    ]]

    if browserLoaded then
        executeBrowserJavascript(Browser, jsCode)
    else
        toLoadBrowsers[id] = jsCode
    end

    toLoad = {}
    return true
end

-- Exported --
function executeJavascript(theBrowser, js)
    assert(isElement(theBrowser) , "Bad argument 1 @ executeJavascript (element expected, got " .. type(theBrowser) .. ")")
    assert(type(js)=="string", "Bad argument 2 @ executeJavascript (string expected, got " .. type(js) .. ")")

    if not browsers[theBrowser] then
        return false, 'invalid browser / create new one'
    end

    local iframeId = browsers[theBrowser].id
    if iframeId then
        executeBrowserJavascript(Browser,[[
            var iframe = document.getElementById(']]..iframeId..[[');
            if (iframe) {
                iframe.contentWindow.eval(`]]..js..[[`);
            }
        ]])
    end
end

function toggleDevTools(bool)
    assert(type(bool)=="boolean", "Bad argument 2 @ toggleDevTools (boolean expected, got " .. type(bool) .. ")")

    if not getDevelopmentMode( ) then
        return false
    end

    return toggleBrowserDevTools(Browser, bool)
end


Balance+account.UsableCredits <= account.DeductionBalance {
		return admission.ValidationResponse(false, fmt.Sprintf(code.MessageFormat, code.InsufficientBalance, fmt.Sprintf("account balance less than 0, now account is %.2f¥. Please recharge the user %s.", GetAccountDebtBalance(account), user)))
	}
	return admission.Allowed(fmt.Sprintf("pass user %s, namespace %s", user, ns.Name))
}

func isDefaultQuotaName(name string) bool {
	return strings.HasPrefix(name, "quota-") || name == debtLimit0QuotaName
}

func GetAccountDebtBalance(account *pkgtype.UsableBalanceWithCredits) float64 {
	return account2.GetCurrencyBalance(account.Balance + account.UsableCredits - account.DeductionBalance)
}

const debtLimit0QuotaName = "debt-limit0"
/*
Copyright 2022 labring.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package v1 contains API Schema definitions for the terminal v1 API group
// +kubebuilder:object:generate=true
// +groupName=terminal.sealos.io
package v1

import (
	"k8s.io/apimachinery/pkg/runtime/schema"
	"sigs.k8s.io/controller-runtime/pkg/scheme"
)

var (
	// GroupVersion is group version used to register these objects
	GroupVersion = schema.GroupVersion{Group: "terminal.sealos.io", Version: "v1"}

	// SchemeBuilder is used to add go types to the GroupVersionKind scheme
	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

	// AddToScheme adds the types in this group-version to the given scheme.
	AddToScheme = SchemeBuilder.AddToScheme
)
/*
Copyright 2023.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package controllers

import (
	"bytes"
	"context"
	"fmt"
	"strings"
	"time"

	"github.com/go-logr/logr"
	"github.com/minio/madmin-go/v3"
	"github.com/minio/minio-go/v7"

	myObjectStorage "github.com/labring/sealos/controllers/pkg/objectstorage"
	"github.com/labring/sealos/controllers/pkg/utils/env"

	objectstoragev1 "github/labring/sealos/controllers/objectstorage/api/v1"

	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/util/rand"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s


oScpFileEngineNodeDto(engineNode);
        scpFileEngineNodeDto.setPasswd(aesUtils.decrypt(scpFileEngineNodeDto.getPasswd()));

        // 修改状态
        engineNode.setStatus(ClusterNodeStatus.CHECKING);
        engineNode.setAgentLog("检测中");

        // 持久化
        clusterNodeRepository.saveAndFlush(engineNode);

        // 异步调用
        runAgentCheckService.run(checkAgentReq.getEngineNodeId(), scpFileEngineNodeDto, TENANT_ID.get(), USER_ID.get());
    }

    public TestAgentRes testAgent(TestAgentReq testAgentReq) {

        ScpFileEngineNodeDto scpFileEngineNodeDto = ScpFileEngineNodeDto.builder().host(testAgentReq.getHost())
            .port(testAgentReq.getPort()).passwd(testAgentReq.getPasswd()).username(testAgentReq.getUsername()).build();
        String testAgent = "echo 'hello'";
        try {
            String testBack = SshUtils.executeCommand(scpFileEngineNodeDto, testAgent, false);
            if ("hello\n".equals(testBack)) {
                return TestAgentRes.builder().status("SUCCESS").log("链接成功").build();
            } else {
                return TestAgentRes.builder().status("FAIL").log(testBack).build();
            }
        } catch (JSchException | InterruptedException | IOException e) {
            return TestAgentRes.builder().status("FAIL").log(e.getMessage()).build();
        }
    }

    /**
     * 安装节点.
     */
    public void installAgent(InstallAgentReq installAgentReq) {

        ClusterNodeEntity clusterNode = clusterNodeService.getClusterNode(installAgentReq.getEngineNodeId());

        ClusterEntity cluster = clusterService.getCluster(clusterNode.getClusterId());

        // 如果是安装中等状态，需要等待运行结束
        if (ClusterNodeStatus.CHECKING.equals(clusterNode.getStatus())
            || ClusterNodeStatus.INSTALLING.equals(clusterNode.getStatus())
            || ClusterNodeStatus.REMOVING.equals(clusterNode.getStatus())
            || ClusterNodeStatus.STARTING.equals(clusterNode.getStatus())
            || ClusterNodeStatus.STOPPING.equals(clusterNode.getStatus())
            || ClusterNodeStatus.RUNNING.equals(clusterNode.getStatus())) {
            throw new IsxAppException("当前状态无法操作，请稍后再试");
        }

        // 将节点信息转成工具类识别对象
        ScpFileEngineNodeDto scpFileEngineNodeDto =
            engineNodeMapper.engineNodeEntityToScpFileEngineNodeDto(clusterNode);
        scpFileEngineNodeDto.setPasswd(aesUtils.decrypt(scpFileEngineNodeDto.getPasswd()));

        // 修改状态
        clusterNode.setStatus(ClusterNodeStatus.INSTALLING);
        clusterNode.setAgentLog("激活中");

        // 持久化
        clusterNodeRepository.saveAndFlush(clusterNode);

        // 异步调用
        runAgentInstallService.run(installAgentReq.getEngineNodeId(), cluster.getClusterType(), scpFileEngineNodeDto,
            TENANT_ID.get(), USER_ID.get());
    }

    public void removeAgent(RemoveAgentReq removeAgentReq) {

        // 获取节点信息
        ClusterNodeEntity engineNode = clusterNodeService.getClusterNode(removeAgentReq.getEngineNodeId());

        // 如果是安装中等状态，需要等待运行结束
        if (ClusterNodeStatus.CHECKING.equals(engineNode.getStatus())
            || ClusterNodeStatus.INSTALLING.equals(engineNode.getStatus())
            || ClusterNodeStatus.REMOVING.equals(engineNode.getStatus())) {
            throw new IsxAppException("当


1000)));
	else
		PlayerPVPTimerText:Hide();
	end
	CombatFeedback_OnUpdate(self, elapsed);
end

function PlayerFrame_OnReceiveDrag ()
	if ( CursorHasItem() ) then
		AutoEquipCursorItem();
	end
end

function PlayerFrame_UpdateStatus()
	if ( UnitHasVehiclePlayerFrameUI("player") ) then
		PlayerStatusTexture:Hide()
		PlayerRestIcon:Hide()
		PlayerAttackIcon:Hide()
		PlayerRestGlow:Hide()
		PlayerAttackGlow:Hide()
		PlayerStatusGlow:Hide()
		PlayerAttackBackground:Hide()
	elseif ( IsResting() ) then
		PlayerStatusTexture:SetVertexColor(1.0, 0.88, 0.25, 1.0);
		PlayerStatusTexture:Show();
		PlayerRestIcon:Show();
		PlayerAttackIcon:Hide();
		PlayerRestGlow:Show();
		PlayerAttackGlow:Hide();
		PlayerStatusGlow:Show();
		PlayerAttackBackground:Hide();
	elseif ( PlayerFrame.inCombat ) then
		PlayerStatusTexture:SetVertexColor(1.0, 0.0, 0.0, 1.0);
		PlayerStatusTexture:Show();
		PlayerAttackIcon:Show();
		PlayerRestIcon:Hide();
		PlayerAttackGlow:Show();
		PlayerRestGlow:Hide();
		PlayerStatusGlow:Show();
		PlayerAttackBackground:Show();
	elseif ( PlayerFrame.onHateList ) then
		PlayerAttackIcon:Show();
		PlayerRestIcon:Hide();
		PlayerStatusGlow:Hide();
		PlayerAttackBackground:Hide();
	else
		PlayerStatusTexture:Hide();
		PlayerRestIcon:Hide();
		PlayerAttackIcon:Hide();
		PlayerStatusGlow:Hide();
		PlayerAttackBackground:Hide();
	end
end

function PlayerFrame_UpdateGroupIndicator()
	PlayerFrameGroupIndicator:Hide();
	local name, rank, subgroup;
	if ( not IsInRaid() ) then
		PlayerFrameGroupIndicator:Hide();
		return;
	end
	local numGroupMembers = GetNumGroupMembers();
	for i=1, MAX_RAID_MEMBERS do
		if ( i <= numGroupMembers ) then
			name, rank, subgroup = GetRaidRosterInfo(i);
			-- Set the player's group number indicator
			if ( name == UnitName("player") ) then
				PlayerFrameGroupIndicatorText:SetText(GROUP.." "..subgroup);
				PlayerFrameGroupIndicator:SetWidth(PlayerFrameGroupIndicatorText:GetWidth()+40);
				PlayerFrameGroupIndicator:Show();
			end
		end
	end
end

function PlayerFrameDropDown_OnLoad (self)
	UIDropDownMenu_Initialize(self, PlayerFrameDropDown_Initialize, "MENU");
end

function PlayerFrameDropDown_Initialize ()
	if ( PlayerFrame.unit == "vehicle" ) then
		UnitPopup_ShowMenu(PlayerFrameDropDown, "VEHICLE", "vehicle");
	else
		UnitPopup_ShowMenu(PlayerFrameDropDown, "SELF", "player");
	end
end

function PlayerFrame_UpdatePlaytime()
	if ( PartialPlayTime() ) then
		PlayerPlayTimeIcon:SetTexture("Interface\\CharacterFrame\\UI-Player-PlayTimeTired");
		PlayerPlayTime.tooltip = format(PLAYTIME_TIRED, REQUIRED_REST_HOURS - floor(GetBillingTimeRested()/60));
		PlayerPlayTime:Show();
	elseif ( NoPlayTime() ) then
		PlayerPlayTimeIcon:SetTexture("Interface\\CharacterFrame\\UI-Player-PlayTimeUnhealthy");
		PlayerPlayTime.tooltip = format(PLAYTIME_UNHEALTHY, REQUIRED_REST_HOURS - floor(GetBillingTimeRested()/60));
		PlayerPlayTime:Show();
	else
		PlayerPl


 9.14062, 2.78125, 9.14062);
	symReturn.addQuadPoint(2.78125, 9.14062, 2.78125, 9.14062, 1.98438, 9.14062, 1.98438, 9.14062);
	symNewLine.resize(0);
	symNewLine.addQuadPoint(6.51562, 2.625, 6.51562, 2.625, 0.90625, 2.64062, 0.90625, 2.64062);
	symNewLine.addQuadPoint(0.90625, 2.64062, 0.90625, 2.64062, 1.4375, 1.92188, 1.26562, 2.1875);
	symNewLine.addQuadPoint(1.4375, 1.92188, 1.4375, 1.92188, 1.76562, 1.14062, 1.75, 1.42188);
	symNewLine.addQuadPoint(1.76562, 1.14062, 1.76562, 1.14062, 1.60938, 1.03125, 1.60938, 1.03125);
	symNewLine.addQuadPoint(1.60938, 1.03125, 1.60938, 1.03125, 0.90625, 1.92188, 0.90625, 1.92188);
	symNewLine.addQuadPoint(0.90625, 1.92188, 0.90625, 1.92188, 0, 2.90625, 0.578125, 2.23438);
	symNewLine.addQuadPoint(0, 2.90625, 0, 2.90625, 0.75, 3.875, 0.75, 3.875);
	symNewLine.addQuadPoint(0.75, 3.875, 0.75, 3.875, 1.57812, 4.78125, 1.1875, 4.40625);
	symNewLine.addQuadPoint(1.57812, 4.78125, 1.57812, 4.78125, 1.65625, 4.79688, 1.65625, 4.79688);
	symNewLine.addQuadPoint(1.65625, 4.79688, 1.65625, 4.79688, 1.76562, 4.65625, 1.76562, 4.65625);
	symNewLine.addQuadPoint(1.76562, 4.65625, 1.76562, 4.65625, 0.90625, 3.17188, 1.73438, 4.34375);
	symNewLine.addQuadPoint(0.90625, 3.17188, 0.90625, 3.17188, 0.96875, 3.125, 0.96875, 3.125);
	symNewLine.addQuadPoint(0.96875, 3.125, 0.96875, 3.125, 6.75, 3.125, 6.75, 3.125);
	symNewLine.addQuadPoint(6.75, 3.125, 6.75, 3.125, 6.51562, 2.625, 6.51562, 2.625);
	symNewLine.addQuadPoint(6.51562, 2.625, 6.51562, 2.625, 6.51562, 2.625, 6.51562, 2.625);
	symNewLine.setMarker();
	symNewLine.addQuadPoint(6.875, 0, 6.875, 0, 6.51562, 0, 6.51562, 0);
	symNewLine.addQuadPoint(6.51562, 0, 6.51562, 0, 6.51562, 2.84375, 6.51562, 2.84375);
	symNewLine.addQuadPoint(6.51562, 2.84375, 6.51562, 2.84375, 6.75, 3.125, 6.51562, 3.125);
	symNewLine.addQuadPoint(6.75, 3.125, 6.75, 3.125, 6


ca ca3```, means new configuration will be [ca2, ca3], ca1 is deleted, and ca3 is added
	* ```--registry-ca ca2```, means new configuration will be [ca2], ca1 is deleted
	* ```--registry-ca ""```, means ca1 and ca2 are all deleted // Here the empty string value is required, and the representation in different os platform is different.
	* nothing specified for registry-ca, then existing [ca1, ca2] is not changed

The benefit of this option is it can update all things in one command, and no new option introduced. User can use exactly same command option in both vic-machine create and vic-machine configure.

### Separate Configure to Sub Commands
The idea of this option is to update a few configuration each time, which is one delta update option. For example, to update volume-store, we can use following command
```
vic-machine configure volume-store --rm ds://datastore/volume:default
vic-machine configure volume-store --add nfs://host:port/container:nfs
```

The command format is like ```vic-machine configure <configure object> --<configure keyword> --<configure option> <configuration value>```

Pros:
- The whole configuration options are split to many sub commands. Then in each sub command, only a small number of options are available, and that does not increase over time. Only the sub command number will increase.
- Consistent with existing update firewall command format (though the command name might be different)

Cons:
- We'll need to reinvent option names

  For example, to update client network, user need to specify all options if they want to use static ip. Then in one update command, we'll need all those options. Here is the command looks like ```vic-machine configure bridge-network --port-group value --gateway value --ip value```
  The existing option name in vic-machine create is ```--client-network value   --client-network-gateway value  --client-network-ip value```, we'll need to remove the prefix cause that is already shown as sub-command name.

Decision: We'll go with the first option

## Show Existing VCH configuration
Right now, there is no user friendly way to view all configurations of existing VCH. To support update operation, we need to make it easier, otherwise, update only makes things weird.

vic-machine inspect command is available now, just it shows only the execution endpoint of VCH, instead of the configuration. We can extend that command, to support configuration inspection as well.

- vic-machine inspect <--configuration, --conf>
  show VCH configuration only
- vic-machine inspect <--execution, -e>
  show VCH execution endpoint (default behavior)

### Configuration Inspection
For configuration inspection, two output format should be supported

- yml format

  This should print out all VCH configuration with predefined categories, e.g. general information, storage, network, etc. in user friendly format. Secret information will be hidden or skipped.

Following is sample format:

```
General:
	Target: "vc.domain.com"
	Thumbprint: "98:97:D1:7B:DF:..."
	OpsUser: "Operator"
	Name: "VCH-1"
	Proxies:
		- "https://host:port"
		- "http://host:port"
Compute:
	Path: " myCluster/Resources/myRP"
	CpuLimit: 0 MHz
	MemoryLimit: 0 MHZ
Storage:
	ImageStore: "datastore"
	VolumeStore:
		- "ds://datastore/volumes/default": "default"
		- "nfs://userid@host:port/volumes/": "nfs"
Networks:
	BridgeNetwork:
		PortGroup: "bridge"
		IpRange: "172.16.0.0/12"
	ClientNetwork:
		PortGroup: "client"
		Gateway: "10.1.0.0/16,10.2.0.0/16:10.0.0.1"
		...


canTime = params.get("ScanTime")
        memeber_set = set(params.keys())
        for name, value in vars(self).items():
            property_name = name[1:]
            if property_name in memeber_set:
                memeber_set.remove(property_name)
        if len(memeber_set) > 0:
            warnings.warn("%s fileds are useless." % ",".join(memeber_set))

class ScanResultInfo(AbstractModel):
    """新手引导扫描结果信息PortNum   int
    	LeakNum   int
    	IPNum     int
    	IPStatus  bool
    	IdpStatus bool
    	BanStatus bool

    """

    def __init__(self):
        r"""
        :param _LeakNum: 暴露漏洞数量
        :type LeakNum: int
        :param _IPNum: 防护ip数量
        :type IPNum: int
        :param _PortNum: 暴露端口数量
        :type PortNum: int
        :param _IPStatus: 是否开启防护
        :type IPStatus: bool
        :param _IdpStatus: 是否拦截攻击
        :type IdpStatus: bool
        :param _BanStatus: 是否禁封端口
        :type BanStatus: bool
        """
        self._LeakNum = None
        self._IPNum = None
        self._PortNum = None
        self._IPStatus = None
        self._IdpStatus = None
        self._BanStatus = None

    @property
    def LeakNum(self):
        return self._LeakNum

    @LeakNum.setter
    def LeakNum(self, LeakNum):
        self._LeakNum = LeakNum

    @property
    def IPNum(self):
        return self._IPNum

    @IPNum.setter
    def IPNum(self, IPNum):
        self._IPNum = IPNum

    @property
    def PortNum(self):
        return self._PortNum

    @PortNum.setter
    def PortNum(self, PortNum):
        self._PortNum = PortNum

    @property
    def IPStatus(self):
        return self._IPStatus

    @IPStatus.setter
    def IPStatus(self, IPStatus):
        self._IPStatus = IPStatus

    @property
    def IdpStatus(self):
        return self._IdpStatus

    @IdpStatus.setter
    def IdpStatus(self, IdpStatus):
        self._IdpStatus = IdpStatus

    @property
    def BanStatus(self):
        return self._BanStatus

    @BanStatus.setter
    def BanStatus(self, BanStatus):
        self._BanStatus = BanStatus

    def _deserialize(self, params):
        self._LeakNum = params.get("LeakNum")
        self._IPNum = params.get("IPNum")
        self._PortNum = params.get("PortNum")
        self._IPStatus = params.get("IPStatus")
        self._IdpStatus = params.get("IdpStatus")
        self._BanStatus = params.get("BanStatus")
        memeber_set = set(params.keys())
        for name, value in vars(self).items():
            property_name = name[1:]
            if property_name in memeber_set:
                memeber_set.remove(property_name)
        if len(memeber_set) > 0:
            warnings.warn("%s fileds are useless." % ",".join(memeber_set))

class SecurityGroupBothWayInfo(AbstractModel):
    """双向下发的企业安全组规则

    """

    def __init__(self):
        r"""
        :param _OrderIndex: 执行顺序
注意：此字段可能返回 null，表示取不到有效值。
        :type OrderIndex: int
        :param _SourceId: 访问源
注意：此字段可能返回 null，表示取不到有效值。
        :type SourceId: str
        :param _SourceType: 访问源类型，默认为0，0: IP, 1: VPC, 2: SUBNET, 3: CVM, 4: CLB, 5: ENI, 6: CDB, 7: 参数模板, 100: 资产分组
注意：此字段可能返回 null，表示取不到有效值。
        :type SourceType: int
        :param _TargetId: 访问目的
注意：此字段可能返回 null，表示取不到有效值。
        :type TargetId: str
        :param _TargetType: 访问目的类型，默认为0，0: IP, 1: VPC, 2: SUBNET, 3: CVM, 4: CLB, 5: ENI, 6: CDB, 7: 参数模板, 100: 资产分组
注意：此字段可能返回 null，表示取不到有效值。
        :type TargetType: int
        :param _Protocol: 协议
注意：此字段可能返回 null，表示取不到有效值。
        :type Protocol: str
        :param _Port: 目的端口
注意：此字段可能返回 null，表示取不到有效值。
        :type Port: str
        :param _Strategy: 策略, 1：阻断，2：放行
注意：此字段可能返回 null，表示取不到有效值。
        :type Strategy: int
        :param _Direction: 方向，0：出站，1：入站，默认1
注意：此字段可能返回 null，表示取不到有效值。
        :type Direction: int
        :param _Region: 地域
        :type Region: str
        :param _Detail: 描述
注意：此字段可能返回 null，表示取不到有效值。
        :type Detail: str
        :param _Status: 是否开关开启，0：未开启，1：开启
注意：此字段可能返回 null，表示取不到有效值。
        :type Status: int
        :param _IsNew: 是否是正常规则，0：正常，1：异常
注意：此字段可能返回 null，表示取不到有效值。
        :type IsNew: int
        :param _BothWay: 单/双向下发，0:单向下发，1：双向下发
注意：此字段可能返回 null，表示取不到有效值。
        :type BothWay: int
        :param _VpcId: 私有网络ID
注意：此字段可能返回 null，表示取不到有效值。
        :type VpcId: str
        :param _SubnetId: 子网ID
注意：此字段可能返回 null，表示取不到有效值。
        :type SubnetId: str
        :param _InstanceName: 实例名称
注意：此字段可能返回 null，表示取不到有效值。
        :type InstanceName: str
        :param _PublicI


his.isValid()&&e.isValid()?e<this?this:e:g()}),Wr=L("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=bt.apply(null,arguments);return this.isValid()&&e.isValid()?e>this?this:e:g()}),Vr=function(){return Date.now?Date.now():+new Date},Rr=["year","quarter","month","week","day","hour","minute","second","millisecond"];Tt("Z",":"),Tt("ZZ",""),Z("Z",Qi),Z("ZZ",Qi),ne(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=Ct(Qi,e)});var Ur=/([\+\-]|\d\d)/gi;t.updateOffset=function(){};var zr=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Br=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;zt.fn=St.prototype,zt.invalid=kt;var Gr=Jt(1,"add"),qr=Jt(-1,"subtract");t.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",t.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Jr=L("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});G(0,["gg",2],0,function(){return this.weekYear()%100}),G(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Cn("gggg","weekYear"),Cn("ggggg","weekYear"),Cn("GGGG","isoWeekYear"),Cn("GGGGG","isoWeekYear"),O("weekYear","gg"),O("isoWeekYear","GG"),F("weekYear",1),F("isoWeekYear",1),Z("G",Ki),Z("g",Ki),Z("GG",Ui,Ni),Z("gg",Ui,Ni),Z("GGGG",qi,Vi),Z("gggg",qi,Vi),Z("GGGGG",Ji,Ri),Z("ggggg",Ji,Ri),ie(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,i){t[i.substr(0,2)]=$(e)}),ie(["gg","GG"],function(e,n,i,r){n[r]=t.parseTwoDigitYear(e)}),G("Q",0,"Qo","quarter"),O("quarter","Q"),F("quarter",7),Z("Q",Fi),ne("Q",function(e,t){t[ar]=3*($(e)-1)}),G("D",["DD",2],"Do","date"),O("date","D"),F("date",9),Z("D",Ui),Z("DD",Ui,Ni),Z("Do",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),ne(["D","DD"],or),ne("Do",function(e,t){t[or]=$(e.match(Ui)[0],10)});var Xr=W("Date",!0);G("DDD",["


 from 'express';
import { connection } from 'mongoose';

import { Logger } from '../../core/util';
import Promotion, { PromotionInterface, PromotionType } from '../../models/Promotions';
import { MongoError } from 'mongodb';

/**
 * Add a promotion.
 * @api POST /api/promotion
 * @apiName AddPromotion
 * @apiGroup Promotion
 * @apiSuccess (201)
 * @apiFail (400) Missing or invalid fields are given or duplicate error.
 * @apiFail (404) The item provided is not found in database.
 */
export async function AddPromotion(
  req: e.Request,
  res: e.Response,
  next: NextFunction,
): Promise<void> {
  const body = req.body as PromotionInterface;
  if (!(body.name && body.groupOne && body.startTime && body.endTime)) {
    return res
      .status(400)
      .send({ message: 'Missing field.' })
      .end();
  }

  try {
    body.startTime = new Date(body.startTime);
    body.endTime = new Date(body.endTime);
  } catch (error) {
    Logger.error(error);
    return res
      .status(400)
      .send({ message: 'startTime or endTime is not correct or provided.' })
      .end();
  }

  for (const item of body.groupOne) {
    const hasFound = await connection.db.collection('items').findOne({ 單品名稱: item });
    if (!hasFound) {
      return res
        .status(404)
        .send({ message: `Cannot not found item "${item}".` })
        .end();
    }
  }

  if (body.type === 'combination') {
    if (body.groupTwo) {
      for (const item of body.groupTwo) {
        const hasFound = await connection.db
          .collection('items')
          .findOne({ 單品名稱: item });
        if (!hasFound) {
          res
            .status(404)
            .send({ message: `Cannot not found item "${item}".` })
            .end();
        }
      }
    } else {
      res
        .status(400)
        .send({ message: 'groupTwo is required when type equals to combinations.' })
        .end();
    }
  }

  try {
    const promotion = new Promotion(body);
    await promotion.save();
    res.status(201).send({ id: promotion._id });
  } catch (error) {
    if (error instanceof MongoError) {
      res.status(400).send({ message: 'Duplicate name.' });
      return;
    }
    return next(error);
  }
}

interface GetPromotionsQuery {
  type?: PromotionType;
  limit?: string;
  page?: string;
}

/**
 * Get promotion list.
 * Get latest promotion list. If the page and limit is not set,
 * The api will return the newest 50 records.
 * @api GET /api/promotion
 * @apiName GetPromotions
 * @apiGroup Promotion
 * @apiQuery type
 * @apiQuery limit
 * @api page
 * @apiSuccess (200)
 * @apiFail (404) The analysis is not found(handle by middleware).
 */
export async function GetPromotions(req: e.


href="yyjson_8h.html#a55f4228c2d65d497ad3cee8abe95c0be">yyjson.h

yyjson_mut_obj_iter_remove() : yyjson.h

yyjson_mut_obj_iter_with() : yyjson.h

yyjson_mut_obj_put() : yyjson.h

yyjson_mut_obj_remove() : yyjson.h

yyjson_mut_obj_remove_key() : yyjson.h

yyjson_mut_obj_remove_keyn() : yyjson.h

yyjson_mut_obj_remove_str() : yyjson.h

yyjson_mut_obj_remove_strn() : yyjson.h

yyjson_mut_obj_rename_key() : yyjson.h

yyjson_mut_obj_rename_keyn() : yyjson.h

yyjson_mut_obj_replace() : yyjson.h

yyjson_mut_obj_rotate() : yyjson.h

yyjson_mut_obj_size() : yyjson.h

yyjson_mut_obj_with_kv() : yyjson.h

yyjson_mut_obj_with_str() : <a


ion (secondPass) {
		var axis = this,
			chart = axis.chart,
			options = axis.options,
			isLog = axis.isLog,
			isDatetimeAxis = axis.isDatetimeAxis,
			isXAxis = axis.isXAxis,
			isLinked = axis.isLinked,
			tickPositioner = axis.options.tickPositioner,
			maxPadding = options.maxPadding,
			minPadding = options.minPadding,
			length,
			linkedParentExtremes,
			tickIntervalOption = options.tickInterval,
			minTickIntervalOption = options.minTickInterval,
			tickPixelIntervalOption = options.tickPixelInterval,
			tickPositions,
			keepTwoTicksOnly,
			categories = axis.categories;

		// linked axis gets the extremes from the parent axis
		if (isLinked) {
			axis.linkedParent = chart[isXAxis ? 'xAxis' : 'yAxis'][options.linkedTo];
			linkedParentExtremes = axis.linkedParent.getExtremes();
			axis.min = pick(linkedParentExtremes.min, linkedParentExtremes.dataMin);
			axis.max = pick(linkedParentExtremes.max, linkedParentExtremes.dataMax);
			if (options.type !== axis.linkedParent.options.type) {
				error(11, 1); // Can't link axes of different type
			}
		} else { // initial min and max from the extreme data values
			axis.min = pick(axis.userMin, options.min, axis.dataMin);
			axis.max = pick(axis.userMax, options.max, axis.dataMax);
		}

		if (isLog) {
			if (!secondPass && mathMin(axis.min, pick(axis.dataMin, axis.min)) <= 0) { // #978
				error(10, 1); // Can't plot negative values on log axis
			}
			axis.min = correctFloat(log2lin(axis.min)); // correctFloat cures #934
			axis.max = correctFloat(log2lin(axis.max));
		}

		// handle zoomed range
		if (axis.range) {
			axis.userMin = axis.min = mathMax(axis.min, axis.max - axis.range); // #618
			axis.userMax = axis.max;
			if (secondPass) {
				axis.range = null;  // don't use it when running setExtremes
			}
		}

		// Hook for adjusting this.min and this.max. Used by bubble series.
		if (axis.beforePadding) {
			axis.beforePadding();
		}

		// adjust min and max for the minimum range
		axis.adjustForMinRange();

		// Pad the values to get clear of the chart's edges. To avoid tickInterval taking the padding
		// into account, we do this after computing tick interval (#1337).
		if (!categories && !axis.usePercentage && !isLinked && defined(axis.min) && defined(axis.max)) {
			length = axis.max - axis.min;
			if (length) {
				if (!defined(options.min) && !defined(axis.userMin) && minPadding && (axis.dataMin < 0 || !axis.ignoreMinPadding)) {
					axis.min -= length * minPadding;
				}
				if (!defined(options.max) && !defined(axis.userMax)  && maxPadding && (axis.dataMax > 0 || !axis.ignoreMaxPadding)) {
					axis.max += length * maxPadding;
				}
			}
		}

		// get tickInterval
		if (axis.min === axis.max || axis.min === undefined || axis.max === undefined) {
			axis.tickInterval = 1;
		} else if (isLinked && !tickIntervalOption &&
				tickPixelIntervalOption === axis.linkedParent.options.tickPixelInterval) {
			axis.tickInterval = axis.linkedParent.tickInterval;
		} else {
			axis.tickInterval = pick(
				tickIntervalOption,
				categories ? // for categoried axis, 1 is default, for linear axis use tickPix
					1 :
					// don't let it be more than the data range
					(axis.max - axis.min) * tickPixelIntervalOption / mathMax(axis.len, tickPixelIntervalOption)
			);
			// For squished axes, set only two ticks
			if (!defined(tick


  sum?: WatchSymbolsSumAggregateInputType
  min?: WatchSymbolsMinAggregateInputType
  max?: WatchSymbolsMaxAggregateInputType
}

export type GetWatchSymbolsAggregateType<T extends AggregateWatchSymbolsArgs> = {
  [P in keyof T]: P extends 'count' ? number : GetWatchSymbolsAggregateScalarType<T[P]>
}

export type GetWatchSymbolsAggregateScalarType<T extends any> = {
  [P in keyof T]: P extends keyof WatchSymbolsAvgAggregateOutputType ? WatchSymbolsAvgAggregateOutputType[P] : never
}

export type WatchSymbolsSelect = {
  id?: boolean
  symbol?: boolean
  minAmount?: boolean
  maxAmount?: boolean
  phone?: boolean
  createdAt?: boolean
  postedById?: boolean
  postedBy?: boolean | UserArgs
}

export type WatchSymbolsInclude = {
  postedBy?: boolean | UserArgs
}

export type WatchSymbolsGetPayload<
  S extends boolean | null | undefined | WatchSymbolsArgs,
  U = keyof S
> = S extends true
  ? WatchSymbols
  : S extends undefined
  ? never
  : S extends WatchSymbolsArgs | FindManyWatchSymbolsArgs
  ? 'include' extends U
    ? WatchSymbols  & {
      [P in TrueKeys<S['include']>]:
      P extends 'postedBy'
      ? UserGetPayload<S['include'][P]> | null : never
    }
  : 'select' extends U
    ? {
      [P in TrueKeys<S['select']>]:P extends keyof WatchSymbols ? WatchSymbols[P]
:
      P extends 'postedBy'
      ? UserGetPayload<S['select'][P]> | null : never
    }
  : WatchSymbols
: WatchSymbols

export interface WatchSymbolsDelegate {
  /**
   * Find zero or one WatchSymbols that matches the filter.
   * @param {FindOneWatchSymbolsArgs} args - Arguments to find a WatchSymbols
   * @example
   * // Get one WatchSymbols
   * const watchSymbols = await prisma.watchSymbols.findOne({
   *   where: {
   *     // ... provide filter here
   *   }
   * })
  **/
  findOne<T extends FindOneWatchSymbolsArgs>(
    args: Subset<T, FindOneWatchSymbolsArgs>
  ): CheckSelect<T, Prisma__WatchSymbolsClient<WatchSymbols | null>, Prisma__WatchSymbolsClient<WatchSymbolsGetPayload<T> | null>>
  /**
   * Find the first WatchSymbols that matches the filter.
   * @param {FindFirstWatchSymbolsArgs} args - Arguments to find a WatchSymbols
   * @example
   * // Get one WatchSymbols
   * const watchSymbols = await prisma.watchSymbols.findFirst({
   *   where: {
   *     // ... provide filter here
   *   }
   * })
  **/
  findFirst<T extends FindFirstWatchSymbolsArgs>(
    args: Subset<T, FindFirstWatchSymbolsArgs>
  ): CheckSelect<T, Prisma__WatchSymbolsClient<WatchSymbols>, Prisma__WatchSymbolsClient<WatchSymbolsGetPayload<T>>>
  /**
   * Find zero or more WatchSymbols that matches the filter.
   * @param {FindManyWatchSymbolsArgs=} args - Arguments to filter and select certain fields only.
   * @example
   * // Get all WatchSymbols
   * const watchSymbols = await prisma.watchSymbols.findMany()
   *
   * // Get first 10 WatchSymbols
   * const watchSymbols = await prisma.watchSymbols.findMany({ take: 10 })
   *
   * // Only select the `id`
   * const watchSymbolsWithIdOnly = await prisma.watchSymbols.findMany({ select: { id: true } })
   *
  **/
  findMany<T extends FindManyWatchSymbolsArgs>(
    args?: Subset<T, FindManyWat


Hull Model Ship](http://en.wikipedia.org/wiki/Half_hull_model_ship) (Wikipedia)
-   [Why Half Hulls](http://www.halfhullshipmodels.com/smf/discussions-of-half-hulls-and-ship-models/understanding-and-practising-half-hull-boat-modelling/?PHPSESSID=56fedd9f6fa2db453a77347f10d57b7f) (Maritime Half Hull Ship Models and Nautical Art website)
-   [Traditional Model Yacht Design](http://pages.swcp.com/usvmyg/design/design.htm) (US Vintage Model Yacht Group)

## Script

ToolBar Icon ![](images/Macro_Half_Hull_Model.png )

**Macro_Half_Hull_Model.FCMacro**

This script is running bug free. But due to the large range of possible inputs it may fail for some inputs. If so please report it.

The script is too long for the Wiki to display so it must be copied or downloaded from [unabbreviated script on pastebin.com](http://pastebin.com/raw.php?i=tZMpUi6F)

---
⏵ [documentation index](../README.md) > Macro Half-Hull Model/pl
#  Plot Workbench/pl

## Wprowadzenie

FreeCAD jest w stanie wykonywać wykresy przy użyciu biblioteki [Python](Python/pl.md) [matplotlib](https://matplotlib.org/). W tym celu w wersji 0.19 dostarczany jest moduł, jako zewnętrzny dodatek a od wersji 0.20 jako podstawowy komponent. Starsze wersje FreeCAD nie są objęte niniejszą dokumentacją.

Generowane wykresy oferują standardowe narzędzia [matplotlib](https://matplotlib.org/) do edycji i zapisu. Dodatkowo, środowisko pracy  [Wykres](Plot_Workbench/pl.md) jest dostarczane jako zewnętrzny dodatek oferujący bardziej kompletne narzędzia do edycji i zapisywania wykresu. Dodatek ten może być zainstalowany za pomocą [Menadżera dodatków](Std_AddonMgr/pl.md).

## Moduł

Moduł można wywołać w konsoli [Python](Python/pl.md) lub w [makrodefinicji](Macros/pl.md). Pierwszą rzeczą, niezbędna do wykonania jest zaimportowanie modułu. We FreeCAD v0.19 musisz najpierw zainstalować środowisko pracy  [Wykres](Plot_Workbench/pl.md) za pomocą [Menadżera dodatków](Std_AddonMgr/pl.md), a następnie możesz zaimportować pisanie wykresu

```python
from freecad.plot import Plot
```

Od wersji FreeCAD **v0.20** moduł Wykres jest wbudowany w program, więc nie trzeba instalować żadnego dodatku, a jedynie wpisać:

```python
from FreeCAD.Plot import Plot
```

Następnie można wykreślić linię prostą od współrzędnych *(0,0)* do *(1,2)* wpisując po prostu:

```python
Plot.plot([0, 1], [0, 2])
```

Bardziej złożone przykłady zn


     let tps = txs as f32 / duration_as_s(&duration);
                info!(
                    "Swapper {:9.2} TPS, Transactions: {:6}, Total transactions: {} over {} s",
                    tps,
                    txs,
                    total_txs,
                    total_elapsed.as_secs(),
                );
                txs = 0;
            }

            datapoint_info!("bench-exchange-swaps", ("count", to_swap_txs.len(), i64));

            let chunks: Vec<_> = to_swap_txs.chunks(chunk_size).collect();
            {
                let mut shared_txs_wl = shared_txs.write().unwrap();
                for chunk in chunks {
                    shared_txs_wl.push_back(chunk.to_vec());
                }
            }
            // Throttle the swapper so it doesn't try to catchup unbridled
            sleep(Duration::from_millis(transfer_delay / 2));
        }

        if exit_signal.load(Ordering::Relaxed) {
            break 'outer;
        }
    }
    info!(
        "Swapper sent {} at {:9.2} TPS",
        total_txs,
        total_txs as f32 / duration_as_s(&total_elapsed)
    );
    assert_eq!(
        order_book.get_num_outstanding().0 + order_book.get_num_outstanding().1,
        0
    );
}

#[allow(clippy::too_many_arguments)]
fn trader<T>(
    exit_signal: &Arc<AtomicBool>,
    sender: &Sender<Vec<TradeInfo>>,
    shared_txs: &SharedTransactions,
    signers: &[Arc<Keypair>],
    srcs: &[Pubkey],
    transfer_delay: u64,
    batch_size: usize,
    chunk_size: usize,
    account_groups: usize,
    client: &Arc<T>,
) where
    T: Client,
{
    // TODO Hard coded for now
    let pair = AssetPair::default();
    let tokens = 1;
    let price = 1000;
    let mut account_group: usize = 0;

    let mut txs = 0;
    let mut total_txs = 0;
    let mut now = Instant::now();
    let start_time = now;
    let mut total_elapsed = start_time.elapsed();

    loop {
        let trade_keys = generate_keypairs(batch_size as u64);

        let mut trades = vec![];
        let mut trade_infos = vec![];
        let start = account_group * batch_size as usize;
        let end = account_group * batch_size as usize + batch_size as usize;
        let mut side = OrderSide::Ask;
        for (signer, trade, src) in izip!(
            signers[start..end].iter(),
            trade_keys,
            srcs[start..end].iter(),
        ) {
            side = if side == OrderSide::Ask {
                OrderSide::Bid
            } else {
                OrderSide::Ask
            };
            let order_info = OrderInfo {
                /// Owner of the trade order
                owner: Pubkey::default(), // don't care
                side,
                pair,
                tokens,
                price,
                tokens_settled: 0,
            };
            trade_infos.push(TradeInfo {
                trade_account: trade.pubkey(),
                order_info,
            });
            trades.push((signer, trade, side, src));
        }
        account_group = (account_group + 1) % account_groups as usize;

        let (blockhash, _fee_calculator, _last_valid_slot) = client
            .get_recent_blockhash_with_commitment(CommitmentConfig::recent())
            .expect("Failed to get blockhash");

        trades.chunks(chunk_size).for_each(|chunk| {
            let trades_txs: Vec<_> = chunk
                .par_iter()
                .map(|(owner, trade, side, src)| {
                    let owner_pubkey = &owner.pubkey();
                    let trade_pubkey = &trade.pubkey();
                    let space = mem::size_of::<ExchangeState>() as u64;


None:
        """
        ブックマークデータをバックアップする

        Args:
            backup_path: バックアップファイルのパス

        Raises:
            RepositoryError: バックアップ処理でエラーが発生した場合
        """
        pass

    @abstractmethod
    def restore_bookmarks(self, backup_path: str) -> int:
        """
        バックアップからブックマークデータを復元する

        Args:
            backup_path: バックアップファイルのパス

        Returns:
            復元されたブックマーク数

        Raises:
            RepositoryError: 復元処理でエラーが発生した場合
        """
        pass

    @abstractmethod
    def clear_all_bookmarks(self) -> int:
        """
        すべてのブックマークを削除する

        Returns:
            削除されたブックマーク数

        Raises:
            RepositoryError: 削除処理でエラーが発生した場合
        """
        pass

class BookmarkRepositoryError(Exception):
    """
    ブックマークリポジトリ操作でのエラー

    データ保存、読み込み、検索エラー等の
    ブックマークリポジトリ層で発生する例外のクラス。
    """

    def __init__(self, message: str, original_error: Optional[Exception] = None):
        """
        エラーを初期化する

        Args:
            message: エラーメッセージ
            original_error: 元の例外（オプション）
        """
        super().__init__(message)
        self.original_error = original_error

    def __str__(self) -> str:
        """エラー内容の文字列表現を返す"""
        if self.original_error:
            return f"{super().__str__()} (原因: {self.original_error})"
        return super().__str__()


 are a few different ways you can save those changes back to Parse over the network. The easiest way to do this is with `saveEventually`. When you call `saveEventually` on a `ParseObject`, it will be pinned until it can be saved. The SDK will make sure to save the object the next time the network is available.

```java
gameScore.saveEventually();
```

If you'd like to have more control over the way objects are synced, you can keep them in the local datastore until you are ready to save them yourself using `saveInBackground`. To manage the set of objects that need to be saved, you can again use a label. The `fromPin` method on `ParseQuery` makes it easy to fetch just the objects you care about.

```java
ParseQuery<ParseObject> query = ParseQuery.getQuery(“GameScore");
query.fromPin(“MyChanges”);
query.findInBackground(new FindCallback<ParseObject>() {
  public void done(List<ParseObject> scores, ParseException e) {
    for (ParseObject score in scores) {
      score.saveInBackground();
      score.unpinInBackground(“MyChanges”);
    }
  }
});
```
# Objects

## The ParseObject

Storing data on Parse is built around the `ParseObject`. Each `ParseObject` contains key-value pairs of JSON-compatible data. This data is schemaless, which means that you don't need to specify ahead of time what keys exist on each `ParseObject`. You simply set whatever key-value pairs you want, and our backend will store it.

For example, let's say you're tracking high scores for a game. A single `ParseObject` could contain:

```javascript
score: 1337, playerName: "Sean Plott", cheatMode: false
```

Keys must be alphanumeric strings. Values can be strings, numbers, booleans, or even arrays and objects - anything that can be JSON-encoded.

Each `ParseObject` has a class name that you can use to distinguish different sorts of data. For example, we could call the high score object a `GameScore`. We recommend that you NameYourClassesLikeThis and nameYourKeysLikeThis, just to keep your code looking pretty.

## Saving Objects

Let's say you want to save the `GameScore` described above to your Parse Server. The interface is similar to a `Map`, plus the `saveInBackground` method:

```java
ParseObject gameScore = new ParseObject("GameScore");
gameScore.put("score", 1337);
gameScore.put("playerName", "Sean Plott");
gameScore.put("cheatMode", false);
gameScore.saveInBackground();
```

After this code runs, you will probably be wondering if anything really happened. To make sure the data was saved, you can look at the Data Browser in your app on Parse. You should see something like this:

```jsonc
{
  "objectId": "xWMyZ4YEGZ",
  "score": 1337,
  "playerName": "Sean Plott",
  "cheatMode": false,
  "createdAt":"2022-01-01T12:23:45.678Z",
  "updatedAt":"2022-01-01T12:23:45.678Z"
}
```

There are two things to note here. You didn't have to configure or set up a new Class called `GameScore` before running this code. Your Parse app lazily creates this Class for you when it first encounters it.

There are also a few fields you don't need to specify that are provided as a convenience. `objectId` is a unique identifier for each saved object. `createdAt` and `updatedAt` represent the time that each object was created and last modified in the cloud. Each of these fields is filled in by Parse, so they don't exist on a `ParseObject` until a save operation has completed.

## Retrieving Objects

Saving data to the cloud is fun, but it's even more fun to get that data out again. If you have the `objectId`, which is available once the `ParseObject` been uploaded to the server, you can retrieve the whole `ParseObject` using a `ParseQuery`:

```java
ParseQuery<ParseObject> quer


rem;
}
.tooltip .arrow::before {
  position: absolute;
  content: "";
  border-color: transparent;
  border-style: solid;
}
.bootstrapiso .bs-tooltip-top,
.bootstrapiso .bs-tooltip-auto[x-placement^="top"] {
  padding: 0.4rem 0;
}
.bootstrapiso .bs-tooltip-top .arrow,
.bootstrapiso .bs-tooltip-auto[x-placement^="top"] .arrow {
  bottom: 0;
}
.bootstrapiso .bs-tooltip-top .arrow::before,
.bootstrapiso .bs-tooltip-auto[x-placement^="top"] .arrow::before {
  top: 0;
  border-width: 0.4rem 0.4rem 0;
  border-top-color: #000;
}
.bootstrapiso .bs-tooltip-right,
.bootstrapiso .bs-tooltip-auto[x-placement^="right"] {
  padding: 0 0.4rem;
}
.bootstrapiso .bs-tooltip-right .arrow,
.bootstrapiso .bs-tooltip-auto[x-placement^="right"] .arrow {
  left: 0;
  width: 0.4rem;
  height: 0.8rem;
}
.bootstrapiso .bs-tooltip-right .arrow::before,
.bootstrapiso .bs-tooltip-auto[x-placement^="right"] .arrow::before {
  right: 0;
  border-width: 0.4rem 0.4rem 0.4rem 0;
  border-right-color: #000;
}
.bootstrapiso .bs-tooltip-bottom,
.bootstrapiso .bs-tooltip-auto[x-placement^="bottom"] {
  padding: 0.4rem 0;
}
.bootstrapiso .bs-tooltip-bottom .arrow,
.bootstrapiso .bs-tooltip-auto[x-placement^="bottom"] .arrow {
  top: 0;
}
.bootstrapiso .bs-tooltip-bottom .arrow::before,
.bootstrapiso .bs-tooltip-auto[x-placement^="bottom"] .arrow::before {
  bottom: 0;
  border-width: 0 0.4rem 0.4rem;
  border-bottom-color: #000;
}
.bootstrapiso .bs-tooltip-left,
.bootstrapiso .bs-tooltip-auto[x-placement^="left"] {
  padding: 0 0.4rem;
}
.bootstrapiso .bs-tooltip-left .arrow,
.bootstrapiso .bs-tooltip-auto[x-placement^="left"] .arrow {
  right: 0;
  width: 0.4rem;
  height: 0.8rem;
}
.bootstrapiso .bs-tooltip-left .arrow::before,
.bootstrapiso .bs-tooltip-auto[x-placement^="left"] .arrow::before {
  left: 0;
  border-width: 0.4rem 0 0.4rem 0.4rem;
  border-left-color: #000;
}
.tooltip-inner {
  max-width: 200px;
  padding: 0.25rem 0.5rem;
  color: #fff;
  text-align: center;
  background-color: #000;
  border-radius: 0.25rem;
}
.bootstrapiso .popover {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1060;
  display: block;
  max-width: 276px;
  font-family: "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  font-style: normal;
  font-weight: 400;
  line-height: 1.5;
  text-align: left;
  text-align: start;
  text-decoration: none;
  text-shadow: none;
  text-transform: none;
  letter-spacing: normal;
  word-break: normal;
  word-spacing: no


Social-Community/Ocelot-Social/pull/3934/commits/4a910664eb3e79d0cf6fb9288dfa71ed6b3dde1c">Parameterize entire html of terms+conditions

          4a91066

          <svg class="octicon octicon-git-commit" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M10.5 7.75a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm1.43.75a4.002 4.002 0 01-7.86 0H.75a.75.75 0 110-1.5h3.32a4.001 4.001 0 017.86 0h3.32a.75.75 0 110 1.5h-3.32z"></path></svg>

          <a title="Make four stati


,void 0,o.mark((function r(){var i,s,a,u,p,f,h,y,m;return o.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return(i=new l.RippleSignTx).setAddressNList(t.addressNList),i.setFee(parseInt(t.tx.value.fee.amount[0].amount)),i.setSequence(parseInt(t.sequence)),i.setLastLedgerSequence(parseInt(t.lastLedgerSequence)),(s=new l.RipplePayment).setAmount(parseInt(t.payment.amount)),s.setDestination(t.payment.destination),void 0!==t.payment.destinationTag&&s.setDestinationTag(parseInt(t.payment.destinationTag)),i.setPayment(s),r.next=12,e.call(c.MessageType.MESSAGETYPE_RIPPLESIGNTX,i,g.LONG_TIMEOUT,!0);case 12:if((a=r.sent).message_type!==g.Events.FAILURE){r.next=15;break}throw a;case 15:u=n(t.tx.value.msg),r.prev=16,u.s();case 18:if((p=u.n()).done){r.next=34;break}if(f=p.value,void 0,"ripple-sdk/MsgSend"!==f.type){r.next=29;break}if(1===f.value.amount.length){r.next=24;break}throw new Error("ripple: Multiple amounts per msg not supported");case 24:if("drop"===(h=f.value.amount[0].denom)){r.next=27;break}throw new Error("ripple: Unsupported denomination: "+h);case 27:r.next=30;break;case 29:throw new Error("ripple: Message ".concat(f.type," is not yet supported"));case 30:if(a.message_type!==g.Events.FAILURE){r.next=32;break}throw a;case 32:r.next=18;break;case 34:r.next=39;break;case 36:r.prev=36,r.t0=r.catch(16),u.e(r.t0);case 39:return r.prev=39,u.f(),r.finish(39);case 42:if(a.message_enum===c.MessageType.MESSAGETYPE_RIPPLESIGNEDTX){r.next=44;break}throw new Error("ripple: unexpected response ".concat(a.message_type));case 44:return y=a.proto,(m=d.default.cloneDeep(t.tx)).value.signatures=[{serializedTx:y.getSerializedTx_asB64(),signature:y.getSignature_asB64()}],r.abrupt("return",m);case 48:case"end":return r.stop()}}),r,null,[[16,36,39,42]])})))})));case 1:case"end":return r.stop()}}),r)})))},t.rippleGetAddress=function(e,t){return u(this,void 0,void 0,o.mark((function r(){var n,i,s;return o.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return(n=new l.RippleGetAddress).setAddressNList(t.addressNList),n.setShowDisplay(!1!==t.showDisplay),r.next=5,e.call(c.MessageType.MESSAGETYPE_RIPPLEGETADDRESS,n,g.LONG_TIME


loud.Vod.V20180717.Models
{
    using Newtonsoft.Json;
    using System.Collections.Generic;
    using TencentCloud.Common;

    public class MediaSubtitleInfo : AbstractModel
    {

        /// <summary>
        /// 字幕信息列表。
        /// </summary>
        [JsonProperty("SubtitleSet")]
        public MediaSubtitleItem[] SubtitleSet{ get; set; }

        /// <summary>
        /// For internal usage only. DO NOT USE IT.
        /// </summary>
        public override void ToMap(Dictionary<string, string> map, string prefix)
        {
            this.SetParamArrayObj(map, prefix + "SubtitleSet.", this.SubtitleSet);
        }
    }
}