Requirejs-quick-guide
RequireJS-概要
RequireJSは、JavaScriptファイルとモジュールプログラミングの依存関係を管理するJavaScriptライブラリおよびファイルローダーです。 また、コードの速度と品質の向上にも役立ちます。
RequireJSはDavid Markによって開発され、その初期バージョンv1.0.0は2009年にリリースされました。 これはオープンソースであり、バージョン2.3.3は最新の安定版リリースです。
RequireJSを使用する理由
- これは、MITライセンスに基づくオープンソースのJavaScriptライブラリです。
- 非同期モジュールのロードを提供します。
- ネストされた依存関係をロードする機能があります。
- 小さなファイルが多数ある場合は、依存関係の順序を追跡することを心配する必要はありません。
- プラグインのサポートを提供し、複数のJavaScriptファイルをロードします。
RequireJSの機能
- JavaScriptファイル間の依存関係を管理し、コードの速度と品質を向上させます。
- 最適化されたエクスペリエンスのために、モジュールを1つのスクリプトに結合および縮小します。
- 大規模アプリケーションのコードの複雑さを軽減します。
- コンパイル時に異なるモジュールから異なるJavaScriptファイルを収集します。
- プレーンスクリプトタグからファイルをロードするため、簡単にデバッグできます。
RequireJS-環境のセットアップ
この章では、RequireJSの環境を設定する方法を理解します。 そのためには、RequireJSライブラリの最新バージョンをダウンロードする必要があります。 minified versionまたはhttp://requirejs.org/docs/release/2.3.3/comments/requireのいずれかをダウンロードできます。 .js [詳細バージョン]。
ダウンロード後、libsフォルダーに require.js ファイルを含める必要があります。プロジェクトの構造は次のようになります-
projectname/
|--indexl
|--libs/
|---main.js
|---require.js
|---helper/
|----util.js
以下に示すように、RequireJSが読み込まれる indexl としてhtmlファイルを定義する必要があります。
<html>
<head>
<script data-main = "libs/main" src = "libs/require.js"></script>
</head>
<body>
<h1> RequireJS Sample Page </h1>
</body>
</html>
RequireJS呼び出しを含む require.js のみが、スクリプトをロードするスクリプトタグに含まれていることに注意してください。
NodeのRequireJS
Nodeアダプターを取得するには2つの方法があります。
- npm -以下に示すように、コマンドプロンプトからrequirejsの最新リリースをインストールできます。
npm install requirejs
- ダウンロード r.js - r.js ファイルはhttp://requirejs.org/docs/downloadl#rjs[download]ページからダウンロードでき、ソースは r.js [[1]] com/requirejs/r.js [repository]ページ。
RequireJS-構成
Requiredataは、_data-main_属性を介してHTMLテンプレートのメイン構成を渡すことで初期化できます。 RequireJSは、アプリケーションにロードするモジュールを知るために使用します。
例えば-
<script data-main = "scripts/main" src = "scripts/require.js"></script>
Require.jsファイルを含めるには、htmlファイルにscriptタグを追加する必要があります。 スクリプトタグ内で、 data-main 属性を追加してモジュールをロードします。 これは、アプリケーションのメインエントリポイントとして使用できます。 _scripts/main_は、RequireJS構成を含むアプリケーションのメインJavaScriptファイルです。
構成オプション
以下は、最初のアプリケーションモジュールのロード中に設定できる構成オプションです-
- baseUrl -RequireJSを介してロードされるすべてのモジュールのルートパスです。 baseUrlは、「スラッシュ(/)」で始まり、プロトコルを含み、「。js」拡張子で終わる文字列で示されます。 baseUrlが指定されていない場合、RequireJSは_data-main_属性パスをbaseUrlとして使用します。
- paths -baseUrlに関連するモジュールのパスマッピングを指定します。 モジュール名をマッピングするときに、パスに.js拡張子が自動的に追加されます。
- shim -依存関係を設定し、グローバル値をエクスポートすることにより、RequireJSで非AMDライブラリの使用を提供します。
- map -特定のモジュールについて、アプリケーションはIDを共有して異なる条件で同じコードを使用することにより、異なる目的の異なるバージョンの同じモジュールを使用します。
- config -config_オプションを使用してモジュールに構成を提供します。これは、特別な依存関係「モジュール」を使用し、その _module.config() 関数を呼び出すことで実行できます。
- urlArgs -クエリ文字列引数は、RequireJSを使用して読み込まれたすべてのリソースを取得するために使用されます。 ブラウザまたはサーバーの設定が不適切な場合、キャッシュの無効化に使用されます。
- waitSeconds -スクリプトの読み込み時にスローするまで待機する秒数を指定します。 デフォルトは「7」秒で、「0」はタイムアウトを無効にします。
- パッケージ-ロードモジュールを構成するためのCommonJSパッケージを提供します。
- context -ページ内のさまざまなモジュールのロードを可能にするコンテキストロードの名前を提供します。
- deps -RequireJSをロードする前にRequireが構成オブジェクトとして指定されている場合に必要な依存関係の配列です。
- callback -依存関係をロードした後に関数を実行し、RequireJSをロードする前にRequireが構成オブジェクトとして指定されている場合に必要です。
- xhtml -このオプションが_true_に設定されている場合、 _ document.createElementNS()_ メソッドを使用してスクリプト要素を作成するために使用されます。
- scriptType -ドキュメントで使用されるスクリプトタイプ属性の値を定義します。 デフォルトのタイプは「text/javascript」です。
- skipDataMain -このオプションが_true_に設定されている場合、モジュールのロード中に_data-main属性scanning_をスキップします。
RequireJS-AMDモジュール
RequireJSのモジュールはスコープオブジェクトであり、グローバル名前空間では使用できません。 したがって、グローバル名前空間は汚染されません。 RequireJS構文を使用すると、依存関係の順序を追跡することを心配することなく、モジュールをより速くロードできます。 同じページに同じモジュールの複数のバージョンをロードできます。
モジュールの定義
モジュールは* define()*関数を使用して定義されます。モジュールのロードにも同じ関数が使用されます。
単純な名前/値のペア
モジュールが名前と値のペアの単なるコレクションである場合、次の構文を使用できます-
define({
state: "karnataka",
city: "bangalore"
});
関数を定義する
モジュールは、依存関係なしでフレームワークの関数を使用することもできます。 これは、次の構文を使用して行うことができます-
define(function () {
//Do setup work here
return {
state: "karnataka",
city: "bangalore"
}
});
依存関係を持つ関数の定義
モジュールに依存関係がある場合、最初の引数(依存関係名の配列)、2番目の引数(定義関数)、およびモジュールを定義する戻りオブジェクトの配置は、次の構文で示されます-
define(["./mnc", "./startup"],
function(mnc, startup) {
return {
state: "karnataka",
city: "bangalore",
addCompany: function() {
mnc.decrement(this);
startup.add(this);
}
}
}
);
モジュールを関数として定義する
モジュールがオブジェクトのみを返すことは必須ではありません。関数から有効な値を返すこともできます。 次の構文は、モジュールを関数として定義するために使用されます-
define(["./mnc", "./startup"],
function(mnc, startup) {
return function(title) {
return title ? (window.title = title) :
startup.storeName + ' ' + mnc.name;
}
}
);
名前を持つモジュールの定義
場合によっては、モジュールの名前を* define()*の最初の引数として含める必要があります。 これは、次の構文を使用して行うことができます-
define("js2/title",
["js1/mnc", "js1/startup"],
function(mnc, startup) {
//Define js2/title object in here.
}
);
リンク:/requirejs/requirejs_modules_loading [モジュールの読み込み]
RequireJS-関数の定義
_define()_関数を使用して、モジュールをロードできます(モジュールは、オブジェクト、関数、クラス、またはモジュールのロード後に実行されるコードにすることができます)。 同じページに同じモジュールの異なるバージョンをロードできます。 異なるバージョンが異なる順序でロードされている場合でも、異なるバージョンを同じ順序で分析できます。
構文
define(['module1', 'module2'], function (module1, module2) {
//define the module value by returning a value
return function () {};
});
モジュールを定義するときにモジュール名のリストを渡すことができ、モジュールを実行する前にこれらのモジュールを取得するためにRequireJSを使用できます。 これらのモジュールは、*定義関数*のパラメーターとして渡すことができます。
例
次の例は、モジュールのロード中の_define()_関数の使用法を示しています。 _indexl_という名前のhtmlファイルを作成し、それに次のコードを配置します-
<!DOCTYPE html>
<html>
<head>
<title>Define() Function</title>
<script data-main = "main" src = "require.js"></script>
</head>
<body>
<h2>RequireJS Define() Function Example</h2>
</body>
</html>
_main.js_という名前の js ファイルを作成し、次のコードを追加します-
define(function (require) {
var myteam = require("./team");
var mylogger = require("./player");
alert("Player Name : " + myteam.player);
mylogger.myfunc();
});
ここで、_team.js_および_player.js_という名前でさらに2つの js ファイルを作成し、それぞれ次のコードを配置します-
team.js
define({
player: "Sachin Tendulkar",
team : "India"
});
player.js
define(function (require) {
var myteam = require("./team");
return {
myfunc: function () {
document.write("Name: " + myteam.player + ", Country: " + myteam.team);
}
};
});
出力
ブラウザでHTMLファイルを開きます。次のスクリーンショットのように出力が表示されます-
「OK」ボタンをクリックすると、モジュールから別の出力が得られます-
RequireJS-オプティマイザー
この章では、RequireJSでの最適化について説明します。 RequireJSのオプティマイザーには、次の特性があります-
- デフォルトで使用する場合はhttps://github.com/mishoo/UglifyJS[UglifyJS]、Javaを使用する場合はhttps://developers.google.com/closure/compiler/[Closure Compiler]のヘルプとスクリプトファイルを組み合わせます
- CSSファイルを結合します。
オプティマイザーは、https://github.com/requirejs/r.js [Node and Nashorn]用の r.js アダプターのコンポーネントです。 開発プロセスではなく、ビルドプロセスの一部として開発されています。
例
プロジェクトフォルダに_r.js_をダウンロードした後、フォルダの構造は以下のようになります-
projectfolder/
|-->indexl
|-->CSS/
|--->main.css
|--->other.css
|-->libs
|--->require.js
|--->main.js
|--->dependent1.js
|--->dependent2.js
|--->dependent3.js
HTMLファイルは次のようになります-
<html>
<head>
<script data-main = "libs/main" src = "libs/require.js"></script>
</head>
<body>
<h1> RequireJS Sample Page </h1>
</body>
</html>
_main.js_ファイルは次のようになります-
require(["dependent1", "dependent2", "dependent3"], function (dependent1, dependent2,
dependent3) {
});
_main.css_ファイルは次のようになります-
@import url("other.css");
.app {
background: transparent url(../../img/app.png);
}
オプティマイザーの基本設定
プロジェクトの設定には、コマンドライン引数またはプロファイル作成プロパティを使用できます。どちらも相互に交換可能です。
以下は、コマンドラインの構文です-
node r.js -o baseUrl = . paths.jquery = content/path/jquery
name = main out = main-built.js
プロファイルを構築するための構文は次のとおりです-
({
baseUrl: ".",
paths: {
jquery: "content/path/jquery"
},
name: "main",
out: "main-built.js"
})
この後、以下に示すように、コマンドラインでビルドプロファイル名をオプティマイザーに渡すことができます-
node r.js -o build.js
コマンドライン引数の構文にはいくつかの欠点があります。 コマンドライン引数またはプロファイル作成プロパティの両方を組み合わせて使用すると、これらの欠点を克服できます。
単一のJSファイルの最適化
単一のJSファイルを最適化するには、そのすべての依存関係のコンテンツを含むJSファイルを作成する必要があります。 あなたのファイルは以下のように見えるはずです-
({
baseUrl: "js/shop",
paths: {
"jquery": "jquery",
"backbone": "backbone",
"underscore": "underscore"
},
shim: {
"backbone": {
"department": ["underscore", "jquery"],
"dependent": "Backbone"
},
"underscore": {
exports: "_"
}
},
name: "../main",
out: "../built/js/main.js"
})
これで、アプリのすべての依存関係を含む_main.js_ファイルを作成できます。 このファイルは、1つの要求ですべてのJSファイルをロードするためにHTMLファイルで使用されます。 作成されたファイルは、ソースコードディレクトリにあるべきではないことに注意してください。ファイルはプロジェクトのコピーにある必要があります。
CDNリソースの使用
オプティマイザーは、ネットワークリソース/CDN(コンテンツ配信ネットワーク)を使用してスクリプトをロードしません。 場合には、スクリプトをCDNを使用してロードする必要があります。次に、これらのファイルをモジュール名にマップし、ファイルをローカルファイルパスにダウンロードする必要があります。 次の構文に示すように、ビルドプロファイルのパス構成で特別な単語「空」を使用できます-
({
baseUrl: "js",
name: "mainCDN",
out: "js/mainCDN-built.js",
paths: {
jquery: "empty:"
}
})
メインファイルは次のようになります-
requirejs.config({
paths: {
'jquery': 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min'
}
});
require(['jquery'], function ($) {
});
単一のCSSファイルの最適化
CSSファイルは、次のようにコマンドラインで次のパラメーターを直接使用して最適化されます-
node ../../r.js -o cssIn = main.css out = main-built.css
CSSファイルは、以下に示すのと同じプロパティを使用してビルドファイルで最適化することもできます-
...
cssIn:"main.css",
out:"main-built.css"
...
上記の方法は両方とも許可されており、_projectfolder/css/mainbuild.css_というファイルを作成します。 このファイルには、main.cssの内容、url()パスが適切に調整され、コメントが削除されます。
プロジェクト全体の最適化
オプティマイザーはビルドプロファイルを使用して、すべての css および js ファイルを最適化します。 次の例では、_build.js_ファイルが作成されます。
({
baseUrl: "js/shop",
appDir: '.',
paths: {
"jquery": "jquery",
"backbone": "backbone",
"underscore": "underscore"
},
shim: {
"backbone": {
"deps": ["underscore", "jquery"],
"exports": "Backbone"
},
"underscore": {
exports: "_"
}
},
optimizeCss: "standard.keepLines",
modules: [
{
name: "app"
}
],
dir: "../built"
})
_build.js_ファイルは、RequireJSにすべてのアプリフォルダー(appDirパラメーター)をビルドされた出力フォルダー(dirパラメーター)にコピーし、すべての最適化を出力フォルダーにあるファイルに適用するよう指示します。 次のコマンドを実行して、アプリフォルダーにプロファイルを作成します-
node r.js -o build.js
RequireJS-jQuery
RequireJSはjQueryを別の依存関係として使用し、名前付きモジュール_jquery_として小文字で登録します。また、AMD/RequireJSの使用中にグローバル関数_ $ _および_jQuery_を使用して自身を登録します。
jQueryの読み込み
require(['jquery'], function($) {
//code here
}
以下に示すように、jQueryとともに複数のカスタムライブラリをロードできます-
require(['custom_library_path',jquery'], function(load_library,$) {
//related code of $ and load_library
});
次の表は、依存関係を指定するためのjQueryとRequireJSの使用を示しています。
シニア
タイプと説明
1
リンク:/requirejs/jquery_shim_config [Shim Configの使用]
jQueryはshim構成を使用して、jQueryプラグインの依存関係を定義します。
2
リンク:/requirejs/jquery_from_cdn [CDNからjQueryをロード]
jQueryはCDNを使用して、jQueryプラグインの依存関係を定義します。
RequireJS-NodeJS
Nodeアダプターは、RequireおよびNodeの検索パスの実装とともに使用できます。 RequireJSで使用されるモジュール構成がない場合は、既存のノードベースのモジュールを変更せずに使用できます。 npmコマンドを使用して、プロジェクトの_node_modules_ディレクトリにノードパッケージをインストールできます。
ノードは、ローカルディスクおよびマップ、パッケージ、パスなどの構成オプションからのみモジュールをロードします。 モジュールがRequireJSによってロードされた場合にのみ適用されます。
ノードのインストール
あなたは、最新のリリースファイルをインストールする次のコマンドを使用して、ノードアダプタをインストールすることができます-
npm install requirejs
次の方法でもノードをインストールできます-
- このhttp://requirejs.org/docs/downloadl#rjs[link]から_r.js_をダウンロードして、プロジェクトフォルダーに保存できます。
- r.js repositoryからソースを取得するか、_node dist.js_からインストールします。
ノードの使用
このノードを使用するには、_require( 'requirejs')_が必要であり、構成内の_require_関数を最上位のmain.jsファイルに移動する必要があります。
例えば-
var requirejs = require('requirejs');
requirejs.config({
//load the mode modules to top level JS file
//by passing the top level main.js require function to requirejs
nodeRequire: require
});
requirejs(['name1', 'name2'],
function (name1, name2) {
//by using requirejs config, name1 and name2 are loaded
//node's require loads the module, if they did not find these
}
);
AMDまたはRequireJSを使用したノードモジュールの構築
ライブラリのユーザーを必要とせずに、RequireJSおよびNodeでコードモジュールを動作させ、_amdefine_パッケージを使用してこの動作を実行できます。
例えば-
if (typeof define !== 'function') {
var define = require('amdefine')(module);
}
define(function(require) {
var myval = require('dependency');
//The returned value from the function can be used
//as module which is visible to Node.
return function () {};
});
ノードモジュールとしてのオプティマイザー
Nodeモジュールは、コマンドラインツールを使用する代わりに関数呼び出しを使用して、RequireJSオプティマイザーを_optimize_メソッドとして使用します。
例えば-
var requirejs = require('requirejs');
var config = {
baseUrl: '../directory/scripts',
name: 'main',
out: '../build/main-built.js'
};
requirejs.optimize(config, function (buildResponse) {
//The text output of the modules specify by using buildResponse
//and loads the built file for the contents
//get the optimized file contents by using config.out
var contents = fs.readFileSync(config.out, 'utf8');
}, function(err) {
//code for optimization err callback
});
RequireJS-Dojo
Dojoは、AMDモジュールアーキテクチャに基づくJavaScriptツールキットであり、Webアプリケーションに追加機能を追加するための追加モジュールを提供し、Webアプリケーション開発プロセスの時間と規模を節約します。
例
次の例は、DojoとRequireJSの使用方法を示しています。 _indexl_という名前のhtmlファイルを作成し、それに次のコードを配置します-
<!DOCTYPE html>
<html>
<head>
<title>RequireJS Dojo</title>
<script data-main="app" src="lib/require.js"></script>
</head>
<body>
<h2>RequireJS Dojo</h2>
<p>
Hello... ...
</p>
</body>
</html>
_app.js_という名前の js ファイルを作成し、その中に次のコードを追加します-
require ({
//You can configure loading modules from the lib directory
baseUrl: 'lib',
paths: {
//mapping of package
dojo: 'http://sfoster.dojotoolkit.org/dojobox/1.7-branch/dojo'
}
}, [
//modules which we are using here
'dojo/dom'
], function(dom) {
//using the 'byId' method from dom module
var mydojo = dom.byId('dojo_val')
mydojo.innerHTML = "The text is displaying via dojo/dom";
}
);
出力
ブラウザでHTMLファイルを開きます。次の出力が表示されます-
RequireJS-CommonJS
モジュール形式はCommonJSによって定義されます。 ブラウザの同等のオプションを他のJavaScript環境に提供せずに定義されます。 したがって、CommonJS仕様では、http://wiki.commonjs.org/wiki/Modules/Transport [トランスポート形式]およびhttp://wiki.commonjs.org/wiki/Modules/Async/A [非同期要求]を推奨しています。 RequireJSで動作するように、従来のCommonJSモジュール形式を簡単に変換できます。 ただし、すべてのモジュールが新しい形式に変換されるわけではありません。 例外のいくつかは以下にリストされています-
- require呼び出しを行うための条件コードを備えたモジュール。
- 循環依存関係のあるモジュール。
手動変換
CommonJSモジュールは、次の構文を使用してRequireJS形式に手動で変換できます-
define(function(require, exports, module) {
//place CommonJS module content here
});
変換ツール
CommonJSモジュールは、_r.js_ファイルに組み込まれているhttps://github.com/requirejs/r.js[r.jsプロジェクト]コンバーターツールを使用して、RequireJS形式に変換できます。 以下に示すように、変換するファイルのパスと出力フォルダーを指定する必要があります-
node r.js -convert path/to/commonjs/modules/path/to/output
エクスポートされた値の設定
CommonJSの一部のシステムでは、エクスポートされた値を_module.exports_として割り当てることでエクスポートされた値を設定できますが、RequireJSは、定義に渡された関数から値を返す簡単な方法をサポートします。 これの利点は、エクスポートとモジュール関数の引数を必要としないため、以下に示すようにモジュール定義から除外することができます-
define(function (require) {
var name = require('name');
//Define the module as exporting a function
return function () {
name.doSomething();
};
});
代替構文
依存関係を指定する別の方法は、依存関係配列引数_define()_を使用することです。 しかし、依存関係配列内の名前の順序は、以下に示すように、定義関数_define()_に渡される引数の順序と一致する必要があります-
define(['name'], function (name) {
return function () {
name.doSomething();
};
});
CommonJSパッケージからモジュールをロードする
RequireJS構成を設定することにより、RequireJSを使用してCommonJSパッケージに場所とパッケージの属性を知るためのモジュールがロードされます。
最適化ツール
RequireJSには最適化ツールがあり、モジュール定義を組み合わせてブラウザー配信用の最適化されたバンドルにすることができます。 コード展開の一部として使用できるように、コマンドラインツールとして動作します。
RequireJS-プラグイン
RequireJSには、さまざまなタイプのリソースを依存関係としてロードできるプラグインの小さなセットが含まれています。 以下はRequireJSで利用可能なプラグインのリストです-
- text
- domReady
- i18n
- CSSの読み込み
text
_text_プラグインは、テキストベースのリソースを非同期でロードするために使用されます。これは、主にJavaScriptファイルにHTMLコンテンツを挿入するために使用されます。 任意のrequireまたはdefineモジュール呼び出しで_text!_プレフィックスを使用し、プラグインにファイル拡張子を渡すときにロードできます。 通常のモジュールのロードと比較して、_text_プラグインはXHRを使用してモジュールをロードし、 script タグとしてヘッダーにコードを追加しません。
テキストファイルリソースは、コードに依存関係として含めることができます-
require(["mymodule", "text!mymodulel", "text!mymodule.css"],
function(mymodule, html, css) {
//the html and css variables will be the text
//of the mymodulel file and mymodule.css files respectively
}
);
domReady
RequireJSを使用すると、DOMの準備が整う前にスクリプトをロードでき、スクリプトが完全にロードされた場合にのみ開発者がDOMと対話できます。 DOMの準備ができる前にスクリプトをロードできる場合があります。 したがって、この問題を克服するために、RequireJSは、DOMの準備ができたらdomReady関数を呼び出すhttps://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded[DOMContentLoaded]イベントと呼ばれる最新のアプローチを提供します。
require(['domReady'], function(domReady) {
domReady(function() {
//the domReady function is called when DOM is ready
//which is safe to manipulate DOM nodes in this function
});
});
i18n
モジュールまたは依存関係が「i18n!」を指定すると自動的にロードされる i18n バンドルサポートを提供する複数のロケールで使用できます。プレフィックス。 これを利用するには、ダウンロードして、メインのJavaScriptファイルが存在するのと同じディレクトリに配置します。 ローカリゼーションファイルを見つけるには、このプラグインを「nls」というディレクトリに配置します。
たとえば、次のコンテンツを持つ_country.js_という名前のjsファイルが1つあり、_mydirectory/nls/country.js_としてディレクトリに配置するとします-
define({
"root": {
"india": "india",
"australia": "australia",
"england": "england"
}
});
あなたは_fr-fr_ロケールを使用してファイルに特定の翻訳を追加することができ、上記のコードは次のように変更されます-
define({
"root": {
"title": "title",
"header": "header",
"description": "description"
},
"es-es": true
});
次に、次の内容で_mydirectory/nls/es-es/country.js_でファイルを指定します-
define({
"root": {
"title": "título",
"header": "cabecera",
"description": "descripción"
},
"es-es": true
});
以下に示すように、_main.js_ファイルのモジュール設定の助けを借りてプラグインに渡すことでロケールを設定できます-
requirejs.config({
config: {
//set the config for the i18n plugin
i18n: {
locale: 'es-es'
}
}
});
RequireJSを使用したCSSの読み込み
ヘッダーリンクに追加してCSSファイルをロードするだけで、いくつかのプラグインを使用してCSSファイルをロードできます。
以下に示すように、独自の関数を使用してCSSをロードすることができます-
function myCss(url) {
var mylink = document.createElement("mylink");
mylink.type = "text/css";
mylink.rel = "stylesheet";
mylink.href = url;
document.getElementsByTagName("head")[0].appendChild(mylink);
}