npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pleta/ui

v0.2.1

Published

Angular UI components, form controls, overlays, and notifications.

Downloads

339

Readme

Pleta UI

All components use separate TypeScript, HTML and CSS files with Angular's default encapsulation. Styles load with the component; no global stylesheet import is needed.

import {
  PleInput,
  PleInputNumber,
  PleInputPassword,
  PleSelect,
  PleMultiSelect,
  PleCheckboxGroup,
  PleRadioGroup,
  PleToggle,
  PleToggleButton,
} from '@pleta/ui';

Add the required components to your component's imports.

<input pleInput />
<input pleInputNumber type="number" />
<ple-select inputId="city" [options]="cities" [(value)]="city" />
<ple-multi-select inputId="topics" [options]="topics" [(value)]="selectedTopics" />

Inputs enhance native elements. With Reactive Forms, explicitly include type="number" so Angular selects its number value accessor.

Template inputs and projected slots

Import PleTemplate from @pleta/ui to use named projected slots. TemplateRef inputs retain their existing contexts. Priority: input → first direct projected slot → default. Removing the input restores projection; child component slots stay isolated.

<ple-select inputId="city" [options]="cities" [itemTemplate]="override">
  <ng-template pleTemplate="item" let-option let-selected="selected">
    <strong>{{ option.label }}</strong>
  </ng-template>
</ple-select>

Select, MultiSelect, CheckboxGroup, RadioGroup, ToggleButton, Menu and Breadcrumb support item/itemTemplate. Panel supports header/headerTemplate. Tabs supports header/headerTemplate and content/contentTemplate. Tabs contentTemplate is now optional because it can be projected; without either template its panel is empty. Ordinary button/panel content projection is unchanged. Both APIs share one renderer. Bare projected contexts do not infer generic types from parent components; typed TemplateRef inputs remain available. Examples and contexts: Storybook /templates.

Custom selectors

Selectors use a custom popup, not a native select. Options have the exported type PleOption<T>: { value: T; label: string; disabled?: boolean }. PleSelectOption<T> remains an alias for existing consumers. Values must be unique and are compared by reference (Object.is). Use stable primitive values or preserve object references. null is reserved for an empty single selection. The single-select value is T | null; the multiselect value is T[]. Both support [(value)] and Signal Forms [formField].

readonly cities = [
  { value: 'moscow', label: 'Moscow' },
  { value: 'kazan', label: 'Kazan' },
];
readonly city = signal<string | null>(null);

Pass one optional template for all items:

<ng-template #item let-option let-selected="selected">
  <strong>{{ option.label }}</strong>
  <small>{{ option.value }} {{ selected ? 'Selected' : '' }}</small>
</ng-template>

<label for="city">City</label>
<ple-select inputId="city" [options]="cities" [(value)]="city" [itemTemplate]="item" />

The template context is PleSelectItemContext<T>: $implicit contains the option and selected indicates its selection state. Without a template, the popup renders option.label. The closed control always shows the selected labels. Item templates must contain non-interactive presentation content, not nested buttons or inputs.

Supply a unique, stable inputId for each instance. It identifies the internal button and derives the list and option IDs, so labels and SSR use deterministic identifiers. A native label for should target inputId, not the custom host. Optional labelledBy and describedBy refer to existing label/hint element IDs. The disabled, readonly, required, and invalid inputs integrate with Signal Forms. Controls emit touch on blur and expose focus() and reset().

Arrow keys navigate enabled options; Home/End jump to the first/last enabled option. Enter/Space choose or toggle an option. Typing searches by label. Escape, Tab, outside pointer interaction and blur close the popup. Multiselect remains open when an item is toggled. Disabled options cannot be chosen.

Run npm run storybook from the workspace root for default and custom-template examples.

Checkbox and radio groups

<ple-checkbox-group
  inputId="interests"
  label="Interests"
  [options]="options"
  [(value)]="interests"
/>
<ple-radio-group inputId="delivery" label="Delivery" [options]="options" [(value)]="delivery" />

Both accept PleOption<T>[], an optional itemTemplate, and Signal Forms [formField]. The checkbox value is T[]; the radio value is T | null. Groups use native fieldset, legend, and inputs. Each group needs its own unique inputId, also used as the native radio group name. label supplies the legend; describedBy associates hints. disabled, readonly, required, and invalid integrate with form state. For checkbox groups, required means a nonempty selection in the form schema, rather than requiring every checkbox.

Toggle and toggle button

<ple-toggle label="Notifications" [(checked)]="notifications" />
<button pleToggleButton label="Status" [options]="statuses" [(value)]="status"></button>

PleToggle implements a boolean switch and binds to Signal Forms through [formField]. PleToggleButton<T> accepts the same PleOption<T> model as the selectors. Click, Enter, or Space selects the next enabled option and wraps to the beginning. Disabled options are skipped; an empty list or an all-disabled list disables the button. With no matching current value, the first enabled option is selected on the next click. Set the initial value explicitly to show an initial option rather than the placeholder.

A two-option button exposes aria-pressed (the second option is pressed). For more options it is an ordinary button announcing the current state in its accessible name. label is required. The button supports itemTemplate, disabled, readonly, invalid, and describedBy.

Datepicker

<label for="appointment">Appointment</label>
<ple-datepicker
  inputId="appointment"
  [(value)]="appointment"
  format="dd.MM.yyyy HH:mm"
  [minDate]="min"
  [maxDate]="max"
  showTime
  showClear
  requireConfirmation
/>

Import PleDatepicker from @pleta/ui. It implements Signal Forms FormValueControl<Date | null> and supports [formField], touch, focus() and reset() (reset discards the draft; the form owns its value). InputId must be unique. Selection is popup-only; there is no inline calendar or free-text date parsing.

Public inputs: format, minDate, maxDate, showTime (false), view: 'date' | 'month' | 'year' (date), showClear (false), requireConfirmation (false), disabled, readonly, required, invalid, labelledBy, describedBy, placeholder. Bind [(value)] or listen to valueChange.

Format uses Angular tokens, e.g. dd.MM.yyyy, MM.yyyy, yyyy, dd.MM.yyyy HH:mm. Formatting uses en-US for named tokens; calendar labels use ru-RU and Monday-first weeks. Dates are local calendar values, not UTC serialization. Without time the value is local midnight; with time precision is minutes. Month/year values are the first day of the selected month / January 1. Time is ignored in these views. Min/max are inclusive at the chosen precision: day, minute, month or year. Invalid or reversed bounds prevent opening. Existing invalid external values are not silently changed; validation of form data belongs to the application.

Without confirmation, date/month/year clicks commit immediately. With showTime, the popup remains open to edit time; valid edits commit immediately. Invalid time drafts never commit. With requireConfirmation, the field previews draft changes, but only Apply emits a new value. Cancel, Escape, the close button, trigger toggle, outside click and focus leaving the popup discard the draft. Clear is also staged in confirmation mode and opens the footer if necessary; Apply then emits null. An external value, bounds or mode change cancels the open draft. Required does not prevent clearing; apply the required rule in your form schema.

Navigation: arrows, Home/End, PageUp/PageDown; Enter/Space selects. Header month/year buttons change the navigation view. Escape restores trigger focus; outside click does not steal focus. Popup uses the existing floating layer, native buttons and grid semantics. Native time inputs support hours 0–23 and minutes 0–59. See Storybook /datepicker for all modes and Signal Forms.

Password

<label for="password">Password</label>
<ple-input-password inputId="password" [formField]="fields.password" autocomplete="new-password" />

The string value is available via [(value)] or [formField]. The reveal button changes visibility without modifying the value. reset() hides the password, and disabling the control hides it as well. autocomplete defaults to current-password; use new-password for registration. The control also accepts name, placeholder, minLength, maxLength, required, invalid, disabled, readonly, and describedBy. Focus moving between the input and the reveal button stays within the control; leaving it emits touch.

Layout

Internal shared UI components live in src/lib/_common/: select-panel, choice-group, and option-content. The common option model lives there too. Every storybook page has its own directory under apps/storybook/src/app/pages/; shared storybook components live under apps/storybook/src/app/_common/.

Floating layer, tooltip and popover

PleFloatingLayer in _common is reused by select, multiselect, tooltip, popover and popup menu. The native Popover API puts the surface in the top layer; our own positioning implementation handles anchor tracking, flipping and viewport limits without external runtime dependencies. It tracks geometry with requestAnimationFrame while the layer is open and stops on close. The shared stack dismisses only the top layer on Escape/outside interaction.

<button #help>Help</button>
<ple-tooltip [origin]="help" tooltipId="help-tip" text="More information" />
<button #settings>Settings</button>
<ple-popover [origin]="settings" panelId="settings-panel" label="Settings">
  <button type="button">An action</button>
</ple-popover>

Use unique tooltip/panel IDs. Tooltip opens on hover/focus and preserves existing descriptions. Popover toggles on anchor click, focuses its content, and restores anchor focus on Escape. Both accept Floating UI placement. Popover supports [(open)] and close(). Origins are DOM elements; with pleButton, use trigger.element.

Dialog and sidebar

Inject PleDialog to create a dynamic Angular component:

const ref = dialogs.open<ProfileResult, ProfileData>(ProfileEditor, {
  title: 'Edit profile',
  data: { name: 'Anna' },
  owner: destroyRef,
  // mode: 'sidebar', side: 'end', // or side: 'start'
});
const result = await ref.closed; // undefined on dismissal

Inside the component use injectDialogData<ProfileData>() and injectDialogRef<ProfileResult>(); call ref.close(result) to return a value. Optional inputs sets component inputs via ComponentRef.setInput; injector supplies the parent injection scope.

Native modal dialog makes the background inert. Scrolling is locked, Tab stays inside the dialog, and close restores focus. Nested selectors, tooltips and dialogs are supported. Sidebar uses the same lifecycle with edge positioning and slide animations. Reduced motion is respected. closeOnEscape: false / closeOnBackdrop: false disable those dismissal methods; the header close button remains available. Passing owner: DestroyRef disposes the dialog with its caller; closeAll() disposes all immediately. Call open() only in browser interactions, not during SSR.

Slider

<ple-slider inputId="volume" label="Volume" [min]="0" [max]="100" [(value)]="volume" />

Both bounds are required and finite, with min < max. step defaults to 1 and must be positive. External values and changed bounds are normalized to the interval and the step grid starting at min. Supports disabled, readonly, invalid, describedBy, touch, and focus().

With Signal Forms, Angular owns min/max bindings. Supply both schema rules instead of binding min/max on the same element as [formField]:

readonly fields = form(this.model, path => {
  min(path.volume, 0);
  max(path.volume, 100);
});
<ple-slider inputId="volume" label="Volume" [formField]="fields.volume" />

File input

Import PleInputFile and use <ple-input-file accept=".pdf,image/*" multiple [(files)]="files" [loading]="loading()" />. files is a readonly File[] model; filesChange emits the complete list after selection or removal. External updates can clear or replace it. Single selection replaces the previous file; multiple selection appends and deduplicates by name, size and lastModified. Cancelling the picker keeps the list. Removed files can be selected again.

accept only filters the native picker; validate files in your application. disabled and loading block selection and removal. Loading displays PleInProgress and sets aria-busy. The component does not upload files or call endpoints.

Customize the button using buttonTemplate or <ng-template pleTemplate="button"> (import PleTemplate). Context: choose(), disabled (includes loading), loading. The explicit template input takes precedence. Give your custom button an accessible name and call choose from its click handler. Examples and API: Storybook /input-file.

Button

<button pleButton severity="success" raised>Save</button>
<button pleButton text raised>Raised text</button>
<a pleButton routerLink="/" outlined>Home</a>
<button pleButton rounded aria-label="Add"><span aria-hidden="true">+</span></button>

PleButton is an attribute component: directive-style usage with encapsulated styles and projected content. There is no label input; text is a visual flag. Button variants are configured through the inputs listed below. Severity values: primary, secondary, success, info, warn, danger, help, contrast. raised, rounded, text, outlined, disabled, iconOnly are boolean inputs. Raised Text combines two flags; outlined takes precedence over text for the border. type defaults to button; specify submit or reset when needed. Anchors preserve native link semantics.

SVG, images, aria-hidden="true" and pleButtonIcon markers allow automatic icon-only detection, including dynamic content. Otherwise set iconOnly. Icon-only buttons are fixed at 44 × 44 px; supply aria-label. Disabled anchors leave the tab order and block click handlers/navigation. Do not nest interactive elements inside the projected content.

Button group

<ple-button-group label="Actions">
  <button pleButton>Save</button>
  <a pleButton routerLink="/">Home</a>
  <button pleButton>Close</button>
</ple-button-group>

PleButtonGroup projects content and joins direct child button/a elements. The first has only left rounded corners, the last only right rounded corners, and intermediate elements have none. A single element keeps all four corners. The group overrides individual rounded variants. Hidden elements are skipped; dynamic insertion/removal updates the edges. Nested groups are independent. The default outer radius is 8px; override --ple-button-group-radius on the group. Original inline corner styles are restored when an element leaves the group. Use the required label to name the group for assistive technology. Native link and button behavior, disabled states and tab order are preserved.

Menu

<button #trigger pleButton>Actions</button>
<ple-menu
  [items]="items"
  menuId="actions"
  label="Actions"
  popup
  [origin]="trigger.element"
  align="right"
  contentAlign="left"
  [itemTemplate]="item"
/>
<ng-template #item let-item let-index="index">
  <span>{{ item.label }}</span> <small>{{ item.data?.shortcut }}</small>
</ng-template>

Without popup, the menu is inline. Popups use the shared floating layer, toggle on anchor click, and support [(open)] and close(). align: left/right; contentAlign: left/center/right. Viewport collision handling takes precedence over alignment when space is insufficient.

PleMenuItem<T = any> has label?, icon? (a PleIconName from @pleta/icons), separator?, disabled?, visible?, url?, target?, data?: T, and command?(event). Untyped items have the requested data?: any; consumers can opt into typed data. selected and command receive { originalEvent, item }. Action items need a label; separators do not. Menu IDs must be unique.

One item template receives $implicit: item and index. It replaces content inside the interactive wrapper: do not put buttons, links or inputs inside it. Arrow keys, Home/End and label search navigate enabled items. Enter/Space activate, Escape restores anchor focus, and Tab/outside interaction close without trapping focus. This is a single-level menu; no nested submenus yet.

Browser baseline

Interactive overlays require native Popover API and modal dialog support. Automated browser checks currently run in Microsoft Edge with desktop/mobile viewports and AXE. Firefox, Safari and real assistive technology need a release compatibility pass.

Panel and tabs

PlePanel takes required panelId and title, [(expanded)] (default true), disabled, and an optional headerTemplate whose implicit value is expanded. Projected content stays mounted while hidden. Header templates must not contain interactive elements because the header itself is a button. Disabled prevents user toggling; the parent can still change expanded.

PleTabs takes required tabsId, label and tabs, plus [(active)] containing a tab ID. Each tab has a unique id, label and optional disabled flag. Supply content through contentTemplate or a projected <ng-template pleTemplate="content">. Content templates receive the tab; optional headerTemplate also receives selected. Only active content is instantiated, and switching tabs destroys the previous view. Keep form/business state in the parent when it needs to persist. Arrow keys and Home/End navigate enabled tabs. Missing/disabled active IDs display the first enabled tab; with all tabs disabled no content is shown.

Confirmation and toast services

await inject(PleConfirm).confirm({ title, message, severity: 'danger', owner }) returns true only for acceptance; dismissal/rejection returns false. Optional acceptLabel/rejectLabel customize buttons. Cancellation receives initial focus. Confirmation uses the existing dialog service and its focus/cleanup behavior.

Place one <ple-toast-outlet /> in the root template. Inject PleToast and call show({ title, message, severity, duration }), which returns an ID. Call dismiss(id) or clear() to remove notifications. Duration defaults to 5000 ms; zero is sticky. The outlet displays up to maxVisible (default 3); queued timers start only when shown and pause during hover/focus. Positions: top-right, top-left, bottom-right, bottom-left. Notifications do not take focus. Use persistent notifications for information the user must explicitly dismiss.

Field, textarea, tag and breadcrumb

textarea[pleTextarea] styles a native textarea and uses native Angular form integration. Put its content/value in a form or native value binding.

PleField takes required controlId and label, plus hint, required and errors (a string array). Project a control whose native focusable element has controlId. The wrapper connects hint/error IDs via aria-describedby, preserving existing descriptions, and sets aria-invalid for displayed errors. The caller supplies validation state, e.g. messages from a touched Signal Forms field. It does not create form validators. Field and hint/error IDs must be unique.

PleTag takes label, severity, optional icon (PleIconName) and removable. The removed output requests removal; the parent owns visibility and subsequent focus. PleBreadcrumb takes items with label and optional url/routerLink/icon. The last item is current and not a link. Optional itemTemplate receives item and current. Both icon inputs use the SVG set from @pleta/icons; arbitrary SVG icons can be rendered in custom templates where supported.

Paginator and skeleton

PlePaginator takes total, [(page)] with zero-based index and positive size, pageSizes, disabled and label. Changing page size resets index to zero. The parent supplies the corresponding data and clamps/reset its state when totals change. The table uses this same paginator.

Navigation uses PleButton and SVG icons from @pleta/icons; page size uses PleSelect. The optional pageSizeId names the internal select (generated per app by default). Provide stable unique pageSizeId values when server/client creation order differs.

PleSkeleton accepts CSS width/height strings, shape (rectangle/circle), and animated (default true). Give equal width and height for a circle. It is purely decorative and aria-hidden, with no accessible text in its markup. Put aria-busy and a loading announcement on the containing content. Reduced-motion disables the shimmer. The /table page uses skeletons in loadingTemplate.

In-progress indicator

Import PleInProgress from @pleta/ui: <ple-in-progress label="Updating users" />. Its only input is label (default Загрузка). It exposes an indeterminate progressbar with an accessible name and no numeric ARIA values. Show/hide it using application loading state. It does not fetch data.

CSS variables: --ple-in-progress-height (4px), --ple-in-progress-radius (999px), --ple-in-progress-color (#2459c4), --ple-in-progress-track (#e4ecfc), --ple-in-progress-duration (1.4s). Reduced-motion disables animation; forced-colors uses system colors. Markup is deterministic with no browser APIs, timers or Zone.js. Examples: /in-progress, /table-remote.

Loading buttons and dialog overlays

PleButton accepts [loading]. A decorative spinner overlays the projected content without changing its size or accessible name; aria-busy marks the operation and both buttons and links block activation while loading. Keep the projected label unchanged if its dimensions must stay identical. The application owns loading state.

PleDialog.open(Component, config) accepts CSS lengths in width, maxWidth and edgeOffset, plus position: 'center' | 'top'. Defaults: 560px wide, centered, 16px edge spacing (sidebar: 440px, 0px). Width and height remain constrained by the viewport; oversized offsets are clamped to keep the surface usable. Sidebars keep their configured side and also support width, maxWidth and edgeOffset.

dialogs.open(Editor, {
  title: 'Edit',
  width: '900px',
  maxWidth: '720px',
  position: 'top',
  edgeOffset: '24px',
});

Tooltips on elements behind a PleDialog close automatically and pending openings are cancelled. Such tooltips cannot consume Escape intended for the active modal. Tooltips inside the active dialog continue to work, including nested dialogs.

Colors and themes

All UI colors, including table and dashboard colors, use inherited --ple-* CSS custom properties with light defaults. No theme service or runtime switcher is required. The Storybook /theme page lists every token, its default and purpose, and provides the complete CSS palette to copy into your application's global stylesheet.

Alternatively, import the optional default palette at the start of your global CSS:

@import '@pleta/ui/theme.css';

Override variables in html[data-theme='dark'] or a prefers-color-scheme media query. Your application chooses the colors and sets the attribute. Set color-scheme: dark for native controls as appropriate. Apply global themes to html so service-created dialogs and notifications under body inherit them too. Pair each accent with its --ple-on-* foreground to maintain readable contrast. Component overrides such as --ple-table-background and --ple-in-progress-color remain supported and fall back to the shared palette.

Field errors (Signal Forms and Reactive Forms)

PleFieldError is independent of PleField: use a native label, a control and an error component. It supports both current Angular forms APIs:

<!-- Signal Forms -->
<label for="name">Name</label>
<input pleInput id="name" [formField]="fields.name" />
<ple-field-error [field]="fields.name" />

<!-- Reactive Forms, inside [formGroup] or formGroupName -->
<input pleInput id="reactive-name" formControlName="name" />
<ple-field-error fieldName="name" />

Pass exactly one of field and fieldName. Reactive paths resolve relative to the nearest ControlContainer, including nested groups/arrays. A missing control produces a configuration error. Changes made with emitEvent: false do not notify Reactive Forms subscribers; emit a control event to refresh displayed errors.

Messages can be configured globally or in a component's providers:

providePleFieldErrors({
  required: 'Обязательное поле',
  spaces: 'Введите хотя бы один непробельный символ',
  maxlength: ({ actualLength, requiredLength }) =>
    `Максимальная длина ${requiredLength}, текущая ${actualLength}`,
  taken: ({ project }: { project: string }) => `Имя уже используется: ${project}`,
});

Local [messages] overrides DI messages per error key. DI messages override explicit Signal Forms error messages, then built-in defaults apply. Unknown keys fall back to «Некорректное значение». Built-ins: required, email, minlength, maxlength, min, max, pattern and spaces. spaces is an optional application validator convention, not a validator supplied by this component.

Strings are literal text, not translation keys or interpolation templates. Functions receive the error payload. Known validators have typed parameters; custom callbacks can declare their own parameter type (the validator must return that shape). Signal Forms minLength/maxLength kinds are normalized to minlength/maxlength with requiredLength/actualLength, matching Reactive Forms. Other custom Signal Forms callbacks receive the error object, including its custom properties. No translation library is required. Pass a computed messages dictionary or read a locale signal in a formatter for language changes.

Default showWhen="interacted" shows errors after touch, edit or submission. Other modes: touched, dirty, submitted, always. Disabled/pending fields hide errors. Signal Forms submission touches invalid fields; use an external [submitted] flag for explicit submission-only visibility and reset it with the form.

controlId is optional. Signal Forms uses its public field bindings for automatic ARIA associations; Reactive Forms native PleInput, PleInputNumber and PleTextarea register automatically. Other Reactive Forms controls can opt in with the exported PleFieldControl directive (pleFieldControl) or supply an explicit controlId. Existing aria-describedby tokens are preserved. Errors render on separate lines, use --ple-error, decorative icons and a polite live region. Avoid rendering both PleField errors and PleFieldError for the same control.

Storybook /field-error includes both forms APIs, nested groups, overrides and reset.

Package boundaries

Table is exported from @pleta/table, not @pleta/ui. See its README for the full template and controlled-data API. SVG icons are exported from @pleta/icons. Build order is icons → ui → table; all workspace build/Storybook scripts handle this automatically. Public components have dedicated Storybook pages; shared internal components under _common are exercised through their public owners.

Theme documentation

Theme documentation is consolidated on Storybook /theme, in the @pleta/ui tab: shared color palette, component overrides, default values and copyable CSS. The other tabs document table, dashboard and icon styling. The shared palette also controls table and dashboard; no runtime theme provider is needed.

License

Pleta uses the proprietary Pleta Free Application Use License. Personal and commercial application use is free, including paid products, client projects, and SaaS. Application builds and distribution with bundled Pleta code are permitted. Modifying or forking the library itself, extracting its implementation, and republishing it as a standalone package or reusable library are not permitted except as stated in the license. Include the license in your application's legal notices. Third-party materials retain their own licenses. See the LICENSE file shipped with each package for the full terms.