code:
//=============================================================================
// Yanfly Engine Plugins - Skill Cost Extension - Cooldowns
// YEP_X_SkillCooldowns.js
//=============================================================================

var Imported = Imported || {};
Imported.YEP_X_SkillCooldowns = true;

var Yanfly = Yanfly || {};
Yanfly.SCD = Yanfly.SCD || {};

//=============================================================================
/*:
 * @plugindesc v1.01 (Requires YEP_SkillCore.js) Cooldowns can be applied
 * to skills to prevent them from being used continuously.
 * @author Yanfly Engine Plugins
 *
 * @param ---Cooldown---
 * @default
 *
 * @param Cooldown Format
 * @desc This is the text format used for cooldowns.
 * %1 - Turns Remaining
 * @default %1CD
 *
 * @param Cooldown Font Size
 * @desc This is the font size used for cooldowns.
 * Default: 28
 * @default 20
 *
 * @param Cooldown Text Color
 * @desc Adjusts the text color used for cooldowns.
 * @default 6
 *
 * @param Cooldown Icon
 * @desc What icon to be used for cooldowns.
 * Use 0 for no icon.
 * @default 75
 *
 * @param Cooldown After Battle
 * @desc How are cooldowns handled after battle?
 * @default -10
 *
 * @param Cooldown Steps
 * @desc Outside of battle, this is how many steps on the map the
 * player must walk to drop each cooldown by 1.
 * @default 5
 *
 * @param Cooldown Bypass
 * @desc This is a list of skills that cannot be on cooldown so that
 * way, skills like Attack, Guard.
 * @default 1 2 3 4 5 6 7
 *
 * @param ---Warmup---
 * @default
 *
 * @param Warmup Format
 * @desc This is the text format used for warmups.
 * %1 - Turns Remaining
 * @default %1WU
 *
 * @param Warmup Font Size
 * @desc This is the font size used for warmups.
 * Default: 28
 * @default 20
 *
 * @param Warmup Text Color
 * @desc Adjusts the text color used for warmups.
 * @default 4
 *
 * @param Warmup Icon
 * @desc What icon to be used for warmups.
 * Use 0 for no icon.
 * @default 75
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin requires YEP_SkillCore.
 * Make sure this plugin is located under YEP_SkillCore in the plugin list.
 *
 * This plugin allows you to give your skills cooldowns. Cooldowns are a limit
 * enforced on a skill to prevent them from being used constantly.
 *
 * ============================================================================
 * Cooldown Types
 * ============================================================================
 *
 * Cooldown (Standard)
 * The standard cooldown only occurs if the skill has a cooldown to pay. When
 * used, the skill cannot be used for x turns as indicated by the cooldown.
 * There are a number of things that contribute to cooldowns going down. The
 * first would be simply waiting. Each turn in battle causes a cooldown to
 * drop by 1 turn. Skills and the such can be used to speed up this process.
 * The second would be to finish battles. Finishing a battle will cause all
 * cooldowns to drop by a certain amount (can be defined in the parameters).
 * And the third would be walking on the field map. Every certain amount of
 * steps allow a skill's cooldown to decrease.
 *
 * Warmups
 * As far as most things go, Warmups do the same thing as Cooldowns: prevent
 * skills from being used until their timer is up. The difference, however, is
 * that warmups only occur once during battle: at the very start of it. If a
 * skill has a warmup timer, it will trigger the moment it goes into battle
 * and instantly disappear after battle. Warmups do not stack on top of any
 * existing cooldowns. If a cooldown is already occurring when a skill is in
 * the warmup phase, both the warmup and cooldown simultaneously update.
 *
 * Linked Cooldowns
 * A linked cooldown occurs when a skill that's used causes another skill in
 * the owner's skill library to have a cooldown. All other attributes of this
 * cooldown are the same as a standard cooldown's. This cooldown type will take
 * priority over Skill Type Cooldowns and Global Cooldowns if this value is
 * defined.
 *
 * Skill Type Cooldowns
 * When a Skill Type Cooldown occurs, all skills currently in the battler's
 * skill library with the matching Skill Type will be on cooldown. All other
 * attributes of this cooldown are the same as a standard cooldown's. This
 * cooldown type will take priority over Global Cooldowns if this value is
 * defined.
 *
 * When a cooldown is applied for a skill that already has a cooldown, the
 * cooldown will change to whatever is the largest value. This means if a
 * skill has 3 turns for a cooldown and a Skill Type Cooldown would set for
 * 1 turn, the 3 turns would remain. On the flip side, if the skill has 3 turns
 * and the Skill Type Cooldown would set for 5 turns, then the cooldown would
 * be changed to 5 turns instead.
 *
 * ============================================================================
 * Notetags
 * ============================================================================
 *
 * Use the following notetags to alter the cooldown properties of a skill.
 *
 * Skill Notetags:
 *   <Cooldown: x>
 *   Sets the cooldown for the skill to X turns. This cooldown only affects
 *   this skill alone. This value will take priority over Skill Type Cooldowns
 *   and Global Cooldowns.
 *
 *   <After Battle Cooldown: +x>
 *   <After Battle Cooldown: -x>
 *   After a battle ends (victory, loss, or escape), change the cooldown for
 *   this skill by +x turns or -x turns.
 *
 *   <Cooldown Steps: x>
 *   Outside of battle, every x steps that the Player takes, this skill's
 *   cooldown will drop by 1.
 *
 *   <Skill x Cooldown: y>
 *   When using this skill, after paying the skill cost, skill x will have a
 *   linked cooldown of y turns. This value will take priority over Skill Type
 *   Cooldowns and Global Cooldowns.
 *
 *   <SType x Cooldown: y>
 *   When using this skill, after paying the skill cost, all skills with the
 *   matching Skill Type x to have a cooldown of y. This value will take
 *   priority over Global Cooldowns.
 *
 *   <Global Cooldown: x>
 *   When using this skill, all skills within the battler's skill library area
 *   set to be on cooldown for x turns. This value has less priority than
 *   Individual Cooldowns and Skill Type Cooldowns.
 *
 *   <Bypass Cooldown>
 *   This causes the skill to bypass cooldowns, no matter what. This should be
 *   used for skills like Attack, Guard, Escape, etc. that should not have a
 *   cooldown assigned to them.
 *
 * Skill and Item Notetags:
 *   <Skill x Cooldown: +y>
 *   <Skill x Cooldown: -y>
 *   Targets hit by this skill will have skill x's cooldown adjusted by y.
 *   This does not apply to the user and applies only to the targets.
 *
 *   <SType x Cooldown: +y>
 *   <SType x Cooldown: -y>
 *   Targets hit by this skill will have all skills in their skill library with
 *   Skill Type x to have their cooldowns adjusted by y. This does not apply to
 *   the user and applies only to the targets.
 *
 *   <Global Cooldown: +x>
 *   <Global Cooldown: -x>
 *   Targets hit by this skill will have all skills in their skill library to
 *   have their cooldowns adjusted by y. This does not apply to the user and
 *   applies only to the targets.
 *
 * Actor, Class, Enemy, Weapon, Armor, and State Notetags:
 *
 *   <Skill x Cooldown Duration: y%>
 *   Alters the cooldown duration of skill x to y% when the cooldown cost is
 *   applied. This effect only applies to skill x.
 *
 *   <SType x Cooldown Duration: y%>
 *   Alters the cooldown duration of skills with Skill Type x to y% when the
 *   cooldown cost is applied. This effect only applies to Skill Type x.
 *
 *   <Global Cooldown Duration: x%>
 *   Alters the cooldown duration of all skills to x% when the cooldown cost
 *   is applied.
 *
 *   <Skill x Cooldown Rate: y%>
 *   Sets the cooldown rate for skill x to y% when the cooldown counter goes
 *   down. This effect only applies to skill x.
 *
 *   <SType x Cooldown Rate: y%>
 *   Sets the cooldown rate for Skill Type x skills to y% when the cooldown
 *   counter goes down. This effect only applies to Skill Type x skills.
 *
 *   <Global Cooldown Rate: x%>
 *   Sets the cooldown rate for all skills to x% when the cooldown counter
 *   goes down.
 *
 *   <Skill x Cooldown: +y>
 *   <Skill x Cooldown: -y>
 *   If the user performs skill x, it will have an increased or decreased
 *   cooldown value as long as the user is the actor, class, enemy, or has the
 *   weapon or armor equipped, or is affected by the state with this notetag.
 *   These flat cooldown modifications are applied after the rates and duration
 *   modifiers have been calculated.
 *
 *   <SType x Cooldown: +y>
 *   <SType x Cooldown: -y>
 *   If the user performs skill with skill type x, it will have an increased or
 *   decreased cooldown value as long as the user is the actor, class, enemy,
 *   or has the weapon or armor equipped, or is affected by the state with this
 *   notetag. These flat cooldown modifications are applied after the rates and
 *   duration modifiers have been calculated.
 *
 *   <Global Cooldown: +x>
 *   <Global Cooldown: -x>
 *   If the user performs any skill, it will have an increased or decreased
 *   cooldown value as long as the user is the actor, class, enemy, or has the
 *   weapon or armor equipped, or is affected by the state with this notetag.
 *   These flat cooldown modifications are applied after the rates and duration
 *   modifiers have been calculated.
 *
 *   <Skill x Warmup: +y>
 *   <Skill x Warmup: -y>
 *   At the start of battle, skill x will have an increased or decreased warmup
 *   value as long as the user is the actor, class, enemy, or has the weapon or
 *   armor equipped, or is affected by the state with this notetag. These flat
 *   warmup modifications are applied after the rates and duration modifiers
 *   have been calculated.
 *
 *   <SType x Warmup: +y>
 *   <SType x Warmup: -y>
 *   At the start of battle, all skills with skill type x it will have an
 *   increased or decreased warmup value as long as the user is the actor,
 *   class, enemy, or has the weapon or armor equipped, or is affected by the
 *   state with this notetag. These flat warmup modifications are applied after
 *   the rates and duration modifiers have been calculated.
 *
 *   <Global Warmup: +x>
 *   <Global Warmup: -x>
 *   At the start of battle, all skills will have an increased or decreased
 *   warmup value as long as the user is the actor, class, enemy, or has the
 *   weapon or armor equipped, or is affected by the state with this notetag.
 *   These flat warmup modifications are applied after the rates and duration
 *   modifiers have been calculated.
 *
 * ============================================================================
 * Lunatic Mode - Specialized Cooldowns
 * ============================================================================
 *
 * For skills, you can set cooldowns to have a special code determine its value
 * when the skill is used.
 *
 * Skill Notetag
 *   <Cooldown Eval>
 *   cooldown = x;
 *   cooldown += x;
 *   </Cooldown Eval>
 *   Insert these two tags into the skill's notebox to give it a unique way to
 *   determine the cooldown's value. The 'cooldown' variable determines the
 *   amount of turns for the cooldown.
 *
 *   <Warmup Eval>
 *   warmup = x;
 *   warmup += x;
 *   </Warmup Eval>
 *   Insert these two tags into the skill's notebox to give it a unique way to
 *   determine the warmup's value. The 'warmup' variable determines the amount
 *   of turns for the warmup.
 *
 * ============================================================================
 * Yanfly Engine Plugins - Battle Engine Extension - Action Sequence Commands
 * ============================================================================
 *
 * If you have YEP_BattleEngineCore.js installed with this plugin located
 * underneath it in the Plugin Manager, you can make use of these extra
 * cooldown related action sequences.
 *
 *=============================================================================
 * GLOBAL COOLDOWN: targets, +X
 * GLOBAL COOLDOWN: targets, -X
 * GLOBAL COOLDOWN: targets, X
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Sets the cooldown for all of the targets to be adjusted by X value. This
 * applies to every skill that doesn't bypass cooldowns.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: global cooldown: target, +5
 *                global cooldown: user, -3
 *                global cooldown: enemies, 10
 *=============================================================================
 *
 *=============================================================================
 * SKILL X COOLDOWN: targets, +Y
 * SKILL X COOLDOWN: targets, -Y
 * SKILL X COOLDOWN: targets, Y
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Causes skill X to be adjusted by Y value for the targets. This only applies
 * the specific skill x's cooldown.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: skill 10 cooldown: target, +5
 *                skill 12 cooldown: user, -3
 *                skill 15 cooldown: enemies, 10
 *=============================================================================
 *
 *=============================================================================
 * SKILL TYPE X COOLDOWN: targets, +Y
 * SKILL TYPE X COOLDOWN: targets, -Y
 * SKILL TYPE X COOLDOWN: targets, Y
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Causes skill type X skills to be adjusted by Y value for the targets. This
 * only applies the specific skill type x skill's cooldown.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: skill type 1 cooldown: target, +5
 *                skill type 2 cooldown: user, -3
 *                skill type 5 cooldown: enemies, 10
 *=============================================================================
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.01:
 * - Cooldowns can now be applied to skills that aren't learned by the actor.
 *
 * Version 1.00:
 * - Finished plugin!
 */
/*:ja
 * @plugindesc スキルが連続で使われるのを防ぐため、
 * クールダウンのシステムを導入できます。
 * @author Yanfly Engine Plugins
 *
 * @param ---クールダウン---
 * @default
 *
 * @param Cooldown Format
 * @desc クールダウンの表示テキストを指定します。
 * %1 - 残りターン数
 * @default %1CD
 *
 * @param Cooldown Font Size
 * @desc クールダウン表示のフォントサイズを指定します。
 * Default: 28
 * @default 20
 *
 * @param Cooldown Text Color
 * @desc クールダウン表示のフォントカラーを指定します。
 * @default 6
 *
 * @param Cooldown Icon
 * @desc クールダウン表示に使われるアイコンを指定します。
 * 0を入力するとアイコン無しになります。
 * @default 75
 *
 * @param Cooldown After Battle
 * @desc 戦闘後にクールダウンがどのように扱われるかを指定します。
 * @default -10
 *
 * @param Cooldown Steps
 * @desc 戦闘中以外で、マップ上でクールダウンを 1 するために必要な歩数を指定します。
 * @default 5
 *
 * @param Cooldown Bypass
 * @desc クールダウンの影響を受けないスキルを指定します。(例えば攻撃/防御など)
 * @default 1 2 3 4 5 6 7
 *
 * @param ---ウォームアップ---
 * @default
 *
 * @param Warmup Format
 * @desc ウォームアップの表示テキストを指定します。
 * %1 - 残りターン数
 * @default %1WU
 *
 * @param Warmup Font Size
 * @desc ウォームアップ表示のフォントサイズを指定します。
 * Default: 28
 * @default 20
 *
 * @param Warmup Text Color
 * @desc ウォームアップ表示のフォントカラーを指定します。
 * @default 4
 *
 * @param Warmup Icon
 * @desc ウォームアップ表示に使われるアイコンを指定します。
 * 0を入力するとアイコン無しになります。
 * @default 75
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * このプラグインを利用するには、YEP_SkillCoreが必要です。
 * リスト内ではYEP_SkillCoreの下にこのプラグインが来るようにしてください。
 *
 * このプラグインで、スキルに「クールダウン」を導入できます。
 * これにより、対象スキルの連続使用を制限することができます。
 *
 * ============================================================================
 * Cooldown Types　タイプ別説明
 * ============================================================================
 *
 * Cooldown (Standard)
 * この機能が働くと、特定のターンの間そのスキルを使うことができません。
 * また、クールダウンをさせるための方法はいくつもあります。
 * まずは、ただ単純に待つという方法。バトル中、各ターンごとにクールダウンが
 * 進行します。スキルなどで、これを早めることもできます。
 * 2つ目の方法は、戦闘を終了することです。戦闘終了によって、全てのクールダウンを
 * 特定の値だけ進行させることができます。(値はパラメータで指定可能)
 * 3つ目の方法は、フィールドマップを歩き回ることです。特定の歩数を歩くことで
 * スキルのクールダウンを行なうことができます。
 *
 * Warmups
 * ウォームアップは、クールダウンと同様の働きを持ちます。一定の時間が経つまで
 * スキルを使わせないようにするのです。しかしクールダウンと異なる点として、
 * ウォームアップは戦闘の最初に一度だけ起こる、という点が挙げられます。
 * ウォームアップタイマーにより、バトルでそのスキルが使われるタイミングを
 * 制限することができ、またそれは戦闘終了後は一時的に消え去ります。
 * ウォームアップは、既存のクールダウン上に重ねられることは有りません。
 * スキルがウォームアップ段階の際にクールダウンがすでに起こっている場合は、
 * 両方が同時にアップデートされます。
 *
 * Linked Cooldowns
 * A linked cooldown は、使用されたスキルが、ライブラリにクールダウンを持った
 * 他のスキルを発動させたときに起こります。このクールダウンの他の特性は、
 * 通常のクールダウン(前述)と同様のものです。このクールダウンタイプは、
 * スキルタイプクールダウン(後述)やグローバルクールダウンよりも優先されます。
 *
 * Skill Type Cooldowns
 * スキルタイプクールダウンが起こると、バトラーのスキルライブラリ内で該当する
 * 全てのスキルが、クールダウンの対象となります。このクールダウンの他の特性は、
 * 通常のクールダウン(前述)と同様のものです。このクールダウンタイプは、
 * グローバルクールダウンよりも優先されます。
 *
 * 既にクールダウンを持つスキルに、さらに別のクールダウンが適用されるときは、
 * 常に最大値が採用されます。つまり、もしスキルが3ターンのクールダウンを持ち、
 * スキルタイプクールダウンは1に設定されていた時、3ターンの方が採用されます。
 * 同様に、もしスキルが3ターン、スキルタイプクールダウンが5ターンだった際は、
 * 5ターンの方が採用されます。
 *
 * ============================================================================
 * Notetags
 * ============================================================================
 *
 * スキルのクールダウンを変更するには下記のNotetagを用いてください。
 *
 * スキルのNotetags:
 *   <Cooldown: x>
 *   スキルに対するクールダウンを x ターンに設定します。このクールダウンは、
 *   このスキルにのみ単独で有効です。この値はスキルタイプクールダウンや
 *   グローバルクールダウンより優先されます。
 *
 *   <After Battle Cooldown: +x>
 *   <After Battle Cooldown: -x>
 *   戦闘終了後(勝利/敗北/逃走)、 +x もしくは -x だけ、スキルのクールダウン数を
 *   増減させます。
 *
 *   <Cooldown Steps: x>
 *   戦闘外で、毎 x 歩ごとにスキルのクールダウンが 1 進行します。
 *
 *   <Skill x Cooldown: y>
 *   このスキルを使う時、スキルコストを消費した後で、 x というスキルは
 *   ターン数 y のlinked cooldownを持ちます。この値はスキルタイプクールダウンや
 *   グローバルクールダウンより優先されます。
 *
 *   <SType x Cooldown: y>
 *   このスキルを使う時、スキルコストを消費した後で、x に該当するタイプを持つ
 *   スキルは、ターン数 y のクールダウンを持ちます。この値はグローバル
 *   クールダウンより優先されます。
 *
 *   <Global Cooldown: x>
 *   このスキルを使うとき、バトラーのライブラリにある全てのスキルには、
 *   ターン数 x のクールダウンが課せられます。この値は個々のクールダウンや
 *   スキルタイプクールダウンよりも低い優先度として扱われます。
 *
 *   <Bypass Cooldown>
 *   その種類に関わらずスキルにクールダウンを無視させることができます。
 *   攻撃、防御、逃走など、クールダウンを適用すべきでないスキルに使ってください。
 *
 * スキルとアイテムのNotetags:
 *   <Skill x Cooldown: +y>
 *   <Skill x Cooldown: -y>
 *   このスキルにヒットしたターゲットのスキル x が y の値で調整されます。
 *   これは使用者には無効で、ターゲットのみに有効です。
 *
 *   <SType x Cooldown: +y>
 *   <SType x Cooldown: -y>
 *   このスキルにヒットしたターゲットについて、スキルライブラリ内の x という
 *   タイプのクールダウンが y の値で調整されます。使用者には無効で、
 *   ターゲットのみに有効です。
 *
 *   <Global Cooldown: +x>
 *   <Global Cooldown: -x>
 *   このスキルにヒットしたターゲットについて、スキルライブラリ内の全てのスキル
 *   のクールダウンが y の値で調整されます。使用者には無効で、
 *   ターゲットのみに有効です。
 *
 * アクター、職業、敵、武器、防具、ステートのNotetags:
 *
 *   <Skill x Cooldown Duration: y%>
 *   クールダウンのコストが適用された際、スキル x のクールダウン持続時間を、
 *   y% に変更します。これはスキル x にのみ作用します。
 *
 *   <SType x Cooldown Duration: y%>
 *   クールダウンのコストが適用された際、タイプ x のスキルのクールダウン
 *   持続時間を y% に変更します。これはスキル x にのみ作用します。
 *
 *   <Global Cooldown Duration: x%>
 *   クールダウンのコストが適用された際、全てのスキルのクールダウン持続時間を
 *   x% に変更します。
 *
 *   <Skill x Cooldown Rate: y%>
 *   クールダウンカウンターが下がった際、スキル x に対するクールダウンレートを
 *   y% に変更します。これはスキル x にのみ作用します。
 *
 *   <SType x Cooldown Rate: y%>
 *   クールダウンカウンターが下がった際、タイプ x のスキルのクールダウンレートを
 *   y% に変更します。これはスキルタイプ x にのみ作用します。
 *
 *   <Global Cooldown Rate: x%>
 *   クールダウンカウンターが下がった際、全てのスキルのクールダウンレートを
 *   x% に変更します。
 *
 *   <Skill x Cooldown: +y>
 *   <Skill x Cooldown: -y>
 *   ユーザーが x というスキルを使った場合、そのスキルのクールダウンの値は
 *   増加、または減少します。これはユーザーがアクター、職業、クラス、敵である、
 *   またはその武器や防具を身に着けている、もしくはこのNotetagを持ったステートに
 *   影響を受けている時に発動します。これらの修正はレートと持続時間の計算が
 *   完了した際に適用されます。
 *
 *   <SType x Cooldown: +y>
 *   <SType x Cooldown: -y>
 *   ユーザーが x タイプのスキルを使った場合、そのスキルのクールダウンの値は
 *   増加、または減少します。これはユーザーがアクター、職業、クラス、敵である、
 *   またはその武器や防具を身に着けている、もしくはこのNotetagを持ったステートに
 *   影響を受けている時に発動します。これらの修正はレートと持続時間の計算が
 *   完了した際に適用されます。
 *
 *   <Global Cooldown: +x>
 *   <Global Cooldown: -x>
 *   ユーザーがスキルを使った場合(種類問わず)、そのスキルのクールダウンの値は
 *   増加、または減少します。これはユーザーがアクター、職業、クラス、敵である、
 *   またはその武器や防具を身に着けている、もしくはこのNotetagを持ったステートに
 *   影響を受けている時に発動します。これらの修正はレートと持続時間の計算が
 *   完了した際に適用されます。
 *
 *   <Skill x Warmup: +y>
 *   <Skill x Warmup: -y>
 *   バトル開始時、スキル x のウォームアップの値は増加、または減少します。
 *   これはユーザーがアクター、職業、クラス、敵である、
 *   またはその武器や防具を身に着けている、もしくはこのNotetagを持ったステートに
 *   影響を受けている時に発動します。これらの修正はレートと持続時間の計算が
 *   完了した際に適用されます。
 *
 *   <SType x Warmup: +y>
 *   <SType x Warmup: -y>
 *   バトル開始時、x タイプの全てのスキルのウォームアップの値は
 *   増加、または減少します。これはユーザーがアクター、職業、クラス、敵である、
 *   またはその武器や防具を身に着けている、もしくはこのNotetagを持ったステートに
 *   影響を受けている時に発動します。これらの修正はレートと持続時間の計算が
 *   完了した際に適用されます
 *
 *   <Global Warmup: +x>
 *   <Global Warmup: -x>
 *   バトル開始時、全てのスキルのウォームアップの値は
 *   増加、または減少します。これはユーザーがアクター、職業、クラス、敵である、
 *   またはその武器や防具を身に着けている、もしくはこのNotetagを持ったステートに
 *   影響を受けている時に発動します。これらの修正はレートと持続時間の計算が
 *   完了した際に適用されます
 *
 * ============================================================================
 * Lunatic Mode - Specialized Cooldowns
 * ============================================================================
 *
 * 特殊なコードを用いて、スキルが使われる際のクールダウンの値を
 * 指定することができます。
 *
 * スキルのNotetag
 *   <Cooldown Eval>
 *   cooldown = x;
 *   cooldown += x;
 *   </Cooldown Eval>
 *   スキルのノートボックスに上記のタグを挿入し、クールダウンに必要なターン数
 *   を決定する方法を指定します。
 *
 *   <Warmup Eval>
 *   warmup = x;
 *   warmup += x;
 *   </Warmup Eval>
 *   スキルのノートボックスに上記のタグを挿入し、ウォームアップに必要なターン数
 *   を決定する方法を指定します。
 *
 * ============================================================================
 * Yanfly Engine Plugins - Battle Engine Extension - Action Sequence Commands
 * ============================================================================
 *
 * プラグインマネージャーに、このプラグインと共にYEP_BattleEngineCore.jsを、
 * 入れていれば、下記のクールダウン関連のアクションシーケンスも利用できます。
 *
 *=============================================================================
 * GLOBAL COOLDOWN: targets, +X
 * GLOBAL COOLDOWN: targets, -X
 * GLOBAL COOLDOWN: targets, X
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * x の値で、クールダウンを全てのターゲットに設定できます。クールダウンが有効な
 * 全てのスキルに対して適用されます。
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * 使用例: global cooldown: target, +5
 *         global cooldown: user, -3
 *         global cooldown: enemies, 10
 *=============================================================================
 *
 *=============================================================================
 * SKILL X COOLDOWN: targets, +Y
 * SKILL X COOLDOWN: targets, -Y
 * SKILL X COOLDOWN: targets, Y
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * ターゲットに対して、X というスキルに Y の値でクールダウンを付与します。
 * 特定のスキル X にのみ適用されます。
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * 使用例: skill 10 cooldown: target, +5
 *      　 skill 12 cooldown: user, -3
 *         skill 15 cooldown: enemies, 10
 *=============================================================================
 *
 *=============================================================================
 * SKILL TYPE X COOLDOWN: targets, +Y
 * SKILL TYPE X COOLDOWN: targets, -Y
 * SKILL TYPE X COOLDOWN: targets, Y
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * ターゲットに対して、X というスキルタイプに Y の値でクールダウンを付与します。
 * 特定のスキル X にのみ適用されます。
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * 使用例: skill type 1 cooldown: target, +5
 *         skill type 2 cooldown: user, -3
 *         skill type 5 cooldown: enemies, 10
 *=============================================================================
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.01:
 * - Cooldowns can now be applied to skills that aren't learned by the actor.
 *
 * Version 1.00:
 * - Finished plugin!
 */

//=============================================================================

if (Imported.YEP_SkillCore) {
  //=============================================================================
  // Parameter Variables
  //=============================================================================

  Yanfly.Parameters = PluginManager.parameters("YEP_X_SkillCooldowns");
  Yanfly.Param = Yanfly.Param || {};
  Yanfly.Icon = Yanfly.Icon || {};

  Yanfly.Param.CDFmt = String(Yanfly.Parameters["Cooldown Format"]);
  Yanfly.Param.CDFontSize = Number(Yanfly.Parameters["Cooldown Font Size"]);
  Yanfly.Param.CDTextColor = Number(Yanfly.Parameters["Cooldown Text Color"]);
  Yanfly.Icon.Cooldown = Number(Yanfly.Parameters["Cooldown Icon"]);
  Yanfly.Param.CDAfterBattle = String(
    Yanfly.Parameters["Cooldown After Battle"]
  );
  Yanfly.Param.CDSteps = Number(Yanfly.Parameters["Cooldown Steps"]);
  Yanfly.Param.CDBypass = String(Yanfly.Parameters["Cooldown Bypass"]);
  Yanfly.Param.CDBypass = Yanfly.Param.CDBypass.split(" ");
  for (Yanfly.i = 0; Yanfly.i < Yanfly.Param.CDBypass.length; ++Yanfly.i) {
    Yanfly.Param.CDBypass[Yanfly.i] = parseInt(Yanfly.Param.CDBypass[Yanfly.i]);
  }
  Yanfly.Param.WUFmt = String(Yanfly.Parameters["Warmup Format"]);
  Yanfly.Param.WUFontSize = Number(Yanfly.Parameters["Warmup Font Size"]);
  Yanfly.Param.WUTextColor = Number(Yanfly.Parameters["Warmup Text Color"]);
  Yanfly.Icon.Warmup = Number(Yanfly.Parameters["Warmup Icon"]);

  //=============================================================================
  // DataManager
  //=============================================================================

  Yanfly.SCD.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
  DataManager.isDatabaseLoaded = function () {
    if (!Yanfly.SCD.DataManager_isDatabaseLoaded.call(this)) return false;
    this.processSCDNotetags1($dataSkills);
    this.processSCDNotetags2($dataSkills);
    this.processSCDNotetags2($dataItems);
    this.processSCDNotetags2($dataActors);
    this.processSCDNotetags2($dataClasses);
    this.processSCDNotetags2($dataEnemies);
    this.processSCDNotetags2($dataWeapons);
    this.processSCDNotetags2($dataArmors);
    this.processSCDNotetags2($dataStates);
    this.processSCDNotetags3($dataActors);
    this.processSCDNotetags3($dataClasses);
    this.processSCDNotetags3($dataEnemies);
    this.processSCDNotetags3($dataWeapons);
    this.processSCDNotetags3($dataArmors);
    this.processSCDNotetags3($dataStates);
    return true;
  };

  DataManager.processSCDNotetags1 = function (group) {
    for (var n = 1; n < group.length; n++) {
      var obj = group[n];
      var notedata = obj.note.split(/[\r\n]+/);

      obj.cooldown = {};
      obj.stypeCooldown = {};
      obj.globalCooldown = 0;
      obj.afterBattleCooldown = eval(Yanfly.Param.CDAfterBattle);
      obj.cooldownSteps = Math.max(1, parseInt(Yanfly.Param.CDSteps));
      obj.warmup = 0;
      obj.bypassCooldown = Yanfly.Param.CDBypass.contains(obj.id);
      obj.cooldownEval = "";
      obj.warmupEval = "";
      var evalMode = "none";

      for (var i = 0; i < notedata.length; i++) {
        var line = notedata[i];
        if (line.match(/<(?:COOLDOWN):[ ](\d+)>/i)) {
          obj.cooldown[obj.id] = parseInt(RegExp.$1);
        } else if (line.match(/<(?:AFTER BATTLE COOLDOWN):[ ]([\+\-]\d+)>/i)) {
          obj.afterBattleCooldown = parseInt(RegExp.$1);
        } else if (line.match(/<(?:COOLDOWN STEPS):[ ](\d+)>/i)) {
          obj.cooldownSteps = parseInt(RegExp.$1);
        } else if (line.match(/<(?:WARMUP):[ ](\d+)>/i)) {
          obj.warmup = parseInt(RegExp.$1);
        } else if (line.match(/<(?:SKILL)[ ](\d+)[ ](?:COOLDOWN):[ ](\d+)>/i)) {
          obj.cooldown[parseInt(RegExp.$1)] = parseInt(RegExp.$2);
        } else if (line.match(/<(?:STYPE)[ ](\d+)[ ](?:COOLDOWN):[ ](\d+)>/i)) {
          obj.stypeCooldown[parseInt(RegExp.$1)] = parseInt(RegExp.$2);
        } else if (line.match(/<(?:GLOBAL COOLDOWN):[ ](\d+)>/i)) {
          obj.globalCooldown = parseInt(RegExp.$1);
        } else if (line.match(/<(?:BYPASS COOLDOWN)>/i)) {
          obj.bypassCooldown = true;
        } else if (line.match(/<(?:COOLDOWN EVAL)>/i)) {
          evalMode = "cooldown";
        } else if (line.match(/<\/(?:COOLDOWN EVAL)>/i)) {
          evalMode = "none";
        } else if (line.match(/<(?:WARMUP EVAL)>/i)) {
          evalMode = "warmup";
        } else if (line.match(/<\/(?:WARMUP EVAL)>/i)) {
          evalMode = "none";
        } else if (evalMode === "cooldown") {
          obj.cooldownEval = obj.cooldownEval + line + "\n";
        } else if (evalMode === "warmup") {
          obj.warmupEval = obj.warmupEval + line + "\n";
        }
      }
    }
  };

  DataManager.processSCDNotetags2 = function (group) {
    var note1 = /<(?:SKILL)[ ](\d+)[ ](?:COOLDOWN):[ ]([\+\-]\d+)>/i;
    var note2 = /<(?:STYPE)[ ](\d+)[ ](?:COOLDOWN):[ ]([\+\-]\d+)>/i;
    var note3 = /<(?:GLOBAL COOLDOWN):[ ]([\+\-]\d+)>/i;
    var note4 = /<(?:SKILL)[ ](\d+)[ ](?:WARMUP):[ ]([\+\-]\d+)>/i;
    var note5 = /<(?:STYPE)[ ](\d+)[ ](?:WARMUP):[ ]([\+\-]\d+)>/i;
    var note6 = /<(?:GLOBAL WARMUP):[ ]([\+\-]\d+)>/i;
    for (var n = 1; n < group.length; n++) {
      var obj = group[n];
      var notedata = obj.note.split(/[\r\n]+/);

      obj.cooldownChange = {};
      obj.stypeCooldownChange = {};
      obj.globalCooldownChange = 0;
      obj.warmupChange = {};
      obj.stypeWarmupChange = {};
      obj.globalWarmupChange = 0;

      for (var i = 0; i < notedata.length; i++) {
        var line = notedata[i];
        if (line.match(note1)) {
          obj.cooldownChange[parseInt(RegExp.$1)] = parseInt(RegExp.$2);
        } else if (line.match(note2)) {
          obj.stypeCooldownChange[parseInt(RegExp.$1)] = parseInt(RegExp.$2);
        } else if (line.match(note3)) {
          obj.globalCooldownChange = parseInt(RegExp.$1);
        } else if (line.match(note4)) {
          obj.warmupChange[parseInt(RegExp.$1)] = parseInt(RegExp.$2);
        } else if (line.match(note5)) {
          obj.stypeWarmupChange[parseInt(RegExp.$1)] = parseInt(RegExp.$2);
        } else if (line.match(note6)) {
          obj.globalWarmupChange = parseInt(RegExp.$1);
        }
      }
    }
  };

  DataManager.processSCDNotetags3 = function (group) {
    var note1 = /<(?:SKILL)[ ](\d+)[ ](?:COOLDOWN DURATION):[ ](\d+)([%％])>/i;
    var note2 = /<(?:STYPE)[ ](\d+)[ ](?:COOLDOWN DURATION):[ ](\d+)([%％])>/i;
    var note3 = /<(?:GLOBAL COOLDOWN DURATION):[ ](\d+)([%％])>/i;
    var note4 = /<(?:SKILL)[ ](\d+)[ ](?:COOLDOWN RATE):[ ](\d+)([%％])>/i;
    var note5 = /<(?:STYPE)[ ](\d+)[ ](?:COOLDOWN RATE):[ ](\d+)([%％])>/i;
    var note6 = /<(?:GLOBAL COOLDOWN RATE):[ ](\d+)([%％])>/i;
    for (var n = 1; n < group.length; n++) {
      var obj = group[n];
      var notedata = obj.note.split(/[\r\n]+/);

      obj.cooldownDuration = {};
      obj.stypeCooldownDuration = {};
      obj.globalCooldownDuration = 1.0;
      obj.cooldownRate = {};
      obj.stypeCooldownRate = {};
      obj.globalCooldownRate = 1.0;

      for (var i = 0; i < notedata.length; i++) {
        var line = notedata[i];
        if (line.match(note1)) {
          obj.cooldownDuration[parseInt(RegExp.$1)] = parseInt(RegExp.$2);
        } else if (line.match(note2)) {
          obj.stypeCooldownDuration[parseInt(RegExp.$1)] = parseInt(RegExp.$2);
        } else if (line.match(note3)) {
          obj.globalCooldownDuration = parseFloat(RegExp.$1 * 0.01);
        } else if (line.match(note4)) {
          obj.cooldownRate[parseInt(RegExp.$1)] = parseInt(RegExp.$2);
        } else if (line.match(note5)) {
          obj.stypeCooldownRate[parseInt(RegExp.$1)] = parseInt(RegExp.$2);
        } else if (line.match(note6)) {
          obj.globalCooldownRate = parseFloat(RegExp.$1 * 0.01);
        }
      }
    }
  };

  //=============================================================================
  // BattleManager
  //=============================================================================

  Yanfly.SCD.BattleManager_endBattle = BattleManager.endBattle;
  BattleManager.endBattle = function (result) {
    Yanfly.SCD.BattleManager_endBattle.call(this, result);
    $gameParty.endBattleCooldowns();
  };

  if (Imported.YEP_BattleEngineCore) {
    Yanfly.SCD.BattleManager_processActionSequence =
      BattleManager.processActionSequence;
    BattleManager.processActionSequence = function (actionName, actionArgs) {
      // GLOBAL COOLDOWN
      if (actionName === "GLOBAL COOLDOWN") {
        return this.actionGlobalCooldown(actionArgs);
      }
      // SKILL COOLDOWN
      if (actionName.match(/SKILL[ ](\d+)[ ]COOLDOWN/i)) {
        return this.actionSkillCooldown(parseInt(RegExp.$1), actionArgs);
      }
      // SKILL TYPE COOLDOWN
      if (actionName.match(/SKILL[ ]TYPE[ ](\d+)[ ]COOLDOWN/i)) {
        return this.actionSTypeCooldown(parseInt(RegExp.$1), actionArgs);
      }
      // STYPE COOLDOWN
      if (actionName.match(/STYPE[ ](\d+)[ ]COOLDOWN/i)) {
        return this.actionSTypeCooldown(parseInt(RegExp.$1), actionArgs);
      }
      return Yanfly.SCD.BattleManager_processActionSequence.call(
        this,
        actionName,
        actionArgs
      );
    };
  }

  BattleManager.actionGlobalCooldown = function (actionArgs) {
    var targets = this.makeActionTargets(actionArgs[0]);
    if (targets.length < 1) return true;
    var cmd = actionArgs[1];
    if (cmd.match(/([\+\-]\d+)/i)) {
      var value = parseInt(RegExp.$1);
      for (var t = 0; t < targets.length; ++t) {
        var target = targets[t];
        for (var i = 0; i < target.skills().length; ++i) {
          var skill = target.skills()[i];
          if (skill) {
            target.addCooldown(skill.id, value);
          }
        }
      }
    } else if (cmd.match(/(\d+)/i)) {
      var value = parseInt(RegExp.$1);
      for (var t = 0; t < targets.length; ++t) {
        var target = targets[t];
        for (var i = 0; i < target.skills().length; ++i) {
          var skill = target.skills()[i];
          if (skill) {
            target.setCooldown(skill.id, value);
          }
        }
      }
    } else {
      return true;
    }
    return true;
  };

  BattleManager.actionSkillCooldown = function (skillId, actionArgs) {
    var targets = this.makeActionTargets(actionArgs[0]);
    if (targets.length < 1) return true;
    var cmd = actionArgs[1];
    if (cmd.match(/([\+\-]\d+)/i)) {
      var value = parseInt(RegExp.$1);
      for (var t = 0; t < targets.length; ++t) {
        var target = targets[t];
        target.addCooldown(skillId, value);
      }
    } else if (cmd.match(/(\d+)/i)) {
      var value = parseInt(RegExp.$1);
      for (var t = 0; t < targets.length; ++t) {
        var target = targets[t];
        target.setCooldown(skillId, value);
      }
    } else {
      return true;
    }
    return true;
  };

  BattleManager.actionSTypeCooldown = function (stypeId, actionArgs) {
    var targets = this.makeActionTargets(actionArgs[0]);
    if (targets.length < 1) return true;
    var cmd = actionArgs[1];
    if (cmd.match(/([\+\-]\d+)/i)) {
      var value = parseInt(RegExp.$1);
      for (var t = 0; t < targets.length; ++t) {
        var target = targets[t];
        for (var i = 0; i < target.skills().length; ++i) {
          var skill = target.skills()[i];
          if (skill && skill.stypeId === stypeId) {
            target.addCooldown(skill.id, value);
          }
        }
      }
    } else if (cmd.match(/(\d+)/i)) {
      var value = parseInt(RegExp.$1);
      for (var t = 0; t < targets.length; ++t) {
        var target = targets[t];
        for (var i = 0; i < target.skills().length; ++i) {
          var skill = target.skills()[i];
          if (skill && skill.stypeId === stypeId) {
            target.setCooldown(skill.id, value);
          }
        }
      }
    } else {
      return true;
    }
    return true;
  };

  //=============================================================================
  // Game_Battler
  //=============================================================================

  Yanfly.SCD.Game_BattlerBase_initMembers =
    Game_BattlerBase.prototype.initMembers;
  Game_BattlerBase.prototype.initMembers = function () {
    Yanfly.SCD.Game_BattlerBase_initMembers.call(this);
    this.clearCooldowns();
    this.clearWarmups();
  };

  Game_BattlerBase.prototype.clearCooldowns = function () {
    this._cooldownTurns = {};
  };

  Game_BattlerBase.prototype.clearWarmups = function () {
    this._warmupTurns = {};
  };

  Game_BattlerBase.prototype.cooldown = function (skillId) {
    if (this._cooldownTurns === undefined) this.clearCooldowns();
    if (this._cooldownTurns[skillId] === undefined) {
      this._cooldownTurns[skillId] = 0;
    }
    return this._cooldownTurns[skillId];
  };

  Game_BattlerBase.prototype.warmup = function (skillId) {
    if (this._warmupTurns === undefined) this.clearWarmups();
    if (this._warmupTurns[skillId] === undefined) {
      this._warmupTurns[skillId] = 0;
    }
    return this._warmupTurns[skillId];
  };

  Game_BattlerBase.prototype.setCooldown = function (skillId, value) {
    if (!$dataSkills[skillId]) return;
    if ($dataSkills[skillId].bypassCooldown) return;
    if (this._cooldownTurns === undefined) this.clearCooldowns();
    this._cooldownTurns[skillId] = value;
  };

  Game_BattlerBase.prototype.addCooldown = function (skillId, value) {
    if (!$dataSkills[skillId]) return;
    if ($dataSkills[skillId].bypassCooldown) return;
    if (this._cooldownTurns === undefined) this.clearCooldowns();
    this._cooldownTurns[skillId] += value;
  };

  Game_BattlerBase.prototype.setWarmup = function (skillId, value) {
    if (!$dataSkills[skillId]) return;
    if ($dataSkills[skillId].bypassCooldown) return;
    if (this._warmupTurns === undefined) this.clearWarmups();
    this._warmupTurns[skillId] = value;
  };

  Game_BattlerBase.prototype.startWarmups = function () {
    if (this._warmupTurns === undefined) this.clearWarmups();
    for (var i = 0; i < this.skills().length; ++i) {
      var skill = this.skills()[i];
      if (!skill) continue;
      var warmup = skill.warmup;
      if (skill.warmupEval.length > 0) {
        var item = skill;
        var a = this;
        var user = this;
        var subject = this;
        var s = $gameSwitches._data;
        var v = $gameVariables._data;
        eval(skill.warmupEval);
      }
      warmup *= this.cooldownDuration(skill);
      warmup += this.getWarmupMods(skill);
      this.setWarmup(skill.id, warmup);
    }
  };

  Game_BattlerBase.prototype.updateCooldowns = function () {
    if (this._cooldownTurns === undefined) this.clearCooldowns();
    for (var skillId in this._cooldownTurns) {
      var skill = $dataSkills[skillId];
      if (!skill) continue;
      this._cooldownTurns[skillId] -= this.cooldownRate(skill);
    }
  };

  Game_BattlerBase.prototype.updateWarmups = function () {
    if (this._warmupTurns === undefined) this.clearWarmups();
    for (var skillId in this._warmupTurns) {
      var skill = $dataSkills[skillId];
      if (!skill) continue;
      this._warmupTurns[skillId] -= this.cooldownRate(skill);
    }
  };

  Yanfly.SCD.Game_BattlerBase_meetsSkillConditions =
    Game_BattlerBase.prototype.meetsSkillConditions;
  Game_BattlerBase.prototype.meetsSkillConditions = function (skill) {
    if (this.cooldown(skill.id) > 0) return false;
    if (this.warmup(skill.id) > 0) return false;
    return Yanfly.SCD.Game_BattlerBase_meetsSkillConditions.call(this, skill);
  };

  Yanfly.SCD.Game_BattlerBase_paySkillCost =
    Game_BattlerBase.prototype.paySkillCost;
  Game_BattlerBase.prototype.paySkillCost = function (skill) {
    Yanfly.SCD.Game_BattlerBase_paySkillCost.call(this, skill);
    this.payGlobalCooldown(skill);
    this.payStypeCooldownCost(skill);
    this.payCooldownCost(skill);
    this.applyCooldownMods(skill);
  };

  Game_BattlerBase.prototype.payGlobalCooldown = function (mainSkill) {
    for (var i = 0; i < this.skills().length; ++i) {
      var skill = this.skills()[i];
      if (!skill) continue;
      var value = mainSkill.globalCooldown;
      value *= this.cooldownDuration(mainSkill);
      value = Math.max(value, this.cooldown(skill.id));
      this.setCooldown(skill.id, value);
    }
  };

  Game_BattlerBase.prototype.payStypeCooldownCost = function (mainSkill) {
    for (var stypeId in mainSkill.stypeCooldown) {
      stypeId = parseInt(stypeId);
      for (var i = 0; i < this.skills().length; ++i) {
        var skill = this.skills()[i];
        if (!skill) continue;
        if (skill.stypeId !== stypeId) continue;
        var value = mainSkill.stypeCooldown[stypeId];
        value *= this.cooldownDuration(mainSkill);
        value = Math.max(value, this.cooldown(skill.id));
        this.setCooldown(skill.id, value);
      }
    }
  };

  Game_BattlerBase.prototype.payCooldownCost = function (skill) {
    for (var skillId in skill.cooldown) {
      skillId = parseInt(skillId);
      if (!$dataSkills[skillId]) continue;
      var cooldown = skill.cooldown[skillId];
      if (skill.id === skillId) {
        if (skill.cooldownEval.length > 0) {
          var item = skill;
          var a = this;
          var user = this;
          var subject = this;
          var s = $gameSwitches._data;
          var v = $gameVariables._data;
          eval(skill.cooldownEval);
        }
      }
      cooldown *= this.cooldownDuration(skill);
      cooldown = Math.max(cooldown, this.cooldown(skillId));
      this.setCooldown(skillId, cooldown);
    }
  };

  Game_BattlerBase.prototype.endBattleCooldowns = function () {
    for (var skillId in this._cooldownTurns) {
      this._cooldownTurns[skillId] += $dataSkills[skillId].afterBattleCooldown;
    }
  };

  Game_BattlerBase.prototype.updateCooldownSteps = function () {
    for (var skillId in this._cooldownTurns) {
      var skill = $dataSkills[skillId];
      if (skill) {
        if ($gameParty.steps() % skill.cooldownSteps === 0) {
          this._cooldownTurns[skillId] -= this.cooldownRate(skill);
        }
      }
    }
  };

  Game_BattlerBase.prototype.applyCooldownEffect = function (skill) {
    this.applyGlobalCooldownChange(skill);
    this.applyStypeCooldownChange(skill);
    this.applyCooldownChange(skill);
  };

  Game_BattlerBase.prototype.applyCooldownChange = function (skill) {
    for (var skillId in skill.cooldownChange) {
      skillId = parseInt(skillId);
      if (!$dataSkills[skillId]) continue;
      var value = skill.cooldownChange[skillId];
      this.addCooldown(skillId, value);
    }
  };

  Game_BattlerBase.prototype.applyStypeCooldownChange = function (mainSkill) {
    for (var stypeId in mainSkill.stypeCooldownChange) {
      stypeId = parseInt(stypeId);
      for (var i = 0; i < this.skills().length; ++i) {
        var skill = this.skills()[i];
        if (!skill) continue;
        if (skill.stypeId !== stypeId) continue;
        var value = mainSkill.stypeCooldownChange[stypeId];
        this.addCooldown(skill.id, value);
      }
    }
  };

  Game_BattlerBase.prototype.applyGlobalCooldownChange = function (mainSkill) {
    for (var i = 0; i < this.skills().length; ++i) {
      var skill = this.skills()[i];
      if (!skill) continue;
      var value = mainSkill.globalCooldownChange;
      this.addCooldown(skill.id, value);
    }
  };

  Game_BattlerBase.prototype.getWarmupMods = function (skill) {
    var value = 0;
    value += this.flatWarmupChange(skill);
    return value;
  };

  Game_BattlerBase.prototype.applyCooldownMods = function (skill) {
    var value = this.cooldown(skill.id);
    value += this.flatCooldownChange(skill);
    this.setCooldown(skill.id, Math.max(0, value));
  };

  //=============================================================================
  // Game_Battler
  //=============================================================================

  Yanfly.SCD.Game_Battler_onBattleStart = Game_Battler.prototype.onBattleStart;
  Game_Battler.prototype.onBattleStart = function () {
    Yanfly.SCD.Game_Battler_onBattleStart.call(this);
    this.startWarmups();
  };

  Game_Battler.prototype.cooldownDuration = function (skill) {
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    var value = 1.0;
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (!state) continue;
      if (state.cooldownDuration[skillId] !== undefined) {
        value *= state.cooldownDuration[skillId];
      }
      if (state.stypeCooldownDuration[stypeId] !== undefined) {
        value *= state.stypeCooldownDuration[stypeId];
      }
      value *= state.globalCooldownDuration;
    }
    return value;
  };

  Game_Battler.prototype.cooldownRate = function (skill) {
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    var value = 1;
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (!state) continue;
      if (state.cooldownRate[skillId] !== undefined) {
        value *= state.cooldownRate[skillId];
      }
      if (state.stypeCooldownRate[stypeId] !== undefined) {
        value *= state.stypeCooldownRate[stypeId];
      }
      value *= state.globalCooldownRate;
    }
    return value;
  };

  Game_Battler.prototype.flatCooldownChange = function (skill) {
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    var value = 0;
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (!state) continue;
      if (state.cooldownChange[skillId] !== undefined) {
        value += state.cooldownChange[skillId];
      }
      if (state.stypeCooldownChange[stypeId] !== undefined) {
        value += state.stypeCooldownChange[stypeId];
      }
      value += state.globalCooldownChange;
    }
    return value;
  };

  Game_Battler.prototype.flatWarmupChange = function (skill) {
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    var value = 0;
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (!state) continue;
      if (state.warmupChange[skillId] !== undefined) {
        value += state.warmupChange[skillId];
      }
      if (state.stypeWarmupChange[stypeId] !== undefined) {
        value += state.stypeWarmupChange[stypeId];
      }
      value += state.globalWarmupChange;
    }
    return value;
  };

  //=============================================================================
  // Game_Actor
  //=============================================================================

  Game_Actor.prototype.cooldownDuration = function (skill) {
    var value = Game_Battler.prototype.cooldownDuration.call(this, skill);
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    if (this.actor().cooldownDuration[skillId] !== undefined) {
      value *= this.actor().cooldownDuration[skillId];
    }
    if (this.currentClass().cooldownDuration[skillId] !== undefined) {
      value *= this.currentClass().cooldownDuration[skillId];
    }
    if (this.actor().stypeCooldownDuration[stypeId] !== undefined) {
      value *= this.actor().stypeCooldownDuration[stypeId];
    }
    if (this.currentClass().stypeCooldownDuration[stypeId] !== undefined) {
      value *= this.currentClass().stypeCooldownDuration[stypeId];
    }
    value *= this.actor().globalCooldownDuration;
    value *= this.currentClass().globalCooldownDuration;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (!equip) continue;
      if (equip.cooldownDuration !== undefined) {
        if (equip.cooldownDuration[skillId] !== undefined) {
          value *= equip.cooldownDuration[skillId];
        }
      }
      if (equip.stypeCooldownDuration !== undefined) {
        if (equip.stypeCooldownDuration[stypeId] !== undefined) {
          value *= equip.stypeCooldownDuration[stypeId];
        }
      }
      if (equip.globalCooldownDuration !== undefined) {
        value *= equip.globalCooldownDuration;
      }
    }
    return value;
  };

  Game_Actor.prototype.cooldownRate = function (skill) {
    var value = Game_Battler.prototype.cooldownRate.call(this, skill);
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    if (this.actor().cooldownRate[skillId] !== undefined) {
      value *= this.actor().cooldownRate[skillId];
    }
    if (this.currentClass().cooldownRate[skillId] !== undefined) {
      value *= this.currentClass().cooldownRate[skillId];
    }
    if (this.actor().stypeCooldownRate[stypeId] !== undefined) {
      value *= this.actor().stypeCooldownRate[stypeId];
    }
    if (this.currentClass().stypeCooldownRate[stypeId] !== undefined) {
      value *= this.currentClass().stypeCooldownRate[stypeId];
    }
    value *= this.actor().globalCooldownRate;
    value *= this.currentClass().globalCooldownRate;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (!equip) continue;
      if (equip.cooldownRate !== undefined) {
        if (equip.cooldownRate[skillId] !== undefined) {
          value *= equip.cooldownRate[skillId];
        }
      }
      if (equip.stypeCooldownRate !== undefined) {
        if (equip.stypeCooldownRate[stypeId] !== undefined) {
          value *= equip.stypeCooldownRate[stypeId];
        }
      }
      if (equip.globalCooldownRate !== undefined) {
        value *= equip.globalCooldownRate;
      }
    }
    return value;
  };

  Game_Actor.prototype.flatCooldownChange = function (skill) {
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    var value = Game_Battler.prototype.flatCooldownChange.call(this, skill);
    if (this.actor().cooldownChange[skillId] !== undefined) {
      value += this.actor().cooldownChange[skillId];
    }
    if (this.currentClass().cooldownChange[skillId] !== undefined) {
      value += this.currentClass().cooldownChange[skillId];
    }
    if (this.actor().stypeCooldownChange[stypeId] !== undefined) {
      value += this.actor().stypeCooldownChange[stypeId];
    }
    if (this.currentClass().stypeCooldownChange[stypeId] !== undefined) {
      value += this.currentClass().stypeCooldownChange[stypeId];
    }
    value += this.actor().globalCooldownChange;
    value += this.currentClass().globalCooldownChange;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (!equip) continue;
      if (equip.cooldownChange[skillId] !== undefined) {
        value += equip.cooldownChange[skillId];
      }
      if (equip.stypeCooldownChange[stypeId] !== undefined) {
        value += equip.stypeCooldownChange[stypeId];
      }
      value += equip.globalCooldownChange;
    }
    return value;
  };

  Game_Actor.prototype.flatWarmupChange = function (skill) {
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    var value = Game_Battler.prototype.flatWarmupChange.call(this, skill);
    if (this.actor().warmupChange[skillId] !== undefined) {
      value += this.actor().warmupChange[skillId];
    }
    if (this.currentClass().warmupChange[skillId] !== undefined) {
      value += this.currentClass().warmupChange[skillId];
    }
    if (this.actor().stypeWarmupChange[stypeId] !== undefined) {
      value += this.actor().stypeWarmupChange[stypeId];
    }
    if (this.currentClass().stypeWarmupChange[stypeId] !== undefined) {
      value += this.currentClass().stypeWarmupChange[stypeId];
    }
    value += this.actor().globalWarmupChange;
    value += this.currentClass().globalWarmupChange;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (!equip) continue;
      if (equip.warmupChange[skillId] !== undefined) {
        value += equip.warmupChange[skillId];
      }
      if (equip.stypeWarmupChange[stypeId] !== undefined) {
        value += equip.stypeWarmupChange[stypeId];
      }
      value += equip.globalWarmupChange;
    }
    return value;
  };

  //=============================================================================
  // Game_Enemy
  //=============================================================================

  if (!Game_Enemy.prototype.skills) {
    Game_Enemy.prototype.skills = function () {
      var skills = [];
      for (var i = 0; i < this.enemy().actions.length; ++i) {
        var skill = $dataSkills[this.enemy().actions[i].skillId];
        if (skill) skills.push(skill);
      }
      return skills;
    };
  }

  Game_Enemy.prototype.cooldownDuration = function (skill) {
    var value = Game_Battler.prototype.cooldownDuration.call(this, skill);
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    if (this.enemy().cooldownDuration[skillId] !== undefined) {
      value *= this.enemy().cooldownDuration[skillId];
    }
    if (this.enemy().stypeCooldownDuration[stypeId] !== undefined) {
      value *= this.enemy().stypeCooldownDuration[stypeId];
    }
    value *= this.enemy().globalCooldownDuration;
    return value;
  };

  Game_Enemy.prototype.cooldownRate = function (skill) {
    var value = Game_Battler.prototype.cooldownRate.call(this, skill);
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    if (this.enemy().cooldownRate[skillId] !== undefined) {
      value *= this.enemy().cooldownRate[skillId];
    }
    if (this.enemy().stypeCooldownRate[stypeId] !== undefined) {
      value *= this.enemy().stypeCooldownRate[stypeId];
    }
    value *= this.enemy().globalCooldownRate;
    return value;
  };

  Game_Enemy.prototype.flatCooldownChange = function (skill) {
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    var value = Game_Battler.prototype.flatCooldownChange.call(this, skill);
    if (this.enemy().cooldownChange[skillId] !== undefined) {
      value += this.enemy().cooldownChange[skillId];
    }
    if (this.enemy().stypeCooldownChange[stypeId] !== undefined) {
      value += this.enemy().stypeCooldownChange[stypeId];
    }
    value += this.enemy().globalCooldownChange;
    return value;
  };

  Game_Enemy.prototype.flatWarmupChange = function (skill) {
    var skillId = skill.id;
    var stypeId = skill.stypeId;
    var value = Game_Battler.prototype.flatWarmupChange.call(this, skill);
    if (this.enemy().warmupChange[skillId] !== undefined) {
      value += this.enemy().warmupChange[skillId];
    }
    if (this.enemy().stypeWarmupChange[stypeId] !== undefined) {
      value += this.enemy().stypeWarmupChange[stypeId];
    }
    value += this.enemy().globalWarmupChange;
    return value;
  };

  //=============================================================================
  // Game_Action
  //=============================================================================

  Yanfly.SCD.Game_Action_applyItemUserEffect =
    Game_Action.prototype.applyItemUserEffect;
  Game_Action.prototype.applyItemUserEffect = function (target) {
    Yanfly.SCD.Game_Action_applyItemUserEffect.call(this);
    target.applyCooldownEffect(this.item());
  };

  //=============================================================================
  // Game_Unit
  //=============================================================================

  Game_Unit.prototype.updateCooldowns = function () {
    return this.members().forEach(function (member) {
      member.updateCooldowns();
      member.updateWarmups();
    });
  };

  Game_Unit.prototype.endBattleCooldowns = function () {
    return this.members().forEach(function (member) {
      member.endBattleCooldowns();
      member.clearWarmups();
    });
  };

  //=============================================================================
  // Game_Party
  //=============================================================================

  Yanfly.SCD.Game_Party_increaseSteps = Game_Party.prototype.increaseSteps;
  Game_Party.prototype.increaseSteps = function () {
    Yanfly.SCD.Game_Party_increaseSteps.call(this);
    this.updateCooldownSteps();
  };

  Game_Party.prototype.updateCooldownSteps = function () {
    return this.members().forEach(function (member) {
      return member.updateCooldownSteps();
    });
  };

  //=============================================================================
  // Game_Troop
  //=============================================================================

  Yanfly.SCD.Game_Troop_increaseTurn = Game_Troop.prototype.increaseTurn;
  Game_Troop.prototype.increaseTurn = function () {
    Yanfly.SCD.Game_Troop_increaseTurn.call(this);
    this.updateCooldowns();
    $gameParty.updateCooldowns();
  };

  //=============================================================================
  // Window_SkillList
  //=============================================================================

  Yanfly.SCD.Window_SkillList_drawCost =
    Window_SkillList.prototype.drawSkillCost;
  Window_SkillList.prototype.drawSkillCost = function (skill, wx, wy, width) {
    if (this._actor.warmup(skill.id) > 0) {
      this.drawWarmup(skill, wx, wy, width);
    } else if (this._actor.cooldown(skill.id) > 0) {
      this.drawCooldown(skill, wx, wy, width);
    } else {
      Yanfly.SCD.Window_SkillList_drawCost.call(this, skill, wx, wy, width);
    }
  };

  Window_SkillList.prototype.drawCooldown = function (skill, wx, wy, dw) {
    if (Yanfly.Icon.Cooldown > 0) {
      var iw = wx + dw - Window_Base._iconWidth;
      this.drawIcon(Yanfly.Icon.Cooldown, iw, wy + 2);
      dw -= Window_Base._iconWidth + 2;
    }
    this.changeTextColor(this.textColor(Yanfly.Param.CDTextColor));
    var fmt = Yanfly.Param.CDFmt;
    var value = this._actor.cooldown(skill.id);
    if (value % 1 !== 0) value = value.toFixed(2);
    if (value <= 0.009) value = 0.01;
    var text = fmt.format(Yanfly.Util.toGroup(value));
    this.contents.fontSize = Yanfly.Param.CDFontSize;
    this.drawText(text, wx, wy, dw, "right");
    this.resetFontSettings();
  };

  Window_SkillList.prototype.drawWarmup = function (skill, wx, wy, dw) {
    if (Yanfly.Icon.Warmup > 0) {
      var iw = wx + dw - Window_Base._iconWidth;
      this.drawIcon(Yanfly.Icon.Warmup, iw, wy + 2);
      dw -= Window_Base._iconWidth + 2;
    }
    this.changeTextColor(this.textColor(Yanfly.Param.WUTextColor));
    var fmt = Yanfly.Param.WUFmt;
    var value = this._actor.warmup(skill.id);
    if (value % 1 !== 0) value = value.toFixed(2);
    if (value <= 0.009) value = 0.01;
    var text = fmt.format(Yanfly.Util.toGroup(value));
    this.contents.fontSize = Yanfly.Param.WUFontSize;
    this.drawText(text, wx, wy, dw, "right");
    this.resetFontSettings();
  };

  //=============================================================================
  // Utilities
  //=============================================================================

  Yanfly.Util = Yanfly.Util || {};

  if (!Yanfly.Util.toGroup) {
    Yanfly.Util.toGroup = function (inVal) {
      return inVal;
    };
  }

  //=============================================================================
  // End of File
  //=============================================================================
}


code:
//=============================================================================
// Yami_8DIR.js
//=============================================================================

/*:ja
 * @plugindesc プレイヤーの8方向の移動が可能になります。
 */

(function () {
  Game_Player.prototype.isMoveDiagonally = function (direction) {
    var dir8 = [1, 3, 7, 9];

    return dir8.some(function (dir) {
      return dir === direction;
    }, this);
  };

  Game_Player.prototype.isMoveStraight = function (direction) {
    var dir4 = [2, 4, 6, 8];

    return dir4.some(function (dir) {
      return dir === direction;
    }, this);
  };

  Game_Player.prototype.getDiagonallyMovement = function (direction) {
    var horz = 0,
      vert = 0;

    if (direction === 1) {
      horz = 4;
      vert = 2;
    } else if (direction === 3) {
      horz = 6;
      vert = 2;
    } else if (direction === 7) {
      horz = 4;
      vert = 8;
    } else if (direction === 9) {
      horz = 6;
      vert = 8;
    }

    return [horz, vert];
  };

  Game_Player.prototype.processMoveByInput = function (direction) {
    var diagonal = this.getDiagonallyMovement(direction);

    if (this.isMoveStraight(direction)) {
      this.moveStraight(direction);
    } else if (this.isMoveDiagonally(direction)) {
      this.moveDiagonally.apply(this, diagonal);
    }
  };

  Game_Player.prototype.moveByInput = function () {
    if (!this.isMoving() && this.canMove()) {
      var direction = Input.dir8;

      if (direction > 0) {
        $gameTemp.clearDestination();
      } else if ($gameTemp.isDestinationValid()) {
        var x = $gameTemp.destinationX();
        var y = $gameTemp.destinationY();
        direction = this.findDirectionTo(x, y);
      }

      if (direction > 0) {
        this.processMoveByInput(direction);
      }
    }
  };
})();

repo_name: dazed/translations

license: unknown


code:
/*:
 * @plugindesc Skip the title scene for testing purpose.
 * @version 1.0
 */

/*:ja
 * @plugindesc テストプレイ用にタイトルシーンを飛ばすことができます。
 * @version 1.0
 */

(function () {
  Scene_Boot.prototype.start = function () {
    Scene_Base.prototype.start.call(this);
    SoundManager.preloadImportantSounds();
    if (DataManager.isBattleTest()) {
      DataManager.setupBattleTest();
      SceneManager.goto(Scene_Battle);
    } else {
      this.checkPlayerLocation();
      DataManager.setupNewGame();
      SceneManager.goto(Scene_Map);
    }
    this.updateDocumentTitle();
  };
})();


code:
//=============================================================================
// Extra maps
// Zeriab_ExtraMaps.js
// Last Updated: 2015.08.23
//=============================================================================

/*:
 * @plugindesc Allows using more than 999 maps
 * @author Zeriab
 *
 * @help
 *
 * Plugin Command:
 *   ExtraMaps set church   # Use maps from the specific "church" subfolder (data/church/Map003.json)
 *   ExtraMaps reset        # Use maps from the default folder (data/Map003.json)
 *
 *   Next transfer will use maps from the new folder
 */
/*:ja
 * @plugindesc 999以上のマップ使用を可能にします。
 * @author Zeriab
 *
 * @help　プラグインコマンドは以下を参照してください。
 *
 * Plugin Command:
 *   ExtraMaps set church   #
 * 	"church"のサブフォルダからマップを使用します(data/church/Map003.json)
 *   ExtraMaps reset        #
 * 	デフォルトのフォルダからマップを使用します(data/Map003.json)
 *
 */

(function () {
  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);
    var actualCommand = command.toLowerCase();
    if (actualCommand === "extramaps") {
      var action = args[0].toLowerCase();
      switch (action) {
        case "set":
          // Retain casing of the map folder
          $gameSystem.setMapsFolder(args[1]);
          break;
        case "clear":
          $gameSystem.clearMapsFolder();
          break;
      }
    }
  };

  Game_System.prototype.setMapsFolder = function (subfolder) {
    if (this._MapSubFolder !== subfolder) {
      this._MapSubFolder = subfolder;
      this._MapFolderChange = true;
    }
  };

  Game_System.prototype.clearMapsFolder = function () {
    this.setMapsFolder("");
  };

  // Overriding: DataManager.loadMapData
  DataManager.loadMapData = function (mapId) {
    subfolder = $gameSystem._MapSubFolder || "";
    if (mapId > 0) {
      var filename = DataManager.makeMapName(mapId);
      this.loadDataFile("$dataMap", filename);
    } else {
      this.makeEmptyMap();
    }
    // Extra check needed since we need to reload the map transferring
    // to a different folder with unchanged mapId.
    DataManager.checkMapFolderReload();
  };

  DataManager.makeMapName = function (mapId) {
    var filename = "Map%1.json".format(mapId.padZero(3));
    if (subfolder && subfolder.length >= 1) {
      filename = "%1/%2".format(subfolder, filename);
    }
    return filename;
  };

  DataManager.checkMapFolderReload = function () {
    reloadNeeded = $gameSystem._MapFolderChange || false;
    if (reloadNeeded) {
      $gamePlayer.requestMapReload();
    }
  };
})();


code:
�wRPG�c�N�[��MV�@�v���O�C���W�x�g�p����

���̎g�p�����i�ȉ��u�{�g�p�����v�Ƃ����܂��j�́A�������KADOKAWA�i�ȉ��u���Ёv�Ƃ����܂��j�̐��i�wRPG�c�N�[��MV�x�i�ȉ��u���А��i�v�Ƃ����܂��j�̐��K���[�U�[�i�ȉ��u���[�U�[�v�Ƃ����܂��j���A�wRPG�c�N�[��MV�v���O�C���W�x�i�ȉ��u�{�v���O�C���W�v�Ƃ����܂��j���g�p����ꍇ�ɂ����āA���А��i�̎g�p�����_��i�ȉ��u���i�Ō_��v�Ƃ����܂��j�ƈ�̂��Ȃ����̂Ƃ��ēK�p�������̂Ƃ��܂��B���[�U�[�́A�{�v���O�C���W�̎g�p�ɐ旧���A�K���{�g�p�������悭���ǂ݂��������B���[�U�[�́A�{�v���O�C���W�̎g�p���J�n�������_�ŁA�{�g�p�����ɓ��ӂ������̂Ƃ݂Ȃ���܂��B�Ȃ��A�{�g�p�����Ŏg�p�����p��́A�{�g�p�����ɂ����ĕʒi�̒�߂̂Ȃ�����A���i�Ō_��ɒ�߂�Ƃ���ɂ����̂Ƃ��܂��B

(1) ���[�U�[�́A�ȉ��̂Ƃ���{�v���O�C���W���g�p���邱�Ƃ��ł��܂��B
�@ ���А��i���g�p���Đ��삵���Q�[���i�ȉ��u���[�U�[�Q�[���v�Ƃ����܂��j�ɁA�{�v���O�C���W�Ɏ��^���ꂽ�v���O�C���\�t�g�E�F�A�i�ȉ��u�{�v���O�C���v�Ƃ����܂��j���g�p���邱�Ƃɂ��A�@�\��ǉ����͕ύX���邱�ƁB
�A ���[�U�[�Q�[���Ɏg�p����ړI�Ɍ���A�{�v���O�C���̉��ς��s�����ƁB
�B �{�v���O�C���A�y�ёO���Ɋ�Â����ς����{�v���O�C�����A���А��i�Ő��삳�ꂽ���[�U�[�Q�[���ƈꏏ�ɔz�z�����邱�ƁB�Ȃ��A�{�v���O�C���y�щ��ό�̖{�v���O�C���́A���А��i�Ő��삳�ꂽ���[�U�[�Q�[���ƈꏏ�ɔz�z�������ꍇ�Ɍ����Ĕz�z�����F�߂�����̂ł��B�{�v���O�C���y�щ��ό�̖{�v���O�C����P�ƂŔz�z�����邱�Ƃ�A���[�U�[�Q�[���ȊO�̃v���O�������Ƒg�ݍ��킹�Ĕz�z�����邱�Ƃ͂ł��܂���B
(2) �{�v���O�C���W�Ɋւ��钘�쌠�A����אڌ��A���̑��̒m�I���Y���́A���Ж��͕��Ђ̔F�߂��O�҂ɋA��������̂Ƃ��܂��B
(3) �{�v���O�C���W�Ɋւ���T�|�[�g�i�{�v���O�C���̃��[�U�[�Q�[���ւ̎g�p���@�A�{�v���O�C���̉��ϕ��@���j�́A���Ђł͈�؍s�Ȃ��Ă���܂���B
(4) ���Ђ́A�{�v���O�C���̐M�������ێ����邽�ߍő���̒��ӂ𕥂��܂����A�{�v���O�C���̓���̖ړI�ւ̓K�����A���тɖ{�v���O�C���̓���̊m�����y�ш��萫�ɂ��Ă͈�ؕۏ؂��Ȃ����̂Ƃ��A���[�U�[�́A�{�v���O�C�������Ȃ̐ӔC�ƕ��S�ɂĎg�p������̂Ƃ��܂��B
(5) ���Ђ́A���ό�̖{�v���O�C�����g�p�������Ƃɂ�胆�[�U�[�ɐ������s��y�ё��Q�A���тɉ��ό�̖{�v���O�C����z�z���������Ƃɂ�胆�[�U�[�Ƒ�O�҂Ƃ̊ԂŐ������g���u���y�ѕ������Ɋւ��ẮA��ؐӔC�𕉂�Ȃ����̂Ƃ��܂��B
(6) �{�g�p�����ɋL�ڂ̂Ȃ��_������́A���i�Ō_��ɒ�߂�Ƃ���ɂ����̂Ƃ��܂��B�A���A�{�g�p�����Ɛ��i�Ō_��ɒ�߂�_��������ꗂ𐶂����ꍇ�ɂ́A�{�g�p�����ɒ�߂�_��������D��I�ɓK�p�������̂Ƃ��܂��B

�ȏ�


code:
/*! FPSMeter 0.3.1 - 9th May 2013 | https://github.com/Darsain/fpsmeter */
(function (m, j) {
  function s(a, e) {
    for (var g in e)
      try {
        a.style[g] = e[g];
      } catch (j) {}
    return a;
  }
  function H(a) {
    return null == a
      ? String(a)
      : "object" === typeof a || "function" === typeof a
      ? Object.prototype.toString
          .call(a)
          .match(/\s([a-z]+)/i)[1]
          .toLowerCase() || "object"
      : typeof a;
  }
  function R(a, e) {
    if ("array" !== H(e)) return -1;
    if (e.indexOf) return e.indexOf(a);
    for (var g = 0, j = e.length; g < j; g++) if (e[g] === a) return g;
    return -1;
  }
  function I() {
    var a = arguments,
      e;
    for (e in a[1])
      if (a[1].hasOwnProperty(e))
        switch (H(a[1][e])) {
          case "object":
            a[0][e] = I({}, a[0][e], a[1][e]);
            break;
          case "array":
            a[0][e] = a[1][e].slice(0);
            break;
          default:
            a[0][e] = a[1][e];
        }
    return 2 < a.length
      ? I.apply(null, [a[0]].concat(Array.prototype.slice.call(a, 2)))
      : a[0];
  }
  function N(a) {
    a = Math.round(255 * a).toString(16);
    return 1 === a.length ? "0" + a : a;
  }
  function S(a, e, g, j) {
    if (a.addEventListener)
      a[j ? "removeEventListener" : "addEventListener"](e, g, !1);
    else if (a.attachEvent) a[j ? "detachEvent" : "attachEvent"]("on" + e, g);
  }
  function D(a, e) {
    function g(a, b, d, c) {
      return y[0 | a][Math.round(Math.min(((b - d) / (c - d)) * J, J))];
    }
    function r() {
      f.legend.fps !== q &&
        ((f.legend.fps = q), (f.legend[T] = q ? "FPS" : "ms"));
      K = q ? b.fps : b.duration;
      f.count[T] = 999 < K ? "999+" : K.toFixed(99 < K ? 0 : d.decimals);
    }
    function m() {
      z = A();
      L < z - d.threshold &&
        ((b.fps -= b.fps / Math.max(1, (60 * d.smoothing) / d.interval)),
        (b.duration = 1e3 / b.fps));
      for (c = d.history; c--; )
        (E[c] = 0 === c ? b.fps : E[c - 1]),
          (F[c] = 0 === c ? b.duration : F[c - 1]);
      r();
      if (d.heat) {
        if (w.length)
          for (c = w.length; c--; )
            w[c].el.style[h[w[c].name].heatOn] = q
              ? g(h[w[c].name].heatmap, b.fps, 0, d.maxFps)
              : g(h[w[c].name].heatmap, b.duration, d.threshold, 0);
        if (f.graph && h.column.heatOn)
          for (c = u.length; c--; )
            u[c].style[h.column.heatOn] = q
              ? g(h.column.heatmap, E[c], 0, d.maxFps)
              : g(h.column.heatmap, F[c], d.threshold, 0);
      }
      if (f.graph)
        for (p = 0; p < d.history; p++)
          u[p].style.height =
            (q
              ? E[p]
                ? Math.round((O / d.maxFps) * Math.min(E[p], d.maxFps))
                : 0
              : F[p]
              ? Math.round((O / d.threshold) * Math.min(F[p], d.threshold))
              : 0) + "px";
    }
    function k() {
      20 > d.interval
        ? ((x = M(k)), m())
        : ((x = setTimeout(k, d.interval)), (P = M(m)));
    }
    function G(a) {
      a = a || window.event;
      a.preventDefault
        ? (a.preventDefault(), a.stopPropagation())
        : ((a.returnValue = !1), (a.cancelBubble = !0));
      b.toggle();
    }
    function U() {
      d.toggleOn && S(f.container, d.toggleOn, G, 1);
      a.removeChild(f.container);
    }
    function V() {
      f.container && U();
      h = D.theme[d.theme];
      y = h.compiledHeatmaps || [];
      if (!y.length && h.heatmaps.length) {
        for (p = 0; p < h.heatmaps.length; p++) {
          y[p] = [];
          for (c = 0; c <= J; c++) {
            var b = y[p],
              e = c,
              g;
            g = (0.33 / J) * c;
            var j = h.heatmaps[p].saturation,
              m = h.heatmaps[p].lightness,
              n = void 0,
              k = void 0,
              l = void 0,
              t = (l = void 0),
              v = (n = k = void 0),
              v = void 0,
              l = 0.5 >= m ? m * (1 + j) : m + j - m * j;
            0 === l
              ? (g = "#000")
              : ((t = 2 * m - l),
                (k = (l - t) / l),
                (g *= 6),
                (n = Math.floor(g)),
                (v = g - n),
                (v *= l * k),
                0 === n || 6 === n
                  ? ((n = l), (k = t + v), (l = t))
                  : 1 === n
                  ? ((n = l - v), (k = l), (l = t))
                  : 2 === n
                  ? ((n = t), (k = l), (l = t + v))
                  : 3 === n
                  ? ((n = t), (k = l - v))
                  : 4 === n
                  ? ((n = t + v), (k = t))
                  : ((n = l), (k = t), (l -= v)),
                (g = "#" + N(n) + N(k) + N(l)));
            b[e] = g;
          }
        }
        h.compiledHeatmaps = y;
      }
      f.container = s(document.createElement("div"), h.container);
      f.count = f.container.appendChild(
        s(document.createElement("div"), h.count)
      );
      f.legend = f.container.appendChild(
        s(document.createElement("div"), h.legend)
      );
      f.graph = d.graph
        ? f.container.appendChild(s(document.createElement("div"), h.graph))
        : 0;
      w.length = 0;
      for (var q in f) f[q] && h[q].heatOn && w.push({ name: q, el: f[q] });
      u.length = 0;
      if (f.graph) {
        f.graph.style.width =
          d.history * h.column.width +
          (d.history - 1) * h.column.spacing +
          "px";
        for (c = 0; c < d.history; c++)
          (u[c] = f.graph.appendChild(
            s(document.createElement("div"), h.column)
          )),
            (u[c].style.position = "absolute"),
            (u[c].style.bottom = 0),
            (u[c].style.right =
              c * h.column.width + c * h.column.spacing + "px"),
            (u[c].style.width = h.column.width + "px"),
            (u[c].style.height = "0px");
      }
      s(f.container, d);
      r();
      a.appendChild(f.container);
      f.graph && (O = f.graph.clientHeight);
      d.toggleOn &&
        ("click" === d.toggleOn && (f.container.style.cursor = "pointer"),
        S(f.container, d.toggleOn, G));
    }
    "object" === H(a) && a.nodeType === j && ((e = a), (a = document.body));
    a || (a = document.body);
    var b = this,
      d = I({}, D.defaults, e || {}),
      f = {},
      u = [],
      h,
      y,
      J = 100,
      w = [],
      W = 0,
      B = d.threshold,
      Q = 0,
      L = A() - B,
      z,
      E = [],
      F = [],
      x,
      P,
      q = "fps" === d.show,
      O,
      K,
      c,
      p;
    b.options = d;
    b.fps = 0;
    b.duration = 0;
    b.isPaused = 0;
    b.tickStart = function () {
      Q = A();
    };
    b.tick = function () {
      z = A();
      W = z - L;
      B += (W - B) / d.smoothing;
      b.fps = 1e3 / B;
      b.duration = Q < L ? B : z - Q;
      L = z;
    };
    b.pause = function () {
      x && ((b.isPaused = 1), clearTimeout(x), C(x), C(P), (x = P = 0));
      return b;
    };
    b.resume = function () {
      x || ((b.isPaused = 0), k());
      return b;
    };
    b.set = function (a, c) {
      d[a] = c;
      q = "fps" === d.show;
      -1 !== R(a, X) && V();
      -1 !== R(a, Y) && s(f.container, d);
      return b;
    };
    b.showDuration = function () {
      b.set("show", "ms");
      return b;
    };
    b.showFps = function () {
      b.set("show", "fps");
      return b;
    };
    b.toggle = function () {
      b.set("show", q ? "ms" : "fps");
      return b;
    };
    b.hide = function () {
      b.pause();
      f.container.style.display = "none";
      return b;
    };
    b.show = function () {
      b.resume();
      f.container.style.display = "block";
      return b;
    };
    b.destroy = function () {
      b.pause();
      U();
      b.tick = b.tickStart = function () {};
    };
    V();
    k();
  }
  var A,
    r = m.performance;
  A =
    r && (r.now || r.webkitNow)
      ? r[r.now ? "now" : "webkitNow"].bind(r)
      : function () {
          return +new Date();
        };
  for (
    var C = m.cancelAnimationFrame || m.cancelRequestAnimationFrame,
      M = m.requestAnimationFrame,
      r = ["moz", "webkit", "o"],
      G = 0,
      k = 0,
      Z = r.length;
    k < Z && !C;
    ++k
  )
    M =
      (C =
        m[r[k] + "CancelAnimationFrame"] ||
        m[r[k] + "CancelRequestAnimationFrame"]) &&
      m[r[k] + "RequestAnimationFrame"];
  C ||
    ((M = function (a) {
      var e = A(),
        g = Math.max(0, 16 - (e - G));
      G = e + g;
      return m.setTimeout(function () {
        a(e + g);
      }, g);
    }),
    (C = function (a) {
      clearTimeout(a);
    }));
  var T =
    "string" === H(document.createElement("div").textContent)
      ? "textContent"
      : "innerText";
  D.extend = I;
  window.FPSMeter = D;
  D.defaults = {
    interval: 100,
    smoothing: 10,
    show: "fps",
    toggleOn: "click",
    decimals: 1,
    maxFps: 60,
    threshold: 100,
    position: "absolute",
    zIndex: 10,
    left: "5px",
    top: "5px",
    right: "auto",
    bottom: "auto",
    margin: "0 0 0 0",
    theme: "dark",
    heat: 0,
    graph: 0,
    history: 20,
  };
  var X = ["toggleOn", "theme", "heat", "graph", "history"],
    Y = "position zIndex left top right bottom margin".split(" ");
})(window);
(function (m, j) {
  j.theme = {};
  var s = (j.theme.base = {
    heatmaps: [],
    container: {
      heatOn: null,
      heatmap: null,
      padding: "5px",
      minWidth: "95px",
      height: "30px",
      lineHeight: "30px",
      textAlign: "right",
      textShadow: "none",
    },
    count: {
      heatOn: null,
      heatmap: null,
      position: "absolute",
      top: 0,
      right: 0,
      padding: "5px 10px",
      height: "30px",
      fontSize: "24px",
      fontFamily: "Consolas, Andale Mono, monospace",
      zIndex: 2,
    },
    legend: {
      heatOn: null,
      heatmap: null,
      position: "absolute",
      top: 0,
      left: 0,
      padding: "5px 10px",
      height: "30px",
      fontSize: "12px",
      lineHeight: "32px",
      fontFamily: "sans-serif",
      textAlign: "left",
      zIndex: 2,
    },
    graph: {
      heatOn: null,
      heatmap: null,
      position: "relative",
      boxSizing: "padding-box",
      MozBoxSizing: "padding-box",
      height: "100%",
      zIndex: 1,
    },
    column: { width: 4, spacing: 1, heatOn: null, heatmap: null },
  });
  j.theme.dark = j.extend({}, s, {
    heatmaps: [{ saturation: 0.8, lightness: 0.8 }],
    container: {
      background: "#222",
      color: "#fff",
      border: "1px solid #1a1a1a",
      textShadow: "1px 1px 0 #222",
    },
    count: { heatOn: "color" },
    column: { background: "#3f3f3f" },
  });
  j.theme.light = j.extend({}, s, {
    heatmaps: [{ saturation: 0.5, lightness: 0.5 }],
    container: {
      color: "#666",
      background: "#fff",
      textShadow:
        "1px 1px 0 rgba(255,255,255,.5), -1px -1px 0 rgba(255,255,255,.5)",
      boxShadow: "0 0 0 1px rgba(0,0,0,.1)",
    },
    count: { heatOn: "color" },
    column: { background: "#eaeaea" },
  });
  j.theme.colorful = j.extend({}, s, {
    heatmaps: [{ saturation: 0.5, lightness: 0.6 }],
    container: {
      heatOn: "backgroundColor",
      background: "#888",
      color: "#fff",
      textShadow: "1px 1px 0 rgba(0,0,0,.2)",
      boxShadow: "0 0 0 1px rgba(0,0,0,.1)",
    },
    column: { background: "#777", backgroundColor: "rgba(0,0,0,.2)" },
  });
  j.theme.transparent = j.extend({}, s, {
    heatmaps: [{ saturation: 0.8, lightness: 0.5 }],
    container: {
      padding: 0,
      color: "#fff",
      textShadow: "1px 1px 0 rgba(0,0,0,.5)",
    },
    count: { padding: "0 5px", height: "40px", lineHeight: "40px" },
    legend: { padding: "0 5px", height: "40px", lineHeight: "42px" },
    graph: { height: "40px" },
    column: {
      width: 5,
      background: "#999",
      heatOn: "backgroundColor",
      opacity: 0.5,
    },
  });
})(window, FPSMeter);


code:
/*! npm.im/iphone-inline-video */
var makeVideoPlayableInline = (function () {
  "use strict"; /*! npm.im/intervalometer */
  function e(e, n, r, i) {
    function t(r) {
      (d = n(t, i)), e(r - (a || r)), (a = r);
    }
    var d, a;
    return {
      start: function () {
        d || t(0);
      },
      stop: function () {
        r(d), (d = null), (a = 0);
      },
    };
  }
  function n(n) {
    return e(n, requestAnimationFrame, cancelAnimationFrame);
  }
  function r(e, n, r, i) {
    function t(n) {
      Boolean(e[r]) === Boolean(i) && n.stopImmediatePropagation(), delete e[r];
    }
    return e.addEventListener(n, t, !1), t;
  }
  function i(e, n, r, i) {
    function t() {
      return r[n];
    }
    function d(e) {
      r[n] = e;
    }
    i && d(e[n]), Object.defineProperty(e, n, { get: t, set: d });
  }
  function t(e, n, r) {
    r.addEventListener(n, function () {
      return e.dispatchEvent(new Event(n));
    });
  }
  function d(e, n) {
    Promise.resolve().then(function () {
      e.dispatchEvent(new Event(n));
    });
  }
  function a(e) {
    var n = new Audio();
    return (
      t(e, "play", n),
      t(e, "playing", n),
      t(e, "pause", n),
      (n.crossOrigin = e.crossOrigin),
      (n.src = e.src || e.currentSrc || "data:"),
      n
    );
  }
  function o(e, n, r) {
    (m || 0) + 200 < Date.now() && ((e[g] = !0), (m = Date.now())),
      r || (e.currentTime = n),
      (A[++k % 3] = (100 * n) | 0);
  }
  function u(e) {
    return e.driver.currentTime >= e.video.duration;
  }
  function s(e) {
    var n = this;
    n.video.readyState >= n.video.HAVE_FUTURE_DATA
      ? (n.hasAudio ||
          ((n.driver.currentTime =
            n.video.currentTime + (e * n.video.playbackRate) / 1e3),
          n.video.loop && u(n) && (n.driver.currentTime = 0)),
        o(n.video, n.driver.currentTime))
      : n.video.networkState !== n.video.NETWORK_IDLE ||
        n.video.buffered.length ||
        n.video.load(),
      n.video.ended && (delete n.video[g], n.video.pause(!0));
  }
  function c() {
    var e = this,
      n = e[b];
    return e.webkitDisplayingFullscreen
      ? void e[E]()
      : ("data:" !== n.driver.src &&
          n.driver.src !== e.src &&
          (o(e, 0, !0), (n.driver.src = e.src)),
        void (
          e.paused &&
          ((n.paused = !1),
          e.buffered.length || e.load(),
          n.driver.play(),
          n.updater.start(),
          n.hasAudio ||
            (d(e, "play"),
            n.video.readyState >= n.video.HAVE_ENOUGH_DATA && d(e, "playing")))
        ));
  }
  function v(e) {
    var n = this,
      r = n[b];
    r.driver.pause(),
      r.updater.stop(),
      n.webkitDisplayingFullscreen && n[T](),
      (r.paused && !e) ||
        ((r.paused = !0),
        r.hasAudio || d(n, "pause"),
        n.ended && ((n[g] = !0), d(n, "ended")));
  }
  function p(e, r) {
    var i = (e[b] = {});
    (i.paused = !0),
      (i.hasAudio = r),
      (i.video = e),
      (i.updater = n(s.bind(i))),
      r
        ? (i.driver = a(e))
        : (e.addEventListener("canplay", function () {
            e.paused || d(e, "playing");
          }),
          (i.driver = {
            src: e.src || e.currentSrc || "data:",
            muted: !0,
            paused: !0,
            pause: function () {
              i.driver.paused = !0;
            },
            play: function () {
              (i.driver.paused = !1), u(i) && o(e, 0);
            },
            get ended() {
              return u(i);
            },
          })),
      e.addEventListener(
        "emptied",
        function () {
          var n = !i.driver.src || "data:" === i.driver.src;
          i.driver.src &&
            i.driver.src !== e.src &&
            (o(e, 0, !0),
            (i.driver.src = e.src),
            n ? i.driver.play() : i.updater.stop());
        },
        !1
      ),
      e.addEventListener("webkitbeginfullscreen", function () {
        e.paused
          ? r && !i.driver.buffered.length && i.driver.load()
          : (e.pause(), e[E]());
      }),
      r &&
        (e.addEventListener("webkitendfullscreen", function () {
          i.driver.currentTime = e.currentTime;
        }),
        e.addEventListener("seeking", function () {
          A.indexOf((100 * e.currentTime) | 0) < 0 &&
            (i.driver.currentTime = e.currentTime);
        }));
  }
  function l(e) {
    var n = e[b];
    (e[E] = e.play),
      (e[T] = e.pause),
      (e.play = c),
      (e.pause = v),
      i(e, "paused", n.driver),
      i(e, "muted", n.driver, !0),
      i(e, "playbackRate", n.driver, !0),
      i(e, "ended", n.driver),
      i(e, "loop", n.driver, !0),
      r(e, "seeking"),
      r(e, "seeked"),
      r(e, "timeupdate", g, !1),
      r(e, "ended", g, !1);
  }
  function f(e, n, r) {
    void 0 === n && (n = !0),
      void 0 === r && (r = !0),
      (r && !h) ||
        e[b] ||
        (p(e, n),
        l(e),
        e.classList.add("IIV"),
        !n && e.autoplay && e.play(),
        /iPhone|iPod|iPad/.test(navigator.platform) ||
          console.warn(
            "iphone-inline-video is not guaranteed to work in emulated environments"
          ));
  }
  var m,
    y =
      "undefined" == typeof Symbol
        ? function (e) {
            return "@" + (e || "@") + Math.random();
          }
        : Symbol,
    h =
      "object-fit" in document.head.style &&
      /iPhone|iPod/i.test(navigator.userAgent) &&
      !matchMedia("(-webkit-video-playable-inline)").matches,
    b = y(),
    g = y(),
    E = y("nativeplay"),
    T = y("nativepause"),
    A = [],
    k = 0;
  return (f.isWhitelisted = h), f;
})();


code:
var LZString = {
  _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  _f: String.fromCharCode,
  compressToBase64: function (e) {
    if (e == null) return "";
    var t = "";
    var n, r, i, s, o, u, a;
    var f = 0;
    e = LZString.compress(e);
    while (f < e.length * 2) {
      if (f % 2 == 0) {
        n = e.charCodeAt(f / 2) >> 8;
        r = e.charCodeAt(f / 2) & 255;
        if (f / 2 + 1 < e.length) i = e.charCodeAt(f / 2 + 1) >> 8;
        else i = NaN;
      } else {
        n = e.charCodeAt((f - 1) / 2) & 255;
        if ((f + 1) / 2 < e.length) {
          r = e.charCodeAt((f + 1) / 2) >> 8;
          i = e.charCodeAt((f + 1) / 2) & 255;
        } else r = i = NaN;
      }
      f += 3;
      s = n >> 2;
      o = ((n & 3) << 4) | (r >> 4);
      u = ((r & 15) << 2) | (i >> 6);
      a = i & 63;
      if (isNaN(r)) {
        u = a = 64;
      } else if (isNaN(i)) {
        a = 64;
      }
      t =
        t +
        LZString._keyStr.charAt(s) +
        LZString._keyStr.charAt(o) +
        LZString._keyStr.charAt(u) +
        LZString._keyStr.charAt(a);
    }
    return t;
  },
  decompressFromBase64: function (e) {
    if (e == null) return "";
    var t = "",
      n = 0,
      r,
      i,
      s,
      o,
      u,
      a,
      f,
      l,
      c = 0,
      h = LZString._f;
    e = e.replace(/[^A-Za-z0-9\+\/\=]/g, "");
    while (c < e.length) {
      u = LZString._keyStr.indexOf(e.charAt(c++));
      a = LZString._keyStr.indexOf(e.charAt(c++));
      f = LZString._keyStr.indexOf(e.charAt(c++));
      l = LZString._keyStr.indexOf(e.charAt(c++));
      i = (u << 2) | (a >> 4);
      s = ((a & 15) << 4) | (f >> 2);
      o = ((f & 3) << 6) | l;
      if (n % 2 == 0) {
        r = i << 8;
        if (f != 64) {
          t += h(r | s);
        }
        if (l != 64) {
          r = o << 8;
        }
      } else {
        t = t + h(r | i);
        if (f != 64) {
          r = s << 8;
        }
        if (l != 64) {
          t += h(r | o);
        }
      }
      n += 3;
    }
    return LZString.decompress(t);
  },
  compressToUTF16: function (e) {
    if (e == null) return "";
    var t = "",
      n,
      r,
      i,
      s = 0,
      o = LZString._f;
    e = LZString.compress(e);
    for (n = 0; n < e.length; n++) {
      r = e.charCodeAt(n);
      switch (s++) {
        case 0:
          t += o((r >> 1) + 32);
          i = (r & 1) << 14;
          break;
        case 1:
          t += o(i + (r >> 2) + 32);
          i = (r & 3) << 13;
          break;
        case 2:
          t += o(i + (r >> 3) + 32);
          i = (r & 7) << 12;
          break;
        case 3:
          t += o(i + (r >> 4) + 32);
          i = (r & 15) << 11;
          break;
        case 4:
          t += o(i + (r >> 5) + 32);
          i = (r & 31) << 10;
          break;
        case 5:
          t += o(i + (r >> 6) + 32);
          i = (r & 63) << 9;
          break;
        case 6:
          t += o(i + (r >> 7) + 32);
          i = (r & 127) << 8;
          break;
        case 7:
          t += o(i + (r >> 8) + 32);
          i = (r & 255) << 7;
          break;
        case 8:
          t += o(i + (r >> 9) + 32);
          i = (r & 511) << 6;
          break;
        case 9:
          t += o(i + (r >> 10) + 32);
          i = (r & 1023) << 5;
          break;
        case 10:
          t += o(i + (r >> 11) + 32);
          i = (r & 2047) << 4;
          break;
        case 11:
          t += o(i + (r >> 12) + 32);
          i = (r & 4095) << 3;
          break;
        case 12:
          t += o(i + (r >> 13) + 32);
          i = (r & 8191) << 2;
          break;
        case 13:
          t += o(i + (r >> 14) + 32);
          i = (r & 16383) << 1;
          break;
        case 14:
          t += o(i + (r >> 15) + 32, (r & 32767) + 32);
          s = 0;
          break;
      }
    }
    return t + o(i + 32);
  },
  decompressFromUTF16: function (e) {
    if (e == null) return "";
    var t = "",
      n,
      r,
      i = 0,
      s = 0,
      o = LZString._f;
    while (s < e.length) {
      r = e.charCodeAt(s) - 32;
      switch (i++) {
        case 0:
          n = r << 1;
          break;
        case 1:
          t += o(n | (r >> 14));
          n = (r & 16383) << 2;
          break;
        case 2:
          t += o(n | (r >> 13));
          n = (r & 8191) << 3;
          break;
        case 3:
          t += o(n | (r >> 12));
          n = (r & 4095) << 4;
          break;
        case 4:
          t += o(n | (r >> 11));
          n = (r & 2047) << 5;
          break;
        case 5:
          t += o(n | (r >> 10));
          n = (r & 1023) << 6;
          break;
        case 6:
          t += o(n | (r >> 9));
          n = (r & 511) << 7;
          break;
        case 7:
          t += o(n | (r >> 8));
          n = (r & 255) << 8;
          break;
        case 8:
          t += o(n | (r >> 7));
          n = (r & 127) << 9;
          break;
        case 9:
          t += o(n | (r >> 6));
          n = (r & 63) << 10;
          break;
        case 10:
          t += o(n | (r >> 5));
          n = (r & 31) << 11;
          break;
        case 11:
          t += o(n | (r >> 4));
          n = (r & 15) << 12;
          break;
        case 12:
          t += o(n | (r >> 3));
          n = (r & 7) << 13;
          break;
        case 13:
          t += o(n | (r >> 2));
          n = (r & 3) << 14;
          break;
        case 14:
          t += o(n | (r >> 1));
          n = (r & 1) << 15;
          break;
        case 15:
          t += o(n | r);
          i = 0;
          break;
      }
      s++;
    }
    return LZString.decompress(t);
  },
  compressToUint8Array: function (e) {
    var t = LZString.compress(e);
    var n = new Uint8Array(t.length * 2);
    for (var r = 0, i = t.length; r < i; r++) {
      var s = t.charCodeAt(r);
      n[r * 2] = s >>> 8;
      n[r * 2 + 1] = s % 256;
    }
    return n;
  },
  decompressFromUint8Array: function (e) {
    if (e === null || e === undefined) {
      return LZString.decompress(e);
    } else {
      var t = new Array(e.length / 2);
      for (var n = 0, r = t.length; n < r; n++) {
        t[n] = e[n * 2] * 256 + e[n * 2 + 1];
      }
      return LZString.decompress(String.fromCharCode.apply(null, t));
    }
  },
  compressToEncodedURIComponent: function (e) {
    return LZString.compressToBase64(e).replace(/=/g, "$").replace(/\//g, "-");
  },
  decompressFromEncodedURIComponent: function (e) {
    if (e) e = e.replace(/$/g, "=").replace(/-/g, "/");
    return LZString.decompressFromBase64(e);
  },
  compress: function (e) {
    if (e == null) return "";
    var t,
      n,
      r = {},
      i = {},
      s = "",
      o = "",
      u = "",
      a = 2,
      f = 3,
      l = 2,
      c = "",
      h = 0,
      p = 0,
      d,
      v = LZString._f;
    for (d = 0; d < e.length; d += 1) {
      s = e.charAt(d);
      if (!Object.prototype.hasOwnProperty.call(r, s)) {
        r[s] = f++;
        i[s] = true;
      }
      o = u + s;
      if (Object.prototype.hasOwnProperty.call(r, o)) {
        u = o;
      } else {
        if (Object.prototype.hasOwnProperty.call(i, u)) {
          if (u.charCodeAt(0) < 256) {
            for (t = 0; t < l; t++) {
              h = h << 1;
              if (p == 15) {
                p = 0;
                c += v(h);
                h = 0;
              } else {
                p++;
              }
            }
            n = u.charCodeAt(0);
            for (t = 0; t < 8; t++) {
              h = (h << 1) | (n & 1);
              if (p == 15) {
                p = 0;
                c += v(h);
                h = 0;
              } else {
                p++;
              }
              n = n >> 1;
            }
          } else {
            n = 1;
            for (t = 0; t < l; t++) {
              h = (h << 1) | n;
              if (p == 15) {
                p = 0;
                c += v(h);
                h = 0;
              } else {
                p++;
              }
              n = 0;
            }
            n = u.charCodeAt(0);
            for (t = 0; t < 16; t++) {
              h = (h << 1) | (n & 1);
              if (p == 15) {
                p = 0;
                c += v(h);
                h = 0;
              } else {
                p++;
              }
              n = n >> 1;
            }
          }
          a--;
          if (a == 0) {
            a = Math.pow(2, l);
            l++;
          }
          delete i[u];
        } else {
          n = r[u];
          for (t = 0; t < l; t++) {
            h = (h << 1) | (n & 1);
            if (p == 15) {
              p = 0;
              c += v(h);
              h = 0;
            } else {
              p++;
            }
            n = n >> 1;
          }
        }
        a--;
        if (a == 0) {
          a = Math.pow(2, l);
          l++;
        }
        r[o] = f++;
        u = String(s);
      }
    }
    if (u !== "") {
      if (Object.prototype.hasOwnProperty.call(i, u)) {
        if (u.charCodeAt(0) < 256) {
          for (t = 0; t < l; t++) {
            h = h << 1;
            if (p == 15) {
              p = 0;
              c += v(h);
              h = 0;
            } else {
              p++;
            }
          }
          n = u.charCodeAt(0);
          for (t = 0; t < 8; t++) {
            h = (h << 1) | (n & 1);
            if (p == 15) {
              p = 0;
              c += v(h);
              h = 0;
            } else {
              p++;
            }
            n = n >> 1;
          }
        } else {
          n = 1;
          for (t = 0; t < l; t++) {
            h = (h << 1) | n;
            if (p == 15) {
              p = 0;
              c += v(h);
              h = 0;
            } else {
              p++;
            }
            n = 0;
          }
          n = u.charCodeAt(0);
          for (t = 0; t < 16; t++) {
            h = (h << 1) | (n & 1);
            if (p == 15) {
              p = 0;
              c += v(h);
              h = 0;
            } else {
              p++;
            }
            n = n >> 1;
          }
        }
        a--;
        if (a == 0) {
          a = Math.pow(2, l);
          l++;
        }
        delete i[u];
      } else {
        n = r[u];
        for (t = 0; t < l; t++) {
          h = (h << 1) | (n & 1);
          if (p == 15) {
            p = 0;
            c += v(h);
            h = 0;
          } else {
            p++;
          }
          n = n >> 1;
        }
      }
      a--;
      if (a == 0) {
        a = Math.pow(2, l);
        l++;
      }
    }
    n = 2;
    for (t = 0; t < l; t++) {
      h = (h << 1) | (n & 1);
      if (p == 15) {
        p = 0;
        c += v(h);
        h = 0;
      } else {
        p++;
      }
      n = n >> 1;
    }
    while (true) {
      h = h << 1;
      if (p == 15) {
        c += v(h);
        break;
      } else p++;
    }
    return c;
  },
  decompress: function (e) {
    if (e == null) return "";
    if (e == "") return null;
    var t = [],
      n,
      r = 4,
      i = 4,
      s = 3,
      o = "",
      u = "",
      a,
      f,
      l,
      c,
      h,
      p,
      d,
      v = LZString._f,
      m = { string: e, val: e.charCodeAt(0), position: 32768, index: 1 };
    for (a = 0; a < 3; a += 1) {
      t[a] = a;
    }
    l = 0;
    h = Math.pow(2, 2);
    p = 1;
    while (p != h) {
      c = m.val & m.position;
      m.position >>= 1;
      if (m.position == 0) {
        m.position = 32768;
        m.val = m.string.charCodeAt(m.index++);
      }
      l |= (c > 0 ? 1 : 0) * p;
      p <<= 1;
    }
    switch ((n = l)) {
      case 0:
        l = 0;
        h = Math.pow(2, 8);
        p = 1;
        while (p != h) {
          c = m.val & m.position;
          m.position >>= 1;
          if (m.position == 0) {
            m.position = 32768;
            m.val = m.string.charCodeAt(m.index++);
          }
          l |= (c > 0 ? 1 : 0) * p;
          p <<= 1;
        }
        d = v(l);
        break;
      case 1:
        l = 0;
        h = Math.pow(2, 16);
        p = 1;
        while (p != h) {
          c = m.val & m.position;
          m.position >>= 1;
          if (m.position == 0) {
            m.position = 32768;
            m.val = m.string.charCodeAt(m.index++);
          }
          l |= (c > 0 ? 1 : 0) * p;
          p <<= 1;
        }
        d = v(l);
        break;
      case 2:
        return "";
    }
    t[3] = d;
    f = u = d;
    while (true) {
      if (m.index > m.string.length) {
        return "";
      }
      l = 0;
      h = Math.pow(2, s);
      p = 1;
      while (p != h) {
        c = m.val & m.position;
        m.position >>= 1;
        if (m.position == 0) {
          m.position = 32768;
          m.val = m.string.charCodeAt(m.index++);
        }
        l |= (c > 0 ? 1 : 0) * p;
        p <<= 1;
      }
      switch ((d = l)) {
        case 0:
          l = 0;
          h = Math.pow(2, 8);
          p = 1;
          while (p != h) {
            c = m.val & m.position;
            m.position >>= 1;
            if (m.position == 0) {
              m.position = 32768;
              m.val = m.string.charCodeAt(m.index++);
            }
            l |= (c > 0 ? 1 : 0) * p;
            p <<= 1;
          }
          t[i++] = v(l);
          d = i - 1;
          r--;
          break;
        case 1:
          l = 0;
          h = Math.pow(2, 16);
          p = 1;
          while (p != h) {
            c = m.val & m.position;
            m.position >>= 1;
            if (m.position == 0) {
              m.position = 32768;
              m.val = m.string.charCodeAt(m.index++);
            }
            l |= (c > 0 ? 1 : 0) * p;
            p <<= 1;
          }
          t[i++] = v(l);
          d = i - 1;
          r--;
          break;
        case 2:
          return u;
      }
      if (r == 0) {
        r = Math.pow(2, s);
        s++;
      }
      if (t[d]) {
        o = t[d];
      } else {
        if (d === i) {
          o = f + f.charAt(0);
        } else {
          return null;
        }
      }
      u += o;
      t[i++] = f + o.charAt(0);
      r--;
      f = o;
      if (r == 0) {
        r = Math.pow(2, s);
        s++;
      }
    }
  },
};
if (typeof module !== "undefined" && module != null) {
  module.exports = LZString;
}