diff options
Diffstat (limited to 'sandbox/testAppNevena/Front/node_modules/npm-packlist')
5 files changed, 726 insertions, 0 deletions
diff --git a/sandbox/testAppNevena/Front/node_modules/npm-packlist/LICENSE b/sandbox/testAppNevena/Front/node_modules/npm-packlist/LICENSE new file mode 100644 index 00000000..19129e31 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/npm-packlist/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/sandbox/testAppNevena/Front/node_modules/npm-packlist/README.md b/sandbox/testAppNevena/Front/node_modules/npm-packlist/README.md new file mode 100644 index 00000000..9ec86afc --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/npm-packlist/README.md @@ -0,0 +1,146 @@ +# npm-packlist + +[](https://travis-ci.com/npm/npm-packlist) + +Get a list of the files to add from a folder into an npm package. + +These can be handed to [tar](http://npm.im/tar) like so to make an npm +package tarball: + +```js +const packlist = require('npm-packlist') +const tar = require('tar') +const packageDir = '/path/to/package' +const packageTarball = '/path/to/package.tgz' + +packlist({ path: packageDir }) + .then(files => tar.create({ + prefix: 'package/', + cwd: packageDir, + file: packageTarball, + gzip: true + }, files)) + .then(_ => { + // tarball has been created, continue with your day + }) +``` + +This uses the following rules: + +1. If a `package.json` file is found, and it has a `files` list, + then ignore everything that isn't in `files`. Always include the + readme, license, notice, changes, changelog, and history files, if + they exist, and the package.json file itself. +2. If there's no `package.json` file (or it has no `files` list), and + there is a `.npmignore` file, then ignore all the files in the + `.npmignore` file. +3. If there's no `package.json` with a `files` list, and there's no + `.npmignore` file, but there is a `.gitignore` file, then ignore + all the files in the `.gitignore` file. +4. Everything in the root `node_modules` is ignored, unless it's a + bundled dependency. If it IS a bundled dependency, and it's a + symbolic link, then the target of the link is included, not the + symlink itself. +4. Unless they're explicitly included (by being in a `files` list, or + a `!negated` rule in a relevant `.npmignore` or `.gitignore`), + always ignore certain common cruft files: + + 1. .npmignore and .gitignore files (their effect is in the package + already, there's no need to include them in the package) + 2. editor junk like `.*.swp`, `._*` and `.*.orig` files + 3. `.npmrc` files (these may contain private configs) + 4. The `node_modules/.bin` folder + 5. Waf and gyp cruft like `/build/config.gypi` and `.lock-wscript` + 6. Darwin's `.DS_Store` files because wtf are those even + 7. `npm-debug.log` files at the root of a project + + You can explicitly re-include any of these with a `files` list in + `package.json` or a negated ignore file rule. + +Only the `package.json` file in the very root of the project is ever +inspected for a `files` list. Below the top level of the root package, +`package.json` is treated as just another file, and no package-specific +semantics are applied. + +### Interaction between `package.json` and `.npmignore` rules + +For simplicity, it is best to use _either_ a `files` list in `package.json` +_or_ a `.npmignore` file, and not both. If you only use one of these +methods, you can skip this documentation section. + +The `files` list in `package.json` is used to direct the exploration of the +tree. In other words, that's all the walker will ever look at when +exploring that level. + +In some cases this can lead to a `.npmignore` file being ignored. If a +_directory_ is listed in `files`, then any rules in a root or nested +`.npmignore` files will be honored. + +For example, with this package.json: + +```json +{ + "files": [ "dir" ] +} +``` + +a `.npmignore` file at `dir/.npmignore` (and any subsequent +sub-directories) will be honored. However, a `.npmignore` at the root +level will be skipped. + +Conversely, with this package.json: + +``` +{ + "files": ["dir/subdir"] +} +``` + +a `.npmignore` file at `dir/.npmignore` will not be honored. + +Any specific file matched by a glob or filename in the package.json `files` +list will be included, and cannot be excluded by any `.npmignore` files in +nested directories, or by a `.npmignore` file in the root package +directory, unless that root `.npmignore` file is also in the `files` list. + +The previous (v1) implementation used in npm 6 and below treated +`package.json` as a special sort of "reverse ignore" file. That is, it was +parsed and handled as if it was a `.npmignore` file with `!` prepended to +all of the globs in the `files` list. In order to include children of a +directory listed in `files`, they would _also_ have `/**` appended to them. + +This is tricky to explain, but is a significant improvement over the +previous (v1) implementation used in npm 6 and below, with the following +beneficial properties: + +- If you have `{"files":["lib"]}` in `package.json`, then the walker will + still ignore files such as `lib/.DS_Store` and `lib/.foo.swp`. The + previous implementation would include these files, as they'd be matched + by the computed `!lib/**` ignore rule. +- If you have `{"files":["lib/a.js","lib/b.js"]}` in `package.json`, and a + `lib/.npmignore` containing `a.js`, then the walker will still include + the two files indicated in `package.json`, and ignore the + `lib/.npmignore` file. The previous implementation would mark these + files for inclusion, but then _exclude_ them when it came to the nested + `.npmignore` file. (Ignore file semantics dictate that a "closer" ignore + file always takes precedence.) +- A file in `lib/pkg-template/package.json` will be included, and its + `files` list will not have any bearing on other files being included or + skipped. When treating `package.json` as just Yet Another ignore file, + this was not the case, leading to difficulty for modules that aim to + initialize a project. + +In general, this walk should work as a reasonable developer would expect. +Matching human expectation is tricky business, and if you find cases where +it violates those expectations, [please let us +know](https://github.com/npm/npm-packlist/issues). + +## API + +Same API as [ignore-walk](http://npm.im/ignore-walk), just hard-coded +file list and rule sets. + +The `Walker` and `WalkerSync` classes take a `bundled` argument, which +is a list of package names to include from node_modules. When calling +the top-level `packlist()` and `packlist.sync()` functions, this +module calls into `npm-bundled` directly. diff --git a/sandbox/testAppNevena/Front/node_modules/npm-packlist/bin/index.js b/sandbox/testAppNevena/Front/node_modules/npm-packlist/bin/index.js new file mode 100644 index 00000000..40811db7 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/npm-packlist/bin/index.js @@ -0,0 +1,25 @@ +#!/usr/bin/env node + +const dirs = [] +let doSort = false +process.argv.slice(2).forEach(arg => { + if (arg === '-h' || arg === '--help') { + console.log('usage: npm-packlist [-s --sort] [directory, directory, ...]') + process.exit(0) + } else if (arg === '-s' || arg === '--sort') + doSort = true + else + dirs.push(arg) +}) + +const sort = list => doSort ? list.sort((a, b) => a.localeCompare(b, 'en')) : list + +const packlist = require('../') +if (!dirs.length) + console.log(sort(packlist.sync({ path: process.cwd() })).join('\n')) +else { + dirs.forEach(path => { + console.log(`> ${path}`) + console.log(sort(packlist.sync({ path })).join('\n')) + }) +} diff --git a/sandbox/testAppNevena/Front/node_modules/npm-packlist/index.js b/sandbox/testAppNevena/Front/node_modules/npm-packlist/index.js new file mode 100644 index 00000000..76018557 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/npm-packlist/index.js @@ -0,0 +1,481 @@ +'use strict' + +// Do a two-pass walk, first to get the list of packages that need to be +// bundled, then again to get the actual files and folders. +// Keep a cache of node_modules content and package.json data, so that the +// second walk doesn't have to re-do all the same work. + +const bundleWalk = require('npm-bundled') +const BundleWalker = bundleWalk.BundleWalker +const BundleWalkerSync = bundleWalk.BundleWalkerSync + +const ignoreWalk = require('ignore-walk') +const IgnoreWalker = ignoreWalk.Walker +const IgnoreWalkerSync = ignoreWalk.WalkerSync + +const rootBuiltinRules = Symbol('root-builtin-rules') +const packageNecessaryRules = Symbol('package-necessary-rules') +const path = require('path') + +const normalizePackageBin = require('npm-normalize-package-bin') + +// Weird side-effect of this: a readme (etc) file will be included +// if it exists anywhere within a folder with a package.json file. +// The original intent was only to include these files in the root, +// but now users in the wild are dependent on that behavior for +// localized documentation and other use cases. Adding a `/` to +// these rules, while tempting and arguably more "correct", is a +// significant change that will break existing use cases. +const packageMustHaveFileNames = 'readme|copying|license|licence' + +const packageMustHaves = `@(${packageMustHaveFileNames}){,.*[^~$]}` +const packageMustHavesRE = new RegExp(`^(${packageMustHaveFileNames})(\\..*[^~$])?$`, 'i') + +const fs = require('fs') +const glob = require('glob') + +const defaultRules = [ + '.npmignore', + '.gitignore', + '**/.git', + '**/.svn', + '**/.hg', + '**/CVS', + '**/.git/**', + '**/.svn/**', + '**/.hg/**', + '**/CVS/**', + '/.lock-wscript', + '/.wafpickle-*', + '/build/config.gypi', + 'npm-debug.log', + '**/.npmrc', + '.*.swp', + '.DS_Store', + '**/.DS_Store/**', + '._*', + '**/._*/**', + '*.orig', + '/package-lock.json', + '/yarn.lock', + '/archived-packages/**', +] + +// There may be others, but :?|<> are handled by node-tar +const nameIsBadForWindows = file => /\*/.test(file) + +// a decorator that applies our custom rules to an ignore walker +const npmWalker = Class => class Walker extends Class { + constructor (opt) { + opt = opt || {} + + // the order in which rules are applied. + opt.ignoreFiles = [ + rootBuiltinRules, + 'package.json', + '.npmignore', + '.gitignore', + packageNecessaryRules, + ] + + opt.includeEmpty = false + opt.path = opt.path || process.cwd() + + // only follow links in the root node_modules folder, because if those + // folders are included, it's because they're bundled, and bundles + // should include the contents, not the symlinks themselves. + // This regexp tests to see that we're either a node_modules folder, + // or a @scope within a node_modules folder, in the root's node_modules + // hierarchy (ie, not in test/foo/node_modules/ or something). + const followRe = /^(?:\/node_modules\/(?:@[^/]+\/[^/]+|[^/]+)\/)*\/node_modules(?:\/@[^/]+)?$/ + const rootPath = opt.parent ? opt.parent.root : opt.path + const followTestPath = opt.path.replace(/\\/g, '/').substr(rootPath.length) + opt.follow = followRe.test(followTestPath) + + super(opt) + + // ignore a bunch of things by default at the root level. + // also ignore anything in the main project node_modules hierarchy, + // except bundled dependencies + if (this.isProject) { + this.bundled = opt.bundled || [] + this.bundledScopes = Array.from(new Set( + this.bundled.filter(f => /^@/.test(f)) + .map(f => f.split('/')[0]))) + const rules = defaultRules.join('\n') + '\n' + this.packageJsonCache = this.parent ? this.parent.packageJsonCache + : (opt.packageJsonCache || new Map()) + super.onReadIgnoreFile(rootBuiltinRules, rules, _ => _) + } else { + this.bundled = [] + this.bundledScopes = [] + this.packageJsonCache = this.parent.packageJsonCache + } + } + + get isProject () { + return !this.parent || this.parent.follow && this.isSymbolicLink + } + + onReaddir (entries) { + if (this.isProject) { + entries = entries.filter(e => + e !== '.git' && + !(e === 'node_modules' && this.bundled.length === 0) + ) + } + + // if we have a package.json, then look in it for 'files' + // we _only_ do this in the root project, not bundled deps + // or other random folders. Bundled deps are always assumed + // to be in the state the user wants to include them, and + // a package.json somewhere else might be a template or + // test or something else entirely. + if (!this.isProject || !entries.includes('package.json')) { + return super.onReaddir(entries) + } + + // when the cache has been seeded with the root manifest, + // we must respect that (it may differ from the filesystem) + const ig = path.resolve(this.path, 'package.json') + + if (this.packageJsonCache.has(ig)) { + const pkg = this.packageJsonCache.get(ig) + + // fall back to filesystem when seeded manifest is invalid + if (!pkg || typeof pkg !== 'object') { + return this.readPackageJson(entries) + } + + // feels wonky, but this ensures package bin is _always_ + // normalized, as well as guarding against invalid JSON + return this.getPackageFiles(entries, JSON.stringify(pkg)) + } + + this.readPackageJson(entries) + } + + onReadPackageJson (entries, er, pkg) { + if (er) { + this.emit('error', er) + } else { + this.getPackageFiles(entries, pkg) + } + } + + mustHaveFilesFromPackage (pkg) { + const files = [] + if (pkg.browser) { + files.push('/' + pkg.browser) + } + if (pkg.main) { + files.push('/' + pkg.main) + } + if (pkg.bin) { + // always an object because normalized already + for (const key in pkg.bin) { + files.push('/' + pkg.bin[key]) + } + } + files.push( + '/package.json', + '/npm-shrinkwrap.json', + '!/package-lock.json', + packageMustHaves + ) + return files + } + + getPackageFiles (entries, pkg) { + try { + // XXX this could be changed to use read-package-json-fast + // which handles the normalizing of bins for us, and simplifies + // the test for bundleDependencies and bundledDependencies later. + // HOWEVER if we do this, we need to be sure that we're careful + // about what we write back out since rpj-fast removes some fields + // that the user likely wants to keep. it also would add a second + // file read that we would want to optimize away. + pkg = normalizePackageBin(JSON.parse(pkg.toString())) + } catch (er) { + // not actually a valid package.json + return super.onReaddir(entries) + } + + const ig = path.resolve(this.path, 'package.json') + this.packageJsonCache.set(ig, pkg) + + // no files list, just return the normal readdir() result + if (!Array.isArray(pkg.files)) { + return super.onReaddir(entries) + } + + pkg.files.push(...this.mustHaveFilesFromPackage(pkg)) + + // If the package has a files list, then it's unlikely to include + // node_modules, because why would you do that? but since we use + // the files list as the effective readdir result, that means it + // looks like we don't have a node_modules folder at all unless we + // include it here. + if ((pkg.bundleDependencies || pkg.bundledDependencies) && entries.includes('node_modules')) { + pkg.files.push('node_modules') + } + + const patterns = Array.from(new Set(pkg.files)).reduce((set, pattern) => { + const excl = pattern.match(/^!+/) + if (excl) { + pattern = pattern.substr(excl[0].length) + } + // strip off any / from the start of the pattern. /foo => foo + pattern = pattern.replace(/^\/+/, '') + // an odd number of ! means a negated pattern. !!foo ==> foo + const negate = excl && excl[0].length % 2 === 1 + set.push({ pattern, negate }) + return set + }, []) + + let n = patterns.length + const set = new Set() + const negates = new Set() + const results = [] + const then = (pattern, negate, er, fileList, i) => { + if (er) { + return this.emit('error', er) + } + + results[i] = { negate, fileList } + if (--n === 0) { + processResults(results) + } + } + const processResults = results => { + for (const {negate, fileList} of results) { + if (negate) { + fileList.forEach(f => { + f = f.replace(/\/+$/, '') + set.delete(f) + negates.add(f) + }) + } else { + fileList.forEach(f => { + f = f.replace(/\/+$/, '') + set.add(f) + negates.delete(f) + }) + } + } + + const list = Array.from(set) + // replace the files array with our computed explicit set + pkg.files = list.concat(Array.from(negates).map(f => '!' + f)) + const rdResult = Array.from(new Set( + list.map(f => f.replace(/^\/+/, '')) + )) + super.onReaddir(rdResult) + } + + // maintain the index so that we process them in-order only once all + // are completed, otherwise the parallelism messes things up, since a + // glob like **/*.js will always be slower than a subsequent !foo.js + patterns.forEach(({pattern, negate}, i) => + this.globFiles(pattern, (er, res) => then(pattern, negate, er, res, i))) + } + + filterEntry (entry, partial) { + // get the partial path from the root of the walk + const p = this.path.substr(this.root.length + 1) + const pkgre = /^node_modules\/(@[^/]+\/?[^/]+|[^/]+)(\/.*)?$/ + const { isProject } = this + const pkg = isProject && pkgre.test(entry) ? + entry.replace(pkgre, '$1') : null + const rootNM = isProject && entry === 'node_modules' + const rootPJ = isProject && entry === 'package.json' + + return ( + // if we're in a bundled package, check with the parent. + /^node_modules($|\/)/i.test(p) && !this.isProject ? this.parent.filterEntry( + this.basename + '/' + entry, partial) + + // if package is bundled, all files included + // also include @scope dirs for bundled scoped deps + // they'll be ignored if no files end up in them. + // However, this only matters if we're in the root. + // node_modules folders elsewhere, like lib/node_modules, + // should be included normally unless ignored. + : pkg ? this.bundled.indexOf(pkg) !== -1 || + this.bundledScopes.indexOf(pkg) !== -1 + + // only walk top node_modules if we want to bundle something + : rootNM ? !!this.bundled.length + + // always include package.json at the root. + : rootPJ ? true + + // always include readmes etc in any included dir + : packageMustHavesRE.test(entry) ? true + + // npm-shrinkwrap and package.json always included in the root pkg + : isProject && (entry === 'npm-shrinkwrap.json' || entry === 'package.json') + ? true + + // package-lock never included + : isProject && entry === 'package-lock.json' ? false + + // otherwise, follow ignore-walk's logic + : super.filterEntry(entry, partial) + ) + } + + filterEntries () { + if (this.ignoreRules['.npmignore']) { + this.ignoreRules['.gitignore'] = null + } + this.filterEntries = super.filterEntries + super.filterEntries() + } + + addIgnoreFile (file, then) { + const ig = path.resolve(this.path, file) + if (file === 'package.json' && !this.isProject) { + then() + } else if (this.packageJsonCache.has(ig)) { + this.onPackageJson(ig, this.packageJsonCache.get(ig), then) + } else { + super.addIgnoreFile(file, then) + } + } + + onPackageJson (ig, pkg, then) { + this.packageJsonCache.set(ig, pkg) + + if (Array.isArray(pkg.files)) { + // in this case we already included all the must-haves + super.onReadIgnoreFile('package.json', pkg.files.map( + f => '!' + f + ).join('\n') + '\n', then) + } else { + // if there's a bin, browser or main, make sure we don't ignore it + // also, don't ignore the package.json itself, or any files that + // must be included in the package. + const rules = this.mustHaveFilesFromPackage(pkg).map(f => `!${f}`) + const data = rules.join('\n') + '\n' + super.onReadIgnoreFile(packageNecessaryRules, data, then) + } + } + + // override parent stat function to completely skip any filenames + // that will break windows entirely. + // XXX(isaacs) Next major version should make this an error instead. + stat ({ entry, file, dir }, then) { + if (nameIsBadForWindows(entry)) { + then() + } else { + super.stat({ entry, file, dir }, then) + } + } + + // override parent onstat function to nix all symlinks, other than + // those coming out of the followed bundled symlink deps + onstat ({ st, entry, file, dir, isSymbolicLink }, then) { + if (st.isSymbolicLink()) { + then() + } else { + super.onstat({ st, entry, file, dir, isSymbolicLink }, then) + } + } + + onReadIgnoreFile (file, data, then) { + if (file === 'package.json') { + try { + const ig = path.resolve(this.path, file) + this.onPackageJson(ig, JSON.parse(data), then) + } catch (er) { + // ignore package.json files that are not json + then() + } + } else { + super.onReadIgnoreFile(file, data, then) + } + } + + sort (a, b) { + return sort(a, b) + } +} + +class Walker extends npmWalker(IgnoreWalker) { + globFiles (pattern, cb) { + glob(pattern, { dot: true, cwd: this.path, nocase: true }, cb) + } + + readPackageJson (entries) { + fs.readFile(this.path + '/package.json', (er, pkg) => + this.onReadPackageJson(entries, er, pkg)) + } + + walker (entry, opt, then) { + new Walker(this.walkerOpt(entry, opt)).on('done', then).start() + } +} + +class WalkerSync extends npmWalker(IgnoreWalkerSync) { + globFiles (pattern, cb) { + cb(null, glob.sync(pattern, { dot: true, cwd: this.path, nocase: true })) + } + + readPackageJson (entries) { + const p = this.path + '/package.json' + try { + this.onReadPackageJson(entries, null, fs.readFileSync(p)) + } catch (er) { + this.onReadPackageJson(entries, er) + } + } + + walker (entry, opt, then) { + new WalkerSync(this.walkerOpt(entry, opt)).start() + then() + } +} + +const walk = (options, callback) => { + options = options || {} + const p = new Promise((resolve, reject) => { + const bw = new BundleWalker(options) + bw.on('done', bundled => { + options.bundled = bundled + options.packageJsonCache = bw.packageJsonCache + new Walker(options).on('done', resolve).on('error', reject).start() + }) + bw.start() + }) + return callback ? p.then(res => callback(null, res), callback) : p +} + +const walkSync = options => { + options = options || {} + const bw = new BundleWalkerSync(options).start() + options.bundled = bw.result + options.packageJsonCache = bw.packageJsonCache + const walker = new WalkerSync(options) + walker.start() + return walker.result +} + +// optimize for compressibility +// extname, then basename, then locale alphabetically +// https://twitter.com/isntitvacant/status/1131094910923231232 +const sort = (a, b) => { + const exta = path.extname(a).toLowerCase() + const extb = path.extname(b).toLowerCase() + const basea = path.basename(a).toLowerCase() + const baseb = path.basename(b).toLowerCase() + + return exta.localeCompare(extb, 'en') || + basea.localeCompare(baseb, 'en') || + a.localeCompare(b, 'en') +} + +module.exports = walk +walk.sync = walkSync +walk.Walker = Walker +walk.WalkerSync = WalkerSync diff --git a/sandbox/testAppNevena/Front/node_modules/npm-packlist/package.json b/sandbox/testAppNevena/Front/node_modules/npm-packlist/package.json new file mode 100644 index 00000000..2fe493a2 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/npm-packlist/package.json @@ -0,0 +1,59 @@ +{ + "name": "npm-packlist", + "version": "3.0.0", + "description": "Get a list of the files to add from a folder into an npm package", + "directories": { + "test": "test" + }, + "main": "index.js", + "dependencies": { + "glob": "^7.1.6", + "ignore-walk": "^4.0.1", + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "license": "ISC", + "files": [ + "bin/index.js", + "index.js" + ], + "devDependencies": { + "@npmcli/lint": "^1.0.2", + "mutate-fs": "^2.1.1", + "tap": "^15.0.6" + }, + "scripts": { + "test": "tap", + "posttest": "npm run lint --", + "snap": "tap", + "postsnap": "npm run lintfix --", + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "eslint": "eslint", + "lint": "npm run npmclilint -- \"*.*js\" \"test/**/*.*js\"", + "lintfix": "npm run lint -- --fix", + "npmclilint": "npmcli-lint" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/npm/npm-packlist.git" + }, + "tap": { + "test-env": [ + "LC_ALL=sk" + ], + "check-coverage": true, + "nyc-arg": [ + "--include=index.js", + "--include=bin/index.js" + ] + }, + "bin": { + "npm-packlist": "bin/index.js" + }, + "engines": { + "node": ">=10" + } +} |